如何将宏保存到未展开的文件中?

如何将宏保存到未展开的文件中?

我希望它能工作,但是它不行:

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

我希望在文件中看到以下内容foo.tex

Hello, \LaTeX!

如何让它工作?

答案1

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

虽然这里的实际问题是:\LaTeX命令是强壮的,但它是老式的稳健版本。因此,另一种解决方法(在这种情况下是相同的,但希望您能看出有什么区别)是

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

据我所知,没有\protected@write类似的东西。\immediate@protected@write

(或者你可以\protected@iwritehttps://tex.stackexchange.com/a/110885/250119

类似问题:通过 \immediate\write 存储环境参数

答案2

您可以使用expl3该作业,它还允许为您的文本变量提供一种命名空间。

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

写出的文件将包含

Hello, \LaTeX !

感叹号前的空格无需担心(它位于控制序列名称之后,因此会被 TeX 忽略)。

相关内容