NewDocumentCommand com especificadores de argumento armazenados na macro

NewDocumentCommand com especificadores de argumento armazenados na macro

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 \NewDocumentCommandtentar 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:Nnnestivesse 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.

informação relacionada