是否可以 \noexpand TeX 组而不是宏?

是否可以 \noexpand TeX 组而不是宏?

我经常发现自己需要一个\noexpand适用于 TeX 组而不是宏的实用程序。例如,在我当前的项目中,我有子程序:

% 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{}{}{}}

我需要这些,因为我用来绘制 TikZ 对象的代码被分为子程序,这些子程序以交错的方式将内容放置在多个 PGF 层上(例如,一个层上的框,另一个层上的阴影),不幸的是,每次\begin{pgfonlayer}{foolayer}使用环境时,它都会擦除foolayer先前写入的层中的任何内容。

我的解决办法是按照以下方式使用上述子程序:

\begin{tikzpicture}
   \addbox {Foo Box}
   \addbox {Bar Box}
   ...
   \begin{pgfonlayer}{boxlayer}
      \renderlayer
   \end{pgfonlayer}
\end{tikzpicture}

这种方法效果很好,但有一个突出的问题:如果 的参数\addbox包含诸如 之类的宏\ref,则必须手动\noexpand修改这些宏以避免出现错误,即

\addbox {Foo Box (section~\ref{sec:foo})}  % gives horrible cryptic LaTeX errors
\addbox {Foo Box (section~\noexpand\ref{sec:foo})}  % works like a charm

理想情况下,我希望避免这种情况,但我不知道有什么好办法。最明显的解决办法是,如果\noexpand可以对 TeX 组而不是宏起作用,但事实并非如此。使用

   \edef\drawboxcode{
      {\noexpand\draw (...) node[
         draw,
         fill,
         ...] {\noexpand{#1}};
      }
   }

例如,什么都不做。我也不能使用

   \def\drawboxcontent{#1}
   \edef\drawboxcode{
      {\noexpand\draw (...) node[
         draw,
         fill,
         ...] {\noexpand\drawboxcontent};
      }
   }

因为当\drawboxcontent最终展开时\renderlayer,宏将只包含最后添加的框的内容。

这只是一个例子,说明防止\edef扩展代码块(即 TeX 组)而不是宏的实用程序非常有用。

一个替代方案是允许如下代码的实用程序

   \passbyvaluedef\drawboxcontent{#1}
   \edef\drawboxcode{
      {\noexpand\draw (...) node[
         draw,
         fill,
         ...] {\drawboxcontent};
      }
   }

其中\passbyvaluedef将定义一个宏\drawboxcontent,当展开时,它将展开为一些唯一的命令序列\drawboxcontentaaaa 无需进一步扩大,并将\drawboxcontentaaaa包含 中的所有内容#1。下一次\passbyvaluedef\drawboxcontent调用 时,\drawboxcontent将扩展为\drawboxcontentaaab,依此类推,在每种情况下都返回唯一的 CS 名称。这不如基于组的 优雅\noexpand,但它也能完成工作。

是否有任何 TeX/LaTeX 宏/包可以执行上述任何一项操作(有效地\noexpand-ing 组,或建议的替代方法)?如果没有,是否有其他方法可以解决必须手动将 s 包含在我的框内容中的问题\noexpand,还是我只能使用它们?

答案1

您可以使用\unexpanded{<balanced text>}。这将避免在 中的扩展<balanced text>

相关内容