TransWikia.com

Expanding command with optional arguments: edef

TeX - LaTeX Asked by loved.by.Jesus on July 19, 2021

I have defined a LaTeX command with an optional argument, e.g., newcommand*{commA}[1][opt]{A#1}, and I cannot get it to be part of an expanded command defintion with edef, e.g., edefexpcom{commA}.

I have tried different combinations to find out what is going on: first, if I define the command commA without optional arguments, the code compiles smoothly. Second, if I leave commA definition with optional arguments, but I define expcom with def, the code compiles smoothly, too. Thus, It is only the combination of optional argument definition and edef that it is faulty.

How can I pass a command with optional arguments to a edef definition?

See example of buggy code

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 }."

edefexpcomm{commA}
%defexpcomm{commA} %The definition with def gives no error
defnoexpcomm{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}

The output I would expect with the commA definition with optional argument is following:
enter image description here

When I use the commA definition without optional argument I get following, as expected:

enter image description here

2 Answers

You can get an expandable command with optional arguments provided

  1. the optional arguments are followed by a mandatory one;
  2. you use NewExpandableDocumentCommand. (For LaTeX release before 2020-10-01 include the xparse package)

So with

NewExpandableDocumentCommand{commA}{O{opt}m}{A#1}

you can call

edefexpcommA{commA{}}
edefexpcommB{commA[new]{}}

Note the dummy mandatory argument.

Full test document:

documentclass{article}

NewExpandableDocumentCommand{commA}{O{opt}m}{A#1}

begin{document}

edefexpcommA{commA{}}
edefexpcommB{commA[new]{}}

texttt{meaningexpcommA}

texttt{meaningexpcommB}

end{document}

enter image description here

I believe this is a typical XY problem, though.

Correct answer by egreg on July 19, 2021

In case it doesn't matter if commA is not replaced by its replacement-text during the edef you can use protected@edef for having expanding commA suppressed while having the tokens forming its optional argument expanded if provided.

documentclass{article}

begin{document}

newcommand*{commA}[1][opt]{A#1} %This definition raises error "! Argument of reserved@a has an extra }."

csname protected@edefendcsnameexpcomm{commA}

noindent This is verb|expcomm|: texttt{meaningexpcomm}

newcommandfoobar{expansion of stringfoobar}
csname protected@edefendcsnameexpcommOptionalArgExpanded{commA[foobar]}

noindent This is verb|expcommOptionalArgExpanded|: texttt{meaningexpcommOptionalArgExpanded}

end{document}

enter image description here

But in your case it seems to matter as in your question you have commA redefined somewhere in the middle of your example...

Answered by Ulrich Diez on July 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP