Someone who is more familiar with Lua will almost certainly have better ideas...
egreg's idea from the comments makes things slightly easier: consider using the [[...]]
string syntax so you don't need to escape the string (but there will still be issues if the string itself contains a ]]
etc), and use eTeX's \unexpanded
so you don't need to worry so much about putting \noexpand
everywhere. See also some of the suggestions about \directlua
on a different question.
As I previously mentioned in a comment, bypassing/emulating the LaTeX commands for this is probably not a good idea. LaTeX's commands for this are slightly more complicated than you might first think, and might get patched/hooked into. Even rewriting LaTeX in Lua (replacing eg \PackageWarning
with something that invokes a Lua script/function) wouldn't necessarily help in the latter situation.
I think the best you could do would be to write your own Lua function that invokes LaTeX's \PackageWarning
, taking care to escape parameters etc as appropriate. (Sorry, I'm not proficient enough to attempt that.)
Compare the terminal output from the following:
\documentclass{article}
\PackageWarningNoLine{mypackage}{Hello, I am a warning}
\PackageWarning{mypackage}{Hello, I am a warning}
\directlua{
texio.write_nl("term and log", [[\unexpanded{Package mypackage Warning: Hello, I am a warning.}]]);
tex.print([[\unexpanded{\PackageWarning{mypackage}{Hello, I am a warning}}]]);
}
\begin{document}
\end{document}
I have used "term and log"
here because (as egreg explained), LaTeX normally writes to an \@unused
stream that is never open, so the output appears both on the terminal and in the log file.
The output is
Package mypackage Warning: Hello, I am a warning.
Package mypackage Warning: Hello, I am a warning on input line 3.
Package mypackage Warning: Hello, I am a warning.
Package mypackage Warning: Hello, I am a warning on input line 1.
Note also that the line numbers from the Lua version are wrong, even when the real \PackageWarning
command is invoked.
For reference, some relevant definitions from latex.ltx
:
\def\set@display@protect{\let\protect\string}
\def\@spaces{\space\space\space\space}
\ifnum\inputlineno=\m@ne
\let\on@line\@empty
\else
\def\on@line{ on input line \the\inputlineno}
\fi
\DeclareRobustCommand{\GenericWarning}[2]{%
\begingroup
\def\MessageBreak{^^J#1}%
\set@display@protect
\immediate\write\@unused{^^J#2\on@line.^^J}%
\endgroup
}
\def\PackageWarning#1#2{%
\GenericWarning{%
(#1)\@spaces\@spaces\@spaces\@spaces
}{%
Package #1 Warning: #2%
}%
}
\def\PackageWarningNoLine#1#2{%
\PackageWarning{#1}{#2\@gobble}%
}
tex.print("\noexpand\\PackageWarning{pack}{Text}")
seems easier.tex.print([[\unexpanded{\PackageWarning{pack}{Text}}]])
so that macros inText
will be expanded only on the TeX side.\write
on an output string that is never open, so by rule the contents is written both to the terminal and in the log file.tex.iowrite
? My knowledge of Lua is rather primitive, so I can't see if and how it could help.