\write16
发送到终端,\message
也这样做。为什么有两个命令,在什么情况下必须使用每个命令?
答案1
以下是D.克努斯的话
不同于
‘\immediate\write16’
,\message
它将\write
文本单独打印在一行上;多个命令的结果\message
可能出现在同一行上,用空格分隔。
示例.tex
First page
\write16{** one **} \message{** two **}
\vfill\eject
Second page
\immediate\write16{** one W **}\immediate\write16{** two W **}
\message{** one M **}\message{** two M **}
\bye
样本日志节目
(sample.tex ** two ** [1{[....]/texmfs/data/pdftex/config/pdftex.map}
** one **
]
** one W **
** two W **
** one M ** ** two M ** [2] )
答案2
好吧,为了完整起见,另一个区别是 LuaTeX 支持超过 16 个流(它支持 128 个),因此与 不同\message
,\write16
实际上可能会写入一些分配该流的代码。
一些替代方案包括
- Lua 的
print()
\write128
,这在其他引擎中也有效\message
末尾带有 ^^J/任意 \newlinechar- LaTeX
\typeout
内部写入\@unused
流的命令。
注意,morewrites
包不触及流 16(它仅使用 0-15 和 19...)所以 16 仍然是安全的。
另一个区别,这个区别仅仅出于学术目的,那就是
\message
随着行进而扩展标记,类似于\csname … \endcsname
、\pdfescapestring
或\scantokens
。\edef
\write16
需要首先收集未展开的参数(如\def
或\toks0={…}
),然后完全展开它(\endwrite
后面放有token}
)需要写入时。\immediate\write16
也继承了这种行为。(它可以做不同的事情,但我认为这是为了实现简单)
因此,在这些情况下行为是不同的:
% given this.
\outer\def\someoutertoken{}
% then...
\message{123 \noexpand\someoutertoken} % works
%\immediate\write16{123 \noexpand\someoutertoken} % fails
\message{\iffalse}{\fi} % works
%\immediate\write16{\iffalse}{\fi} % fails, produces a "incomplete iffalse" error message just like "\iffalse\someoutertoken\fi"