\write16
sends to terminal, \message
also does this. Why there are two commands for this and in which cases each one must be used?
2 Answers
Here's in D. Knuth's words
An
‘\immediate\write16’
differs from\message
in that\write
prints the text on a line by itself; the results of several\message
commands might appear on the same line, separated by spaces.
Sample.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.log shows
(sample.tex ** two ** [1{[....]/texmfs/data/pdftex/config/pdftex.map}
** one **
]
** one W **
** two W **
** one M ** ** two M ** [2] )
Well, for the sake of completeness, another difference is that LuaTeX supports more than 16 streams (it supports 128), therefore unlike \message
, \write16
might actually write to some code that allocates that stream.
Some alternatives include
- Lua's
print()
\write128
, which is also valid in other engines\message
with ^^J/whatever \newlinechar is at the end- LaTeX's
\typeout
command which internally writes to the\@unused
stream.
Remark, morewrites
package does not touch stream 16 (it only uses 0-15 and 19...) so 16 is still safe.
Another difference, this one only for academical purpose, is that
\message
expands tokens as it goes, similar to\csname … \endcsname
,\pdfescapestring
,\scantokens
or\edef
.\write16
needs to first collect the arguments unexpanded (like\def
or\toks0={…}
), then fully expand it (with an\endwrite
token put after the}
) when it needs to be written.\immediate\write16
inherits this behavior as well. (it could do differently, but I assume this is for implementation simplicity)
Consequently, in these cases the behavior is different:
% 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"
\message
like\immediate\write
but there is an other difference that's each write start a new line and\message
don't