TransWikia.com

Is it possible to noexpand a TeX group instead of a macro?

TeX - LaTeX Asked by COTO on March 26, 2021

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
newcommandaddbox[1] {
   edefdrawboxcode{
      {noexpanddraw (...) node[
         draw,
         fill,
         ...] {#1};
      }
   }
   expandafteraddcodetolayerdrawboxcode
}

% pushes object code onto layer
newcommandaddcodetolayer[1]
    {seq_gput_right:Nnsq__layercmds{#1}}

% renders layer
newcommandrenderlayer
    {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~noexpandref{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

   edefdrawboxcode{
      {noexpanddraw (...) node[
         draw,
         fill,
         ...] {noexpand{#1}};
      }
   }

does nothing, for instance. I also can’t use

   defdrawboxcontent{#1}
   edefdrawboxcode{
      {noexpanddraw (...) node[
         draw,
         fill,
         ...] {noexpanddrawboxcontent};
      }
   }

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

   passbyvaluedefdrawboxcontent{#1}
   edefdrawboxcode{
      {noexpanddraw (...) 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 passbyvaluedefdrawboxcontent 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 noexpands in my box contents, or am I stuck with them?

One Answer

You can use unexpanded{<balanced text>}. This will avoid the expansion in the <balanced text>.

Correct answer by Ulrike Fischer on March 26, 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