使用 \typeout 的行为与 \newtoks 和 \def 不同

使用 \typeout 的行为与 \newtoks 和 \def 不同

我觉得我应该知道这一点,但遗憾的是我不知道。为什么 的输出 \typeout{\the\myToken}与 打印在 PDF 中不一样\the\myToken。 没有问题\def,只是通过 声明了一些东西\newtoks

PDF显示:

在此处输入图片描述

但控制台显示

默认值=1-9

MyToken=\DefaultValue

扩展问题?嗯,我也是这么想的,但应该\expandafter\typeout{\the\myToken}能行得通吧?

问题:

  • 为什么会发生这种情况?
  • 我如何定义\MyTypeout{}(或者最好重新定义 \typeout{}) 宏,以便在控制台中输出实际的当前扩展值,就像在 PDF 中显示的那样。

代码:

\documentclass{article}

\newtoks\myToken

\edef\CurrentValue{1-9}
\edef\DefaultValue{\CurrentValue}
\myToken={\DefaultValue}

\begin{document}
\typeout{DefaultValue=\DefaultValue}  DefaultValue=\DefaultValue

\typeout{MyToken=\the\myToken}        MyToken=\the\myToken
\end{document}

答案1

在排版环境中,表达式\the\myToken在 TeX 的肚子里完全展开并排版。因此预期结果是1-9

\typeout定义在latex.ltx

\def\typeout#1{%
  \begingroup
    \set@display@protect
    \immediate\write\@unused{#1}%
  \endgroup
}

在这个上下文中(\immediate\write)表达式\the<token register>被扩展一次,但是标记寄存器的内容不会进一步扩展。

摘自《The TeXbook》,《第 20 章:定义(又名宏)》:

\edef用或进行的扩展定义\xdef继续扩展标记,直到只剩下不可扩展的标记,但由生成的标记列表\the不会进一步扩展。

\immediate\write不是\edef\xdef,因此我们还需要:

TeX 的原始命令\mark{...}\message{...}\errmessage{...}\special{...}和都几乎像和一样\write<number>{...}扩展了括号中的标记列表 。但是,像这样的宏参数字符不应该在这样的命令中重复;[...]\edef\xdef#

例子:

\edef\x{\the\myToken}
\show\x
> \x=macro:
->\DefaultValue .

\edef\x{\x}
\show\x
> \x=macro:
->1-9.

因此,您需要触发扩展两次才能扩展令牌寄存器的内容。

标记寄存器可用于模拟 eTeX \unexpanded(尽管构造不可扩展,\unexpanded但可扩展)。例如,这在\g@addto@macro( latex.ltx) 中用于将第二个参数中的一些标记添加到第一个参数中的宏中:

\toksdef\toks@=0
\long\def\g@addto@macro#1#2{%
  \begingroup
    \toks@\expandafter{#1#2}%
    \xdef#1{\the\toks@}%
  \endgroup
}

#1被展开一次,结果被放入一个标记寄存器,其中包含附加的标记#2。下面\xdef使用其原始定义文本和附加的标记来定义宏#2

内部扩展令牌寄存器\typeout

如果两次触碰令牌寄存器,其内容将失去其不可扩展的行为:

\makeatletter
\newcommand*{\exptok}[1]{%
  \expandafter\@firstofone\expandafter{\the#1}%
}
\makeatother

\typeout{\exptok\myToken}

\typeout不应重新定义,如果将其扩展,令牌寄存器的内容可能包含中断的内容(未定义的命令、无限递归等)。此外,\typeout如果令牌突然扩展,它还会扰乱其他用法。

相关内容