Newcommand: 何ができないのか?

Newcommand: 何ができないのか?

新しいコマンドの作成に失敗したのは今回が初めてではありません。 いくつかは機能しないことが分かりました (「未定義の制御シーケンス」やその他のエラーが発生します)。

  • quote-endquote 引数を使用します。

    \newcommand{\mytest}[1]{
      \quote #1 \endquote
    }
    
  • \verb引数付きコマンドを使用する

    \newcommand{\mytest}[1]{
      \verb+#1+
    }
    
  • 環境を使用するbegin{lstlisting}:

    \newcommand{\mytest}[1]{
      \begin{lstlisting}
      #1
      \end{lstlisting}
    }
    

何ができて\newcommand、何ができないかの完全なリストをどこで見つけられるかご存知ですか? また、その理由も教えてください。

答え1

で何ができるかを言うのは非常に困難です\newcommand。可能性は(本当に)無限だからです。

私はあなたの 2 つの例について話し、あなたが犯している間違いを指摘することができます。

最初の定義では\quote、とを使用しています\endquoteが、これは間違いです。\quoteは、LaTeXが を見つけたときに実行するコマンドです\begin{quote}が、これが発生します。グループが開かれた後の副作用として、 LaTeX が を見つけたときに\beginグループは通常 によって閉じられ、によって実行されたパラメータの設定が自動的に元に戻されます。\end\end{quote}\quote

あなたの定義によれば、\mytest{something}線の幅は永久に変更左のインデントは永遠に続く。代わりに、

\newenvironment{myenv}{\quote}{\endquote}

\begin{myenv}グループ化はおよびによって提供されるためです\end{myenv}

の主な機能は何でしょうか\newcommand? 簡単な例を見てみましょう。

\newcommand{\foo}[1]{?#1!}

ここで と入力すると\foo{xyz}、 と入力するのと全く同じになります。

?xyz!

TeX がスキャンするときに、\foo引数 (\fooでない場合は の後の最初のトークン{、または一致する までのトークン リスト全体) を見つけて、命令で指定された置換テキスト ( は で示される) で}置き換える必要があることを認識しているからです。\foo<argument>\newcommand<argument>#1

引数は最大 9 個まで (引数なしでも) 指定できます。実行するのはこの「置換」だけです。適切な定義と条件構造を組み合わせると、再帰マクロを定義することもできますが、これを説明するには長くなりすぎます。「ユーザー定義」の大部分は、論理ユニットをマークアップするための単純な (またはやや複雑な) 置換です。

TeXはコマンドの後に続くものをスキャンしません。もっているに。したがって、 を実行すると\foo、マクロ置換が終了するまで引数を超えて引数内にマクロを展開することはありません。したがって、

\foo{\baz{x}}

TeXは

?\baz{x}!

その後、最初に処理が行われ?、次に\baz{x}それらが最初から入力にあったかのように処理されますが、2 番目の例に示すように小さな違いがあります。

入力との違いは\foo{\baz{x}}?\baz{x}!TeXにはすでにトークン化された \baz{x}

この\verbコマンドは、すべての特殊文字の意味を変更することによって機能します。これは、テキストが逐語的にタイプセットされるのを可能な限り遅らせることによって行われ、これはグループで行われます。

\verb+\baz{x}+

次の手順を実行する

  1. グループを開く( を指定{
  2. 等幅フォントで組版を開始する
  3. すべての特殊文字の意味を「印刷可能」に変更します
  4. (グループ終了トークン)+として動作するように定義します}
  5. 見つけたものは何でもタイプセットしてください
  6. 末尾に+特殊設定がすべて解除されます

説明は完全ではありませんが、私たちの目的には十分です。全体像を理解するのに無関係なその他の技術的な詳細があります。

定義すると何が起こるか

\newcommand{\foo}[1]{\verb+#1+}

あなたが提案したように?TeXは\foo{\baz{x}}それを見ると、引数をスキャンしてトークン化する必要があることがわかります。したがって、引数は4つのトークン(私は•で区切っています)

\baz • { • x • }

の意味は変わらず\、および{}これ以上実行できません。さらに悪いことに、+は意味が変わってグループ終了トークンになるはずですが、定義時にすでにトークン化されているため、変更できません。そのため、LaTeX\verbには、 をコマンドの引数に含めることを禁止する保護メカニズムがあります。このような場所で を使用すると、あらゆる種類の悪影響が発生する可能性があるためです。設定を元に戻す可能性がないまま特殊文字の意味を変更すると、逃げ場のない窮地に陥ります。

回避策はありますか?はい、\verb コマンドを \textbf{} ブロック内に配置するにはどうすればよいでしょうか?しかし、まず最初に、コマンドの引数に verbatim が本当に必要かどうかを自問してください。

関連情報