0% found this document useful (0 votes)
84 views7 pages

Pythontex: Fast Access To Python From Within Latex: Xie Pastell MK

Uploaded by

haji saheb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views7 pages

Pythontex: Fast Access To Python From Within Latex: Xie Pastell MK

Uploaded by

haji saheb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

30 PROC. OF THE 11th PYTHON IN SCIENCE CONF.

(SCIPY 2012)

PythonTeX: Fast Access to Python from within LaTeX


Geoffrey M. Poore‡∗

Abstract—PythonTeX is a new LaTeX package that provides access to the full Several methods of including executable code in LaTeX docu-
power of Python from within LaTeX documents. It allows Python code entered ments ultimately function as preprocessors or templating systems.
within a LaTeX document to be executed, and provides access to the output. A document might contain a mix of LaTeX and code, and the
PythonTeX also provides syntax highlighting for any language supported by the preprocessor replaces the code with its output. The original docu-
Pygments highlighting engine.
ment would not be valid LaTeX; only the preprocessed document
PythonTeX is fast and user-friendly. Python code is separated into user-
defined sessions. Each session is only executed when its code is modified.
would be. Sweave, knitr [Xie], the Python-based Pweave [Pastell],
When code is executed, sessions run in parallel. The contents of stdout and and template libraries such as Mako [MK] function in this manner.
stderr are synchronized with the LaTeX document, so that printed content is More recently, the IPython notebook has provided an interactive
easily accessible and error messages have meaningful line numbering. browser-based interface in which text, code, and code output may
PythonTeX simplifies scientific document creation with LaTeX. Plots can be interspersed [IPY]. Since the notebook can be exported as
be created with matplotlib and then customized in place. Calculations can be LaTeX, it functions similarly to the preprocessor-style approach.
performed and automatically typeset with NumPy. SymPy can be used to auto- The preprocessor/templating-style approach has a significant
matically create mathematical tables and step-by-step mathematical derivations. advantage. All of the examples mentioned above are compatible
with multiple document formats, not just LaTeX. This is par-
Index Terms—LaTeX, document preparation, document automation, matplotlib,
ticularly true in the case of templating libraries. One significant
NumPy, SymPy, Pygments
drawback is that the line numbers of the preprocessed document,
which LaTeX receives, do not correspond to those of the original
Introduction document. This makes it difficult to debug LaTeX errors, partic-
ularly in longer documents. It also breaks standard LaTeX tools
Scientific documents and presentations are often created with the
such as forward and inverse search between a document and its
LaTeX document preparation system. Though some LaTeX tools
PDF (or other) output; only Sweave and knitr have systems to
exist for creating figures and performing calculations, external
work around this. An additional issue is that it is difficult for
scientific software is typically required for these tasks. This can
LaTeX code to interact with code in other languages, when the
result in an inefficient workflow. Every time a calculation requires
code in other languages has already been executed and removed
modification or a figure needs tweaking, the user must switch
before LaTeX runs.
between LaTeX and the scientific software. The user must locate
In an alternate approach to including executable code in LaTeX
the code that created the calculation or figure, modify it, and
documents, the original document is valid LaTeX, containing
execute it before returning to LaTeX.
code wrapped in special commands and environments. The code
One way to streamline this process is to include non-LaTeX
is extracted by LaTeX itself during compilation, then executed
code within LaTeX documents, with a means to execute this
and replaced by its output. Such approaches with Python go
code and access the output. That approach has connections to
back to at least 2007, with Martin R. Ehmsen’s python.sty style
Knuth’s concept of literate programming, in which code and its
file [Ehmsen]. Since 2008, SageTeX has provided access to the
documentation are combined in a single document [Knuth]. The
Sage mathematics system from within LaTeX [Drake]. Because
noweb literate programming tool extended Knuth’s work to ad-
Sage is largely based on Python, it also provides Python ac-
ditional document formats and arbitrary programming languages
cess. SympyTeX (2009) is based on SageTeX [Molteno]. Though
[Ramsey]. Sweave subsequently built on noweb by allowing the
SympyTeX is primarily intended for accessing the SymPy library
output of individual chunks of R code to be accessed within
for symbolic mathematics [SymPy], it provides general access to
the document [Leisch]. This made possible dynamic reports that
Python. Since these packages begin with a valid LaTeX document,
are reproducible since they contain the code that generated their
they automatically work with standard LaTeX editing tools and
results. As such, Sweave and similar tools represent an additional,
also allow LaTeX code to interact with Python.
complementary approach to reproducibility compared to makefile-
Python.sty, SageTeX, and SympyTeX illustrate the potential
based approaches [Schwab].
of a close Python-LaTeX integration. At the same time, they leave
much of the possible power of the Python-LaTeX combination un-
* Corresponding author: [email protected]
‡ Union University tapped. Python.sty requires that all Python code be executed every
time the document is compiled. SageTeX and SympyTeX separate
Copyright © 2012 Geoffrey M. Poore. This is an open-access article distributed code execution from document compilation, but because all code
under the terms of the Creative Commons Attribution License, which permits
unrestricted use, distribution, and reproduction in any medium, provided the is executed in a single session, everything must be executed
original author and source are credited. whenever anything changes. None of these packages provides
PYTHONTEX: FAST ACCESS TO PYTHON FROM WITHIN LATEX 31

