/latex.py

A python preprocessor for latex: Define latex macros in python

Primary LanguagePython

latex.py is a preprocessor for LaTeX source files.

It was originally written because a journal asked me not to have any
user-defined latex macro in the source file. Which was a problem, since
I had lots of them. Hence, a program was needed to process the file and
expand these macros to create a file to send to the publisher.

Since then, it has grown a bit. There are now three main use cases:

1) Write macros in python. Because it's simpler? More powerful libraries?
   Use '@' instead of '\' as macro prefix. Typical build process:
       python latex.py -i macros.py -o manuscript.pdf manuscript.tex

2) Expand user-defined macros in text, because some journals don't like these.
   Uses '\' as macro prefix, but replaces as many as possible with their
   expansions.
       python latex.py -L -o manuscript.texp manuscript.tex

3) Parse a latex file to determine its dependencies, for use in makefiles etc.
       deps=$(python latex.py -L \
              -P includegraphics:1:%s.pdf \
              -P input:1:%s.tex \
              -P bibliography:1:%s.bib \
              manuscript.tex)

In the .tex file, lines beginning with '%@', or between '{%@' and '}%@', 
form a block of python code. As a simple case, the following can be put in 
the .tex file,

---
{%@
def vec(x):
    return r'\hat{%s}' % x
A = r'\mathrm{A}'                        [1]
}%@
---

and now \vec{\A} is expanded to \hat{\mathrm{A}} in the text (assuming 
the -L flag is used).

There are various shortcuts to make this more pleasant to write. The 
following are two equivalent ways to write the definitions above:

---
{%@
def vec(x):
    return : \hat{#(x)}                  [2]
A =: \mathrm{A}
}%@
---
{%@
vec =: \hat{%s}                          [3]
A   =: \mathrm{A}
}%@
---
\newcommand{\vec}[1]{\hat{#1}}           [4]
\newcommand{\A}{\mathrm{A}}

(The ':' syntax is not pure python obviously. For the curious, line [2] is
converted to 
    return r"""\hat{%(x)s}""" % locals()
Furthermore, a macro can either be a string (as in lines [1] and [3]), or
a function (as in [2]). Strings are formatted using the arguments to the
macro.

[4]: Yes, latex.py understands \newcommand when the -L flag is given. It
can be used on an unmodified latex file to expand all user-defined macros.


Another short example:

---
%@eval = eval                              [5]
\title{Proving that $2+2=@eval{2+2}$
---

The line [5] is required to make the builtin function eval visible as a macro. 
Note that these builtins may be shadowed by user variables, but are always 
accessible as for example __builtin__.eval.
It is recommended that functions, variables and classes that should not be
visible as macros should contain the underscore character ('_'), since it is
not allowed in a macro name.


See the examples/ directory for other examples.


latex.py was written in 2010 by Joachim B Haga (jobh@simula.no).
It is licensed under GPL v2 (or later).