XParse: コマンドを作成するコマンド

XParse: コマンドを作成するコマンド

SE、最近少し遊んでいてexpl3xparse次の問題に遭遇しました:新しいコマンドを作成するコマンドを作成したいのですが、この郵便受け2 番目のコマンドに引数がない限り、これはそれほど難しくありません。引数を受け入れるコマンドを作成するのは、少し難しくなります。

これまでに得たもの:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand\test{ m}
{
    \NewDocumentCommand#1 {m}
        {My name is \string#1, king of kings}
}

\begin{document}
\test{\ozymandias}
\ozymandias{\manthano}
\end{document}

出力はMy name is ozymandias, king of kingsで、正しいソネットが得られますが、私が望んでいたものではありません。どこに問題があるかはわかっていますが、現時点では修正方法がわかりません :)

答え1

中が気になります\string#1

内部の新しいコマンドは次のように構築できます。

\expandafter\NewDocumentCommand\csname #1\endcsname{...}{....}

つまり、新しいシーケンスの名前は、最初に で構築する必要があります\expandafter(最初に名前が指定され、その後に\NewDocumentCommand実行されます)。従来の\newcommandまたは\renewcommandなどについても同じアプローチを取る必要があります。

ただし、コマンドは!なし\testで として使用する必要があります。\test{ozymandias}\

内部マクロの最初の引数にアクセスするにはを使用する必要があることに注意してください##1(これが必要な場合)。後続の引数には、##2などという番号が付けられます。

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\manthano}{}{Manthano}

\NewDocumentCommand\test{ m}
{%
  \expandafter\NewDocumentCommand\csname #1\endcsname{m}{%
   My name is ##1, king of kings%
   }
}

\begin{document}
\test{ozymandias}
\ozymandias{\manthano}
\end{document}

編集:\testを使用するには\、コマンドを次のように変更する必要があります。

\makeatletter
\NewDocumentCommand\test{ m}
{%
  \expandafter\NewDocumentCommand\csname\expandafter\@gobble\string #1\endcsname{m}{%
   My name is ##1, king of kings%
   }
}
\makeatother

関連情報