我已经定义了一个带有可选参数的 LaTeX 命令,例如,\newcommand*{\commA}[1][opt]{A#1}
并且我无法让它成为带有的扩展命令定义的一部分\edef
,例如\edef\expcom{\commA}
。
我尝试了不同的组合来找出问题所在:首先,如果我定义命令时\commA
不带可选参数,代码就可以顺利编译。其次,如果我保留\commA
带有可选参数的定义,但使用\expcom
来定义\def
,代码也可以顺利编译。因此,只有 的组合可选参数定义和\edef
它是有缺陷的。
如何将带有可选参数的命令传递给\edef
定义?
查看错误代码示例
\documentclass{article}
\begin{document}
%\newcommand*{\commA}{A} %This definition gives no error
\newcommand*{\commA}[1][opt]{A#1} %This definition raises error "! Argument of \reserved@a has an extra }."
\edef\expcomm{\commA}
%\def\expcomm{\commA} %The definition with \def gives no error
\def\noexpcomm{\commA}
\noindent
This is \verb|\expcomm|: \expcomm\\
This is \verb|\noexpcomm|; \noexpcomm\\
\renewcommand*{\commA}{B}
\noindent
This is \verb|\expcomm|: \expcomm\\
This is \verb|\noexpcomm|; \noexpcomm\\
\end{document}
当我使用\commA
不带可选参数的定义时,我得到以下结果,正如预期的那样:
答案1
您可以获得带有可选参数的可扩展命令
- 可选参数后面跟着一个强制参数;
- 你使用
\NewExpandableDocumentCommand
。(对于2020-10-01 之前的 LaTeX 版本包括xparse
包裹)
因此
\NewExpandableDocumentCommand{\commA}{O{opt}m}{A#1}
你可以打电话
\edef\expcommA{\commA{}}
\edef\expcommB{\commA[new]{}}
注意虚拟强制参数。
完整测试文档:
\documentclass{article}
\NewExpandableDocumentCommand{\commA}{O{opt}m}{A#1}
\begin{document}
\edef\expcommA{\commA{}}
\edef\expcommB{\commA[new]{}}
\texttt{\meaning\expcommA}
\texttt{\meaning\expcommB}
\end{document}
我相信这是一个典型的XY问题, 尽管。
答案2
如果\commA
在期间没有被其替换文本替换,则\edef
可以使用\protected@edef
扩展来\commA
抑制扩展,同时扩展形成其可选参数的标记(如果提供)。
\documentclass{article}
\begin{document}
\newcommand*{\commA}[1][opt]{A#1} %This definition raises error "! Argument of \reserved@a has an extra }."
\csname protected@edef\endcsname\expcomm{\commA}
\noindent This is \verb|\expcomm|: \texttt{\meaning\expcomm}
\newcommand\foobar{expansion of \string\foobar}
\csname protected@edef\endcsname\expcommOptionalArgExpanded{\commA[\foobar]}
\noindent This is \verb|\expcommOptionalArgExpanded|: \texttt{\meaning\expcommOptionalArgExpanded}
\end{document}
但在您的情况下,这似乎很重要,因为在您的问题中,您已经\commA
在示例中间的某个地方重新定义了......