NewDocumentCommand с спецификаторами аргументов, сохраненными в макросе

NewDocumentCommand с спецификаторами аргументов, сохраненными в макросе

Я пытаюсь написать несколько макросов, которые в свою очередь автоматически генерируют другие макросы в зависимости от опций и т. д.

Интересно, можно ли использовать \NewDocumentCommand{\somename}{\standardargs}, т. е. сам список аргументов «скрыть» в макросе.

Вот нерабочий, короткий пример (естественно, ненужные накладные расходы удалены)

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

Сообщение об ошибке:

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

Некоторые заметки

  • Я почти уверен, что это какая-то проблема расширения.
  • яявляюсьосознавая, что мне, возможно, придется использовать более сложный подход, чтобы сохранить {}скобки в качестве необязательных спецификаторов значений по умолчанию для \NewDocumentCommand.
  • Использование/пригодность такого стандартного списка аргументов может быть сомнительной, я с этим согласен.

решение1

Да, разверните макрос перед \NewDocumentCommandпопыткой получить второй аргумент (определение макроса):

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

решение2

l3 позволяет вам избегать\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}

решение3

Это именно проблема расширения. Вот определение \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} }
  }

Было бы очень легко определить вариацию, которая принимает аргумент для расширения, если бы \__xparse_declare_cmd:Nnnбыла среди публичных функций, но это не так. Не нарушая соглашений программирования, вы можете сделать это самостоятельно:

\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

и затем ваш синтаксис

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

будет работать. Для чего это может быть полезно, я действительно не знаю.

Связанный контент