【问题标题】:Programmatically converting/parsing LaTeX code to plain text以编程方式将 LaTeX 代码转换/解析为纯文本
【发布时间】:2011-01-25 09:58:38
【问题描述】:

我有几个 C++/Python 代码项目,其中 LaTeX 格式的描述和标签用于生成 PDF 文档或使用 LaTeX+pstricks 制作的图表。但是,我们也有一些纯文本输出,例如文档的 HTML 版本(我已经有代码可以为此编写最少的标记)和不支持 TeX 的绘图渲染器。

对于这些,我想消除例如必要的 TeX 标记。表示物理单位。这包括不间断(细)空格、\text、\mathrm 等。将 \frac{#1}{#2} 之类的内容解析为 #1/#2 以用于纯文本输出(和对 HTML 使用 MathJax)。由于我们目前拥有的系统,我需要能够从 Python 执行此操作,即 理想情况下我正在寻找一个 Python 包,但我正在寻找一个非 Python 可执行文件可以从 Python 调用并捕获输出字符串也可以。

我知道similar question on the TeX StackExchange site,但没有任何真正的程序化解决方案:我看过 detex、plasTeX 和 pytex,它们似乎都有些死气沉沉,并没有真正做些什么我需要:将 TeX 字符串编程转换为有代表性的纯文本字符串。

我可以尝试使用例如编写一个基本的 TeX 解析器。 pyparsing,但是 a) 这可能是陷阱和帮助将不胜感激 b) 肯定有人以前尝试过,或者知道有一种方法可以连接到 TeX 本身以获得更好的结果?

更新:感谢您的所有回答......这确实似乎是一个有点尴尬的要求!我可以使用少于一般的 LaTeX 解析,但考虑在循环中使用解析器而不是加载正则表达式的原因是我希望能够很好地处理嵌套宏和多参数宏,并获得大括号匹配才能正常工作。然后我可以例如首先减少与 txt 无关的宏,如 \text 和 \mathrm,最后处理与 \frac 等 txt 相关的宏......甚至可以使用适当的括号!好吧,我可以梦想......现在正则表达式并没有做那么糟糕的工作。

【问题讨论】:

  • 你是对的,TeX 的 pyparsing 是一件残酷的事情,但其他人已经在这方面取得了一些进展。 matplotlib 包含一个 pyparsing TeX 解析器,您也许可以根据自己的目的进行调整。您也可以尝试在 pyparsing 邮件列表上发帖,看看过去做过 TeX 工作的人是否可以提供帮助。
  • 谢谢:我先看看 matplotlib... 这也是我的一个包的预先存在的依赖项,所以如果我 非常 幸运的话,我可以使用它通过mpl API!干杯:)

标签: python parsing text latex


【解决方案1】:

我知道这是一篇旧文章,但由于这篇文章经常出现在 latex-python-parsing 搜索中(Extract only body text from arXiv articles formatted as .tex 很明显),所以这里留给人们:这是 Python 中的 LaTeX 解析器支持搜索和修改解析树,https://github.com/alvinwan/texsoup。摘自自述文件,这里是示例文本以及如何通过 TexSoup 与之交互。

from TexSoup import TexSoup
soup = TexSoup("""
\begin{document}

\section{Hello \textit{world}.}

\subsection{Watermelon}

(n.) A sacred fruit. Also known as:

\begin{itemize}
\item red lemon
\item life
\end{itemize}

Here is the prevalence of each synonym.

\begin{tabular}{c c}
red lemon & uncommon \\
life & common
\end{tabular}

\end{document}
""")

以下是如何导航解析树。

>>> soup.section  # grabs the first `section`
\section{Hello \textit{world}.}
>>> soup.section.name
'section'
>>> soup.section.string
'Hello \\textit{world}.'
>>> soup.section.parent.name
'document'
>>> soup.tabular
\begin{tabular}{c c}
red lemon & uncommon \\
life & common
\end{tabular}
>>> soup.tabular.args[0]
'c c'
>>> soup.item
\item red lemon
>>> list(soup.find_all('item'))
[\item red lemon, \item life]

免责声明:我写了这个库,但出于类似的原因。关于 Little Bobby Tales 的帖子(关于 def),TexSoup 不处理定义。

