我希望它能工作,但是它不行:
\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@iwrite
从https://tex.stackexchange.com/a/110885/250119。
答案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 忽略)。