是否可以从 LaTeX 调用外部程序?

是否可以从 LaTeX 调用外部程序?

我正在尝试编写一个非常具体的 LaTeX 包,它可以进行大量复杂的计算。它将文本的某些部分(或用户想要打印的其他内容)封装到框中,然后运行相当复杂的计算来确定在文档中布局这些框的位置。

用 LaTeX 编写这种计算程序并不实用 - 即使使用高级编程语言,它们也具有挑战性。有没有办法将这些计算委托给某个外部程序?理想的工作流程如下:

  1. 在 LaTeX 代码中收集必要的参数:要打印的所有框的尺寸、文本宽度和文本高度。
  2. 将其发送到外部程序。
  3. 根据收到的参数,程序将计算所有框的位置并以某种方式将结果发送回 LaTeX。
  4. 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 文档中。

相关内容