我在尝试启动并运行一段代码时遇到了一些问题。我正在扩展 python.sty 文件,以便将 python 嵌入到 LaTex 文档中(添加持久数据和将 LaTex 命令的结果传递给 Python 的能力)。从高层次上讲,此样式文件提供的功能可让您执行以下操作:
\begin{python}
print r"Raw output, goes right into the Tex file."
\end{python}
我正在寻找一个简单的函数,允许将数据从 Tex/Latex 传递到该 Python 代码的主体,但我遇到了真正的脆弱性问题。愚蠢的是,我以为以下方法可以奏效:
\xdef\internalSetPythonVariable#1#2{\PythonPersistenceInternalName["#1"] = r"#2"}
\xdef\setPythonVariable#1#2{\begin{python}\internalSetPythonVariable{#1}{#2}\end{python}}
显然,这种方法行不通,因为 Python 环境会干扰里面的所有命令 - 所以这种方法不行。但我想,“好吧,我只要确保在我们启动那个愚蠢的环境时 Python 环境中的内容都是文本就行了。”所以我尝试了以下方法:
\xdef\internalSetPythonVariable#1#2{\PythonPersistenceInternalName["#1"] = r"#2"}
\xdef\setPythonVariable#1#2{\expandafter\begin{python}\internalSetPythonVariable{#1}{#2}\end{python}}
但是 expandafter 似乎不想处理 \begin 的内容,现在我有点卡住了。我一直收到非常有用的“!\reserved@a 的参数有一个额外的 }”错误。总的来说,我认为这在概念上是一个相当简单的问题:我希望能够在环境启动之前将环境中的所有内容评估为文本。
需要注意的是,似乎没有太多其他方法可以实现这一点。当环境全面运行时,它会将所有内容视为纯文本(没有宏,什么都没有)。此外,由于我使用这些函数来读取/写入变量,所以我需要它们是接受参数的单行代码。而且,为了这个目的而必须创建一个接受可选参数的全新环境似乎相当愚蠢。
那么,有人知道如何在事情开始之前完全展开这些参数吗?我尝试过疯狂地摆弄它,但一无所获。话虽如此,如果我能做到这一点 - 我希望避免再次使用 TeX 做平凡的垃圾(参见:条件、循环、非排版宏)。
答案1
您需要确保\begin
和\end
宏未在 中展开\xdef
。您需要使用\noexpand
not\expandafter
来实现这一点。后者仅影响展开的顺序。
\xdef\setPythonVariable#1#2{\noexpand\begin{python}\internalSetPythonVariable{#1}{#2}\noexpand\end{python}}
答案2
我可以提出的一个对我有用的解决方案是使用一些我基本上视为临时变量的命令来传递所需的信息。这有点丑陋,我不能说我喜欢使用临时变量方法,但它有效,这对我来说已经足够了。此外,虽然我不太喜欢使用临时变量类型的命令 - 但在定义和使用它们之间,它们被篡改的风险很小(据我所知,TeX 并不是多线程的......)。
以下是一个建议的解决方案。我不能说它是理想的,但它确实有效:
\newcommand\PythonActiveVariableName{} % Store name of active variable
\newcommand\PythonActiveVariableValue{} % Value of the active variable
\gdef\getPythonVariable#1{\renewcommand{\PythonActiveVariableName}{#1}%
\getPythonActiveVariableValue}
\gdef\setPythonVariable#1#2{\renewcommand{\PythonActiveVariableName}{#1}%
\renewcommand{\PythonActiveVariableValue}{#2}\setPythonActiveVariableValue}
与前一种情况不同,这种方法颠覆了使用 Python 环境的做法,而是使用一些自定义命令,这些命令可以执行类似操作,但针对的是固定文本。虽然 python.sty 中的 Python 环境在尝试传递内容方面非常脆弱,但创建静态重复项却非常简单(这就是 \getPythonActiveVariableValue 和 \setPythonActiveVariableValue 所做的 - 一个无需参数即可工作的宏)。
所以,这可能是我能得到的最好的东西了。话虽如此,我会再讨论一段时间,看看是否还有其他想法。我仍然觉得去标记化和标记化很有意义,并且可以移植到许多环境中。
总而言之,我仍然感到困惑,LaTex 有一个奇怪的现象,如果你输入:
\begin{something}
<text>
\end{something}
放入文本中,它就会起作用。但是如果你在宏中做类似的事情,有时它会失败。宏是否使用不同的 catcode 或类似的东西?如果对规则不一致的原因有了更好的了解,我可能能够做出更好的修复。