comprehensive syntax highlighting. SageTeX and SympyTeX do The printed content is not automatically included. Typically, the
not provide access to stdout or stderr. They do synchronize error user wouldn’t want the printed content immediately after the
messages with the document, but synchronization is performed by typeset code—explanation of the code, or just some space, might
executing a try/except statement on every line of the user’s be desirable before showing the output. Two equivalent commands
code. This reduces performance and fails in the case of syntax are provided for including the printed content generated by a block
errors. environment: \printpythontex and \stdoutpythontex.
PythonTeX is a new LaTeX package that provides access to These bring in any printed content created by the most recent
Python from within LaTeX documents. It emphasizes performance PythonTeX environment and interpret it as LaTeX code. Both
and usability. commands also take an optional argument to bring in content
• Python-generated content is always saved, so that the La- as verbatim text. For example, \printpythontex[v] brings
TeX document can be compiled without running Python. in the content in a verbatim form suitable for inline use, while
• Python code is divided into user-defined sessions. Each \printpythontex[verb] brings in the content as a verbatim
session is only executed when it is modified. When code block.
is executed, sessions run in parallel. All code entered within code and block environments is
• Both stdout and stderr are easily accessible. executed within the same Python session (unless the user specifies
• All Python error messages are synchronized with the otherwise, as discussed below). This means that there is continuity
LaTeX document, so that error line numbers correctly among environments. For example, since myvar has already been
correspond to the document. created, it can now be modified:
• Code may be typeset with highlighting provided by Pyg- \begin{pycode}
ments [Pyg]—this includes any language supported by myvar += 4
Pygments, not just Python. Unicode is supported. print('myvar = ' + str(myvar))
\end{pycode}
• Native Python code is fully supported, including imports
from __future__. No changes to Python code are
This produces
required to make it compatible with PythonTeX.
While PythonTeX lacks the rapid interactivity of the IPython myvar = 127
notebook, as a LaTeX package it offers much tighter Python- The verb environment typesets its contents, without executing
LaTeX integration. It also provides greater control over what is it. This is convenient for simply typesetting Python code. Since
displayed (code, stdout, or stderr) and allows executable code to the verb environment has a parallel construction to the code and
be included inline within normal text. block environments, it can also be useful for temporarily disabling
This paper presents the main features of PythonTeX and the execution of some code. Thus
considers several examples. It also briefly discusses the internal
workings of the package. \begin{pyverb}
myvar = 123
print('Greetings from Python!')
PythonTeX environments and commands \end{pyverb}
PythonTeX provides four LaTeX environments and four LaTeX
commands for accessing Python. These environments and com- results in the typeset content
mands save code to an external file and then bring back the output myvar = 123
once the code has been processed by PythonTeX. print('Greetings from Python!')
The code environment simply executes the code it contains.
By default, any printed content is brought in immediately after without any code actually being executed.
the end of the environment and interpreted as LaTeX code. For The final environment is different. The console environment
example, the LaTeX code emulates a Python interactive session, using Python’s code mod-
\begin{pycode} ule. Each line within the environment is treated as input to an
myvar = 123 interactive interpreter. The LaTeX code
print('Greetings from Python!')
\end{pycode} \begin{pyconsole}
myvar = 123
creates a variable myvar and prints a string, and the printed myvar
content is automatically included in the document: print('Greetings from Python!')
Greetings from Python! \end{pyconsole}

