如何将宏的参数视为文字或逐字文本?

如何将宏的参数视为文字或逐字文本?

我正在开发一个包,它允许在特定命令和环境中输入 Python 代码,将 Python 代码保存到外部文件并执行它,然后通过 返回结果\input。类似于 SympyTeX 和 SageTeX,但具有附加功能。

举一个简单的例子,\pylab{print 1+1}将文本字符串保存print 1+1到一个文件中,Python 执行这个文件以获取2并将其保存在第二个文件中,然后使用将第二个文件带回到原始文档中\input

这是一个最小的例子。(在第一次运行后,在运行 Python 创建 infile.tex 之前,它会给出错误。)

\newcommand{\pylab}[1]{
    \newwrite\outputstream
    \immediate\openout\outputstream=outfile.py
    \immediate\write\outputstream{#1}
    \immediate\closeout\outputstream
    \input{infile.tex}
}

问题是,在更复杂的情况下,的参数\pylab可能包含特殊字符,例如\pylab{print 3%2}(模数运算符)。处理这个问题的最佳方法是什么?理想情况下,我的命令应该像 一样\verb,这样它就可以接受除 * 之外的任何字符作为开关,以便能够绕过几乎所有特殊代码字符。我一直在阅读有关 verbatim、catcodes、\gdef等的文章,但我还没有能够用它们取得任何进展。

SympyTeX 和 SageTeX 的使用

\catcode`\%=12
\newcommand{\percent}{%}
\catcode`\%=14

定义 % 的替代品,但如果可能的话,我想避免这种方法,因为这意味着我不能直接粘贴有效的 Python 代码。

答案1

您可以使用以下方法逐字读取参数。但是,这保持{正常},因此它们需要在参数内部匹配。

\documentclass{article}

\makeatletter
\newwrite\@pyout
\newcommand{\pylab}{%
    \begingroup
    % deactivate special characters
    \let\do\@makeother
    \dospecials
    % change '{' and '}' back to normal
    \catcode`\{=1
    \catcode`\}=2
    \@pylab
}
\def\@pylab#1{%
    \endgroup
    \immediate\openout\@pyout=\jobname.py
    \immediate\write\@pyout{#1}%
    \immediate\closeout\@pyout
    \immediate\write18{python \jobname.py > \jobname-py.tex}%
    \input{\jobname-py}%
}

\makeatother


\begin{document}

\pylab{print 3%2}

\end{document}

\verb如果您想要使用以下受实际代码启发的代码的行为\verb

\documentclass{article}

\makeatletter

\newwrite\@pyout

\newcommand{\pylab}[1]{%
    \begingroup
    \verb@eol@error
    \let\do\@makeother
    \dospecials
    \catcode`#1\active
    \lccode`\~`#1%
    \lowercase{\def\@@pylab##1~}{\endgroup\@pylab{##1}}%
    \@@pylab
}

\def\@pylab#1{%
    \immediate\openout\@pyout=\jobname.py
    \immediate\write\@pyout{#1}%
    \immediate\closeout\@pyout
    \immediate\write18{python \jobname.py > \jobname-py.tex}%
    \input{\jobname-py}%
}

\makeatother

\begin{document}

\pylab|print 3%2|

\end{document}

更新:

使用我的软件包的新版本 2011/07/23,newverbs您可以将\pylab宏简化为\newcommand{\pylab}{\begingroup\Collectverb{\@pylab}}

相关内容