\write16 和 \message 之间有什么区别?

\write16 和 \message 之间有什么区别?

\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"

相关内容