The block environment executes its contents and also typesets creates
it. By default, the typeset code is highlighted using Pygments.
Reusing the Python code from the previous example, >>> myvar = 123
>>> myvar
\begin{pyblock} 123
myvar = 123 >>> print('Greetings from Python!')
print('Greetings from Python!') Greetings from Python!
\end{pyblock}
PythonTeX provides options for showing and customizing a ban-
creates ner at the beginning of console environments. The content of all
myvar = 123 console environments is executed within a single Python session,
print('Greetings from Python!') providing continuity, unless the user specifies otherwise.
32 PROC. OF THE 11th PYTHON IN SCIENCE CONF. (SCIPY 2012)

While the PythonTeX environments are useful for executing \begin{pycode}[slowsession]


and typesetting large blocks of code, the PythonTeX commands myvar = 123
print('Greetings from Python!')
are intended for inline use. Command names are based on abbrevi- \end{pycode}
ations of environment names. The code command simply executes
its contents. For example, \pyc{myvar = 123}. Again, any Each session is only executed when its code has changed,
printed content is automatically included by default. The block and sessions run in parallel (via Python’s multiprocessing
command typesets and executes the code, but does not automati- package), so careful use of sessions can significantly increase
cally include printed content (\printpythontex is required). performance.
Thus, \pyb{myvar = 123} would typeset All PythonTeX environments also accept a second optional
myvar = 123
argument. This consists of settings for the LaTeX fancyvrb
(Fancy Verbatims) package [FV], which PythonTeX uses for
in a form suitable for inline use, in addition to executing the typesetting code. These settings allow customization of the code’s
code. The verb command only typesets its contents. The command appearance. For example, a block of code may be surrounded by
\pyv{myvar = 123} would produce a colored frame, with a title. Or line numbers may be included.

myvar=123
Plotting with matplotlib
without executing anything. If Pygments highlighting for inline
The PythonTeX commands and environments can greatly simplify
code snippets is not desired, it may be turned off.
the creation of scientific documents and presentations. One exam-
The final inline command, \py, is different. It provides a
ple is the inclusion of plots created with matplotlib [MPL].
simple way to typeset variable values or to evaluate short pieces of
All of the commands and environments discussed above be-
code and typeset the result. For example, \py{myvar} accesses
gin with the prefix py. PythonTeX provides a parallel set of
the previously created variable myvar and brings in a string
commands and environments that begin with the prefix pylab.
representation: 123. Similarly, \py{2**8 + 1} converts its
These behave identically to their py counterparts, except that
argument to a string and returns 257.
matplotlib’s pylab module is automatically imported via from
It might seem that the effect of \py could be achieved using
pylab import *. The pylab commands and environments
\pyc combined with print. But \py has significant advantages.
can make it easier to keep track of code dependencies and separate
First, it requires only a single external file per document for
content that would otherwise require explicit sessions; the default
bringing in content, while print requires an external file for each
pylab session is separate from the default py session.
environment and command in which it is used. This is discussed in
Combining PythonTeX with matplotlib significantly simplifies
greater detail in the discussion of PythonTeX’s internals. Second,
plotting. The commands for creating a plot may be included
the way in which \py converts its argument to a valid LaTeX
directly within the LaTeX source, and the plot may be edited in
string can be specified by the user. This can save typing when
place to get the appearance just right. Matplotlib’s LaTeX option
several conversions or formatting operations are needed. The
may be used to keep fonts consistent between the plot and the
examples below using SymPy illustrate this approach.
document. The code below illustrates this approach. Notice that
All of the examples of inline commands shown above use
the plot is created in its own session, to increase performance.
opening and closing curly brackets to delimit the code. This
system breaks down if the code itself contains an unmatched \begin{pylabcode}[plotsession]
curly bracket. Thus, all inline commands also accept arbitrary rc('text', usetex=True)
rc('font', **{'family':'serif', 'serif':['Times']})
matched characters as delimiters. This is similar to the behavior of rc('font', size=10.0)
LaTeX’s \verb macro. For example, \pyc!myvar = 123! rc('legend', fontsize=10.0)
and \pyc#myvar = 123# are valid. No such consideration is x = linspace(0, 3*pi)
required for environments, since they are delimited by \begin figure(figsize=(3.25,2))
plot(x, sin(x), label='$\sin(x)$')
and \end commands. plot(x, sin(x)**2, label='$\sin^2(x)$',
linestyle='dashed')
xlabel(r'$x$-axis')
Options: Sessions and Fancy Verbatims ylabel(r'$y$-axis')
xticks(arange(0, 4*pi, pi), ('$0$',
PythonTeX commands and environments take optional arguments. '$\pi$', '$2\pi$', '$3\pi$'))
These determine the session in which the code is executed and axis([0, 3*pi, -1, 1])
provide additional formatting options. legend(loc='lower right')
savefig('myplot.pdf', bbox_inches='tight')
By default, all code and block content is executed within a \end{pylabcode}
single Python session, and all console content is executed within a
separate session. In many cases, such behavior is desired because The plot may be brought in and positioned using the standard
of the continuity it provides. At times, however, it may be useful LaTeX commands:
to isolate some independent code in its own session. A long
calculation could be placed in its own session, so that it only \begin{figure}
\centering
runs when its code is modified, independently of other code. \includegraphics{myplot}
PythonTeX provides such functionality through user- \caption{\label{fig:matplotlib} A plot
defined sessions. All commands and environments take created with PythonTeX.}
\end{figure}
a session name as an optional argument. For example,
\pyc[slowsession]{myvar = 123} and The end result is shown in Figure 1.
PYTHONTEX: FAST ACCESS TO PYTHON FROM WITHIN LATEX 33

