将带有参数的命令定义写入文件

将带有参数的命令定义写入文件

我正在尝试创建一个命令,它可以将命令定义写入文件,同时定义它们。所以我想要一个\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}

这个想法是利用这个答案以防止#被扩展。现在的问题是,我想有选择地扩展它以实际定义命令。为此,我将命令写入一个临时文件,然后立即再次输入。一个更好的解决方案将非常受欢迎

相关内容