olsak/OpTeX

expandability of a macro defined with \optdef

Closed this issue · 2 comments

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 :)

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.

Great, thanks!