1.0 The roots of $\pylab{eq}$ are


$[\pylab{latex_roots}]$.

0.5 This yields


The roots of 4x2 + 2x − 4 = 0 are [−1.281, +0.781].
y-axis

0.0
The automated generation of LaTeX code on the Python side
begins to demonstrate the full power of PythonTeX.
−0.5 sin(x)
sin2 (x) Solving equations with SymPy
−1.0 Several examples with SymPy further illustrate the potential of
0 π 2π 3π Python-generated LaTeX code [SymPy].
x-axis To simplify SymPy use, PythonTeX provides a set of com-
mands and environments that begin with the prefix sympy. These
Fig. 1: A matplotlib plot created with PythonTeX. are identical to their py counterparts, except that SymPy is
automatically imported via from sympy import *.
SymPy is ideal for PythonTeX use, because its
Solving equations with NumPy
LatexPrinter class and the associated latex() function
PythonTeX didn’t require any special modifications to the Python provide LaTeX representations of objects. For example, returning
code in the previous example with matplotlib. The code that to solving the same polynomial,
created the plot was the same as it would have been had an
\begin{sympycode}
external script been used to generate the plot. In some situations, x = symbols('x')
however, it can be beneficial to acknowledge the LaTeX context myeq = Eq(4*x**2 + 2*x - 4)
of the Python code. This may be illustrated by solving an equation print('The roots of the equation ')
print(latex(myeq, mode='inline'))
with NumPy [NP].
print(' are ')
Perhaps the most obvious way to solve an equation using print(latex(solve(myeq), mode='inline'))
PythonTeX is to separate the Python solving from the LaTeX \end{sympycode}
typesetting. Consider finding the roots of a polynomial using
NumPy. creates
2
\begin{pylabcode}  1The
√ roots of the equation
√  4x + 2x − 4 = 0 are
coeff = [4, 2, -4] − 4 17 − 14 , − 14 + 14 17
r = roots(coeff)
\end{pylabcode} Notice that the printed content appears as a single uninter-
rupted line, even though it was produced by multiple prints. This
The roots of $4x^2 + 2x - 4 = 0$ are is because the printed content is interpreted as LaTeX code, and
$\pylab{r[0]}$ and $\pylab{r[1]}$.
in LaTeX an empty line is required to end a paragraph.
This yields The \sympy command provides an alternative to printing.
While the \py and \pylab commands attempt to convert their
The roots of 4x2 + 2x − 4 = 0 are −1.2807764064 arguments directly to a string, the \sympy command converts its
and 0.780776406404. argument using SymPy’s LatexPrinter class. Thus, the output
Such an approach works, but the code must be modified sig- from the last example could also have been produced using
nificantly whenever the polynomial changes. A more sophisticated \begin{sympycode}
approach automatically generates the LaTeX code and perhaps x = symbols('x')
rounds the roots as well, for an arbitrary polynomial. myeq = Eq(4*x**2 + 2*x - 4)
\end{sympycode}
\begin{pylabcode}
coeff = [4, 2, -4] The roots of the equation $\sympy{myeq}$
# Build a string containing equation are $\sympy{solve(myeq)}$.
eq = ''
for n, c in enumerate(coeff): The \sympy command uses a special interface to
if n == 0 or str(c).startswith('-'): the LatexPrinter class, to allow for context-dependent
eq += str(c)
LatexPrinter settings. PythonTeX includes a utilities class,
else:
eq += '+' + str(c) and an instance of this class called pytex is created within each
if len(coeff) - n - 1 == 1: PythonTeX session. The formatter() method of this class is
eq += 'x' responsible for converting objects into strings for \py, \pylab,
elif len(coeff) - n - 1 > 1:
eq += 'x^' + str(len(coeff) - n - 1) and \sympy. In the case of SymPy, pytex.formatter()
eq += '=0' provides an interface to LatexPrinter, with provision for
# Get roots and format for LaTeX context-dependent customization. In LaTeX, there are four possi-
r = ['{0:+.3f}'.format(root) ble math styles: displaystyle (regular equations), textstyle (inline),
for root in roots(coeff)]
latex_roots = ','.join(r) scriptstyle (superscripts and subscripts), and scriptscriptstyle (su-
\end{pylabcode} perscripts and subscripts, of superscripts and subscripts). Separate
34 PROC. OF THE 11th PYTHON IN SCIENCE CONF. (SCIPY 2012)

