我正在尝试创建一个命令,它可以将命令定义写入文件,同时定义它们。所以我想要一个\teecommand
接受一个参数的命令。这个参数应该按原样写入文件,并进行扩展。
我目前的尝试是:
\documentclass{memoir}
\newwrite\commandsfile
\immediate\openout\commandsfile=commands.tex
\DeclareDocumentCommand\teecommand{s m}{%
\write\commandsfile{\unexpanded{#2}}%
\IfBooleanTF{#1}{}{#2} % Only expand the command if no * is given
}
\teecommand{\newcommand{\foo}{this is foo}}
\teecommand{\newcommand{\foobar}[1]{this is bar: #1}}
\begin{document}
\foo\\
\foobar{123}
\end{document}
commands.tex
还会创建文件,其内容如下:
\newcommand {\foo }{this is foo}
\newcommand {\foobar }[1]{this is bar: ##1}
第一行符合预期,但第二行出现了重复的#
。不幸的是,这导致应用程序无法解析.tex
文件(来自 MathJax 的基于公式预览器的LaTeX 工作坊)。
问题: 我如何修复命令,以便用而不是参数占位符\teecommand
给出正确的输出?#1
##1
笔记:memoir
我在上面的例子中使用它是因为这是我在实际文档中需要使用的,并且我想避免出现与它不兼容的解决方案。
答案1
#
您可以使用相同的字符但类别代码为“其他”进行正则表达式替换。
\documentclass{memoir}
\ExplSyntaxOn
\iow_new:N \g_lukas_teecommand_iow
\iow_open:Nn \g_lukas_teecommand_iow { \c_sys_jobname_str.cmd }
\NewDocumentCommand\teecommand{s m}
{
\tl_set:Nn \l_tmpa_tl { #2 }
\regex_replace_all:nnN { \cP\# } { \cO\# } \l_tmpa_tl
\iow_now:NV \g_lukas_teecommand_iow \l_tmpa_tl
\IfBooleanT{#1}{#2} % Only expand the command if no * is given
}
\cs_generate_variant:Nn \iow_now:Nn { NV }
\ExplSyntaxOff
\teecommand{\newcommand{\foo}{this is foo}}
\teecommand{\newcommand{\foobar}[1]{this is bar: #1}}
\teecommand{\newcommand{\fooagain}[2]{this is again: #1 and #2}}
\stop
写入文件的内容(我更改了名称以免破坏我的文件):
\newcommand {\foo }{this is foo}
\newcommand {\foobar }[1]{this is bar: #1}
\newcommand {\fooagain }[2]{this is again: #1 and #2}
答案2
我终于找到了一个解决方案,尽管不太好(如果您能想到一个不需要临时文件的更好的解决方案,请告诉我):
\documentclass{memoir}
\newwrite\commandsfile
\immediate\openout\commandsfile=commands.tex
\makeatletter
\newwrite\commandtempfile
\newcommand{\teecommand}{\begingroup\catcode`\#=12\relax\@teecommand}
\DeclareDocumentCommand\@teecommand{s m}{%
\endgroup%
\write\commandsfile{\unexpanded{#2}}%
\IfBooleanTF{#1}{}{%
\immediate\openout\commandtempfile=currentcommand.tmp%
\immediate\write\commandtempfile{\unexpanded{#2}}%
\immediate\closeout\commandtempfile%
\input{currentcommand.tmp}
}
}
\makeatother
\teecommand{\newcommand{\foo}{this is foo}}
\teecommand{\newcommand{\foobar}[1]{this is bar: #1}}
\begin{document}
\foo\\
\foobar{123}
\end{document}
这个想法是利用这个答案以防止#
被扩展。现在的问题是,我想有选择地扩展它以实际定义命令。为此,我将命令写入一个临时文件,然后立即再次输入。一个更好的解决方案将非常受欢迎