【讨论】:

    【解决方案2】:

    请注意:为纯 TeX 编写一个完整的解析器比您想象的要困难得多。 TeX 级别(不是 LaTeX)\def 命令实际上扩展了 TeX 的语法。例如,\def\foo #1.{{\bf #1}} 会将\foo goo. 扩展为 goo - 注意点变成了 foo 宏的分隔符!因此,如果你必须处理 any 形式的 TeX,不限制可以使用哪些包,不建议依赖简单的解析。你需要 TeX 渲染。 catdvi 是我用的,虽然不完美。

    【讨论】:

    • 我可以使用比这更少的一般解析,但感谢您的提醒!我可以将使用限制为 LaTeX 的一个更合理的子集——在循环中考虑解析器而不是加载正则表达式的原因是我希望能够很好地处理嵌套宏和多参数宏,并获得支撑数学正常工作。然后我可以例如首先减少与 txt 无关的宏,如 \text 和 \mathrm,最后处理与 txt 相关的宏,如 \frac... 甚至可以使用适当的括号!
    【解决方案3】:

    尝试detex(大多数*TeX 发行版附带)或改进版本:http://code.google.com/p/opendetex/

    编辑:哦,我看到你已经尝试过 detex 了。不过,opendetex 可能对你有用。

    【讨论】:

    • 我以前没有见过 opendetex ——它看起来好多了,也许他们的解析器可以连接并扩展为在数学模式下使用命令做更多结构化的事情。谢谢。
    【解决方案4】:

    我会尝试 pandoc [在此处输入链接描述][1]。它是用 Haskell 编写的,但它是一个非常好的 Latex 2 转换器。

    [1]: http://johnmacfarlane.net/pandoc/index.html

    【讨论】:

    • 我希望在 Haskell 中没有问题,但它是:我不能真正分发依赖于非标准程序和使用 Haskell 编译器的用户的代码!据我所知,也没有真正的 Python-Haskell 绑定,这不是杀手,但无济于事:) 不过我会私下使用它——谢谢!
    【解决方案5】:

    当您考虑使用 TeX 本身进行渲染时,我怀疑性能不是问题。在这种情况下,您有两个选择:dvi2txt 从单个 dvi 文件中获取文本(准备为每个标签生成一个),或者甚至将 dvi 渲染为光栅图像,如果它适合您的话 - 这就是 hevea 或latex2html 处理公式。

    【讨论】:

    • 感谢 cmets。实际上,我们有数千个标签要解析(这针对绘图生成进行了一些优化,我们希望加快速度)。但是非常简单的 LaTeX 文档的处理速度可能可以接受,并且在一个 TeX 文档中批量处理多个标签可能是可行的——我会试一试。 AFAIK 在这种情况下,LaTeX 的启动时间很可能占主导地位,所以像在 PyTeX 中工作过的 LaTeX 守护进程之类的东西会很有用......只要那个项目还活着!
    【解决方案6】:

    删除这个旧线程,但发现这个名为pylatexenc 的漂亮库似乎几乎完全符合 OP 的要求:

    from pylatexenc.latex2text import LatexNodes2Text
    
    
    LatexNodes2Text().latex_to_text(r"""\
    \section{Euler}
    \emph{This} bit is \textbf{very} clever:
    \begin{equation}
        \mathrm{e}^{i \pi} + 1 = 0  % wow!!
    \end{equation}
    where
    \[
    \mathrm{e} = \lim_{n \to \infty} \left(1 + \frac{1}{n}\right)^n
    \]
    """)
    

    产生

    
    § EULER
    
    This bit is very clever:
    
        e^i π + 1 = 0
    
    where
    
        e = lim_n →∞(1 + 1/n)^n
    

    如您所见,结果对于方程来说并不完美,但它在剥离和转换所有 tex 命令方面做得很好。

    【讨论】:

    • 非常感谢!!
    【解决方案7】:

    在 Eduardo Leoni 的另一篇文章中,我正在查看 pandoc,我看到它带有一个独立的可执行文件,但也在 this page 上,它承诺提供一种构建 C 可调用系统库的方法。也许这是你可以忍受的东西?

    【讨论】:

      【解决方案8】:

      LaTeX 格式的描述和标签用于生成 PDF 文档或使用 LaTeX+pstricks 制作的图表

      这是你的错误。你不应该那样做。

      使用 RST 或其他一些更好的标记语言。

      使用Docutils 从 RST 源创建 LaTeX 和 HTML。

      【讨论】:

      • 感谢您的 cmets!不过,这并不是一个错误——该软件用于学术物理学,我们使用 LaTeX 进行数学解析/渲染——可能 50% 或更多的编码文本是数学——并且输出可以无缝地用于 ( LaTeX 准备的)出版物。所以虽然我可能同意重新。 RST 在不需要对格式进行非常详细的控制的文本主导的情况下,这个用例几乎相反,LaTeX 更适合应用程序和用户社区。用它来做灵活的事情很尴尬......
      • @andybuckley:RST 支持 LaTeX 数学。我用过。我更喜欢 sphinx (sphinx.pocoo.org) 的支持。请参阅此相关问题stackoverflow.com/questions/3610551/… 以获得更多有用的建议。
      • @andybuckley:“这不是一个错误”。如果它不起作用,那么一定是某个地方出错了。如果没有错误,它必须完美运行。如果它工作得很好,为什么要问一个问题?
      • 我想这是一个误解——我的 TeX 片段主要用作绘图系统的输入,与 RST 的适用范围几乎没有重叠。我其次想提取这些以数学为主的片段的合理可读的纯文本版本,用于网络和命令行显示。据我所知,Sphinx 的 LaTeX 支持是通过分叉 LaTeX 和 dvipng 进程完成的:这对例如将 \frac{a}{b/c} 渲染为 a/(b/c)。
      • 第三种选择是没有明显的、现成的方法可以同时满足所有要求!找出是否存在 显而易见但仍然是现成的方法是提出这个问题的原因 :) 我的系统不能完美运行,但 LaTeX 是我们的明智选择最基本的用例——TeX -> txt 解析对于应用程序的不太关键的方面来说是一个很好的可用性特性。但我不想给 OP 带来所有这些细节的负担!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-31
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多