LatexPrinter settings may be specified for each of these \begin{sympycode}


styles individually, using a command of the form x, y = symbols('x, y')
f = x + sin(y)
pytex.set_sympy_latex(style, **kwargs) step1 = Integral(f, x, y)
step2 = Integral(Integral(f, x).doit(), y)
For example, by default \sympy is set to create normal-sized step3 = step2.doit()
matrices in displaystyle and small matrices elsewhere. Thus, the \end{sympycode}
following code \begin{align*}
\sympy{step1} &= \sympy{step2} \\
\begin{sympycode}
&= \sympy{step3}
m = Matrix([[1,0], [0,1]])
\end{align*}
\end{sympycode}

The matrix in inline is small: $\sympy{m}$ This produces

The matrix in an equation is of normal size:


\[ \sympy{m} \] 1 2
ZZ Z
x + sin (y) dx dy = x + x sin (y) dy
2
produces 1
= x2 y − x cos (y)
The matrix in inline is small: 10 01 2


The matrix in an equation is of normal size:


Automated mathematical tables with SymPy
1 0
 
The creation of mathematical tables is another traditionally tedious
0 1
task that may be automated with PythonTeX and SymPy. Consider
As another example, consider customizing the appearance of the following code, which automatically creates a small integral
inverse trigonometric functions based on their context. and derivative table.

\begin{sympycode} \begin{sympycode}
x = symbols('x') x = symbols('x')
sineq = Eq(asin(x/2)-pi/3) funcs = ['sin(x)', 'cos(x)', 'sinh(x)', 'cosh(x)']
pytex.set_sympy_latex('display', ops = ['Integral', 'Derivative']
inv_trig_style='power') print('\\begin{align*}')
pytex.set_sympy_latex('text', for func in funcs:
inv_trig_style='full') for op in ops:
\end{sympycode} obj = eval(op + '(' + func + ', x)')
left = latex(obj)
Inline: $\sympy{sineq}$ right = latex(obj.doit())
if op != ops[-1]:
Equation: \[ \sympy{sineq} \] print(left + '&=' + right + '&')
else:
This creates print(left + '&=' + right + r'\\')
print('\\end{align*}')
1
Inline: arcsin 2x − 31 π = 0 \end{sympycode}


