コマンドの後のスペースを避けるcsnameメソッドの欠点

コマンドの後のスペースを避けるcsnameメソッドの欠点

私もこれと似たような問題を抱えていました: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}

関連情報