
SE, últimamente estoy jugando expl3
un xparse
poco y encontré el siguiente problema: quiero crear un comando que cree un nuevo comando, similar aesta publicación. Esto no es tan difícil, siempre y cuando el segundo comando no tenga ningún argumento; intentar crear un comando que acepte argumentos es un poco más complicado.
Lo que tengo hasta ahora:
\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}
Esto genera My name is ozymandias, king of kings
, lo que da el soneto correcto, pero no lo que quería. Sé dónde está el problema, pero no sé cómo solucionarlo :)
Respuesta1
Me pregunto por el \string#1
interior.
El nuevo comando interior se puede construir con
\expandafter\NewDocumentCommand\csname #1\endcsname{...}{....}
es decir, primero se debe construir el nombre de la nueva secuencia \expandafter
(primero se da el nombre, luego \NewDocumentCommand
entra en acción). Se debe adoptar el mismo enfoque para los tradicionales \newcommand
, \renewcommand
etc.
Sin embargo, el \test
comando debe usarse como \test{ozymandias}
, sin \
!
Tenga en cuenta que es necesario utilizar ##1
para acceder al primer argumento de la macro interna (si es que se desea), los argumentos posteriores se numeran con ##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
con \
, tienes que adaptar el comando a
\makeatletter
\NewDocumentCommand\test{ m}
{%
\expandafter\NewDocumentCommand\csname\expandafter\@gobble\string #1\endcsname{m}{%
My name is ##1, king of kings%
}
}
\makeatother