
SE, ultimamente estou brincando expl3
um xparse
pouco e encontrei o seguinte problema: Quero criar um comando que crie um novo comando - semelhante aesta postagem. Isto não é tão difícil, desde que o segundo comando não tenha argumentos; tentar criar um comando que aceite argumentos é um pouco mais complicado.
O que consegui até agora:
\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}
Isso gera My name is ozymandias, king of kings
o soneto correto, mas não o que eu queria. Eu sei onde está o problema, só não sei como consertar isso :)
Responder1
Eu me pergunto sobre o \string#1
interior.
O novo comando interno pode ser construído com
\expandafter\NewDocumentCommand\csname #1\endcsname{...}{....}
isto é, o nome da nova sequência deve ser construído primeiro com \expandafter
(primeiro o nome é dado, depois \NewDocumentCommand
entra em ação). A mesma abordagem deve ser adotada para o tradicional \newcommand
ou \renewcommand
etc.
Porém, o \test
comando deve ser usado como \test{ozymandias}
, sem \
!
Observe que é necessário usar ##1
para acessar o primeiro argumento da macro interna (se isso for desejado), os argumentos subsequentes são numerados com ##2
etc.
\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}
EDITAR:Para usar \test
with \
, você tem que adaptar o comando para
\makeatletter
\NewDocumentCommand\test{ m}
{%
\expandafter\NewDocumentCommand\csname\expandafter\@gobble\string #1\endcsname{m}{%
My name is ##1, king of kings%
}
}
\makeatother