我觉得我应该知道这一点,但遗憾的是我不知道。为什么 的输出 \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
如果令牌突然扩展,它还会扰乱其他用法。