Estou tentando escrever algumas macros que, por sua vez, geram automaticamente outras macros, dependendo das opções, etc.
Gostaria de saber se é possível usar \NewDocumentCommand{\somename}{\standardargs}
, ou seja, a própria lista de argumentos está 'escondida' em uma macro.
Aqui está um exemplo curto e não funcional (a sobrecarga desnecessária é removida, é claro)
\documentclass{article}
\usepackage{xparse}
\newcommand{\standardargs}{O{}+m}
\NewDocumentCommand{\somecmd}{\standardargs}{%
% Do something more or less useful
My args: #2
}
\begin{document}
\somecmd{Hello World}
\end{document}
A mensagem de erro é
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! LaTeX error: "xparse/unknown-argument-type"
!
! Unknown argument type '\standardargs' replaced by 'm'.
!
! See the LaTeX3 documentation for further information.
!
! For immediate help type H <return>.
!...............................................
l.10 }
Algumas notas
- Tenho certeza, isso é algum problema de expansão
- EUsouciente de que talvez seja necessário usar uma abordagem mais sofisticada para manter os
{}
colchetes como especificadores padrão de valor opcional para\NewDocumentCommand
. - O uso/usabilidade de tal lista de argumentos padrão pode ser duvidoso, eu concordo com isso.
Responder1
Sim, expanda a macro antes de \NewDocumentCommand
tentar capturar o segundo argumento (definição da macro):
\documentclass{article}
\usepackage{xparse}
\newcommand{\standardargs}{O{}+m}
\expandafter\NewDocumentCommand\expandafter\somecmd\expandafter{\standardargs}{%
% Do something more or less useful
My args: #2
}
\begin{document}
\somecmd{Hello World}
\end{document}
Responder2
l3 permite que você evite\expandafter
\documentclass{article}
\usepackage{xparse}
\newcommand{\standardargs}{O{}+m}
\ExplSyntaxOn
\def\MyNewDocumentCommand{\exp_args:NNo\NewDocumentCommand}
\ExplSyntaxOn
\MyNewDocumentCommand{\somecmd}{\standardargs}{%
% Do something more or less useful
My args: #2
}
\begin{document}
\somecmd{Hello World}
\end{document}
Responder3
É exatamente um problema de expansão. Aqui está a definição de \NewDocumentCommand
:
\cs_new_protected:Npn \NewDocumentCommand #1#2#3
{
\cs_if_exist:NTF #1
{
\__msg_kernel_error:nnx { xparse } { command-already-defined }
{ \token_to_str:N #1 }
}
{ \__xparse_declare_cmd:Nnn #1 {#2} {#3} }
}
Seria muito fácil definir uma variação que aceitasse que um argumento fosse ampliado, se \__xparse_declare_cmd:Nnn
estivesse entre as funções públicas, mas não está. Sem ir contra as convenções de programação, você poderia fazer isso sozinho:
\ExplSyntaxOn
\cs_set_eq:NN \hupfer_newdocumentcommand:Nnn \NewDocumentCommand
\cs_generate_variant:Nn \hupfer_newdocumentcommand:Nnn { No }
\NewDocumentCommand\NewDocumentCommandExp{mmm}
{
\hupfer_newdocumentcommand:Non #1 { #2 } { #3 }
}
\ExplSyntaxOff
e então sua sintaxe
\NewDocumentCommandExp{\somecmd}{\standardargs}{%
% Do something more or less useful
My args: #2
}
podia funcionar. Para que isso pode ser útil, eu realmente não sei.