15

I am looking to write python programs that modify LaTeX source files. To do this I would like to have a basic parser in python that can reliably read and write LaTeX files while maintaining the tree. I'm okay if it is not a full implementation, but I need it to handle LaTeX's odd quoting rules and {} notation. Regular expressions simply do not work for this, due to the fact that braces can be recursive.

EDIT:

The main thing I want to handle is recursive braces, which is why I need a parser, rather than a simple lexical analyzer. That is, I want to be able to register \foo{} as a command I care about and catch:

\foo{this is the foo argument}

But I also want to be able to catch:

\foo{this is \emph{really} the foo argument}

Is there any such python module out there?

7
  • 1
    I'm not aware of a library that can directly parse LaTeX and write it back to a file. One way (admittedly not very straightforward) might be to convert LaTeX to semantics-preserving xml with LaTeXML, read the xml with Python, and regenerate LaTeX using PyLaTeX.
    – Marijn
    Sep 27, 2020 at 13:59
  • Does LaTeXML->PyLaTeX guarantee a clean round-trip?
    – vy32
    Sep 27, 2020 at 14:00
  • If you mean that the resulting .tex is the same as the original input file, then no. But depending on the actual use case this may still be a suitable approach.
    – Marijn
    Sep 27, 2020 at 14:03
  • You can try TeXSoup. However, there is yet to be a complete LaTeX parser that can fully handle macro definitions, catcodes, LaTeX3 and so on.
    – Alan Xiang
    Sep 27, 2020 at 14:14
  • there clearly can be no full parser try xii.tex (although actually latexml parses that with perl, which is quite a feat) but there will always be cases that require a full tex system to parse correctly. So it's a matter of how strict you want to be. Just parsing simple "latex book" document markup not tex macro code should be fairly easy. When you say "maintaining the tree" note latex never parses the full file and never constructs a tree. Sep 27, 2020 at 16:10

1 Answer 1

7

Please see if the LatexWalker class of pylatexenc can help:

from pylatexenc.latexwalker import LatexWalker

w = LatexWalker(r"\foo{this is \emph{really} the foo argument}")
(nodelist, pos, len_) = w.get_latex_nodes(pos=0)

print(nodelist[0].macroname)
print(nodelist[1].latex_verbatim())

>>> foo
{this is \emph{really} the foo argument}
4
  • I tried to use your advice for this but quite complex apparently
    – JeT
    Dec 4, 2020 at 11:00
  • Do you know how to navigate over the "sub-nodes" of nodelist? I mean, nodelist[-1] has almost the entire document but I don't know how to go through the sections, paragraphs, equations, and so on.
    – user171780
    Apr 4, 2021 at 17:26
  • I have a recursive function to walk the node and find some macro that I'm looking for. It does not fit here. If you make a new question I can answer there. Apr 6, 2021 at 8:50
  • @MatteoGamboz I cannot parse paragraphs as separate objects, do you know how to do? here is my question.
    – user171780
    Apr 22, 2021 at 23:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .