我正在开发一个包,它允许在特定命令和环境中输入 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}}
。