NewDocumentCommand mit im Makro gespeicherten Argumentspezifizierern

NewDocumentCommand mit im Makro gespeicherten Argumentspezifizierern

Ich versuche, einige Makros zu schreiben, die wiederum je nach Optionen usw. automatisch andere Makros generieren.

Ich frage mich, ob es möglich ist, zu verwenden \NewDocumentCommand{\somename}{\standardargs}, d. h. die Argumentliste selbst wird in einem Makro „versteckt“.

Hier ist ein nicht funktionierendes, kurzes Beispiel (der nicht notwendige Overhead wurde natürlich entfernt)

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

Die Fehlermeldung lautet

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

Einige Notizen

  • Ich bin ziemlich sicher, dass dies ein Erweiterungsproblem ist
  • ICHBinmir ist bewusst, dass ich möglicherweise einen ausgefeilteren Ansatz verwenden muss, um die {}Klammern als optionale Standardwertspezifizierer für beizubehalten \NewDocumentCommand.
  • Der Nutzen/die Verwendbarkeit einer solchen Standardargumentliste dürfte fraglich sein, dem würde ich zustimmen.

Antwort1

Ja, erweitern Sie das Makro, bevor \NewDocumentCommandSie versuchen, das zweite Argument (Makrodefinition) zu erfassen:

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

Antwort2

l3 ermöglicht es Ihnen, zu vermeiden\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}

Antwort3

Es handelt sich genau genommen um ein Expansionsproblem. Hier ist die Definition von \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} }
  }

Es wäre sehr einfach, eine Variante zu definieren, die ein zu erweiterndes Argument akzeptiert, wenn \__xparse_declare_cmd:Nnnes zu den öffentlichen Funktionen gehört, aber das ist nicht der Fall. Ohne gegen die Programmierkonventionen zu verstoßen, könnten Sie es selbst tun:

\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

und dann Ihre Syntax

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

würde funktionieren. Wofür das nützlich sein kann, weiß ich wirklich nicht.

verwandte Informationen