私もこれと似たような問題を抱えていました:LaTeXコマンドの後のスペース
私の最初の試みは次のようなものでした:
\newcommand{\satip}{SAT\textgreater IP}
これにより、コマンドの後のスペースが消費されるという既知の問題が発生します。
\satip is a cool Protocol. %Produces: SAT>IPis a cool Protocol.
space missing ^^^
検索して、上記の質問を見つけました。提供された解決策は非常に役立ちましたが、どれも完全に満足できるものではありませんでした。LaTeX\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
さて、私の質問は:
このマクロには 2 番目の拡張ステップが必要です。これにより問題が発生する可能性がありますか? 他に問題はありますか? (これまでどこにもこれを見つけたことはありません。)
追伸: タイトルが悪くてすみません。もっと良いものが思いつきませんでした。自由に編集してください。
答え1
いつでも使えます
\newcommand*\satip{SAT\textgreater IP}
\satip{} is a cool protocol
問題は分かりません。
ちなみに、最後の定義では、名前satip{}
(括弧含まれるマクロ名に が含まれる場合、その後にトークンが続きます\relax
。マクロ内でと#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}