我正在尝试编写一个非常具体的 LaTeX 包,它可以进行大量复杂的计算。它将文本的某些部分(或用户想要打印的其他内容)封装到框中,然后运行相当复杂的计算来确定在文档中布局这些框的位置。
用 LaTeX 编写这种计算程序并不实用 - 即使使用高级编程语言,它们也具有挑战性。有没有办法将这些计算委托给某个外部程序?理想的工作流程如下:
- 在 LaTeX 代码中收集必要的参数:要打印的所有框的尺寸、文本宽度和文本高度。
- 将其发送到外部程序。
- 根据收到的参数,程序将计算所有框的位置并以某种方式将结果发送回 LaTeX。
- LaTeX 将使用外部计算的盒子位置并在这些位置打印存储的盒子。
有没有办法与外部程序通信?它不必太精致,将参数存储在文件中,然后从另一个文件读取计算结果就足够了。我暂时不打算重新分发该软件包,因此外部程序无法重新分发并不重要。
答案1
我的pythontex
软件包可能是一个选项(最新版本GitHub;即将在 CTAN 上线)。它提供以下功能。
- 在 LaTeX 文档中输入 Python,然后将输出带回 LaTeX。
- 用户定义的会话。如果您有速度较慢的独立计算,只需将它们放在单独的会话中,它们将使用所有可用核心自动并行运行。
- 所有计算都被保存或缓存;代码仅在修改时执行(除非您另有指定)。
- 任何错误或警告都会与您的文档同步,以便您知道文档中的哪一行导致了问题。
最简单的做法是将您需要的任何参数传递给 Python,进行计算,然后将 LaTeX 代码打印回 TeX 端。文档中有一些示例,我也用它来pythontex
回答这个网站上的一些问题。
如果您只想从 Python 获取存储在宏中的值,这里有一个示例。这允许您将长度传递给 Python,对其进行一些计算,然后将输出返回给 TeX,存储在宏中。同样,通常可能更容易在 Python 中组装完整的 LaTeX 代码块,然后将其打印回来(可能有一个模板,并执行替换)。
\documentclass{article}
\usepackage{pythontex}
\makeatletter
% Define a Python function that takes a TeX length and a name,
% extracts the numerical part of the length and performs
% a calculation with it, and finally prints a macro definition
% back to TeX that stores the calculated value, with its
% units, using the specified name for the macro.
\begin{pylabcode}
def my_calc(length, name):
num = float(length[:-2])
unit = length[-2:]
print(r'\def\{0}{{{1}{2}}}'.format(name, str(sqrt(num**2/2)), unit))
\end{pylabcode}
\newcommand{\mycalc}[2]{%
% Create a default macro for the output.
% This avoids errors before PythonTeX runs
% and creates the real value
\expandafter\def\csname #2\endcsname{0pt}%
% When using PythonTeX commands inside macros,
% it's sometimes easiest to employ a helper
% macro to get everything expanded properly.
\expandafter\mycalc@i\expandafter{\the#1}{#2}%
}
\newcommand{\mycalc@i}[2]{%
\pylabc{my_calc('#1','#2')}%
}
\makeatother
\begin{document}
% This passes the value of \textwidth to Python,
% performs a calculation on it, and stores the result,
% including units, in the macro \returnvalue
\mycalc{\textwidth}{returnvalue}
\returnvalue
\end{document}
答案2
(这是一个 ConTeXt 解决方案,而不是 LaTeX 解决方案;我发布这个是为了防止有人想在 ConTeXt 中实现同样的效果)。
有没有办法与外部程序通信?它不必太精致,将参数存储在文件中,然后从另一个文件读取计算结果就足够了。
对于 ConTeXt,我编写了一个模块---筛选(在github)---就是这样做的。例如,假设您想使用Graphviz并将它们包含在 ConTeXt 中。为此,定义一个graphviz
环境如下:
\usemodule[filter]
\defineexternalfilter
[graphviz]
[
filter=\externalfilterparameter{layout} -Tpdf -o\externalfilteroutputfile,
layout=dot, % neato or twopi
cache=yes,
output=\externalfilterbasefile.pdf,
readcommand=\ReadPDF,
]
\def\ReadPDF#1%
{\externalfigure[#1]}
然后将图形排版为:
\startgraphviz
digraph G {
a_1-> a_2 -> a_3 -> a_1;
}
\stopgraphviz
如果要更改布局程序(graphviz 使用的不同算法),请使用:
\startgraphviz[layout=neato]
....
\stopgraphviz
您可以使用命令行选项将任意选项传递给外部程序。
这个包只是一个包装器\write18
,但提供了一些有用的功能:
- 缓存结果(仅当内容发生变化时才重新运行外部程序)
- 指定用于存储所有临时文件的输出目录(默认使用当前目录)
- 如果出现问题,启用诊断信息。
答案3
如果你有复杂的计算,我倾向于认为你想要python 包或者sagetex 包。这里有一个使用 Python 的示例这里但sagetex
使用 Python 命令以及为 CAS 创建的数学命令,称为智者所以它是解决复杂问题的理想选择。Sage 单元服务器您可以在这里亲自试用 Sage。这里您会发现“sagetex 的简要描述是,它是 TeX 宏的集合,允许 LaTeX 文档包含指令,让 Sage 使用内置于 Sage 的 latex() 支持计算各种对象和/或格式化对象。因此,作为编译 LaTeX 文档的中间步骤,Sage 的所有计算和 LaTeX 格式化功能都可以自动处理。”。sagetex 包的文档第 5 页和第 6 页指出:“请注意,由于 LaTeX 会对您提供给 \sage 的任何内容进行宏扩展,因此您可以混合使用 LaTeX 变量和 Sage 变量!如果您已将 Sage 变量 foo 定义为 12(例如,使用 sageblock 环境),那么您可以执行以下操作:当前页码加上 foo 的质因数分解为 $\sage{factor(foo + \thepage)}$。”下面是我整理的一个小工作示例,展示了这一点:
进行了重大编辑以更好地回答问题
\documentclass{article}
\usepackage{sagetex}
\pagestyle{empty}
\begin{document}
The documentation of the sagetex package gives a simple example
showing how you can combine \LaTeX and Sage variables similar
to this:
\begin{sagesilent}
foo=99
\end{sagesilent}
The prime factorization of the current page number plus foo
is $\sage{factor(foo + \thepage)}$.
The 2nd footnote (bottom of page 6) indicates there can be some
``weirdness'' depending on what you're processing.
\end{document}
使用 pdfLaTeX 运行 MyFile.tex 后,会创建一个 MyFile.sage 文件。使用 Sage 从命令行处理此文件:加载“MyFile.sage”,Sage 将创建 MyFile.sout 并指示您再次在文档上使用 LaTeX。执行此操作后,您的文档将打印出包含其创建的 Sage 计算/文本/图片的文档。这是上述代码的输出。
也可以“...在编译时获取输入并将其发送给 Sage”(引自这在第 271 页)。您可以使用更多示例;sagetex
第 9 页上的重要应用程序:“让 Sage 为您编写 LaTeX”。可能还有其他软件包可以做您想做的事情,但是当与复杂的数学,sagetex
是你需要学习的一个包。
答案4
有许多软件包允许这样做。最常用的可能是bashful
。
bashful 为 TEX 的原始 \write18 提供了一个方便的接口——从输入文件中执行 shell 命令,也称为 shell escape。\bash 和 \END 之间的文本由 bash(一种流行的 Unix 命令行解释器)执行。各种标志控制执行的命令及其输出是否显示在打印文档中,以及是否将它们保存到文件中。
这样您就可以执行任何可以通过 BASH CLI 执行的操作。
如果你愿意将自己限制在 Python 中,那么Python包裹
该软件包使您能够将 Python 代码(www.python.org)嵌入 LaTeX 并将输出插入到您的 LaTeX 文档中。