I often find myself in need of a \noexpand
utility that works on a TeX group rather than a macro. For example, in my current project, I have subroutines:
% adds a box to the layer
\newcommand\addbox[1] {
\edef\drawboxcode{
{\noexpand\draw (...) node[
draw,
fill,
...] {#1};
}
}
\expandafter\addcodetolayer\drawboxcode
}
% pushes object code onto layer
\newcommand\addcodetolayer[1]
{\seq_gput_right:Nn\sq__layercmds{#1}}
% renders layer
\newcommand\renderlayer
{\seq_use:Nnnn \sq__layercmds{}{}{}}
I require these because the code I use to draw TikZ objects is divided into subroutines that place content on multiple PGF layers (e.g. a box on one layer, a shadow on another layer) in an interleaved way and, unfortunately, every time the \begin{pgfonlayer}{foolayer}
environment is used, it wipes out any content in the foolayer
layer previously written.
My recourse has been to use the subroutines above in the following way:
\begin{tikzpicture}
\addbox {Foo Box}
\addbox {Bar Box}
...
\begin{pgfonlayer}{boxlayer}
\renderlayer
\end{pgfonlayer}
\end{tikzpicture}
This works well but has one outstanding problem: the argument to \addbox
, if it contains macros such as \ref
, must have these manually \noexpand
-ed to avoid errors, i.e.
\addbox {Foo Box (section~\ref{sec:foo})} % gives horrible cryptic LaTeX errors
\addbox {Foo Box (section~\noexpand\ref{sec:foo})} % works like a charm
Ideally I would like to avoid this, but I know of no good way to do it. The most obvious fix would be if \noexpand
could work on TeX groups rather than macros, but it doesn't. Using
\edef\drawboxcode{
{\noexpand\draw (...) node[
draw,
fill,
...] {\noexpand{#1}};
}
}
does nothing, for instance. I also can't use
\def\drawboxcontent{#1}
\edef\drawboxcode{
{\noexpand\draw (...) node[
draw,
fill,
...] {\noexpand\drawboxcontent};
}
}
because when \drawboxcontent
is finally expanded in \renderlayer
, the macro will only contain the content of the last added box.
This is just one example of where a utility that prevents \edef
from expanding a block of code (i.e. TeX group) rather than a macro would be extremely useful.
One alternative would be a utility that allowed code such as
\passbyvaluedef\drawboxcontent{#1}
\edef\drawboxcode{
{\noexpand\draw (...) node[
draw,
fill,
...] {\drawboxcontent};
}
}
where \passbyvaluedef
would define a macro \drawboxcontent
that, when expanded, would expand into some unique command sequence \drawboxcontentaaaa
without expanding further, and \drawboxcontentaaaa
would contain whatever was in #1
. The next time \passbyvaluedef\drawboxcontent
was called, \drawboxcontent
would expand into \drawboxcontentaaab
, and so on, returning a unique CS name in each case. This is less elegant than a group-based \noexpand
, but it would also get the job done.
Are there any TeX/LaTeX macros/packages for doing either of these things (effectively \noexpand
-ing groups, or the suggested alternative)? If not, is there another way to solve the problem of having to manually include \noexpand
s in my box contents, or am I stuck with them?
unexpanded
's behavior is like\the\toks0
instead of like\noexpand
each token, which is the same inside an\edef
(which is the case here) but might be different in other cases e.g. tex core - Why is \unexpanded not respected after an \if? - TeX - LaTeX Stack Exchange.