Equation: Z


1

1 sin (x) dx = − cos (x) sin (x) = cos (x)
sin−1
x − π =0 ∂x
2 3 Z

cos (x) dx = sin (x) cos (x) = − sin (x)
Notice that in both examples above, the \sympy com- ∂x
Z
mand is simply used—no information about context must be sinh (x) dx = cosh (x)

sinh (x) = cosh (x)
passed to Python. On the Python side, the context-dependent ∂x
Z
LatexPrinter settings are used to determine whether the cosh (x) dx = sinh (x)

cosh (x) = sinh (x)
LaTeX representation of some object is context-dependent. If not, ∂x
Python creates a single LaTeX representation of the object and
returns that. If the LaTeX representation is context-dependent,
This code could easily be modified to generate a page or more
then Python returns multiple LaTeX representations, wrapped
of integrals and derivatives by simply adding additional function
in LaTeX’s \mathchoice macro. The \mathchoice macro
names to the funcs list.
takes four arguments, one for each of the four LaTeX math
styles display, text, script, and scriptscript. The correct argument
is typeset by LaTeX based on the current math style. Debugging and access to stderr
PythonTeX commands and environments save the Python code
Step-by-step derivations with SymPy
they contain to an external file, where it is processed by Python-
TeX. When the Python code is executed, errors may occur. The
With SymPy’s LaTeX functionality, it is simple to automate tasks line numbers for these errors do not correspond to the document
that could otherwise be tedious. Instead of manually typing step- line numbers, because only the Python code contained in the
by-step mathematical solutions, or copying them from an external document is executed; the LaTeX code is not present. Furthermore,
program, the user can generate them automatically from within the error line numbers do not correspond to the line numbers
LaTeX. that would be obtained by only counting the Python code in
PYTHONTEX: FAST ACCESS TO PYTHON FROM WITHIN LATEX 35

the document, because PythonTeX must execute some boilerplate that was executed may be shown, or simply a name based on
management code in addition to the user’s code. This presents a the session ("errorsession.py" in this case), or the more
challenge for debugging. generic "<file>" or "<script>". Second, the line number
PythonTeX addresses this issue by tracking the original LaTeX shown corresponds to the code that was actually entered in the
document line number for each piece of code. All error messages document, not to the document line number or to the line number
are parsed, and Python code line numbers are converted to LaTeX of the code that was actually executed (which would have included
document line numbers. The raw stderr from the Python code is PythonTeX boilerplate). To accomplish this, PythonTeX parses the
interspersed with PythonTeX messages giving the document line stderr and corrects the line number, so that the typeset code and
numbers. For example, consider the following code, with a syntax the typeset stderr are in sync.
error in the last line:
\begin{pyblock}[errorsession] General code highlighting with Pygments
x = 1 The primary purpose of PythonTeX is to execute Python code
y = 2
z = x + y + included in LaTeX documents and provide access to the output.
\end{pyblock} Once support for Pygments highlighting of Python code was added
[Pyg], however, it was simple to add support for general code
The error occurred on line 3 of the Python code, but this might highlighting.
be line 104 of the actual document and line 47 of the combined PythonTeX provides a \pygment command for typesetting
code and boilerplate. In this case, running the PythonTeX script inline code snippets, a pygments environment for typesetting
that processes Python code would produce the following message, blocks of code, and an \inputpygments command for bring-
where <temp file name> would be the name of a temporary ing in and highlighting an external file. All of these have a
file that was executed: mandatory argument that specifies the Pygments lexer to be used.
* PythonTeX code error on line 104: For example, \pygment{latex}{\pygment} produces
File "<temp file name>", line 47
z = x + y + \pygment
^
SyntaxError: invalid syntax in a form suitable for inline use while
Thus, finding code error locations is as simple as it would be if \begin{pygments}{python}
the code were written in separate files and executed individually. def f(x):
return x**3
PythonTeX is the first Python-LaTeX solution to provide such
\end{pygments}
comprehensive error line synchronization.
In general, errors are something to avoid. In the context of creates
writing about code, however, they may be created intentionally for
instructional purposes. Thus, PythonTeX also provides access to def f(x):
return x**3
error messages in a form suitable for typesetting. If the PythonTeX
package option stderr is enabled, any error message created by The pygments environment and the \inputpygments com-
the most recent PythonTeX command or environment is available mand accept an optional argument containing fancyvrb set-
via \stderrpythontex. By default, stderr content is brought tings.
in as LaTeX verbatim content; this preserves formatting and As far as the author is aware, PythonTeX is the only LaTeX
prevents issues caused by stderr content not being valid LaTeX. package that provides Pygments highlighting with Unicode sup-
Python code and the error it produces may be typeset next to port under the standard pdfTeX engine. The listings package
each other. Reusing the previous example, [LST], probably the most prominent non-Pygments highlighting
\begin{pyblock}[errorsession] package, does support Unicode—but only if the user follows spe-
x = 1 cial procedures that could become tedious. PythonTeX requires no
y = 2 special treatment of Unicode characters, so long as the fontenc
z = x + y + and inputenc packages are loaded and used correctly. For
\end{pyblock}
example, PythonTeX can correctly highlight the following snippet
creates the following typeset code: copied and pasted from a Python 3 console session, without any
modification.
x = 1
y = 2 >>> var1 = 'âæéöø'
z = x + y + >>> var2 = 'ßçñðŠ'
>>> var1 + var2
The stderr may be brought in via \stderrpythontex: 'âæéöøßçñðŠ'

