我遇到了與此類似的問題:LaTeX 指令後的空格
我的第一次嘗試是這樣的:
\newcommand{\satip}{SAT\textgreater IP}
這導致了已知的問題,即命令後面的空格被耗盡:
\satip is a cool Protocol. %Produces: SAT>IPis a cool Protocol.
space missing ^^^
我四處搜尋,發現了提到的問題。提供的解決方案很有幫助,但我對其中任何一個都不完全滿意。\satip/
只是在乳膠文檔中看起來有點奇怪,我\satip{}
更喜歡。只是,如果我忘記放在{}
指令後面,輸出就會缺少空格。因此,如果我使用錯誤,我希望得到一個錯誤。
可能的解決方案:
\def\satip#{SAT\textgreater IP}
%\satip is a cool Protocol. %doesn't compile, error
這樣就強制使用了左大括號,但大括號可以包含一些內容:
\satip{is} a cool Protocol.
這編譯得很好,但由於它沒有任何意義,我希望它產生一個錯誤。我目前處理問題的方法是這樣的:
\expandafter\def\csname satip{}\endcsname \relax{SAT\textgreater IP}
\def\satip#1{\csname satip{}\endcsname #1\relax}
%\satip{is} a cool Protocol. %Use of \satip{} doesn't match its definition.
%\satip is a cool Protocol. %Use of \satip{} doesn't match its definition.
\satip{} is a cool Protocol. %works
現在我的問題:
該巨集需要第二個擴充步驟。這會造成什麼麻煩嗎?還有其他問題嗎? (因為我以前沒有在任何地方找到過這個。)
PS:對不起,我的標題不好,我沒有想出更好的東西。請隨意編輯。
答案1
您可以隨時使用
\newcommand*\satip{SAT\textgreater IP}
\satip{} is a cool protocol
我沒有看到問題所在。
順便說一句,您的最後一個定義定義了帶有名稱的巨集satip{}
(大括號包括在巨集名稱中)後面跟著一個\relax
標記。如果將 and 放在#1
巨集中\endcsname
,則僅當 為空時才有效(即,僅當給出空大括號時)。\relax
\satip
#1
\satip{} is...
也許這能達到你想要的目的?
\newcommand*\satip[1]
{\if\relax\detokenize{#1}\relax
SAT\textgreater IP%
\else
\GenericError{} % <- I don't know what this argument does
{Wrong use of \string\satip{}.} % <- short version
{Wrong use of \string\satip. You must use \string\satip\space followed by an empyt argument `{}'.}% <- long version
\fi}
答案2
我不會{}
在輔助巨集的名稱中使用,但該方法是合理的:
\newcommand{\satip}[1]{\csname satip\string+\endcsname #1\relax}
\expandafter\def\csname satip\string+\endcsname\relax{%
SAT\textgreater IP%
}
\satip{x}
如果使用的話會觸發錯誤
! Use of \satip+ doesn't match its definition.
<argument> x
然而\satip ip
不會。你應該做二腳步:
\newcommand{\satip}{}% initialize
\protected\def\satip#{\csname satip\string+\endcsname}
\expandafter\def\csname satip\string+\endcsname#1{%
\csname satip\string+\string+\endcsname #1\relax
}
\expandafter\def\csname satip\string+\string+\endcsname\relax{%
SAT\textgreater IP%
}
現在\satip x
和\satip{x}
都會觸發錯誤:
! Use of \satip doesn't match its definition.
l.14 \satip x
?
! Use of \satip++ doesn't match its definition.
<argument> x
l.16 \satip{x}
?
請注意\protected
的定義前面\satip
,因此它不會在“移動參數”上下文中擴展。
抽象版本:
\documentclass{article}
\makeatletter
\newcommand\definestringcommand[2]{%
\@ifdefinable#1{\@definestringcommand#1{#2}}%
}
\newcommand{\@definestringcommand}[2]{%
\begingroup
\escapechar=\m@ne % get rid of the backslash
% require brace
\protected\xdef#1##{\expandafter\noexpand\csname\string#1\string+\endcsname}%
% examine the argument
\expandafter\xdef\csname\string#1\string+\endcsname##1{%
\expandafter\noexpand\csname\string#1\string+\string+\endcsname##1\relax
}%
\expandafter\gdef\csname\string#1\string+\string+\endcsname\relax{#2}%
\endgroup
}
\makeatother
\definestringcommand{\satip}{SAT\textgreater IP}
\begin{document}
\satip is nice
\satip{x} is nice
\satip{} is nice
\end{document}
這是否有用,我將決定權留給你。
一種不同的實作:檢查{
,然後檢查後續}
是否成功吃掉這兩個令牌。
\documentclass{article}
\makeatletter
\newcommand\definestringcommand[2]{%
\@ifdefinable#1{\@definestringcommand#1{#2}}%
}
\newcommand{\@definestringcommand}[2]{%
\begingroup
\escapechar=\m@ne % get rid of the backslash
% require brace
\protected\xdef#1##{%
\expandafter\noexpand\csname\string#1\string+\endcsname
}%
\expandafter\gdef\csname\string#1\string+\endcsname{%
#2%
\afterassignment\@checkrightbrace\let\@forget= % the space counts
}
\endgroup
}
\newcommand{\@checkrightbrace}{%
\@ifnextchar\egroup{\let\@forget= }{\@strcmderr\let\@forget= }%
}
\newcommand{\@strcmderr}{%
\@latex@error{Non empty group}{The braces must contain nothing}%
}
\makeatother
\definestringcommand{\satip}{SAT\textgreater IP}
\begin{document}
\satip is nice
\satip{x} is nice
\satip{} is nice
\end{document}