NewDocumentCommand con especificadores de argumentos almacenados en macro

NewDocumentCommand con especificadores de argumentos almacenados en macro

Estoy intentando escribir algunas macros que a su vez generan automáticamente otras macros, dependiendo de las opciones, etc.

Me pregunto si es posible utilizar \NewDocumentCommand{\somename}{\standardargs}, es decir, la lista de argumentos en sí está "oculta" en una macro.

A continuación se muestra un breve ejemplo que no funciona (por supuesto, se eliminan los gastos generales innecesarios)

\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}

El mensaje de error es

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! 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 }

Algunas notas

  • Estoy bastante seguro de que se trata de algún problema de expansión.
  • Isoyconsciente de que podría tener que utilizar un enfoque más sofisticado para mantener los {}corchetes como especificadores predeterminados de valores opcionales para \NewDocumentCommand.
  • El uso/utilizabilidad de una lista de argumentos estándar de este tipo podría ser dudoso, estoy de acuerdo con eso.

Respuesta1

Sí, expanda la macro antes de \NewDocumentCommandintentar obtener el segundo argumento (definición de 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}

Respuesta2

l3 te permite evitar\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}

Respuesta3

Es exactamente un problema de expansión. Aquí está la definición 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} }
  }

Sería muy fácil definir una variación que acepte un argumento a ampliar, si \__xparse_declare_cmd:Nnnestuviera entre las funciones públicas, pero no lo está. Sin ir en contra de las convenciones de programación, puedes hacerlo tú mismo:

\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

y luego tu sintaxis

\NewDocumentCommandExp{\somecmd}{\standardargs}{%
  % Do something more or less useful
  My args: #2
}

trabajaría. Para qué puede ser útil esto, realmente no lo sé.

información relacionada