8

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
  • 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 '20 at 13:59
  • Does LaTeXML->PyLaTeX guarantee a clean round-trip? – vy32 Sep 27 '20 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 '20 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 '20 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. – David Carlisle Sep 27 '20 at 16:10
4

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 '20 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 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. – Matteo Gamboz Apr 6 at 8:50
  • @MatteoGamboz I cannot parse paragraphs as separate objects, do you know how to do? here is my question. – user171780 Apr 22 at 23:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.