0% found this document useful (0 votes)
84 views

Pythontex

Uploaded by

dario
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views

Pythontex

Uploaded by

dario
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 149

The pythontex package

Geoffrey M. Poore
gpoore@gmail.com
github.com/gpoore/pythontex

v0.18 from 2021/06/06

Abstract
PythonTEX provides access to Python from within LATEX documents. It
allows Python code entered within a LATEX document to be executed, and
the results to be included within the original document. Python code may
be adjacent to the figure or calculation it produces. The package also makes
possible macro definitions that mix Python and LATEX code. In addition,
PythonTEX provides syntax highlighting for many programming languages
via the Pygments syntax highlighter.
PythonTEX is fast and user-friendly. Python code is only executed when
it has been modified, or when user-specified criteria are met. When code
is executed, user-defined sessions automatically run in parallel. If Python
code produces errors, the error message line numbers are synchronized with
the LATEX document line numbering, simplifying debugging. Dependencies
may be specified so that code is automatically re-executed whenever they
are modified.
Because documents that use PythonTEX mix LATEX and Python code,
they are less suitable than plain LATEX documents for journal submis-
sion, sharing, and conversion to other formats. PythonTEX includes
a depythontex utility that creates a copy of a document in which all
PythonTEX content is replaced by its output.
While Python is the focus of PythonTEX, adding basic support for an
additional language is usually as simple as creating a new class instance and
a few templates, usually totaling less than 100 lines of code. The following
languages already have built-in support: Ruby, Julia, Octave, Bash, Rust,
R, Perl, Perl 6, and JavaScript.

Warning
PythonTEX makes possible some pretty amazing things. But that power brings
with it a certain risk and responsibility. Compiling a document that uses
PythonTEX involves executing Python code, and potentially other programs, on
your computer. You should only compile PythonTEX documents from sources you
trust. PythonTEX comes with NO WARRANTY.1 The copyright holder and any
additional authors will not be liable for any damages.
1 All LAT X code is licensed under the L
AT X Project Public License (LPPL) and all Python
E E
code is licensed under the BSD 3-Clause License.

1
Contents
1 Introduction 5

2 Citing PythonTEX 8

3 Installing and running 9


3.1 Installing PythonTEX . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2 Compiling documents using PythonTEX . . . . . . . . . . . . . . . 11

4 Usage 16
4.1 Package options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.2 Commands and environments . . . . . . . . . . . . . . . . . . . . . 21
4.2.1 Inline commands . . . . . . . . . . . . . . . . . . . . . . . . 22
4.2.2 Environments . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2.3 Console command and environment families . . . . . . . . . 25
4.2.4 Default families . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2.5 Custom code . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.2.6 PythonTEX utilities class . . . . . . . . . . . . . . . . . . . 28
4.2.7 Formatting of typeset code . . . . . . . . . . . . . . . . . . 32
4.2.8 Access to printed content (stdout) and error messages (stderr) 33
4.3 Pygments commands and environments . . . . . . . . . . . . . . . 35
4.4 General code typesetting . . . . . . . . . . . . . . . . . . . . . . . . 36
4.4.1 Listings float . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.4.2 Background colors . . . . . . . . . . . . . . . . . . . . . . . 36
4.4.3 Referencing code by line number . . . . . . . . . . . . . . . 36
4.4.4 Beamer compatibility . . . . . . . . . . . . . . . . . . . . . 37
4.5 Advanced PythonTEX usage . . . . . . . . . . . . . . . . . . . . . . 37
4.6 Working with other programs . . . . . . . . . . . . . . . . . . . . . 40
4.6.1 latexmk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5 depythontex 41
5.1 Preparing a document that will be converted . . . . . . . . . . . . 42
5.2 Removing PythonTEX dependence . . . . . . . . . . . . . . . . . . 43
5.3 Technical details . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

6 LATEX programming with PythonTEX 47


6.1 Macro programming with PythonTEX . . . . . . . . . . . . . . . . 47
6.2 Package writing with PythonTEX . . . . . . . . . . . . . . . . . . . 48

7 Support for additional languages 49


7.1 Ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
7.2 Julia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
7.3 Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
7.4 bash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
7.5 Rust . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
7.6 R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

2
7.7 Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
7.8 Perl 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
7.9 JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
7.10 Adding support for a new language . . . . . . . . . . . . . . . . . . 52
7.10.1 Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
7.10.2 Wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
7.10.3 The CodeEngine class . . . . . . . . . . . . . . . . . . . . . 55
7.10.4 Creating the LATEX interface . . . . . . . . . . . . . . . . . 57

8 Troubleshooting 57

9 The future of PythonTEX 59


9.1 To Do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
9.1.1 Modifications to make . . . . . . . . . . . . . . . . . . . . . 59
9.1.2 Modifications to consider . . . . . . . . . . . . . . . . . . . 60

Version History 61

10 Implementation 75
10.1 Package opening . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.2 Required packages . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.3 Package options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.3.1 Enabling command and environment families . . . . . . . . 76
10.3.2 Gobble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.3.3 Beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.3.4 Runall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.3.5 Rerun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.3.6 Hashdependencies . . . . . . . . . . . . . . . . . . . . . . . 77
10.3.7 Autoprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
10.3.8 Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
10.3.9 makestderr . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
10.3.10 stderrfilename . . . . . . . . . . . . . . . . . . . . . . . . . . 79
10.3.11 Python’s __future__ module . . . . . . . . . . . . . . . . . 80
10.3.12 Upquote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
10.3.13 Fix math spacing . . . . . . . . . . . . . . . . . . . . . . . . 80
10.3.14 Keep temporary files . . . . . . . . . . . . . . . . . . . . . . 81
10.3.15 Pygments . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
10.3.16 Python console environment . . . . . . . . . . . . . . . . . . 83
10.3.17 depythontex . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
10.3.18 Process options . . . . . . . . . . . . . . . . . . . . . . . . . 84
10.4 Utility macros and input/output setup . . . . . . . . . . . . . . . . 85
10.4.1 Automatic counter creation . . . . . . . . . . . . . . . . . . 85
10.4.2 Saving verbatim content in macros . . . . . . . . . . . . . . 85
10.4.3 Code context . . . . . . . . . . . . . . . . . . . . . . . . . . 86
10.4.4 Code groups . . . . . . . . . . . . . . . . . . . . . . . . . . 86
10.4.5 File input and output . . . . . . . . . . . . . . . . . . . . . 88

3
10.4.6 Interface to fancyvrb . . . . . . . . . . . . . . . . . . . . . 93
10.4.7 Enabling fvextra support for Pygments macros . . . . . . 95
10.4.8 Access to printed content (stdout) . . . . . . . . . . . . . . 96
10.4.9 Access to stderr . . . . . . . . . . . . . . . . . . . . . . . . . 98
10.4.10 depythontex . . . . . . . . . . . . . . . . . . . . . . . . . . 99
10.5 Inline commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
10.5.1 Inline core macros . . . . . . . . . . . . . . . . . . . . . . . 103
10.5.2 Inline command constructors . . . . . . . . . . . . . . . . . 109
10.6 Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
10.6.1 Block and verbatim environment constructors . . . . . . . . 113
10.6.2 Code environment constructor . . . . . . . . . . . . . . . . 119
10.6.3 Sub environment constructor . . . . . . . . . . . . . . . . . 122
10.6.4 Console environment constructor . . . . . . . . . . . . . . . 123
10.7 Constructors for command and environment families . . . . . . . . 125
10.8 Default commands and environment families . . . . . . . . . . . . . 129
10.9 Listings environment . . . . . . . . . . . . . . . . . . . . . . . . . . 130
10.10Pygments for general code typesetting . . . . . . . . . . . . . . . . 131
10.11Pygments utilities macros . . . . . . . . . . . . . . . . . . . . . . . 131
10.11.1 Inline Pygments command . . . . . . . . . . . . . . . . . . . 132
10.11.2 Pygments environment . . . . . . . . . . . . . . . . . . . . . 133
10.11.3 Special Pygments commands . . . . . . . . . . . . . . . . . 135
10.11.4 Creating the Pygments commands and environment . . . . 137
10.12Final cleanup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
10.13Compatibility with beta releases . . . . . . . . . . . . . . . . . . . 139

4
1 Introduction
This introduction provides background and objectives for the PythonTEX package.
To jump right in and get started, you may wish to consult the pythontex_quickstart
and pythontex_gallery documents, as well as Sections 3 and 4, below. If you
are primarily interested in using PythonTEX with a language other than Python,
see Section 7.
LATEX can do a lot,2 but the programming required can sometimes be painful.3
In spite of the many packages available for LATEX, the libraries and packages
of a general-purpose programming language are lacking. Furthermore, it can be
convenient to include non-LATEX code in a document to make it more reproducible.
For these reasons, there have been multiple systems that allow other languages to
be used within LATEX documents.4
• PerlTEX allows the bodies of LATEX macros to be written in Perl.
• SageTEX allows code for the Sage mathematics software to be executed from
within a LATEX document.
• Martin R. Ehmsen’s python.sty provides a very basic method of executing
Python code from within a LATEX document.
• SympyTEX allows more sophisticated Python execution, and is largely based
on a subset of SageTEX.
• LuaTEX extends the pdfTEX engine to provide Lua as an embedded scripting
language, and as a result yields tight, low-level Lua integration.
PythonTEX attempts to fill a perceived gap in the current integrations of LATEX
with an additional language. It has a number of objectives, only some of which
have been met by previous packages.
Execution speed
In the approaches mentioned above, all the non-LATEX code is executed
at every compilation of the LATEX document (PerlTEX, LuaTEX, and
python.sty), or all the non-LATEX code is executed every time it is modified
(SageTEX and SympyTEX). However, many tasks such as plotting and data
analysis take a significant time to execute. We need a way to fine-tune code
execution, so that independent blocks of slow code may be separated into
their own sessions and are only executed when modified. If we are going
to split code into multiple sessions, we might as well run these sessions in
parallel, further increasing speed. A byproduct of this approach is that it
now becomes much more feasible to include slower code, since we can still
have fast compilations whenever the slow code isn’t modified.
2T
EX is a Turing-complete language.
3 AsI learned in creating this package.
4 I am not including the various web and weave dialects in my discussion, since they typically

involve a web or weave document from which the .tex source is generated, and thus weaker
integration with LATEX. Two sophisticated examples of this approach are Sweave and knitr, both
of which combine LATEX with the R language for tasks such as dynamic report generation.

5
Compiling without executing
Even with all of these features to boost execution speed, there will be times
when we have to run slow code. Thus, we need the execution of non-LATEX
code to be separated from compiling the LATEX document. We need to be
able to edit and compile a document containing unexecuted code. Unex-
ecuted code should be invisible or be replaced by placeholders. SageTEX
and SympyTEX have implemented such a separation of compiling and ex-
ecuting. In contrast, LuaTEX and PerlTEX execute all the code at each
compilation—but that is appropriate given their goal of simplifying macro
programming.
Error messages
Whenever code is saved from a LATEX document to an external file and then
executed, the line numbers for any error messages will not correspond to the
line numbering of the original LATEX document. At one extreme, python.sty
doesn’t attempt to deal with this issue, while at the other extreme, SageTEX
uses an ingenous system of Try/Except statements on every chunk of code.
We need a system that translates all error messages so that they correspond
to the line numbering of the original LATEX document, with minimal overhead
when there are no errors.
Syntax highlighting
Once we begin using non-LATEX code, sooner or later we will want to typeset
some of it, which means we need syntax highlighting. A number of syntax
highlighting packages currently exist for LATEX; perhaps the most popular
are listings and minted. listings uses pure LATEX. It has not been up-
dated since 2007, which makes it a less ideal solution in some circumstances.
minted uses the Python-based syntax highlighter Pygments to perform high-
lighting. Pygments can provide superior syntax highlighting, but minted can
be very slow because all code must be highlighted at each compilation and
each instance of highlighting involves launching an external Python process.
We need high-speed, user-friendly syntax highlighting via Pygments.5
Printing
It would be nice for the print statement/function,6 or its equivalent, to
automatically return its output within the LATEX document. For example,
using python.sty it is possible to generate some text while in Python, open a
file, save the text to it, close the file, and then \input the file after returning
to LATEX. But it is much simpler to generate the text and print it, since
the printed content is automatically included in the LATEX document. This
was one of the things that python.sty really got right.
5 The author recently started maintaining the minted package. In the near future, minted will

inherit PythonTEX’s speed enhancements, and the two packages will become more compatible.
6 In Python, print was a statement until Python 3, when it be-
came a function. The function form is available via import from
\textunderscore\textunderscore future\textunderscore\textunderscore in Python 2.6
and later.

6
Pure code
LATEX has a number of special characters (# $ % & ~ _ ^ \ { }), which
complicates the entry of non-LATEX code since these same characters are
common in many languages. SageTEX and SympyTEX delimit all inline code
with curly braces ({}), but this approach fails in the (somewhat unlikely)
event that code needs to contain an unmatched brace. More seriously, they
do not allow the percent symbol % (modular arithmetic and string formatting
in Sage and Python) to be used within inline code. Rather, a \percent
macro must be used instead. This means that code must (sometimes) be
entered as a hybrid between LATEX and the non-LATEX language. LuaTEX is
somewhat similar: “The main thing about Lua code in a TeX document is
this: the code is expanded by TeX before Lua gets to it. This means that
all the Lua code, even the comments, must be valid TeX!”7 In the case of
LuaTEX, though, there is the luacode package that allows for pure Lua.
This language hybridization is not terribly difficult to work around in the
SageTEX and SympyTEX cases, and is actually a LuaTEX feature in many
contexts. But if we are going to create a system for general-purpose access
to a non-LATEX language, we need all valid code to work correctly in all
contexts, with no hybridization of any sort required. We should be able
to copy and paste valid code into a LATEX document, without having to
worry about hybridizing it. Among other things, this means that inline code
delimiters other than LATEX’s default curly braces {} must be available.

Hybrid code
Although we need a system that allows input of pure non-LATEX code, it
would also be convenient to allow hybrid code, or code in which LATEX
macros may be present and are expanded before the code is executed. This
allows LATEX data to be easily passed to the non-LATEX language, facilitat-
ing a tighter integration of the two languages and the use of the non-LATEX
language in macro definitions.
Math and science libraries
The author decided to create PythonTEX after writing a physics disserta-
tion using LATEX and realizing how frustrating it can be to switch back and
forth between a TEX editor and plotting software when fine-tuning figures.
We need access to a non-LATEX language like Python, MATLAB, or Mathe-
matica that provides strong support for data analysis and visualization. To
maintain broad appeal, this language should primarily involve open-source
tools, should have strong cross-platform support, and should also be suitable
for general-purpose programming.

Language-independent implementation
It would be nice to have a system for executing non-LATEX code that depends
very little on the language of the code. We should not expect to escape
all language dependence. But if the system is designed to be as general
7 http://wiki.contextgarden.net/Programming_in_LuaTeX

7
as possible, then it may be expanded in the future to support additional
languages.
Python was chosen as the language to fulfill these objectives for several reasons.
• It is open-source and has good cross-platform support.

• It has a strong set of scientific, numeric, and visualization packages, including


NumPy, SciPy, matplotlib, and SymPy. Much of the initial motivation for
PythonTEX was the ability to create publication-quality plots and perform
complex mathematical calculations without having to leave the TEX editor.
• We need a language that is suitable for scripting. Lua is already available
via LuaTEX, and in any case lacks the math and science tools.8 Perl is al-
ready available via PerlTEX, although PerlTEX’s emphasis on Perl for macro
creation makes it rather unsuitable for scientific work using the Perl Data
Language (PDL) or for more general programming. Python is one logical
choice for scripting.

Now at this point there will almost certainly be some reader, sooner or later,
who wants to object, “But what about language X !” Well, yes, in some respects
the choice to use Python did come down to personal preference. But you should
give Python a try, if you haven’t already. You may also wish to consider the many
interfaces that are available between Python and other languages. If you still
aren’t satisfied, keep in mind PythonTEX’s “language-independent” implementa-
tion! In many cases, adding support for additional languages is relatively simple
(see Section 7).

2 Citing PythonTEX
If you use PythonTEX in your writing and research, please consider citing it in
any resulting publications. The best and most recent paper is in Computational
Science & Discovery.
• “PythonTeX: reproducible documents with LaTeX, Python, and more,” Ge-
offrey M Poore. Computational Science & Discovery 8 (2015) 014010. Full
text and BibTEX entry available at http://stacks.iop.org/1749-4699/
8/i=1/a=014010.

• “Reproducible Documents with PythonTeX,” Geoffrey M. Poore. Pro-


ceedings of the 12th Python in Science Conference (2013), pp. 73–79.
Full text and BibTEX entry available at http://conference.scipy.org/
proceedings/scipy2013/poore.html.
8 One could use Lunatic Python, and some numeric packages for Lua are in development.

8
3 Installing and running
3.1 Installing PythonTEX
PythonTEX requires a TEX installation. It has been tested with TEX Live and
MiKTEX, but should work with other distributions. The following LATEX packages,
with their dependencies, are required: fancyvrb, fvextra, etoolbox, xstring,
pgfopts, newfloat (part of the caption bundle), currfile, and color or xcolor.
A current TEX installation is recommended, since some features require recent
versions of the packages. If you are creating and including graphics, you will also
need graphicx. The mdframed package is recommended for enclosing typeset code
in boxes with fancy borders and/or background colors; tcolorbox and framed are
alternatives.
PythonTEX also requires a Python installation. Python 2.7 is recommended
for the greatest compatibility with scientific tools, although many scientific pack-
ages are now compatible with Python 3. PythonTEX is compatible with Python
2.7 and 3.2+. The Python package Pygments must be installed for syntax
highlighting to function. PythonTEX has been tested with Pygments 1.4 and
later, but the latest version is recommended. For scientific work, or to compile
pythontex_gallery.tex, the following are also recommended: NumPy, SciPy,
matplotlib, and SymPy. When using PythonTEX with LyX, be aware that LyX
may try to use its own version of Python; you may need to reconfigure LyX.
PythonTEX also provides support for other languages such as Ruby, so you
will need to install any additional languags you plan to use. Typically, the most
recent major version of these languages is supported.
PythonTEX consists of the following files:
• Installer file pythontex.ins
• Documented LATEX source file pythontex.dtx, from which pythontex.pdf
and pythontex.sty are generated
• Main script pythontex.py, which imports from pythontex2.py or pythontex3.py,
based on the Python version
• Language definitions pythontex_engines.py

• Utilities class pythontex_utils.py


• depythontex.py, which imports from depythontex2.py or depythontex3.py,
based on the Python version; used to remove PythonTEX dependence
• Synchronized Python Debugger syncpdb.py

• README (in rst style)


• pythontex_gallery.tex and pythontex_gallery.pdf
• pythontex_quickstart.tex and pythontex_quickstart.pdf

9
• Optional installation script pythontex_install.py for TEX Live and MiK-
TeX
• Optional batch file pythontex.bat for use in launching pythontex.py under
Windows

• Optional conversion script pythontex_2to3.py for converting PythonTEX


code written for Python 2 into a form compatible with Python 3
The style file pythontex.sty may be generated by running LATEX on pythontex.ins.
The documentation you are reading may be generated by running LATEX on
pythontex.dtx. Some code is provided in two forms, one for Python 2 and one
for Python 3 (names ending in 2 and 3). Whenever this is the case, a version-
independent wrapper is supplied that automatically runs the correct code based
on the Python version. For example, there are two main scripts, pythontex2.py
and pythontex3.py, but you should actually run pythontex.py, which imports
the correct code based on the Python version.9
If you want the absolute latest version of PythonTEX, you should install it man-
ually from github.com/gpoore/pythontex. A Python installation script is provided
for use with TEX Live and MiKTeX. It has been tested with Windows, Linux, and
OS X, but may need manual input or slight modifications depending on your
system. The installation script performs the steps described below.
For a MiKTeX installation, you may need administrator privileges;
running pythontex_install.bat as administrator may be simplest.
Note that for a typical TEX setup under Linux, you may need to run
the script with elevated privileges, and may need to run it with the
user’s PATH. This can be necessary when you are using a Linux distribution
that includes an outdated version of TEX Live, and have installed a new version
manually. If you are installing PythonTEX on a machine with multiple
versions of TEX, make sure you install PythonTEX for the correct ver-
sion. For example, under Ubuntu Linux, you will probably need the following
command if you have installed the latest version of TEX Live manually:
sudo env PATH=$PATH python pythontex_install.py

The installer creates the following files. It will offer to create the paths if
they do not exist. If you are installing in TEXMFLOCAL, the paths will have an
additional local/ at the end.

• hTEX tree rooti/doc/latex/pythontex/


– pythontex.pdf
– README
9 Unfortunately, it is not possible to provide full Unicode support for both Python 2 and 3
using a single script. Currently, all code is written for Python 2, and then the Python 3 version
is automatically generated via the pythontex\_2to3.py script. This script comments out code
that is only for Python 2, and un-comments code that is only for Python 3.

10
– pythontex_quickstart.tex
– pythontex_quickstart.pdf
– pythontex_gallery.tex
– pythontex_gallery.pdf

• hTEX tree rooti/scripts/pythontex/


– pythontex.py, pythontex2.py and pythontex3.py
– pythontex_engines.py
– pythontex_utils.py
– depythontex.py, depythontex2.py and depythontex3.py
– syncpdb.py
• hTEX tree rooti/source/latex/pythontex/
– pythontex.dtx
– pythontex.ins
• hTEX tree rooti/tex/latex/pythontex/
– pythontex.sty
After the files are installed, the system must be made aware of their exis-
tence. The installer runs mktexlsr to do this. In order for pythontex.py and
depythontex.py to be executable, a symlink (TEX Live under Linux), launch-
ing wrapper (TEX Live under Windows), or batch file (general Windows) should
be created in the bin/hsystemi directory. The installer attempts to create a
symlink or launching wrapper automatically. For TEX Live under Windows, it
copies bin/win32/runscript.exe to bin/win32/pythontex.exe to create the
wrapper.10

3.2 Compiling documents using PythonTEX


Compiling a document with PythonTEX involves three steps: running a LATEX-
compatible TEX engine (binary executable), running pythontex.py (preferably
via a symlink, wrapper, or batch file, as described above), and finally running
the TEX engine again. The first TEX run saves code into an external file where
PythonTEX can access it. The second TEX run pulls the PythonTEX output back
into the document.
If you plan to use code that contains non-ASCII characters such as Unicode,
you should make sure that your document is properly configured:

• Under pdfLaTeX, your documents need \usepackage[T1]{fontenc} and


\usepackage[utf8]{inputenc}, or a similar configuration.
10 See the output of runscript -h under Windows for additional details.

11
• Under LuaLaTeX, your documents need \usepackage{fontspec}, or a sim-
ilar configuration.
• Under XeLaTeX, your documents need \usepackage{fontspec} as well as
\defaultfontfeatures{Ligatures=TeX}, or a similar configuration.
For an example of a PythonTEX document that will correctly compile under all
three engines, see the pythontex_gallery.tex source.
If you use XeLaTeX, and your non-LATEX code contains tabs, you must invoke
XeLaTeX with the -8bit option so that tabs will be written to file as actual tab
characters rather than as the character sequence ^^I.11
pythontex.py requires a single command-line argument: the name of the .tex
file to process. The filename can be passed with or without an extension; the
script really only needs the \jobname, so any extension is stripped off.12 The
filename may include the path to the file; you do not have to be in the same
directory as the file to run PythonTEX. If you are configuring your editor to run
PythonTEX automatically via a shortcut, you may want to wrap the filename in
double quotes " to allow for space characters.13 For example, under Windows
with TEX Live and Python 2.7 we would create the wrapper pythontex.exe.
Then we could run PythonTEX on a file hfile namei.tex using the command
pythontex.exe "hfile namei".
pythontex.py accepts the following optional command-line arguments. Some
of these options duplicate package-level options, so that settings may be config-
ured either within the document or at the command line. In the event that the
command-line and package options conflict, the package options always override
the command-line options. For variations on these options that are acceptable,
run pythontex.py -h.
• --encoding=hencodingi This sets the file encoding. Any encoding supported
by Python’s codecs module may be used. The encoding should match that
of the LATEX document. If an encoding is not specified, PythonTEX uses
UTF-8. If support for characters beyond ASCII is required, then additional
LATEX packages are required; see the discussion of TEX engines above.
• --error-exit-code={true,false} By default, pythontex.py returns an
exit code of 1 if there were any errors, and an exit code of 0 otherwise.
This may be useful when PythonTEX is used in a scripting or command-line
context, since the presence of errors may be easily detected. It is also useful
with some TEX editors. For example, TeXworks automatically hides the
output of external programs unless there are errors.
In some contexts, returning a nonzero exit code can be redundant. For exam-
ple, with the WinShell editor under Windows with TeX Live, the complete
11 See http://tex.stackexchange.com/questions/58732/how-to-output-a-tabulation-into-a-file

for more on tabs with XeTeX.


12 Thus, PythonT X works happily with .tex, .ltx, .dtx, and any other extension.
E
13 Using spaces in the names of .tex files is apparently frowned upon. But if you configure

things to handle spaces whenever it doesn’t take much extra work, then that’s one less thing
that can go wrong.

12
output of PythonTEX is always available in the “Output” view, so it is clear
if errors have occurred. Having a nonzero exit code causes runscript.exe
to return an additional, redundant error message in the “Output” view. In
such situations, it may be desirable to disable the nonzero exit code.
• --runall=[{true,false}] This causes all code to be executed, regardless
of modification or rerun settings. It is useful when code has not been modi-
fied, but a dependency such as a library or external data has changed. Note
that the PythonTEX utilities class also provides a mechanism for automat-
ically re-executing code that depends on external files when those external
files are modified.
There is an equivalent runall package option. The command-line option
--rerun=always is essentially equivalent.
• --rerun={never,modified,errors,warnings,always} This sets the thresh-
old for re-executing code. By default, PythonTEX will rerun code that has
been modified or that produced errors on the last run. Sometimes, we may
wish to have a more lenient setting (only rerun if modified) or a more strin-
gent setting (rerun even for warnings, or just rerun everything). never never
executes code; a warning is issued if there is modified code. modified only
executes code that has been modified (or that has modified dependencies).
errors executes all modified code as well as all code that produced errors
on the last run; this is the default. warnings executes all modified code, as
well as all code that produced errors or warnings. always executes all code
always and is essentially equivalent to --runall.
There is an equivalent rerun package option.
• --hashdependencies=[{true,false}] This determines whether dependen-
cies (external files highlighted by Pygments, code dependencies specified via
pytex.add_dependencies(), etc.) are checked for changes via their hashes
or modification times. By default, mtime is used, since it is faster. The
package option hashdependencies is equivalent.
• --jobs This sets the maximum number of concurrent processes. By default,
this will be Python’s multiprocessing.cpu_count(), which is the number
of CPUs in the system. It may be useful to set a smaller value when some
jobs are particularly resource intensive or themselves use subprocesses.
• --verbose This gives more verbose output, including a list of all processes
that are launched.
• --interpreter This allows the interpreter for a given language to be spec-
ified. The argument should be in the form

--interpreter "<interpreter>:<command>, <interp>:<cmd>, ..."

13
where <interpreter> is python, ruby, etc., and <command> is the command
for invoking the desired interpreter. The argument to --interpreter may
also be in the form of a Python dictionary. The argument need not be
enclosed in quotation marks if it contains no spaces.
For example, by default Python code is executed with whatever inter-
preter the python command invokes. But Python 3 could be speci-
fied using --interpreter python:python3 (many Linux distributions) or
--interpreter "python:py -3" (Windows, with Python 3.3 installed so
that the py wrapper is available).
• --interactive [<family>:<session>:<restart>] This is used to run a
single session in interactive mode. This allows user input. Code output is
written to stdout. Interactive mode is particularly useful when working with
debuggers (but also see the --debug option).
[<family>:<session>:<restart>] is optional; if it is not provided, the
default session is executed. For non-default sessions (or if there are
multiple default sessions, due to the use of multiple families of com-
mands), simply supplying the session name is usually sufficient (for example,
--debug session). The full combination of [<family>:<session>:<restart>]
(for example, py:session:default) is only necessary when the session name
alone would be ambiguous.
Note that when a session is run in interactive mode, it will not save printed
content in a form that may be brought back into the document. You will have
to run the session again in normal mode to complete document compilation.
Code that requires user input will cause PythonTEX to “hang” when
PythonTEX is not running in interactive mode. This is because the code
will request user input, but no input is possible given the way that the code
is being executed, so the code will wait for input forever. It is inefficient
constantly to add and then delete interactive code as you switch between
normal and interactive modes. To avoid this, you can conditionally invoke
code that requires input. In interactive mode, the temporary script that
is executed is given the command-line argument --interactive. You can
check for the presence of this argument, and only invoke interactive code if
it is present. For example, under Python you could start the pdb debugger,
only when the code is being executed in interactive mode, using commands
such as the following.

import pdb
import sys
if '--interactive' in sys.argv[1:]:
pdb.set_trace()

This option is currently not compatible with Python console commands and
environments.

14
• --debug [<family>:<session>:<restart>] This is used to run a single
session with the default debugger in interactive mode. Currently, only stan-
dard Python sessions are supported. (Python console commands and envi-
ronments are not supported.) Support for other languages and support for
customization will be added in the future.
[<family>:<session>:<restart>] is optional; if it is not provided, the
default session is executed. For non-default sessions (or if there are
multiple default sessions, due to the use of multiple families of com-
mands), simply supplying the session name is usually sufficient (for example,
--debug session). The full combination of [<family>:<session>:<restart>]
(for example, py:session:default) is only necessary when the session name
alone would be ambiguous.
Note that when a session is run in debug mode, it will not save printed
content in a form that may be brought back into the document. You will have
to run the session again in normal mode to complete document compilation.
The default Python debugger is syncpdb, the Synchronized Python Debug-
ger. It provides a wrapper around pdb that is aware of the connection
between the code and the LATEX document from which it was extracted.
All pdb commands function normally. In addition, commands that take a
line number or filename:lineno as an argument will also take these same
values with a percent symbol % prefix. If the percent symbol is present,
then syncpdb interprets the filename and line number as referring to the
document, rather than to the code that is executed. It will translate the
filename and line number to the corresponding code equivalents, and then
pass these to the standard pdb internals. For example, the pdb command
list 50 would list the code that is being executed, centered around line
50. syncpdb allows the command list %10, which would list the code that
is being executed, centered around the code that came from line 10 in the
main LATEX document. (If no file name is given, then the main LATEX docu-
ment is assumed.) If the code instead came from an inputed file input.tex,
then list %input.tex:10 could be used. Further details are provided at
github.com/gpoore/syncpdb.
The temporary script that is executed is given the command-line argument
--interactive when run in debug mode. You can check for the presence
of this argument if you wish to invoke code that requires user input condi-
tionally. See the --interactive command-line option for more details.
PythonTEX attempts to check for a wide range of errors and return mean-
ingful error messages. But due to the interaction of LATEX and Python code,
some strange errors are possible. If you cannot make sense of errors when
using PythonTEX, the simplest thing to try is deleting all files created by
PythonTEX, then recompiling. By default, these files are stored in a directory
called pythontex-files-hjobnamei, in the same directory as your .tex document.
See Section 8 for more details regarding troubleshooting.

15
4 Usage
4.1 Package options
Package options may be set in the standard manner when the package is loaded:
\usepackage[hoptionsi]{pythontex}
All options are described as follows. The option is listed, followed by its possible
values. When a value is not required, hnonei is listed as a possible value. In this
case, the value to which hnonei defaults is also given. Each option lists its default
setting, if the option is not invoked when the package is loaded.
Some options have a command-line equivalent. Package options override
command-line options.
All options related to printed content are provided in two forms for convenience:
one based on the word print and one based on stdout.
usefamily=hbasename i/{hbasename1, basename2, ... i}
By default, only the py, sympy, and pylab families of commands and envi-
ronments are defined, to prevent possible package conflicts.14 This option defines
preconfigured families for other available languages. It takes either a single lan-
guage base name, or a list of comma-separated names enclosed in curly braces.
For example, the Ruby families rb and ruby, the Julia families jl and julia, and
the Octave family octave may be enabled. For a full list of supported languages,
see Section 7.
gobble=none/auto
default:none This option is still under development and may change somewhat in future
releases. If that occurs, equivalent functionality will be provided.
This option determines how code indentation is handled. By default, in-
dentation is left as-is; leading whitespace is significant. auto will dedent
all code by gobbling the largest common leading whitespace, using Python’s
textwrap.dedent().15 Keep in mind that Python’s dedent will not work cor-
rectly with mixed tabs and spaces.
The gobble option always works correctly with executed code. However,
currently the option only works with typeset code when Pygments is used.
The option is currently only available at the document level, but finer-grained
control is planned in the future.
The gobble option is supported by depythontex.
beta=hnone i/true/false
default:false hnone i=true 14 For example, a \ruby command for Ruby code, and the \ruby command defined by the Ruby

package in the CJK package.


15 It would be possible to do the dedent on the L AT X side, as is done manually in the fancyvrb
E
and listings packages with the gobble option and is done automatically in the lstautogobble
package. This is not done for stability and security reasons. lstautogobble determines the
dedent by extracting the leading whitespace from the first line of code, and then applying this
dedent to each subsequent line. This is adequate for typesetting code, since the worst-case
scenario is that a subsequent line with less indentation will be typeset with the first few characters
missing. Such an approach is not acceptable when the code will be executed, since a few missing
characters could in principle cause serious damage. Doing the dedent on the Python side ensures
that no characters are discarded, even if that results in an indentation error.

16
This option provides compatibility with the beta releases from before the full
v0.11 release, which introduced some changes in syntax and command names.
This option should only be used with old PythonTEX documents that require it.
You are encouraged to update old documents, since this compatility option
will only be provided for a few releases.
runall=hnone i/true/false
default:false hnone i=true This option causes all code to be executed, regardless of whether it has been
modified. This option is primarily useful when code depends on external files,
and needs to be re-executed when those external files are modified, even though
the code itself may not have changed. Note that the PythonTEX utilities class
also provides a mechanism for automatically re-executing code that depends on
external files when those external files are modified.
A command-line equivalent --runall exists for pythontex.py. The package
option rerun=always is essentially equivelent.
rerun=never/modified/errors/warnings/always
default:errors This option sets the threshold for re-executing code. By default, PythonTEX
will rerun code that has been modified or that produced errors on the last run.
Sometimes, we may wish to have a more lenient setting (only rerun if modified)
or a more stringent setting (rerun even for warnings, or always rerun). never
never executes code; a warning is issued if there is modified code. modified only
executes code that has been modified. errors executes all modified code as well
as all code that produced errors on the last run; this is the default. warnings
executes all modified code, as well as all code that produced errors or warnings.
always executes all code regardless of its condition.
A command-line equivalent --rerun exists for pythontex.py.
hashdependencies=hnone i/true/false
default:false hnone i=true When external code files are highlighted with Pygments, or external dependen-
cies are specified via the PythonTEX utilities class, they are checked for modifi-
cation via their modification time (Python’s os.path.getmtime()). Usually, this
should be sufficient—and it offers superior performance, which is important if data
sets are large enough that hashing takes a noticeable amount of time. However,
occasionally hashing may be necessary or desirable, so this option is provided.
A command-line equivalent --hashdependencies exists for pythontex.py.
autoprint=hnone i/true/false
default:true hnone i=true
autostdout=hnone i/true/false Whenever a print command/statement is used, the printed content will au-
default:true hnone i=true tomatically be included in the document, unless the code doing the printing is
being typeset.16 In that case, the printed content must be included using the
16 Note that autoprint only works within the body of the document. The code command and
environment can be used in the preamble, but autoprint is disabled there. It is usually a not a
good idea to print in the preamble, because nothing can be typeset; the only thing that could be
validly printed is LATEX commands that do not typeset content, such as macro definitions. Thus,
it is appropriate that printed content is only brought in while in the preamble if it is explicitly
requested via \string\printpythontex. This approach is also helpful for writing packages using
PythonTEX, since the author does not have to worry about any LATEX commands printed by the
package either not being included (if autoprint is relied upon, but the user turns it off) or being
included twice (if \string\printpythontex is used and autoprint is enabled). Printing should

17
\printpythontex or \stdoutpythontex commands.
Printed content is pulled in directly from the external file in which it is saved,
and is interpreted by LATEX as LATEX code. If you wish to avoid this, you should
print appropriate LATEX commands with your content to ensure that it is typeset
as you desire. Alternatively, you may use \printpythontex or \stdoutpythontex
to bring in printed content in verbatim form, using those commands’ optional verb
and verbatim options.
The autoprint (autostdout) option sets autoprint behavior for the entire doc-
ument. This may be overridden within the document using the \setpythontexautoprint
command.
debug
This option aids in debugging invalid LATEX code that is brought in from
Python. It disables the inclusion of printed content/content written to stdout.
Since printed content should almost always be included, a warning is raised when
this option is used.
Not including printed content is useful when the printed content contains LATEX
errors, and would cause document compilation to fail. When the document fails
to compile, this can prevent modified Python code from being written to the code
file, resulting in an inescapable loop unless printed content is disabled or the saved
output is deleted.
Note that since commands like \py involve printing, they are also disabled.
makestderr=hnone i/true/false
default:false hnone i=true This option determines whether the stderr produced by scripts is available for
input by PythonTEX, via the \stderrpythontex macro. This will not be needed
in most situations. It is intended for typeseting incorrect code next to the errors
that it produces. This option is not true by default, because additional processing
is required to synchronize stderr with the document.
stderrfilename=full/session/genericfile/genericscript
default:full This option governs the file name that appears in stderr. Python errors begin
with a line of the form
File "<file or source>", line <line>
By default (option full), <file or source> is the actual name of the script that
was executed. The name will be in the form hfamily namei_hsessioni_hrestarti.hextensioni.
For example, an error produced by a py command or environment, in the session
mysession, using the default restart (that is, the default \restartpythontexsession
treatment), would be reported in py_mysession_default.py. The session op-
tion replaces the full file name with the name of the session, mysession.py in this
example. The genericfile and genericscript options replace the file name
with <file> and <script>, respectively.
pyfuture=none/all/default
default:default Under Python 2, this determines what is automatically imported from
__future__ for all code. It does not apply to console content. none im-
ports nothing from __future__. all imports everything available in Python
only be used in the preamble with great care.

18
2.7 (absolute_import, division, print_function, and unicode_literals).
default imports a default set of features that should be compatible with al-
most all packages. Everything except unicode_literals is imported, since
unicode_literals can occasionally cause conflicts. Note that imports from
__future__ are also allowed within sessions, so long as they are at the very be-
ginning of the session, as they would have to be in a normal script.
This option has no effect under Python 3.
pyconfuture=none/all/default
default:none This is the equivalent of pyfuture for Python console content. The two
options are separate, because in the console context it may be desirable to show
explicitly all code that is executed.
upquote=hnone i/true/false
default:true hnone i=true This option determines whether the upquote package is loaded. In general, the
upquote package should be loaded, because it ensures that quotes within verbatim
contexts are “upquotes,” that is, ' rather than '.
Using upquote is important beyond mere presentation. It allows code to be
copied directly from the compiled PDF and executed without any errors due to
quotes ' being copied as acute accents ´.
fixlr=hnone i/true/false
default:false hnone i=true This option removes “extra” spacing around \left and \right in math mode.
This spacing is sometimes undesirable, especially when typesetting functions such
as the trig functions. See the implementation for details. Similar functionality is
provided by the mleftright package
keeptemps=hnone i/all/code/none
default:none hnone i=all When PythonTEX runs, it creates a number of temporary files. By default,
none of these are kept. The none option keeps no temp files, the code option
keeps only code temp files (these can be useful for debugging), and the all option
keeps all temp files (code, stdout and stderr for each code file, etc.). Note that this
option does not apply to any user-generated content, since PythonTEX knows very
little about that; it only applies to files that PythonTEX automatically creates by
itself.
prettyprinter=pygments/fancyvrb
default:pygments This allows the user to determine at the document level whether code is typeset
using Pygments or fancyvrb.
The package-level option can be overridden for individual command and en-
vironment families, using the \setpythontexprettyprinter command. Overrid-
ing is never automatic and should generally be avoided, since using Pygments to
highlight only some content results in an inconsistent style. Keep in mind that
Pygment’s text lexer and/or bw style can be used when content needs little or no
syntax highlighting.
prettyprintinline=hnone i/true/false
default:true hnone i=true This determines whether inline content is pretty printed. If it is turned off,
inline content is typeset with fancyvrb.
pygments=hnone i/true/false
default:true hnone i=true This allows the user to determine at the document level whether code is typeset
using Pygments rather than fancyvrb. It is an alias for prettyprinter=pygments.

19
pyginline=hnone i/true/false
default:true hnone i=true This option governs whether inline code, not just code in environments, is
highlighted when Pygments highlighting is in use. When Pygments is in use, it
will highlight everything by default.
It is an alias for prettyprintinline.
pyglexer=hpygments lexer i
default:hnone i This allows a Pygments lexer to be set at the document level. In general, this
option should not be used. It overrides the default lexer for all commands and
environments, for both PythonTEX and Pygments content, and this is usually not
desirable. It should be useful primarily when all content uses the same lexer, and
multiple lexers are compatible with the content.
pygopt={hpygments options i}
default:hnone i This allows Pygments options to be set at the document level. The op-
tions must be enclosed in curly braces {}. Currently, three options may
be passed in this manner: style=hstyle namei, which sets the formatting
style; texcomments, which allows LATEX in code comments to be rendered;
and mathescape, which allows LATEX math mode ($...$) in comments. The
texcomments and mathescape options may be used with an argument (for exam-
ple, texcomments=true/false); if an argument is not supplied, true is assumed.
Example: pygopt={style=colorful, texcomments=true, mathescape=false}.
Pygments options for individual command and environment families may
be set with the \setpythontexpygopt macro; for Pygments content, there is
\setpygmentspygopt. These individual settings are always overridden by the
package option.
fvextfile=hnone i/hinteger i
default:∞ hnone i=25 This option speeds the typesetting of long blocks of code that are created
on the Python side. This includes content highlighted using Pygments and the
console environment. Typesetting speed is increased at the expense of creating
additional external files (in the PythonTEX directory). The hintegeri determines
the number of lines of code at which the system starts using multiple external
files, rather than a single external file. See the implementation for the technical
details; basically, an external file is used rather than fancyvrb’s SaveVerbatim,
which becomes increasingly inefficient as the length of the saved verbatim content
grows. In most situations, this option should not be needed, or should be fine with
the default value or similar “small” integers.
pyconbanner=none/standard/default/pyversion
default:none This option governs the appearance (or disappearance) of a banner at the be-
ginning of Python console environments. (A banner only appears in the first envi-
ronment within each session.) The options none (no banner), standard (standard
Python banner), default (default banner for Python’s code module, standard
banner plus interactive console class name), and pyversion (banner in the form
Python x.y.z) are accepted.
pyconfilename=stdin/console
default:stdin This governs the form of the filename that appears in error messages in Python
console environments. Python errors messages have a form such as the following:

20
>>> z = 1 + 34 +
File "<name>", line 1
z = 1 + 34 +
^
SyntaxError: invalid syntax

The stdin option replaces <name> with <stdin>, as it appears in a standard


Python interactive session. The console option uses <console> instead, which
is the default setting for the Python code module used by PythonTEX to create
Python console environments.
depythontex=hnone i/true/false
default:false hnone i=true This option is used to create a version of the LATEX document that does not
require the PythonTEX package. When invoked, it creates an auxiliary file called
<filename>.depytx. The script depythontex.py uses the original document and
this auxiliary file to create a new document in which all PythonTEX commands and
environments have been replaced by typeset code and code output. For additional
information on depythontex, see Section 5.

4.2 Commands and environments


PythonTEX provides four types of commands for use with inline code and three
environments for use with multiple lines of code, plus special commands and envi-
ronments for console content. All commands and environments are named using
a base name and a command- or environment-specific suffix. A complete set of
commands and environments with the same base name constitutes a command
and environment family. In what follows, the different commands and envi-
ronments are described using the py base name (the py family) as an example.
Most commands and environments cannot be used in the preamble, because
they typeset material and that is not possible in the preamble. The one exception
is the code command and environment. These can be used to enter code, but
need not typeset anything. This allows you to collect your PythonTEX code in
the preamble, if you wish, or even use PythonTEX in package writing. Note that
the package option autoprint is never active in the preamble, so even if a code
command or environment did print in the preamble, printed content would never
be inputted unless \printpythontex or \stdoutpythontex were used.
All commands and environments take a session name as an optional argument.
The session name determines the session in which the code is executed. This allows
code to be executed in multiple independent sessions, increasing speed (sessions
run in parallel) and preventing naming conflicts. If a session is not specified, then
the default session is used. Session names should use the characters a-z, A-Z,
0-9, the hyphen, and the underscore. All characters used must be valid in file
names, since session names are used to create temporary files. The colon is also
allowed, but it is replaced with a hyphen internally, so the sessions code:1 and
code-1 are identical.
In addition, all environments take fancyvrb settings as a second, optional ar-
gument. See the fancyvrb documentation for an explanation of accepted settings.

21
This second optional argument must be preceeded by the first optional argument
(session name). If a named session is not desired, the optional argument can be
left empty (default session), but the square brackets [] must be present so that
the second optional argument may be correctly identified:
\begin{henvironmenti}[][hfancyvrb settingsi]

4.2.1 Inline commands


Inline commands are suitable for single lines of code that need to be executed
within the body of a paragraph or within a larger body of text. The commands
use arbitrary code delimiters (like \verb does), which allows the code to contain
arbitrary characters. Note that this is only guaranteed to work properly when the
inline commands are not inside other macros. If an inline command is used within
another macro, the code will be read by the external macro before PythonTEX
can read the special code characters (that is, LATEX will tokenize the code). The
inline commands can work properly within other macros, but it is best to stick
with curly braces for delimiters in this case and you may have trouble with the
hash # and percent % characters.
\py[hsession i]hopening delim ihcode ihclosing delim i
This command is used for including variable values or other content that can
be converted to a string. It is an alternative to including content via the print
statement/function within other commands/environments.
The \py command sends hcodei to Python, and Python returns a string repre-
sentation of hcodei. hopening delimi and hclosing delimi must be either a pair of
identical, non-space characters, or a pair of curly braces. If curly braces are used
as delimiters, then curly braces may only be used within hcodei if they are paired.
Thus, \py{1+1} sends the code 1+1 to Python, Python evaluates the string repre-
sentation of this code, and the result is returned to LATEX and included as 2. The
commands \py#1+1# and \py@1+1@ would have the same effect. The command
can also be used to access variable values. For example, if the code a=1 had been
executed previously, then \py{a} simply brings the string represantation of a back
into the document as 1.
Assignment is not allowed using \py. For example, \py{a=1} is not valid.
This is because assignment cannot be converted to a string.17
The text returned by Python must be valid LATEX code. Verbatim and other
special content is allowed. The primary reasons for using \py rather than print
are (1) \py is more compact and (2) print requires an external file to be created for
every command or environment in which it is used, while \py and equivalents for
17 It would be simple to allow any code within \textbackslash py, including assignment,

by using a try/except statement. In this way, the functionality of \textbackslash py and


\textbackslash pyc could be merged. While that would be simpler to use, it also has serious
drawbacks. If \textbackslash py is not exclusively used to typeset string representations of
hcodei, then it is no longer possible on the LATEX side to determine whether a command should
return a string. Thus, it is harder to determine, from within a TEX editor, whether pythontex.py
needs to be run; warnings for missing Python content could not be issued, because the system
wouldn’t know (on the LATEX side) whether content was indeed missing.

22
other families share a single external file. Thus, use of \py minimizes the creation
of external files, which is a key design goal for PythonTEX.18 The main reason
for using print rather than \py is if you need to include a very large amount of
material; print’s use of external files won’t use up TEX’s memory, and may give
noticeably better performance once the material is sufficiently long.
\pyc[hsession i]hopening delim ihcode ihclosing delim i
This command is used for executing but not typesetting hcodei. The suffix c
is an abbreviation of code. If the print statement/function is used within hcodei,
printed content will be included automatically so long as the package autoprint
option is set to true (the default setting).
\pys[hsession i]hopening delim ihcode ihclosing delim i
This command performs variable and expression substitution, or string inter-
polation, on hcodei. Fields of the form !{hexpri} in hcodei are replaced with the
evaluated and printed output of hexpri. Then the modified hcodei is inserted into
the document and interpreted as LATEX. The suffix s is an abbreviation of sub,
for “substitute.”
This command is useful for inserting Python-generated content in contexts
where the normal \py and \pyc would not function or would be inconvenient
due to the restrictions imposed by LATEX. Since Python processes hcodei and
performs substitutions before the result is passed to LATEX, substitution fields may
be anywhere, including within parts of hcodei that will become LATEX comments.
Literal exclamation points ! in hcodei only need to be escaped when they
immediately precede an opening curly brace {, or when they precede exclamation
points that precede a brace. Escaping is performed by doubling. Thus, !!{ would
indicate a literal exclamation point followed by a literal curly brace (!{), not the
beginning of a substitution field. And !!!{ would indicate a literal exclamation
point (!!) followed by a substitution field (!{...}). Because curly braces {} only
have the meaning of field delimiters when immediately following a non-escaped
exclamation point, curly braces never need to be escaped.
The rules for delimiting hexpri depend on the number of curly braces used.
1 pair If hexpri is delimited by a single pair of braces, then hexpri may contain
curly braces so long as the braces only appear in matched pairs and are
nested no more than 5 levels deep. This is essentially the same as standard
LATEX tokenization rules except for the nesting limit.
2–6 pairs If hexpri is delimited by 2–6 immediately adjacent curly braces
(!{{...}} to !{{{{{{...}}}}}}), then hexpri may contain any combina-
tion of braces, paired or unpaired, so long as the longest sequence of identical
brace characters is shorter than the delimiters. Thus, !{{...}} can only
18 For \textbackslash py, the text returned by Python is stored in macros and thus must be
valid LATEX code, because LATEX interprets the returned content. The use of macros for storing re-
turned content means that an external file need not be created for each use of \textbackslash py.
Rather, all macros created by \textbackslash py and equivalent commands from other fami-
lies are stored in a single file that is inputted. Note that even though the content is stored in
macros, verbatim content is allowed, through the use of special macro definitions combined with
\scantokens.

23
contain single braces { and } (paired or unpaired); !{{{...}}} can contain
{, }, {{, or }}; and so forth.
In both cases, anything more than five identical, immediately adjacent braces will
always trigger an error. If a greater level of nesting is needed, then a function
should be created within a pycode environment and afterward used to assemble
the desired result.
Curly braces used for delimiting hexpri must not be immediately adjacent to
braces that are part of hexpri, because it would be impossible to distinguish them
in the general case. If hexpri begins/ends with a literal curly brace, the brace
should be preceded/followed by a space or other whitespace character; leading
and trailing whitespace in hexpri is stripped, so this will not affect the output.
Besides braces, hexpri may contain any character except for literal newlines.
In some cases, it may be appropriate to represent newlines in escaped form (\n).
In other cases, it will be more appropriate to perform most calculations within a
preceding pycode environment, and then access them via a variable or function
call.
Because hexpri is evaluated and printed, it must be suitable for insertion in
a print() function (or the equivalent, for languages besides Python). If string
conversion as performed by print() is not desirable, then commands for explicit
string conversion should be used.
\pyv[hsession i]hopening delim ihcode ihclosing delim i
This command is used for typesetting but not executing hcodei. The suffix v
is an abbreviation for verb.
\pyb[hsession i]hopening delim ihcode ihclosing delim i
This command both executes and typesets hcodei. Since it is unlikely that the
user would wish to typeset code and then immediately include any output of
the code, printed content is not automatically included, even when the package
autoprint option is set to true. Rather, any printed content is included at a
user-designated location via the \printpythontex or \stdoutpythontex macros.

4.2.2 Environments
pycode [hsession i][hfancyvrb settings i]
This environment encloses code that is executed but not typeset. The second
optional argument hfancyvrb settingsi is irrelevant since nothing is typeset, but it
is accepted to maintain parallelism with the verbatim and block environments.
If the print statement/function is used within the environment, printed content
will be included automatically so long as the package autoprint option is set to
true (the default setting).
pysub [hsession i][hfancyvrb settings i]
This environment performs variable and expression substitution, or string in-
terpolation, on the enclosed code. Fields of the form !{hexpri} in hcodei are
replaced with the evaluated and printed output of hexpri. See the description of
the \pys command for details about substitution and the substitution field syntax.
pyverbatim [hsession i][hfancyvrb settings i]

24
This environment encloses code that is typeset but not executed.
pyblock [hsession i][hfancyvrb settings i]
This environment encloses code that is both executed and typeset. Since it is
unlikely that the user would wish to typeset code and then immediately print any
output of the code, printed content is not automatically included, even when the
package autoprint option is set to true. Rather, any printed content is included
at a user-designated location via the \printpythontex or \stdoutpythontex
macros.

4.2.3 Console command and environment families


So far, we have considered the py command and environment family. PythonTEX
also provides families for console content. These emulate the behavior of a Python
interactive console. In what follows, the pycon family is described
The pycon family includes a \pyconv and pyconverbatim that typeset a con-
sole session pasted from an interpreter. It also includes a \pyconc and pyconcode
that execute code but typeset nothing. These should be used with care, since it
may often be advisable to show all executed code when working with an interactive
console.
The pycon family also includes a special environment and command.
pyconsole [hsession i][hfancyvrb settings i]
This environment treats its contents as a series of commands passed to an inter-
active Python console. Python’s code module is used to intersperse the commands
with their output, to emulate an interactive Python interpreter.
When a multi-line command is entered (for example, a function definition), a
blank line after the last line of the command may be necessary.
For example,
a = 1
b = 2
a + b

produces
>>> a = 1
>>> b = 2
>>> a + b
3

\pycon[hsession i]hopening delim ihcode ihclosing delim i


This command executes hcodei using the emulated interpreter, and brings the
output back into the document, discarding the input. The output is typeset
verbatim (since it will not in general be valid LATEX), with the same font used for
the pyconsole environment.
For example, \pycon{a + b} would create 3.
This command is primarily for use in referencing console variable values.

25
Notice that there is not a command or environment for console content that
parallels the block command and environment. That is, there is not a command
or environment that both typesets and executes code in the console, but does not
show the output. This is intentional. In most cases, if you are going to use the
console, you should use it consistently, showing input and output together.

4.2.4 Default families


By default, three command and environment families are defined, with three cor-
responding console families.
• Python
– Base name py: \py, \pyc, \pyv, \pyb, pycode, pyverbatim, pyblock.
– Base name pycon: \pycon, \pyconc, \pyconv, pyconsole, pyconcode,
pyconverbatim.
– Imports: None.
• Python + pylab (matplotlib module)
– Base name pylab: \pylab, \pylabc, \pylabv, \pylabb, pylabcode,
pylabverbatim, pylabblock.
– Base name pylabcon: \pylabcon, \pylabconc, \pylabconv, pylabconsole,
pylabconcode, pylabconverbatim.
– Imports: matplotlib’s pylab module, which provides access to much
of matplotlib and NumPy within a single namespace. pylab content is
brought in via from pylab import *.
– Additional notes: matplotlib added a pgf backend in version 1.2. You
will probably want to use this for creating most plots. However, this
is not currently configured automatically because many users will want
to customize font, TEX engine, and other settings. Using TEX to create
plots also introduces a performance penalty.

• Python + SymPy
– Base name sympy: \sympy, \sympyc, \sympyv, \sympyb, sympycode,
sympyverbatim, sympyblock, sympyconsole.
– Base name sympycon: \sympycon, \sympyconc, \sympyconv, sympyconsole,
sympyconcode, sympyconverbatim.
– Imports: SymPy via from sympy import *.
– Additional notes: By default, content brought in via \sympy is format-
ted using a context-sensitive interface to SymPy’s LatexPrinter class,
described below.

26
Under Python 2.7, all non-console families import absolute_import, division,
and print_function from __future__ by default. This may be changed using
the package option pyfuture. There is an equivalent pyconfuture for console
families. Keep in mind that importing unicode_literals from __future__ may
break compatibility with some packages; this is why it is not imported by default.
Imports from __future__ are also possible without using the pyfuture option.
You may use the \pythontexcustomc command or pythontexcustomcode envi-
ronment (described below), or simply enter the import commands immediately at
the beginning of a session.

4.2.5 Custom code


You may wish to customize the behavior of one or more families within a document
by adding custom code to the beginning and end of each session. The custom code
command and environment make this possible. While the custom code command
and environment work with console content, most of the discussion below is
geared toward the non-console case.
If you wish to share these customizations among several documents, you can
create your own document class or package containing custom code commands
and environments.
While custom code can be added anywhere in a document, it is probably best
for organizational reasons to add it in the preamble or near the beginning of the
document.
Note that custom code is executed, but never typeset. Only code that is ac-
tually entered within a block (or verbatim) command or environment is ever
typeset. This means that you should be careful about how you use custom code.
For example, if you are documenting code, you probably want to show absolutely
all code that is executed, and in that case using custom code might not be ap-
propriate. If you are using PythonTEX to create figures or automate text, are
using many sessions, and require many imports, then custom code could save
some typing by centralizing the imports.
Any errors or warnings due to custom code will be correctly synchronized with
the document, just like normal errors and warnings. Any errors or warnings will
be specifically identified as originating in custom code.
Custom code is not allowed to print or write to stdout. It would be pointless
for custom code at the beginning of a session to print, because all printed content
would be identical since custom code at the beginning comes before any regular
code that might make the output session-specific. In addition, it is not obvious
where printed content from custom code would be included, especially for custom
code at the end of a session. Furthermore, custom code may be in the preamble,
where nothing can be typeset.
If custom code does attempt to print, a warning is raised and the printed
content is included in the PythonTEX run summary. This gives you access to the
printed content, while not including it in the document. This can be useful in
cases where you cannot control whether content prints (for example, if a library
automatically prints debugging information).

27
\pythontexcustomc[hposition i]{hfamily i}{hcode i}
This macro allows custom code to be added to all sessions within a command
and environment family. hpositioni should be either begin or end; it determines
whether the custom code is executed at the beginning or end of each session. By
default, custom code is executed at the beginning. hcodei should be a single
line of code. For example, \pythontexcustomc{py}{a=1; b=2} would create the
variables a and b within all sessions of the py family, by adding that line of code
at the beginning of each session.
If you need to add more than a single line of custom code, you could
use the command multiple times, but it will be more efficient to use the
pythontexcustomcode environment.
hcodei may contain imports from __future__. These must be the first elements
in any custom code command or environment, since __future__ imports are only
possible at the very beginning of a Python script and only the very beginning of
custom code is checked for them. If imports from __future__ are present at the
beginning of both custom code and the user’s code, all imports will work correctly;
the presence of the imports in custom code, before user code, does not turn off
checking for __future__ imports at the very beginning of user code. However, it
is probably best to keep all __future__ imports in a single location.
pythontexcustomcode[hposition i]{hfamily i}
This is the environment equivalent of \pythontexcustomc. It is used for adding
multi-line custom code to a command and environment family. In general, the en-
vironment should be preferrred to the command unless only a very small amount of
custom code is needed. The environment has the same properties as the command,
including the ability to contain imports from __future__.

4.2.6 PythonTEX utilities class


All non-console families import pythontex_utils.py, and create an instance
of the PythonTEX utilities class called pytex. This provides various utilities for
interfacing with LATEX and PythonTEX.
The utilities class has an attribute context. This is a dictionary that can
contain contextual information, such as page dimensions, from the TEX side. Val-
ues may also be accessed as attributes rather than as dictionary keys. To de-
termine what contextual information is available, and for additional details, see
\setpythontexcontext under Section 4.5. For working with contextual data, the
utilities class provides pt_to_in(), pt_to_cm(), pt_to_mm(), and pt_to_bp()
methods for converting from TEX points to other units.
The utilities class provides an interface for determining how Python objects are
converted into strings in commands such as \py. The pytex.set_formatter(hformatteri)
method is used to set the conversion. Two formatters are provided:
• 'str' converts Python objects to a string, using the str() function un-
der Python 3 and the unicode() function under Python 2. (The use of
unicode() under Python 2 should not cause problems, even if you have not
imported unicode_literals and are not using unicode strings. All encod-
ing issues should be taken care of automatically by the utilities class.)

28
• 'sympy_latex' uses SymPy’s LatexPrinter class to return context-sensitive
LATEX representations of SymPy objects. Separate LatexPrinter set-
tings may be created for the following contexts: 'display' (displaystyle
math), 'text' (textstyle math), 'script' (superscripts and subscripts),
and 'scriptscript' (superscripts and subscripts, of superscripts and sub-
scripts). Settings are created via pytex.set_sympy_latex(hcontexti,hsettingsi).
For example, pytex.set_sympy_latex('display', mul_symbol='times')
sets multiplication to use a multiplication symbol ×, but only when math is
in displaystyle.19 See the SymPy documentation for a list of possible settings
for the LatexPrinter class.
By default, 'sympy_latex' only treats matrices differently based on context.
Matrices in displaystyle are typeset using pmatrix, while those in all other
styles are typeset via smallmatrix with parentheses.
The context-sensitive interface to SymPy’s LatexPrinter is always available
via pytex.sympy_latex().
The PythonTEX utilities formatter may be set to a custom function that re-
turns strings, simply by reassigning the pytex.formatter() method. For exam-
ple, define a formatter function my_func(), and then pytex.formatter=my_func
within a pycode or pythontexcustomcode environment. Any subsequent uses of
\py will then use my_func() to perform formatting.
The utilities class also provides methods for tracking dependencies and created
files.
• pytex.add_dependencies(hdependenciesi) This adds hdependenciesi to a
list. If any dependencies in the list change, code is re-executed, even if the
code itself has not changed (unless rerun=never). Modified dependencies are
determined via either modification time (default) or hash; see the package
option hashdependencies for details. This method is useful for tracking
changes in external data and similar files.
hdependenciesi should be one or more strings, separated by commas, that are
the file names of dependencies. Dependencies should be given with relative
paths from the current working directory, with absolute paths, or with paths
based on the user’s home directory (that is, starting with a tilde ~). Paths
can use a forward slash “/” even under Windows. Remember that by default,
the working directory is the main document directory. This can be adjusted
with \setpythontexworkingdir.
It is possible that a dependency of one session might be modified by another
session while PythonTEX runs. The first session might not be executed
during the PythonTEX run because its dependency was unmodified at the
beginning. A more serious case occurs when the first session does run, but
we don’t know whether it accessed the dependency before or after the de-
pendency was updated (remember, sessions run in parallel). PythonTEX
19 Internally, the 'sympy\_latex' formatter uses the \textbackslash mathchoice macro to

return multiple representations of a SymPy object, if needed by the current settings. Then
\textbackslash mathchoice typesets the correct representation, based on context.

29
keeps track of the time at which it started. Any sessions with dependencies
that were modified after that time are set to re-execute on the next run. A
warning is also issued to indicate that this is the case.
• pytex.add_created(hcreated filesi) This adds hcreated filesi to a list of files
created by the current session. Any time the code for the current session is
executed, all of these files will be deleted. Since this method deletes files,
it should be used with care. It is intended for automating cleanup when code
is modified. For example, if a figure’s name is changed, the old figure would
be deleted if its name had been added to the list. By default, PythonTEX
can only clean up the temporary files it creates; it knows nothing about
user-created files. This method allows user-created files to be specified, and
thus added to PythonTEX’s automatic cleanup.
hcreated filesi should be one or more strings, separated by commas, that
are the file names of created files. Paths should be the same as for
pytex.add_dependencies(): relative to the working directory, absolute,
or based on the user’s home directory. Again, paths can use a forward slash
“/” even under Windows.
Depending on how you use PythonTEX, this method may not be very ben-
eficial. If all of the output is contained in the default output directory, or
a similar directory of your choosing, then manual cleanup may be simple
enough that this method is not needed.
These two methods for tracking files may be used manually. However, that is
prone to errors, since you will have to modify both a PythonTEX utilities command
and an open or save command every time you change a file name or add or remove
a dependency or created file. It may be better to redefine your open and save
commands, or define new ones, so that a single command opens (or saves) and
adds a dependency (or adds a created file). For this reason, the PythonTEX
utilities class provides an open() method that automatically tracks dependencies
and created files.
• pytex.open(hfilei, hmodei, hargsi, hkwargsi) This method automatically
tracks all files opened for reading (text or binary mode) as dependencies. It
automatically tracks all files opened for writing (text or binary mode) as
created files. Files opened for updating and appending will raise a warning,
since it is not necessarily obvious how these files should be treated. The
general form of the custom open() function is shown below.
def track_open(name, mode='r', *args, **kwargs):
if mode in ('r', 'rt', 'rb'):
pytex.add_dependencies(name)
elif mode in ('w', 'wt', 'wb'):
pytex.add_created(name)
else:
warnings.warn('Unsupported mode {0} for file tracking'.format(mode))
return open(name, mode, *args, **kwargs)

30
Unicode note for Python 2: By default, pytex.open() call the stan-
dard Python 2 open(). If more than 3 positional arguments are used, or
if the encoding keyword is used, then io.open() will be called instead.
So if you are working with Unicode, make sure to specify an encoding in
pytex.open() so that io.open() will be used, or manually encode/decode
everything.
The utilities class provides a pair of methods, before() and after(), that
are called immediately before and after each chunk of user code. These may be
redefined to customize the output of user code. For example, LATEX commands
could be printed at the beginning and end of each command or environment,
wrapping any content printed by the user. Or any matplotlib figures that were
created in the chunk of code could be detected and saved, and LATEX commands
to include them in the document could be printed. Or stdout could be redirected
to a StringIO stream in before(), then processed in after() before being sent
to the original stdout.
The before() and after() methods may be redefined in any code or block
command or environment, using the techniques described below. Once they have
been redefined, the new methods will be called for all subsequent commands and
environments. When redefining these methods, it is important to realize that the
order of redefinition may be important. For example, if the new before() and
after() depend upon one another, then you should call the old after() (if it
does anything), then redefine the methods, and finally call the new before().
This is necessary because after() will be called after the end of the command
or environment in which redefinition takes place. If after() has been redefined
so that it depends on the new before(), and the new before() has not yet
been called, errors will likely result. Other methods of dealing with this scenario,
involving disabling before() and after() for a given command or environment,
are being considered as potential features for a future release.
When redefining before() and after(), you may wish to have behavior that
is command- or environment-specific. Information about the current command or
environment is available in pytex.command. The string i corresponds to an inline
command such as \py; b, to an inline block such as \pyb; c, to inline code such
as \pyc. Similarly, code corresponds to a code environment and block to a block
environment.
You may redefine before() and after() at the class level. For example,
def open(self):
<body>
PythontexUtils.open = open

Or you may redefine these methods as instance attributes that happen to be


functions (rather than bound methods). Notice that in this case self is not
allowed.
def open():
<body>

31
pytex.open = open

Finally, you may redefine these methods as bound methods for the pytex instance.
def open(self):
<body>
import types
pytex.open = types.MethodType(open, pytex)

The first and third approaches are necessary if you want to be able to use self
(for example, to access instance attributes). Notice that before() and after()
take no arguments (except self where applicable).
An example of using the after() method to automatically save and in-
clude all matplotlib figures created in a command or environment is shown be-
low. This example is designed for the pylab family of commands, or when
from pylab import * is used. If pyplot is imported as plt instead, then
plt.get_fignums(), plt.figure(), plt.savefig(), plt.close(), etc., would
be needed.
# Basename for figures that will be created
pytex.basename = '_'.join([pytex.family, pytex.session, pytex.restart])

# Need to keep track of total number of figures in each session


pytex.fignum = 0

# The figure could be included in more sophisticated ways


# For example, a ``figure`` environment could be used
def after():
for num in get_fignums():
fname = pytex.basename + '_fig' + str(pytex.fignum) + '.pdf'
pytex.fignum += 1
figure(num)
savefig(fname)
pytex.add_created(fname)
close(num)
print(r'\includegraphics{' + fname + '}')

# In this case, I'm taking the easy approach to redefine ``open()``


pytex.after = after

4.2.7 Formatting of typeset code


\setpythontexfv[hfamily i]{hfancyvrb settings i}
This command sets the fancyvrb settings for all command and environment
families. Alternatively, if an optional argument hfamilyi is supplied, the settings
only apply to the family with that base name. The general command will override
family-specific settings.

32
Each time the command is used, it completely overwrites the previous settings.
If you only need to change the settings for a few pieces of code, you should use
the second optional argument in block and verb environments.
Note that \setpythontexfv and \setpygmentsfv are equivalent when they
are used without an optional argument; in that case, either may be used to deter-
mine the document-wide fancyvrb settings, because both use the same underlying
macro.
\setpythontexprettyprinter[hfamily i]{hprinter i}
This should generally not be needed. It sets the pretty printing used by the
document, or by hfamilyi if given. Valid options for hprinteri are fancyvrb and
pygments. The option auto may be given for hfamilyi, in which case the formatter
is inherited from the document-level settings. Using either of the other two options
will force hfamilyi to use that printer, regardless of the document-level settings.
By default, families use auto.
Remember that Pygments has a text lexer and a bw style. These are an
alternative to setting the formatter to fancyvrb.
\setpythontexpyglexer[hfamily i]{hpygments lexer i}
This allows the Pygments lexer to be set for hfamilyi. hpygments lexeri should
use a form of the lexer name that does not involve any special characters. For
example, you would want to use the lexer name csharp rather than C#. This will be
a consideration primarily when using the Pygments commands and environments
to typeset code of an arbitrary language.
If a hfamilyi is not specified, the lexer is set for the entire document.
\setpythontexpygopt[hfamily i]{hpygments options i}
This allows the Pygments options for hfamilyi to be redefined. Note that any
previous options are overwritten. The same Pygments options may be passed
here as are available via the package pygopt option. Note that for each available
option, individual family settings will be overridden by the package-level pygopt
settings, if any are given.
If a hfamilyi is not specified, the options are set for the entire document.

4.2.8 Access to printed content (stdout) and error messages (stderr)


The macros that allow access to printed content and any additional content written
to stdout are provided in two identical forms: one based off of the word print and
one based off of stdout. Macro choice depends on user preference. The stdout
form provides parallelism with the macros that provide accesss to stderr.
\printpythontex[hmode i][hoptions i]

\stdoutpythontex[hmode i][hoptions i]
Unless the package option autoprint is true, printed content from code com-
mands and environments will not be automatically included. Even when the
autoprint option is turned on, block commands and environments do not auto-
matically include printed content, since we will generally not want printed content
immediately after typeset code. This macro brings in any printed content from
the last command or environment. It is reset after each command/environment,

33
so its scope for accessing particular printed content is very limited. It will return
an error if no printed content exists.
hmodei determines how printed content is handled. It may be raw (interpreted
as LATEX), verb (inline verbatim), or verbatim; raw is the default. Verbatim
content is brought in via fancyvrb. hoptionsi consists of fancyvrb settings.
\saveprintpythontex{hname i}

\savestdoutpythontex{hname i}

\useprintpythontex[hverbatim options i][hfancyvrb options i]{hname i}

\usestdoutpythontex[hverbatim options i][hfancyvrb options i]{hname i}


We may wish to be able to access the printed content from a command or
environment at any point after the code that prints it, not just before any addi-
tional commands or environments are used. In that case, we may save access to
the content under hnamei, and access it later via \useprintpythontex{hnamei}.
hmodei must be raw, verb, or verbatim. If content is brought in verbatim, then
hfancyvrb optionsi are applied.
\stderrpythontex[hmode i][hfancyvrb options i]
This brings in the stderr produced by the last command or environment. It
is intended for typesetting incorrect code next to the errors that it produces.
By default, stderr is brought in verbatim. hmodei may be set to raw, verb, or
verbatim. In general, bringing in stderr raw should be avoided, since stderr will
typically include special characters that will make TEX unhappy.
The line number given in the stderr message will correctly align with the line
numbering of the typeset code. Note that this only applies to code and block
environments. Inline commands do not have line numbers, and as a result, they
do not produce stderr content.
By default, the file name given in the message will be in the form

hfamily namei_hsessioni_hgroupi.hextensioni
For example, an error produced by a pycode environment, in the session
mysession, using the default group (that is, the default \restartpythontexsession
treatment), would be reported in py_mysession_default.py. The package op-
tion stderrfilename may be used to change the reported name to the following
forms: mysession.py, <file>, <script>.
\savestderrpythontex{hname i}

\usestderrpythontex[hmode i][hfancyvrb options i]{hname i}


Content written to stderr may be saved and accessed anywhere later in the
document, just as stdout content may be. These commands should be used with
care. Using Python-generated content at multiple locations within a document
may often be appropriate. But an error message will usually be most meaningful
in its context, next to the code that produced it.
\setpythontexautoprint{hboolean i}

\setpythontexautostdout{hboolean i}

34
This allows autoprint behavior to be modified at various points within the
document. The package-level autoprint option is also available for setting au-
toprint at the document level, but it is overridden by \setpythontexautoprint.
hbooleani should be true or false.

4.3 Pygments commands and environments


Although PythonTEX’s goal is primarily the execution and typesetting of Python
code from within LATEX, it also provides access to syntax highlighting for any
language supported by Pygments.
\pygment{hlexer i}hopening delim ihcode ihclosing delim i
This command typesets hcodei in a suitable form for inline use within a para-
graph, using the specified Pygments hlexeri. Internally, it uses the same macros
as the PythonTEX inline commands. hopening delimi and hclosing delimi may be
a pair of any characters except for the space character, or a matched set of curly
braces {}.
As with the inline commands for code typesetting and execution, there is not an
optional argument for fancyvrb settings, since almost all of them are not relevant
for inline usage, and the few that might be should probably be used document-wide
if at all.
pygments [hfancyvrb settings i]{hlexer i}
This environment typesets its contents using the specified Pygments hlexeri
and applying the hfancyvrb settingsi.
\inputpygments[hfancyvrb settings i]{hlexer i}{hexternal file i}
This command brings in the contents of hexternal filei, highlights it using
hlexeri, and typesets it using hfancyvrb settingsi.
\setpygmentsfv[hlexer i]{hfancyvrb settings i}
This command sets the hfancyvrb settingsi for hlexeri. If no hlexeri is supplied,
then it sets document-wide hfancyvrb settingsi. In that case, it is equivalent to
\setpythontexfv{hfancyvrb settingsi}.
\setpygmentspygopt[hlexer i]{hpygments options i}
This sets hlexeri to use hpygments optionsi. If there is any overlap between
hpygments optionsi and the package-level pygopt, the package-level options over-
ride the lexer-specific options.
If hlexeri is not given, options are set for the entire document.
\setpygmentsprettyprinter{hprinter i}
This usually should not be needed. It allows the pretty printer for the document
to be set; it is equivalent to using \setpythontexprettyprinter without an
optional argument. Valid options for hprinteri are fancyvrb and pygments.
Remember that Pygments has a text lexer and a bw style. These are an
alternative to setting the formatter to use fancyvrb.

35
4.4 General code typesetting
4.4.1 Listings float
listing
PythonTEX will create a float environment listing for code listings, unless
an environment with that name already exists. The listing environment is cre-
ated using the newfloat package. Customization is possible through newfloat’s
\SetupFloatingEnvironment command.
\setpythontexlistingenv{halternate listing environment name i}
In the event that an environment named listing already exists for some other
purpose, PythonTEX will not override it. Instead, you may set an alternate name
for PythonTEX’s listing environment, via \setpythontexlistingenv.

4.4.2 Background colors


PythonTEX uses fancyvrb internally to typeset all code. Even code that is high-
lighted with Pygments is typeset afterwards with fancyvrb. Using fancyvrb, it
is possible to set background colors for individual lines of code, but not for entire
blocks of code, using \FancyVerbFormatLine (you may also wish to consider the
formatcom option). For example, the following command puts a green background
behind all the characters in each line of code:
\renewcommand{\FancyVerbFormatLine}[1]{\colorbox{green}{#1}}

If you need a completely solid colored background for an environment, or


a highly customizable background, you should consider the mdframed package.
Wrapping PythonTEX environments with mdframed frames works quite well. You
can even automatically add a particular style of frame to all instances of an envi-
ronment using the command

\surroundwithmdframed[hframe optionsi]{henvironmenti}
Or you could consider using etoolbox to do the same thing with mdframed or an-
other framing package of your choice, via etoolbox’s \BeforeBeginEnvironment
and \AfterEndEnvironment macros.

4.4.3 Referencing code by line number


It is possible to reference individual lines of code, by line number. If code is
typeset using pure fancyvrb, then LATEX labels can be included within com-
ments. The labels will only operate correctly (that is, be treated as LATEX rather
than verbatim content) if fancyvrb’s commandchars option is used. For example,
commandchars=\\\{\} makes the backslash and the curly braces function nor-
mally within fancyvrb environments, allowing LATEX macros to work, including
label definitions. Once a label is defined within a code comment, then referencing
it will return the code line number.

36
The disadvantage of the pure fancyvrb approach is that by making the back-
slash and curly braces command characters, we can produce conflicts if the code
we are typesetting contains these characters for non-LATEX purposes. In such a
case, it might be possible to make alternate characters command characters, but
it would probably be better to use Pygments.
If code is typeset using Pygments (which also ties into fancyvrb), then this
problem is avoided. The Pygments option texcomments=true has Pygments look
for LATEX code only within comments. Possible command character conflicts with
the language being typeset are thus eliminated.
Note that when labels are created within comments, the labes themselves will
be invisible within the final document but the comment character(s) and any other
text within comments will still be visible. For example, the following
abc = 123 # An important line of code!\label{lst:important}
would appear as
abc = 123 # An important line of code!
If a comment only contains the \label command, then only the comment char-
acter # would actually be visible in the typeset code. If you are typesetting code
for instructional purposes, this may be less than ideal. Unfortunately, Pygments
currently does not allow escaping to LATEX outside of comments (though this fea-
ture has been requested). At the same time, by only allowing references within
comments, Pygments does force us to create code that would actually run. And
in many cases, if a line is important enough to label, it is also important enough
for a brief comment.

4.4.4 Beamer compatibility


PythonTEX is compatible with Beamer. Since PythonTEX typesets code as verba-
tim content, Beamer’s fragile option must be used for any frame that contains
typeset code. Beamer’s fragile option involves saving frame contents to an ex-
ternal file and bringing it back in. This use of an external file breaks PythonTEX’s
error line number synchronization, since the error line numbers will correspond to
the temporary external file rather than to the actual document.
If you need to typeset code with Beamer, but don’t need to use overlays on the
slides containing code, you should use the fragile=singleslide option. This al-
lows verbatim content to be typeset without using an external file, so PythonTEX’s
error line syncronization will work correctly.

4.5 Advanced PythonTEX usage


\setpythontexcontext{hkey-value pairs i}
This macro is used for passing contextual information such as page dimensions
from the TEX side to the Python/other language side. hkey-value pairsi is a set
of comma-delimited key-value pairs. An evaluated version of hkey-value pairsi is
passed to the programming language, wrapped in quotation marks to become a

37
string. Thus, hkey-value pairsi should not contain quotation marks, backslashes,
or other characters that would prevent the evaluated contents from being the body
of a normal, quoted string.
As an example, the following would pass the values of \textwidth and
\textheight to the Python side.
\setpythontexcontext{textwidth=\the\textwidth, textheight=\the\textheight}

Python would receive a string something like "textwidth=390pt, textheight=592pt".


This string would be parsed into key-value pairs, and the results stored in the
pytex.context dictionary. For Python, the keys also become the names of at-
tributes of pytex.context. Thus, the values may be accessed on the Python side
via pytex.context['textwidth'], pytex.context.textwidth, etc.
All contextual data is available as strings on the Python/other language side.
For convenience, the utilities class provides unit conversion methods for converting
from TEX points to inches, centimeters, millimeters, and big (DTP or PostScript)
points. These methods take integers, floats, or strings that consist of digits (op-
tionally ending in “pt”), and return floats. For example, pytex.pt_to_in(),
pytex.pt_to_cm(), pytex.pt_to_mm(), pytex.pt_to_bp(). Keep in mind that
the units of TEX points are 1/72.27 of an inch, not 1/72 of an inch (which is a
bp).
There is also a type system for Python that allows the types of hvaluesi to be
specified. Any hvaluei beginning with !!int will become an integer; with !!float,
a float; with !!str, a string. This notation is borrowed from YAML. For example,
\setpythontexcontext{a=!!int 42, b=!!float 42, c=!!str 42}

This type system is still under development and is subject to change


in the future. Once the system stabilizes, it will be extended to non-Python
languages. Comments on the type system are welcome.
The context may only be set in the preamble.
Technical note: Contextual data is cached, so the dictionary (and its attributes,
if applicable) is only updated when contextual data changes. This largely elimi-
nates any potential overhead from contextual data.
\restartpythontexsession{hcounter value(s) i}
This macro determines when or if sessions are restarted (or “subdivided”).
Whenever hcounter value(s)i change, the session will be restarted.
By default, each session corresponds to a single code file that is executed.
But sometimes it might be convenient if the code from each chapter or section
or subsection were to run within its own file, as its own session. For exam-
ple, we might want each chapter to execute separately, so that changing code
within one chapter won’t require that all the code from all the other chapters
be executed. But we might not want to have to go to the bother and ex-
tra typing of defining a new session for every chapter (like \py[ch1]{hcodei}).
To do that, we could use \restartpythontexsession{\thechapter}. This
would cause all sessions to restart whenever the chapter counter changes. If
we wanted sessions to restart at each section within a chapter, we would

38
use \restartpythontexsession{\thechapterhdelimi\thesection}. hdelimi is
needed to separate the counter values so that they are not ambiguous (for ex-
ample, we need to distinguish chapter 11-1 from chapter 1-11). Usually hdelimi
should be a hyphen or an underscore; it must be a character that is valid in file
names.
Note that counter values, and not counters themselves, must be supplied as
the argument. Also note that the command applies to all sessions. If it did not,
then we would have to keep track of which sessions restarted when, and the lack
of uniformity could easily result in errors on the part of the user.
Keep in mind that when a session is restarted, all continuity is lost. It is best
not to restart sessions if you need continuity. If you must restart a session, but
also need to keep some data, you could save the data before restarting the session
and then load the saved data after the restart. This approach should be used with
extreme caution, since it can result in unanticipated errors due to sessions not
staying synchronized.20
This command can only be used in the preamble.
\setpythontexoutputdir{houtput directory i}
By default, PythonTEX saves all temporary files and automatically gener-
ated content in a directory called pythontex-files-hsanitized jobnamei, where
hsanitized jobnamei is just \jobname with any space characters or asterisks re-
placed with hyphens. This directory will be created by pythontex.py. If we wish
to specify another directory (for example, if \jobname is long and complex, and
there is no danger of two files trying to use the same directory), then we can use
the \setpythontexoutputdir macro to redefine the output directory.21
Any slashes in houtput directoryi should be forward slashes “/” (even under
Windows). Tildes ~ may be used to refer to the user’s home directory, including
under Windows.
\setpythontexworkingdir{hworking directory i}
The PythonTEX working directory is the current working directory for
PythonTEX scripts. This is the directory in which any open or save operations
will take place, unless a path is explicitly specified. By default, the working direc-
tory is the same as the main document directory. For example, if you are writing
my_file.tex and save a matplotlib figure with savefig('my_figure.pdf'), then
my_figure.pdf will be created in the same directory as my_file.tex. But maybe
you have a directory called plots in your document root directory. In that case,
20 For example, suppose sessions are restarted based on chapter. session-ch1 saves a data file,

and session-ch2 loads it and uses it. You write the code, and run PythonTEX. Then you realize
that session-ch1 needs to be modified and make some changes. The next time PythonTEX
runs, it will only execute session-ch1, since it detects no code changes in session-ch2. This
means that session-ch2 is not updated, at least to the extent that it depends on the data
from session-ch1. Again, saving and loading data between restarted sessions, or just be-
tween sessions in general, can produce unexpected behavior. This can be avoided by using the
pytex.add_dependencies() method for all data that is loaded. It will ensure that all sessions
stay in sync.
21 In the rare event that both \string\setpythontexoutputdir is used and
\string\printpythontex is needed in the preamble, \string\setpythontexoutputdir must be
used first, so that \string\printpythontex will know where to look for output.

39
you could leave the working directory unchanged, and simply specify the relative
path to plots when saving. Or you could set the working directory to plots using
\setpythontexworkingdir{plots}, so that all content would automatically be
saved there.
Any slashes in hworking directoryi should be forward slashes “/” (even under
Windows). Tildes ~ may be used to refer to the user’s home directory, including
under Windows.
The working directory is automatically added to Python’s sys.path, so that
code in the working directory there may be imported without a path being speci-
fied.
Note that in many use cases, you may be able to use the output directory as
the working directory. The graphicx package will automatically look for images
and figures in the output directory when it is used as the working directory, so
long as you do not use the \graphicspath command outside the preamble.22 To
use the output directory as the working directory, you may enter the full name of
the output directory manually, or use the text “<outputdir>” as a shortcut:
\setpythontexworkingdir{<outputdir>}

It is also possible to change the working directory from within Python code,
via os.chdir().

4.6 Working with other programs


4.6.1 latexmk
PythonTEX is compatible with latexmk. How you configure latexmk largely de-
pends on how you are using PythonTEX.
If you are compiling in the same location as the document source (if you are
not using -auxdir, -outdir, or $out_dir, or alternatively TEXINPUTS), and are
not using PythonTEX’s dependency tracking, then adding a simple rule such as
the following to your .latexmkrc should usually be sufficient.
add_cus_dep('pytxcode', 'tex', 0, 'pythontex');
sub pythontex { return system("pythontex \"$_[0]\""); }

This tells latexmk that the document (tex) depends on the file of code extracted
from the document (pytxcode).23 Whenever the document is compiled, the file
of code is updated. If latexmk detects that the code changed, then it will run
22 graphicx looks for graphics in the document root directory and in the most recent graph-

ics path defined by \graphicspath. \graphicspath stores the graphics path in \Ginput@path,
overwriting any previous value. At the end of the preamble, PythonTEX appends the output
directory to \Ginput@path if the output directory is being used as the working directory. Thus,
that directory will always be checked for graphics, so long as \Ginput@path is not overwritten
by a subsequent use of \graphicspath. If you need to use \graphicspath within the document,
you could consider creating a custom version that redefines \Ginput@path with the PythonTEX
output directory automatically appended.
23 This is a slightly atypical use, if not a “misuse,” of add_cus_dep(). In the standard usage,

the first argument is the extension of a file that is used to create another file with the extension
given in the second argument, via the rule named in the fourth argument. In this case, we just

40
PythonTEX. When PythonTEX runs, it will modify at least one file that is brought
into the document. latexmk will detect this modification, and automatically re-
compile the document.
If you are compiling to a different directory (using -auxdir, -outdir,
or $out_dir, or alternatively TEXINPUTS), then the preceding rule may fail
due to the different directory configuration. In that case, you should use
\setpythontexoutputdir{.} so that PythonTEX will store its output in the cur-
rent default location, rather than in a subdirectory, to ensure that latexmk will
locate the output files. Since the tex source is no longer in the location of the
compiled output, you also need a different dependency specification. It is probably
simplest to use the pytxmcr file that PythonTEX always generates.
add_cus_dep('pytxcode','pytxmcr',0,'pythontex');
sub pythontex { return system("pythontex.py \"$_[0]\""); }

Note that this configuration should always work, but has the disadvantage of re-
quiring that PythonTEX not use a subdirectory to isolate the files it automatically
generates.
If you are using PythonTEX’s dependency tracking, then you should run
PythonTEX once during every compile cycle (unless you simply wish to run it
manually, as needed). Checking the pytxcode for modification is not sufficient,
because it does not reflect the state of dependencies. If you are testing for de-
pendency modification using modification time (the default) rather than hashing,
this should typically add very little overhead. If PythonTEX detects modified de-
pendencies and actually does execute code, then the pytxmcr file will be updated,
which will trigger another compile. It is possible to have PythonTEX run after each
individual LATEX run by modifying latexmk’s -latex, -pdflatex, or -xelatex
options. Ideally, however, PythonTEX would only run once per compile cycle.
The situation is similar if you are using the rerun=always setting. The above
rules will fail to run PythonTEX on each and every compile; in that situation, you
should configure your .latexmkrc so that PythonTEX always runs at least once
during every compile cycle.

5 depythontex
PythonTEX can greatly simplify the creation of documents. At the same time, by
introducing dependence on non-LATEX external tools, it can constrain how these
documents are used. For example, many publishers will not accept LATEX docu-
ments that require special packages or need special macros. To address this issue,
the package includes a feature called depythontex that can convert a PythonTEX
document into a plain LATEX document.
want to run the rule whenever files with the first extension are modified. The extension given in
the second argument is irrelevant, so long as a file with the document name and that extension
exists. Since the tex file itself will exist, its extension is a logical choice for the second argument.

41
5.1 Preparing a document that will be converted
The conversion process should work flawlessly in most cases, with no special for-
matting required.
For best results, keep the following in mind.
• The PythonTEX package should have its own \usepackage.
• Currently, depythontex only supports the standard PythonTEX commands
and environments. Support for user-defined commands and environments
that incorporate PythonTEX is planned for a future release.
• If you need to insert content from Python in inline contexts, it is best to
use \py or an equivalent command. If you use print, either directly (for
example, from within \pyc) or via \printpythontex, make sure that the
spacing following the printed content is correct. You may need to print
an \endinput or % at the end of your content to prevent an extra trailing
space. depythontex will attempt to reproduce the spacing of the original
document, even if it is not ideal. See Section 5.3 for additional details.
• Some LATEX environments, such as the verbatim environment from the
verbatim package and the Verbatim environment from fancyvrb, do not al-
low text to follow the \end{henvironmenti}. If you bring Python-generated
content that ends with one of these environments into your document, using
print or \py, make sure that the end-of-environment command is followed
by a newline. For example, if you are assembling a Verbatim environment
to bring in, the last line should be the string

'\\end{Verbatim}\n'

Even if you neglect a final newline, depythontex will still function correctly
in most cases. Whenever Python-generated content does not end with a
newline, depythontex usually inserts one and gobbles spaces that follow
the environment. This preserves the correct spacing while avoiding any
issues produced by an end-of-environment command. But in some cases,
depythontex cannot do this. For example, if \py is used to bring in a
Verbatim environment, and there is text immediately after the \py, without
any intervening space, depythontex cannot substitute a newline for spaces,
because there are none. Because of the way that print and \py content is
brought in, everything may still work correctly in the original PythonTEX
document. But it would fail in the depythontex output.
• Do not create PythonTEX commands or environments on the Python side
and print or otherwise bring them in. That is too many levels of complexity!
• depythontex is only designed to replace PythonTEX commands and envi-
ronments that are actually in the main document file. Do not bring in
anything that contains PythonTEX commands or environments via \input,

42
\include, or \usepackage. The only exception is PythonTEX commands
and environments that do not typeset anything (for example, code environ-
ments that don’t print). If these are brought in via a package or external file,
the command \DepythontexOff must come before them, and they must be
followed by the command \DepythontexOn. Basically, depythontex must
be disabled for commands and environments brought in via external files.
This works so long as the commands and environments only provide code
and settings, rather than any typeset content.
Tools for automatically removing the \usepackage for packages that contain
PythonTEX commands will be added soon; for now, these \usepackage’s
must be removed manually in the depythontex output.
• Keep in mind that the file produced by depythontex will need to include
any graphics that you create with PythonTEX. Make sure any graphics are
saved in a location where they are easily accessible.

5.2 Removing PythonTEX dependence


Converting a document requires three steps.
1. Turn on the package option depythontex. Then compile the document,
run pythontex.py, and compile the document again. Depending on the
document, additional compiles may be necessary (for example, to resolve
references). Any syntax highlighting will be turned off automatically during
this process, to remove dependence on Pygments.
During compilation, an auxiliary file called hjobnamei.depytx is created.
This file contains information about the location of the PythonTEX com-
mands and environments that need to be replaced, and about the content
with which they are to be replaced.
2. Run the depythontex.py script. This takes the following arguments.
• --encoding This is the encoding of the LATEX file and all related files.
If an encoding is not specified, UTF-8 is assumed.
• --overwrite This turns off the user prompt in the event that a file
already exists with the output name, making overwriting automatic.
• --listing This option specifies the commands and environments that
are used for any typeset code. This can be verbatim, fancyvrb,
listings, minted, or pythontex.24 verbatim is used by default. An
appropriate \usepackage command is automatically added to the out-
put document’s preamble.
When code is typeset with any option other than verbatim, listing
line numbering from the original document will be preserved. When
24 The pythontex option is included for completeness. In most cases, you would probably use

depythontex to remove all dependence on PythonTEX. But sometimes it might be useful to


remove all Python code while still using PythonTEX for syntax highlighting.

43
code is typeset with any option other than verbatim and fancyvrb,
syntax highlighting will also be preserved. The only exception is
when listings is used, and listings’s language name does not cor-
respond to Pygments’ lexer name. In this case, you should use the
--lexer-dict option to specify how the Pygments lexer is to be trans-
lated into a listings language.
• --lexer-dict This option is used to specify how Pygments lexers are
converted to listings languages, when the two do not have the same
name. It takes a comma-separated list of the form
"<Pygments lexer>:<listings language>, ..., ... "

A Python-style dict will also be accepted.


• --preamble This option allows additional commands to be added to
the output document’s preamble. This is useful when you want the
output document to load a package that was automatically loaded by
PythonTEX, such as upquote.
• --graphicspath This option adds the outputdir to any existing
graphics path defined by \graphicspath, or adds a \graphicspath
command if one does not already exist. This causes the depythontex
document to automatically look in the outputdir for graphics. Only
use this option if you want to continue using the outputdir with the
depythontex document. Graphics are further discussed below.
• -o --output The name of the output file. If no name is given, the
converted file is written to stdout.
• TEXNAME The name of the LATEX file whose PythonTEX dependence is
to be removed.
3. Compile the depythontex file, and compare it to the original.
The original and depythontex files should be nearly identical. All Python-
generated content is substituted directly, so it should be unchanged. Usually,
any differences will be due to changes in the way that code is typeset. For ex-
ample, by default all code in the depythontex file is typeset with \verb and
verbatim. But \verb is more fragile than the inline PythonTEX commands
(it isn’t allowed inside other commands), and verbatim does not support
line numbering or syntax highlighting.
Remember that the depythontex file will need to include any graphics cre-
ated by PythonTEX. By default, these are saved in the document root
directory. They may be in other locations if you have set a non-default
workingdir or have specified a path when saving graphics. Depending on
your needs and configuration, you may wish to copy the graphics into a
new location or specify their location via \graphicspath. If you are us-
ing the outputdir as the workingdir, you can run depythontex with the

44
--graphicspath option, which will add the outputdir to any existing us-
age of \graphicspath, or add a \graphicspath command if one does not
already exist.25
Depending on your needs, you may wish to customize depythontex.py. The
actual substitutions are performed in a few functions that are defined at the
beginning of the script.

5.3 Technical details


The depythontex process should go smoothly under most circumstances, and the
document produced usually should not need manual tweaking. There are a few
technical details that may be of interest.
• Content that is printed (actually printed, not from a command like \py)
is always followed by a space when included as LATEX code rather than as
verbatim. Usually this is only noticeable when the content is used inline, ad-
jacent to other text. In such cases, you need to make sure that the spacing is
correct in your original document, and need to be aware of how depythontex
handles the conversion.
This spacing behavior is due to LATEX’s \input. When the file of printed
content is brought in via \input, LATEX removes any newline characters (\n,
\r, or \r\n) at the end of each line, and adds a space at the end of each line
(even if there wasn’t a newline character). Thus, when the printed content
is brought in, a space is added to its end. Since this space is within the
\input’s curly braces {}, it is not combined with any following spaces in
the LATEX document to make a single space. Rather, if the printed content
is followed by one or more spaces, two spaces will result; and if it is followed
immediately by text, there will be a single space before the text.
The space added by \input is often invisible, and even when it is not, it
is sometimes desirable.26 But this space can be an issue in some inline
contexts. The simplest solution is to use a command like \py to bring in
content inline.
If a command like \py is not practical for some reason, there are at least three
ways to deal with the space introduced by \input: by printing \endinput at
the end of the printed content (ending the content before the final space), by
printing % at the end of the printed content (commenting out the final space),
or by using \unskip after the printed content (eating preceding spaces).
depythontex will work with all three approaches, but only under a limited
range of circumstances. In summary, depythontex works with \endinput
25 Keep in mind that any time \graphicspath is used, it overwrites any previously specified

path. If your document is using \graphicspath at multiple points in the preamble, or using it
anywhere outside the preamble, then the --graphicspath option will fail due to the path being
overwritten.
26 For example, \string\printpythontex behaves as a normal command, and gobbles following

spaces, but the space from \string\input puts a space back. So you often get the space you
want in inline contexts.

45
and % only if they are the very last thing printed (before a final newline),
and works with a following \unskip.27
– \endinput cannot be left in the printed content that is substituted
into the new document, because it would cause the new document to
end immediately. depythontex checks the very end of printed content
for \endinput, and removes it if it is there before substituting the
content. The terminating \endinput is only removed if it is not a
string, \string\endinput.
If \endinput is anywhere else in the printed content, and it is not
immediately preceded by \string, depythontex issues a warning.
– A terminating % cannot be left in the printed content that is substituted
into the new document, because it would comment out any text in
the remainder of the line into which it is substituted (in \input, its
effect is limited to the print file). depythontex checks the very end of
printed content for %, and removes it if it is there before substituting
the content. depythontex only removes the terminating % if it is not a
literal character \% or \string%.
depythontex checks the last line of printed content for other % char-
acters, and issues a warning if there are any % characters that are not
part of \% or \string%.
– A following \unskip could be left in the new document, since it would
not produce incorrect spacing. But it would be undesirable, since it
was only there in the first place because of the way that PythonTEX
was used. depythontex checks for \unskip, and if it is found, attempts
to correct the spacing and remove the \unskip. This removal process
is only possible if \unskip immediately follows a command (otherwise,
it wouldn’t work anyway) or is on the line immediately after the end of
an environment.
If depythontex finds \unskip following printed content, but cannot
replace it (it doesn’t immediately follow a command, or isn’t on the
line immediately after the end of an environment), a warning is issued.
It is possible that the \unskip is not correctly positioned, and even if
it produces the correct spacing, the user should know that due to its
location it will survive in the converted document.
If one of the above approaches is not used to eliminate the space introduced
by the final newline in printed content, depythontex still makes sure that the
spacing in the new document matches that of the original document, even
if that means forcing a double space. In the majority of cases, depythontex
27 It would be possible to make depythontex work with \endinput and % anywhere, not just

at the very end of printed content. But doing so would require a lot of additional parsing,
especially for \endinput, to be absolutely sure that we found an actual command rather than a
string. Furthermore, there is no reason that there should be any content after an \endinput or
%, since such content would never be included in the document. Indeed, the current approach
prevents any printed content from accidentally being eliminated in this manner.

46
can create the correct spacing using actual spaces and newlines. But in a few
instances, it will include a \space{} to ensure a double space that matches
the original document. In those situations, a warning is issued in case the
spacing was not intentional.
• Strings such as \\}, \\{, and \string can occur in PythonTEX content
that is being replaced. It is possible that they might decrease performance
somewhat in larger or more complex documents.
PythonTEX commands for entering code allow the code to be delimited with
either matched braces {} or with a repeated character such as # (as in
\verb). Any verbatim code delimited by braces cannot contain any braces
unless they are paired. So it is easy for depythontex.py to find the end of
the delimited code.
However, depythontex.py must also replace PythonTEX commands that
take a normal, non-verbatim argument delimited by braces (for example, the
various \setpythontex... commands). Finding the closing brace for these
commands is usually straightforward, but it can be tricky because the argu-
ment might contain a literal brace such as \} or \string}. depythontex.py
automatically accounts for \}. If it detects \string, it also accounts for it,
but doing so requires more intense parsing. Similarly, \\} requires extra
parsing, because depending on what comes before it, the first backslash \
could be literal (for example, if preceded by \string), or the two backslashes
\\ could go together to indicate a new line.

6 LATEX programming with PythonTEX


This section will be expanded in the future. For now, it offers a brief summary.

6.1 Macro programming with PythonTEX


In many situations, you can use PythonTEX commands inside macro definitions
without any special consideration. For example, consider the following macro, for
calculating powers.
\newcommand{\pow}[2]{\py{#1**#2}}

Once this is defined, we can calculate 2**8 via \pow{2}{8}: 256. Similarly, we
can reverse a string.
\newcommand{\reverse}[1]{\py{"#1"[::-1]}}

Now we can use \reverse{``This is some text!''}: ”!txet emos si sihT“.


Such approaches will break down when some special LATEX characters such
as percent % and hash # must be passed as arguments. In such cases, the argu-
ments need to be captured verbatim. The xparse and newverbs packages provide

47
commands for creating macros that capture verbatim arguments. You could also
consult the PythonTEX implementation, particularly the implementation of the
inline commands. In either case, you may need to learn about TEX’s catcodes and
tokenization, if you aren’t already familiar with them.
Of course, there are many cases where macros don’t need arguments. Here is
code for creating a macro that generates random polynomials.
\begin{sympycode}
from sympy.stats import DiscreteUniform, sample
x = Symbol('x')
a = DiscreteUniform('a', range(-10, 11))
b = DiscreteUniform('b', range(-10, 11))
c = DiscreteUniform('c', range(-10, 11))
def randquad():
return Eq(sample(a)*x**2 + sample(b)*x + sample(c))
\end{sympycode}
\newcommand\randquad{\sympy{randquad()}}

If you are considering writing macros that involve PythonTEX, you should keep
a few things in mind.
• Do you really need to use PythonTEX? If another package already provides
the functionality you need, it may be simpler to use an existing tool, partic-
ularly if you are working with special characters and thus need to capture
verbatim arguments.
• A feature called depythontex has recently been added. It creates a copy
of the original LATEX document in which all PythonTEX commands and
environments are replaced by their output, so that the new document does
not depend on PythonTEX at all. This is primarily of interest for publication,
since publishers tend not to like special packages or macros. depythontex
does not yet support custom user commands. So if you decide to create
custom macros now, and expect to need depythontex, you should expect to
have to edit your macros before they will work with depythontex.

6.2 Package writing with PythonTEX


As of v0.10beta, the custom code command and environment, and the regular
code command and environment, work in the preamble. This means that it is now
possible to write packages that incorporate PythonTEX! At this point, packages
are probably a good way to keep track of custom code that you use frequently,
and maybe some macros that use PythonTEX.
However, you are encouraged not to develop a huge mathematical or scien-
tific package for LATEX using PythonTEX. At least not yet! As discussed above,
depythontex will bring changes to macro programming involving PythonTEX. So
have fun writing packages if you want—but keep in mind that PythonTEX will
keep changing, and some things that are difficult now may be very simple in the
future.

48
7 Support for additional languages
Details about adding support for additional languages are in Section 7.10. This
section begins with a brief overview of supported languages and available features.
Languages beyond Python are typically not be enabled by default to prevent
potential macro naming conflicts with other packages. Languages are enabled via
the usefamily package option (Section 4). For example,
\usepackage[usefamily=ruby]{pythontex}

Usually at least two possible base names for commands and environments will be
provided for each language. Typically these will be the name of the language and
the language’s file extension. For example, Ruby has the ruby and rb base names.
You can choose which base name to use for creating a family of commands and
environments based on personal preference and potential naming conflicts.

7.1 Ruby
Support for Ruby was added in v0.12. Ruby support should be almost at the same
level as that for Python.
The utilities class is called RubyTeXUtils, and the class instance is rbtex. The
variables and methods are the same as those for Python (Section 4.2.6), except
that there is not currently a set_formatter() or an open() method. (The Python
utilities class has the special SymPy formatter, but there aren’t yet any specialized
formatters for Ruby.)
A family of commands and environments for Ruby is not created by default.
Two base names are provided for families: ruby and rb. Preconfigured families
for these names may be created via the usefamily package option. Keep in mind
that a ruby command is defined as part of the Ruby package in the CJK package.
I am unaware of a package that provides an \rb command.
Ruby exceptions are synchronized with the document, but the line numbering
does not always correspond to the Python equivalent. For example, suppose that
\pyc{1+} is on line 10 of a document. The SyntaxError will then be synchronized
with line 10. If \rubyc{1+} were on the same line, the resulting error would be
synchronized with line 11. This is because Ruby allows addition to continue on
subsequent lines of code, so an error is only raised when the next line of code that
is executed does not contain a number (there is always template code after user
code).

7.2 Julia
Support for Julia was added in v0.12. Julia support should be at almost the same
level as that for Python. The format of Julia stderr is somethat different from
that of Python and Ruby. This required a modified parsing and synchronization
algorithm. The current system is functional but will likely change somewhat in
the future.

49
The utilities “class” is called JuliaTeXUtils (it is actually a composite type,
very similar to a struct), and the “class” instance is jltex. The variables and
methods are the same as those for Python (Section 4.2.6), except that there is
not currently a set_formatter() method or an open() method. (The Python
utilities class has the special SymPy formatter, but there aren’t yet any specialized
formatters for Julia.)
A family of commands and environments for Julia is not created by default.
Two base names are provided for families: julia and jl. Preconfigured families
for these names may be created via the usefamily package option. Keep in mind
that Pygments only added Julia support in version 1.6, so you may need to update
your Pygments installation, or just change the default lexer.
Julia exceptions are synchronized with the document, but the line numbering
does not always correspond to the Python equivalent. This is because Julia allows
expressions to be continued on subsequent lines in ways that Python does not.

Console
Julia console support was added in v0.16. It may be enabled by loading
PythonTEX with usefamily=juliacon. The juliaconsole environment uses
Weave.jl internally to evaluate code. There is also a juliaconcode environment
that executes code but typesets nothing.

7.3 Octave
Support for Octave was added in v0.13. Octave support should be at almost the
same level as that for Python. Parsing of stderr for synchronization is successful
in most cases but not ideal; this will be improved in a future release by a rewrite
of the stderr parser.
Octave does not have a genuine utilities class, since it only supports @CLASS
classes and does not yet support newer MATLAB-style classdef. As a result of
this limited support for classes, there is a struct octavetex rather than a utilities
class instance octavetex. What would have been attributes of a utilities class
instance are instead fields of the struct. What would have been methods of a
class are instead anonymous functions. This allows octavetex to be used in most
respects as if it were a class instance, especially insofar as syntax is concerned.
There are no set_formatter() or open() methods.
If any “methods” need to be overwritten, the simplest approach is proba-
bly to define a function and then set the appropriate struct field to an anony-
mous function that will call that function. For example, to replace the default
octavetex.before(), we might define a function before(), and then use the
command octavetex.before = @() before();. Of course, if the function is suf-
ficiently short, it will be simpler just to put everything in the anonymous function:
octavetex.before = @() <expression>;
A family of commands and environments for Octave is not created by default;
the base name octave is provided.

50
When \setpythontexcontext is used, it must be accessed as struct fields, of
the form octavetex.context.<name>.

7.4 bash
Support for bash was added in v0.15. Support for bash is very basic. Bash
commands may be executed, and their output (stdout and stderr) may be typeset.
As with other languages, all commands are executed in a single session unless the
user specifies otherwise. There is not a utilities class or any related features.
Bash will work with Windows if it is installed.

7.5 Rust
Support for Rust was added in v0.15, with the command/environment base names
rs and rust. Complete support is provided, except that the utilities struct rstex
does not have an open() method. Also rstex.formatter(), rstex.before(),
and rstex.after() may need additional refinement in the future to make them
more convenient to work with. All user code is inserted within a template-
generated main() function; main() should not be defined explicitly. Future refine-
ments of PythonTEX’s template system may allow user code outside of main().
Because Rust typically gives a long sequence of errors, PythonTEX processing
and synchronization of stderr is currently verbose and may need to be improved in
the future as well. There is no support for encodings other than UTF-8. Currently,
executables always use the .exe extension, even under non-Windows systems.
Due to the way rstex is used in template-generated code, it needs to remain a
mutable local variable. This means that, while there should be no problem using
it through either shared or mutable references, taking it by value requires that the
“altered” copy is reassigned to a new variable that shadows the old one. That is,
code that needs to work with rstex by value should look like

let mut rstex = hcode i;


Additionally, when using \rust and \rs, keep in mind that these wrap code in
a block, so you cannot use rstex by value in these contexts (both shared and
mutable references are still fine, though).

7.6 R
Support for R was added in v0.17.
Loading PythonTEX with usefamily=R enables the R family of commands
and environments (\R, \Rc, Rcode, ...). These execute code with Rscript. The
methods library is loaded automatically as part of the template code. Expres-
sions passed to the \R command are converted into strings via toString().
There is currently no utilities class or related features. A null graphics device,
pdf(file=NULL), is created by default to avoid the automatic, unintentional cre-
ation of plot files with default names. Plots that are to be saved require explicit
graphics commands.

51
Console
Loading PythonTEX with usefamily=Rcon enables the Rconsole environment,
which executes code to emulate an interactive R session. There is also an Rconcode
environment that executes code but typesets nothing. Code is executed with
Rscript. The methods library is loaded automatically as part of the template
code. The option echo=TRUE is used to intersperse code with output, while
error=function(){} is used to avoid halting on errors. A null graphics device,
pdf(file=NULL), is created by default to avoid the automatic, unintentional cre-
ation of plot files with default names. Plots that are to be saved require explicit
graphics commands.

7.7 Perl
Support for Perl was added in v0.17.
Loading PythonTEX with usefamily=perl enables the perl family of com-
mands and environments. Alternatively, usefamily=pl may be used to enable
the pl family. There is currently no utilities class or related features.

7.8 Perl 6
Support for Perl 6 was added in v0.17.
Loading PythonTEX with usefamily=perlsix enables the perlsix family of
commands and environments. Alternatively, usefamily=psix may be used to
enable the psix family. There is currently no utilities class or related features.

7.9 JavaScript
Support for JavaScript was added in v0.17.
Loading PythonTEX with usefamily=javascript enables the javascript
family of commands and environments. Alternatively, usefamily=js may be used
to enable the js family. There is a utilities object jstex.

7.10 Adding support for a new language


Adding support for an additional language involves creating two templates, cre-
ating a new instance of a class, and using a PythonTEX macro. In some cases,
additional changes may be necessary for full support. The information below
does not deal with creating console families; additional support for user-defined
console families will be added in the future.
The system for adding languages should be relatively stable, but is subject
to change as additional languages with additional requirements are added. The
current system is sufficient for Python and similar languages. Languages with less
regular stderr may require additional features and may not be able to have full
synchronization between stderr and the LATEX document. Keep in mind that if
PythonTEX is unable to classify exceptions as errors or warnings, it treats them
as errors or warnings based on the script exit status.

52
It may be helpful to refer to pythontex_engines.py, specifically the templates
and utilities classes, while reading the section below.

7.10.1 Template
PythonTEX executes user code by inserting it in a script template. Replacement
fields in the template are indicated by curly braces: {hfieldi}.28 Space between
hfieldi and the braces is not allowed. Replacement fields (including the braces)
should be surrounded by quotation marks or equivalent when the replacement is
to be a string rather than literal code.
The template should perform the following tasks.
• Set the script encoding. The {encoding} field will be replaced with a user-
specified encoding or the default UTF-8. If you are not using anything beyond
ASCII, this is not strictly necessary.

• Python templates should have a {future} field at the beginning, for com-
pability with Python 2 and the package option pyfuture.29
• Set the stdout and stderr encoding, again using {encoding}. As before,
this is not strictly necessary when only ASCII support is needed.

• Create a language-specific equivalent of the PythonTEX utilities class.30 Cre-


ate an instance of this class. It is recommended that the class be called
hlanguage nameiTeXUtils and the instance hlanguage extensionitex, by
analogy with the Python case.31 When the hlanguage extensioni is only
a single character or is shared by multiple languages, it may be better to
use the full hlanguage namei or an abbreviation in the name of the class
instance.
For full PythonTEX support, the utilities class should provide the following
methods:
– formatter(): For formatting content for inline commands equivalent
to \py. This should take a single argument of any type. By default, it
should return a standard string representation of its argument.
28 This follows Python’s format string syntax. Literal curly braces are obtained by doubling.
29 The beginning of user code is parsed for imports from __future__. Any imports are collected
and inserted into the {{future}} field.
30 Python templates can import the PythonT X utilities class. In that case,
E
sys.path.append(’{{utilspath}}’) is needed before the import, so that the location of the
utilities class is known.
31 The class could be called hlanguage nameiTeX. In that case, the class and the instance would

have the very same name (except for capitalization) in cases where the language name and
extension are the same (for example, Lua). That is probably not desirable, and besides, Utils
adds additional clarity. The instance name hlanguage extensionitex is recommended because it
will be short and easily remembered. Plain tex could be used instead, but that would be less
descriptive (it lacks the interface connotations) and would not remind the user of the language
currently in use (which could be beneficial in a document combining multiple languages, each
with its own slightly different utilities class).

53
– before() and after(): Initially, these should do nothing; they are
provided to be redefined by the user. They should take no arguments.
– add_dependencies() and add_created(): These should accept an ar-
bitrary number of comma-separated strings (if supported by the lan-
guage). Each method should append its arguments to a list or equiva-
lent data structure, for later use.
– cleanup(): This prints a dependencies delimiter string {dependencies_delim}
to stdout, then prints all dependencies (one per line), then prints a cre-
ated files delimiter string {created_delim}, then prints the names of
all created files (one per line). The delimiters should be printed even
if there are no dependencies or created files. The delimiters contain no
backslashes or quotes.
The utilities class should also provide several variables, as described below.
• Attempt to change to the working directory {workingdir}. Raise an error
and exit if this is not possible. For convenience, the script should check for
a --manual command line argument. If this argument is present, the script
should proceed even if the working directory cannot be found. This allows
the user to manually invoke the script for debugging (the script can be saved
via keeptemps).
The working directory should be added to the module search path (Python
sys.path, Ruby $: or $LOAD_PATH, etc.), unless it is the same as the docu-
ment root directory or is otherwise already on the module search path.
• For full compatibility, the template should have an {extend} field where
additional module imports or other code may be inserted. This allows a
basic template to be a created for each language. The basic template may
then be customized for specific purposes. The {extend} field should be
after the utilities class instance has been created, so that the workings of the
utilities class (formatter(), before(), after(), etc.) may be customized
by it.
• LATEX-related variables of the utilities class instance that do not change
should be set. These use the fields {family}, {session}, and {restart}; all
should be strings. These variables should be named after the fields if possible
(for example, pytex.family). These variables are not strictly necessary, but
they allow user code to access information about its origin on the TEX side.
• There should be a {body} field where the body of the script is inserted.

• The script should end by calling the cleanup() method.

7.10.2 Wrapper
Each chunk of user code is inserted into a wrapper template. This performs the
following tasks.

54
• Set additional LATEX-related utilities variables: {command}, {context},
{args}, {instance}, {line}. They are not required, but make possible
closer LATEX integration. {args} is not yet supported on the LATEX side, but
will allow arguments from LATEX commands to be passed to user code.
All utilities variables should be stored as strings, except for context and
args. If possible, these should be dictionaries or equivalent associative ar-
rays of string keys that point to string values. The dictionaries should be
created by processing {context} and {args} into comma-separated lists of
key-value pairs. For example, if {context} is the string “k1=v1, k2=v2”,
then pytex.context should be a dictionary, and pytex.context['k1']
should yield the string “v1”. The key-value pairs may optionally be accessed
as attributes, when this is possible with a given language. For example,
pytex.context.k1 could yield the string “v1”.
• Write a delimiter {stdoutdelim} to stdout and a delimiter {stderrdelim}
to stderr. Both delimiters should be strings. Both should be written in
such a way that the delimiter is followed by a newline; the delimiters that
are inserted in the wrapper template do not contain a newline.32 For exam-
ple, something like "{stderrdelim}\n" might be necessary. The delimiters
contain no backslashes or quotation marks.
• Call before().
• Have a {code} field into which the current chunk of user code is inserted.

• Call after().

7.10.3 The CodeEngine class


The final step in adding support for a language is creating a new instance of the
CodeEngine class. The CodeEngine class manages the process of inserting user
code into code templates and creates the records needed for synchronizing stderr
with the document.
A new CodeEngine instance is initialized with the following arguments. All
arguments are strings unless noted otherwise.
• The instance name. This will be the base name for commands and environ-
ments that use the instance. For example, \py, \pyc, pycode, etc., rely on
the py instance of the CodeEngine class.

• The name of the language. In some cases, this may be the same as the
instance name.
• The filename extension for scripts (with or without a period).
32 This way, we don’t have to assume that all languages will use \n for the newline character.

55
• The command for running scripts. The script that is executed should be
referred to as “{file}.hextensioni” (without the quotes).33 The interpreter
may be hardcoded (python {file}.py), but it is best to leave it as a substi-
tution field ({python} {file}.py) so that the --interpreter command-
line option can be used to provide a specific interpreter.

• The script template.


• The wrapper template.
• A template that specifies how code from commands like \py should be in-
serted into a call to the formatter() method. The user code is specified
by {code}. The output of the formatter() method should be written to
stdout, so something like 'print(pytex.formatter({code}))' is needed.
• An optional list of strings (or an individual string) that gives patterns for
identifying error messages.
• An optional list of strings (or an individual string) that gives patterns for
identifying warning messages.
• An optional list of strings (or an individual string) that gives patterns
for identifying code line numbers in stderr. These patterns use the field
{number}. These patterns are searched for in any line of stderr that con-
tains the name of the script that was executed.

• An optional boolean that specifies whether the engine emulates an interac-


tive console. Currently, user-defined engines that emulate consoles are not
supported.
• An optional string of startup commands for engines that emulate consoles.

• An optional list of strings (or an individual string) that specifies any files
created during execution, beyond the script {file}.hextensioni. The field
{file} may be used in file names, if files are created with the same base
name as the script; this could be useful with compiled languages, which
might have a {file}.hextensioni that ultimately results in a {file}.out,
{file}.exe, etc.

An example of creating the py engine is shown below. The python_template


and python_wrapper are long enough that they are defined separately.
CodeEngine('py', 'python', '.py', 'python {file}.py',
python_template, python_wrapper,
'print(pytex.formatter({code}))',
'Error:', 'Warning:', ['line {number}', ':{number}:'])

33 It might seem that the extension is redundant, since it is specified separately. The command

is specified in this form to simplify cases where there may be intermediary files in the execution
process.

56
The script template and wrapper templates may be defined with Python’s triple-
quoted strings. All content within such a string may be indented for clarity, as
can be seen in pythontex_engines.py. Strings are automatically dedented when
CodeEngine instances are created.
In addition to the CodeEngine class, there is also a SubCodeEngine class. It
allows a new engine to be created based on an existing engine. It requires the
name of the engine from which to inherit and the name of the new engine. All of
the other arguments listed above are optional; if any are provided, they overwrite
the inherited arguments. The class also takes one additional optional argument,
extend. This is a string that specifies additional code to be entered in the inherited
template, in the {extend} field. Subengines of subengines may be created; in that
case, any extends are cumulative.

7.10.4 Creating the LATEX interface


Once a new engine has been created, access from the LATEX side must be provided.
PythonTEX provides a macro for this purpose.
\makepythontexfamily[hoptions i]{hengine i}
This command creates a non-console family of commands and environments
for henginei: code, block, and verbatim commands and environments, and an
inline command like \py.
This command is appropriate for user-defined languages, but it is
preferable (and more convenient) to use the package option usefamily
when using an engine that is included with PythonTEX. The package
option will create a preconfigured family in which things such as the appropriate
Pygments lexer have already been set.
hoptionsi allows prettyprinter, pyglexer, and pygopt to be specified for the
family.

8 Troubleshooting
• If a PythonTEX document will not compile, you may want to delete the
directory in which PythonTEX content is stored and try compiling from
scratch. It is possible for PythonTEX to become stuck in an unrecoverable
loop. Suppose you tell Python to print some LATEX code back to your LATEX
document, but make a fatal LATEX syntax error in the printed content. This
syntax error prevents LATEX from compiling. Now suppose you realize what
happened and correct the syntax error. The problem is that the corrected
code cannot be executed until LATEX correctly compiles and saves the code
externally, but LATEX cannot compile until the corrected code has already
been executed. One solution in such cases is to correct the code, delete all
files in the PythonTEX directory, compile the LATEX document, and then
run PythonTEX from scratch. You can also disable the inclusion of printed
content using the debug package option.

57
You may also run PythonTEX with the --debug option to launch the default
debugger, or use the debugger of your choice by adding code that launches
a debugger and then running PythonTEX with the --interactive option.
See Section 3.2 for more details.
• Dollar signs $ may appear as £ in italic code comments typeset by Pygments.
This is a font-related issue. One fix is to \usepackage[T1]{fontenc}.
• The tabular environment can conflict with PythonTEX under some circum-
stances, due to how tabular functions. Among other things, printing within
a tabular environment can cause errors, because printing involves bringing
in external content via \InputIfFileExists, but that macro is not expand-
able.34 There are a few different ways to work around the limitations of
tabular.
– Put the printed content in a macro definition, and use the macro in
tabular. You will have to create a dummy version of the macro, to
avoid errors before the macro is defined by PythonTEX. An example is
given below. The \global\def is needed so that the macro is defined
outside of the pycode environment.
\let\row\relax
\begin{pycode}
print("\\global\\def\\row{a & b & c & d & e \\\\}")
\end{pycode}

\begin{tabular}{|c|c|c|c|c|}
\row
\end{tabular}
– Use \py. The end-of-row \\ must be outside of the command. Example:
\begin{tabular}{|c|c|c|c|c|}
\py{"a & b & c & d & e"} \\
\end{tabular}

• PythonTEX commands like \py won’t work inside siunitx macros, because
\py and company aren’t fully expandable.35 There are different ways to
work around this; some examples are shown below.

\documentclass{article}
\usepackage{siunitx}
\usepackage{pythontex}

\begin{pycode}
def SI(var, unit):
return '\\SI{' + str(var) + '}{' + unit + '}'
\end{pycode}
34 For more information, see this, this, and this.
35 For more details, see this, this, and this.

58
\newcommand{\pySI}[2]{\py{'\\SI{' + str(#1) + '}{#2}'}}

\begin{document}
\pyc{y = 4}

The value of y is \py{SI(y, r'\metre')}.

The value of y is \pySI{y}{\metre}.

\end{document}

Another example, this time using SymPy:

\newcommand{\sympySI}[2]{\sympy{SI(#1,r"#2")}}
\begin{sympycode}
def SI(var, unit):
return '\\SI{{{0}}}{{{1}}}'.format(N(var, 4), unit)
\end{sympycode}

9 The future of PythonTEX


This section consists of a To Do list for future development. The To Do list is
primarily for the benefit of the author, but also gives users a sense of what changes
are in progress or under consideration.

9.1 To Do
9.1.1 Modifications to make
• Add support for depythontex to remove the \usepackage for a package
that contains PythonTEX commands and environments.
• Add better support for macro programming, including depythontex support
for user-defined commands and environments.
• Add Pygments commands and environments that are compatible with basic
listings and minted syntax. This will make it easier to work with docu-
ments converted to LATEX from another format, for example via Pandoc.
• User-defined custom commands and environments for general Pygments
typesetting.
• Additional documentation for the Python code (Sphinx?).

• Improved testing framework.


• It might nice to include some methods in the PythonTEX utilities for for-
matting numbers (especially with SymPy and Pylab).

59
• Test the behavior of files brought in via \input and \include that contain
PythonTEX content.
• Continue adding support for additional languages. Under consideration:
Perl, Lua, MATLAB, Mathematica, Sage, R, Octave.

9.1.2 Modifications to consider


• Consider fixing error line number synchronization with Beamer (and other
situations involving error lines in externalized files). The filehook and
currfile packages may be useful in this. One approach may be to patch the
macros associated with \beamer@doframeinput in beamerbaseframe.sty.
Note: Beamer’s fragile=singleslide option makes this much less of an
issue. This is low priority.
• Allow LATEX in code, and expand LATEX macros before passing code to
pythontex.py. Maybe create an additional set of inline commands with
additional exp suffix for expanded? This can already be done by creating a
macro that contains a PythonTEX macro, though.
• Built-in support for background colors for blocks and verbatim, via mdframed
or a similar package?

• Support for executing external scripts, not just internal code? It would be
nice to be able to typeset an external file, as well as execute it by passing
command-line arguments and then pull in its output.
• Is there any reason that saved printed content should be allowed to be
brought in before the code that caused it has been typeset? Are there
any cases in which the output should be typeset before the code that cre-
ated it? That would require some type of external file for bringing in saved
definitions.
• Consider some type of primitive line-breaking algorithm for use with Pyg-
ments. Could break at closest space, indent 8 spaces further than parent
line (assuming 4-space indents; could auto-detect the correct size), and use
LATEX counter commands to keep the line numbering from being incorrectly
incremented. Such an approach might not be hard and might have some real
promise.
• Consider allowing names of files into which scripts are saved to be specified.
This could allow PythonTEX to be used for literate programming, general
code documentation, etc. Also, it could allow writing a document that
describes code and also produces the code files, for user modification (see
the bashful package for the general idea). Doing something like this would
probably require a new, slightly modified interface to preexisting macros.

60
Acknowledgements
Thanks to Nicholas Lu Chee Seng for help testing the earliest versions.
Thanks to Øystein Bjørndal for many suggestions and for help with OS X
compatibility.
Thanks to Alexander Altman for suggesting Rust support and providing tem-
plate code.
Thanks to Nathan Carter for suggesting JavaScript support and providing
template code.

Version History
v0.18 (2021/06/06)
• \inputpygments now checks inputted files for modification, so that typeset
code will correctly update when the source is changed (#162).
• Julia now uses project flag “--project=@.” (#157, #158).

• Fixed bug in processing Pygments options (pygopt) when a key is used


without a value (#181).
• Some error handling for Windows was incompatible with other operating
systems: replaced checks for WindowsError with checks for OSError (#177).
• Rust support is now compatible with document and working directory paths
that contain spaces (#167).

v0.17 (2019/09/22)
• Pygments syntax highlighting for the Python console (pycon lexer) now uses
the python3 option, and the default Python lexer is now python3 (#156).

• Added support for JavaScript (#147; thanks to Nathan Carter).


• Updated Julia support for Julia versions 0.6 (#107), and 0.7 and 1.0 (#126,
#130).
• There are now meaningful error messages for the Julia console when Weave.jl
is not installed or raises errors (#131).
• pythontexcustomcode and \pythontexcustomc now set pytex.context
(#65).
• Added support for R. The R family of commands and environments (\R,
\Rc, Rcode, ...) executes code as a script. There is currently no utilities
class or equivalent. The Rcon family (Rconsole) executes code to emulate
an interactive R session (#121).

61
• fancyvrb settings from \setpythontexfv and console environments now
work with Julia and R consoles.
• pythontexcustomcode now works with juliacon. There are now proper
juliaconcode and Rconcode environments that execute code but typeset
nothing, to parallel pyconcode (#134).

• Added support for Perl with the perl and pl families of commands and
environments. There is currently no utilities class or equivalent.
• Added support for Perl 6 with the perlsix and psix families of commands
and environments (#104). There is currently no utilities class or equivalent.

• Updated Rust support by using dyn with traits in utilities object.


• Under Windows, capitalization of script paths in stderr is now preserved.
• Fixed a bug that prevented the sub environment from working with
depythontex (#155).

• Fixed a bug in checking mtime of dependencies to see if they have been


modified while pythontex is running. The check failed for dependencies
that do not exist or were deleted before pythontex can read them (#136).

v0.16 (2017/07/20)
• Added preliminary console support for Julia (#98).
• Fixed Python console compatibility with Python 3.6 by setting the code
module’s new exitmsg argument to suppress the exit message (#100).
• Improved Rust support, including tracking of created files and dependencies
(#91).

v0.15 (2016/07/21)
New features
• The fvextra package is now required. This provides line breaking with fine-
grained control over break locations, the ability to highlight specific lines or
ranges of lines, improved handling of tabs, and several additional features.
• Added sub commands and environments (\pys, pysub, ...). These com-
mands and environments perform string interpolation on text. Fields delim-
ited by !{...} are replaced by the result of evaluating and then printing
their content. This works for all families of commands and environments,
not just Python. See the documentation for details about field delimiters
and escaping.

62
• Added rust and rs families of commands and environments. These pro-
vide essentially complete support for Rust, except that rstex.formatter(),
rstex.before(), and rstex.after() will likely need additional refinement
(#90).
• Added the sage family of commands and environments, which provide sup-
port for Sage (#63).
• Added bash family of commands and environments. This provides basic
support for bash (no utilities class or equivalent). Bash works with Windows
if it is installed.

• Improved console compatibility under Linux with Python 3 (#70).


• Counters for default sessions are now created automatically. This prevents
counter errors under some circumstances when working with \includeonly.
• Commands like \py can now output verbatim content under LuaTeX.

Bugfixes
• Fixed a bug that could cause an endless loop when a code command or
environment printed a code command or environment of the same family
with autoprint=true.

v0.14 (2014/07/17)
New features
• All commands for working with code inline are now robust, via etoolbox’s
\newrobustcmd. Among other things, this allows commands like \py to
work in standard captions that have not been redefined to avoid protection
issues.
• Upgraded syncpdb to v0.2, which provides better list formatting.
Backward-incompatible changes
• The default working directory is now the main document directory instead
of the output directory. Using the output directory was a common source of
confusion for new users and was incompatible with plans for future develop-
ment. Old documents in which the working directory was not specified will
continue to use the output directory, but PythonTeX will print an upgrade
message; new documents will use the new setting. The output directory
may be selected as the working directory manually, or with the shorthand
“\setpythontexworkingdir{<outputdir>}”.
• Standardized version numbering by removing the “v” prefix from the stored
version numbers in Python variables and LaTeX macros. Standardized the
PythonTeX scripts by renaming version to __version__.

63
v0.13 (2014/07/14)
New features
• Added --interactive command-line option. This runs a single session in
interactive mode, allowing user input. Among other things, this is useful
when working with debuggers.
• Added --debug command-line option. This runs a single session with the de-
fault debugger in interactive mode. Currently, only standard (non-console)
Python sessions are supported. The default Python debugger is the new
syncpdb, which wraps pdb and synchronizes code line numbers with doc-
ument line numbers. All pdb commands that take a line number or file-
name:lineno as an argument will refer to document files and line numbers
when the argument has a percent symbol (%) as a prefix. For example, list
%50 lists code that came from around line 50 in the document. The --debug
option will support other languages and provide for customization in the
future.

• Added command-line option --jobs, which allows the maximum number of


concurrent processes to be specified (#35).
• Added support for GNU Octave, via the octave family of commands and
environments (#36). Parsing of Octave stderr is not ideal, though synchro-
nization works in most cases; this will be addressed by a future rewrite of
the stderr parser.
• Installer now automatically works with MiKTeX, not just TeX Live.
• The PythonTeX utilities class has a new open() method that opens files and
automatically tracks dependencies/created files.

• When pythontex2.py and pythontex3.py are run directly, the Python in-
terpreter is automatically set to a reasonable default (py -2 or py -3 under
Windows, using the Python 3.3+ wrapper; python2 or python3 under other
systems).
• The installer now creates symlinks for the numbered scripts pythontex*.py
and depythontex*.py.
• Added Python version checking to all numbered scripts.
• Under Python, the type of data passed via \setpythontexcontext may
now be set using YAML-style tags (!!str, !!int, !!float). For example,
\setpythontexcontext{myint=!!int 123}.
• The fancyvrb options firstline and lastline now work with the
pygments environment and \inputpygments command. This required some
additional patching of fancyvrb.

64
• The pytx@Verbatim and pytx@SaveVerbatim environments are now used
for typesetting verbatim code. These are copies of the fancyvrb environ-
ments. This prevents conflicts when literal Verbatim and SaveVerbatim
environments need to be typeset.
• Improved latexmk compatibility (#40). Added discussion of latexmk usage
to documentation.
• Tildes ~ may now be used in outputdir and workingdir to refer to the
user’s home directory, even under Windows.
Bugfixes

• Fixed a bug that prevented created files from being cleaned up when the
working directory was not the document root directory and the full path to
the files was not provided.
• Fixed a bug that prevented the fvextfile option from working when ex-
ternal files were highlighted.

v0.13-beta (2014/02/06)
New features
• Switching to GitHub’s Releases for downloads.

• TeX information such as page dimensions may now be easily passed to the
programming-language side, using the new \setpythontexcontext com-
mand. Contextual information is stored in the context attribute of the
utilities class, which is a dictionary (and also has attributes in Python).
• The utilities class now has pt_to_in(), pt_to_cm(), and pt_to_mm() meth-
ods for converting units of TeX points into inches, centimeters, and millime-
ters. These work with integers and floats, as well as strings that consist of
numbers and optionally end in “pt”. There is also a pt_to_bp() for con-
verting TeX points (1/72.27 inch) into big (DTP or PostScript) points (1/72
inch).

• Expanded Quickstart. Quickstart is now compatible with all LaTeX engines.


Quickstart now avoids microtype issues on some systems (#32).
• Added information on citing PythonTeX (#28).
• Utilities class has a new attribute id, which is a string that joins the com-
mand family name, session name, and session restart parameters with un-
derscores. This may be used in creating files that need a name that contains
a unique, session-based identifier (for example, names for figures that are
saved automatically).
Backward-incompatible changes

65
• All utilities-class attributes with names of the form input_* have been re-
named with the “input_” removed. Among other things, this makes it easier
to access the context attribute (pytex.context vs. pytex.input_context).
• depythontex now has -o and --output command-line options for specifying
the name of the output file. If an output file is not specified, then output is
written to stdout. This allows depythontex output to be piped to another
program.
• All scripts *2.py now have shebangs with env python2, and all scripts
*3.py now have shebangs with env python3. This allows the wrapper
scripts (env python shebang) to be used with the default Python installa-
tion, and the numbered scripts to be used with specific versions. Remember
that except for console content, the --interpreter option is what deter-
mines the Python version that actually executes code. The version of Python
used to launch pythontex.py merely determines the version that manages
code execution. (--interpreter support for console content is coming.)
• Changed the template style used in the CodeEngine class. Replacement
fields are now surrounded by single curly braces (as in Python’s format
string syntax), rather than double curly braces. Literal curly braces are
obtained by doubling braces. This allows the use of literal adjacent double
braces in templates, which was not possible previously.
• The Julia template now uses the new in() function, replacing contains().
This requires Julia v0.2.0+.
Bugfixes
• Modified test for LuaTeX, so that \directlua is not \let to \relax if it
does not exist. This was causing incompatibility with babel under pdfTeX
and XeTeX (#33).
• Added missing shebangs to depythontex*.py. Handling of utilspath is
now more forgiving, so that pythontex_utils.py can be installed in alter-
nate locations (#23).
• depythontex no longer leaves a blank line where \usepackage{pythontex}
was removed.
• Console environments typeset with fancyvrb no longer end with an unnec-
essary empty line.
• Fixed bug in installer when kpsewhich was not found (#21).

v0.12 (2013/08/26)
• Added support for the Julia language, with the julia and jl families of com-
mands and environments. (Note that Pygments only added Julia support in
version 1.6.)

66
• Warnings and errors are now synchronized with the line numbers of files
brought in via \input, \include, etc. This is accomplished using the
currfile package.
• Added package option gobble. When gobble=auto, all code is dedented
before being executed and/or typeset. The current implementation is func-
tional but basic; it will be improved and extended in the future.
• The document root directory is now always added to sys.path (or its equiv-
alent), even when it is not the working directory. (The working directory has
been added to sys.path since v0.12beta.) The document directory is added
after the working directory, so that the working directory has precedence.

• Fixed a bug in console commands and environments; sys.path now con-


tains the working and document directories, and the working directory is now
the output directory by default. This parallels the behavior of non-console
commands and environments.
• Added command-line option --interpreter that allows an interpreter to be
invoked via a specific command. This allows, for example, a specific version
of Python to be invoked.
• Improved synchronization of stderr in cases when an error is triggered far
after its origin (for example, an error caused by a multiline string that is
lacking a closing quote/delimiter, and thus may span several chunks of user
code).
• Modified usage of the shlex module to work around its lack of Unicode
support in Python versions prior to 2.7.3.
• Fixed a bug from v0.12beta that prevented \inputpygments from working
when pygments=true.
• Fixed a bug with counters that caused errors when content spanning multiple
columns was created within a tabular environment.
• Added checking for compatible Python versions in pythontex.py.

• Improved execution of *.bat and *.cmd files under Windows. The solution
from v0.12beta allowed *.bat and *.cmd to be found and executed when
the extension was not given, but did not give correct return codes.

v0.12beta (2013/06/24)
• Merged pythontex_types*.py into a single replacement pythontex_engines.py
compatible with both Python 2 and 3. It is now much simpler to add support
for additional languages.

67
• Added support for the Ruby language as a demonstration of new capabilities.
The ruby and rb families of commands and environments may be enabled
via the new usefamily package option. Support for additional languages is
coming soon. See the new section in the documentation on support for other
languages for more information.

• Reimplemented treatment of Pygments content for better efficiency. Now


a Pygments process only runs if there is content to highlight. Eliminated
redundant highlighting of unmodified code.
• Improved treatment of dependencies. If a dependency is modified (os.path.getmtime())
after the current PythonTeX run starts, then code that depends on it will
be re-executed the next time PythonTeX runs. A message is also issued to
indicate that this is the case.
• The utilities class now has before() and after() methods that are called
immediately before and after user code. These may be redefined to customize
output. For example, LaTeX commands could be printed before and after
user code; stdout could be redirected to StringIO for further processing; or
matplotlib figures could be automatically detected, saved, and included in
the document.
• Added explanation of how to track dependencies and created files automat-
ically, and how to include matplotlib figures automatically, to the documen-
tation for the PythonTeX utilities class.
• Created a new system for parsing and synchronizing stderr.
– Exceptions that do not reference a line number in user code (such as
those from warnings.warn() in a module) are now traced back to a
single command or environment. Previously no synchronization was
attempted. This is accomplished by writing delimiters to stderr before
executing the code from each command/environment.
– Exceptions that do reference a line in user code are more efficiently
synchronized with a document line number. This is accomplished by
careful record keeping as each script is assembled. Line number syn-
chronization no longer involves parsing the script that was executed.
– Improved and generalized parsing of stderr, in preparation for support-
ing additional languages. Exceptions that cannot be identified as errors
or warnings are treated based on Popen.returncode.
• Created a new system for console content.

– There are now separate families of console commands and environ-


ments. No Pygments or fancyvrb settings are shared with the non-
console families, as was previously the case. There is a new family of
commands and environments based on pycon, including the \pycon

68
command (inline reference to console variable), pyconsole environ-
ment (same as the old one), \pyconc and pyconcode (execute only),
and \pyconv and pyconverbatim (typeset only). There are equivalent
families based on pylabcon and sympycon.
– Each console session now runs in its own process and is cached individu-
ally. Console output is now cached so that changing Pygments settings
no longer requires re-execution.
– Unicode is now supported under Python 2.
– The new package option pyconfuture allows automatic imports from
__future__ for console families under Python 2, paralleling the
pyfuture option.
– Any errors or warnings caused by code that is not typeset (code com-
mand and environment, startup code) are reported in the run summary.
This ensures that such code does not create mischief.
– customcode is now supported for console content.

• Better support for latexmk and similar build tools. PythonTeX creates a file
of macros (*.pytxmcr) that is always included in a document, and thus can
be automatically detected and tracked by latexmk. This file now contains
the time at which PythonTeX last created files. When new files are created,
the macro file will have a new hash, triggering another document compile.

• Improved the way in which the PythonTeX outputdir is added to the graph-
ics path. This had been done with \graphicspath, but that overwrites any
graphics path previously specified by the user. Now the outputdir is ap-
pended to any pre-existing path.
• Added the depythontex option --graphicspath. This adds the outputdir
to the graphics path of the depythontex document.
• The installer now provides more options for installation locations. It will
now create missing directories if desired.
• The working directory (workingdir) is now appended to sys.path, so that
code there may be imported.

• Under Windows, subprocess.Popen() is now invoked with shell=True if


shell=False results in a WindowsError. This allows commands involving
*.bat and *.cmd files to be executed when the extension is not specified;
otherwise, only *.exe can be found and run.

• The path to utils is now found in pythontex.py via sys.path[0] rather


than kpsewhich. This allows the PythonTeX scripts to be executed in an
arbitrary location; they no longer must be installed in a texmf tree where
kpsewhich can find them.
• Added rerun value never.

69
• At the end of each run, data and macros are only saved if modified, improving
efficiency.
• The number of temporary files required by each process was reduced by one.
All macros for commands like \py are now returned within stdout, rather
than in their own file.

• Fixed a bug with \stderrpythontex; it was defaulting to verb rather than


verbatim mode.

v0.11 (2013/04/21)
• As the first non-beta release, this version adds several features and intro-
duces several changes. You should read these release notes carefully, since
some changes are not backwards-compatible. Changes are based on a thor-
ough review of all current and planned features. PythonTeX’s capabilities
have already grown beyond what was originally intended, and a long list
of features still remains to be implemented. As a result, some changes are
needed to ensure consistent syntax and naming in the future. Insofar as
possible, all command names and syntax will be frozen after this release.
• Added the pythontex.py and depythontex.py wrapper scripts. When run,
these detect the current version of Python and import the correct Python-
TeX code. It is still possible to run pythontex*.py and depythontex*.py
directly, but the new wrapper scripts should be used instead for simplicity.
There is now only a single pythontex_utils.py, which works with both
Python 2 and Python 3.
• Added the beta package option. This makes the current version behave like
v0.11beta, for compatibility. This option is temporary and will probably
only be retained for a few releases.

• Backward-incompatible changes (require the beta option to restore old be-


havior)
– The pyverb environment has been renamed pyverbatim. The old name
was intended to be concise, but promoted confusion with LaTeX’s \verb
macro.
– For \printpythontex, \stdoutpythontex, and \stderrpythontex,
the modes inlineverb and v have been replaced by verb, and the
old mode verb has been replaced by verbatim. This brings naming
conventions in line with standard LaTeX \verb and verbatim, avoid-
ing a source of potential confusion.
– The \setpythontexpyglexer, \setpythontexpygopt, and \setpygmentspygopt
commands now take an optional argument and a mandatory argument,
rather than two mandatory arguments. This creates better uniformity
among current and planned settings macros.

70
– The \setpythontexformatter and \setpygmentsformatter commands
have been replaced by the \setpythontexprettyprinter and \setpygmentsprettyprinter
commands. This anticipates possible upcoming features. It also avoids
potential confusion with Pygments’s formatters and the utilities class’s
formatter() method.

• Deprecated (still work, but raise warnings; after a few releases, they will
raise errors instead, and after that eventually be removed)
– The rerun setting all was renamed always, in preparation for upcom-
ing features.
– The stderr option is replaced by makestderr. The print/stdout
option is replaced by debug. These are intended to prevent confusion
with future features.
– The fixlr option is deprecated. It was originally introduced to deal
with some of SymPy’s LaTeX formatting, which has since changed.
– The utilities class method init_sympy_latex() is deprecated. The
sympy_latex() and set_sympy_latex() methods now automatically
initialize themselves on first use.
• Added autostdout package option and \setpythontexautostdout, to com-
plement autoprint. Added prettyprinter and prettyprintinline pack-
age options to complement new settings commands.

• Added quickstart guide.


• Installer now installs gallery and quickstart files, if present.

v0.11beta (2013/02/17)
• Commands like \py can now bring in any valid LaTeX code, including ver-
batim content, under the pdfTeX and XeTeX engines. Verbatim content was
not allowed previously. LuaTeX cannot bring in verbatim, due to a known
bug.
• Added package option depythontex and scripts depythontex*.py. These
allow a PythonTeX document to be converted into a pure LaTeX document,
with no Python dependency. The package option creates an auxiliary file
with extension .depytx. The depythontex*.py scripts take this auxiliary
file and the original LaTeX document, and combine the two to produce a new
document that does not rely on the PythonTeX package. All PythonTeX
commands and environments are replaced by their output. All Python-
generated content is substituted directly into the document. By default, all
typeset code is wrapped in \verb and verbatim, but depythontex*.py has
a --listing option that allows fancyvrb, listings, minted, or pythontex
to be used instead.

71
• The current PythonTeX version is now saved in the .pytxcode. If this does
not match the version of the PythonTeX scripts, a warning is issued. This
makes it easier to determine errors due to version mismatches.
• Fixed an incompatibility with the latest release of xstring (version 1.7,
2013/01/13).

• Fixed a bug in the console environment that could cause problems


when switching from Pygments highlighting to fancyvrb when using the
fvextfile option. Fixed a bug introduced in the v0.10beta series that pre-
vented the console environment from working with fancyvrb.

• Fixed a bug with PythonTeX verbatim commands and environments that


use Pygments. The verbatim commands and environments were incorrectly
treated as if they had the attributes of executed code in the v0.10beta series.
• Fixed a bug from the v0.10beta series that sometimes prevented imports
from __future__ from working when there were multiple sessions.

• Fixed a bug related to hashing dependencies’ mtime under Python 3.

v0.10beta2 (2013/01/23)
• Improved pythontex*.py’s handling of the name of the file being processed.
A warning is no longer raised if the name is given with an extension; ex-
tensions are now processed (stripped) automatically. The filename may now
contain a path to the file, so you need not run pythontex*.py from within
the document’s directory.
• Added command-line option --verbose for more verbose output. Currently,
this prints a list of all processes that are launched.

• Fixed a bug that could crash pythontex*.py when the package option
pygments=false.
• Added documentation about autoprint behavior in the preamble. Sum-
mary: code commands and environments are allowed in the preamble as of
v0.10beta. autoprint only applies to the body of the document, because
nothing can be typeset in the preamble. Content printed in the preamble
can be brought in by explicitly using \printpythontex, but this should be
used with great care.
• Revised \stdoutpythontex and \printpythontex so that they work in the
preamble. Again, this should be used with great care if at all.

• Revised treatment of any content that custom code attempts to print. Cus-
tom code is not allowed to print to the document (see documentation). If
custom code attempts to print, a warning is raised, and the printed content
is included in the pythontex*.py run summary.

72
• One-line entries in stderr, such as those produced by Python’s warnings.warn(),
were not previously parsed because they are of the form :<linenumber>:
rather than line <linenumber>. These are now parsed and synchronized
with the document. They are also correctly parsed for inclusion in the doc-
ument via \stderrpythontex.
• If the package option stderrfilename is changed, all sessions that produced
errors or warnings are now re-executed automatically, so that their stderr
content is properly updated with the new filename.

v0.10beta (2013/01/09)
• Backward-incompatible: Redid treatment of command-line options for
pythontex*.py, using Python’s argparse module. Run pythontex*.py
with option -h to see new command line options.
• Deprecated: \setpythontexcustomcode is deprecated in favor of the
\pythontexcustomc command and pythontexcustomcode environment.
These allow entry of pure code, unlike \setpythontexcustomcode. These
also allow custom code to be added to the beginning or end of a session, via
an optional argument. Improved treatment of errors and warnings associated
with custom code.
• The summary of errors and warnings now correctly differentiates errors and
warnings produced by user code, rather than treating all of them as errors.
By default, pythontex*.py now returns an exit code of 1 if there were errors.
• The PythonTeX utilities class now allows external file dependencies to
be specified via pytex.add_dependencies(), so that sessions are auto-
matically re-executed when external dependencies are modified (modifica-
tion is determined via either hash or mtime; this is governed by the new
hashdependencies option).
• The PythonTeX utilities class now allows created files to be specified via
pytex.add_created(), so that created files may be automatically cleaned
up (deleted) when the code that created them is modified (for example, name
change for a saved plot).
• Added the following package options.
– stdout (or print): Allows input of stdout to be disabled. Useful for
debugging.
– runall: Executes everything. Useful when code depends on external
data.
– rerun: Determines when code is re-executed. Code may be set to
always run (same as runall option), or only run when it is modified
or when it produces errors or warnings. By default, code is always
re-executed if there are errors or modifications, but not re-executed if
there are warnings.

73
– hashdependencies: Determines whether external dependencies (data,
external code files highlighted with Pygments, etc.) are checked for
modification via hashing or modification time. Modification time is
default for performance reasons.
• Added the following new command line options. The options that are equiv-
alent to package options are overridden by the package options when present.
– --error-exit-code: Determines whether an exit code of 1 is returned
if there were errors. On by default, but can be turned off since it is
undesirable when working with some editors.
– --runall: Equivalent to new package option.
– --rerun: Equivalent to new package option.
– --hashdependencies: Equivalent to new package option.
• Modified the fixlr option, so that it only patches commands if they have
not already been patched (avoids package conflicts).
• Added \setpythontexautoprint command for toggling autoprint on/off
within the body of the document.
• Installer now attempts to create symlinks under OS X and Linux with TeX
Live, and under OS X with MacPorts Tex Live.
• Performed compatibility testing under lualatex and xelatex (previously, had
only tested with pdflatex). Added documentation for using these TeX en-
gines; at most, slightly different preambles are needed. Modified the Python-
TeX gallery to support all three engines.
• Code commands and environments may now be used in the preamble. This,
combined with the new treatment of custom code, allows PythonTeX to be
used in creating LaTeX packages.
• Added documentation for using PythonTeX in LaTeX programming.
• Fixed a bug that sometimes caused incorrect line numbers with stderr
content. Improved processing of stderr.
• Fixed a bug in automatic detection of pre-existing listings environment.
• Improved the detection of imports from __future__. Detection should now
be stricter, faster, and more accurate.

v0.9beta3 (2012/07/17)
• Added Unicode support, which required the Python code to be split into
one set for Python 2 and another set for Python 3. This will require any old
installation to be completely removed, and a new installation created from
scratch.

74
• Refactoring of Python code. Documents should automatically re-execute all
code after updating to the new version. Otherwise, you should delete the
PythonTeX directory and run PythonTeX.
• Improved installation script.

• Added package options: pyfuture, stderr, upquote, pyglexer, pyginline. Re-


named the pygextfile option to fvextfile.
• Added custom code and workingdir commands.
• Added the console environment and associated options.

• Rewrote pythontex_utils*.py, creating a new, context-aware interface to


SymPy’s LatexPrinter class.
• Content brought in via macros no longer uses labels. Rather, long defs are
used, which allows line breaks.
• Pygments highlighting is now default for PythonTeX commands and envi-
ronments

v0.9beta2 (2012/05/09)
• Changed Python output extension to .stdout.

v0.9beta (2012/04/27)
• Initial public beta release.

10 Implementation
This section describes the technical implementation of the package. Unless you
wish to understand all the fine details or need to use the package in extremely
sophisticated ways, you should not need to read it.
The prefix pytx@ is used for all PythonTEX macros, to prevent conflict with
other packages. Macros that simply store text or a value for later retrieval are
given names completely in lower case. For example, \pytx@packagename stores the
name of the package, PythonTeX. Macros that actually perform some operation in
contrast to simple storage are named using CamelCase, with the first letter after
the prefix being capitalized. For example, \pytx@CheckCounter checks to see if a
counter exists, and if not, creates it. Thus, macros are divided into two categories
based on their function, and named accordingly.

75
10.1 Package opening
We store the name of the package in a macro for later use in warnings and error
messages.
1 \newcommand{\pytx@packagename}{PythonTeX}
2 \newcommand{\pytx@packageversion}{0.18}

10.2 Required packages


A number of packages are required. fvextra, which loads and extends fancyvrb,
is used to typeset all code that is not inline. fancyvrb internals are used to format
inline code. etoolbox is used for string comparison and boolean flags. xstring
provides string manipulation. pgfopts is used to process package options, via
the pgfkeys package. newfloat allows the creation of a floating environment for
code listings. currfile is needed to allow errors and warnings to be synchronized
with content brought in via \input, \include, etc. xcolor or color is needed
for syntax highlighting with Pygments.
3 \RequirePackage{fvextra}
4 \RequirePackage{etoolbox}
5 \RequirePackage{xstring}
6 \RequirePackage{pgfopts}
7 \RequirePackage{newfloat}
8 \@ifpackageloaded{currfile}{}{\RequirePackage{currfile}}
9 \AtEndPreamble{\@ifpackageloaded{color}{}{\RequirePackage{xcolor}}}

10.3 Package options


We now proceed to define package options, using the pgfopts package that pro-
vides a package-level interface to pgfkeys. All keys for package-level options are
placed in the key tree under the path /PYTX/pkgopt/, to prevent conflicts with
any other packages that may be using pgfkeys.

10.3.1 Enabling command and environment families


\pytx@families This option determines which command and environment families are defined
beyond py, pylab, and sympy. Additional families are not automatically defined
since some of them create commands or environment that may conflict with other
packages.36
10 \def\pytx@families{}
11 \pgfkeys{/PYTX/pkgopt/usefamily/.estore in=\pytx@families}

10.3.2 Gobble
\pytx@opt@gobble This option determines how leading whitespace in user code is treated.
12 \def\pytx@opt@gobble{none}
example, a \ruby command for Ruby code, and the \ruby command defined by the Ruby
36 For

package in the CJK package.

76
13 \pgfkeys{/PYTX/pkgopt/gobble/.is choice}
14 \pgfkeys{/PYTX/pkgopt/gobble/none/.code=\def\pytx@opt@gobble{none}}
15 \pgfkeys{/PYTX/pkgopt/gobble/auto/.code=\def\pytx@opt@gobble{auto}}

10.3.3 Beta
pytx@opt@beta This option provides compatibility with the beta releases from before the full v0.11
release. It should be removed after a few major releases.
16 \newbool{pytx@opt@beta}
17 \pgfkeys{/PYTX/pkgopt/beta/.default=true}
18 \pgfkeys{/PYTX/pkgopt/beta/.is choice}
19 \pgfkeys{/PYTX/pkgopt/beta/true/.code=\booltrue{pytx@opt@beta}}
20 \pgfkeys{/PYTX/pkgopt/beta/false/.code=\boolfalse{pytx@opt@beta}}

10.3.4 Runall
pytx@opt@rerun This option causes all code to be executed, regardless of whether it has been
modified. It is primarily useful for re-executing code that has not changed, when
the code depends on external files that have changed. Since it shares functionality
with the rerun option, both options share a single macro. Note that the macro
is initially set to default, rather than the default value of errors, so that the
Python side can distinguish whether a value was actually set by the user on the
TEX side, and thus any potential conflicts between command-line options and
package options can be resolved in favor of package options.
21 \def\pytx@opt@rerun{default}
22 \pgfkeys{/PYTX/pkgopt/runall/.default=true}
23 \pgfkeys{/PYTX/pkgopt/runall/.is choice}
24 \pgfkeys{/PYTX/pkgopt/runall/true/.code=\def\pytx@opt@rerun{always}}
25 \pgfkeys{/PYTX/pkgopt/runall/false/.code=\relax}

10.3.5 Rerun
This option determines the conditions under which code is rerun. It stores its
state in a macro shared with runall.
26 \pgfkeys{/PYTX/pkgopt/rerun/.is choice}
27 \pgfkeys{/PYTX/pkgopt/rerun/never/.code=\def\pytx@opt@rerun{never}}
28 \pgfkeys{/PYTX/pkgopt/rerun/modified/.code=\def\pytx@opt@rerun{modified}}
29 \pgfkeys{/PYTX/pkgopt/rerun/errors/.code=\def\pytx@opt@rerun{errors}}
30 \pgfkeys{/PYTX/pkgopt/rerun/warnings/.code=\def\pytx@opt@rerun{warnings}}
31 \pgfkeys{/PYTX/pkgopt/rerun/always/.code=\def\pytx@opt@rerun{always}}
32 \pgfkeys{/PYTX/pkgopt/rerun/all/.code=\def\pytx@opt@rerun{always}%
33 \PackageWarning{\pytx@packagename}{rerun=all is deprecated; use rerun=always}}

10.3.6 Hashdependencies
pytx@opt@hashdependencies This option determines whether dependencies (either code to be highlighted, or
dependencies such as data that have been specified within a session) are checked
for modification via modification time or via hashing.

77
34 \def\pytx@opt@hashdependencies{default}
35 \pgfkeys{/PYTX/pkgopt/hashdependencies/.is choice}
36 \pgfkeys{/PYTX/pkgopt/hashdependencies/.default=true}
37 \pgfkeys{/PYTX/pkgopt/hashdependencies/true/.code=\def\pytx@opt@hashdependencies{true}}
38 \pgfkeys{/PYTX/pkgopt/hashdependencies/false/.code=\def\pytx@opt@hashdependencies{false}}

10.3.7 Autoprint
pytx@opt@autoprint The autoprint option determines whether content printed within a code com-
mand or environment is automatically included at the location of the command or
environment. If the option is not used, autoprint is turned on by default. If the
option is used, but without a setting (\usepackage[autoprint]{pythontex}), it
is true by default. We use the key handler hkeyi/.is choice to ensure that only
true/false values are allowed. The code for the true branch is redundant, but is
included for symmetry.
39 \newbool{pytx@opt@autoprint}
40 \booltrue{pytx@opt@autoprint}
41 \pgfkeys{/PYTX/pkgopt/autoprint/.default=true}
42 \pgfkeys{/PYTX/pkgopt/autoprint/.is choice}
43 \pgfkeys{/PYTX/pkgopt/autoprint/true/.code=\booltrue{pytx@opt@autoprint}}
44 \pgfkeys{/PYTX/pkgopt/autoprint/false/.code=\boolfalse{pytx@opt@autoprint}}
45 \pgfkeys{/PYTX/pkgopt/autostdout/.default=true}
46 \pgfkeys{/PYTX/pkgopt/autostdout/.is choice}
47 \pgfkeys{/PYTX/pkgopt/autostdout/true/.code=\booltrue{pytx@opt@autoprint}}
48 \pgfkeys{/PYTX/pkgopt/autostdout/false/.code=\boolfalse{pytx@opt@autoprint}}

\setpythontexautoprint Sometimes it may be useful to switch autoprint on and off within different parts
\setpythontexautostdout of a document, rather than setting it to a single setting for the entire document.
So we provide a command for that purpose. Note that the command overrides the
package-level option.
49 \newcommand{\setpythontexautoprint}[1]{%
50 \Depythontex{cmd:setpythontexautoprint:m:n}%
51 \ifstrequal{#1}{true}{\booltrue{pytx@opt@autoprint}}{}%
52 \ifstrequal{#1}{false}{\boolfalse{pytx@opt@autoprint}}{}%
53 }
54 \newcommand{\setpythontexautostdout}[1]{%
55 \Depythontex{cmd:setpythontexautostdout:m:n}%
56 \ifstrequal{#1}{true}{\booltrue{pytx@opt@autoprint}}{}%
57 \ifstrequal{#1}{false}{\boolfalse{pytx@opt@autoprint}}{}%
58 }

10.3.8 Debug
pytx@opt@stdout This option determines whether printed content/content written to stdout is in-
cluded in the document. Disabling the inclusion of printed content is useful when
the printed content contains LATEX errors that would prevent successful compila-
tion.
59 \newbool{pytx@opt@stdout}

78
60 \booltrue{pytx@opt@stdout}
61 \pgfkeys{/PYTX/pkgopt/debug/.code=\boolfalse{pytx@opt@stdout}}
62 \pgfkeys{/PYTX/pkgopt/stdout/.default=true}
63 \pgfkeys{/PYTX/pkgopt/stdout/.is choice}
64 \pgfkeys{/PYTX/pkgopt/stdout/true/.code=\booltrue{pytx@opt@stdout}%
65 \PackageWarning{\pytx@packagename}{Option stdout is deprecated; use option debug}}
66 \pgfkeys{/PYTX/pkgopt/stdout/false/.code=\boolfalse{pytx@opt@stdout}%
67 \PackageWarning{\pytx@packagename}{Option stdout is deprecated; use option debug}}
68 \pgfkeys{/PYTX/pkgopt/print/.default=true}
69 \pgfkeys{/PYTX/pkgopt/print/.is choice}
70 \pgfkeys{/PYTX/pkgopt/print/true/.code=\booltrue{pytx@opt@stdout}%
71 \PackageWarning{\pytx@packagename}{Option print is deprecated; use option debug}}
72 \pgfkeys{/PYTX/pkgopt/print/false/.code=\boolfalse{pytx@opt@stdout}%
73 \PackageWarning{\pytx@packagename}{Option print is deprecated; use option debug}}
74 \AtBeginDocument{%
75 \ifbool{pytx@opt@stdout}{}{%
76 \PackageWarning{\pytx@packagename}{Using package option debug}%
77 }%
78 }

10.3.9 makestderr
pytx@opt@stderr The makestderr option determines whether stderr is saved and may be included
in the document via \stderrpythontex.
79 \newbool{pytx@opt@stderr}
80 \pgfkeys{/PYTX/pkgopt/makestderr/.default=true}
81 \pgfkeys{/PYTX/pkgopt/makestderr/.is choice}
82 \pgfkeys{/PYTX/pkgopt/makestderr/true/.code=\booltrue{pytx@opt@stderr}}
83 \pgfkeys{/PYTX/pkgopt/makestderr/false/.code=\boolfalse{pytx@opt@stderr}}
84 \pgfkeys{/PYTX/pkgopt/stderr/.default=true}
85 \pgfkeys{/PYTX/pkgopt/stderr/.is choice}
86 \pgfkeys{/PYTX/pkgopt/stderr/true/.code=\booltrue{pytx@opt@stderr}%
87 \PackageWarning{\pytx@packagename}{Option stderr is deprecated; use option makestderr}}
88 \pgfkeys{/PYTX/pkgopt/stderr/false/.code=\boolfalse{pytx@opt@stderr}%
89 \PackageWarning{\pytx@packagename}{Option stderr is deprecated; use option makestderr}}

10.3.10 stderrfilename
\pytx@opt@stderrfilename This option determines how the file name appears in stderr.
90 \def\pytx@opt@stderrfilename{full}
91 \pgfkeys{/PYTX/pkgopt/stderrfilename/.default=full}
92 \pgfkeys{/PYTX/pkgopt/stderrfilename/.is choice}
93 \pgfkeys{/PYTX/pkgopt/stderrfilename/full/.code=\def\pytx@opt@stderrfilename{full}}
94 \pgfkeys{/PYTX/pkgopt/stderrfilename/session/.code=\def\pytx@opt@stderrfilename{session}}
95 \pgfkeys{/PYTX/pkgopt/stderrfilename/genericfile/.code=%
96 \def\pytx@opt@stderrfilename{genericfile}}
97 \pgfkeys{/PYTX/pkgopt/stderrfilename/genericscript/.code=%
98 \def\pytx@opt@stderrfilename{genericscript}}

79
10.3.11 Python’s __future__ module
\pytx@opt@pyfuture The pyfuture option determines what is imported from the __future__ module
under Python 2. It has no effect under Python 3.
99 \def\pytx@opt@pyfuture{default}
100 \pgfkeys{/PYTX/pkgopt/pyfuture/.is choice}
101 \pgfkeys{/PYTX/pkgopt/pyfuture/default/.code=\def\pytx@opt@pyfuture{default}}
102 \pgfkeys{/PYTX/pkgopt/pyfuture/all/.code=\def\pytx@opt@pyfuture{all}}
103 \pgfkeys{/PYTX/pkgopt/pyfuture/none/.code=\def\pytx@opt@pyfuture{none}}

\pytx@opt@pyconfuture The pyconfuture option determines what is automatically imported from the
__future__ module under Python 2, for console content. It has no effect under
Python 3.
104 \def\pytx@opt@pyconfuture{none}
105 \pgfkeys{/PYTX/pkgopt/pyconfuture/.is choice}
106 \pgfkeys{/PYTX/pkgopt/pyconfuture/default/.code=\def\pytx@opt@pyconfuture{default}}
107 \pgfkeys{/PYTX/pkgopt/pyconfuture/all/.code=\def\pytx@opt@pyconfuture{all}}
108 \pgfkeys{/PYTX/pkgopt/pyconfuture/none/.code=\def\pytx@opt@pyconfuture{none}}

10.3.12 Upquote
pytx@opt@upquote The upquote option determines whether the upquote package is loaded. It makes
quotes within verbatim contexts ' rather than '. This is important, because it
means that code may be copied directly from the compiled PDF and executed
without any errors due to quotes ' being copied as acute accents ´.
109 \newbool{pytx@opt@upquote}
110 \booltrue{pytx@opt@upquote}
111 \pgfkeys{/PYTX/pkgopt/upquote/.default=true}
112 \pgfkeys{/PYTX/pkgopt/upquote/.is choice}
113 \pgfkeys{/PYTX/pkgopt/upquote/true/.code=\booltrue{pytx@opt@upquote}}
114 \pgfkeys{/PYTX/pkgopt/upquote/false/.code=\boolfalse{pytx@opt@upquote}}

10.3.13 Fix math spacing


pytx@opt@fixlr The fixlr option fixes extra, undesirable spacing in mathematical formulae in-
troduced by the commands \left and \right. For example, compare the results
of $\sin(x)$ and $\sin\left(x\right)$: sin(x) and sin (x). The fixlr option
fixes this, using a solution proposed by Mateus Araújo, Philipp Stephani, and
Heiko Oberdiek.37
115 \newbool{pytx@opt@fixlr}
116 \pgfkeys{/PYTX/pkgopt/fixlr/.default=true}
117 \pgfkeys{/PYTX/pkgopt/fixlr/.is choice}
118 \pgfkeys{/PYTX/pkgopt/fixlr/true/.code=\booltrue{pytx@opt@fixlr}}
119 \pgfkeys{/PYTX/pkgopt/fixlr/false/.code=\boolfalse{pytx@opt@fixlr}}
37 http://tex.stackexchange.com/questions/2607/spacing-around-left-and-right

80
10.3.14 Keep temporary files
\pytx@opt@keeptemps By default, PythonTEX tries to be very tidy. It creates many temporary files, but
deletes all that are not required to compile the document, keeping the overall file
count very low. At times, particularly during debugging, it may be useful to keep
these temporary files, so that code, errors, and output may be examined more
directly. The keeptemps option makes this possible.
120 \def\pytx@opt@keeptemps{none}
121 \pgfkeys{/PYTX/pkgopt/keeptemps/.default=all}
122 \pgfkeys{/PYTX/pkgopt/keeptemps/.is choice}
123 \pgfkeys{/PYTX/pkgopt/keeptemps/all/.code=\def\pytx@opt@keeptemps{all}}
124 \pgfkeys{/PYTX/pkgopt/keeptemps/code/.code=\def\pytx@opt@keeptemps{code}}
125 \pgfkeys{/PYTX/pkgopt/keeptemps/none/.code=\def\pytx@opt@keeptemps{none}}

10.3.15 Pygments
pytx@opt@pygments By default, PythonTEX uses fancyvrb to typeset code. This provides nice format-
ting and font options, but no syntax highlighting. The prettyprinter options,
and pygments alias, determine whether Pygments or fancyvrb is used to type-
set code. Pygments is a generic syntax highlighter written in Python. Since
PythonTEX sends code to Python anyway, having Pygments process the code is
only a small additional step and in many cases takes little if any extra time to
execute.38
Command and environment families obey the prettyprinter option by de-
fault, but they may be set to override it and always use Pygments or always use
fancyvrb, via \setpythontexprettyprinter and \setpygmentsprettyprinter.
126 \newbool{pytx@opt@pygments}
127 \booltrue{pytx@opt@pygments}
128 \pgfkeys{/PYTX/pkgopt/prettyprinter/.is choice}
129 \pgfkeys{/PYTX/pkgopt/prettyprinter/pygments/.code=\booltrue{pytx@opt@pygments}}
130 \pgfkeys{/PYTX/pkgopt/prettyprinter/fancyvrb/.code=\boolfalse{pytx@opt@pygments}}
131 \pgfkeys{/PYTX/pkgopt/pygments/.default=true}
132 \pgfkeys{/PYTX/pkgopt/pygments/.is choice}
133 \pgfkeys{/PYTX/pkgopt/pygments/true/.code=\booltrue{pytx@opt@pygments}}
134 \pgfkeys{/PYTX/pkgopt/pygments/false/.code=\boolfalse{pytx@opt@pygments}}

pytx@opt@pyginline This option governs whether, when Pygments is in use, it highlights inline content.
135 \newbool{pytx@opt@pyginline}
136 \booltrue{pytx@opt@pyginline}
137 \pgfkeys{/PYTX/pkgopt/prettyprintinline/.default=true}
138 \pgfkeys{/PYTX/pkgopt/prettyprintinline/.is choice}
139 \pgfkeys{/PYTX/pkgopt/prettyprintinline/true/.code=\booltrue{pytx@opt@pyginline}}
140 \pgfkeys{/PYTX/pkgopt/prettyprintinline/false/.code=\boolfalse{pytx@opt@pyginline}}
141 \pgfkeys{/PYTX/pkgopt/pyginline/.default=true}
142 \pgfkeys{/PYTX/pkgopt/pyginline/.is choice}
38 Pygments code highlighting is executed as a separate process by pythontex.py, so it runs

in parallel on a multicore system. Pygments usage is optimized by saving highlighted code and
only reprocessing it when changed.

81
143 \pgfkeys{/PYTX/pkgopt/pyginline/true/.code=\booltrue{pytx@opt@pyginline}}
144 \pgfkeys{/PYTX/pkgopt/pyginline/false/.code=\boolfalse{pytx@opt@pyginline}}

pytx@pyglexer For completeness, we need a way to set the Pygments lexer for all content. Note
that in general, resetting the lexers for all content is not desirable.
145 \def\pytx@pyglexer{}
146 \pgfkeys{/PYTX/pkgopt/pyglexer/.code=\def\pytx@pyglexer{#1}}

\pytx@pygopt We also need a way to specify Pygments options at the package level. This is
accomplished via the pygopt option: pygopt={hoptionsi}. Note that the options
must be enclosed in curly braces since they contain equals signs and thus must be
distinguishable from package options.
Currently, three options may be passed in this manner: style=hstylei, which
sets the formatting style; texcomments, which allows LATEX in code comments to
be rendered; and mathescape, which allows LATEX math mode ($...$) in com-
ments. The texcomments and mathescape options may be used with a boolean
argument; if an argument is not supplied, true is assumed. As an example of
pygopt usage, consider the following:
pygopt={style=colorful, texcomments=true, mathescape=false}

While the package-level pygments option may be overridden by individual com-


mands and environments (though it is not by default), the package-level Pygments
options cannot be overridden by individual commands and environments. While
we’re defining storage for pygopt, go ahead and define parsing to extract style
for later use under all cicumstances. This should be reorganized during the next
refactoring.
147 \def\pytx@pygopt{}
148 \pgfkeys{/PYTX/pkgopt/pygopt/.code=\def\pytx@pygopt{#1}\pgfkeys{/PYTX/gopt/pygopt/.cd, #1}}
149 \pgfkeys{/PYTX/gopt/pygopt/.is choice}
150 \pgfkeys{/PYTX/gopt/pygopt/texcomments/.code=\relax}
151 \pgfkeys{/PYTX/gopt/pygopt/mathescape/.code=\relax}
152 \pgfkeys{/PYTX/gopt/pygopt/style/.code=\ifstrempty{#1}{}{\def\pytx@style{#1}}}
153 \pgfkeys{/PYTX/lopt/pygopt/.is choice}
154 \pgfkeys{/PYTX/lopt/pygopt/name/.code=\def\pytx@tmp@name{#1}}
155 \pgfkeys{/PYTX/lopt/pygopt/texcomments/.code=\relax}
156 \pgfkeys{/PYTX/lopt/pygopt/mathescape/.code=\relax}
157 \pgfkeys{/PYTX/lopt/pygopt/style/.code=\ifstrempty{#1}{}{%
158 \expandafter\def\csname pytx@style@\pytx@tmp@name\endcsname{#1}}}
159 \pgfkeys{/PYTX/popt/pygopt/.is choice}
160 \pgfkeys{/PYTX/popt/pygopt/name/.code=\def\pytx@tmp@name{#1}}
161 \pgfkeys{/PYTX/popt/pygopt/texcomments/.code=\relax}
162 \pgfkeys{/PYTX/popt/pygopt/mathescape/.code=\relax}
163 \pgfkeys{/PYTX/popt/pygopt/style/.code=\ifstrempty{#1}{}{%
164 \expandafter\def\csname pytx@style@PYG\pytx@tmp@name\endcsname{#1}}}

\pytx@fvextfile By default, code highlighted by Pygments, the console environment, and some
other content is brought back via fancyvrb’s SaveVerbatim macro, which saves

82
verbatim content into a macro and then allows it to be restored. This makes it
possible for all Pygments content to be brought back in a single file, keeping the
total file count low (which is a major priority for PythonTEX!). This approach does
have a disadvantage, though, because SaveVerbatim slows down as the length of
saved code increases.39 To deal with this issue, we create the fvextfile option.
This option takes an integer, fvextfile=hintegeri. All content that is more than
hintegeri lines long will be saved to its own external file and inputted from there,
rather than saved and restored via SaveVerbatim and UseVerbatim. This provides
a workaround should speed ever become a hindrance for large blocks of code.
A default value of 25 is set. There is nothing special about 25; it is just a
relatively reasonably cutoff. If the option is unused, it has a value of −1, which is
converted to the maximum integer on the Python side.
165 \def\pytx@fvextfile{-1}
166 \pgfkeys{/PYTX/pkgopt/fvextfile/.default=25}
167 \pgfkeys{/PYTX/pkgopt/fvextfile/.code=\IfInteger{#1}{%
168 \ifnum#1>0\relax
169 \def\pytx@fvextfile{#1}%
170 \else
171 \PackageError{\pytx@packagename}{option fvextfile must be an integer > 0}{}%
172 \fi}%
173 {\PackageError{\pytx@packagename}{option fvextfile must be an integer > 0}{}}%
174 }

10.3.16 Python console environment


\pytx@opt@pyconbanner This option governs the appearance (or disappearance) of a banner at the begin-
ning of Python console environments. The options none (no banner), standard
(standard Python banner), default (default banner for Python’s code module,
standard banner plus interactive console class name), and pyversion (banner in
the form Python x.y.z) are accepted.
175 \def\pytx@opt@pyconbanner{none}
176 \pgfkeys{/PYTX/pkgopt/pyconbanner/.is choice}
177 \pgfkeys{/PYTX/pkgopt/pyconbanner/none/.code=\def\pytx@opt@pyconbanner{none}}
178 \pgfkeys{/PYTX/pkgopt/pyconbanner/standard/.code=\def\pytx@opt@pyconbanner{standard}}
179 \pgfkeys{/PYTX/pkgopt/pyconbanner/default/.code=\def\pytx@opt@pyconbanner{default}}
180 \pgfkeys{/PYTX/pkgopt/pyconbanner/pyversion/.code=\def\pytx@opt@pyconbanner{pyversion}}

\pytx@opt@pyconfilename This option governs the file name that appears in error messages in the console.
The file name may be either stdin, as it is in a standard interactive interpreter,
or console, as it would typically be for the Python code module.
Traceback (most recent call last):
File "<file name>", line <line no>, in <module>

39 The macro in which code is saved is created by grabbing the code one line at a time, and

for each line redefining the macro to be its old value with the additional line tacked on. This is
rather inefficient, but apparently there isn’t a good alternative.

83
181 \def\pytx@opt@pyconfilename{stdin}
182 \pgfkeys{/PYTX/pkgopt/pyconfilename/.is choice}
183 \pgfkeys{/PYTX/pkgopt/pyconfilename/stdin/.code=\def\pytx@opt@pyconfilename{stdin}}
184 \pgfkeys{/PYTX/pkgopt/pyconfilename/console/.code=\def\pytx@opt@pyconfilename{console}}

10.3.17 depythontex
pytx@opt@depythontex This option governs whether PythonTEX saved data that can be used to create a
version of the .tex file that does not require PythonTEX to be compiled. This op-
tion should be useful for converting a PythonTEX document into a more standard
TEX document when sharing or publishing documents.
While we’re at it, we go ahead and define dummy versions of the depythontex
macros, so that they can be used in defining commands that are used within the
package, not just outside of it.
185 \newbool{pytx@opt@depythontex}
186 \pgfkeys{/PYTX/pkgopt/depythontex/.default=true}
187 \pgfkeys{/PYTX/pkgopt/depythontex/.is choice}
188 \pgfkeys{/PYTX/pkgopt/depythontex/true/.code=\booltrue{pytx@opt@depythontex}}
189 \pgfkeys{/PYTX/pkgopt/depythontex/false/.code=\boolfalse{pytx@opt@depythontex}}
190 \let\Depythontex\@gobble
191 \let\DepyFile\@gobble
192 \let\DepyMacro\@gobble
193 \let\DepyListing\@empty

10.3.18 Process options


Now we process the package options.
194 \ProcessPgfPackageOptions{/PYTX/pkgopt}
The fixlr option only affects one thing, so we go ahead and take care of that.
Notice that before we patch \left and \right, we make sure that they have not
already been patched by checking how \left is expanded. This is important if
the user has manually patched these commands, is using the mleftright package,
or accidentally loads PythonTEX twice.
195 \ifbool{pytx@opt@fixlr}{
196 \IfStrEq{\detokenize\expandafter{\left}}{\detokenize{\left}}{
197 \let\originalleft\left
198 \let\originalright\right
199 \renewcommand{\left}{\mathopen{}\mathclose\bgroup\originalleft}
200 \renewcommand{\right}{\aftergroup\egroup\originalright}
201 }{}
202 }{}
Likewise, the upquote option.
203 \ifbool{pytx@opt@upquote}{\RequirePackage{upquote}}{}
If the depythontex option is used, we also need to disable Pygments highlight-
ing. This is necessary because some content, such as console environments, is
needed in a non-highlighted form, so that it will not contain any special macros.
204 \ifbool{pytx@opt@depythontex}{\boolfalse{pytx@opt@pygments}}{}

84
10.4 Utility macros and input/output setup
Once options are processed, we proceed to define a number of utility macros
and setup the file input/output that is required by PythonTEX. We also create
macros and perform setup needed by depythontex, since these are closely related
to input/output.

10.4.1 Automatic counter creation


\pytx@CheckCounter We will be using counters to give each command/environment a unique identifier,
as well as to manage line numbering of code when desired. We don’t know the
names of the counters ahead of time (this is actually determined by the user’s
naming of code sessions), so we need a macro that checks whether a counter
exists, and if not, creates it.
205 \def\pytx@CheckCounter#1{%
206 \ifcsname c@#1\endcsname\else\newcounter{#1}\fi
207 }

10.4.2 Saving verbatim content in macros


\pytx@SVMCR Commands like \py bring in string representations of objects. Printed content is
saved to external files, but commands like \py bring in content by saving it in
macros. A single large file of macro definitions is brought in, rather than many
external files.
This prevents the creation of unnecessary files, but it also has a significant
drawback: only some content can be saved in a standard macro. In particular,
verbatim content using \verb and verbatim will not work. So we need a way
to save anything in a macro. The solution is to create a special macro that
captures its argument verbatim. The argument is then tokenized when it is used
via \scantokens. All of this requires a certain amount of catcode trickery.
208 \def\pytx@SVMCR#1{%
209 \edef\pytx@tmp{\csname #1\endcsname}%
210 \begingroup
211 \endlinechar`\^^J
212 \let\do\@makeother\dospecials
213 \pytx@SVMCR@i}
214 \begingroup
215 \catcode`!=0
216 !catcode`!\=12
217 !long!gdef!pytx@SVMCR@i#1\endpytx@SVMCR^^J{%
218 !endgroup
219 !expandafter!gdef!pytx@tmp{%
220 !expandafter!scantokens!expandafter{#1!empty}}%
221 }%
222 !endgroup

pytx@Verbatim We need custom versions of fancyvrb’s Verbatim and SaveVerbatim environ-


pytx@SaveVerbatim ments, because we don’t want to have to worry about the possibility of these

85
environments containing literal Verbatim and SaveVerbatim environments.
223 \DefineVerbatimEnvironment{pytx@Verbatim}{Verbatim}{}
224 \DefineVerbatimEnvironment{pytx@SaveVerbatim}{SaveVerbatim}{}

10.4.3 Code context


\pytx@context It would be nice if when our code is executed, we could know something about its
\pytx@SetContext context, such as the style of its surroundings or information about page size.
\setpythontexcontext By default, no contextual information is passed to LATEX. There is a wide
variety of information that could be passed, but most use cases would only need a
very specific subset. Instead, the user can customize what information is passed to
LATEX. The \setpythontexcontext macro defines what is passed. It creates the
\pytx@SetContext macro, which creates \pytx@context, in which the expanded
context information is stored. The context should only be defined in the preamble,
so that it is consistent throughout the document.
If you are interested in typesetting mathematics based on math styles, you
should use the \mathchoice macro rather than attempting to pass contextual
information.
225 \newcommand{\setpythontexcontext}[1]{%
226 \Depythontex{cmd:setpythontexcontext:m:n}%
227 \def\pytx@SetContext{%
228 \edef\pytx@context{#1}%
229 }%
230 }
231 \setpythontexcontext{}
232 \@onlypreamble\setpythontexcontext

10.4.4 Code groups


By default, PythonTEX executes code based on sessions. All of the code entered
within a command and environment family is divided based on sessions, and each
session is saved to a single external file and executed. If you have a calculation
that will take a while, you can simply give it its own named session, and then the
code will only be executed when there is a change within that session.
While this approach is appropriate for many scenarios, it is sometimes ineffi-
cient. For example, suppose you are writing a document with multiple chapters,
and each chapter needs its own session. You could manually do this, but that would
involve a lot of commands like \py[chapter x]{hsome codei}, which means lots
of extra typing and extra session names. So we need a way to subdivide or restart
sessions, based on context such as chapter, section, or subsection.
“Groups” provide a solution to this problem. Each session is subdivided based
on groups behind the scenes. By default, this changes nothing, because each
session is put into a single default group. But the user can redefine groups based on
chapter, section, and other counters, so that sessions are automatically subdivided
accordingly. Note that there is no continuity between sessions thus subdivided. For
example, if you set groups to change between chapters, there will be no continuity
between the code of those chapters, even if all the code is within the same named

86
session. If you require continuity, the groups approach is probably not appropriate.
You could consider saving results at the end of one chapter and loading them at
the beginning of the next, but that introduces additional issues in keeping all code
properly synchronized, since code is executed only when it changes, not when any
data it loads may have changed.

\restartpythontexsessionWe begin by creating the \restartpythontexsession macro. It creates the


\pytx@group\pytx@SetGroup* macros, which create \pytx@group, in which the expanded
\pytx@SetGroupcontext information is stored. The context should only be defined in the
\pytx@SetGroupVerbpreamble, so that it is consistent throughout the document. Note that groups
\pytx@SetGroupCons should be defined so that they will only contain characters that are valid in
file names, because groups are used in naming temporary files. It is also a
good idea to avoid using periods, since LATEX input of file names containing
multiple periods can sometimes be tricky. For best results, use A-Z, a-z, 0-9,
and the hyphen and underscore characters to define groups. If groups contain
numbers from multiple sources (for example, chapter and section), the num-
bers should be separated by a non-numeric character to prevent unexpected
collisions (for example, distinguishing chapter 1-11 from 11-1). For example,
\restartpythontexsession{\arabic{chapter}-\arabic{section}} could be
a good approach.
Three forms of \pytx@SetGroup* are provided. \pytx@SetGroup is for general
code use. \pytx@SetGroupVerb is for use in verbatim contexts. It splits verbatim
content off into its own group. That way, verbatim content does not affect the in-
stance numbers of code that is actually executed. This prevents code from needing
to be run every time verbatim content is added or removed; code is only executed
when it is actually changed. pytx@SetGroupCons is for console environments. It
separate console content from executed code and from verbatim content, again for
efficiency reasons.
233 \newcommand{\restartpythontexsession}[1]{%
234 \Depythontex{cmd:restartpythontexsession:m:n}%
235 \def\pytx@SetGroup{%
236 \edef\pytx@group{#1}%
237 }%
238 \def\pytx@SetGroupVerb{%
239 \edef\pytx@group{#1verb}%
240 }%
241 \def\pytx@SetGroupCons{%
242 \edef\pytx@group{#1cons}%
243 }%
244 \AtBeginDocument{%
245 \pytx@SetGroup
246 \IfSubStr{\pytx@group}{verb}{%
247 \PackageError{\pytx@packagename}%
248 {String "verb" is not allowed in \string\restartpythontexsession}%
249 {Use \string\restartpythontexsession with a valid argument}}{}%
250 \IfSubStr{\pytx@group}{cons}{%
251 \PackageError{\pytx@packagename}%

87
252 {String "cons" is not allowed in \string\restartpythontexsession}%
253 {Use \string\restartpythontexsession with a valid argument}}{}%
254 }%
255 }

For the sake of consistency, we only allow group behaviour to be set in the
preamble. And if the group is not set by the user, then we use a single default
group for each session.
256 \@onlypreamble\restartpythontexsession
257 \restartpythontexsession{default}

10.4.5 File input and output


\pytx@jobname We will need to create directories and files for PythonTEX output, and some of
these will need to be named using \jobname. This presents a problem. Ideally,
the user will choose a job name that does not contain spaces. But if the job
name does contain spaces, then we may have problems bringing in content from a
directory or file that is named based on the job, due to the space characters. So
we need a “sanitized” version of \jobname. We replace spaces with hyphens. We
replace double quotes " with nothing. Double quotes are placed around job names
containing spaces by TEX Live, and thus may be the first and last characters of
\jobname. Since we are replacing any spaces with hyphens, quote delimiting is
no longer needed, and in any case, some operating systems (Windows) balk at
creating directories or files with names containing double quotes. We also replace
asterisks with hyphens, since MiKTEX (at least v. 2.9) apparently replaces spaces
with asterisks in \jobname,40 and some operating systems may not be happy with
names containing asterisks.
This approach to “sanitizing” \jobname is not foolproof. If there are ever two
files in a directory that both use PythonTEX, and if their names only differ by these
substitutions for spaces, quotes, and asterisks, then the output of the two files will
collide. We believe that it is better to graciously handle the possibility of space
characters at the expense of nearly identical file names, since nearly identical file
names are arguably a much worse practice than file names containing spaces, and
since such nearly identical file names should be much rarer. At the same time, in
rare cases a collision might occur, and in even rarer cases it might go unnoticed.41
To prevent such issues, pythontex.py checks for collisions and issues a warning if
a potential collision is detected.
258 \StrSubstitute{\jobname}{ }{-}[\pytx@jobname]
259 \StrSubstitute{\pytx@jobname}{"}{}[\pytx@jobname]
260 \StrSubstitute{\pytx@jobname}{*}{-}[\pytx@jobname]
40 http://tex.stackexchange.com/questions/14949/why-does-jobname-give-s-instead-of-spaces-

and-how-do-i-fix-this
41 In general, a collision would produce errors, and the user would thereby become aware of

the collision. The dangerous case is when the two files with similar names use exactly the same
PythonTEX commands, the same number of times, so that the naming of the output is identical.
In that case, no errors would be issued.

88
\pytx@outputdir To keep things tidy, all PythonTEX files are stored in a directory that is
\setpythontexoutputdir created in the document root directory. By default, this directory is called
pythontex-files-hsanitized jobnamei, but we want to provide the user with the
option to customize this. For example, when hsanitized jobnamei is very long, it
might be convenient to use pythontex-habbreviated namei.
The command \setpythontexoutputdir stores the name of PythonTEX’s out-
put directory in \pytx@outputdir. The command \setpythontexoutputdir is
only allowed in the preamble, because the location of PythonTEX content should
be specified before the body of the document is typeset.
261 \def\pytx@outputdir{pythontex-files-\pytx@jobname}
262 \newcommand{\setpythontexoutputdir}[1]{%
263 \Depythontex{cmd:setpythontexoutputdir:m:n}%
264 \def\pytx@outputdir{#1}}
265 \@onlypreamble\setpythontexoutputdir

pytx@workingdir We need to be able to set the current working directory for the scripts executed
\setpythontexworkingdir by PythonTEX. By default, the working directory should be the same as the
document root directory. But in some cases the user may wish to specify a different
working directory. We want to be able to use “<outputdir>” as a shortcut for
setting the working directory to the output directory.
If the graphicx package is loaded, and the output directory is being used as the
working directory, then the output directory is added to the graphics path at the
beginning of the document, so that files in the output directory may be included
within the main document without the necessity of specifying path information.
266 \def\pytx@workingdir{.}
267 \def\pytx@workingdirset{false}
268 \newcommand{\setpythontexworkingdir}[1]{%
269 \Depythontex{cmd:setpythontexworkingdir:m:n}%
270 \def\pytx@workingdir{#1}%
271 \def\pytx@workingdirset{true}%
272 }
273 \@onlypreamble\setpythontexworkingdir
274 \AtBeginDocument{%
275 \ifdefstring{\pytx@workingdir}{<outputdir>}%
276 {\let\pytx@workingdir\pytx@outputdir}{}%
277 \ifdefstrequal{\pytx@workingdir}{\pytx@outputdir}{%
278 \@ifpackageloaded{graphicx}{%
279 \ifx\Ginput@path\@undefined
280 \graphicspath{{\pytx@outputdir/}}%
281 \else
282 \g@addto@macro\Ginput@path{{\pytx@outputdir/}}%
283 \fi
284 }{}%
285 }{}%
286 }

pytx@usedpygments Once we have specified the output directory, we are free to pull in content from
it. Most content from the output directory will be pulled in manually by the user

89
(for example, via \includegraphics) or automatically by PythonTEX as it goes
along. But content “printed” by code commands and environments (via macros)
as well as code typeset by Pygments needs to be included conditionally, based on
whether it exists and on user preferences.
This gets a little tricky. We only want to pull in the Pygments content if it
is actually used, since Pygments content will typically use fancyvrb’s SaveVerb
environment, and this can slow down compilation when very large chunks of code
are saved. It doesn’t matter if the code is actually used; saving it in a macro is
what potentially slows things down. So we create a bool to keep track of whether
Pygments is ever actually used, and only bring in Pygments content if it is.42
This bool must be set to true whenever a command or environment is created
that makes use of Pygments (in practice, we will simply set it to true when a
family is created). Note that we cannot use the pytx@opt@pygments bool for this
purpose, because it only tells us if the package option for Pygments usage is true
or false. Typically, this will determine if any Pygments content is used. But it is
possible for the user to create a command and environment family that overrides
the package option (indeed, this may sometimes be desirable, for example, if the
user wishes code in a particular language never to be highlighted). Thus, a new
bool is needed to allow detection in such nonstandard cases.
287 \newbool{pytx@usedpygments}

Now we can conditionally bring in the Pygments content. Note that we must
use the etoolbox macro \AfterEndPreamble. This is because commands and
environments are created using \AtBeginDocument, so that the user can change
their properties in the preamble before they are created. And since the com-
mands and environments must be created before we know the final state of
pytx@usedpygments, we must bring in Pygments content after that. We typi-
cally need to patch the Pygments single quote macro so that it cooperates with
upquote.
288 \AfterEndPreamble{%
289 \ifbool{pytx@usedpygments}%
290 {\InputIfFileExists{\pytx@outputdir/\pytx@jobname.pytxpyg}{}{}%
291 \ifcsname PYGZsq\endcsname
292 \ifdefstring{\PYGZsq}{\char`\'}{\pytx@patch@PYGZsq}{}%
293 \fi}%
294 {}%
295 }
296 \begingroup
297 \catcode`\'=\active
42 The same effect could be achieved by having pythontex.py delete the Pygments content

whenever it is run and Pygments is not used. But that approach is faulty in two regards. First,
it requires that pythontex.py be run, which is not necessarily the case if the user simply sets the
package option pygments to false and the recompiles. Second, even if it could be guaranteed
that the content would be deleted, such an approach would not be optimal. It is quite possible
that the user wishes to temporarily turn off Pygments usage to speed compilation while working
on other parts of the document. In this case, deleting the Pygments content is simply deleting
data that must be recreated when Pygments is turned back on.

90
298 \gdef\pytx@patch@PYGZsq{\gdef\PYGZsq{'}}
299 \endgroup
While we are pulling in content, we also pull in the file of macros that stores
some inline “printed” content, if the file exists. Since we need this file in general,
and since it will not typically invole a noticeable speed penalty, we bring it in at
the beginning of the document without any special conditions.
300 \AtBeginDocument{%
301 \makeatletter
302 \InputIfFileExists{\pytx@outputdir/\pytx@jobname.pytxmcr}{}%
303 {\ifstrempty{\pytx@outputdir}%
304 {\typeout{No file \pytx@jobname.pytxmcr.}}%
305 {}%
306 \IfStrEq{\pytx@outputdir}{.}%
307 {\typeout{No file \pytx@jobname.pytxmcr.}}%
308 {\typeout{No file \pytx@outputdir/\pytx@jobname.pytxmcr.}}%
309 \typeout{Run \pytx@packagename\space to create it.}}%
310 \makeatother
311 }

\pytx@codefile We create a new write, named \pytx@codefile, to which we will save code. All
the code from the document will be written to this single file, interspersed with
information specifying where in the document it came from. PythonTEX parses
this file to separate the code into individual sessions and groups. These are then
executed, and the identifying information is used to tie code output back to the
original code in the document.43
312 \newwrite\pytx@codefile
313 \immediate\openout\pytx@codefile=\jobname.pytxcode

In the code file, information from PythonTEX must be interspersed with


the code. Some type of delimiting is needed for PythonTEX information. All
PythonTEX content is written to the file in the form =>PYTHONTEX#hcontenti#.
When this content involves package options, the delimiter is modified to the form
=>PYTHONTEX:SETTINGS#hcontenti#. The # symbol is also used as a subdelim-
iter within hcontenti. The # symbol is convenient as a delimiter since it has a
special meaning in TEX and is very unlikely to be accidentally entered by the
user in unexpected locations without producing errors. Note that the usage of
“=>PYTHONTEX#” as a beginning delimiter for PythonTEX data means that this
43 The choice to write all code to a single file is the result of two factors. First, T X has a limited
E
number of output registers available (16), so having a separate output stream for each group or
session is not possible. The morewrites package from Bruno Le Floch potentially removes this
obstacle, but since this package is very recent (README from 2011/7/10), we will not consider
using additional writes in the immediate future. Second, one of the design goals of PythonTEX
is to minimize the number of persistent files created by a run. This keeps directories cleaner
and makes file synchronization/transfer somewhat simpler. Using one write per session or group
could result in numerous code files, and these could only be cleaned up by pythontex.py since
LATEX cannot delete files itself (well, without unrestricted write18). Using a single output file
for code does introduce a speed penalty since the code does not come pre-sorted by session or
group, but in typical usage this should be minimal. Adding an option for single or multiple code
files may be something to reconsider at a later date.

91
string should never be written by the user at the beginning of a line, because
pythontex.py will try to intepret it as data and will fail.

\pytx@delimchar We create a macro to store the delimiting character.


314 \edef\pytx@delimchar{\string#}

\pytx@delim We create a macro to store the starting delimiter.


315 \edef\pytx@delim{=\string>PYTHONTEX\string#}

\pytx@delimsettings And we create a second macro to store the starting delimiter for settings that are
passed to Python.
316 \edef\pytx@delimsettings{=\string>PYTHONTEX:SETTINGS\string#}

Settings need to be written to the code file. Some of these settings are not final
until the beginning of the document, since they may be modified by the user within
the preamble. Thus, all settings should be written at the end of the document,
so that they will all be together and will not be interspersed with any code that
was entered in the preamble. The order in which the settings are written is not
significant, but for symmetry it should mirror the order in which they were defined.
317 \AtEndDocument{%
318 \immediate\write\pytx@codefile{\pytx@delimsettings}%
319 \immediate\write\pytx@codefile{version=\pytx@packageversion}%
320 \immediate\write\pytx@codefile{outputdir=\pytx@outputdir}%
321 \immediate\write\pytx@codefile{workingdir=\pytx@workingdir}%
322 \immediate\write\pytx@codefile{workingdirset=\pytx@workingdirset}%
323 \immediate\write\pytx@codefile{gobble=\pytx@opt@gobble}%
324 \immediate\write\pytx@codefile{rerun=\pytx@opt@rerun}%
325 \immediate\write\pytx@codefile{hashdependencies=\pytx@opt@hashdependencies}%
326 \immediate\write\pytx@codefile{makestderr=\ifbool{pytx@opt@stderr}{true}{false}}%
327 \immediate\write\pytx@codefile{stderrfilename=\pytx@opt@stderrfilename}%
328 \immediate\write\pytx@codefile{keeptemps=\pytx@opt@keeptemps}%
329 \immediate\write\pytx@codefile{pyfuture=\pytx@opt@pyfuture}%
330 \immediate\write\pytx@codefile{pyconfuture=\pytx@opt@pyconfuture}%
331 \immediate\write\pytx@codefile{pygments=\ifbool{pytx@opt@pygments}{true}{false}}%
332 \immediate\write\pytx@codefile{pygglobal=:GLOBAL|\pytx@pyglexer|\pytx@pygopt}%
333 \immediate\write\pytx@codefile{fvextfile=\pytx@fvextfile}%
334 \immediate\write\pytx@codefile{pyconbanner=\pytx@opt@pyconbanner}%
335 \immediate\write\pytx@codefile{pyconfilename=\pytx@opt@pyconfilename}%
336 \immediate\write\pytx@codefile{depythontex=\ifbool{pytx@opt@depythontex}{true}{false}}%
337 }

\pytx@WriteCodefileInfo Later, we will frequently need to write PythonTEX information to the code file in
\pytx@WriteCodefileInfoExt standardized form. We create a macro to simplify that process. We also create
an alternate form, for use with external files that must be inputted or read in by
PythonTEX and processed.44
44 The external-file form also takes an optional argument. This corresponds to a command-

line argument that is passed to an external file during the file’s execution. Currently, executing
external files, with or without arguments, is not implemented. But this feature is under con-

92
338 \def\pytx@argsrun{}
339 \def\pytx@argspprint{}
340 \def\pytx@WriteCodefileInfo{%
341 \ifcurrfile{\currfilebase}{\jobname}%
342 {\let\pytx@currfile\@empty}{\let\pytx@currfile\currfilename}%
343 \immediate\write\pytx@codefile{\pytx@delim\pytx@type\pytx@delimchar%
344 \pytx@session\pytx@delimchar\pytx@group\pytx@delimchar%
345 \arabic{\pytx@counter}\pytx@delimchar\pytx@cmd\pytx@delimchar%
346 \pytx@context\pytx@delimchar\pytx@argsrun\pytx@delimchar%
347 \pytx@argspprint\pytx@delimchar%
348 \pytx@currfile\pytx@delimchar%
349 \the\inputlineno\pytx@delimchar}%
350 }
351 \newcommand{\pytx@WriteCodefileInfoExt}[1][]{%
352 \ifcurrfile{\currfilebase}{\jobname}%
353 {\let\pytx@currfile\@empty}{\let\pytx@currfile\currfilename}%
354 \immediate\write\pytx@codefile{\pytx@delim\pytx@type\pytx@delimchar%
355 \pytx@session\pytx@delimchar\pytx@group\pytx@delimchar%
356 \arabic{\pytx@counter}\pytx@delimchar\pytx@cmd\pytx@delimchar%
357 \pytx@context\pytx@delimchar\pytx@argsrun\pytx@delimchar%
358 \pytx@argspprint\pytx@delimchar%
359 \pytx@currfile\pytx@delimchar%
360 \the\inputlineno\pytx@delimchar#1}%
361 }

10.4.6 Interface to fancyvrb


The fancyvrb package is used to typeset lines of code, and its internals are also
used to format inline code snippets. We need a way for each family of PythonTEX
commands and environments to have its own independent fancyvrb settings.
\pytx@fvsettings The macro \setpythontexfv[hfamilyi]{hsettingsi} takes hsettingsi and stores
\setpythontexfv them in a macro that is run through fancyvrb’s \fvset at the beginning
of PythonTEX code. If a hfamilyi is specified, the settings are stored in
\pytx@fvsettings@hfamilyi, and the settings only apply to typeset code belong-
ing to that family. If no optional argument is given, then the settings are stored
in \pytx@fvsettings, and the settings apply to all typeset code.
In the current implementation, \setpythontexfv and \fvset differ because
the former is not persistent in the same sense as the latter. If we use \fvset
to set one property, and then use it later to set another property, the setting for
the original property is persistent. It remains until another \fvset command is
issued to change it. In contrast, every time \setpythontexfv is used, it clears
all prior settings and only the current settings actually apply. This is because
\fvset stores the state of each setting in its own macro, while \setpythontexfv
simply stores a string of settings that is passed to \fvset at the appropriate times.
sideration, and the macro retains the optional argument for the potential future compatibility.
Originally, the external version used a fixed instance, but that conflicted with the fancyvrb
options firstline and lastline, so instances had to be added.

93
For typical use scenarios, this distinction shouldn’t be important—usually, we will
want to set the behavior of fancyvrb for all PythonTEX content, or for a family of
PythonTEX content, and leave those settings constant throughout the document.
Furthermore, environments that typeset code take fancyvrb commands as their
second optional argument, so there is already a mechanism in place for changing
the settings for a single environment. However, if we ever want to change the
typesetting of code for only a small portion of a document (larger than a single
environment), this persistence distinction does become important.45
362 \newcommand{\setpythontexfv}[2][]{%
363 \Depythontex{cmd:setpythontexfv:om:n}%
364 \ifstrempty{#1}%
365 {\gdef\pytx@fvsettings{#2}}%
366 {\expandafter\gdef\csname pytx@fvsettings@#1\endcsname{#2}}%
367 }%
Now that we have a mechanism for applying global settings to typeset
PythonTEX code, we go ahead and set a default tab size for all environments.
If \setpythontexfv is ever invoked, this setting will be overwritten, so that must
be kept in mind.
368 \setpythontexfv{tabsize=4}

\pytx@FVSet Once the fancyvrb settings for PythonTEX are stored in macros, we need a way
to actually invoke them. \pytx@FVSet applies family-specific settings first, then
PythonTEX-wide settings second, so that PythonTEX-wide settings have prece-
dence and will override family-specific settings. Note that by using \fvset, we are
overwriting fancyvrb’s settings. Thus, to keep the settings local to the PythonTEX
code, \pytx@FVSet must always be used within a \begingroup ... \endgroup
block.
369 \def\pytx@FVSet{%
370 \expandafter\let\expandafter\pytx@fvsettings@@%
371 \csname pytx@fvsettings@\pytx@type\endcsname
372 \ifdefstring{\pytx@fvsettings@@}{}%
373 {}%
374 {\expandafter\fvset\expandafter{\pytx@fvsettings@@}}%
375 \ifdefstring{\pytx@fvsettings}{}%
376 {}%
377 {\expandafter\fvset\expandafter{\pytx@fvsettings}}%
378 }

\pytx@FVB@SaveVerbatim fancyvrb’s SaveVerbatim environment will be used extensively to include code


pytx@FancyVerbLineTemp highlighted by Pygments and other processed content. Unfortunately, when the
saved content is included in a document with the corresponding UseVerbatim,
45 An argument could be made for having \textbackslash setpythontexfv behave exactly

like \textbackslash fvset. Properly implementing this behavior would be tricky, because of
inheritance issues between PythonTEX-wide and family-specific settings (this is probably a job
for pgfkeys). Full persistence would likely require a large number of macros and conditionals.
At least from the perspective of keeping the code clean and concise, the current approach is
superior, and probably introduces minor annoyances at worst.

94
line numbering does not work correctly. Based on a web search, this ap-
pears to be a known bug in fancyvrb. We begin by fixing this, which re-
quires patching fancyvrb’s \FVB@SaveVerbatim and \FVE@SaveVerbatim. We
create a patched \pytx@FVB@SaveVerbatim by inserting \FV@StepLineNo and
\FV@CodeLineNo=1 at appropriate locations. We also delete an unnecessary
\gdef\SaveVerbatim@Name{#1}. Then we create a \pytx@FVE@SaveVerbatim,
and add code so that the two macros work together to prevent FancyVerbLine
from incorrectly being incremented within the SaveVerbatim environment. This
involves using the counter pytx@FancyVerbLineTemp to temporarily store the
value of FancyVerbLine, so that it may be restored to its original value after
verbatim content has been saved.
There is an additional line-numbering issue when the firstline option is
used with SaveVerbatim. This is fixed by globally reseting \FV@CodeLineNo to
zero. That was originally done in fancyvrb, via \FV@FormattingPrep, but this
macro is commented out in the current version of fancyvrb, which throws off line
numbering.
Typically, we \let our own custom macros to the corresponding macros within
fancyvrb, but only within a command or environment. In this case, however, we
are fixing behavior that should be considered a bug even for normal fancyvrb
usage. So we let the buggy macros to the patched macros immediately after
defining the patched versions.
379 \newcounter{pytx@FancyVerbLineTemp}
380 \def\pytx@FVB@SaveVerbatim#1{%
381 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
382 \global\FV@CodeLineNo\z@
383 \@bsphack
384 \begingroup
385 \FV@UseKeyValues
386 \def\SaveVerbatim@Name{#1}%
387 \def\FV@ProcessLine##1{%
388 \expandafter\gdef\expandafter\FV@TheVerbatim\expandafter{%
389 \FV@TheVerbatim\FV@StepLineNo\FV@ProcessLine{##1}}}%
390 \gdef\FV@TheVerbatim{\FV@CodeLineNo=1}%
391 \FV@Scan}
392 \def\pytx@FVE@SaveVerbatim{%
393 \expandafter\global\expandafter\let
394 \csname FV@SV@\SaveVerbatim@Name\endcsname\FV@TheVerbatim
395 \endgroup\@esphack
396 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}}
397 \let\FVB@SaveVerbatim\pytx@FVB@SaveVerbatim
398 \let\FVE@SaveVerbatim\pytx@FVE@SaveVerbatim

10.4.7 Enabling fvextra support for Pygments macros


\pytx@ConfigPygments The fvextra package provides Pygments support. We need a macro that can be
used to turn this on at the appropriate points.
399 \def\pytx@ConfigPygments{%

95
400 \def\pytx@currentstyle{default}%
401 \ifcsname pytx@style\endcsname
402 \let\pytx@currentstyle\pytx@style
403 \else
404 \ifcsname pytx@style@\pytx@type\endcsname
405 \expandafter\let\expandafter\pytx@currentstyle\csname pytx@style@\pytx@type\endcsname
406 \fi
407 \fi
408 \expandafter\let\expandafter\PYG@style\csname PYG\pytx@currentstyle\endcsname
409 \VerbatimPygments{\PYG}{\PYG@style}}

10.4.8 Access to printed content (stdout)


The autoprint package option automatically pulls in printed content from code
commands and environments. But this does not cover all possible use cases, be-
cause we could have print statements/functions in block commands and environ-
ments as well. Furthermore, sometimes we may print content, but then desire
to bring it back into the document multiple times, without duplicating the code
that creates the content. Here, we create a number of macros that allow access to
printed content. All macros are created in two identical forms, one based on the
name print and one based on the name stdout. Which macros are used depends
on user preference. The macros based on stdout provide symmetry with stderr
access.

\pytx@stdfile We begin by defining a macro to hold the base name for stdout and stderr content.
The name of this file is updated by most commands and environments so that it
stays current.46 It is important, however, to initially set the name empty for
error-checking purposes.
410 \def\pytx@stdfile{}

\pytx@FetchStdoutfile Now we create a generic macro for bringing in the stdout file. This macro can
input the content in verbatim form, applying fancyvrb options if present. Usage:
\pytx@FetchStdoutfile[hmodei][hoptionsi]{hfile pathi}. We must disable the
macro in the event that the debug option is false. Also, the warning text should
not be included if we are in the preamble.
411 \def\pytx@stdout@warntext{}
412 \def\pytx@FetchStdoutfile[#1][#2]#3{%
413 \IfFileExists{\pytx@outputdir/#3.stdout}{%
414 \ifstrempty{#1}{\input{\pytx@outputdir/#3.stdout}}{}%
415 \ifstrequal{#1}{raw}{\input{\pytx@outputdir/#3.stdout}}{}%
416 \ifstrequal{#1}{verb}{\BVerbatimInput[#2]{\pytx@outputdir/#3.stdout}}{}%
417 \ifstrequal{#1}{verbatim}{\VerbatimInput[#2]{\pytx@outputdir/#3.stdout}}{}%
418 \DepyFile{p:\pytx@outputdir/#3.stdout:mode=#1}%
419 }%
is only updated by those commands and environments that interact with pythontex.py and
46 It

thus increment a type-session-group counter so that they can be distinguished. verb commands
and environments that use fancyvrb for typesetting do not interact with pythontex.py, do not
increment a counter, and thus do not update the stdout file.

96
420 {\pytx@stdout@warntext
421 \PackageWarning{\pytx@packagename}{Non-existent printed content}}%
422 }
423 \ifbool{pytx@opt@stdout}{}{\def\pytx@FetchStdoutfile[#1][#2]#3{}}
424 \AtBeginDocument{\def\pytx@stdout@warntext{\textbf{??~\pytx@packagename~??}}}

\printpythontex We define a macro that pulls in the content of the most recent stdout file, accepting
\stdoutpythontex verbatim settings and also fancyvrb settings if they are given.
425 \def\stdoutpythontex{%
426 \Depythontex{cmd:stdoutpythontex:oo:p}%
427 \@ifnextchar[{\pytx@Stdout}{\pytx@Stdout[raw]}%
428 }
429 \def\pytx@Stdout[#1]{%
430 \@ifnextchar[{\pytx@Stdout@i[#1]}{\pytx@Stdout@i[#1][]}%
431 }
432 \def\pytx@Stdout@i[#1][#2]{%
433 \pytx@FetchStdoutfile[#1][#2]{\pytx@stdfile}%
434 }
435 \def\printpythontex{%
436 \Depythontex{cmd:printpythontex:oo:p}%
437 \@ifnextchar[{\pytx@Stdout}{\pytx@Stdout[raw]}%
438 }

\saveprintpythontex Sometimes, we may wish to use printed content at multiple locations in a docu-
\savestdoutpythontex ment. Because \pytx@stdfile is changed by every command and environment
that could print, the printed content that \printpythontex tries to access is
constantly changing. Thus, \printpythontex is of use only immediately after
content has actually been printed, before any additional PythonTEX commands
or environments change the definition of \pytx@stdfile. To get around this, we
create \saveprintpythontex{hnamei}. This macro saves the current name of
\pytx@stdfile so that it is associated with hnamei and thus can be retrieved
later, after \pytx@stdfile has been redefined.
439 \def\savestdoutpythontex{%
440 \Depythontex{cmd:savestdoutpythontex:m:n}%
441 \savestdoutpythontex@i
442 }
443 \def\savestdoutpythontex@i#1{%
444 \ifcsname pytx@SVout@#1\endcsname
445 \PackageError{\pytx@packagename}%
446 {Attempt to save content using an already-defined name}%
447 {Use a name that is not already defined}%
448 \else
449 \expandafter\edef\csname pytx@SVout@#1\endcsname{\pytx@stdfile}%
450 \fi
451 }
452 \def\saveprintpythontex{%
453 \Depythontex{cmd:saveprintpythontex:m:n}%
454 \savestdoutpythontex@i
455 }

97
\useprintpythontex Now that we have saved the current \pytx@stdoutfile under a new, user-chosen
\usestdoutpythontex name, we need a way to retrieve the content of that file later, using the name.
456 \def\usestdoutpythontex{%
457 \Depythontex{cmd:usestdoutpythontex:oom:p}%
458 \@ifnextchar[{\pytx@UseStdout}{\pytx@UseStdout[]}%
459 }
460 \def\pytx@UseStdout[#1]{%
461 \@ifnextchar[{\pytx@UseStdout@i[#1]}{\pytx@UseStdout@i[#1][]}%
462 }
463 \def\pytx@UseStdout@i[#1][#2]#3{%
464 \ifcsname pytx@SVout@#3\endcsname
465 \pytx@FetchStdoutfile[#1][#2]{\csname pytx@SVout@#3\endcsname}%
466 \else
467 \textbf{??~\pytx@packagename~??}%
468 \PackageWarning{\pytx@packagename}{Non-existent saved printed content}%
469 \fi
470 }
471 \def\useprintpythontex{%
472 \Depythontex{cmd:useprintpythontex:oom:p}%
473 \@ifnextchar[{\pytx@UseStdout}{\pytx@UseStdout[]}%
474 }

10.4.9 Access to stderr


We need access to stderr, if it is enabled via the package makestderr option.
Both stdout and stderr share the same base file name, stored in \pytx@stdfile.
Only the file extensions, .stdout and .stderr, differ.
stderr and stdout are treated identically, except that stderr is brought in ver-
batim by default, while stdout is brought in raw by default.

\pytx@FetchStderrfile Create a generic macro for bringing in the stderr file.


475 \def\pytx@FetchStderrfile[#1][#2]#3{%
476 \IfFileExists{\pytx@outputdir/#3.stderr}{%
477 \ifstrequal{#1}{raw}{\input{\pytx@outputdir/#3.stderr}}{}%
478 \ifstrempty{#1}{\VerbatimInput[#2]{\pytx@outputdir/#3.stderr}}{}%
479 \ifstrequal{#1}{verb}{\BVerbatimInput[#2]{\pytx@outputdir/#3.stderr}}{}%
480 \ifstrequal{#1}{verbatim}{\VerbatimInput[#2]{\pytx@outputdir/#3.stderr}}{}%
481 \DepyFile{p:\pytx@outputdir/#3.stderr:mode=#1}%
482 }%
483 {\textbf{??~\pytx@packagename~??}%
484 \PackageWarning{\pytx@packagename}{Non-existent stderr content}}%
485 }

\stderrpythontex We define a macro that pulls in the content of the most recent error file, accepting
verbatim settings and also fancyvrb settings if they are given.
486 \def\stderrpythontex{%
487 \Depythontex{cmd:stderrpythontex:oo:p}%
488 \@ifnextchar[{\pytx@Stderr}{\pytx@Stderr[verbatim]}%
489 }

98
490 \def\pytx@Stderr[#1]{%
491 \@ifnextchar[{\pytx@Stderr@i[#1]}{\pytx@Stderr@i[#1][]}%
492 }
493 \def\pytx@Stderr@i[#1][#2]{%
494 \pytx@FetchStderrfile[#1][#2]{\pytx@stdfile}%
495 }

A mechanism is provided for saving and later using stderr. This should be
used with care, since stderr content may lose some of its meaning if isolated from
the larger code context that produced it.

\savestderrpythontex
496 \def\savestderrpythontex#1{%
497 \Depythontex{cmd:savestderrpythontex:m:n}%
498 \ifcsname pytx@SVerr@#1\endcsname
499 \PackageError{\pytx@packagename}%
500 {Attempt to save content using an already-defined name}%
501 {Use a name that is not already defined}%
502 \else
503 \expandafter\edef\csname pytx@SVerr@#1\endcsname{\pytx@stdfile}%
504 \fi
505 }

\usestderrpythontex
506 \def\usestderrpythontex{%
507 \Depythontex{cmd:usestderrpythontex:oom:p}%
508 \@ifnextchar[{\pytx@UseStderr}{\pytx@UseStderr[verb]}%
509 }
510 \def\pytx@UseStderr[#1]{%
511 \@ifnextchar[{\pytx@UseStderr@i[#1]}{\pytx@UseStderr@i[#1][]}%
512 }
513 \def\pytx@UseStderr@i[#1][#2]#3{%
514 \ifcsname pytx@SVerr@#3\endcsname
515 \pytx@FetchStderrfile[#1][#2]{\csname pytx@SVerr@#3\endcsname}%
516 \else
517 \textbf{??~\pytx@packagename~??}%
518 \PackageWarning{\pytx@packagename}{Non-existent saved stderr content}%
519 \fi
520 }

10.4.10 depythontex
The purpose of depythontex is to create a version of the original LATEX docu-
ment that does not rely on the PythonTEX package. All uses of PythonTEX are
replaced by their output. This is particularly useful when submitting a paper to
a journal, because PythonTEX can simplify the writing process, but many jour-
nals frown upon “special” packages or custom macros. Note that if you just need
to share a PythonTEX document with someone, you can always include a copy
of pythontex.sty and the PythonTEX output directory with the document, and

99
then non-Python parts of the document can be edited just like a normal LATEX
document, without running any Python code.
The general strategy for depythontex is to write an auxiliary file that contains
information about all environments and macros that need to be replaced, includ-
ing location, format, and the content with which they are to be replaced. This
auxiliary file is then used to performed substitutions on a copy of the original doc-
ument. It would be possible to simply create a list of all PythonTEX macros and
environments, and use that to perform substitutions. But that approach would
have to track the state of PythonTEX more carefully than the auxiliary file ap-
proach. For example, in the auxiliary file approach, it is easy to track whether
autoprint is on or off, because commands and environments will write to the
auxiliary file if they do indeed use autoprint. But without an auxiliary file, you
would have to search for \setpythontexautoprint and devise an algorithm for
determining where it is on or off. Furthermore, once there is a large set of macros,
a general search-and-replace could be quite expensive computationally.
These commands need to be defined after all the other settings commands,
because some of the other settings commands are used within this package after
being defined, and thus don’t need replacement because they’re in the package. At
the same time, the depythontex commands have to exist so that other commands
can be defined with them. So dummy versions are created earlier. During the
next refactoring, the order will be cleaned up and clarified.

\pytx@depyfile If the depythontex package option is on, we need to open an auxiliary file for
writing depythontex information.
521 \ifbool{pytx@opt@depythontex}{%
522 \newwrite\pytx@depyfile
523 \immediate\openout\pytx@depyfile=\jobname.depytx
524 }{}

\Depythontex Each command or environment that is to work with depythontex will write the
following information to the auxiliary file:
=>DEPYTHONTEX#<type>:<name>:<args>:<typeset>:<line>:[<Pygments lexer>]#

where <type> is cmd or env; <name> is the complete name of the com-
mand or environment; <args> is a string representing the arguments taken
(o=optional, m=mandatory, v=mandatory verbatim, n=none); <typeset> is a
string representing what is typeset (c=code, p=printed, n=null), and <line> is
\the\inputlineno. The last one can be determined automatically without user
input, but the first four must be entered when a macro is created. Optionally, the
Pygments lexer is written to file if it is available (if \pytx@lexer is not \relax).
These pieces of information are needed for the following reasons.
• <type> We need to know whether we are dealing with a command or envi-
ronment, so we know how to deal with it. There is no way to detect this
automatically, since a command could always be inside some environment.

100
• <name> We need to know the name of what is to be replaced. There’s no
way to automatically get this.
• <args> We need to know the form of the arguments, so we can assemble an
appropriate regular expression. In some cases, a command might be created
in such a way that this could be detected or easily passed on to PythonTEX
(for example, if the command was defined using the xparse package), but
in general there isn’t a simple way to detect it.
• <typeset> Technically, this could be determined from \pytx@cmd in many
instances. But it couldn’t be determined for cases like \printpythontex and
\stderrpythontex. Furthermore, we want a very general interface suitable
for users writing custom commands and environments.
• <line> This can be determined automatically.
• <Pygments lexer> This is needed if so that the language can be specified
in the output. In general, \pytx@lexer can be defined automatically by a
command and environment generator.
We need a command that writes this information to the auxiliary file. Since
this command may be employed by users writing custom macros, we choose a
capitalized name not containing any ampersands @. Since we need to be able to
easily disable the macro, we create the real macro with name ending in @orig,
and then \let the intended name to it.
525 \let\pytx@lexer\relax
526 \def\Depythontex@orig#1{%
527 \immediate\write\pytx@depyfile{=>DEPYTHONTEX\pytx@delimchar#1:%
528 \the\inputlineno:\ifx\pytx@lexer\relax\else\pytx@lexer\fi\pytx@delimchar}%
529 \let\pytx@lexer\relax}
530 \ifbool{pytx@opt@depythontex}%
531 {\let\Depythontex\Depythontex@orig}%
532 {\let\Depythontex\@gobble}
533 \ifbool{pytx@opt@depythontex}{%
534 \AtEndDocument{%
535 \immediate\write\pytx@depyfile{=>DEPYTHONTEX:SETTINGS\pytx@delimchar version=%
536 \pytx@packageversion\pytx@delimchar}%
537 \immediate\write\pytx@depyfile{=>DEPYTHONTEX:SETTINGS\pytx@delimchar macrofile=%
538 \pytx@outputdir/\pytx@jobname.pytxmcr\pytx@delimchar}%
539 \immediate\write\pytx@depyfile{=>DEPYTHONTEX:SETTINGS\pytx@delimchar outputdir=%
540 \pytx@outputdir\pytx@delimchar}%
541 \immediate\write\pytx@depyfile{=>DEPYTHONTEX:SETTINGS\pytx@delimchar graphicx=%
542 \ifcsname graphicspath\endcsname true\else false\fi\pytx@delimchar}%
543 \immediate\write\pytx@depyfile{=>DEPYTHONTEX:SETTINGS\pytx@delimchar gobble=%
544 \pytx@opt@gobble\pytx@delimchar}%
545 }%
546 }{}

\DepyMacro We need a macro that will write the appropriate information to the auxiliary file
if substitution with the contents of a macro is needed. The argument is of the

101
form <typeset>:<macro name>, where <typeset> is the type of content (p=print,
c=code).
547 \def\DepyMacro@orig#1{%
548 \immediate\write\pytx@depyfile{MACRO:#1}%
549 }
550 \ifbool{pytx@opt@depythontex}%
551 {\let\DepyMacro\DepyMacro@orig}%
552 {\let\DepyMacro\@gobble}

\DepyFile We also need a macro that will write the appropriate information to the auxiliary
file if substitution with the contents of a file is needed. As an argument, this
command takes <typeset>:<filename>[:mode=<format>], where <typeset> is
the type of content (p=print, c=code), <filename> is the full filename, and the
optional mode is the format in which the file is brought in (raw, verb, verbatim).
If mode is not specified, it defaults to reasonable defaults. In general, mode is only
needed for p content; c content is verbatim of one form or another.
553 \def\DepyFile@orig#1{%
554 \immediate\write\pytx@depyfile{FILE:#1}%
555 }%
556 \ifbool{pytx@opt@depythontex}%
557 {\let\DepyFile\DepyFile@orig}%
558 {\let\DepyFile\@gobble}

\DepyListing We need a macro that will write information to the auxiliary file for code listings,
specifically whether line numbers were used, and if so, what the starting number
was. This is non-trivial, because it is possible to change both of these via an
environment’s second optional argument. One approach would be to capture all
optional arguments, pass the second to fancyvrb, and then attempt to evaluate the
status of line numbers via an examination of fancyvrb’s internals. That approach
would require a good deal of work and would likely involve a patch for fancyvrb.
Instead, we redefine \theFancyVerbLine, so that it saves the line number to file
the first time it is used, and then redefines itself to its original form.
Since we are redefining \theFancyVerbLine, \DepyListing can only be used
with commands (such as \inputpygments) if it is in a group (\begingroup ...
\endgroup). This prevents the redefinition from “escaping,” if line numbering is
not used. (Environments are wrapped in groups automatically, so this doesn’t
apply to them.)
559 \newcommand{\pytx@DepyListing@write}{%
560 \immediate\write\pytx@depyfile{LISTING:firstnumber=\arabic{FancyVerbLine}}%
561 }
562 \def\DepyListing@orig{%
563 \let\oldFancyVerbLine\theFancyVerbLine
564 \def\theFancyVerbLine{%
565 \pytx@DepyListing@write
566 \expandafter\gdef\expandafter\theFancyVerbLine\expandafter{\oldFancyVerbLine}%
567 \theFancyVerbLine
568 }%
569 }

102
570 \ifbool{pytx@opt@depythontex}%
571 {\let\DepyListing\DepyListing@orig}%
572 {\let\DepyListing\@empty}

\DepythontexOn We need a way to switch depythontex on and off. When depythontex is being
\DepythontexOff used, it needs to be on throughout the entire main document. But it must be
switched off for any commands or environments that are brought in via external
files (for example, in a package). Since anything that is brought in isn’t actually in
the text of the main document, substitution is both impossible and unnecessary.
573 \newcommand{\DepythontexOn}{%
574 \let\Depythontex\Depythontex@orig
575 \let\DepyMacro\DepyMacro@orig
576 \let\DepyFile\DepyFile@orig
577 \let\DepyListing\DepyListing@orig
578 }
579 \newcommand{\DepythontexOff}{%
580 \let\Depythontex\@gobble
581 \let\DepyMacro\@gobble
582 \let\DepyFile\@gobble
583 \let\DepyListing\@empty
584 }

10.5 Inline commands


10.5.1 Inline core macros
All inline commands use the same core of inline macros. Inline commands in-
voke the \pytx@Inline macro, and this then branches through a number of ad-
ditional macros depending on the details of the command and the usage context.
\@ifnextchar and \let are used extensively to control branching.
\pytx@Inline, and the macros it calls, perform the following series of opera-
tions.
• If there is an optional argument, capture it. The optional argument is the
session name of the command. If there is no session name, use the “default”
session.
• Determine the delimiting character(s) used for the code encompassed by the
command. Any character except for the space character and the opening
curly brace { may be used as a delimiting character, just as for \verb. The
opening curly brace { may be used, but in this case the closing delimiting
character is the closing curly brace }. If paired curly braces are used as
delimiters, then the code enclosed may only contain paired curly braces.
• Using the delimiting character(s), capture the code. Perform some combi-
nation of the following tasks: typeset the code, save it to the code file, and
bring in content created by the code.

103
\pytx@Inline This is the gateway to all inline core macros. It is called by all inline commands.
Because the delimiting characters could be almost anything, we need to turn off
all special category codes before we peek ahead with \@ifnextchar to see if an
optional argument is present, since \@ifnextchar sets the category code of the
character it examines. But we set the opening curly brace { back to its standard
catcode, so that matched braces can be used to capture an argument as usual.
The catcode changes are enclosed withing \begingroup ... \endgroup so that
they may be contained.
The macro \pytx@InlineOarg which is called at the end of \pytx@Inline
takes an argument enclosed by square brackets. If an optional argument is
not present, then we supply an empty one, which invokes default treatment in
\pytx@InlineOarg.
585 \def\pytx@Inline{%
586 \begingroup
587 \let\do\@makeother\dospecials
588 \catcode`\{=1
589 \@ifnextchar[{\endgroup\pytx@InlineOarg}{\endgroup\pytx@InlineOarg[]}%
590 }%

\pytx@InlineOarg This macro captures the optional argument (or the empty default substitute),
which corresponds to the code session. Then it determines whether the delimiters
of the actual code are a matched pair of curly braces or a pair of other, identical
characters, and calls the next macro accordingly.
We begin by testing for an empty argument (either from the user or from the
default empty substitute), and setting the default value if this is indeed the case.
It is also possible that the user chose a session name containing a colon. If so,
we substitute a hyphen for the colon. This is because temporary files are named
based on session, and file names often cannot contain colons.
Then we turn off all special catcodes and set the catcodes of the curly braces
back to their default values. This is necessary because we are about to capture
the actual code, and we need all special catcodes turned off so that the code can
contain any characters. But curly braces still need to be active just in case they are
being used as delimiters. We also make the space and tab characters active, since
fancyvrb needs them that way.47 Using \@ifnextchar we determine whether
the delimiters are curly braces. If so, we proceed to \pytx@InlineMargBgroup to
capture the code using curly braces as delimiters. If not, we reset the catcodes of
the braces and proceed to \pytx@InlineMargOther, which uses characters other
than the opening curly brace as delimiters.
591 \def\pytx@InlineOarg[#1]{%
592 \ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
593 \begingroup
594 \let\do\@makeother\dospecials
595 \catcode`\{=1
47 Part of this may be redundant, since we detokenize later and then retokenize during type-

setting if Pygments isn’t used. But the detokenizing and saving eliminates tab characters if they
aren’t active here.

104
596 \catcode`\}=2
597 \catcode`\ =\active
598 \catcode`\^^I=\active
599 \@ifnextchar\bgroup
600 {\pytx@InlineMargBgroup}%
601 {\catcode`\{=12
602 \catcode`\}=12
603 \pytx@InlineMargOther}%
604 }

\pytx@InlineMargOther This macro captures code delimited by a pair of identical non-brace characters.
\pytx@InlineMargOtherGet Then it passes the code on to \pytx@InlineMargBgroup for processing. This
approach means that the macro definition may be kept concise, and that the
processing code must only be defined once.
The macro captures only the next character. This will be the delimiting charac-
ter. We must begin by ending the group that was left open by \pytx@InlineOarg,
so that catcodes return to normal. Next we check to see if the delimiting charac-
ter is a space character. If so, we issue an error, because that is not allowed.
If the delimiter is valid, we define a macro \pytx@InlineMargOtherGet that
will capture all content up to the next delimiting character and pass it to the
\pytx@InlineMargBgroup macro for processing. That macro does exactly what
is needed, except that part of the retokenization is redundant since curly braces
were not active when the code was captured.
Once the custom capturing macro has been created, we turn off special catcodes
and call the capturing macro.
605 \def\pytx@InlineMargOther#1{%
606 \endgroup
607 \ifstrequal{#1}{ }{%
608 \PackageError{\pytx@packagename}%
609 {The space character cannot be used as a delimiting character}%
610 {Choose another delimiting character}}{}%
611 \def\pytx@InlineMargOtherGet##1#1{\pytx@InlineMargBgroup{##1}}%
612 \begingroup
613 \let\do\@makeother\dospecials
614 \pytx@InlineMargOtherGet
615 }

\pytx@InlineMargBgroup We are now ready to capture code using matched curly braces as delimiters, or to
process previously captured code that used another delimiting character.
At the very beginning, we must end the group that was left open from
\pytx@InlineOarg (or by \pytx@InlineMargOther), so that catcodes return to
normal.
We save a detokenized version of the argument in \pytx@argdetok. Even
though the argument was captured under special catcode conditions, this is still
necessary. If the argument was delimited by curly braces, then any internal curly
braces were active when the argument was captured, and these need their catcodes
corrected. If the code contains any unicode characters, detokenization is needed
so that they may be correctly saved to file.

105
We save a retokenized version of the argument in \pytx@argretok. This is
needed for typesetting with fancyvrb. The code must be retokenized so that
space characters are active, since fancyvrb allows space characters to be visible
or invisible by making them active.
The name of the counter corresponding to this code is assembled. It is needed
for keeping track of the instance, and is used for bringing in content created by
the code and for bringing in highlighting created by Pygments.
Next we call a series of macros that determine whether the code is shown
(typeset), whether it is saved to the code file, and whether content created by
the code (“printed”) should be brought in. These macros are \let to appropriate
values when an inline command is called; they are not defined independently.
Finally, the counter for the code is incremented.
616 \def\pytx@InlineMargBgroup#1{%
617 \endgroup
618 \def\pytx@argdetok{\detokenize{#1}}%
619 \def\pytx@arg{#1}%
620 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
621 \pytx@CheckCounter{\pytx@counter}%
622 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
623 \pytx@InlineShow
624 \pytx@InlineSave
625 \pytx@InlinePrint
626 \stepcounter{\pytx@counter}%
627 }%

\pytx@InlineShow The three macros \pytx@InlineShow, \pytx@InlineSave, and \pytx@InlinePrint


\pytx@InlineSave will be \let to appropriate values when commands are called. We must now define
\pytx@InlinePrint the macros to which they may be \let.

\pytx@InlineShowFV Code may be typeset with fancyvrb. fancyvrb settings are invoked via
pytx@FVSet, but this must be done within a group so that the settings re-
main local. Most of the remainder of the commands are from fancyvrb’s
\FV@FormattingPrep, and take care of various formatting matters, including spac-
ing, font, whether space characters are shown, and any user-defined formatting.
Finally, we create an \hbox and invoke \FancyVerbFormatLine to maintain paral-
lelism with BVerbatim, which is used for inline content highlighted with Pygments.
\FancyVerbFormatLine may be redefined to alter the typeset code, for example,
by putting it in a colorbox via the following command:48
\renewcommand{\FancyVerbFormatLine}[1]{\colorbox{green}{#1}}
628 \def\pytx@InlineShowFV{%
629 \def\pytx@argretok{%
630 \begingroup
48 Currently, \textbackslash FancyVerbFormatLine is global, as in fancyvrb. Allowing a

family-specific variant may be considered in the future. In most cases, the fancyvrb option
formatcom, combined with external formatting from packages like mdframed, should provide all
formatting desired. But something family-specific might occasionally prove useful.

106
631 \everyeof{\noexpand}%
632 \endlinechar-1\relax
633 \let\do\@makeother\dospecials
634 \catcode`\ =\active
635 \catcode`\^^I=\active
636 \expandafter\scantokens\expandafter{\pytx@arg}%
637 \endgroup}%
638 \begingroup
639 \pytx@FVSet
640 \FV@BeginVBox
641 \frenchspacing
642 \FV@SetupFont
643 \FV@DefineWhiteSpace
644 \FancyVerbDefineActive
645 \FancyVerbFormatCom
646 \FV@ObeyTabsInit
647 \hbox{\FancyVerbFormatLine{\pytx@argretok}}%
648 \FV@EndVBox
649 \endgroup
650 }

\pytx@InlineShowPyg Code may be typeset with Pygments. Processed Pygments content is saved in
the .pytxmcr file, wrapped in fancyvrb’s SaveVerbatim environment. The con-
tent is then restored, in a form suitable for inline use, via BUseVerbatim. Un-
like non-inline content, which may be brought in either via macro or via sep-
arate external file, inline content is always brought in via macro. The counter
pytx@FancyVerbLineTemp is used to prevent fancyvrb’s line count from being
affected by PythonTEX content. A group is necessary to confine the fancyvrb
settings created by \pytx@FVSet.
651 \def\pytx@InlineShowPyg{%
652 \begingroup
653 \pytx@FVSet
654 \pytx@ConfigPygments
655 \ifcsname FV@SV@\pytx@counter @\arabic{\pytx@counter}\endcsname
656 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
657 \BUseVerbatim{\pytx@counter @\arabic{\pytx@counter}}%
658 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
659 \else
660 \textbf{??}%
661 \PackageWarning{\pytx@packagename}{Non-existent Pygments content}%
662 \fi
663 \endgroup
664 }

\pytx@InlineSaveCode This macro writes PythonTEX information to the code file and then writes the
actual code.
665 \def\pytx@InlineSaveCode{%
666 \pytx@WriteCodefileInfo
667 \immediate\write\pytx@codefile{\pytx@argdetok}%

107
668 }

\pytx@InlineAutoprint This macro brings in printed content automatically, if the package autoprint
option is true. Otherwise, it does nothing. We must disable the macro in the event
that the debug option is false. We wait until the beginning of the document to
create the real macro, since any code commands and environments in the preamble
shouldn’t be printing and in any case we can’t know what the outputdir is until
the beginning of the document.
669 \let\pytx@InlineAutoprint\@empty
670 \AtBeginDocument{
671 \def\pytx@InlineAutoprint{%
672 \ifbool{pytx@opt@autoprint}{%
673 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.stdout}%
674 {\DepyFile{p:\pytx@outputdir/\pytx@stdfile.stdout}}{}}{}%
675 }
676 \ifbool{pytx@opt@stdout}{}{\let\pytx@InlineAutoprint\@empty}
677 }

\pytx@InlineAlwaysprint This is like \pytx@InlineAutoprint, except that it always prints rather than de-
pending on autoprint. It is used for the s commands, which are always expected
to have output.
678 \def\pytx@InlineAlwaysprint{%
679 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.stdout}%
680 {\DepyFile{p:\pytx@outputdir/\pytx@stdfile.stdout}}%
681 {\textbf{??}%
682 \PackageWarning{\pytx@packagename}{Missing sub content}}}

\pytx@InlineMacroprint This macro brings in “printed” content that is brought in via macros in the
.pytxmcr file. We must disable the macro in the event that the debug option
is false.
683 \def\pytx@InlineMacroprint{%
684 \edef\pytx@mcr{pytx@MCR@\pytx@type @\pytx@session @\pytx@group @\arabic{\pytx@counter}}%
685 \ifcsname\pytx@mcr\endcsname
686 \csname\pytx@mcr\endcsname
687 \DepyMacro{p:\pytx@mcr}%
688 \else
689 \textbf{??}%
690 \PackageWarning{\pytx@packagename}{Missing autoprint content}%
691 \fi
692 }
693 \ifbool{pytx@opt@stdout}{}{\let\pytx@InlineMacroprint\@empty}

\pytx@InlineMacroprintFV This macro brings in “printed” content that is brought in via SaveVerbatim (only
inline console references at the moment). We must disable the macro in the event
that the debug option is false.
694 \def\pytx@InlineMacroprintFV{%
695 \edef\pytx@mcr{pytx@\pytx@type @\pytx@session @\pytx@group @\arabic{\pytx@counter}}%
696 \ifcsname FV@SV@\pytx@mcr\endcsname

108
697 \BUseVerbatim{\pytx@mcr}%
698 \DepyMacro{c:\pytx@mcr}%
699 \else
700 \textbf{??}%
701 \PackageWarning{\pytx@packagename}{Missing autoprint content}%
702 \fi
703 }
704 \ifbool{pytx@opt@stdout}{}{\let\pytx@InlineMacroprint\@empty}

10.5.2 Inline command constructors


With the core inline macros complete, we are ready to create constructors for
different kinds of inline commands. All of these consctructors take a string and
define an inline command named using that string as a base name. Two forms
of each constructor are created, one that uses Pygments and one that does not.
The Pygments variants have names ending in “Pyg”. All commands are created
using etoolbox’s \newrobustcmd. Among other things, this is needed so that
commands will work within the default caption command.

\pytx@MakeInlinebFV These macros creates inline block commands, which both typeset code and save
\pytx@MakeInlinebPyg it so that it may be executed. The base name of the command is stored in
\pytx@type. A string representing the kind of command is stored in \pytx@cmd.
Then \pytx@SetContext is used to set \pytx@context and \pytx@SetGroup is
used to set \pytx@group. Macros for showing, saving, and printing are set to ap-
propriate values. Then the core inline macros are invoked through \pytx@Inline.
705 \newcommand{\pytx@MakeInlinebFV}[1]{%
706 \expandafter\newrobustcmd\expandafter{\csname #1b\endcsname}{%
707 \expandafter\let\expandafter\pytx@lexer\csname pytx@pyglexer@#1\endcsname
708 \Depythontex{cmd:#1b:ov:c}%
709 \xdef\pytx@type{#1}%
710 \edef\pytx@cmd{b}%
711 \pytx@SetContext
712 \pytx@SetGroup
713 \let\pytx@InlineShow\pytx@InlineShowFV
714 \let\pytx@InlineSave\pytx@InlineSaveCode
715 \let\pytx@InlinePrint\@empty
716 \pytx@Inline
717 }%
718 }%
719 \newcommand{\pytx@MakeInlinebPyg}[1]{%
720 \expandafter\newrobustcmd\expandafter{\csname #1b\endcsname}{%
721 \xdef\pytx@type{#1}%
722 \edef\pytx@cmd{b}%
723 \pytx@SetContext
724 \pytx@SetGroup
725 \let\pytx@InlineShow\pytx@InlineShowPyg
726 \let\pytx@InlineSave\pytx@InlineSaveCode
727 \let\pytx@InlinePrint\@empty
728 \pytx@Inline

109
729 }%
730 }%

\pytx@MakeInlinevFV This macro creates inline verbatim commands, which only typeset code. \pytx@type,
\pytx@MakeInlinevPyg \pytx@cmd, \pytx@context, and \pytx@group are still set, for symmetry with
other commands. They are not needed for fancyvrb typesetting, though. We
use \pytx@SetGroupVerb to split verbatim content (v and verb) off into its own
group. That way, verbatim content doesn’t affect the instance numbers of exe-
cuted code, and thus executed code is not affected by the addition or removal of
verbatim content.
731 \newcommand{\pytx@MakeInlinevFV}[1]{%
732 \expandafter\newrobustcmd\expandafter{\csname #1v\endcsname}{%
733 \expandafter\let\expandafter\pytx@lexer\csname pytx@pyglexer@#1\endcsname
734 \Depythontex{cmd:#1v:ov:c}%
735 \xdef\pytx@type{#1}%
736 \edef\pytx@cmd{v}%
737 \pytx@SetContext
738 \pytx@SetGroupVerb
739 \let\pytx@InlineShow\pytx@InlineShowFV
740 \let\pytx@InlineSave\@empty
741 \let\pytx@InlinePrint\@empty
742 \pytx@Inline
743 }%
744 }%
745 \newcommand{\pytx@MakeInlinevPyg}[1]{%
746 \expandafter\newrobustcmd\expandafter{\csname #1v\endcsname}{%
747 \xdef\pytx@type{#1}%
748 \edef\pytx@cmd{v}%
749 \pytx@SetContext
750 \pytx@SetGroupVerb
751 \let\pytx@InlineShow\pytx@InlineShowPyg
752 \let\pytx@InlineSave\pytx@InlineSaveCode
753 \let\pytx@InlinePrint\@empty
754 \pytx@Inline
755 }%
756 }%

\pytx@MakeInlinecFV This macro creates inline code commands, which save code for execution but do
\pytx@MakeInlinecPyg not typeset it. If the code prints content, this content is inputted automatically if
the package option autoprint is on. Since no code is typeset, there is no difference
between the fancyvrb and Pygments forms.
757 \newcommand{\pytx@MakeInlinecFV}[1]{%
758 \expandafter\newrobustcmd\expandafter{\csname #1c\endcsname}{%
759 \Depythontex{cmd:#1c:ov:p}%
760 \xdef\pytx@type{#1}%
761 \edef\pytx@cmd{c}%
762 \pytx@SetContext
763 \pytx@SetGroup
764 \let\pytx@InlineShow\@empty

110
765 \let\pytx@InlineSave\pytx@InlineSaveCode
766 \let\pytx@InlinePrint\pytx@InlineAutoprint
767 \pytx@Inline
768 }%
769 }%
770 \let\pytx@MakeInlinecPyg\pytx@MakeInlinecFV

\pytx@MakeInlinesFV This macro behaves almost exactly like code commands on the LATEX side, but
\pytx@MakeInlinesPyg on the Python side, the argument is treated as a template in which fields are
evaluated and replaced with the result. Since no code is typeset, there is no
difference between the fancyvrb and Pygments forms.
771 \newcommand{\pytx@MakeInlinesFV}[1]{%
772 \expandafter\newrobustcmd\expandafter{\csname #1s\endcsname}{%
773 \Depythontex{cmd:#1s:ov:p}%
774 \xdef\pytx@type{#1}%
775 \edef\pytx@cmd{s}%
776 \pytx@SetContext
777 \pytx@SetGroup
778 \let\pytx@InlineShow\@empty
779 \let\pytx@InlineSave\pytx@InlineSaveCode
780 \let\pytx@InlinePrint\pytx@InlineAlwaysprint
781 \pytx@Inline
782 }%
783 }%
784 \let\pytx@MakeInlinesPyg\pytx@MakeInlinesFV

\pytx@MakeInlineFV This macro creates plain inline commands, which save code and then bring in
\pytx@MakeInlinePyg the output of pytex.formatter(hcodei) (pytex.formatter() is the formatter
function in Python sessions that is provided by pythontex_utils*.py). The
Python output is saved in a TEX macro, and the macro is written to a file shared
by all PythonTEX sessions. This greatly reduces the number of external files
needed. Since no code is typeset, there is no difference between the fancyvrb and
Pygments forms.
785 \newcommand{\pytx@MakeInlineFV}[1]{%
786 \expandafter\newrobustcmd\expandafter{\csname #1\endcsname}{%
787 \Depythontex{cmd:#1:ov:p}%
788 \xdef\pytx@type{#1}%
789 \edef\pytx@cmd{i}%
790 \pytx@SetContext
791 \pytx@SetGroup
792 \let\pytx@InlineShow\@empty
793 \let\pytx@InlineSave\pytx@InlineSaveCode
794 \let\pytx@InlinePrint\pytx@InlineMacroprint
795 \pytx@Inline
796 }%
797 }%
798 \let\pytx@MakeInlinePyg\pytx@MakeInlineFV

\pytx@MakeInlineConsFV This is the inline form for console types. It brings in SaveVerbatim.
\pytx@MakeInlineConsPyg

111
799 \newcommand{\pytx@MakeInlineConsFV}[1]{%
800 \expandafter\newrobustcmd\expandafter{\csname #1\endcsname}{%
801 \Depythontex{cmd:#1:ov:c}%
802 \xdef\pytx@type{#1}%
803 \edef\pytx@cmd{i}%
804 \pytx@SetContext
805 \pytx@SetGroup
806 \let\pytx@InlineShow\@empty
807 \let\pytx@InlineSave\pytx@InlineSaveCode
808 \let\pytx@InlinePrint\pytx@InlineMacroprintFV
809 \pytx@Inline
810 }%
811 }%
812 \let\pytx@MakeInlineConsPyg\pytx@MakeInlineConsFV

\pythontexcustomc This macro takes a single line of code and adds it to all sessions within a family.
It is the inline version of the pythontexcustomcode environment.
813 \newrobustcmd{\pythontexcustomc}[2][begin]{%
814 \Depythontex{cmd:pythontexcustomc:omv:p}%
815 \ifstrequal{#1}{begin}{}{%
816 \ifstrequal{#1}{end}{}{\PackageError{\pytx@packagename}%
817 {Invalid optional argument for \string\pythontexcustomc}{}
818 }%
819 }%
820 \xdef\pytx@type{CC:#2:#1}%
821 \edef\pytx@cmd{c}%
822 \pytx@SetContext
823 \def\pytx@group{none}%
824 \let\pytx@InlineShow\@empty
825 \let\pytx@InlineSave\pytx@InlineSaveCode
826 \let\pytx@InlinePrint\@empty
827 \pytx@Inline[none]%
828 }%

\setpythontexcustomcode This macro is a holdover from 0.9beta3. It has been deprecated in favor of
\pythontexcustomc and pythontexcustomcode.
829 \def\setpythontexcustomcode#1{%
830 \Depythontex{cmd:setpythontexcustomcode:mv:p}%
831 \PackageWarning{\pytx@packagename}{The command
832 \string\setpythontexcustomcode\space has been deprecated;
833 use \string\pythontexcustomc\space or pythontexcustomcode instead}%
834 \begingroup
835 \let\do\@makeother\dospecials
836 \catcode`\{=1
837 \catcode`\}=2
838 \catcode`\^^M=10\relax
839 \pytx@SetCustomCode{#1}%
840 }
841 \long\def\pytx@SetCustomCode#1#2{%

112
842 \endgroup
843 \pythontexcustomc{#1}{pythontexcustomcode=[#2];
844 exec('for expr in pythontexcustomcode: exec(expr)');
845 del(pythontexcustomcode)}
846 }
847 \@onlypreamble\setpythontexcustomcode

10.6 Environments
The inline commands were all created using a common core set of macros, com-
bined with short, command-specific constructors. In the case of environments,
we do not have a common core set of macros. Each environment is coded sepa-
rately, though there are similarities among environments. In the future, it may be
worthwhile to attempt to consolidate the environment code base.
One of the differences between inline commands and environments is that envi-
ronments may need to typeset code with line numbers. Each family of code needs
to have its own line numbering (actually, its own numbering for code, verbatim,
and console groups), and this line numbering should not overwrite any line num-
bering that may separately be in use by fancyvrb. To make this possible, we use
a temporary counter extensively. When line numbers are used, fancyvrb’s line
counter is copied into pytx@FancyVerbLineTemp, lines are numbered, and then
fancyvrb’s line counter is restored from pytx@FancyVerbLineTemp. This keeps
fancyvrb and PythonTEX’s line numbering separate, even though PythonTEX is
using fancyvrb and its macros internally.

10.6.1 Block and verbatim environment constructors


We begin by creating block and verb environment constuctors that use fancyvrb.
Then we create Pygments versions.

\pytx@FancyVerbGetLine The block environment needs to both typeset code and save it so it can be ex-
ecuted. fancyvrb supports typesetting, but doesn’t support saving at the same
time. So we create a modified version of fancyvrb’s \FancyVerbGetLine macro
which does. This is identical to the fancyvrb version, except that we add a line
that writes to the code file. The material that is written is detokenized to avoid
catcode issues and make unicode work correctly.
848 \begingroup
849 \catcode`\^^M=\active
850 \gdef\pytx@FancyVerbGetLine#1^^M{%
851 \@nil%
852 \FV@CheckEnd{#1}%
853 \ifx\@tempa\FV@EnvironName%
854 \ifx\@tempb\FV@@@CheckEnd\else\FV@BadEndError\fi%
855 \let\next\FV@EndScanning%
856 \else%
857 \def\FV@Line{#1}%
858 \def\next{\FV@PreProcessLine\FV@GetLine}%
859 \immediate\write\pytx@codefile{\detokenize{#1}}%

113
860 \fi%
861 \next}%
862 \endgroup

\pytx@MakeBlockFV Now we are ready to actually create block environments. This macro takes an
environment base name hnamei and creates a block environment hnameiblock,
using fancyvrb.
The block environment is a Verbatim environment, so we declare that with
the \VerbatimEnvironment macro, which lets fancyvrb find the end of the envi-
ronment correctly. We define the type, define the command, and set the context
and group.
We need to check for optional arguments, so we begin a group and use
\obeylines to make line breaks active. Then we check to see if the next char
is an opening square bracket. If so, there is an optional argument, so we end
our group and call the \pytx@BeginBlockEnvFV macro, which will capture the
argument and finish preparing for the block content. If not, we end the group and
call the same \pytx@BeginBlockEnvFV macro with an empty argument. The line
breaks need to be active during this process because we don’t care about content
on the next line, including opening square brackets on the next line; we only care
about content in the line on which the environment is declared, because only on
that line should there be an optional argument. The problem is that since we are
dealing with code, it is quite possible for there to be an opening square bracket at
the beginning of the next line, so we must prevent that from being misinterpreted
as an optional argument.
After the environment, we need to clean up several things. Much of this relates
to what is done in the \pytx@BeginBlockEnvFV macro. The body of the environ-
ment is wrapped in a Verbatim environment, so we must end that. It is also
wrapped in a group, so that fancyvrb settings remain local; we end the group.
Then we define the name of the outfile for any printed content, so that it may
be accessed by \printpythontex and company. Finally, we rearrange counters.
The current code line number needs to be stored in \pytx@linecount, which was
defined to be specific to the current type-session-group set. The fancyvrb line
number needs to be set back to its original value from before the environment be-
gan, so that PythonTEX content does not affect the line numbering of fancyvrb
content. Finally, the \pytx@counter, which keeps track of commands and envi-
ronments within the current type-session-group set, needs to be incremented.
863 \newcommand{\pytx@MakeBlockFV}[1]{%
864 \expandafter\newenvironment{#1block}{%
865 \VerbatimEnvironment
866 \expandafter\let\expandafter\pytx@lexer\csname pytx@pyglexer@#1\endcsname
867 \Depythontex{env:#1block:oo|:c}%
868 \DepyListing
869 \xdef\pytx@type{#1}%
870 \edef\pytx@cmd{block}%
871 \pytx@SetContext
872 \pytx@SetGroup
873 \begingroup

114
874 \obeylines
875 \@ifnextchar[{\endgroup\pytx@BeginBlockEnvFV}{\endgroup\pytx@BeginBlockEnvFV[]}%
876 }%
877 {\end{Verbatim}%
878 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
879 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
880 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
881 \stepcounter{\pytx@counter}%
882 }%
883 }

\pytx@BeginBlockEnvFV This macro finishes preparations to actually begin the block environment. It
captures the optional argument (or the empty argument supplied by default). If
this argument is empty, then it sets the value of the argument to the default
value. If not, then colons in the optional argument are replaced with underscores,
and the modified argument is stored in \pytx@session. Colons are replaced with
underscores because session names must be suitable for file names, and colons are
generally not allowed in file names. However, we want to be able to enter session
names containing colons, since colons provide a conventient method of indicating
relationships, and are commonly used in LATEX labels. For example, we could have
a session named plots:specialplot.
Once the session is established, we are free to define the counter for the current
type-session-group, and make sure it exists. We also define the counter that will
keep track of line numbers for the current type-session-group, and make sure it
exists. Then we do some counter trickery. We don’t want fancyvrb line counting
to be affected by PythonTEX content, so we store the current line number held
by FancyVerbLine in pytx@FancyVerbLineTemp; we will restore FancyVerbLine
to this original value at the end of the environment. Then we set FancyVerbLine
to the appropriate line number for the current type-session-group. This provides
proper numbering continuity between different environments within the same type-
session-group.
Next, we write environment information to the code file, now that all the
necessary information is assembled. We begin a group, to keep some things local.
We \let a fancyvrb macro to our custom macro. We set fancyvrb settings to
those of the current type using \pytx@FVSet. Once this is done, we are finally
ready to start the Verbatim environment. Note that the Verbatim environment
will capture a second optional argument delimited by square brackets, if present,
and apply this argument as fancyvrb formatting. Thus, the environment actually
takes up to two optional arguments, but if you want to use fancyvrb formatting,
you must supply an empty (default session) or named (custom session) optional
argument for the PythonTEX code.
884 \def\pytx@BeginBlockEnvFV[#1]{%
885 \ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
886 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
887 \pytx@CheckCounter{\pytx@counter}%
888 \edef\pytx@linecount{\pytx@counter @line}%
889 \pytx@CheckCounter{\pytx@linecount}%

115
890 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
891 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
892 \pytx@WriteCodefileInfo
893 \let\FancyVerbGetLine\pytx@FancyVerbGetLine
894 \pytx@FVSet
895 \begin{Verbatim}%
896 }

\pytx@MakeVerbFV The verbatim environments only typeset code; they do not save it for execution.
Thus, we just use a standard fancyvrb environment with a few enhancements.
As in the block environment, we declare that we are using a Verbatim envi-
ronment, define type and command, set context and group (note the use of the
Verb group), and take care of optional arguments before calling a macro to wrap
things up (in this case, \pytx@BeginVerbEnvFV). Currently, much of the saved
information is unused, but it is provided to maintain parallelism with the block
environment.
Ending the environment involves ending the Verbatim environment begun by
\pytx@BeginVerbEnvFV, ending the group that kept fancyvrb settings local, and
resetting counters. We define a stdfile and step the counter, even though there
will never actually be any output to pull in, to force \printpythontex and com-
pany to be used immediately after the code they refer to and to maintain paral-
lelism.
897 \newcommand{\pytx@MakeVerbFV}[1]{%
898 \expandafter\newenvironment{#1verbatim}{%
899 \VerbatimEnvironment
900 \expandafter\let\expandafter\pytx@lexer\csname pytx@pyglexer@#1\endcsname
901 \Depythontex{env:#1verbatim:oo|:c}%
902 \DepyListing
903 \xdef\pytx@type{#1}%
904 \edef\pytx@cmd{verbatim}%
905 \pytx@SetContext
906 \pytx@SetGroupVerb
907 \begingroup
908 \obeylines
909 \@ifnextchar[{\endgroup\pytx@BeginVerbEnvFV}{\endgroup\pytx@BeginVerbEnvFV[]}%
910 }%
911 {\end{Verbatim}%
912 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
913 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
914 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
915 \stepcounter{\pytx@counter}%
916 }%
917 }

\pytx@BeginVerbEnvFV This macro captures the optional argument of the environment (or the default
empty argument that is otherwise supplied). If the argument is empty, it assignes
a default value; otherwise, it substitutes underscores for colons in the argument.
The argument is assigned to \pytx@session. A line counter is created, and its

116
existence is checked. We do the standard line counter trickery. Then we begin a
group to keep fancyvrb settings local, invoke the settings via \pytx@FVSet, and
begin the Verbatim environment.
918 \def\pytx@BeginVerbEnvFV[#1]{%
919 \ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
920 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
921 \pytx@CheckCounter{\pytx@counter}%
922 \edef\pytx@linecount{\pytx@counter @line}%
923 \pytx@CheckCounter{\pytx@linecount}%
924 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
925 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
926 \pytx@FVSet
927 \begin{Verbatim}%
928 }

Now for the Pygments forms of block and verb. Since all code must be saved
now (either to be executed or processed by Pygments, or both), the environment
code may be simplified compared to the non-Pygments case.
\pytx@MakePygEnv The block and verb environments are created via the same macro. The
\pytx@MakePygEnv macro takes two arguments: first, the code type, and sec-
ond, the environment (block or verb). The reason for using the same macro is
that both must now save their code externally, and bring back the result typeset
by Pygments. Thus, on the LATEX side, their behavior is identical. The only dif-
ference is on the Python side, where the block code is executed and thus there
may be output available via \printpythontex and company.
The actual workings of the macro are a combination of those of the non-
Pygments macros, so please refer to those for details. The only exception is the
code for bringing in Pygments output, but this is done using almost the same
approach as that used for the inline Pygments commands. There are two dif-
ferences: first, the block and verb environments use \UseVerbatim rather than
\BUseVerbatim, since they are not typesetting code inline; and second, they ac-
cept a second, optional argument containing fancyvrb commands and this is
used in typesetting the saved content. Any fancyvrb commands are saved in
\pytx@fvopttmp by \pytx@BeginEnvPyg@i, and then used when the code is type-
set.
Note that the positioning of all the FancyVerbLine trickery in what follows is
significant. Saving the FancyVerbLine counter to a temporary counter before the
beginning of VerbatimOut is important, because otherwise the fancyvrb number-
ing can be affected.
929 \newcommand{\pytx@MakePygEnv}[2]{%
930 \expandafter\newenvironment{#1#2}{%
931 \VerbatimEnvironment
932 \xdef\pytx@type{#1}%
933 \edef\pytx@cmd{#2}%
934 \pytx@SetContext
935 \ifstrequal{#2}{block}{\pytx@SetGroup}{}

117
936 \ifstrequal{#2}{verbatim}{\pytx@SetGroupVerb}{}
937 \begingroup
938 \obeylines
939 \@ifnextchar[{\endgroup\pytx@BeginEnvPyg}{\endgroup\pytx@BeginEnvPyg[]}%
940 }%
941 {\end{VerbatimOut}%
942 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
943 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
944 \pytx@FVSet
945 \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
946 \pytx@ConfigPygments
947 \ifcsname FV@SV@\pytx@counter @\arabic{\pytx@counter}\endcsname
948 \UseVerbatim{\pytx@counter @\arabic{\pytx@counter}}%
949 \else
950 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.pygtex}{}%
951 {\textbf{??~\pytx@packagename~??}%
952 \PackageWarning{\pytx@packagename}{Non-existent Pygments content}}%
953 \fi
954 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
955 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
956 \stepcounter{\pytx@counter}%
957 }%
958 }%

\pytx@BeginEnvPyg This macro finishes preparing for the content of a verb or block environment with
Pygments content. It captures an optional argument corresponding to the session
name and sets up instance and line counters. Finally, it calls an additional macro
that handles the possibility of a second optional argument.
959 \def\pytx@BeginEnvPyg[#1]{%
960 \ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
961 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
962 \pytx@CheckCounter{\pytx@counter}%
963 \edef\pytx@linecount{\pytx@counter @line}%
964 \pytx@CheckCounter{\pytx@linecount}%
965 \pytx@WriteCodefileInfo
966 \begingroup
967 \obeylines
968 \@ifnextchar[{\endgroup\pytx@BeginEnvPyg@i}{\endgroup\pytx@BeginEnvPyg@i[]}%
969 }%

\pytx@BeginEnvPyg@i This macro captures a second optional argument, corresponding to fancyvrb op-
tions. Note that not all fancyvrb options may be passed to saved content when it
is actually used, particularly those corresponding to how the content was read in
the first place (for example, command characters). But at least most formatting
options such as line numbering work fine. As with the non-Pygments environ-
ments, \begin{VerbatimOut} doesn’t take a second mandatory argument, since
we are using a custom version and don’t need to specify the file in which Verbatim
content is saved. It is important that the FancyVerbLine saving be done here; if

118
it is done later, after the end of VerbatimOut, then numbering can be off in some
circumstances (for example, a single pyverbatim between two Verbatim’s).
970 \def\pytx@BeginEnvPyg@i[#1]{%
971 \def\pytx@fvopttmp{#1}%
972 \def\pytx@argspprint{#1}%
973 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
974 \let\FVB@VerbatimOut\pytx@FVB@VerbatimOut
975 \let\FVE@VerbatimOut\pytx@FVE@VerbatimOut
976 \begin{VerbatimOut}%
977 }%

Since we are using the same code to create both block and verb environments,
we now create a specific macro for creating each case, to make usage equivalent
to that for the non-Pygments case.
\pytx@MakeBlockPyg The block environment is constructed via the \pytx@MakePygEnv macro.
978 \newcommand{\pytx@MakeBlockPyg}[1]{\pytx@MakePygEnv{#1}{block}}

\pytx@MakeVerbPyg The verb environment is constructed likewise.


979 \newcommand{\pytx@MakeVerbPyg}[1]{\pytx@MakePygEnv{#1}{verbatim}}

10.6.2 Code environment constructor


The code environment merely saves code to the code file; nothing is typeset. To
accomplish this, we use a slightly modified version of fancyvrb’s VerbatimOut.
\pytx@WriteDetok We can use fancyvrb to capture the code, but we will need a way to write the
code in detokenized form. This is necessary so that TEX doesn’t try to process
the code as it is written, which would generally be disastrous.
980 \def\pytx@WriteDetok#1{%
981 \immediate\write\pytx@codefile{\detokenize{#1}}}%

\pytx@FVB@VerbatimOut We need a custom version of the macro that begins VerbatimOut. We don’t need
fancyvrb’s key values, and due to our use of \detokenize to write content, we
don’t need its space and tab treatment either. We do need fancyvrb to write to
our code file, not the file to which it would write by default. And we don’t need
to open any files, because the code file is already open. These last two are the
only important differences between our version and the original fancyvrb version.
Since we don’t need to write to a user-specified file, we don’t require the mandatory
argument of the original macro.
982 \def\pytx@FVB@VerbatimOut{%
983 \@bsphack
984 \begingroup
985 \let\FV@ProcessLine\pytx@WriteDetok
986 \let\FV@FontScanPrep\relax
987 \let\@noligs\relax
988 \FV@Scan}%

119
\pytx@FVE@VerbatimOut Similarly, we need a custom version of the macro that ends VerbatimOut. We
don’t want to close the file to which we are saving content.
989 \def\pytx@FVE@VerbatimOut{\endgroup\@esphack}%

\pytx@EnvAutoprint We also need a macro for bringing in autoprint content. This is a separate macro
so that it can be easily disabled by the package option debug. We wait until the
beginning of the document to create the real macro, since any code commands
and environments in the preamble shouldn’t be printing and in any case we can’t
know what the outputdir is until the beginning of the document.
990 \let\pytx@EnvAutoprint\@empty
991 \AtBeginDocument{
992 \def\pytx@EnvAutoprint{%
993 \ifbool{pytx@opt@autoprint}{%
994 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.stdout}%
995 {\DepyFile{p:\pytx@outputdir/\pytx@stdfile.stdout}}{}}{}%
996 }
997 \ifbool{pytx@opt@stdout}{}{\let\pytx@EnvAutoprint\@empty}
998 }

\pytx@MakeCodeFV Now that the helper macros for the code environment have been defined, we are
ready to create the macro that makes code environments. Everything at the
beginning of the environment is similar to the block and verb environments.
After the environment, we need to close the VerbatimOut environment begun
by \pytx@BeginCodeEnv@i and end the group it began. We define the outfile,
and bring in any printed content if the autoprint setting is on. We must still
perform some FancyVerbLine trickery to prevent the fancyvrb line counter from
being affected by writing content! Finally, we step the counter.
999 \newcommand{\pytx@MakeCodeFV}[1]{%
1000 \expandafter\newenvironment{#1code}{%
1001 \VerbatimEnvironment
1002 \Depythontex{env:#1code:oo|:p}%
1003 \xdef\pytx@type{#1}%
1004 \edef\pytx@cmd{code}%
1005 \pytx@SetContext
1006 \pytx@SetGroup
1007 \begingroup
1008 \obeylines
1009 \@ifnextchar[{\endgroup\pytx@BeginCodeEnv}{\endgroup\pytx@BeginCodeEnv[]}%
1010 }%
1011 {\end{VerbatimOut}%
1012 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
1013 \ifcsname pytx@nonpyconsole@\pytx@type\endcsname
1014 \ifcsname pytx@code@as@console\endcsname
1015 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
1016 \pytx@FVSet
1017 \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
1018 \pytx@ConfigPygments
1019 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.stdout}%

120
1020 {\DepyFile{p:\pytx@outputdir/\pytx@stdfile.stdout}}%
1021 {\par\textbf{??~\pytx@packagename~??}\par
1022 \PackageWarning{\pytx@packagename}{Non-existent console content}}%
1023 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
1024 \else
1025 \fi
1026 \let\pytx@EnvAutoprint\relax
1027 \else
1028 \fi
1029 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1030 \stepcounter{\pytx@counter}%
1031 \pytx@EnvAutoprint
1032 }%
1033 }%

\pytx@BeginCodeEnv This macro finishes setting things up before the code environment contents. It
processes the optional argument, defines a counter and checks its existence, writes
info to the code file, and then calls the \pytx@BeginCodeEnv@i macro. This macro
is necessary so that the environment can accept two optional arguments. Since the
block and verb environments can accept two optional arguments (the first is the
name of the session, the second is fancyvrb options), the code environment also
should be able to, to maintain parallelism (for example, pyblock should be able
to be swapped with pycode without changing environment arguments—it should
just work). However, VerbatimOut doesn’t take an optional argument. So we
need to capture and discard any optional argument, before starting VerbatimOut.
1034 \def\pytx@BeginCodeEnv[#1]{%
1035 \ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
1036 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
1037 \pytx@CheckCounter{\pytx@counter}%
1038 \edef\pytx@linecount{\pytx@counter @line}%
1039 \pytx@CheckCounter{\pytx@linecount}%
1040 \pytx@WriteCodefileInfo
1041 \begingroup
1042 \obeylines
1043 \@ifnextchar[{\endgroup\pytx@BeginCodeEnv@i}{\endgroup\pytx@BeginCodeEnv@i[]}%
1044 }%

\pytx@BeginCodeEnv@i As described above, this macro captures a second optional argument, if present,
and then starts the VerbatimOut environment. Note that VerbatimOut does not
have a mandatory argument, because we are invoking our custom \pytx@FVB@VerbatimOut
macro. The default fancyvrb macro needs an argument to tell it the name of the
file to which to save the verbatim content. But in our case, we are always writing
to the same file, and the custom macro accounts for this by not having a manda-
tory file name argument. We must perform the typical FancyVerbLine trickery,
to prevent the fancyvrb line counter from being affected by writing content!
1045 \def\pytx@BeginCodeEnv@i[#1]{%
1046 \def\pytx@fvopttmp{#1}%
1047 \def\pytx@argspprint{#1}%

121
1048 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
1049 \let\FVB@VerbatimOut\pytx@FVB@VerbatimOut
1050 \let\FVE@VerbatimOut\pytx@FVE@VerbatimOut
1051 \begin{VerbatimOut}%
1052 }%

\pytx@MakeCodePyg Since the code environment simply saves code for execution and typesets nothing,
the Pygments version is identical to the non-Pygments version, so we simply let
the former to the latter.
1053 \let\pytx@MakeCodePyg\pytx@MakeCodeFV

pythontexcustomcode This environment is used for adding custom code to all sessions within a command
and environment family. It is the environment equivalent of the inline command
\pythontexcustomc.
1054 \newenvironment{pythontexcustomcode}[2][begin]{%
1055 \VerbatimEnvironment
1056 \Depythontex{env:pythontexcustomcode:om:n}%
1057 \ifstrequal{#1}{begin}{}{%
1058 \ifstrequal{#1}{end}{}{\PackageError{\pytx@packagename}%
1059 {Invalid optional argument for pythontexcustomcode}{}
1060 }%
1061 }%
1062 \xdef\pytx@type{CC:#2:#1}%
1063 \edef\pytx@cmd{code}%
1064 \pytx@SetContext
1065 \def\pytx@group{none}%
1066 \pytx@BeginCodeEnv[none]}%
1067 {\end{VerbatimOut}%
1068 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1069 \stepcounter{\pytx@counter}%
1070 }%

10.6.3 Sub environment constructor


The sub environment behaves exactly like a code environment on the LATEX side:
environment content is saved to the code file, and then the output is brought back
in. The difference is on the Python side, where the environment content is treated
as a template in which fields are evaluated and replaced with the result.

\pytx@MakeSubFV Create a sub environment compatible with fancyvrb, reusing the code approach
almost entirely.
1071 \newcommand{\pytx@MakeSubFV}[1]{%
1072 \expandafter\newenvironment{#1sub}{%
1073 \VerbatimEnvironment
1074 \Depythontex{env:#1sub:oo|:p}%
1075 \xdef\pytx@type{#1}%
1076 \edef\pytx@cmd{sub}%
1077 \pytx@SetContext
1078 \pytx@SetGroup

122
1079 \begingroup
1080 \obeylines
1081 \@ifnextchar[{\endgroup\pytx@BeginCodeEnv}{\endgroup\pytx@BeginCodeEnv[]}%
1082 }%
1083 {\end{VerbatimOut}%
1084 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
1085 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1086 \stepcounter{\pytx@counter}%
1087 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.stdout}%
1088 {\DepyFile{p:\pytx@outputdir/\pytx@stdfile.stdout}}%
1089 {\textbf{??~\pytx@packagename~??}%
1090 \PackageWarning{\pytx@packagename}{Non-existent substituted content}}%
1091 }%
1092 }%

\pytx@MakeSubPyg The Pygments-compatible version is the same.


1093 \let\pytx@MakeSubPyg\pytx@MakeSubFV

10.6.4 Console environment constructor


The console environment needs to write all code contained in the environment
to the code file, and then bring in the console output.
An environment suffix is not enforced for flexibility. For Python, the convention
is that console type names will end with con, and then the environment will use
the suffix sole. For example, the pycon type has the pyconsole environment.
\pytx@MakeConsoleFV
1094 \newcommand{\pytx@MakeConsFV}[2]{%
1095 \expandafter\newenvironment{#1#2}{%
1096 \VerbatimEnvironment
1097 \expandafter\let\expandafter\pytx@lexer\csname pytx@pyglexer@#1\endcsname
1098 \Depythontex{env:#1#2:oo|:c}%
1099 \DepyListing
1100 \xdef\pytx@type{#1}%
1101 \edef\pytx@cmd{console}%
1102 \pytx@SetContext
1103 \pytx@SetGroup
1104 \begingroup
1105 \obeylines
1106 \@ifnextchar[{\endgroup\pytx@BeginConsEnvFV}{\endgroup\pytx@BeginConsEnvFV[]}%
1107 }%
1108 {\end{VerbatimOut}%
1109 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
1110 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
1111 \pytx@FVSet
1112 \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
1113 \ifcsname FV@SV@\pytx@counter @\arabic{\pytx@counter}\endcsname
1114 \UseVerbatim{\pytx@counter @\arabic{\pytx@counter}}%
1115 \DepyMacro{c:\pytx@counter @\arabic{\pytx@counter}}%

123
1116 \else
1117 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.tex}%
1118 {\DepyFile{c:\pytx@outputdir/\pytx@stdfile.tex}}%
1119 {\textbf{??~\pytx@packagename~??}%
1120 \PackageWarning{\pytx@packagename}{Non-existent console content}}%
1121 \fi
1122 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
1123 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1124 \stepcounter{\pytx@counter}%
1125 }%
1126 }

\pytx@BeginConsEnvFV
1127 \def\pytx@BeginConsEnvFV[#1]{%
1128 \ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
1129 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
1130 \pytx@CheckCounter{\pytx@counter}%
1131 \edef\pytx@linecount{\pytx@counter @line}%
1132 \pytx@CheckCounter{\pytx@linecount}%
1133 \pytx@WriteCodefileInfo
1134 \begingroup
1135 \obeylines
1136 \@ifnextchar[{\endgroup\pytx@BeginConsEnvFV@i}{\endgroup\pytx@BeginConsEnvFV@i[]}%
1137 }%

\pytx@BeginConsEnvFV@i
1138 \def\pytx@BeginConsEnvFV@i[#1]{%
1139 \def\pytx@fvopttmp{#1}%
1140 \def\pytx@argspprint{#1}%
1141 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
1142 \let\FVB@VerbatimOut\pytx@FVB@VerbatimOut
1143 \let\FVE@VerbatimOut\pytx@FVE@VerbatimOut
1144 \begin{VerbatimOut}%
1145 }%

\pytx@MakeConsPyg The Pygments version of the console environment is identical to the fancyvrb
version, except that .pygtex rather than .tex files are brought in.
1146 \newcommand{\pytx@MakeConsPyg}[2]{%
1147 \expandafter\newenvironment{#1#2}{%
1148 \VerbatimEnvironment
1149 \expandafter\let\expandafter\pytx@lexer\csname pytx@pyglexer@#1\endcsname
1150 \Depythontex{env:#1#2:oo|:c}%
1151 \DepyListing
1152 \xdef\pytx@type{#1}%
1153 \edef\pytx@cmd{console}%
1154 \pytx@SetContext
1155 \pytx@SetGroup
1156 \begingroup
1157 \obeylines

124
1158 \@ifnextchar[{\endgroup\pytx@BeginConsEnvFV}{\endgroup\pytx@BeginConsEnvFV[]}%
1159 }%
1160 {\end{VerbatimOut}%
1161 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
1162 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
1163 \pytx@FVSet
1164 \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
1165 \pytx@ConfigPygments
1166 \ifcsname FV@SV@\pytx@counter @\arabic{\pytx@counter}\endcsname
1167 \UseVerbatim{\pytx@counter @\arabic{\pytx@counter}}%
1168 \DepyMacro{c:\pytx@counter @\arabic{\pytx@counter}}%
1169 \else
1170 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.pygtex}%
1171 {\DepyFile{c:\pytx@outputdir/\pytx@stdfile.pygtex}}%
1172 {\textbf{??~\pytx@packagename~??}%
1173 \PackageWarning{\pytx@packagename}{Non-existent console content}}%
1174 \fi
1175 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
1176 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1177 \stepcounter{\pytx@counter}%
1178 }%
1179 }

10.7 Constructors for command and environment families


Everything is now in place to create commands and environments, with and with-
out Pygments usage. To make all of this more readily usable, we need macros
that will create a whole family of commands and environments at once, using a
base name. For example, we need a way to create all commands and environments
based off of the py base name.

\makepythontexfamily This macro creates a family of commands. It needs a some pgfkeys to handle
the optional arguments. The actual creation of all non-code commands and envi-
ronments is delayed using \AtBeginDocument, so that the user has the option to
choose whether fancyvrb or Pygments is used for the family.
We need to create a counter for the default session for each family to avoid
(some of the) issues with \includeonly and counters. See http://tug.org/
pipermail/macostex-archives/2010-December/046007.html for more on the
problematic counter behavior with \includeonly.
1180 \pgfkeys{
1181 /PYTX/family/.is family,
1182 /PYTX/family,
1183 name/.estore in = \pytx@tmp@name,
1184 prettyprinter/.estore in = \pytx@tmp@pprinter,
1185 pyglexer/.estore in = \pytx@tmp@pyglexer,
1186 pygopt/.code = \def\pytx@tmp@pygopt{#1}\pgfkeys{/PYTX/lopt/pygopt/.cd, #1},
1187 console/.estore in = \pytx@tmp@console,
1188 default/.style = {prettyprinter=auto, pyglexer=text, pygopt={}, console=false}

125
1189 }
1190 \def\pytx@MakeFamilyFV#1{%
1191 \pytx@MakeInlinebFV{#1}%
1192 \pytx@MakeInlinevFV{#1}%
1193 \pytx@MakeInlineFV{#1}%
1194 \pytx@MakeBlockFV{#1}%
1195 \pytx@MakeVerbFV{#1}%
1196 }
1197 \def\pytx@MakeFamilyPyg#1{%
1198 \ifbool{pytx@opt@pyginline}%
1199 {\pytx@MakeInlinebPyg{#1}\pytx@MakeInlinevPyg{#1}}%
1200 {\pytx@MakeInlinebFV{#1}\pytx@MakeInlinevFV{#1}}%
1201 \pytx@MakeInlinePyg{#1}%
1202 \pytx@MakeBlockPyg{#1}%
1203 \pytx@MakeVerbPyg{#1}%
1204 \booltrue{pytx@usedpygments}%
1205 \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=#1|%
1206 \csname pytx@pyglexer@#1\endcsname|%
1207 \csname pytx@pygopt@#1\endcsname}%
1208 }%
1209 }
1210 \def\pytx@MakeFamilyFVCons#1{%
1211 \pytx@MakeInlinevFV{#1}%
1212 \pytx@MakeInlineConsFV{#1}%
1213 \pytx@MakeConsFV{#1}{sole}%
1214 \pytx@MakeVerbFV{#1}%
1215 }
1216 \def\pytx@MakeFamilyPygCons#1{%
1217 \ifbool{pytx@opt@pyginline}%
1218 {\pytx@MakeInlinevPyg{#1}}%
1219 {\pytx@MakeInlinevFV{#1}}%
1220 \pytx@MakeInlineConsPyg{#1}%
1221 \pytx@MakeConsPyg{#1}{sole}%
1222 \pytx@MakeVerbPyg{#1}%
1223 \booltrue{pytx@usedpygments}%
1224 \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=#1|%
1225 \csname pytx@pyglexer@#1\endcsname|%
1226 \csname pytx@pygopt@#1\endcsname}%
1227 }%
1228 }
1229 \newcommand{\makepythontexfamily}[2][]{%
1230 \IfBeginWith{#2}{PYG}%
1231 {\PackageError{\pytx@packagename}%
1232 {Attempt to create macros with reserved prefix PYG}{}}{}%
1233 \pgfkeys{/PYTX/family, name=#2, default, #1}
1234 \expandafter\xdef\csname pytx@macroformatter@#2\endcsname{\pytx@tmp@pprinter}
1235 \expandafter\gdef\csname pytx@fvsettings@#2\endcsname{}
1236 \expandafter\xdef\csname pytx@pyglexer@#2\endcsname{\pytx@tmp@pyglexer}
1237 \expandafter\xdef\csname pytx@pygopt@#2\endcsname{\pytx@tmp@pygopt}
1238 \expandafter\xdef\csname pytx@console@#2\endcsname{\pytx@tmp@console}

126
1239 \pytx@MakeInlinecFV{#2}
1240 \pytx@MakeInlinesFV{#2}
1241 \pytx@MakeCodeFV{#2}
1242 \pytx@MakeSubFV{#2}
1243 \AtBeginDocument{%
1244 \ifcsstring{pytx@macroformatter@#2}{auto}{%
1245 \ifbool{pytx@opt@pygments}%
1246 {\ifcsstring{pytx@console@#2}{true}%
1247 {\pytx@MakeFamilyPygCons{#2}}{\pytx@MakeFamilyPyg{#2}}}%
1248 {\ifcsstring{pytx@console@#2}{true}%
1249 {\pytx@MakeFamilyFVCons{#2}}{\pytx@MakeFamilyFV{#2}}}%
1250 }{}%
1251 \ifcsstring{pytx@macroformatter@#2}{fancyvrb}%
1252 {\ifcsstring{pytx@console@#2}{true}%
1253 {\pytx@MakeFamilyFVCons{#2}}{\pytx@MakeFamilyFV{#2}}}{}%
1254 \ifcsstring{pytx@macroformatter@#2}{pygments}%
1255 {\ifcsstring{pytx@console@#2}{true}%
1256 {\pytx@MakeFamilyPygCons{#2}}{\pytx@MakeFamilyPyg{#2}}}{}%
1257 }%
1258 \newcounter{pytx@#2@default@default}%
1259 }
1260 \@onlypreamble\makepythontexfamily

\makepythontexfamily@con This macro creates console and code environments for non-Python consoles.
PythonTEX was not designed with commands and environments for non-Python
consoles. Non-Python consoles are currently created via specially customized
code environments. Note that simply creating these console and code environ-
ments is typically not enough to create non-Python consoles; pythontex2.py and
pythontex3.py usually also require customization. This macro’s definition should
not be treated as stable; it will change in the future. The ultimate long-term goal
is to eliminate it entirely, by redesigning the code execution core of PythonTEX
to accomodate non-Python consoles more easily.
1261 \newcommand{\makepythontexfamily@con}[2][text]{%
1262 \pgfkeys{/PYTX/family, name=#2con, default, pyglexer=#1, console=true}%
1263 \expandafter\xdef\csname pytx@macroformatter@#2con\endcsname{\pytx@tmp@pprinter}%
1264 \expandafter\gdef\csname pytx@fvsettings@#2con\endcsname{}%
1265 \expandafter\xdef\csname pytx@pyglexer@#2con\endcsname{\pytx@tmp@pyglexer}%
1266 \expandafter\xdef\csname pytx@pygopt@#2con\endcsname{\pytx@tmp@pygopt}%
1267 \expandafter\xdef\csname pytx@console@#2con\endcsname{\pytx@tmp@console}%
1268 \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=#2con|%
1269 \csname pytx@pyglexer@#2con\endcsname|%
1270 \csname pytx@pygopt@#2con\endcsname}%
1271 }%
1272 \pytx@MakeCodeFV{#2con}%
1273 \expandafter\global\expandafter\let\csname pytx@nonpyconsole@#2con\endcsname\relax
1274 \newenvironment{#2console}%
1275 {\VerbatimEnvironment
1276 \def\pytx@type{#2con}%
1277 \let\pytx@code@as@console\relax

127
1278 \begin{#2concode}}%
1279 {\end{#2concode}}%
1280 }

\setpythontexpyglexer We need to be able to reset the lexer associated with a family after the family has
already been created.
1281 \newcommand{\setpythontexpyglexer}[2][]{%
1282 \Depythontex{cmd:setpythontexpyglexer:om:n}%
1283 \ifstrempty{#1}{\def\pytx@pyglexer{#2}}{%
1284 \ifcsname pytx@pyglexer@#1\endcsname
1285 \expandafter\xdef\csname pytx@pyglexer@#1\endcsname{#2}%
1286 \else
1287 \PackageError{\pytx@packagename}%
1288 {Cannot modify a non-existent family}{}%
1289 \fi
1290 }%
1291 }%
1292 \@onlypreamble\setpythontexpyglexer

\setpythontexpygopt The user may wish to modify the Pygments options associated with a family. This
macro takes two arguments: first, the family base name; and second, the Pygments
options to associate with the family. This macro is particularly useful in changing
the Pygments style of default command and environment families.
Due to the implementation (and also in the interest of keeping typesetting
consistent), the Pygments style for a family must remain constant throughout the
document. Thus, we only allow changes to the style in the preamble.
1293 \newcommand{\setpythontexpygopt}[2][]{%
1294 \Depythontex{cmd:setpythontexpygopt:om:n}%
1295 \ifstrempty{#1}%
1296 {\def\pytx@pygopt{#2}\pgfkeys{/PYTX/gopt/pygopt/.cd, #2}}%
1297 {\ifcsname pytx@pygopt@#1\endcsname
1298 \expandafter\xdef\csname pytx@pygopt@#1\endcsname{#2}%
1299 \pgfkeys{/PYTX/lopt/pygopt/.cd, name=#1, #2}
1300 \else
1301 \PackageError{\pytx@packagename}%
1302 {Cannot modify Pygments options for a non-existent family}{}%
1303 \fi}%
1304 }
1305 \@onlypreamble\setpythontexpygopt

\setpythontexprettyprinter We need to be able to reset the pretty printer used by a family among the options
auto, fancyvrb, and pygments.
1306 \newcommand{\setpythontexprettyprinter}[2][]{%
1307 \Depythontex{cmd:setpythontexprettyprinter:om:n}%
1308 \ifstrempty{#1}{%
1309 \ifstrequal{#2}{fancyvrb}{\boolfalse{pytx@opt@pygments}}%
1310 \ifstrequal{#2}{pygments}{\booltrue{pytx@opt@pygments}}%
1311 }{%
1312 \ifcsname pytx@macroformatter@#1\endcsname

128
1313 \ifbool{pytx@opt@depythontex}{}{%
1314 \expandafter\xdef\csname pytx@macroformatter@#1\endcsname{#2}}
1315 \else
1316 \PackageError{\pytx@packagename}%
1317 {Cannot modify a family that does not exist or does not allow formatter choices}
1318 {Create the family with \string\makepythontexfamily}%
1319 \fi
1320 }%
1321 }
1322 \@onlypreamble\setpythontexprettyprinter

10.8 Default commands and environment families


We are finally prepared to create the default command and environment families.
We create a basic Python family with the base name py. We also create customized
Python families for the SymPy package, using the base name sympy, and for the
pylab module, using the base name pylab. All of these are created with a console
environment.
All of these command and environment families are created conditionally, de-
pending on whether the package option pygments is used, via \makepythontexfamily.
We recommend that any custom families created by the user be constructed in
the same manner.
1323 \makepythontexfamily[pyglexer=python3]{py}
1324 \makepythontexfamily[pyglexer=pycon, console=true]{pycon}
1325 \makepythontexfamily[pyglexer=python3]{sympy}
1326 \makepythontexfamily[pyglexer=pycon, console=true]{sympycon}
1327 \makepythontexfamily[pyglexer=python3]{pylab}
1328 \makepythontexfamily[pyglexer=pycon, console=true]{pylabcon}
We also need to create any additional families specified via the usefamily package
option.49
1329 \renewcommand{\do}[1]{%
1330 \ifstrequal{#1}{ruby}{\makepythontexfamily[pyglexer=ruby]{ruby}}{}%
1331 \ifstrequal{#1}{rb}{\makepythontexfamily[pyglexer=ruby]{rb}}{}%
1332 \ifstrequal{#1}{julia}{\makepythontexfamily[pyglexer=julia]{julia}}{}%
1333 \ifstrequal{#1}{juliacon}{\makepythontexfamily@con[jlcon]{julia}}{}%
1334 \ifstrequal{#1}{jl}{\makepythontexfamily[pyglexer=julia]{jl}}{}%
1335 \ifstrequal{#1}{matlab}{\makepythontexfamily[pyglexer=matlab]{matlab}}{}%
1336 \ifstrequal{#1}{octave}{\makepythontexfamily[pyglexer=octave]{octave}}{}%
1337 \ifstrequal{#1}{bash}{\makepythontexfamily[pyglexer=bash]{bash}}{}%
1338 \ifstrequal{#1}{sage}{\makepythontexfamily[pyglexer=sage]{sage}}{}%
1339 \ifstrequal{#1}{rust}{\makepythontexfamily[pyglexer=rust]{rust}}{}%
1340 \ifstrequal{#1}{rs}{\makepythontexfamily[pyglexer=rust]{rs}}{}%
1341 \ifstrequal{#1}{R}{\makepythontexfamily[pyglexer=r]{R}}{}%
1342 \ifstrequal{#1}{Rcon}{\makepythontexfamily@con[rconsole]{R}}{}%
1343 \ifstrequal{#1}{perl}{\makepythontexfamily[pyglexer=perl]{perl}}{}%
49 The loop here is accomplished via etoolbox. pgffor might be an alternative, but making

definitions global requires trickery.

129
1344 \ifstrequal{#1}{pl}{\makepythontexfamily[pyglexer=perl]{pl}}{}%
1345 \ifstrequal{#1}{perlsix}{\makepythontexfamily[pyglexer=perl6]{perlsix}}{}%
1346 \ifstrequal{#1}{psix}{\makepythontexfamily[pyglexer=perl6]{psix}}{}%
1347 \ifstrequal{#1}{javascript}{\makepythontexfamily[pyglexer=js]{javascript}}{}%
1348 \ifstrequal{#1}{js}{\makepythontexfamily[pyglexer=js]{js}}{}%
1349 }
1350 \expandafter\docsvlist\expandafter{\pytx@families}

10.9 Listings environment


fancyvrb, especially when combined with Pygments, provides most of the format-
ting options we could want. However, it simply typesets code within the flow of
the document and does not provide a floating environment. So we create a floating
environment for code listings via the newfloat package.
It is most logical to name this environment listing, but that is already defined
by the minted package (although PythonTEX and minted are probably not likely
to be used together, due to overlapping features). Furthermore, the listings
package specifically avoided using the name listing for an environment due to
the use of this name by other packages.
We have chosen to make a compromise. We create a macro that creates a float
environment with a custom name for listings. If this macro is invoked, then a float
environment for listings is created and nothing else is done. If it is not invoked,
the package attempts to create an environment called listing at the beginning
of the document, and issues a warning if another macro with that name already
exists. This approach makes the logical listing name available in most cases,
and provides the user with a simple fallback in the event that another package
defining listing must be used alongside PythonTEX.

\setpythontexlistingenv We define a bool pytx@listingenv that keeps track of whether a listings environ-
ment has been created. Then we define a macro that creates a floating environment
with a custom name, with appropriate settings for a listing environment. We only
allow this macro to be used in the preamble, since later use would wreak havok.
1351 \newbool{pytx@listingenv}
1352 \def\setpythontexlistingenv#1{%
1353 \Depythontex{cmd:setpythontexlistingenv:m:n}%
1354 \DeclareFloatingEnvironment[fileext=lopytx,listname={List of Listings},name=Listing]{#1}
1355 \booltrue{pytx@listingenv}
1356 }
1357 \@onlypreamble\setpythontexlistingenv

At the beginning of the document, we issue a warning if the listing envi-


ronment needs to be created but cannot be due to a pre-existing macro (and no
version with a custom name has been created). Otherwise, we create the listing
environment.
1358 \AtBeginDocument{
1359 \ifcsname listing\endcsname
1360 \ifbool{pytx@listingenv}{}%

130
1361 {\PackageWarning{\pytx@packagename}%
1362 {A "listing" environment already exists \MessageBreak
1363 \pytx@packagename\space will not create one \MessageBreak
1364 Use \string\setpythontexlistingenv\space to create a custom listing environment
1365 \else
1366 \ifbool{pytx@listingenv}{}{\DeclareFloatingEnvironment[fileext=lopytx]{listing}}
1367 \fi
1368 }

10.10 Pygments for general code typesetting


After all the work that has gone into PythonTEX thus far, it would be a pity
not to slightly expand the system to allow Pygments typesetting of any language
Pygments supports. While PythonTEX currently can only execute Python code,
it is relatively easy to add support for highlighting any language supported by
Pygments. We proceed to create a \pygment command, a pygments environment,
and an \inputpygments command that do just this. The functionality of these is
very similar to that provided by the minted package.
Both the commands and the environment are created in two forms: one that
actually uses Pygments, which is the whole point in the first place; and one
that uses fancyvrb, which may speed compilation or make editing faster since
pythontex.py need not be invoked. By default, the two forms are switched be-
tween based on the package pygments option, but this may be easily modified as
described below.
The Pygments commands and environment operate under the code type
PYGhlexer namei. This allows Pygments typesetting of general code to proceed
with very few additions to pythontex.py; in most situations, the Pygments code
types behave just like standard PythonTEX types that don’t execute any code.
Due to the use of the PYG prefix for all Pygments content, the use of this prefix is
not allowed at the beginning of a base name for standard PythonTEX command
and environment families.
We have previously used the suffix Pyg to denote macro variants that use
Pygments rather than fancyvrb. We continue that practice here. To distinguish
the special Pygments typesetting macros from the regular PythonTEX macros, we
use Pygments in the macro names, in addition to any Pyg suffix

10.11 Pygments utilities macros


\pytx@CheckPygmentsInit We need to see if macros exist for storing Pygments fv settings and pygopt. If
not, create them, and make sure they will be written to file.
1369 \def\pytx@CheckPygmentsInit#1{%
1370 \ifcsname pytx@fvsettings@PYG#1\endcsname\else
1371 \expandafter\gdef\csname pytx@fvsettings@PYG#1\endcsname{}%
1372 \expandafter\gdef\csname pytx@pygopt@PYG#1\endcsname{}%
1373 \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=PYG#1|#1|%
1374 \csname pytx@pygopt@PYG#1\endcsname}}%
1375 \fi

131
1376 }

10.11.1 Inline Pygments command


\pytx@MakePygmentsInlineFV These macros create an inline command. They reuse the \pytx@Inline macro
\pytx@MakePygmentsInlinePyg sequence. The approach is very similar to the constructors for inline commands,
\pygment except for the way in which the type is defined and for the fact that we have to
check to see if a macro for fancyvrb settings exists. Just as for the PythonTEX
inline commands, we do not currently support fancyvrb options in Pygments
inline commands, since almost all options are impractical for inline usage, and the
few that might conceivably be practical, such as showing spaces, should probably
be used throughout an entire document rather than just for a tiny code snippet
within a paragraph.
We supply an empty optional argument to \pytx@Inline, so that the \pygment
command can only take two mandatory arguments, and no optional argument
(since sessions don’t make sense for code that is merely typeset):
\pygment{hlexeri}{hcodei}
1377 \def\pytx@MakePygmentsInlineFV{%
1378 \newcommand{\pygment}[1]{%
1379 \edef\pytx@lexer{##1}%
1380 \Depythontex{cmd:pygment:mv:c}%
1381 \edef\pytx@type{PYG##1}%
1382 \edef\pytx@cmd{v}%
1383 \pytx@SetContext
1384 \pytx@SetGroupVerb
1385 \let\pytx@InlineShow\pytx@InlineShowFV
1386 \let\pytx@InlineSave\@empty
1387 \let\pytx@InlinePrint\@empty
1388 \pytx@CheckPygmentsInit{##1}%
1389 \pytx@Inline[]%
1390 }%
1391 }
1392 \def\pytx@MakePygmentsInlinePyg{%
1393 \newcommand{\pygment}[1]{%
1394 \edef\pytx@type{PYG##1}%
1395 \edef\pytx@cmd{v}%
1396 \pytx@SetContext
1397 \pytx@SetGroupVerb
1398 \let\pytx@InlineShow\pytx@InlineShowPyg
1399 \let\pytx@InlineSave\pytx@InlineSaveCode
1400 \let\pytx@InlinePrint\@empty
1401 \pytx@CheckPygmentsInit{##1}%
1402 \pytx@Inline[]
1403 }%
1404 }

132
10.11.2 Pygments environment
\pytx@MakePygmentsEnvFV The pygments environment is created to take an optional argument, which corre-
pygments sponds to fancyvrb settings, and one mandatory argument, which corresponds to
the Pygments lexer to be used in highlighting the code.
The pygments environment begins by declaring that it is a Verbatim envi-
ronment and setting variables. Again, some variables are unnecessary, but they
are created to maintain uniformity with other PythonTEX environments. The
environment code is very similar to that of PythonTEX verb environments.
1405 \def\pytx@MakePygmentsEnvFV{%
1406 \newenvironment{pygments}{%
1407 \VerbatimEnvironment
1408 \pytx@SetContext
1409 \pytx@SetGroupVerb
1410 \begingroup
1411 \obeylines
1412 \@ifnextchar[{\endgroup\pytx@BEPygmentsFV}{\endgroup\pytx@BEPygmentsFV[]}%
1413 }%
1414 {\end{Verbatim}%
1415 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
1416 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1417 }%
1418 }

\pytx@BEPygmentsFV This macro captures the optional argument containing fancyvrb commands.
1419 \def\pytx@BEPygmentsFV[#1]{%
1420 \def\pytx@fvopttmp{#1}%
1421 \def\pytx@argspprint{#1}%
1422 \begingroup
1423 \obeylines
1424 \pytx@BEPygmentsFV@i
1425 }

\pytx@BEPygmentsFV@i This macro captures the mandatory argument, containing the lexer name, and
proceeds.
1426 \def\pytx@BEPygmentsFV@i#1{%
1427 \endgroup
1428 \edef\pytx@type{PYG#1}%
1429 \edef\pytx@lexer{#1}%
1430 \Depythontex{env:pygments:om:c}%
1431 \DepyListing
1432 \edef\pytx@cmd{verbatim}%
1433 \edef\pytx@session{default}%
1434 \edef\pytx@linecount{pytx@\pytx@type @\pytx@session @\pytx@group @line}%
1435 \pytx@CheckCounter{\pytx@linecount}%
1436 \pytx@CheckPygmentsInit{#1}%
1437 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
1438 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
1439 \pytx@FVSet

133
1440 \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
1441 \begin{Verbatim}%
1442 }

\pytx@MakePygmentsEnvPyg The Pygments version is very similar, except that it must bring in external Pyg-
pygments ments content.
1443 \def\pytx@MakePygmentsEnvPyg{%
1444 \newenvironment{pygments}{%
1445 \VerbatimEnvironment
1446 \pytx@SetContext
1447 \pytx@SetGroupVerb
1448 \begingroup
1449 \obeylines
1450 \@ifnextchar[{\endgroup\pytx@BEPygmentsPyg}{\endgroup\pytx@BEPygmentsPyg[]}%
1451 }%
1452 {\end{VerbatimOut}%
1453 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
1454 \pytx@FVSet
1455 \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
1456 \pytx@ConfigPygments
1457 \ifcsname FV@SV@\pytx@counter @\arabic{\pytx@counter}\endcsname
1458 \UseVerbatim{\pytx@counter @\arabic{\pytx@counter}}%
1459 \else
1460 \InputIfFileExists{\pytx@outputdir/%
1461 \pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}.pygtex}{}%
1462 {\textbf{??~\pytx@packagename~??}%
1463 \PackageWarning{\pytx@packagename}{Non-existent Pygments content}}%
1464 \fi
1465 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
1466 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1467 \stepcounter{\pytx@counter}%
1468 }%
1469 }

\pytx@BEPygmentsPyg This macro captures the optional argument, which corresponds to fancyvrb set-
tings.
1470 \def\pytx@BEPygmentsPyg[#1]{%
1471 \def\pytx@fvopttmp{#1}%
1472 \def\pytx@argspprint{#1}%
1473 \begingroup
1474 \obeylines
1475 \pytx@BEPygmentsPyg@i
1476 }

\pytx@BEPygmentsPyg@i This macro captures the mandatory argument, containing the lexer name, and
proceeds.
1477 \def\pytx@BEPygmentsPyg@i#1{%
1478 \endgroup
1479 \edef\pytx@type{PYG#1}%

134
1480 \edef\pytx@cmd{verbatim}%
1481 \edef\pytx@session{default}%
1482 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
1483 \pytx@CheckCounter{\pytx@counter}%
1484 \edef\pytx@linecount{\pytx@counter @line}%
1485 \pytx@CheckCounter{\pytx@linecount}%
1486 \pytx@WriteCodefileInfo
1487 \pytx@CheckPygmentsInit{#1}%
1488 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
1489 \let\FVB@VerbatimOut\pytx@FVB@VerbatimOut
1490 \let\FVE@VerbatimOut\pytx@FVE@VerbatimOut
1491 \begin{VerbatimOut}%
1492 }

10.11.3 Special Pygments commands


Code highlighting may be used for some tasks that would never appear in a code
execution context, which is what the PythonTEX part of this package focuses on.
We create some special Pygments macros to handle these highlighting cases.

\pytx@MakePygmentsInputFV For completeness, we need to be able to read in a file and highlight it. This
\pytx@MakePygmentsInputPyg is done through some trickery with the current system. We define the type as
PYGhlexeri, and the command as verb. We set the context for consistency. We
set the session as EXT:hfile namei.50 Next we define a fancyvrb settings macro
for the type if it does not already exist. We write info to the code file using
\pytx@WriteCodefileInfoExt.
Then we check to see if the file actually exists, and issue a warning if not. This
saves the user from running pythontex.py to get the same error. We perform our
typical FancyVerbLine trickery. Next we make use of the saved content in the
same way as the pygments environment. Note that we do not create a counter
for the line numbers. This is because under typical usage an external file should
have its lines numbered beginning with 1. We also encourage this by setting
firstnumber=auto before bringing in the content.
The current naming of the macro in which the Pygments content is saved is
probably excessive. In almost every situation, a unique name could be formed with
less information. The current approach has been taken to maintain parallelism,
thus simplifying pythontex.py, and to avoid any rare potential conflicts.
1493 \def\pytx@MakePygmentsInputFV{
1494 \newcommand{\inputpygments}[3][]{%
1495 \edef\pytx@lexer{##2}%
1496 \Depythontex{cmd:inputpygments:omm:c}%
1497 \edef\pytx@type{PYG##2}%
1498 \edef\pytx@cmd{verbatim}%
1499 \pytx@SetContext
50 There is no possibility of this session being confused with a user-defined session, because

colons are substituted for hyphens in all user-defined sessions, before they are written to the
code file.

135
1500 \pytx@SetGroupVerb
1501 \edef\pytx@session{EXT:##3}%
1502 \pytx@CheckPygmentsInit{##2}%
1503 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
1504 \pytx@CheckCounter{\pytx@counter}%
1505 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
1506 \begingroup
1507 \DepyListing %Always must be in a group
1508 \pytx@FVSet
1509 \fvset{firstnumber=auto}%
1510 \IfFileExists{##3}%
1511 {\DepyFile{c:##3:mode=verbatim}\VerbatimInput[##1]{##3}}%
1512 {\PackageWarning{\pytx@packagename}{Input file <##3> doesn't exist}}%
1513 \endgroup
1514 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1515 \stepcounter{\pytx@counter}%
1516 }%
1517 }
1518 \def\pytx@MakePygmentsInputPyg{
1519 \newcommand{\inputpygments}[3][]{%
1520 \begingroup
1521 \edef\pytx@type{PYG##2}%
1522 \edef\pytx@cmd{verbatim}%
1523 \pytx@SetContext
1524 \pytx@SetGroupVerb
1525 \def\pytx@argspprint{##1}%
1526 \edef\pytx@session{EXT:##3}%
1527 \pytx@CheckPygmentsInit{##2}%
1528 \xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
1529 \pytx@CheckCounter{\pytx@counter}%
1530 \pytx@WriteCodefileInfoExt
1531 \IfFileExists{##3}{}{\PackageWarning{\pytx@packagename}%
1532 {Input file <##3> does not exist}}%
1533 \setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
1534 \begingroup
1535 \pytx@FVSet
1536 \fvset{firstnumber=auto}%
1537 \pytx@ConfigPygments
1538 \ifcsname FV@SV@pytx@\pytx@type @\pytx@session @\pytx@group
1539 @\arabic{\pytx@counter}\endcsname
1540 \UseVerbatim[##1]{pytx@\pytx@type @\pytx@session @\pytx@group
1541 @\arabic{\pytx@counter}}%
1542 \else
1543 \InputIfFileExists{\pytx@outputdir/\pytx@type_##3_\pytx@group
1544 _\arabic{\pytx@counter}.pygtex}{}%
1545 {\textbf{??~\pytx@packagename~??}%
1546 \PackageWarning{\pytx@packagename}{Non-existent Pygments content}}%
1547 \fi
1548 \endgroup
1549 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%

136
1550 \stepcounter{\pytx@counter}%
1551 \endgroup
1552 }%
1553 }

10.11.4 Creating the Pygments commands and environment


We are almost ready to actually create the Pygments commands and environments.
First, though, we create some macros that allow the user to set fancyvrb settings,
Pygments options, and formatting of Pygments content.
\setpygmentsfv This macro allows fancyvrb settings to be specified for a Pygments lexer. It
takes the lexer name as the optional argument and the settings as the mandatory
argument. If no optional argument (lexer) is supplied, then it sets the document-
wide fancyvrb settings, and is in that case equivalent to \setpythontexfv.
1554 \newcommand{\setpygmentsfv}[2][]{%
1555 \Depythontex{cmd:setpygmentsfv:om:n}%
1556 \ifstrempty{#1}%
1557 {\gdef\pytx@fvsettings{#2}}%
1558 {\expandafter\gdef\csname pytx@fvsettings@PYG#1\endcsname{#2}}%
1559 }%

\setpygmentspygopt This macro allows the Pygments option to be set for a lexer. It takes the lexer
name as the first argument and the options as the second argument. If this macro
is used multiple times for a lexer, it will write the settings to the code file multiple
times. But pythontex.py will simply process all settings, and each subsequent
set of settings will overwrite any prior settings, so this is not a problem.
1560 \newcommand{\setpygmentspygopt}[2][]{%
1561 \Depythontex{cmd:setpygmentspygopt:om:n}%
1562 \ifstrempty{#1}%
1563 {\def\pytx@pygopt{#2}\pgfkeys{/PYTX/gopt/pygopt/.cd, #2}}%
1564 {\expandafter\gdef\csname pytx@pygopt@PYG#1\endcsname{#2}%
1565 \pgfkeys{/PYTX/popt/pygopt/.cd, name=#1, #2}}%
1566 }
1567 \@onlypreamble\setpygmentspygopt

\setpygmentsprettyprinter This macro parallels \setpythontexprettyprinter. Currently, it takes no op-


tional argument. Eventually, it may be desirable to allow an optional argument
that sets the pretty printer on a per-lexer basis.
1568 \newcommand{\setpygmentsprettyprinter}[1]{%
1569 \Depythontex{cmd:setpygmentsprettyprinter:m:n}%
1570 \ifstrequal{#1}{fancyvrb}{\boolfalse{pytx@opt@pygments}}%
1571 \ifstrequal{#1}{pygments}{\booltrue{pytx@opt@pygments}}%
1572 }
1573 \@onlypreamble\setpygmentsprettyprinter
1574 \xdef\pytx@macroformatter@PYG{auto}

\makepygmentsfv This macro creates the Pygments commands and environment using fancyvrb, as
a fallback when Pygments is unavailable or when the user desires maximum speed.

137
1575 \def\makepygmentsfv{%
1576 \pytx@MakePygmentsInlineFV
1577 \pytx@MakePygmentsEnvFV
1578 \pytx@MakePygmentsInputFV
1579 }%
1580 \@onlypreamble\makepygmentsfv

\makepygmentspyg This macro creates the Pygments commands and environment using Pygments.
We must set the bool pytx@usedpygments true so that pythontex.py knows that
Pygments content is present and must be highlighted.
1581 \def\makepygmentspyg{%
1582 \ifbool{pytx@opt@pyginline}%
1583 {\pytx@MakePygmentsInlinePyg}%
1584 {\pytx@MakePygmentsInlineFV}%
1585 \pytx@MakePygmentsEnvPyg
1586 \pytx@MakePygmentsInputPyg
1587 \booltrue{pytx@usedpygments}
1588 }%
1589 \@onlypreamble\makepygmentspyg

\makepygments This macro uses the two preceding macros to conditionally define the Pygments
commands and environments, based on the package Pygments settings.
1590 \def\makepygments{%
1591 \AtBeginDocument{%
1592 \ifdefstring{\pytx@macroformatter@PYG}{auto}%
1593 {\ifbool{pytx@opt@pygments}%
1594 {\makepygmentspyg}{\makepygmentsfv}}{}
1595 \ifdefstring{\pytx@macroformatter@PYG}{pygments}%
1596 {\makepygmentspyg}{}
1597 \ifdefstring{\pytx@macroformatter@PYG}{fancyvrb}%
1598 {\makepygmentsfv}{}
1599 }%
1600 }%
1601 \@onlypreamble\makepygments

We conclude by actually creating the Pygments commands and environments.


1602 \makepygments

10.12 Final cleanup


At the end of the document, we need to close files.
1603 \AfterEndDocument{%
1604 \immediate\closeout\pytx@codefile
1605 \ifbool{pytx@opt@depythontex}{\immediate\closeout\pytx@depyfile}{}%
1606 }

138
10.13 Compatibility with beta releases
The following code maintains compatibility with the beta releases when the pack-
age option beta is used. It will be retained for several releases before being
removed.
1607 \ifbool{pytx@opt@beta}{
1608
1609 % Revert changes in stdout and stderr modes
1610 \def\pytx@FetchStdoutfile[#1][#2]#3{%
1611 \IfFileExists{\pytx@outputdir/#3.stdout}{%
1612 \ifstrempty{#1}{\input{\pytx@outputdir/#3.stdout}}{}%
1613 \ifstrequal{#1}{raw}{\input{\pytx@outputdir/#3.stdout}}{}%
1614 \ifstrequal{#1}{verb}{\VerbatimInput[#2]{\pytx@outputdir/#3.stdout}}{}%
1615 \ifstrequal{#1}{inlineverb}{\BVerbatimInput[#2]{\pytx@outputdir/#3.stdout}}{}%
1616 \ifstrequal{#1}{v}{\BVerbatimInput[#2]{\pytx@outputdir/#3.stdout}}{}%
1617 \DepyFile{p:\pytx@outputdir/#3.stdout:mode=#1}%
1618 }%
1619 {\pytx@stdout@warntext
1620 \PackageWarning{\pytx@packagename}{Non-existent printed content}}%
1621 }
1622 \def\pytx@FetchStderrfile[#1][#2]#3{%
1623 \IfFileExists{\pytx@outputdir/#3.stderr}{%
1624 \ifstrequal{#1}{raw}{\input{\pytx@outputdir/#3.stderr}}{}%
1625 \ifstrempty{#1}{\VerbatimInput[#2]{\pytx@outputdir/#3.stderr}}{}%
1626 \ifstrequal{#1}{verb}{\VerbatimInput[#2]{\pytx@outputdir/#3.stderr}}{}%
1627 \ifstrequal{#1}{inlineverb}{\BVerbatimInput[#2]{\pytx@outputdir/#3.stderr}}{}%
1628 \ifstrequal{#1}{v}{\BVerbatimInput[#2]{\pytx@outputdir/#3.stderr}}{}%
1629 \DepyFile{p:\pytx@outputdir/#3.stderr:mode=#1}%
1630 }%
1631 {\textbf{??~\pytx@packagename~??}%
1632 \PackageWarning{\pytx@packagename}{Non-existent stderr content}}%
1633 }
1634
1635
1636 % Old verb environment
1637 \renewcommand{\pytx@MakeVerbFV}[1]{%
1638 \expandafter\newenvironment{#1verb}{%
1639 \VerbatimEnvironment
1640 \expandafter\let\expandafter\pytx@lexer\csname pytx@pyglexer@#1\endcsname
1641 \Depythontex{env:#1verb:oo|:c}%
1642 \DepyListing
1643 \xdef\pytx@type{#1}%
1644 \edef\pytx@cmd{verb}%
1645 \pytx@SetContext
1646 \pytx@SetGroupVerb
1647 \begingroup
1648 \obeylines
1649 \@ifnextchar[{\endgroup\pytx@BeginVerbEnvFV}{\endgroup\pytx@BeginVerbEnvFV[]}%
1650 }%

139
1651 {\end{Verbatim}%
1652 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
1653 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
1654 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1655 \stepcounter{\pytx@counter}%
1656 }%
1657 }
1658 \renewcommand{\pytx@MakePygEnv}[2]{%
1659 \expandafter\newenvironment{#1#2}{%
1660 \VerbatimEnvironment
1661 \xdef\pytx@type{#1}%
1662 \edef\pytx@cmd{#2}%
1663 \pytx@SetContext
1664 \ifstrequal{#2}{block}{\pytx@SetGroup}{}
1665 \ifstrequal{#2}{verb}{\pytx@SetGroupVerb}{}
1666 \begingroup
1667 \obeylines
1668 \@ifnextchar[{\endgroup\pytx@BeginEnvPyg}{\endgroup\pytx@BeginEnvPyg[]}%
1669 }%
1670 {\end{VerbatimOut}%
1671 \xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
1672 \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
1673 \pytx@FVSet
1674 \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
1675 \ifcsname FV@SV@\pytx@counter @\arabic{\pytx@counter}\endcsname
1676 \UseVerbatim{\pytx@counter @\arabic{\pytx@counter}}%
1677 \else
1678 \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.pygtex}{}%
1679 {\textbf{??~\pytx@packagename~??}%
1680 \PackageWarning{\pytx@packagename}{Non-existent Pygments content}}%
1681 \fi
1682 \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
1683 \setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
1684 \stepcounter{\pytx@counter}%
1685 }%
1686 }%
1687 \renewcommand{\pytx@MakeVerbPyg}[1]{\pytx@MakePygEnv{#1}{verb}}
1688
1689
1690 % Settings macros
1691 \def\setpythontexpyglexer#1#2{%
1692 \Depythontex{cmd:setpythontexpyglexer:mm:n}%
1693 \ifcsname pytx@pyglexer@#1\endcsname
1694 \expandafter\xdef\csname pytx@pyglexer@#1\endcsname{#2}%
1695 \else
1696 \PackageError{\pytx@packagename}%
1697 {Cannot modify a non-existent family}{}%
1698 \fi
1699 }%
1700 \renewcommand{\setpythontexpygopt}[2]{%

140
1701 \Depythontex{cmd:setpythontexpygopt:mm:n}%
1702 \ifcsname pytx@pygopt@#1\endcsname
1703 \expandafter\xdef\csname pytx@pygopt@#1\endcsname{#2}%
1704 \else
1705 \PackageError{\pytx@packagename}%
1706 {Cannot modify Pygments options for a non-existent family}{}%
1707 \fi
1708 }
1709 \def\setpygmentspygopt#1#2{%
1710 \Depythontex{cmd:setpygmentspygopt:mm:n}%
1711 \AtEndDocument{\immediate\write\pytx@codefile{%
1712 \pytx@delimsettings pygfamily=PYG#1,#1,%
1713 \string{#2\string}\pytx@delimchar}%
1714 }%
1715 }
1716
1717
1718 % Old formatters
1719 \def\setpythontexformatter#1#2{%
1720 \Depythontex{cmd:setpythontexformatter:mm:n}%
1721 \ifcsname pytx@macroformatter@#1\endcsname
1722 \ifbool{pytx@opt@depythontex}{}{%
1723 \expandafter\xdef\csname pytx@macroformatter@#1\endcsname{#2}}
1724 \else
1725 \PackageError{\pytx@packagename}%
1726 {Cannot modify a family that does not exist or does not allow formatter choices}%
1727 {Create the family with \string\makepythontexfamily}%
1728 \fi
1729 }
1730 \@onlypreamble\setpythontexformatter
1731 \def\setpygmentsformatter#1{%
1732 \Depythontex{cmd:setpygmentsformatter:m:n}%
1733 \ifbool{pytx@opt@depythontex}{}{\xdef\pytx@macroformatter@PYG{#1}}}
1734 \@onlypreamble\setpygmentsformatter
1735
1736
1737
1738
1739 }{} %End beta

Index
Numbers written in italic refer to the page where the corresponding entry is de-
scribed; numbers underlined refer to the code line of the definition; numbers in
roman refer to the code lines where the entry is used.

Symbols \@bsphack . . . . 376, 944 554, 565, 650,


657, 669, 680,
\= . . . . . . . . . . . . . . 201 \@empty 178, 335, 346,

141
691, 703, 716, 874, 904, 908, 1142, 1150–
717, 729, 740, 909, 973, 1027, 1154, 1178,
754, 768, 786, 1031–1033, 1190, 1206,
788, 951, 958, 1079, 1083– 1250, 1251,
1265, 1266, 1279 1085, 1335, 1253, 1435,
\@esphack . . . . 388, 950 1336, 1339, 1440, 1515,
\@gobble 175–177, 514, 1416, 1418, 1569, 1578, 1598
534, 540, 562–564 1421, 1527, \currfilebase . 334, 345
\@ifnextchar 409, 412, 1546, 1550, 1551 \currfilename . 335, 346
419, 440, 443, \AtBeginDocument . .
455, 470, 473, . . . . . . 10, 75, D
490, 493, 571, 245, 275, 293, \DeclareFloatingEnvironment
581, 837, 871, 406, 651, 952, . . . . . . 1233, 1245
901, 929, 970, 1157, 1237, 1466 \DefineVerbatimEnvironment
986, 1024, 1054, \AtEndDocument . . . . . . . . . . . . 224, 225
1076, 1291, 310, 516, 1121, \DepyFile . . . . 176,
1329, 1524, 1543 1140, 1252, 1586 400, 463, 535,
\@ifpackageloaded . 558, 564, 655,
. . . . . . . . 10, 279 B 956, 1036, 1088,
\@makeother 197, 569, \boolfalse . . 21, 45, 1389, 1492, 1504
576, 595, 615, 797 49, 53, 58, 62, \DepyFile@orig . . . .
\@nil . . . . . . . . . . . . 813 67, 73, 84, 89, . . . . 535, 539, 558
\@noligs . . . . . . . . . 948 115, 120, 131, \DepyListing 178, 541,
\@onlypreamble . . . . 135, 141, 145, 559, 565, 830,
. 233, 257, 266, 174, 189, 1201, 1445 864, 1017, 1069,
274, 809, 1173, \booltrue . . . . . 20, 1310, 1385, 1517
1185, 1197, 41, 44, 48, 52, \DepyListing@orig .
1214, 1236, 57, 61, 65, 71, . . . . 544, 553, 559
1442, 1448, 83, 87, 111, 114, \DepyMacro . . . 177,
1455, 1464, 119, 128, 130, 529, 557, 563,
1476, 1605, 1609 134, 137, 140, 663, 674, 1033, 1085
\@tempa . . . . . . . . . . 815 144, 173, 1120, \DepyMacro@orig . . .
\@tempb . . . . . . . . . . 816 1139, 1202, . . . . 529, 533, 557
\@undefined . . . . . . . 280 1234, 1446, 1462 \Depythontex . 51, 56,
\{ . . . 570, 577, 583, 798 \BUseVerbatim . 638, 673 175, 227, 235,
\} . . . . . . . 578, 584, 799 \BVerbatimInput . . . 264, 270, 356,
\^ 196, 580, 617, 800, 811 398, 461, 1490, 408, 418, 422,
1491, 1502, 1503 435, 439, 454,
469, 479, 489,
\␣ . . . . . . . . . . 579, 616 C 507, 556, 562,
\csname . . . 194, 210, 684, 710, 735,
A 218, 359, 364, 749, 763, 776,
\active . . . . . . 579, 387, 431, 447, 792, 829, 863,
580, 616, 617, 811 485, 497, 662, 963, 997, 1016,
\AfterEndDocument 1478 682, 683, 696, 1068, 1175,
\AfterEndPreamble . 289 708, 709, 722, 1187, 1199,
\aftergroup . . . . . . . 185 734, 748, 762, 1232, 1259,
\arabic 338, 349, 542, 828, 862, 1015, 1309, 1374,
604, 636, 638, 1067, 1122, 1432, 1438,
660, 671, 840, 1123, 1141, 1444, 1516,

142
1567, 1576, 381, 386, 431, \FV@GetLine . . . . . . . 820
1585, 1595, 1607 485, 548, 618, \FV@Line . . . . . . . . . 819
\Depythontex@orig . 682, 683, 696, \FV@ObeyTabsInit . . 628
. . . . 508, 513, 556 708, 709, 722, \FV@PreProcessLine . 820
\DepythontexOff . . . 555 734, 748, 762, \FV@ProcessLine . . .
\DepythontexOn . . . . 555 826, 828, 860, . . . . 380, 382, 946
\detokenize . . . . . . . 862, 892, 907, \FV@Scan . . . . . 384, 949
. 181, 600, 821, 942 961, 1013, 1015, \FV@SetupFont . . . . . 624
\directlua . . . 208, 216 1030, 1065, \FV@StepLineNo . . . . 382
\do . . 197, 569, 576, 1067, 1082, \FV@TheVerbatim . . .
595, 615, 797, 1221 1150–1154, . . . . 381–383, 387
\docsvlist . . . . . . 1229 1178, 1190, \FV@UseKeyValues . . 378
\dospecials 197, 569, 1206, 1229, \FVB@SaveVerbatim . 390
576, 595, 615, 797 1250, 1251, \FVB@VerbatimOut . .
1319, 1334, 935, 990, 1060, 1367
E 1435, 1440, \FVE@SaveVerbatim . 391
\endcsname . . . . . . . 1513, 1515, \FVE@VerbatimOut . .
. 191, 194, 210, 1534, 1549, 936, 991, 1061, 1368
218, 359, 364, 1569, 1578, 1598 \fvset . . . . 367, 370,
387, 426, 431, 907, 1030, 1082,
446, 447, 480, F 1319, 1334,
485, 496, 497, \FancyVerbDefineActive 1387, 1414, 1549
524, 636, 661, . . . . . . . . . . . 626
662, 672, 682, \FancyVerbFormatCom 627 G
683, 696, 708, \FancyVerbFormatLine \g@addto@macro . . . . 283
709, 722, 734, . . . . . . . . . . . 629 \gdef . 213, 221, 358,
748, 762, 828, \FancyVerbGetLine . 855 359, 381, 383,
862, 908, 1015, \fi 157, 191, 215, 223, 548, 812, 1151,
1031, 1067, 284, 432, 451, 1250, 1251,
1083, 1122, 486, 501, 510, 1434, 1435, 1440
1123, 1141, 524, 643, 667, \Ginput@path . . 280, 283
1142, 1150– 678, 816, 822, \global . . . . . . 375, 386
1154, 1177, 914, 1039, 1091, \graphicspath . . . . . 281
1178, 1189, 1182, 1194,
1190, 1204, 1211, 1246, H
1206, 1238, 1254, 1342, \hbox . . . . . . . . . . . . 629
1249–1251, 1424, 1556,
1253, 1335, 1573, 1582, 1603 I
1416, 1435, \frenchspacing . . . . 623 \IfBeginWith . . . . . 1146
1440, 1515, \FV@@@CheckEnd . . . . 816 \ifbool . . . . . . . 76,
1550, 1568, \FV@BadEndError . . . 816 180, 188, 189,
1569, 1577, \FV@BeginVBox . . . . . 622 290, 319, 324,
1578, 1596, 1598 \FV@CheckEnd . . . . . . 814 329, 405, 503,
\endlinechar . . 196, 614 \FV@CodeLineNo 375, 383 512, 515, 532,
\endpytx@SVMCR . . . . \FV@DefineWhiteSpace 538, 552, 653,
. . . . 202, 212, 220 . . . . . . . . . . . 625 657, 669, 680,
\everyeof . . . . . . . . 613 \FV@EndScanning . . . 817 954, 958, 1114,
\expandafter . . 181, \FV@EndVBox . . . . . . . 630 1133, 1159,
213, 221, 359, \FV@EnvironName . . . 815 1205, 1239,
363, 367, 370, \FV@FontScanPrep . . 947 1245, 1457,

143
1468, 1480, \immediate . . . 306, 994, 1015, 1060,
1482, 1597, 1608 311–329, 336, 1061, 1067,
\ifcsname . . . . 191, 347, 505, 509, 1264–1266,
426, 446, 480, 517, 519, 521, 1277–1279,
496, 524, 636, 523, 525, 530, 1367, 1368, 1515
661, 672, 908, 536, 542, 648, \long . . . . . 212, 220, 803
1031, 1083, 821, 942, 1121,
1177, 1189, 1140, 1252, M
1204, 1238, 1479, 1480, 1586 \makeatletter . . . . . 294
1249, 1335, \input 396, 397, 459, \makeatother . . . . . . 303
1415, 1550, 1487, 1488, 1499 \makepygments 1465, 1477
1568, 1577, 1596 \InputIfFileExists . \makepygmentsfv . . .
\ifcsstring . . . . . . . . . . . . . . . 291, . . 1450, 1469, 1473
. . . 1158, 1160, 295, 654, 911, \makepygmentspyg . .
1162, 1165, 955, 1035, 1087, . . 1456, 1469, 1471
1166, 1168, 1169 1338, 1420, 1553 \makepythontexfamily
\ifcurrfile . . . 334, 345 \inputlineno . . . . . . . . . 1097, 1210,
\ifdefstrequal . . . . 278 . . . . 342, 353, 510 1215–1220,
\ifdefstring 276, 365, \inputpygments . . . . 1222–1227, 1602
368, 907, 1030, . . . . . . 1372, 1397 \mathclose . . . . . . . 184
1082, 1319, \mathopen . . . . . . . . 184
1334, 1467, J \MessageBreak 1241, 1242
1470, 1472, 1549 \jobname . . . . . 259,
N
\IfFileExists . . . . . 306, 334, 345, 505
\newbool 17, 40, 60, 80,
395, 458, 1388,
110, 116, 127,
1409, 1486, 1498 L
136, 170, 288, 1230
\IfInteger . . . . . . . 152 \left . . . . . 181, 182, 184
\newcounter . . . 191, 372
\ifnum . . . . . . . . . . . 153 \let . . . 175–178, 182,
\newrobustcmd . 682,
\ifstrempty . . . 296, 183, 197, 277,
696, 708, 722,
357, 396, 460, 335, 346, 363,
734, 748, 762, 775
574, 847, 881, 386, 390, 391,
\newwrite . . . . 305, 504
921, 980, 1046, 507, 511, 513,
\next . . . . . 817, 820, 823
1176, 1188, 514, 533, 534,
\noexpand . . . . . . . . 613
1200, 1433, 539, 540, 545,
1439, 1487, 1500 553, 554, 556– O
\IfStrEq . . . . . 181, 299 559, 562–565, \obeylines 836, 870,
\ifstrequal . . 52, 53, 569, 576, 595, 900, 928, 969,
57, 58, 397–399, 615, 650, 657, 985, 1023, 1053,
459, 461, 462, 669, 680, 683, 1075, 1290,
589, 777, 778, 689–691, 701– 1302, 1328,
897, 898, 998, 703, 709, 715– 1352, 1523, 1542
999, 1201, 1202, 717, 727–729, \oldFancyVerbLine .
1222–1227, 740–742, 746, . . . . . . . . 545, 548
1445, 1446, 754–756, 760, \openout . . . . . 306, 505
1488–1491, 768–770, 774, \originalleft . 182, 184
1499, 1501– 786–788, 797, \originalright 183, 185
1503, 1539, 1540 817, 828, 855,
\IfSubStr . . . . 247, 251 862, 935, 936, P
\ifx . . . . . . 208, 216, 946–948, 951, \PackageError . . . . .
280, 510, 815, 816 958, 990, 991, . . . . 156, 158,

144
248, 252, 427, \pytx@BeginCodeEnv . \pytx@counter . 338,
481, 590, 778, . . . 970, 979, 1007 349, 602–604,
999, 1147, 1180, \pytx@BeginCodeEnv@i 608, 636, 638,
1192, 1208, . . . . . . . . 986, 988 660, 671, 840,
1571, 1580, 1600 \pytx@BeginConsEnvFV 843, 848–850,
\PackageWarning 34, . . 1024, 1045, 1076 874, 877, 882–
66, 68, 72, 74, \pytx@BeginConsEnvFV@i 884, 904, 908,
77, 88, 90, 403, . . . . . . 1054, 1056 909, 917, 922–
450, 466, 500, \pytx@BeginEnvPyg . 924, 973, 976,
642, 666, 677, . . . 901, 920, 1543 981, 982, 1010,
793, 913, 1038, \pytx@BeginEnvPyg@i 1027, 1031–
1090, 1240, . . . . . . . . 929, 931 1033, 1042,
1341, 1390, \pytx@BeginVerbEnvFV 1047–1049,
1409, 1423, . . . 871, 880, 1524 1079, 1083–
1495, 1507, 1555 \pytx@BEPygmentsFV . 1085, 1094,
\pgfkeys . . . . . . 12, . . . . . . 1291, 1298 1335, 1336,
14–16, 18–21, \pytx@BEPygmentsFV@i 1339, 1345,
23–33, 36–39, . . . . . . 1303, 1305 1360–1362,
42–49, 62–65, \pytx@BEPygmentsPyg 1381, 1382,
67, 69–71, 73, . . . . . . 1329, 1348 1393, 1406,
81–87, 89, 92– \pytx@BEPygmentsPyg@i 1407, 1416,
96, 98, 101– . . . . . . 1353, 1355 1418, 1421,
104, 106–109, \pytx@CheckCounter . 1427, 1527,
112–115, 117– . . . . 190, 603, 1530, 1546,
120, 122–126, 849, 851, 883, 1550, 1551, 1559
129–135, 138– 885, 923, 925, \pytx@currfile . . . .
145, 147, 149, 982, 1048, 1050, . 335, 341, 346, 352
151, 152, 161– 1314, 1361, \pytx@delim 308, 336, 347
165, 167–169, 1363, 1382, 1407 \pytx@delimchar . . .
171–174, 1097, 1149 \pytx@CheckPygmentsInit . 307, 336–342,
\printpythontex . . . 407 . . . 1248, 1267, 347–353, 509,
\ProcessPgfPackageOptions 1280, 1315, 510, 517–526, 1588
. . . . . . . . . . . 179 1365, 1380, 1405 \pytx@delimsettings
\pygment . . . . . . . . 1256 \pytx@cmd . . . . 338, . . . 309, 311, 1587
\pygments . . 1284, 1322 349, 686, 698,
\pytx@depyfile 503,
\pythontexcustomc . 712, 724, 737,
509, 517, 519,
. . . . 775, 795, 805 751, 765, 783,
521, 523, 525,
\pythontexcustomcode 832, 866, 895,
530, 536, 542, 1480
. . . . . . . . . . . 995 965, 1004, 1019,
\pytx@DepyListing@write
\pytx@arg . . . . 601, 618 1071, 1261,
. . . . . . . . 541, 547
\pytx@argdetok 600, 648 1274, 1311,
\pytx@argretok 611, 629 1358, 1376, \pytx@EnvAutoprint .
\pytx@argspprint . . 1400, 1519, 1537 . . . . . . . . 951, 974
. . . . 332, 340, \pytx@codefile 305, \pytx@families 11, 1229
351, 933, 1058, 311–329, 336, \pytx@FancyVerbGetLine
1300, 1350, 1403 347, 648, 821, . . . . . . . . 810, 855
\pytx@argsrun . . . . . 942, 1121, 1140, \pytx@FancyVerbLineTemp
. . . . 331, 339, 350 1252, 1479, 1586 . . . . . . . . . . . 372
\pytx@BeginBlockEnvFV \pytx@context . 226, \pytx@FetchStderrfile
. . . . . . . . 837, 846 339, 350, 784, 1005 457, 476, 497, 1497

145
\pytx@FetchStdoutfile \pytx@InlineMargBgroup 1362, 1363,
393, 415, 447, 1485 . . . . 582, 593, 598 1528, 1547, 1557
\pytx@FVB@SaveVerbatim \pytx@InlineMargOther \pytx@macroformatter@PYG
. . . . . . . . . . . 372 . . . . . . . . 585, 587 . . . 1449, 1467,
\pytx@FVB@VerbatimOut \pytx@InlineMargOtherGet 1470, 1472, 1608
. . . . . . . . 935, . . . . . . . . . . . 587 \pytx@MakeBlockFV .
943, 990, 1060, 1367 \pytx@InlineOarg . . . . . . . . . 825, 1110
\pytx@FVE@SaveVerbatim . . . . . . . . 571, 573 \pytx@MakeBlockPyg .
. . . . . . . . 385, 391 \pytx@InlinePrint . . . . . . . . 939, 1118
\pytx@FVE@VerbatimOut . . . . 607, 610, \pytx@MakeCodeFV . .
. . . . . . . . 936, 691, 703, 717, . . . 960, 994, 1156
950, 991, 1061, 1368 729, 742, 756, \pytx@MakeCodePyg . 994
\pytx@fvextfile 150, 326 770, 788, 1266, 1279 \pytx@MakeConsFV . .
\pytx@InlineSave . .
\pytx@fvopttmp . . . . . . . . . . 1012, 1129
. . . . 606, 610, \pytx@MakeConsoleFV
907, 932, 1030,
690, 702, 716, . . . . . . . . . . 1012
1057, 1082,
728, 741, 755, \pytx@MakeConsPyg .
1299, 1319,
769, 787, 1265, 1278 . . . . . . 1064, 1137
1334, 1349, 1549
\pytx@InlineSaveCode \pytx@MakeFamilyFV .
\pytx@FVSet 362, 621,
. . . . 646, 690, . . 1106, 1163, 1167
635, 856, 888,
702, 728, 741,
906, 1029, 1081, \pytx@MakeFamilyFVCons
755, 769, 787, 1278
1318, 1333, . . 1126, 1163, 1167
\pytx@InlineShow . .
1386, 1413, 1548 \pytx@MakeFamilyPyg
. . . . 605, 610,
\pytx@fvsettings . . . . 1113, 1161, 1170
689, 701, 715,
355, 368, 370, 1434 \pytx@MakeFamilyPygCons
727, 740, 754,
\pytx@fvsettings@@ . 768, 786, 1264, 1277
. . 1132, 1161, 1170
. . . . 363, 365, 367 \pytx@MakeInlinebFV
\pytx@InlineShowFV .
\pytx@group 234, 337, 610, 689, 715, 1264
. . 681, 1107, 1116
348, 602, 604, \pytx@InlineShowPyg \pytx@MakeInlinebPyg
660, 671, 785, 633, 701, 727, 1277 . . . . . . . 681, 1115
840, 848, 874, \pytx@jobname . 259, \pytx@MakeInlinecFV
882, 904, 922, 262, 291, 295, . . . . . . . 733, 1155
973, 981, 1006, 297, 300, 301, 520 \pytx@MakeInlineConsFV
1027, 1047, \pytx@lexer 507, 510, . . . . . . . 761, 1128
1079, 1313, 511, 683, 709, \pytx@MakeInlineConsPyg
1339, 1360, 828, 862, 1015, . . . . . . . 761, 1136
1381, 1406, 1067, 1258, \pytx@MakeInlinecPyg
1415, 1417, 1308, 1373, 1515 . . . . . . . . . . . 733
1420, 1527, 1546 \pytx@linecount . . . \pytx@MakeInlineFV .
\pytx@Inline . . 567, . . . . 841, 850, . . . . . . . 747, 1109
692, 704, 718, 851, 853, 875, \pytx@MakeInlinePyg
730, 743, 757, 884, 885, 887, . . . . . . . 747, 1117
771, 789, 1268, 1281 905, 915, 924, \pytx@MakeInlinevFV
\pytx@InlineAutoprint 925, 1028, 1040, . . . . 707, 1108,
. . . . . . . . 650, 742 1049, 1050, 1116, 1127, 1135
\pytx@InlineMacroprint 1080, 1092, \pytx@MakeInlinevPyg
. . . . 659, 680, 756 1294, 1313, . . 707, 1115, 1134
\pytx@InlineMacroprintFV 1314, 1317, \pytx@MakePygEnv 891,
. . . . . . . . 670, 770 1332, 1343, 939, 940, 1533, 1562

146
\pytx@MakePygmentsEnvFV 522, 654, 655, 1406, 1415,
. . . . . . 1284, 1452 911, 955, 956, 1417, 1527, 1546
\pytx@MakePygmentsEnvPyg 1035, 1036, \pytx@SetContext 226,
. . . . . . 1322, 1460 1087, 1088, 687, 699, 713,
\pytx@MakePygmentsInlineFV 1338, 1420, 725, 738, 752,
. . 1256, 1451, 1459 1486–1492, 766, 833, 867,
\pytx@MakePygmentsInlinePyg 1498–1504, 1553 896, 966, 1020,
. . . . . . 1256, 1458 \pytx@packagename . 1072, 1262,
\pytx@MakePygmentsInputFV . . . . . . . 1, 34, 1275, 1287,
. . . . . . 1371, 1453 66, 68, 72, 74, 1325, 1377,
\pytx@MakePygmentsInputPyg 77, 88, 90, 156, 1401, 1520, 1538
. . . . . . 1371, 1461 158, 248, 252, \pytx@SetCustomCode
\pytx@MakeVerbFV 859, 302, 403, 406, . . . . . . . . 801, 803
1111, 1130, 1512 427, 449, 450, \pytx@SetGroup . . . .
\pytx@MakeVerbPyg . 465, 466, 481, . 234, 688, 700,
. . . . . . . . 940, 499, 500, 590, 739, 753, 767,
1119, 1138, 1562 642, 666, 677, 834, 897, 967,
\pytx@mcr . . . . . . . . 778, 793, 912, 1021, 1073, 1539
. 660–663, 671–674 913, 999, 1037, \pytx@SetGroupCons . 234
\pytx@opt@autoprint 40 1038, 1089, \pytx@SetGroupVerb .
\pytx@opt@beta . . . . 17 1090, 1147, . 234, 714, 726,
\pytx@opt@depythontex 1180, 1192, 868, 898, 1263,
. . . . . . . . . . . 170 1208, 1240, 1276, 1288,
\pytx@opt@fixlr . . . 116 1242, 1340, 1326, 1378,
\pytx@opt@gobble . . 1341, 1390, 1402, 1521, 1540
. . . . . 13, 316, 526 1409, 1422,
\pytx@Stderr . . 470, 472
\pytx@opt@hashdependencies 1423, 1495,
\pytx@Stderr@i 473, 475
35, 35, 38, 39, 318 1506, 1507,
\pytx@stdfile . . . . .
\pytx@opt@keeptemps 1554, 1555,
. . . . 392, 415,
. . . . . . . . 121, 321 1571, 1580, 1600
431, 476, 485,
\pytx@opt@pyconbanner \pytx@packageversion
604, 654, 655,
. . . . . . . . 160, 327 . . . . . . 2, 312, 518
840, 874, 904,
\pytx@opt@pyconfilename \pytx@pyglexer 146,
911, 955, 956,
. . . . . . . . 166, 328 146, 147, 325, 1176
973, 1027, 1035,
\pytx@opt@pyconfuture \pytx@pygopt . . . . . .
1036, 1079,
. . . . . . . . 105, 323 148, 325, 1188, 1439
1087, 1088,
\pytx@opt@pyfuture . \pytx@SaveVerbatim . 224
1527, 1546, 1553
. . . . . . . . 100, 322 \pytx@session . 337,
\pytx@Stdout . . . . . .
\pytx@opt@pyginline 136 348, 574, 602,
. . . . 409, 411, 419
\pytx@opt@pygments . 127 604, 660, 671,
\pytx@opt@rerun 22, 840, 847, 848, \pytx@Stdout@i 412, 414
22, 25, 28–33, 317 874, 881, 882, \pytx@stdout@warntext
\pytx@opt@stderr . . 80 904, 921, 922, 393, 402, 406, 1494
\pytx@opt@stderrfilename 973, 980, 981, \pytx@SVMCR . . . . . . . 193
. . . . . . . . 91, 320 1027, 1046, \pytx@SVMCR@i . 198,
\pytx@opt@stdout . . 60 1047, 1079, 211, 212, 219, 220
\pytx@opt@upquote . 110 1312, 1313, \pytx@tmp . . . . 194,
\pytx@outputdir 262, 1339, 1359, 210, 213, 218, 221
313, 395–400, 1360, 1379, \pytx@tmp@console .
458–463, 520, 1381, 1404, . . . . . . 1103, 1154

147
\pytx@tmp@pprinter . R \setpythontexautoprint
. . . . . . 1100, 1150 \relax . 26, 153, 216, . . . . . . . . . . . . 50
\pytx@tmp@pyglexer . 507, 510, 511, \setpythontexautostdout
. . . . . . 1101, 1152 614, 800, 947, 948 . . . . . . . . . . . . 50
\pytx@tmp@pygopt . . \renewcommand . 184, \setpythontexcontext
. . . . . . 1102, 1153 185, 1221, 1512, . . . . . . . . . . . 226
\pytx@type . . . 336, 1533, 1562, 1575 \setpythontexcustomcode
347, 364, 602, \RequirePackage . . . . . . . . . . . . . . 791
604, 660, 671, . . . . . . . 3–10, 188 \setpythontexformatter
685, 697, 711, \restartpythontexsession . . . . . . 1594, 1605
723, 736, 750, . . . . 234, 257, 258 \setpythontexfv . . . 355
764, 782, 831, \right . . . . . . . 183, 185 \setpythontexlistingenv
840, 848, 865, . . . . . . 1230, 1243
874, 882, 894, S \setpythontexoutputdir
904, 922, 964, \saveprintpythontex 421 . . . . . . . . . . . 262
973, 981, 1003, \savestderrpythontex \setpythontexprettyprinter
1018, 1027, . . . . . . . . . . . 478 . . . . . . . . . . 1198
1047, 1070, \savestdoutpythontex \setpythontexpyglexer
1079, 1260, . . . . . . . . . . . 421 . . . . . . 1174, 1566
1273, 1307, \setpythontexpygopt
\savestdoutpythontex@i
1313, 1339, . . . . . . 1186, 1575
. . . . 423, 425, 436
1357, 1360, \setpythontexworkingdir
\SaveVerbatim@Name .
1375, 1381, . . . . . . . . . . . 267
. . . . . . . . 379, 387
1399, 1406,
\scantokens . . . . . . . 618 \space . . . . . . . 302,
1415, 1417,
1420, 1518, \setcounter 374, 389, 794, 795, 1242, 1243
637, 639, 841, \stderrpythontex . . 468
1527, 1536, 1546
842, 852, 853, \stdoutpythontex . . 407
\pytx@undefined . . . 208
875, 876, 886, \stepcounter . . . . . .
\pytx@usedpygments . 288
887, 905, 915, . 608, 843, 877,
\pytx@UseStderr 490, 492 916, 934, 975, 917, 976, 1010,
\pytx@UseStderr@i . 989, 1009, 1028, 1042, 1094,
. . . . . . . . 493, 495 1040, 1041, 1345, 1393,
\pytx@UseStdout . . . 1059, 1080, 1427, 1530, 1559
. . . . 440, 442, 455 1092, 1093, \string . . . . . . 249,
\pytx@UseStdout@i . 1294, 1295, 250, 253, 254,
. . . . . . . . 443, 445 1316, 1317, 307–309, 779,
\pytx@Verbatim . . . . 224 1332, 1343, 794, 795, 1210,
\pytx@workingdir . . 1344, 1366, 1243, 1588, 1602
. . . . 267, 267, 1383, 1392, \StrSubstitute 259–
271, 276–278, 314 1411, 1426, 261, 574, 847,
\pytx@workingdirset 1528, 1529, 881, 921, 980, 1046
. . . . 268, 272, 315 1547, 1557, 1558
\pytx@WriteCodefileInfo \setpygmentsformatter T
. 331, 647, 854, . . . . . . 1606, 1609 \textbf 406, 449, 465,
926, 983, 1051, 1364 \setpygmentsfv . . . 1431 499, 641, 665,
\pytx@WriteCodefileInfoExt\setpygmentsprettyprinter 676, 912, 1037,
. . . . . . . 331, 1408 . . . . . . . . . . 1443 1089, 1340,
\pytx@WriteDetok . . \setpygmentspygopt . 1422, 1506, 1554
. . . . . . . . 941, 946 . . . . . . 1437, 1584 \the . . . . . . 342, 353, 510

148
\theFancyVerbLine . 1316, 1317, X
. 545, 546, 548, 549 1332, 1343, \xdef . . . . . 602, 604,
\typeout . . 297, 300–302 1344, 1366, 685, 697, 711,
1383, 1392, 723, 736, 750,
U 1411, 1426, 764, 782, 831,
\useprintpythontex . 438 1528, 1529, 840, 848, 865,
\usestderrpythontex 488 1547, 1557, 1558 874, 882, 894,
\usestdoutpythontex 438 \VerbatimEnvironment 904, 922, 964,
\UseVerbatim . . . . . . . 827, 861, 893, 973, 981, 1003,
909, 1032, 1084, 962, 996, 1014, 1018, 1027,
1336, 1417, 1551 1066, 1286, 1047, 1070,
1324, 1514, 1535 1079, 1150,
V \VerbatimInput 399, 1152–1154,
\value . . . . 374, 389, 460, 462, 1389, 1178, 1190,
637, 639, 841, 1489, 1500, 1501 1206, 1360,
842, 852, 853, 1381, 1406,
875, 876, 886, W 1449, 1518,
887, 905, 915, \write . . . . 311–329, 1527, 1536,
916, 934, 975, 336, 347, 509, 1546, 1569,
989, 1009, 1028, 517, 519, 521, 1578, 1598, 1608
1040, 1041, 523, 525, 530,
1059, 1080, 536, 542, 648,
1092, 1093, 821, 942, 1121, Z
1294, 1295, 1140, 1252, 1586 \z@ . . . . . . . . . . . . . 375

149

You might also like