4

As pointed out by the following MCE, \TeX and \LaTeX are expl3-written to an auxiliary file:

  • the same way when no manipulation is involved (\iow_now:Nn) (but that is useless for my real use case):

    \LaTeX {}
    \TeX {}
    
  • differently when exhaustive expansion is involved (\iow_now:Nx):

    \protect \LaTeX  {}
    T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\@{}
    

Why this difference and how to get \protect \TeX {} instead of T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\@{}?

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\iow_new:N \g_output_stream

\iow_open:Nn \g_output_stream { \c_sys_jobname_str.sbj }
\iow_now:Nn \g_output_stream { \LaTeX{} }
\iow_now:Nn \g_output_stream { \TeX{} }
\iow_now:Nx \g_output_stream { \exp_not:V\LaTeX{} }
\iow_now:Nx \g_output_stream { \exp_not:V\TeX{} }
\iow_close:N \g_output_stream

\ExplSyntaxOff

\begin{document}
\end{document}
1
  • You surely don't want \exp_not:V, but rather \exp_not:N. – egreg May 10 '19 at 10:52
4

If we do \show\TeX, the result is

\TeX=macro:
->T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\@.

On the other hand, the result of \show\LaTeX is

   > \LaTeX=macro:
   ->\protect \LaTeX  .

Now \LaTeX is defined in latex.ltx using \DeclareRobustCommand, and as @egreg has pointed out, \MakeRobust can protect an existing macro in the same way.

\documentclass{article}
\MakeRobust{\TeX}

\usepackage{xparse}

\ExplSyntaxOn

\iow_new:N \g_output_stream

\iow_open:Nn \g_output_stream { \c_sys_jobname_str.sbj }
\iow_now:Nn \g_output_stream { \LaTeX{} }
\iow_now:Nn \g_output_stream { \TeX{} }
\iow_now:Nx \g_output_stream { \exp_not:V\LaTeX{} }
\iow_now:Nx \g_output_stream { \exp_not:V\TeX{} }
\iow_close:N \g_output_stream

\ExplSyntaxOff

\begin{document}
\end{document}
3
  • 3
    \MakeRobust{\TeX} is the correct way to do the same thing. – egreg May 10 '19 at 10:51
  • Thanks, @egreg. I have updated the answer. – Ian Thompson May 10 '19 at 11:31
  • Too bad \TeX and friends are not defined in latex.ltx using \DeclareRobustCommand. – Denis Bitouzé May 10 '19 at 12:35
5

You don't want \exp_not:V, but rather \exp_not:N

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\iow_new:N \g_output_stream

\iow_open:Nn \g_output_stream { \c_sys_jobname_str.sbj }
\iow_now:Nn \g_output_stream { \LaTeX{} }
\iow_now:Nn \g_output_stream { \TeX{} }
\iow_now:Nx \g_output_stream { \exp_not:N \LaTeX{} }
\iow_now:Nx \g_output_stream { \exp_not:N \TeX{} }
\iow_close:N \g_output_stream

\ExplSyntaxOff

\begin{document}
\end{document}

The auxiliary file will have

\LaTeX {}
\TeX {}
\LaTeX {}
\TeX {}

What's the difference? In this case \exp_not:V does a one step expansion, which is not desired here, because \LaTeX and \TeX are not variables, but parameterless functions. Recall that V stands for variable and is used to get its value, not subject to further expansion.

1
  • I should have mentioned that what is written to the auxiliary file is in fact (only) the replacement text (that may contain \TeX) of a token list. Hence, if I'm right, \exp_not:N is useless in my use case: I asked this new question in order to explain why and a bit further my aim. – Denis Bitouzé May 10 '19 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.