expandability of a macro defined with \optdef
Closed this issue · 2 comments
Udi-Fogiel commented
the following code produce, IMO, undesired result
\optdef\foo[default] {\the\opt}
\foo[a]
\edef\bar{\foo[b]}
\bar
\bye
It can be fixed by adding \_immediateassigned
in the correct places in the definition of \optdef
:
\def\optdef#1[#2]{%
\_def#1{\_immediateassigned{\_opt={#2}}\_isnextchar[{\_cs{_oA:\_csstring#1}}{\_cs{_oB:\_csstring#1}}}%
\_sdef{_oA:\_csstring#1}[##1]{\_immediateassigned{\_opt={##1}}\_cs{_oB:\_csstring#1\_nospaceafter}}%
\_sdef{_oB:\_csstring#1\_nospaceafter}%
}
\optdef\foo[default] {\the\opt}
\foo[a]
\edef\bar{\foo[b]}
\bar
\bye
or by making the macro protected:
\def\optdef#1[#2]{%
\_protected\_def#1{\_opt={#2}\_isnextchar[{\_cs{_oA:\_csstring#1}}{\_cs{_oB:\_csstring#1}}}%
\_sdef{_oA:\_csstring#1}[##1]{\_opt={##1}\_cs{_oB:\_csstring#1\_nospaceafter}}%
\_sdef{_oB:\_csstring#1\_nospaceafter}%
}
\optdef\foo[default] {\the\opt}
\foo[a]
\edef\bar{\foo[b]}
\bar
\bye
or maybe simply mention in the documentation the expected output. Personally I like the first option, but it is not my call :)
olsak commented
The \isnextchar
macro was not originally expandable, but now it is. So, it makes sense now to create macros defined by \optdef
expandable. Thank you for noticing. I'll prepare a commit which modifies \optdef
using \immediateassigment
.
Udi-Fogiel commented
Great, thanks!