0

I want this to work, but it doesn't:

\documentclass{article}
\begin{document}
\newcommand\hello{Hello, \LaTeX!}
\newwrite\foo
\immediate\openout\foo foo.tex
\immediate\write\foo{\hello}
\immediate\closeout\foo
\end{document}

I expect to see this in the foo.tex file:

Hello, \LaTeX!

How to make it work?

yegor256
  • 12,021

2 Answers2

3
\documentclass{article}
\begin{document}
\newcommand\hello{Hello, \LaTeX!}
\newwrite\foo
\immediate\openout\foo foo.tex
\immediate\write\foo{\unexpanded\expandafter{\hello}} % documentation of `\unexpanded` is in texdoc etex_man
%\immediate\write\foo{\detokenize\expandafter{\hello}} % this is an alternative, I believe it's slower than the above, although I didn't benchmark
\immediate\closeout\foo
\end{document}

although the actual issue here is: \LaTeX command is robust, but it's old-style robust. So an alternative fix (identical in this case but hopefully you can see what's the difference) is

\documentclass{article}
\begin{document}
\newcommand\hello{Hello, \LaTeX!}
\newwrite\foo
\immediate\openout\foo foo.tex
\makeatletter
\set@display@protect % see source2e...
\immediate\write\foo{\hello}
\restore@protect
\makeatother
\immediate\closeout\foo
\end{document}

there's \protected@write but no analogous \immediate@protected@write as far as I can see.

(or you can copy the \protected@iwrite from https://tex.stackexchange.com/a/110885/250119.

Similar question: Storing environment arguments by \immediate\write

user202729
  • 7,143
1

You can use expl3 for the job, which also allows to have a sort of namespace for your text variables.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\vardef}{mm} {% #1 = symbolic name, #2 = text \tl_clear_new:c { l_yegor_var_#1_tl } \tl_set:cn { l_yegor_var_#1_tl } { #2 } }

\NewDocumentCommand{\varwrite}{mm} {% #1 = symbolic name, #2 = file \iow_open:Nn \g_yegor_var_outfile_iow { #2 } \iow_now:Nv \g_yegor_var_outfile_iow { l_yegor_var_#1_tl } \iow_close:N \g_yegor_var_outfile_iow }

\NewExpandableDocumentCommand{\varuse}{m} { \tl_use:c { l_yegor_var_#1_tl } }

\iow_new:N \g_yegor_var_outfile_iow \cs_generate_variant:Nn \iow_now:Nn { Nv }

\ExplSyntaxOff

\begin{document}

\vardef{foo}{Hello, \LaTeX!}

\varwrite{foo}{\jobname.txt}

\end{document}

The file written out will contain

Hello, \LaTeX !

The space before the exclamation mark should be of no concern (it follows a control sequence name, so it will be ignored by TeX).

egreg
  • 1,121,712