File "<file>", line 3


z = x + y +
^ Implementation
SyntaxError: invalid syntax
A brief overview of the internal workings of PythonTeX is
Two things are noteworthy about the form of the stderr. provided below. For additional details, please consult the docu-
First, in the case shown, the file name is given as "<file>". mentation.
PythonTeX provides a package option stderrfilename for When a LaTeX document is compiled, the PythonTeX com-
controlling this name. The actual name of the temporary file mands and environments write their contents to a single shared
36 PROC. OF THE 11th PYTHON IN SCIENCE CONF. (SCIPY 2012)

external file. The command and environment contents are inter- ument’s PythonTeX commands or environments are modified. By
spersed with delimiters, which contain information about the type default, all files created by PythonTeX are kept in a subdirectory
of command or environment, the session in which the code is to within the document directory, keeping things tidy.
be executed, the document line number where the code originated,
and similar tracking information. A single external file is used to Conclusion
minimize the number of temporary files created, and because TeX
PythonTeX provides access to the full power of Python from
has a very limited number of output streams.
within LaTeX documents. This can greatly simplify the creation
During compilation, each command and environment also
of scientific documents and presentations.
checks for any Python-generated content that belongs to it, and
One of the potential drawbacks of using a special LaTeX pack-
brings in this content if it exists. Python-generated content is
age like PythonTeX is that publishers may not support it. Since
brought in via LaTeX macros and via separate external files. At the
PythonTeX saves all Python-generated content, it already provides
beginning of the LaTeX document, the PythonTeX package brings
document compilation without the execution of any Python code,
in two files of LaTeX macros that were created on the Python
so that aspect will not be an issue. Ideally, a PythonTeX document
side, if these files exist. One file consists of macros containing
and its Python output could be merged into a single, new document
the Python content accessed by \py, \pylab, and \sympy. The
that does not require the PythonTeX package. This feature is being
other file contains highlighted Pygments content. The files are
considered for an upcoming release.
separate for performance reasons. In addition to content that is
PythonTeX provides many features not discussed here, in-
brought in via macros, content may be brought in via separate
cluding a number of formatting options and methods for adding
external files. Each command or environment that uses the print
custom code to all sessions. PythonTeX is also under active de-
statement/function must bring in an external file containing the
velopment. For additional information and the latest code, please
printed content. The printed content cannot be brought in as
visit https://github.com/gpoore/pythontex.
LaTeX macros, because in general printed content need not be
valid LaTeX code. In contrast, \py, \pylab, and \sympy
should return valid LaTeX, and of course Pygments-highlighted R EFERENCES
content is valid LaTeX as well. [Leisch] F. Leisch. Sweave: Dynamic generation of statistical reports using
On the Python side, the file containing code and delimiters literate data analysis, in Wolfgang Härdle and Bernd Rönz, editors,
must be processed. All code is hashed, to determine what has been Compstat 2002 - Proceedings in Computational Statistics, pages
575-580. Physica Verlag, Heidelberg, 2002. ISBN 3-7908-1517-9.
modified since the previous run so that only new and modified
http://www.statistik.lmu.de/~leisch/Sweave/.
code may be executed. Code that must be executed is divided [Ehmsen] M. R. Ehmsen. "Python in LaTeX." http://www.ctan.org/pkg/
by session, and each session (plus some PythonTeX management python.
code) is saved to its own external file. The highlighting settings [Drake] D. Drake. "The SageTeX package." https://bitbucket.org/ddrake/
sagetex/.
for Pygments content are compared with the settings for the last [Molteno] T. Molteno. "The sympytex package." https://github.com/tmolteno/
run, to determine what needs to be highlighted again with new SympyTeX/.
settings. [SymPy] SymPy Development Team. "SymPy." http://sympy.org/.
Next, Python’s multiprocessing package is used to per- [Pyg] The Pocoo Team. "Pygments: Python Syntax Highlighter." http:
//pygments.org/.
form all necessary tasks. Each of the session code files is executed [FV] T. Van Zandt, D. Girou, S. Rahtz, and H. Voß. "The ’fancyvrb’
within a separate process. The process executes the file, parses package: Fancy Verbatims in LaTeX." http://www.ctan.org/pkg/
the stdout into separate files of printed content based on the fancyvrb.
[MPL] J. D. Hunter. Matplotlib: A 2D Graphics Environment, in Comput-
command or environment from which it originated, and parses ing in Science & Engineering, Vol. 9, No. 3. (2007), pp. 90-95.
the stderr to synchronize it with the document line numbers. If http://matplotlib.sourceforge.net/.
specified by the user, a modified version of the stderr is created [NP] Numpy developers. "NumPy." http://numpy.scipy.org/.
and saved in an external file for inclusion in the document via [LST] C. Heinz and B. Moses. "The Listings Package." http://www.ctan.
org/tex-archive/macros/latex/contrib/listings/.
\stderrpythontex. Two additional processes are used, one [IPY] The IPython development team. "The IPython Notebook." http:
for highlighting code with Pygments and one for evaluating and //ipython.org/notebook.html.
highlighting all console content (using Python’s code module). [Pastell] M. Pastell. "Pweave - reports from data with Python." http:
//mpastell.com/pweave/.
Finally, all LaTeX macros created by all processes are saved [Knuth] D. E. Knuth. Literate Programming. CSLI Lecture Notes, no.
in one of two external files, depending on whether they contain 27. Stanford, California: Center for the Study of Language and
general content or content highlighted by Pygments (again, this is Information, 1992.
for performance reasons). All information that will be needed the [Ramsey] N. Ramsey. Literate programming simplified. IEEE Soft-
ware, 11(5):97-105, September 1994. http://www.cs.tufts.edu/~nr/
next time the Python side runs is saved. This includes the hashes noweb/.
for each session. Any session that produced errors is automatically [Schwab] M. Schwab, M. Karrenbach, and J. Claerbout. Making scientific
set to be executed the next time the Python side runs. A list of all computations reproducible. Computing in Science & Engineering,
2(6):61-67, Nov/Dec 2000.
files that were automatically created by PythonTeX is also saved, [Xie] Y. Xie. "knitr: Elegant, flexible and fast dynamic report generation
so that future runs can clean up outdated and unused files. with R." http://yihui.name/knitr/.
PythonTeX consists of a LaTeX package and several Python [MK] M. Bayer. "Mako Templates for Python." http://www.
scripts. A complete compilation cycle for a PythonTeX document makotemplates.org/.
involves running LaTeX to create the file of code and delimiters,
running the PythonTeX script to create Python content, and finally
running LaTeX again to compile the document with Python-
generated content included. Since all Python-generated content
is saved, the PythonTeX script only needs to be run when the doc-

You might also like