隐藏宏的输出

隐藏宏的输出

有没有办法让宏隐藏其输出但仍然使用计数器等执行逻辑?

我被困在下面的宏的定义上\dontoutput

% \documentclass, \usepackage, ...

\newcount\innercount

\def\dontoutput#1{#1} % ???

\long\def\inner#1{\advance\innercount 1\relax}

\long\def\outer#1{
  \innercount 0\relax
  \dontoutput{#1}    % call it, increment counters in \inner, but don't output anything!
  Inner called \the\innercount times.
  \def\inner##1{##1} % we want to output it too now.
  #1                 % call again
}

\begin{document}
  \outer{
    a
    \inner{b}
    \inner{c}
    \inner{d}
    e
  }
\end{document}

% Outputs:  a e Inner called 3 times. abcde
% I'd like:     Inner called 3 times. abcde

答案1

\newcounter{inner}
\def\inner#1{#1}
\def\outer#1{%
  {\sbox0{\setcounter{inner}{0}\def\inner##1{\stepcounter{inner}}#1}}%
  Inner called \theinner\ times. #1}

LaTeX 计数器上的命令是全局起作用的;因此,我们在一个框中排版了 的参数,\outer在该框中我们将计数器设置为零,并定义\inner来步进计数器。 的默认定义\inner(在框外恢复)是排版其参数。

根据 Martin 的建议,我还将箱子分配放在一个组中,以提高安全性。该命令\sbox构建一个箱子并将其保存到存储箱中,但不会在文档中排版任何内容。但是,所有命令都会执行,特别是我们可以重新定义\inner为具有不同的含义,因为当我们输入箱子构造时,会打开另一个组。操作周围的组\sbox确保存储箱将在组的末尾被遗忘。

通常人们会写

\newsavebox{\mybox}

在序言中,然后\sbox{\mybox}{...}为了在\usebox{\mybox}其他地方;但是,\mybox仅指某个内部数字,而数字 0、2、4、6 和 8 则保留用于“刮擦盒”,人们可以自由地将它们用于诸如当前的目的。

答案2

您可以将内容存储到未使用的盒子中,正如 egreg 已经展示的那样。

您还可以使用\nullfont来关闭任何文本输出。但是,据我所知,段落仍然插入,因此\let\par\relax也很有用。最后,您想禁用任何命令再次切换到真实字体,因此也\let\selectfont\relax应该添加。要么将它们放在一个组中,要么保存并恢复原始定义(先保存\let\origfoo\foo,然后保存)。在后一种情况下,您应该在恢复后\let\foo\origfoo使用。\normalfont\selectfont

通常我猜使用盒子是更好的选择。

相关内容