以编程方式将LaTeX代码转换/解析为纯文本

时间:2011-01-25 09:58:38

标签: python parsing text latex

我在C ++ / Python中有几个代码项目,其中使用LaTeX格式描述和标签来生成使用LaTeX + pstricks制作的PDF文档或图形。但是,我们还有一些纯文本输出,例如HTML版本的文档(我已经有代码为其编写最小标记)和一个非TeX启用的绘图渲染器。

对于这些我想要消除例如必要的TeX标记。代表物理单位。这包括非间断(薄)的空间,\文本,\ mathrm等,也将是不错解析下来的东西等\压裂{#1} {#2}成#1 /#2用于纯文本输出(和将MathJax用于HTML)。由于我们目前已经拥有的系统,我需要能够从Python执行此操作,即理想情况我正在寻找一个Python包,但我是一个非Python可执行文件,我可以从Python调用并捕获输出字符串也没关系。

我知道similar question on the TeX StackExchange site,但是没有任何真正的程序化解决方案:我看过detex,plasTeX和pytex,它们看起来都有点死了而且不是真的做我需要的:将TeX字符串编程转换为代表性纯文本字符串。

我可以尝试使用例如编写基本的TeX解析器pyparsing,但A)可能是陷阱拉丹和帮助,将不胜感激和b)肯定有人之前试过了,还是的方式知道挂接到TeX的本身,以获得更好的结果?

更新:感谢所有答案......这确实有点尴尬!我可以凑合着低于乳胶一般的解析,但考虑解析器,而不是在一个循环中的正则表达式的负荷的原因是,我希望能够处理嵌套宏和多ARG宏很好,并获得梅开二度匹配工作正常。然后我可以,例如首先减少txt无关的宏,比如\ text和\ mathrm,并处理与txt相关的宏,比如\ frac last ...甚至可以用合适的括号!好吧,我可以梦想...现在正则表达并没有做那么糟糕的工作。

8 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

我理解这是一篇很老的帖子,但由于这篇文章经常出现在latex-python-parsing搜索中(如Extract only body text from arXiv articles formatted as .tex所示),所以请留下这里的人员:这里是一个LaTeX解析器支持搜索和修改解析树https://github.com/alvinwan/texsoup的Python。摘自README,这里是示例文本以及如何通过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]

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

我会尝试pandoc [在这里输入链接描述] [1]。它是用Haskell编写的,但它是一个非常好的乳胶2无论转换器。

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

答案 5 :(得分:0)

构建另一篇文章Eduardo Leoni,我看着pandoc,我发现它附带了一个独立的可执行文件,但也在this page它承诺一种方法来构建一个C可调用的系统库。也许这是你可以忍受的东西?

答案 6 :(得分:0)

修复这个旧线程,但发现这个名为 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 :(得分:-3)

  

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

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

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

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