diff --git a/NEWS.rst b/NEWS.rst
index 58fa279..69057dd 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -7,6 +7,120 @@ Version History
===============
+v0.19 (2026/02/15)
+------------------
+
+* Fixed backslash escapes in docstrings and regexes for syntax compatibility
+ with Python 3.11+.
+
+* ``js`` now works as a command family for JavaScript (#197).
+
+* Python console commands and environments are now compatible with Python
+ 3.14 (#229).
+
+* Fixed a bug that could cause non-Windows operating systems to attempt to
+ invoke a nonexistent batch file when the executable associated with a
+ language is not found (#225).
+
+* Replaced doctype ``tex`` with ``texminted`` for ``Weave.jl`` (#219).
+
+* Fixed a bug that resulted in uncaught exceptions when ``\inputpygments``
+ was used with files that do not exist (#64).
+
+* Fixed a bug in tracking the number of Pygments errors (#206).
+
+* Improved error messages (#207, #209). Improved documentation for
+ ``--error-exit-code`` (#208).
+
+* Several minor improvements to documentation.
+
+
+
+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).
+
+* ``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)
------------------
diff --git a/README.rst b/README.rst
index d129756..2854032 100644
--- a/README.rst
+++ b/README.rst
@@ -1,52 +1,87 @@
-|flattr|_
-
===============================================
PythonTeX
===============================================
------------------------------------------------
- Fast Access to Python from within LaTeX
------------------------------------------------
+------------------------------------------------------------------------------------------
+ Execute Python and other code in LaTeX documents, or typeset it with syntax highlighting
+------------------------------------------------------------------------------------------
-:Author: Geoffrey Poore
+PythonTeX executes code in LaTeX documents and allows the output to be
+included in the original document. It supports Python as well as Bash,
+JavaScript, Julia, Octave, Perl, R, Raku (Perl 6), Ruby, Rust, and SageMath.
+PythonTeX also provides syntax highlighting for typeset code in LaTeX
+documents via the `Pygments `_ syntax highlighter.
-:Version: 0.15
+See ``pythontex_quickstart.pdf`` to get started, and ``pythontex_gallery.pdf``
+for examples of what is possible with PythonTeX. PythonTeX is included in TeX
+Live and MiKTeX and may be installed via the package manager. See
+``pythontex.pdf`` for detailed installation instructions if you want to
+install the current development version, or just use the installation script
+for TeX Live and MiKTeX.
-:License: LPPL_ (LaTeX code) and `BSD 3-Clause`_ (Python code)
+The ``depythontex`` utility creates a copy of a PythonTeX document in which
+all code has been replaced by its output. This plain LaTeX document is
+more suitable for journal submission, sharing, or conversion to other document
+formats. See ``pythontex_gallery.html`` and the accompanying conversion
+script for an example of a PythonTeX document that was converted to HTML via
+``depythontex`` and `Pandoc `_.
-.. _LPPL: http://www.latex-project.org/lppl.txt
-.. _`BSD 3-Clause`: http://www.opensource.org/licenses/BSD-3-Clause
+Example
+=======
+* LaTeX document ``doc.tex``:
+ .. code-block:: latex
-Overview
-========
+ \documentclass{article}
-PythonTeX provides fast, user-friendly access to Python from within LaTeX. It
-allows Python code entered within a LaTeX document to be executed, and the
-results to be included within the original document. It also provides syntax
-highlighting for code within LaTeX documents via the Pygments syntax
-highlighter.
+ \usepackage{pythontex}
-PythonTeX also provides support for Ruby, Julia, Octave, Sage, Bash, and Rust.
-Support for additional languages is coming soon.
+ \newcommand{\pymultiply}[2]{\py{#1*#2}}
-See ``pythontex_quickstart.pdf`` to get started, and ``pythontex_gallery.pdf``
-for examples of what is possible with PythonTeX. PythonTeX is included in
-TeX Live and MiKTeX and may be installed via the package manager. See
-``pythontex.pdf`` for detailed installation instructions if you want to
-install the current development version, or use the installation script for
-TeX Live and MiKTeX.
+ \begin{document}
-The ``depythontex`` utility creates a copy of a PythonTeX document in which
-all Python code has been replaced by its output. This plain LaTeX document is
-more suitable for journal submission, sharing, or conversion to other document
-formats. See ``pythontex_gallery.html`` and the accompanying conversion
-script for an example of a PythonTeX document that was converted to HTML via
-``depythontex`` and `Pandoc `_.
+ \begin{pycode}
+ print("Python says ``Hello!''")
+ \end{pycode}
+
+ $8 \times 256 = \pymultiply{8}{256}$
+
+ \end{document}
+* Compiling under Windows:
+
+ ::
+
+ pdflatex -interaction=nonstopmode doc.tex
+ pythontex doc.tex
+ pdflatex -interaction=nonstopmode doc.tex
+
+
+* Compiling under other operating systems:
+
+ ::
+
+ pdflatex -interaction=nonstopmode doc.tex
+ pythontex.py doc.tex
+ pdflatex -interaction=nonstopmode doc.tex
+
+
+
+* Output:
+
+ ::
+
+ Python says “Hello!”
+ 8 × 256 = 2048
+
+Notice that there is a three-step compile process. This is what makes
+possible commands like ``\pymultiply`` that use Python or other languages
+internally. You may want to configure your LaTeX editor with a shortcut for
+running ``pythontex`` or ``pythontex.py``, or configure your LaTeX build
+system to run ``pythontex`` or ``pythontex.py``.
Citing PythonTeX
@@ -54,12 +89,34 @@ 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 `_ (doi:10.1088/1749-4699/8/1/014010).
-You may also cite the paper in the
+`Computational Science & Discovery `_
+(doi:10.1088/1749-4699/8/1/014010). You may also cite the paper in the
`2013 SciPy proceedings `_.
+Development status
+==================
+
+Since 2020, I am increasingly creating new teaching materials with Markdown
+and HTML instead of PythonTeX and LaTeX. I have limited time for developing
+open-source software that I do not use frequently myself. There should be
+occasional releases to keep PythonTeX running, but no major changes or
+significant new features are anticipated.
+
+I have been developing `Codebraid `_ since 2019,
+partially to have a PythonTeX equivalent for Markdown but also in the hope
+that it could eventually be integrated with LaTeX as a PythonTeX replacement.
+As part of `minted `_ version 3, I created
+new software for passing data between LaTeX and Python. I cannot make any
+guarantees, but I hope that this will eventually make it possible to create a
+new LaTeX package based on Codebraid, with significant PythonTeX compatibility.
+
-.. |flattr| image:: https://api.flattr.com/button/flattr-badge-large.png
+License
+=======
-.. _flattr: https://flattr.com/submit/auto?user_id=gpoore&url=https://github.com/gpoore/pythontex&title=pythontex&category=software
+LPPL_ for LaTeX code and `BSD 3-Clause`_ for Python code.
+
+.. _LPPL: http://www.latex-project.org/lppl.txt
+
+.. _`BSD 3-Clause`: http://www.opensource.org/licenses/BSD-3-Clause
diff --git a/pythontex/README b/pythontex/README
index 84ae1cf..14c2e82 100644
--- a/pythontex/README
+++ b/pythontex/README
@@ -3,15 +3,16 @@
===================================================================
:Author: Geoffrey Poore
-:Version: 0.15 (2016/07/21)
+:Version: 0.19 (2026/02/15)
:License: LPPL v1.3 or later (LaTeX code) and BSD 3-Clause (Python code)
:Development: https://github.com/gpoore/pythontex
:Requirements: Python 2.7 or 3.2+; Pygments
-The PythonTeX package allows you to enter Python code within a LaTeX
-document, execute the code, and access its output in the original document.
-It also supports the Ruby, Julia, Octave, Sage, Bash, and Rust languages.
+The PythonTeX package allows you to enter Python code within a LaTeX document,
+execute the code, and access its output in the original document. It also
+supports the Ruby, Julia, Octave, Sage, Bash, Rust, R, Perl, Perl 6, and
+JavaScript languages.
PythonTeX provides fast, user-friendly access to Python from within LaTeX.
Python code is only executed when it has been modified, or when it meets
diff --git a/pythontex/depythontex.py b/pythontex/depythontex.py
index 30256c6..f015c15 100644
--- a/pythontex/depythontex.py
+++ b/pythontex/depythontex.py
@@ -9,7 +9,7 @@
launch depythontex2.py or depythontex3.py directly. The version of Python
does not matter for depythontex, since no code is executed.
-Copyright (c) 2013-2016, Geoffrey M. Poore
+Copyright (c) 2013-2026, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
diff --git a/pythontex/depythontex2.py b/pythontex/depythontex2.py
index 0600fb4..6e5a7f8 100644
--- a/pythontex/depythontex2.py
+++ b/pythontex/depythontex2.py
@@ -47,7 +47,7 @@
typeset with a different package.
-Copyright (c) 2013-2016, Geoffrey M. Poore
+Copyright (c) 2013-2026, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
@@ -86,7 +86,7 @@
# Script parameters
# Version
-__version__ = '0.16dev'
+__version__ = '0.19'
# Functions and parameters for customizing the script output
@@ -760,7 +760,7 @@ def replace_print_env(name, arglist, linenum,
if not os.path.isfile(depytxfile_name):
print('* DePythonTeX error:')
print(' Could not find DePythonTeX auxiliary file "' + depytxfile_name + '"')
- print(' Use package option depythontex to creat it')
+ print(' Use package option depythontex to create it')
sys.exit(1)
diff --git a/pythontex/depythontex3.py b/pythontex/depythontex3.py
index b80699b..e19f102 100644
--- a/pythontex/depythontex3.py
+++ b/pythontex/depythontex3.py
@@ -29,7 +29,7 @@
facilitate customization. Most of the key substitutions are performed by a
few functions defined near the beginning of the script, so if you need custom
substitutions, you should begin there. By default, all typeset code is
-wrapped in `\verb` commands and verbatim environments, since these have the
+wrapped in `\\verb` commands and verbatim environments, since these have the
greatest generality. However, the command-line option --listing allows code
to be typeset with the fancyvrb, listings, minted, or PythonTeX packages
instead.
@@ -47,7 +47,7 @@
typeset with a different package.
-Copyright (c) 2013-2016, Geoffrey M. Poore
+Copyright (c) 2013-2026, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
@@ -86,7 +86,7 @@
# Script parameters
# Version
-__version__ = '0.16dev'
+__version__ = '0.19'
# Functions and parameters for customizing the script output
@@ -121,7 +121,7 @@ def replace_code_cmd(name, arglist, linenum, code_replacement,
Usually, code from a command is also typeset with a command. This
function primarily deals with that case. In cases where code from a
- command is typeset with an environment (for example, `\inputpygments`),
+ command is typeset with an environment (for example, `\\inputpygments`),
this function performs some preprocessing and then uses
replace_code_env() to do the real work. This approach prevents the two
functions from unnecessarily duplicating each other, while still giving
@@ -161,7 +161,7 @@ def replace_code_cmd(name, arglist, linenum, code_replacement,
# Make sure the introduction of an environment where a command was
# previously won't produce errors with following content; make sure
# that any following content is on a separate line
- if bool(match('[ \t]*\S', after)):
+ if bool(match(r'[ \t]*\S', after)):
after = '\n' + after
# Rather than duplicating much of replace_code_env(), just use it
return replace_code_env(name, arglist, linenum, code_replacement,
@@ -333,7 +333,7 @@ def replace_print_cmd(name, arglist, linenum,
break
print_replacement = r'\verb' + delim + print_replacement + delim
elif print_replacement_mode == 'verbatim':
- if bool(match('\s*?\n', after)):
+ if bool(match(r'\s*?\n', after)):
# Usually, we would end the verbatim environment with a newline.
# This is fine if there is content in `after` before the next
# newline---in fact, it's desirable, because the verbatim package
@@ -405,11 +405,11 @@ def replace_print_cmd(name, arglist, linenum,
# the `\input` content.
print_replacement = print_replacement.rstrip(' \t\n')
after = sub(r'^\\unskip\s+', '', after)
- elif bool(match('\S', after)):
+ elif bool(match(r'\S', after)):
# If the next character is not whitespace, we can just leave
# the `\n`, and it will yield a space.
pass
- elif bool(match('\s*$', after)):
+ elif bool(match(r'\s*$', after)):
# If the rest of the current line, and the next line, are
# whitespace, we will get the correct spacing without needing
# `\space{}`. We could leave `\n`, but it would be
@@ -421,14 +421,14 @@ def replace_print_cmd(name, arglist, linenum,
# it's at the end of an environment, and thus is needed to
# protect the following content
print_replacement += '\\space{}'
- after = sub('^\s+', '', after)
+ after = sub(r'^\s+', '', after)
forced_double_space_list.append((name, linenum))
else:
- if bool(match('\s+\S', after)):
+ if bool(match(r'\s+\S', after)):
# If the following line starts with whitespace, replace it
# with a newline, to protect in the event that the printed
# content ended with an end-of-environment command
- after = sub('^\s+', '\n', after)
+ after = sub(r'^\s+', '\n', after)
# Issue warnings, if warranted
# Warn about `\endinput`
if (r'\endinput' in print_replacement and
@@ -505,7 +505,7 @@ def replace_print_env(name, arglist, linenum,
#### The inlineverb and verb modes should work, but haven't been tested
since there are currently no environments that use them; they are only
- used by `\printpythontex`, which is a command.
+ used by `\\printpythontex`, which is a command.
'''
if print_replacement_mode == 'verb':
if print_replacement.count('\n') > 1:
@@ -519,17 +519,17 @@ def replace_print_env(name, arglist, linenum,
if delim not in print_replacement:
break
print_replacement = r'\verb' + delim + print_replacement + delim
- if not bool(match('[ \t]+\S', after)):
+ if not bool(match(r'[ \t]+\S', after)):
# If there is text on the same line as the end of the
# environment, we're fine (this is unusual). Otherwise,
# we need to toss the newline at the end of the environment
# and gobble leading spaces. Leading spaces need to be
# gobbled because previously they were at the beginning of a
# line, where they would have been discarded.
- if not bool(match('\s*$', after)):
- after = sub('^\s*?\n\s*', '', after)
+ if not bool(match(r'\s*$', after)):
+ after = sub(r'^\s*?\n\s*', '', after)
elif print_replacement_mode == 'verbatim':
- if bool(match('\s*?\n', after)):
+ if bool(match(r'\s*?\n', after)):
# Usually, we would end the verbatim environment with a newline.
# This is fine if there is content in `after` before the next
# newline---in fact, it's desirable, because the verbatim package
@@ -570,15 +570,15 @@ def replace_print_env(name, arglist, linenum,
# printed content. Later, we issue a warning in case it appears
# anywhere else.
print_replacement = print_replacement.rsplit(r'\endinput', 1)[0]
- if not bool(match('[ \t]+\S', after)):
+ if not bool(match(r'[ \t]+\S', after)):
# If there is text on the same line as the end of the
# environment, we're fine (this is unusual). Otherwise,
# we need to toss the newline at the end of the environment
# and gobble leading spaces. Leading spaces need to be
# gobbled because previously they were at the beginning of a
# line, where they would have been discarded.
- if not bool(match('\s*$', after)):
- after = sub('^\s*?\n\s*', '', after)
+ if not bool(match(r'\s*$', after)):
+ after = sub(r'^\s*?\n\s*', '', after)
elif (print_replacement.endswith('%\n') and
not print_replacement.endswith('\\%\n') and
not print_replacement.endswith('\\string%\n')):
@@ -590,15 +590,15 @@ def replace_print_env(name, arglist, linenum,
# warning if there is reason to think that a percent character
# was active in the last line.
print_replacement = print_replacement.rsplit(r'%', 1)[0]
- if not bool(match('[ \t]+\S', after)):
+ if not bool(match(r'[ \t]+\S', after)):
# If there is text on the same line as the end of the
# environment, we're fine (this is unusual). Otherwise,
# we need to toss the newline at the end of the environment
# and gobble leading spaces. Leading spaces need to be
# gobbled because previously they were at the beginning of a
# line, where they would have been discarded.
- if not bool(match('\s*$', after)):
- after = sub('^\s*?\n\s*', '', after)
+ if not bool(match(r'\s*$', after)):
+ after = sub(r'^\s*?\n\s*', '', after)
else:
# By default, LaTeX strips newlines and adds a space at the end
# of each line of content that is brought in by `\input`. This
@@ -611,13 +611,13 @@ def replace_print_env(name, arglist, linenum,
# `\unskip`
print_replacement = print_replacement.rstrip(' \t\n')
after = sub(r'^\s*\\unskip\s+', '', after)
- elif bool(match('[ \t]+\S', after)):
+ elif bool(match(r'[ \t]+\S', after)):
# If the next character after the end of the environment is
# not whitespace (usually not allowed), we can just leave
# the `\n` in printed content, and it will yield a space.
# So we need do nothing. But if there is text on that line
# we need `\space{}`.
- after = sub('^\s+', '\\space', after)
+ after = sub(r'^\s+', '\\space', after)
forced_double_space_list.append((name, linenum))
else:
# If the line at the end of the environment is blank,
@@ -760,7 +760,7 @@ def replace_print_env(name, arglist, linenum,
if not os.path.isfile(depytxfile_name):
print('* DePythonTeX error:')
print(' Could not find DePythonTeX auxiliary file "' + depytxfile_name + '"')
- print(' Use package option depythontex to creat it')
+ print(' Use package option depythontex to create it')
sys.exit(1)
@@ -1080,7 +1080,7 @@ def replace_print_env(name, arglist, linenum,
else:
if obeylines:
# Take into account possible whitespace before arg
- if bool(match('[ \t]*\[', after)):
+ if bool(match(r'[ \t]*\[', after)):
after = after.split('[', 1)[1]
while ']' not in after:
texlinenum += 1
@@ -1094,11 +1094,11 @@ def replace_print_env(name, arglist, linenum,
after = sub('^[ \t]*', '', after)
else:
# Allow peeking ahead a line for the argument
- if bool(match('\s*$', after)) and after.count('\n') < 2:
+ if bool(match(r'\s*$', after)) and after.count('\n') < 2:
texlinenum += 1
after += tex[texlinenum]
# Take into account possible whitespace before arg
- if bool(match('\s*\[', after)):
+ if bool(match(r'\s*\[', after)):
after = after.split('[', 1)[1]
while ']' not in after:
texlinenum += 1
@@ -1108,11 +1108,11 @@ def replace_print_env(name, arglist, linenum,
optarg = None
# Account for eating whitespace afterward, if arg not found
if argindex == len(depy_args) - 1:
- if bool(match('\s*$', after)) and after.count('\n') < 2:
+ if bool(match(r'\s*$', after)) and after.count('\n') < 2:
texlinenum += 1
after += tex[texlinenum]
- if not bool(match('\s*$', after)):
- after = sub('^\s*', '', after)
+ if not bool(match(r'\s*$', after)):
+ after = sub(r'^\s*', '', after)
arglist.append(optarg)
elif arg == 'm':
# Account for possible line breaks or spaces before arg
@@ -1121,7 +1121,7 @@ def replace_print_env(name, arglist, linenum,
else:
if obeylines:
# Account for possible leading whitespace
- if bool(match('[ \t\f\v]*\{', after)):
+ if bool(match(r'[ \t\f\v]*\{', after)):
after = after.split('{', 1)[1]
else:
print('* DePythonTeX error:')
@@ -1129,10 +1129,10 @@ def replace_print_env(name, arglist, linenum,
sys.exit(1)
else:
# Peek ahead a line if needed
- if bool(match('\s*$', after)) and after.count('\n') < 2:
+ if bool(match(r'\s*$', after)) and after.count('\n') < 2:
texlinenum += 1
after += tex[texlinenum]
- if bool(match('\s*\{', after)):
+ if bool(match(r'\s*\{', after)):
after = after.split('{', 1)[1]
else:
print('* DePythonTeX error:')
@@ -1338,7 +1338,7 @@ def replace_print_env(name, arglist, linenum,
after = tex[texlinenum]
break
after = after.split(end_environment, 1)[1]
- if bool(match('\s*\n', after)):
+ if bool(match(r'\s*\n', after)):
# If the line following `after` is whitespace, it should
# be stripped, since most environments throw away
# anything after the end of the environment
@@ -1389,7 +1389,7 @@ def replace_print_env(name, arglist, linenum,
# Take care of graphicspath
if args.graphicspath and settings['graphicx']:
for n, line in enumerate(texout):
- if '\\graphicspath' in line and not bool(match('\s*%', line)):
+ if '\\graphicspath' in line and not bool(match(r'\s*%', line)):
texout[n] = line.replace('\\graphicspath{', '\\graphicspath{{' + settings['outputdir'] +'/}')
break
elif line.startswith(r'\begin{document}'):
diff --git a/pythontex/pythontex.dtx b/pythontex/pythontex.dtx
index 2c71c2b..be9c287 100644
--- a/pythontex/pythontex.dtx
+++ b/pythontex/pythontex.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2012-2017 by Geoffrey M. Poore
+% Copyright (C) 2012-2026 by Geoffrey M. Poore
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -26,7 +26,7 @@
%\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%\ProvidesPackage{pythontex}
%<*package>
- [2017/05/25 v0.16dev execute and typeset Python code and other languages]
+ [2026/02/15 v0.19 execute and typeset Python code and other languages]
%
%
%<*driver>
@@ -35,11 +35,27 @@
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
+\usepackage{microtype}
+
\usepackage{textcomp}
\usepackage[svgnames]{xcolor}
\usepackage{environ}
\usepackage{enumitem}
\usepackage{fvextra}
+% The typesetting for macrocode doesn't use \@noligs, which upquote modifies.
+% So apply the upquote fix to \verbatim@nolig@list as well, which is in macrocode.
+\begingroup
+\catcode`'=\active
+\catcode``=\active
+\g@addto@macro\verbatim@nolig@list{%
+ \let'\textquotesingle
+ \let`\textasciigrave
+ \ifx\encodingdefault\upquote@OTone
+ \ifx\ttdefault\upquote@cmtt
+ \def'{\char13 }%
+ \def`{\char18 }%
+ \fi\fi}
+\endgroup
\usepackage{pythontex}
\usepackage{hyperref}
\hypersetup{
@@ -94,6 +110,11 @@
\AtBeginDocument{\let|\pipe@active@verbatim}
\endgroup
+\renewenvironment{verbatim}%
+ {\VerbatimEnvironment\begin{Verbatim}[gobble=1]}%
+ {\end{Verbatim}}
+
+
\def\MacroFont{%
\fontencoding\encodingdefault%
\fontfamily\ttdefault%
@@ -103,13 +124,56 @@
\def\PrintMacroName#1{{\strut\MacroFont\color{DarkGreen}\footnotesize\string #1\ }}
-\def\PrintDescribeMacro#1{\strut\MacroFont\textcolor{DarkGreen}{\string #1\ }}
+\def\PrintDescribeMacro#1{\parbox[t]{1in}{\strut\MacroFont\textcolor{DarkGreen}{\string #1\ }}}
\let\PrintDescribeEnv\PrintDescribeMacro
%\let\PrintMacroName\PrintDescribeMacro
\let\PrintEnvName\PrintDescribeEnv
\def\theCodelineNo{\textcolor{DarkGreen}{\sffamily\scriptsize{\arabic{CodelineNo}}}}
+
+\renewenvironment{macro}{\macro@custom@arg}{}
+\def\macro@custom@arg{%
+ \begingroup\makeatletter\macro@custom@arg@i}
+\def\macro@custom@arg@i#1{%
+ \makeatother
+ \par\noindent
+ \ifstrempty{#1}%
+ {~\par}%
+ {\ttfamily\color{DarkGreen}\hspace*{-0.5in}%
+ \macro@custom@arg@split#1,\FV@Sentinel\par}%
+ \endgroup}
+\def\macro@custom@arg@spacegobble#1{#1}
+\def\macro@custom@arg@split#1,#2\FV@Sentinel{%
+ \expandafter\string\macro@custom@arg@spacegobble#1%
+ \if\relax\detokenize{#2}\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {}{\\\hspace*{-0.5in}\macro@custom@arg@split#2\FV@Sentinel}}
+
+\renewenvironment{environment}{\env@custom@arg}{}
+\def\env@custom@arg{%
+ \begingroup\makeatletter\env@custom@arg@i}
+\def\env@custom@arg@i#1{%
+ \makeatother
+ \ifstrempty{#1}%
+ {~\par}%
+ {\ttfamily\color{DarkGreen}\hspace*{-0.5in}%
+ \env@custom@arg@split#1,\FV@Sentinel\par}%
+ \endgroup}
+\def\env@custom@arg@spacegobble#1{#1}
+\def\env@custom@arg@split#1,#2\FV@Sentinel{%
+ \env@custom@arg@spacegobble#1{\textrm{ \textit{(env.)}}}%
+ \if\relax\detokenize{#2}\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {}{\\\hspace*{-0.5in}\env@custom@arg@split#2\FV@Sentinel}}
+
+
\let\orig@footnote\footnote
\renewcommand{\footnote}{%
\begingroup
@@ -122,6 +186,7 @@
\endgroup
\orig@footnote{\scantokens{#1}}}
+
%\EnableCrossrefs
%\CodelineIndex
%\RecordChanges
@@ -134,7 +199,7 @@
%
% \fi
%
-% \CheckSum{3182}
+% \CheckSum{3289}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -153,11 +218,57 @@
% Right brace \} Tilde \~}
%
%
-
-% \begin{changelog}{v0.16}{2017/06/??}
+%
+% \begin{changelog}{v0.19}{2026/02/15}
+% \begin{itemize}
+% \item Fixed backslash escapes in docstrings and regexes for syntax compatibility with Python 3.11+.
+% \item \texttt{js} now works as a command family for JavaScript (\#197).
+% \item Python console commands and environments are now compatible with Python 3.14 (\#229).
+% \item Fixed a bug that could cause non-Windows operating systems to attempt to invoke a nonexistent batch file when the executable associated with a language is not found (\#225).
+% \item Replaced doctype \texttt{tex} with \texttt{texminted} for \texttt{Weave.jl} (\#219).
+% \item Fixed a bug that resulted in uncaught exceptions when \Verb{\inputpygments} was used with files that do not exist (\#64).
+% \item Fixed a bug in tracking the number of Pygments errors (\#206).
+% \item Improved error messages (\#207, \#209). Improved documentation for \Verb{--error-exit-code} (\#208).
+% \item Several minor improvements to documentation.
+% \end{itemize}
+% \end{changelog}
+%
+%
+% \begin{changelog}{v0.18}{2021/06/06}
+% \begin{itemize}
+% \item \texttt{\string\inputpygments} now checks inputted files for modification, so that typeset code will correctly update when the source is changed (\#162).
+% \item Julia now uses project flag ``\texttt{-{}-project=@.}'' (\#157, \#158).
+% \item Fixed bug in processing Pygments options (\texttt{pygopt}) when a key is used without a value (\#181).
+% \item Some error handling for Windows was incompatible with other operating systems: replaced checks for \texttt{WindowsError} with checks for \texttt{OSError} (\#177).
+% \item Rust support is now compatible with document and working directory paths that contain spaces (\#167).
+% \end{itemize}
+% \end{changelog}
+%
+%
+% \begin{changelog}{v0.17}{2019/09/22}
+% \begin{itemize}
+% \item Pygments syntax highlighting for the Python console (\texttt{pycon} lexer) now uses the \texttt{python3} option, and the default Python lexer is now \texttt{python3} (\#156).
+% \item Added support for JavaScript (\#147; thanks to Nathan Carter).
+% \item Updated Julia support for Julia versions 0.6 (\#107), and 0.7 and 1.0 (\#126, \#130).
+% \item There are now meaningful error messages for the Julia console when Weave.jl is not installed or raises errors (\#131).
+% \item \texttt{pythontexcustomcode} and \texttt{\string\pythontexcustomc} now set \texttt{pytex.context} (\#65).
+% \item Added support for R. The \texttt{R} family of commands and environments (\texttt{\string\R}, \texttt{\string\Rc}, \texttt{Rcode}, ...) executes code as a script. There is currently no utilities class or equivalent. The \texttt{Rcon} family (\texttt{Rconsole}) executes code to emulate an interactive R session (\#121).
+% \item \texttt{fancyvrb} settings from \texttt{\string\setpythontexfv} and console environments now work with Julia and R consoles.
+% \item \texttt{pythontexcustomcode} now works with \texttt{juliacon}. There are now proper \texttt{juliaconcode} and \texttt{Rconcode} environments that execute code but typeset nothing, to parallel \texttt{pyconcode} (\#134).
+% \item Added support for Perl with the \texttt{perl} and \texttt{pl} families of commands and environments. There is currently no utilities class or equivalent.
+% \item Added support for Perl 6 with the \texttt{perlsix} and \texttt{psix} families of commands and environments (\#104). There is currently no utilities class or equivalent.
+% \item Updated Rust support by using \texttt{dyn} with traits in utilities object.
+% \item Under Windows, capitalization of script paths in \texttt{stderr} is now preserved.
+% \item Fixed a bug that prevented the \texttt{sub} environment from working with \texttt{depythontex} (\#155).
+% \item Fixed a bug in checking mtime of dependencies to see if they have been modified while \texttt{pythontex} is running. The check failed for dependencies that do not exist or were deleted before \texttt{pythontex} can read them (\#136).
+% \end{itemize}
+% \end{changelog}
+%
+%
+% \begin{changelog}{v0.16}{2017/07/20}
% \begin{itemize}
% \item Added preliminary console support for Julia (\#98).
-% \item Fixed Python console compatibility with Python 3.6 by setting the \texttt{code} module's new \texttt{exitmsg} argument to suppress the exit message (\#100).
+% \item Fixed Python console compatibility with Python 3.6 by setting the \texttt{code} module's new \texttt{exitmsg} argument to suppress the exit message (\#100).
% \item Improved Rust support, including tracking of created files and dependencies (\#91).
% \end{itemize}
% \end{changelog}
@@ -305,7 +416,7 @@
% \begin{changelog}{v0.11}{2013/04/21}
% \begin{itemize}
% \item As the first non-beta release, this version adds several features and introduces several changes. You should read these release notes carefully, since some changes are not backwards-compatible. Changes are based on a thorough 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.
-% \item Added the \texttt{pythontex.py} and \texttt{depythontex.py} wrapper scripts. When run, these detect the current version of Python and import the correct PythonTeX code. It is still possible to run \texttt{pythontex*.py} and \texttt{depythontex*.py} directly, but the new wrapper scripts should be used instead for simplicity. There is now only a single \texttt{pythontex\_utils.py}, which works with both Python 2 and Python 3.
+% \item Added the \texttt{pythontex.py} and \texttt{depythontex.py} wrapper scripts. When run, these detect the current version of Python and import the correct PythonTeX code. It is still possible to run \texttt{pythontex*.py} and \texttt{depythontex*.py} directly, but the new wrapper scripts should be used instead for simplicity. There is now only a single \texttt{pythontex\_utils.py}, which works with both Python 2 and Python 3.
% \item Added the \texttt{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.
% \item Backward-incompatible changes (require the \texttt{beta} option to restore old behavior)
% \begin{itemize}
@@ -429,6 +540,7 @@
%
% \maketitle
%
+%
% \begin{abstract}
% \pytex\ 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, \pytex\ provides syntax highlighting for many programming languages via the Pygments syntax highlighter.
%
@@ -436,14 +548,25 @@
%
% Because documents that use \pytex\ mix \LaTeX\ and Python code, they are less suitable than plain \LaTeX\ documents for journal submission, sharing, and conversion to other formats. \pytex\ includes a |depythontex| utility that creates a copy of a document in which all \pytex\ content is replaced by its output.
%
-% While Python is the focus of \pytex, 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, and Octave.
+% While Python is the focus of \pytex, 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.
% \end{abstract}
%
%
-% \section*{\centering Warning}
-%
+%
+% \begingroup
+% \small
+%
+% \subsection*{\centering Development Status}
+% Since 2020, I am increasingly creating new teaching materials with Markdown and HTML instead of \pytex\ and \LaTeX. I have limited time for developing open-source software that I do not use frequently myself. There should be occasional releases to keep \pytex\ running, but no major changes or significant new features are anticipated.
+%
+%
+%
+% \subsection*{\centering Warning}
+%
% \pytex\ makes possible some pretty amazing things. But that power brings with it a certain risk and responsibility. Compiling a document that uses \pytex\ involves executing Python code, and potentially other programs, on your computer. You should only compile \pytex\ documents from sources you trust. \pytex\ comes with NO WARRANTY.\footnote{All \LaTeX\ code is licensed under the \href{http://www.latex-project.org/lppl.txt}{\LaTeX\ Project Public License (LPPL)} and all Python code is licensed under the \href{http://www.opensource.org/licenses/BSD-3-Clause}{BSD 3-Clause License}.} The copyright holder and any additional authors will not be liable for any damages.
%
+% \endgroup
+%
%
% \pagebreak
% \tableofcontents
@@ -469,7 +592,7 @@
% \item[Compiling without executing]\hfill\\ 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. Unexecuted code should be invisible or be replaced by placeholders. Sage\TeX\ and Sympy\TeX\ have implemented such a separation of compiling and executing. In contrast, Lua\TeX\ and Perl\TeX\ execute all the code at each compilation---but that is appropriate given their goal of simplifying macro programming.
% \item[Error messages]\hfill\\ 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, Sage\TeX\ 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.
% \item[Syntax highlighting]\hfill\\ 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 updated since 2007, which makes it a less ideal solution in some circumstances. |minted| uses the Python-based syntax highlighter Pygments to perform highlighting. 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.\footnote{The author recently started maintaining the \texttt{minted} package. In the near future, \texttt{minted} will inherit \pytex's speed enhancements, and the two packages will become more compatible.}
-% \item[Printing]\hfill\\ It would be nice for the |print| statement/function,\footnote{In Python, |print| was a statement until Python 3, when it became a function. The function form is available via import from |\textunderscore\textunderscore future\textunderscore\textunderscore| in Python 2.6 and later.} 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.
+% \item[Printing]\hfill\\ It would be nice for the |print| statement/function,\footnote{In Python, |print| was a statement until Python 3, when it became a function. The function form is available via import from |__future__| in Python 2.6 and later.} 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.
% \item[Pure code]\hfill\\ \LaTeX\ has a number of special characters (|#| \texttt{\$} |%| |&| |~| |_| |^| |\| |{| |}|), which complicates the entry of non-\LaTeX\ code since these same characters are common in many languages. Sage\TeX\ and Sympy\TeX\ 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. Lua\TeX\ 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!''\footnote{\url{http://wiki.contextgarden.net/Programming_in_LuaTeX}} In the case of Lua\TeX, though, there is the \href{http://www.ctan.org/pkg/luacode}{\texttt{luacode}} package that allows for pure Lua.
%
% This language hybridization is not terribly difficult to work around in the Sage\TeX\ and Sympy\TeX\ cases, and is actually a Lua\TeX\ feature in many contexts. But if we are going to create a system for general-purpose access to a non-\LaTeX\ language, we need \textbf{all} valid code to work correctly in \textbf{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.
@@ -490,7 +613,7 @@
%
% \section{Citing \pytex}
% \label{sec:citing}
-%
+%
% If you use \pytex\ in your writing and research, please consider citing it in any resulting publications. The best and most recent paper is in \textit{Computational Science \& Discovery}.
% \begin{itemize}
% \item ``PythonTeX: reproducible documents with LaTeX, Python, and more,'' Geoffrey M Poore. \textit{Computational Science \& Discovery} 8 (2015) 014010. Full text and Bib\TeX\ entry available at \url{http://stacks.iop.org/1749-4699/8/i=1/a=014010}.
@@ -501,11 +624,11 @@
% \section{Installing and running}
% \label{sec:installing-and-running}
%
-% \subsection{Installing \pytex}
+% \subsection{Installing \pytex}
%
% \pytex\ requires a \TeX\ installation. It has been tested with \href{http://www.tug.org/texlive/}{\TeX\ Live} and \href{http://miktex.org/}{MiK\TeX}, 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 \href{http://www.ctan.org/pkg/mdframed}{\texttt{mdframed}} package is recommended for enclosing typeset code in boxes with fancy borders and/or background colors; \href{http://www.ctan.org/pkg/tcolorbox}{\texttt{tcolorbox}} and \href{http://www.ctan.org/pkg/framed}{\texttt{framed}} are alternatives.
%
-% \pytex\ also requires a \href{http://www.python.org/}{Python} installation. Python 2.7 is recommended for the greatest compatibility with scientific tools, although many scientific packages are now compatible with Python 3. \pytex\ is compatible with Python 2.7 and 3.2+. The Python package \href{http://pygments.org/}{Pygments} must be installed for syntax highlighting to function. \pytex\ 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: \href{http://numpy.scipy.org/}{NumPy}, \href{http://www.scipy.org/}{SciPy}, \href{http://matplotlib.sourceforge.net/}{matplotlib}, and \href{http://sympy.org}{SymPy}. When using \pytex\ with LyX, be aware that LyX may try to use its own version of Python; you may need to reconfigure LyX.
+% \pytex\ also requires a \href{http://www.python.org/}{Python} installation. A recent Python 3 installation is recommended, but there is still support for Python 2.7. The Python package \href{http://pygments.org/}{Pygments} must be installed for syntax highlighting to function. \pytex\ 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: \href{http://numpy.scipy.org/}{NumPy}, \href{http://www.scipy.org/}{SciPy}, \href{http://matplotlib.sourceforge.net/}{matplotlib}, and \href{http://sympy.org}{SymPy}. When using \pytex\ with LyX, be aware that LyX may try to use its own version of Python; you may need to reconfigure LyX.
%
% \pytex\ 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.
%
@@ -523,9 +646,9 @@
% \item |pythontex_quickstart.tex| and |pythontex_quickstart.pdf|
% \item Optional installation script |pythontex_install.py| for \TeX\ Live and MiKTeX
% \item Optional batch file |pythontex.bat| for use in launching |pythontex.py| under Windows
-% \item Optional conversion script |pythontex_2to3.py| for converting \pytex\ code written for Python 2 into a form compatible with Python 3
+% \item |pythontex_2to3.py| was originally included with \pytex, but it is no longer needed. Originally, the core of \pytex\ was developed in |pythontex2.py| for Python 2.7, and then |pythontex_2to3.py| was used convert |pythontex2.py| into |pythontex3.py| for Python 3.2+. Currently, all development is in |pythontex3.py|. |pythontex2.py| is retained for backward compatibility, but in most cases it is no longer updated to maintain parity with |pythontex3.py|. Similarly, |depythontex3.py| is now developed directly, separately from |depythontex2.py|, and |depythontex2.py| typically doesn't receive updates.
% \end{itemize}
-% 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.\footnote{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.}
+% 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 can typically run |pythontex.py|, which imports the correct code based on the Python version.
%
% If you want the absolute latest version of \pytex, you should install it manually from \href{https://github.com/gpoore/pythontex}{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.
%
@@ -533,7 +656,7 @@
%
% \textbf{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. \textbf{If you are installing \pytex\ on a machine with multiple versions of \TeX, make sure you install \pytex\ for the correct version.} For example, under Ubuntu Linux, you will probably need the following command if you have installed the latest version of \TeX\ Live manually:
% \begin{verbatim}
-% sudo env PATH=$PATH python pythontex_install.py
+%sudo env PATH=$PATH python pythontex_install.py
% \end{verbatim}
%
% 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.
@@ -581,14 +704,14 @@
% \end{itemize}
% For an example of a \pytex\ 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 \textbf{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|.\footnote{See \url{http://tex.stackexchange.com/questions/58732/how-to-output-a-tabulation-into-a-file} for more on tabs with XeTeX.}
+% If you use XeLaTeX, and your non-\LaTeX\ code contains tabs, you \textbf{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|.\footnote{See \url{http://tex.stackexchange.com/questions/58732/how-to-output-a-tabulation-into-a-file} for more on tabs with XeTeX.}
%
% |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.\footnote{Thus, \pytex\ works happily with .tex, .ltx, .dtx, and any other extension.} The filename may include the path to the file; you do not have to be in the same directory as the file to run \pytex. If you are configuring your editor to run \pytex\ automatically via a shortcut, you may want to wrap the filename in double quotes |"| to allow for space characters.\footnote{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.} For example, under Windows with \TeX\ Live and Python 2.7 we would create the wrapper |pythontex.exe|. Then we could run \pytex\ on a file \meta{file~name}.tex using the command |pythontex.exe "|\meta{file~name}|"|.
%
% |pythontex.py| accepts the following optional command-line arguments. Some of these options duplicate package-level options, so that settings may be configured 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|.
% \begin{itemize}
% \item |--encoding=|\meta{encoding} This sets the file encoding. Any encoding supported by Python's \href{http://docs.python.org/library/codecs.html}{\texttt{codecs}} module may be used. The encoding should match that of the \LaTeX\ document. If an encoding is not specified, \pytex\ uses UTF-8. If support for characters beyond ASCII is required, then additional \LaTeX\ packages are required; see the discussion of \TeX\ engines above.
-% \item |--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 \pytex\ 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, \href{http://www.tug.org/texworks/}{TeXworks} automatically hides the output of external programs unless there are errors.
+% \item |--error-exit-code={true,false}| By default, when |pythontex.py| finishes running, it returns an exit code of 1 if there were any errors (for example, in code execution), and an exit code of 0 otherwise. This may be useful when \pytex\ 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, \href{http://www.tug.org/texworks/}{TeXworks} automatically hides the output of external programs unless there are errors.
%
% In some contexts, returning a nonzero exit code can be redundant. For example, with the \href{http://winshell.de/}{WinShell} editor under Windows with TeX Live, the complete output of \pytex\ 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.
% \item |--runall=[{true,false}]| This causes \textbf{all} code to be executed, regardless of modification or |rerun| settings. It is useful when code has not been modified, but a dependency such as a library or external data has changed. Note that the \pytex\ utilities class also provides a mechanism for automatically re-executing code that depends on external files when those external files are modified.
@@ -660,12 +783,12 @@
%
% \DescribeMacro{usefamily=\meta{basename}/\marg{basename1,~basename2,~...}}
%
-% By default, only the |py|, |sympy|, and |pylab| families of commands and environments are defined, to prevent possible package conflicts.\footnote{For example, a \texttt{\string\ruby} command for Ruby code, and the \texttt{\string\ruby} command defined by the Ruby package in the \href{http://www.ctan.org/pkg/cjk}{CJK package}.} This option defines preconfigured families for other available languages. It takes either a single language base name, or a list of comma-separated names enclosed in curly braces. Currently, the Ruby families |rb| and |ruby|, the Julia families |jl| and |julia|, and the Octave family |octave| may be created.
+% By default, only the |py|, |sympy|, and |pylab| families of commands and environments are defined, to prevent possible package conflicts.\footnote{For example, a \texttt{\string\ruby} command for Ruby code, and the \texttt{\string\ruby} command defined by the Ruby package in the \href{http://www.ctan.org/pkg/cjk}{CJK package}.} This option defines preconfigured families for other available languages. It takes either a single language 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 \Cref{sec:other-languages}.
%
%
% \DescribeMacro{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 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, indentation 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()|.\footnote{It would be possible to do the dedent on the \LaTeX\ side, as is done manually in the \texttt{fancyvrb} and \texttt{listings} packages with the \texttt{gobble} option and is done automatically in the \texttt{lstautogobble} package. This is not done for stability and security reasons. \texttt{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 \textbf{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 \textbf{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.} Keep in mind that Python's dedent will not work correctly with mixed tabs and spaces.
%
@@ -678,7 +801,7 @@
%
% 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 \textbf{only} be used with old \pytex\ documents that require it.
%
-% You are encouraged to update old documents, since this compatility option will only be provided for a few releases.
+% You are encouraged to update old documents, since this compatibility option will only be provided for a few releases.
%
%
% \DescribeMacro{runall=\meta{none}/true/false default:false \meta{none}=true}
@@ -687,7 +810,7 @@
%
% A command-line equivalent |--runall| exists for |pythontex.py|. The package option |rerun=always| is essentially equivelent.
%
-%
+%
% \DescribeMacro{rerun=never/modified/errors/warnings/always default:errors}
%
% This option sets the threshold for re-executing code. By default, \pytex\ 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.
@@ -704,9 +827,13 @@
%
% \DescribeMacro{autoprint=\meta{none}/true/false default:true \meta{none}=true}
%
+% ~
+%
+% ~
+%
% \DescribeMacro{autostdout=\meta{none}/true/false default:true \meta{none}=true}
%
-% Whenever a |print| command/statement is used, the printed content will automatically be included in the document, unless the code doing the printing is being typeset.\footnote{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 \pytex, 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 only be used in the preamble with great care.} In that case, the printed content must be included using the |\printpythontex| or |\stdoutpythontex| commands.
+% Whenever a |print| command/statement is used, the printed content will automatically be included in the document, unless the code doing the printing is being typeset.\footnote{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 |\printpythontex|. This approach is also helpful for writing packages using \pytex, 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 |\printpythontex| is used and |autoprint| is enabled). Printing should only be used in the preamble with great care.} In that case, the printed content must be included using the |\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.
%
@@ -749,17 +876,17 @@
%
% 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, \expandafter|\textquotesingle| 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 \texttt{\'}.
+% 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 \texttt{\'}.
%
% \DescribeMacro{fixlr=\meta{none}/true/false default:false \meta{none}=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 \href{http://www.ctan.org/pkg/mleftright}{\texttt{mleftright}} package
%
-% \DescribeMacro{keeptemps=\meta{none}/all/code/none default:none \meta{none}=all}
+% \DescribeMacro{keeptemps=\meta{none}/all/code/none default:none \meta{none}=all}
%
% When \pytex\ 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 \pytex\ knows very little about that; it only applies to files that \pytex\ automatically creates by itself.
%
-% \DescribeMacro{prettyprinter=pygments/fancyvrb default:pygments}
+% \DescribeMacro{prettyprinter=pygments/fancyvrb default:pygments}
%
% This allows the user to determine at the document level whether code is typeset using Pygments or |fancyvrb|.
%
@@ -771,31 +898,31 @@
% This determines whether inline content is pretty printed. If it is turned off, inline content is typeset with |fancyvrb|.
%
%
-% \DescribeMacro{pygments=\meta{none}/true/false default:true \meta{none}=true}
+% \DescribeMacro{pygments=\meta{none}/true/false default:true \meta{none}=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|.
%
%
% \DescribeMacro{pyginline=\meta{none}/true/false default:true \meta{none}=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|.
%
%
-% \DescribeMacro{pyglexer=\meta{pygments~lexer} default:\meta{none}}
+% \DescribeMacro{pyglexer=\meta{pygments~lexer} default:\meta{none}}
%
% This allows a Pygments lexer to be set at the document level. In general, this option should \textbf{not} be used. It overrides the default lexer for all commands and environments, for both \pytex\ 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.
%
%
-% \DescribeMacro{pygopt=\marg{pygments~options} default:\meta{none}}
+% \DescribeMacro{pygopt=\marg{pygments~options} default:\meta{none}}
%
% This allows Pygments options to be set at the document level. The options must be enclosed in curly braces |{}|. Currently, three options may be passed in this manner: |style=|\meta{style~name}, 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 example, |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.
%
%
-% \DescribeMacro{fvextfile=\meta{none}/\meta{integer} default:$\infty$ \meta{none}=25}
+% \DescribeMacro{fvextfile=\meta{none}/\meta{integer} default:$\infty$ \meta{none}=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 \pytex\ directory). The \meta{integer} 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.
%
@@ -809,11 +936,11 @@
%
% 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:
% \begin{verbatim}
-% >>> z = 1 + 34 +
-% File "", line 1
-% z = 1 + 34 +
-% ^
-% SyntaxError: invalid syntax
+%>>> z = 1 + 34 +
+% File "", line 1
+% z = 1 + 34 +
+% ^
+%SyntaxError: invalid syntax
% \end{verbatim}
% The |stdin| option replaces || with ||, as it appears in a standard Python interactive session. The |console| option uses || instead, which is the default setting for the Python |code| module used by \pytex\ to create Python console environments.
%
@@ -836,7 +963,7 @@
% \end{quote}
%
%
-% \subsubsection{Inline commands}
+% \subsubsection{Inline commands}
% \pytxtodo{Fix spacing around |\DescribeMacro|!}
% 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 \textbf{not} inside other macros. If an inline command is used within another macro, the code will be read by the external macro before \pytex\ 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.
%
@@ -844,11 +971,11 @@
%
% 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 \meta{code} to Python, and Python returns a string representation of \meta{code}.\pytxtodo{Link to details about Python built-ins} \meta{opening~delim} and \meta{closing~delim} 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 \meta{code} if they are paired. Thus, |\py{1+1}| sends the code |1+1| to Python, Python evaluates the string representation 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|.
+% The |\py| command sends \meta{code} to Python, and Python returns a string representation of \meta{code}.\pytxtodo{Link to details about Python built-ins} \meta{opening~delim} and \meta{closing~delim} 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 \meta{code} if they are paired. Thus, |\py{1+1}| sends the code |1+1| to Python, Python evaluates the string representation 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 \textbf{not} allowed using |\py|. For example, |\py{a=1}| is \textbf{not} valid. This is because assignment cannot be converted to a string.\footnote{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 \meta{code}, 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.}
+% Assignment is \textbf{not} allowed using |\py|. For example, |\py{a=1}| is \textbf{not} valid. This is because assignment cannot be converted to a string.\footnote{It would be simple to allow any code within |\py|, including assignment, by using a |try/except| statement. In this way, the functionality of |\py| and |\pyc| could be merged. While that would be simpler to use, it also has serious drawbacks. If |\py| is not exclusively used to typeset string representations of \meta{code}, 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.}
%
-% 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 other families share a single external file. Thus, use of |\py| minimizes the creation of external files, which is a key design goal for \pytex.\footnote{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 returned 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 families 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 \texttt{\string\scantokens}.} 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.
+% 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 other families share a single external file. Thus, use of |\py| minimizes the creation of external files, which is a key design goal for \pytex.\footnote{For |\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 returned content means that an external file need not be created for each use of |\py|. Rather, all macros created by |\py| and equivalent commands from other families 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 \texttt{\string\scantokens}.} 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.
%
% \DescribeMacro{\pyc\oarg{session}\meta{opening~delim}\meta{code}\meta{closing~delim}}
%
@@ -856,7 +983,9 @@
%
% \DescribeMacro{\pys\oarg{session}\meta{opening~delim}\meta{code}\meta{closing~delim}}
%
-% This command performs variable and expression substitution, or string interpolation, on \meta{code}. Fields of the form |!{|\meta{expr}|}| in \meta{code} are replaced with the evaluated and printed output of \meta{expr}. 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 \meta{code} and performs substitutions before the result is passed to \LaTeX, substitution fields may be anywhere.
+% This command performs variable and expression substitution, or string interpolation, on \meta{code}. Fields of the form |!{|\meta{expr}|}| in \meta{code} are replaced with the evaluated and printed output of \meta{expr}. Then the modified \meta{code} 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 \meta{code} and performs substitutions \emph{before} the result is passed to \LaTeX, substitution fields may be anywhere, including within parts of \meta{code} that will become \LaTeX\ comments.
%
% Literal exclamation points |!| in \meta{code} 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.
%
@@ -891,7 +1020,7 @@
%
% \DescribeEnv{pysub~\oarg{session}\oarg{fancyvrb~settings}}
%
-% This environment performs variable and expression substitution, or string interpolation, on the enclosed code. Fields of the form |!{|\meta{expr}|}| in \meta{code} are replaced with the evaluated and printed output of \meta{expr}. See the description of the |\pys| command for details about substitution field syntax.
+% This environment performs variable and expression substitution, or string interpolation, on the enclosed code. Fields of the form |!{|\meta{expr}|}| in \meta{code} are replaced with the evaluated and printed output of \meta{expr}. See the description of the |\pys| command for details about substitution and the substitution field syntax.
%
%
%
@@ -1012,7 +1141,7 @@
% The utilities class provides an interface for determining how Python objects are converted into strings in commands such as |\py|. The |pytex.set_formatter(|\meta{formatter}|)| method is used to set the conversion. Two formatters are provided:
% \begin{itemize}
% \item |'str'| converts Python objects to a string, using the |str()| function under 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 encoding issues should be taken care of automatically by the utilities class.)
-% \item |'sympy_latex'| uses SymPy's |LatexPrinter| class to return context-sensitive \LaTeX\ representations of SymPy objects. Separate |LatexPrinter| settings 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 subscripts). Settings are created via |pytex.set_sympy_latex(|\meta{context}|,|\meta{settings}|)|. For example, |pytex.set_sympy_latex('display', mul_symbol='times')| sets multiplication to use a multiplication symbol $\times$, but only when math is in displaystyle.\footnote{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.} See the \href{http://docs.sympy.org/dev/modules/printing.html}{SymPy documentation} for a list of possible settings for the |LatexPrinter| class.
+% \item |'sympy_latex'| uses SymPy's |LatexPrinter| class to return context-sensitive \LaTeX\ representations of SymPy objects. Separate |LatexPrinter| settings 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 subscripts). Settings are created via |pytex.set_sympy_latex(|\meta{context}|,|\meta{settings}|)|. For example, |pytex.set_sympy_latex('display', mul_symbol='times')| sets multiplication to use a multiplication symbol $\times$, but only when math is in displaystyle.\footnote{Internally, the |'sympy_latex'| formatter uses the |\mathchoice| macro to return multiple representations of a SymPy object, if needed by the current settings. Then |\mathchoice| typesets the correct representation, based on context.} See the \href{http://docs.sympy.org/dev/modules/printing.html}{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.
%
@@ -1024,7 +1153,7 @@
% The utilities class also provides methods for tracking dependencies and created files.
% \begin{itemize}
% \item |pytex.add_dependencies(|\meta{dependencies}|)| This adds \meta{dependencies} 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.
-%
+%
% \meta{dependencies} 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 \pytex\ runs. The first session might not be executed during the \pytex\ 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 dependency was updated (remember, sessions run in parallel). \pytex\ 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.
@@ -1151,7 +1280,7 @@
%
%
% \DescribeMacro{\saveprintpythontex\marg{name}}
-%
+%
% \DescribeMacro{\savestdoutpythontex\marg{name}}
%
% \DescribeMacro{\useprintpythontex\oarg{verbatim~options}\oarg{fancyvrb~options}\marg{name}}
@@ -1190,14 +1319,14 @@
% ~\par
%
% This allows autoprint behavior to be modified at various points within the document. The package-level |autoprint| option is also available for setting autoprint at the document level, but it is overridden by |\setpythontexautoprint|. \meta{boolean} should be |true| or |false|.
-%
+%
%
% \subsection{Pygments commands and environments}
%
% Although \pytex'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.
%
% \DescribeMacro{\pygment\marg{lexer}\meta{opening~delim}\meta{code}\meta{closing~delim}}
-%
+%
% This command typesets \meta{code} in a suitable form for inline use within a paragraph, using the specified Pygments \meta{lexer}. Internally, it uses the same macros as the \pytex\ inline commands. \meta{opening~delim} and \meta{closing~delim} 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.
@@ -1207,10 +1336,10 @@
%
% This environment typesets its contents using the specified Pygments \meta{lexer} and applying the \meta{fancyvrb~settings}.
%
-%
+%
% \DescribeMacro{\inputpygments\oarg{fancyvrb~settings}\marg{lexer}\marg{external~file}}
%
-% This command brings in the contents of \meta{external~file}, highlights it using \meta{lexer}, and typesets it using \meta{fancyvrb~settings}.
+% This command brings in the contents of \meta{external~file}, highlights it using \meta{lexer}, and typesets it using \meta{fancyvrb~settings}.
%
%
% \DescribeMacro{\setpygmentsfv\oarg{lexer}\marg{fancyvrb~settings}}
@@ -1224,7 +1353,7 @@
%
% If \meta{lexer} is not given, options are set for the entire document.
%
-%
+%
% \DescribeMacro{\setpygmentsprettyprinter\marg{printer}}
%
% 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 \meta{printer} are |fancyvrb| and |pygments|.
@@ -1249,7 +1378,7 @@
%
% \pytex\ uses |fancyvrb| internally to typeset all code. Even code that is highlighted 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:
% \begin{verbatim}
-% \renewcommand{\FancyVerbFormatLine}[1]{\colorbox{green}{#1}}
+%\renewcommand{\FancyVerbFormatLine}[1]{\colorbox{green}{#1}}
% \end{verbatim}
%
% If you need a completely solid colored background for an environment, or a highly customizable background, you should consider the |mdframed| package. Wrapping \pytex\ environments with |mdframed| frames works quite well. You can even automatically add a particular style of frame to all instances of an environment using the command
@@ -1299,7 +1428,7 @@
%
% 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 (optionally 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 \href{http://tex.stackexchange.com/questions/41370/what-are-the-possible-dimensions-sizes-units-latex-understands}{$1/72.27$} of an inch, \emph{not} $1/72$ of an inch (which is a bp).
%
-% There is also a type system for Python that allows the types of \meta{values} to be specified. Any \meta{value} beginning with |!!int| will become an integer; with |!!float|, a float; with |!!str|, a string. This notation is borrowed from \href{http://yaml.org/}{YAML}. For example,
+% There is also a type system for Python that allows the types of \meta{values} to be specified. Any \meta{value} beginning with |!!int| will become an integer; with |!!float|, a float; with |!!str|, a string. This notation is borrowed from \href{http://yaml.org/}{YAML}. For example,
%\begin{verbatim}
%\setpythontexcontext{a=!!int 42, b=!!float 42, c=!!str 42}
%\end{verbatim}
@@ -1323,7 +1452,7 @@
%
% \DescribeMacro{\setpythontexoutputdir\marg{output~directory}}
%
-% By default, \pytex\ saves all temporary files and automatically generated content in a directory called |pythontex-files-|\meta{sanitized jobname}, where \meta{sanitized jobname} is just |\jobname| with any space characters or asterisks replaced 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.\footnote{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.}
+% By default, \pytex\ saves all temporary files and automatically generated content in a directory called |pythontex-files-|\meta{sanitized jobname}, where \meta{sanitized jobname} is just |\jobname| with any space characters or asterisks replaced 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.\footnote{In the rare event that both |\setpythontexoutputdir| is used and |\printpythontex| is needed in the preamble, |\setpythontexoutputdir| must be used first, so that |\printpythontex| will know where to look for output.}
%
% Any slashes in \meta{output~directory} should be forward slashes ``|/|'' (even under Windows). Tildes |~| may be used to refer to the user's home directory, including under Windows.
%
@@ -1337,7 +1466,7 @@
%
% 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.\footnote{\texttt{graphicx} looks for graphics in the document root directory and in the most recent graphics path defined by \texttt{\string\graphicspath}. \texttt{\string\graphicspath} stores the graphics path in \texttt{\string\Ginput@path}, overwriting any previous value. At the end of the preamble, \pytex\ appends the output directory to \texttt{\string\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 \texttt{\string\Ginput@path} is not overwritten by a subsequent use of \texttt{\string\graphicspath}. If you need to use \texttt{\string\graphicspath} within the document, you could consider creating a custom version that redefines \texttt{\string\Ginput@path} with the \pytex\ output directory automatically appended.} To use the output directory as the working directory, you may enter the full name of the output directory manually, or use the text ``||'' as a shortcut:
%\begin{verbatim}
-%\setpythontexworkingdir{}
+%\setpythontexworkingdir{}
%\end{verbatim}
%
% It is also possible to change the working directory from within Python code, via |os.chdir()|.
@@ -1373,8 +1502,8 @@
% \label{sec:depythontex}
%
% \pytex\ 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\ documents that require special packages or need special macros. To address this issue, the package includes a feature called |depythontex| that can convert a \pytex\ document into a plain \LaTeX\ document.
-%
-%
+%
+%
% \subsection{Preparing a document that will be converted}
%
% The conversion process should work flawlessly in most cases, with no special formatting required.
@@ -1386,7 +1515,7 @@
% \item 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~\ref{sec:depythontex:technical-details} for additional details.
% \item Some \LaTeX\ environments, such as the |verbatim| environment from the |verbatim| package and the |Verbatim| environment from |fancyvrb|, do not allow text to follow the |\end{|\meta{environment}|}|. 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
% \begin{verbatim}
-% '\\end{Verbatim}\n'
+%'\\end{Verbatim}\n'
% \end{verbatim}
% 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 \pytex\ document. But it would fail in the |depythontex| output.
% \item Do not create \pytex\ commands or environments on the Python side and |print| or otherwise bring them in. That is too many levels of complexity!
@@ -1397,7 +1526,7 @@
% \end{itemize}
%
% \subsection{Removing \pytex\ dependence}
-%
+%
% Converting a document requires three steps.
% \begin{enumerate}
% \item 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.
@@ -1413,13 +1542,13 @@
% When code is typeset with any option other than |verbatim|, listing line numbering from the original document will be preserved. When 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 correspond to Pygments' lexer name. In this case, you should use the |--lexer-dict| option to specify how the Pygments lexer is to be translated into a |listings| language.
% \item |--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
% \begin{verbatim}
-% ":, ..., ... "
+%":, ..., ... "
% \end{verbatim}
% A Python-style dict will also be accepted.
% \item |--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 \pytex, such as |upquote|.
% \item |--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.
% \item |-o| |--output| The name of the output file. If no name is given, the converted file is written to |stdout|.
-% \item |TEXNAME| The name of the \LaTeX\ file whose \pytex\ dependence is to be removed.
+% \item |TEXNAME| The name of the \LaTeX\ file whose \pytex\ dependence is to be removed.
% \end{itemize}
% \item Compile the |depythontex| file, and compare it to the original.
%
@@ -1440,7 +1569,7 @@
% 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.\footnote{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.} 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.
+% The space added by |\input| is often invisible, and even when it is not, it is sometimes desirable.\footnote{For example, |\printpythontex| behaves as a normal command, and gobbles following spaces, but the space from |\input| puts a space back. So you often get the space you want in inline contexts.} 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| and |%| only if they are the very last thing printed (before a final newline), and works with a following |\unskip|.\footnote{It would be possible to make \texttt{depythontex} work with \texttt{\string\endinput} and \texttt{\%} anywhere, not just at the very end of printed content. But doing so would require a lot of additional parsing, especially for \texttt{\string\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 \texttt{\string\endinput} or \texttt{\%}, 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.}
% \begin{itemize}
@@ -1474,16 +1603,16 @@
% This section will be expanded in the future. For now, it offers a brief summary.
%
% \subsection{Macro programming with \pytex}
-%
+%
% In many situations, you can use \pytex\ commands inside macro definitions without any special consideration. For example, consider the following macro, for calculating powers.
% \newcommand{\pow}[2]{\py{#1**#2}}
% \begin{verbatim}
-% \newcommand{\pow}[2]{\py{#1**#2}}
+%\newcommand{\pow}[2]{\py{#1**#2}}
% \end{verbatim}
% Once this is defined, we can calculate |2**8| via |\pow{2}{8}|: \pow{2}{8}. Similarly, we can reverse a string.
% \newcommand{\reverse}[1]{\py{"#1"[::-1]}}
% \begin{verbatim}
-% \newcommand{\reverse}[1]{\py{"#1"[::-1]}}
+%\newcommand{\reverse}[1]{\py{"#1"[::-1]}}
% \end{verbatim}
% Now we can use |\reverse{``This is some text!''}|: \reverse{``This is some text!''}.
%
@@ -1491,16 +1620,16 @@
%
% Of course, there are many cases where macros don't need arguments. Here is code for creating a macro that generates random polynomials.
% \begin{verbatim}
-% \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()}}
+%\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), 0)
+%\end{sympycode}
+%\newcommand{\randquad}{\ensuremath{\sympy{randquad()}}}
% \end{verbatim}
%
% If you are considering writing macros that involve \pytex, you should keep a few things in mind.
@@ -1519,11 +1648,13 @@
% \section{Support for additional languages}
% \label{sec:other-languages}
%
-% Beginning with v0.12, it is much simpler to add support for languages beyond Python. Support for several additional languages will be added in coming months.
+% Details about adding support for additional languages are in \Cref{sec:other-languages:adding}. This section begins with a brief overview of supported languages and available features.
%
-% In the immediate future, support for additional languages will be part of \pytex. Later, it may make sense to provide an alternative interface for other languages. For example, a package could be created that provides access to \pytex\ internals in a language-agnostic manner, without having the word ``python'' as part of the command names.
-%
-% Languages beyond Python will typically not be enabled by default, to prevent potential macro naming conflicts with other packages. 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.
+% 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 (\Cref{sec:usage}). For example,
+%\begin{verbatim}
+%\usepackage[usefamily=ruby]{pythontex}
+%\end{verbatim}
+% 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.
%
%
% \subsection{Ruby}
@@ -1547,6 +1678,10 @@
%
% 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.
%
+% \subsubsection*{Console}
+%
+% Julia console support was added in v0.16. It may be enabled by loading \pytex\ with |usefamily=juliacon|. The |juliaconsole| environment uses \href{https://github.com/mpastell/Weave.jl}{\textsf{Weave.jl}} internally to evaluate code. There is also a |juliaconcode| environment that executes code but typesets nothing.
+%
%
% \subsection{Octave}
%
@@ -1583,7 +1718,40 @@
% Additionally, when using |\rust| and |\rs|, keep in mind that these wrap code in a block, so you \emph{cannot} use |rstex| by value in these contexts (both shared and mutable references are still fine, though).
%
%
+% \subsection{R}
+%
+% Support for R was added in v0.17.
+%
+% Loading \pytex\ 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. Expressions 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 creation of plot files with default names. Plots that are to be saved require explicit graphics commands.
+%
+% \subsubsection*{Console}
+%
+% Loading \pytex\ 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 creation of plot files with default names. Plots that are to be saved require explicit graphics commands.
+%
+%
+% \subsection{Perl}
+%
+% Support for Perl was added in v0.17.
+%
+% Loading \pytex\ with |usefamily=perl| enables the |perl| family of commands and environments. Alternatively, |usefamily=pl| may be used to enable the |pl| family. There is currently no utilities class or related features.
+%
+%
+% \subsection{Perl 6}
+%
+% Support for Perl 6 was added in v0.17.
+%
+% Loading \pytex\ 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.
+%
+%
+% \subsection{JavaScript}
+%
+% Support for JavaScript was added in v0.17.
+%
+% Loading \pytex\ 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|.
+%
+%
% \subsection{Adding support for a new language}
+% \label{sec:other-languages:adding}
%
% Adding support for an additional language involves creating two templates, creating a new instance of a class, and using a \pytex\ 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.
%
@@ -1600,7 +1768,7 @@
% \item 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.
% \item Python templates should have a |{future}| field at the beginning, for compability with Python 2 and the package option |pyfuture|.\footnote{The beginning of user code is parsed for imports from \texttt{\_\_future\_\_}. Any imports are collected and inserted into the \texttt{\{\{future\}\}} field.}
% \item Set the |stdout| and |stderr| encoding, again using |{encoding}|. As before, this is not strictly necessary when only ASCII support is needed.
-% \item Create a language-specific equivalent of the \pytex\ utilities class.\footnote{Python templates can import the \pytex\ utilities class. In that case, \texttt{sys.path.append('\{\{utilspath\}\}')} is needed before the import, so that the location of the utilities class is known.} Create an instance of this class. It is recommended that the class be called \meta{language~name}|TeXUtils| and the instance \meta{language~extension}|tex|, by analogy with the Python case.\footnote{The class could be called \meta{language~name}\texttt{TeX}. 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, \texttt{Utils} adds additional clarity. The instance name \meta{language~extension}\texttt{tex} is recommended because it will be short and easily remembered. Plain \texttt{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).} When the \meta{language~extension} is only a single character or is shared by multiple languages, it may be better to use the full \meta{language~name} or an abbreviation in the name of the class instance.
+% \item Create a language-specific equivalent of the \pytex\ utilities class.\footnote{Python templates can import the \pytex\ utilities class. In that case, |sys.path.append('{{utilspath}}')| is needed before the import, so that the location of the utilities class is known.} Create an instance of this class. It is recommended that the class be called \meta{language~name}|TeXUtils| and the instance \meta{language~extension}|tex|, by analogy with the Python case.\footnote{The class could be called \meta{language~name}\texttt{TeX}. 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, \texttt{Utils} adds additional clarity. The instance name \meta{language~extension}\texttt{tex} is recommended because it will be short and easily remembered. Plain \texttt{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).} When the \meta{language~extension} is only a single character or is shared by multiple languages, it may be better to use the full \meta{language~name} or an abbreviation in the name of the class instance.
%
% For full \pytex\ support, the utilities class should provide the following methods:
% \begin{itemize}
@@ -1686,7 +1854,7 @@
%
% \item The |tabular| environment can conflict with \pytex\ under some circumstances, 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 expandable.\footnote{For more information, see \href{http://tex.stackexchange.com/questions/50820/expandable-version-of-inputiffileexists-or-iffileexists}{this}, \href{http://tex.stackexchange.com/questions/50828/execute-non-expandable-code-inside-a-tabular-environment}{this}, and \href{http://tex.stackexchange.com/questions/50694/cannot-use-toprule-when-doing-input-inside-tabular-why}{this}.} There are a few different ways to work around the limitations of |tabular|.
% \begin{itemize}
-%\item 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 \pytex. An example is given below. The |\global\def| is needed so that the macro is defined outside of the |pycode| environment.
+%\item 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 \pytex. An example is given below. The |\global\def| is needed so that the macro is defined outside of the |pycode| environment.
%\begin{verbatim}
%\let\row\relax
%\begin{pycode}
@@ -1790,6 +1958,8 @@
%
% Thanks to Alexander Altman for suggesting Rust support and providing template code.
%
+% Thanks to Nathan Carter for suggesting JavaScript support and providing template code.
+%
%
% \PrintChangelog
%
@@ -1809,7 +1979,7 @@
% We store the name of the package in a macro for later use in warnings and error messages.
% \begin{macrocode}
\newcommand{\pytx@packagename}{PythonTeX}
-\newcommand{\pytx@packageversion}{0.16dev}
+\newcommand{\pytx@packageversion}{0.19}
% \end{macrocode}
%
% \subsection{Required packages}
@@ -2030,7 +2200,7 @@
%
% \subsubsection{Upquote}
% \begin{macro}{pytx@opt@upquote}
-% The |upquote| option determines whether the |upquote| package is loaded. It makes quotes within verbatim contexts \expandafter|\textquotesingle| 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 \texttt{\'}.
+% The |upquote| option determines whether the |upquote| package is loaded. It makes quotes within verbatim contexts \expandafter|\textquotesingle| 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 \texttt{\'}.
% \begin{macrocode}
\newbool{pytx@opt@upquote}
\booltrue{pytx@opt@upquote}
@@ -2071,7 +2241,7 @@
% By default, \pytex\ uses |fancyvrb| to typeset code. This provides nice formatting and font options, but no syntax highlighting. The |prettyprinter| options, and |pygments| alias, determine whether Pygments or |fancyvrb| is used to typeset code. Pygments is a generic syntax highlighter written in Python. Since \pytex\ 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.\footnote{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.}
%
% Command and environment families obey the |prettyprinter| option by default, but they may be set to override it and always use Pygments or always use |fancyvrb|, via |\setpythontexprettyprinter| and |\setpygmentsprettyprinter|.
-% \begin{macrocode}
+% \begin{macrocode}
\newbool{pytx@opt@pygments}
\booltrue{pytx@opt@pygments}
\pgfkeys{/PYTX/pkgopt/prettyprinter/.is choice}
@@ -2116,7 +2286,7 @@
%
% Currently, three options may be passed in this manner: |style=|\meta{style}, 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 a boolean argument; if an argument is not supplied, true is assumed. As an example of |pygopt| usage, consider the following:
% \begin{verbatim}
-% pygopt={style=colorful, texcomments=true, mathescape=false}
+%pygopt={style=colorful, texcomments=true, mathescape=false}
% \end{verbatim}
%
% While the package-level |pygments| option may be overridden by individual commands 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.
@@ -2149,7 +2319,7 @@
% 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.
% \begin{macrocode}
\def\pytx@fvextfile{-1}
-\pgfkeys{/PYTX/pkgopt/fvextfile/.default=25}
+\pgfkeys{/PYTX/pkgopt/fvextfile/.default=25}
\pgfkeys{/PYTX/pkgopt/fvextfile/.code=\IfInteger{#1}{%
\ifnum#1>0\relax
\def\pytx@fvextfile{#1}%
@@ -2160,7 +2330,7 @@
}
% \end{macrocode}
% \end{macro}
-%
+%
% \subsubsection{Python console environment}
% \begin{macro}{\pytx@opt@pyconbanner}
% This option governs the appearance (or disappearance) of a banner at the beginning 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.
@@ -2177,8 +2347,8 @@
% \begin{macro}{\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.
% \begin{verbatim}
-% Traceback (most recent call last):
-% File "", line , in
+%Traceback (most recent call last):
+% File "", line , in
% \end{verbatim}
% \begin{macrocode}
\def\pytx@opt@pyconfilename{stdin}
@@ -2239,7 +2409,7 @@
% Once options are processed, we proceed to define a number of utility macros and setup the file input/output that is required by \pytex. We also create macros and perform setup needed by depythontex, since these are closely related to input/output.
%
% \subsubsection{Automatic counter creation}
-%
+%
% \begin{macro}{\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.
% \begin{macrocode}
@@ -2352,7 +2522,7 @@
\@onlypreamble\restartpythontexsession
\restartpythontexsession{default}
% \end{macrocode}
-%
+%
% \subsubsection{File input and output}
%
% \begin{macro}{\pytx@jobname}
@@ -2411,7 +2581,7 @@
%
% \begin{macro}{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 (for example, via |\includegraphics|) or automatically by \pytex\ 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.\footnote{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.} 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.
% \begin{macrocode}
\newbool{pytx@usedpygments}
@@ -2450,7 +2620,7 @@
}
% \end{macrocode}
% \end{macro}\end{macro}
-%
+%
%
% \begin{macro}{\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. \pytex\ 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.\footnote{The choice to write all code to a single file is the result of two factors. First, \TeX\ has a limited 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 \pytex\ 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.}
@@ -2459,7 +2629,7 @@
\immediate\openout\pytx@codefile=\jobname.pytxcode
% \end{macrocode}
% \end{macro}
-%
+%
% In the code file, information from \pytex\ must be interspersed with the code. Some type of delimiting is needed for \pytex\ information. All \pytex\ content is written to the file in the form |=>PYTHONTEX#|\meta{content}|#|. When this content involves package options, the delimiter is modified to the form |=>PYTHONTEX:SETTINGS#|\meta{content}|#|. The |#| symbol is also used as a subdelimiter within \meta{content}. 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 \pytex\ data means that this string should \textbf{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.
%
% \begin{macro}{\pytx@delimchar}
@@ -2542,7 +2712,7 @@
% \begin{macro}{\pytx@fvsettings}\begin{macro}{\setpythontexfv}
% The macro |\setpythontexfv|\oarg{family}\marg{settings} takes \meta{settings} and stores them in a macro that is run through |fancyvrb|'s |\fvset| at the beginning of \pytex\ code. If a \meta{family} is specified, the settings are stored in |\pytx@fvsettings@|\meta{family}, and the settings only apply to typeset code belonging 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. For typical use scenarios, this distinction shouldn't be important---usually, we will want to set the behavior of |fancyvrb| for all \pytex\ content, or for a family of \pytex\ 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.\footnote{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 \pytex-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.}
+% 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. For typical use scenarios, this distinction shouldn't be important---usually, we will want to set the behavior of |fancyvrb| for all \pytex\ content, or for a family of \pytex\ 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.\footnote{An argument could be made for having |\setpythontexfv| behave exactly like |\fvset|. Properly implementing this behavior would be tricky, because of inheritance issues between \pytex-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.}
% \begin{macrocode}
\newcommand{\setpythontexfv}[2][]{%
\Depythontex{cmd:setpythontexfv:om:n}%
@@ -2551,7 +2721,7 @@
{\expandafter\gdef\csname pytx@fvsettings@#1\endcsname{#2}}%
}%
% \end{macrocode}
-%
+%
% Now that we have a mechanism for applying global settings to typeset \pytex\ 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.
% \begin{macrocode}
\setpythontexfv{tabsize=4}
@@ -2775,7 +2945,7 @@
%
% 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.
%
-% \begin{macro}{\savestderrpythontex}
+% \begin{macro}{\savestderrpythontex}
% \begin{macrocode}
\def\savestderrpythontex#1{%
\Depythontex{cmd:savestderrpythontex:m:n}%
@@ -2832,7 +3002,7 @@
% \begin{macro}{\Depythontex}
% Each command or environment that is to work with depythontex will write the following information to the auxiliary file:
% \begin{verbatim}
-% =>DEPYTHONTEX#:::::[]#
+%=>DEPYTHONTEX#:::::[]#
% \end{verbatim}
% where || is |cmd| or |env|; || is the complete name of the command or environment; || is a string representing the arguments taken (|o|=optional, |m|=mandatory, |v|=mandatory~verbatim, |n|=none); || is a string representing what is typeset (|c|=code, |p|=printed, |n|=null), and || 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.
% \begin{itemize}
@@ -3023,7 +3193,7 @@
% 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 \textbf{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.
@@ -3052,7 +3222,7 @@
%
%
% \begin{macro}{\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 remain local. Most of the remainder of the commands are from |fancyvrb|'s |\FV@FormattingPrep|, and take care of various formatting matters, including spacing, font, whether space characters are shown, and any user-defined formatting. Finally, we create an |\hbox| and invoke |\FancyVerbFormatLine| to maintain parallelism 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:\footnote{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.}
+% 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 remain local. Most of the remainder of the commands are from |fancyvrb|'s |\FV@FormattingPrep|, and take care of various formatting matters, including spacing, font, whether space characters are shown, and any user-defined formatting. Finally, we create an |\hbox| and invoke |\FancyVerbFormatLine| to maintain parallelism 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:\footnote{Currently, |\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.}
% \begin{quote}
% |\renewcommand{\FancyVerbFormatLine}[1]{\colorbox{green}{#1}}|
% \end{quote}
@@ -3345,7 +3515,7 @@
}%
\xdef\pytx@type{CC:#2:#1}%
\edef\pytx@cmd{c}%
- \def\pytx@context{}%
+ \pytx@SetContext
\def\pytx@group{none}%
\let\pytx@InlineShow\@empty
\let\pytx@InlineSave\pytx@InlineSaveCode
@@ -3383,7 +3553,7 @@
%
%
% \subsection{Environments}
-%
+%
% The inline commands were all created using a common core set of macros, combined with short, command-specific constructors. In the case of environments, we do not have a common core set of macros. Each environment is coded separately, 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 environments 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 numbering 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 \pytex's line numbering separate, even though \pytex\ is using |fancyvrb| and its macros internally.
@@ -3399,7 +3569,7 @@
\gdef\pytx@FancyVerbGetLine#1^^M{%
\@nil%
\FV@CheckEnd{#1}%
- \ifx\@tempa\FV@EnvironName%
+ \ifx\@tempa\FV@EnvironName%
\ifx\@tempb\FV@@@CheckEnd\else\FV@BadEndError\fi%
\let\next\FV@EndScanning%
\else%
@@ -3614,7 +3784,7 @@
%
%
% \subsubsection{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|.
+% 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|.
% \begin{macro}{\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.
% \begin{macrocode}
@@ -3679,6 +3849,22 @@
}%
{\end{VerbatimOut}%
\xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
+ \ifcsname pytx@nonpyconsole@\pytx@type\endcsname
+ \ifcsname pytx@code@as@console\endcsname
+ \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
+ \pytx@FVSet
+ \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
+ \pytx@ConfigPygments
+ \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.stdout}%
+ {\DepyFile{p:\pytx@outputdir/\pytx@stdfile.stdout}}%
+ {\par\textbf{??~\pytx@packagename~??}\par
+ \PackageWarning{\pytx@packagename}{Non-existent console content}}%
+ \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
+ \else
+ \fi
+ \let\pytx@EnvAutoprint\relax
+ \else
+ \fi
\setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
\stepcounter{\pytx@counter}%
\pytx@EnvAutoprint
@@ -3695,6 +3881,8 @@
\ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
\xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
\pytx@CheckCounter{\pytx@counter}%
+ \edef\pytx@linecount{\pytx@counter @line}%
+ \pytx@CheckCounter{\pytx@linecount}%
\pytx@WriteCodefileInfo
\begingroup
\obeylines
@@ -3708,6 +3896,8 @@
% 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 mandatory file name argument. We must perform the typical |FancyVerbLine| trickery, to prevent the |fancyvrb| line counter from being affected by \textbf{writing} content!
% \begin{macrocode}
\def\pytx@BeginCodeEnv@i[#1]{%
+ \def\pytx@fvopttmp{#1}%
+ \def\pytx@argspprint{#1}%
\setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
\let\FVB@VerbatimOut\pytx@FVB@VerbatimOut
\let\FVE@VerbatimOut\pytx@FVE@VerbatimOut
@@ -3738,7 +3928,7 @@
}%
\xdef\pytx@type{CC:#2:#1}%
\edef\pytx@cmd{code}%
- \def\pytx@context{}%
+ \pytx@SetContext
\def\pytx@group{none}%
\pytx@BeginCodeEnv[none]}%
{\end{VerbatimOut}%
@@ -3759,7 +3949,7 @@
\newcommand{\pytx@MakeSubFV}[1]{%
\expandafter\newenvironment{#1sub}{%
\VerbatimEnvironment
- \Depythontex{env:#1sub:om|:p}%
+ \Depythontex{env:#1sub:oo|:p}%
\xdef\pytx@type{#1}%
\edef\pytx@cmd{sub}%
\pytx@SetContext
@@ -3788,11 +3978,11 @@
% \end{macrocode}
% \end{macro}
%
-%
+%
%
%
% \subsubsection{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.
@@ -3995,6 +4185,34 @@
\@onlypreamble\makepythontexfamily
% \end{macrocode}
% \end{macro}
+%
+%
+% \begin{macro}{\makepythontexfamily@con}
+% This macro creates |console| and |code| environments for non-Python consoles. \pytex\ 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| environments 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 \pytex\ to accomodate non-Python consoles more easily.
+% \begin{macrocode}
+\newcommand{\makepythontexfamily@con}[2][text]{%
+ \pgfkeys{/PYTX/family, name=#2con, default, pyglexer=#1, console=true}%
+ \expandafter\xdef\csname pytx@macroformatter@#2con\endcsname{\pytx@tmp@pprinter}%
+ \expandafter\gdef\csname pytx@fvsettings@#2con\endcsname{}%
+ \expandafter\xdef\csname pytx@pyglexer@#2con\endcsname{\pytx@tmp@pyglexer}%
+ \expandafter\xdef\csname pytx@pygopt@#2con\endcsname{\pytx@tmp@pygopt}%
+ \expandafter\xdef\csname pytx@console@#2con\endcsname{\pytx@tmp@console}%
+ \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=#2con|%
+ \csname pytx@pyglexer@#2con\endcsname|%
+ \csname pytx@pygopt@#2con\endcsname}%
+ }%
+ \pytx@MakeCodeFV{#2con}%
+ \expandafter\global\expandafter\let\csname pytx@nonpyconsole@#2con\endcsname\relax
+ \newenvironment{#2console}%
+ {\VerbatimEnvironment
+ \def\pytx@type{#2con}%
+ \let\pytx@code@as@console\relax
+ \begin{#2concode}}%
+ {\end{#2concode}}%
+}
+% \end{macrocode}
+% \end{macro}
+
%
% \begin{macro}{\setpythontexpyglexer}
% We need to be able to reset the lexer associated with a family after the family has already been created.
@@ -4064,11 +4282,11 @@
%
% All of these command and environment families are created conditionally, depending 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.
% \begin{macrocode}
-\makepythontexfamily[pyglexer=python]{py}
+\makepythontexfamily[pyglexer=python3]{py}
\makepythontexfamily[pyglexer=pycon, console=true]{pycon}
-\makepythontexfamily[pyglexer=python]{sympy}
+\makepythontexfamily[pyglexer=python3]{sympy}
\makepythontexfamily[pyglexer=pycon, console=true]{sympycon}
-\makepythontexfamily[pyglexer=python]{pylab}
+\makepythontexfamily[pyglexer=python3]{pylab}
\makepythontexfamily[pyglexer=pycon, console=true]{pylabcon}
% \end{macrocode}
% We also need to create any additional families specified via the |usefamily| package option.\footnote{The loop here is accomplished via \texttt{etoolbox}. \texttt{pgffor} might be an alternative, but making definitions global requires trickery.}
@@ -4077,11 +4295,7 @@
\ifstrequal{#1}{ruby}{\makepythontexfamily[pyglexer=ruby]{ruby}}{}%
\ifstrequal{#1}{rb}{\makepythontexfamily[pyglexer=ruby]{rb}}{}%
\ifstrequal{#1}{julia}{\makepythontexfamily[pyglexer=julia]{julia}}{}%
- \ifstrequal{#1}{juliacon}{\pytx@MakeCodeFV{juliacon}%
- \newenvironment{juliaconsole}%
- {\VerbatimEnvironment\begin{juliaconcode}}%
- {\end{juliaconcode}%
- \ifbool{pytx@opt@autoprint}{}{\printpythontex{}}}}{}%
+ \ifstrequal{#1}{juliacon}{\makepythontexfamily@con[jlcon]{julia}}{}%
\ifstrequal{#1}{jl}{\makepythontexfamily[pyglexer=julia]{jl}}{}%
\ifstrequal{#1}{matlab}{\makepythontexfamily[pyglexer=matlab]{matlab}}{}%
\ifstrequal{#1}{octave}{\makepythontexfamily[pyglexer=octave]{octave}}{}%
@@ -4089,6 +4303,14 @@
\ifstrequal{#1}{sage}{\makepythontexfamily[pyglexer=sage]{sage}}{}%
\ifstrequal{#1}{rust}{\makepythontexfamily[pyglexer=rust]{rust}}{}%
\ifstrequal{#1}{rs}{\makepythontexfamily[pyglexer=rust]{rs}}{}%
+ \ifstrequal{#1}{R}{\makepythontexfamily[pyglexer=r]{R}}{}%
+ \ifstrequal{#1}{Rcon}{\makepythontexfamily@con[rconsole]{R}}{}%
+ \ifstrequal{#1}{perl}{\makepythontexfamily[pyglexer=perl]{perl}}{}%
+ \ifstrequal{#1}{pl}{\makepythontexfamily[pyglexer=perl]{pl}}{}%
+ \ifstrequal{#1}{perlsix}{\makepythontexfamily[pyglexer=perl6]{perlsix}}{}%
+ \ifstrequal{#1}{psix}{\makepythontexfamily[pyglexer=perl6]{psix}}{}%
+ \ifstrequal{#1}{javascript}{\makepythontexfamily[pyglexer=js]{javascript}}{}%
+ \ifstrequal{#1}{js}{\makepythontexfamily[pyglexer=js]{js}}{}%
}
\expandafter\docsvlist\expandafter{\pytx@families}
% \end{macrocode}
@@ -4343,7 +4565,7 @@
% 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.
-%
+%
% \begin{macrocode}
\def\pytx@MakePygmentsInputFV{
\newcommand{\inputpygments}[3][]{%
@@ -4390,9 +4612,9 @@
\pytx@FVSet
\fvset{firstnumber=auto}%
\pytx@ConfigPygments
- \ifcsname FV@SV@pytx@\pytx@type @\pytx@session @\pytx@group
+ \ifcsname FV@SV@pytx@\pytx@type @\pytx@session @\pytx@group
@\arabic{\pytx@counter}\endcsname
- \UseVerbatim[##1]{pytx@\pytx@type @\pytx@session @\pytx@group
+ \UseVerbatim[##1]{pytx@\pytx@type @\pytx@session @\pytx@group
@\arabic{\pytx@counter}}%
\else
\InputIfFileExists{\pytx@outputdir/\pytx@type_##3_\pytx@group
@@ -4659,7 +4881,7 @@
}{} %End beta
% \end{macrocode}
-%
+%
%
%
% \iffalse
diff --git a/pythontex/pythontex.ins b/pythontex/pythontex.ins
index 605cf4c..2d7f3c1 100644
--- a/pythontex/pythontex.ins
+++ b/pythontex/pythontex.ins
@@ -1,4 +1,4 @@
-%% Copyright (C) 2012-2016 by Geoffrey M. Poore
+%% Copyright (C) 2012-2026 by Geoffrey M. Poore
%% --------------------------------------------------------------------------
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
@@ -25,7 +25,7 @@
This is a generated file.
-Copyright (C) 2012-2016 by Geoffrey M. Poore
+Copyright (C) 2012-2026 by Geoffrey M. Poore
--------------------------------------------------------------------------
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
diff --git a/pythontex/pythontex.pdf b/pythontex/pythontex.pdf
index 2531310..635a412 100644
Binary files a/pythontex/pythontex.pdf and b/pythontex/pythontex.pdf differ
diff --git a/pythontex/pythontex.py b/pythontex/pythontex.py
index 0c6e5c7..21c2966 100644
--- a/pythontex/pythontex.py
+++ b/pythontex/pythontex.py
@@ -16,7 +16,7 @@
Licensed under the BSD 3-Clause License:
-Copyright (c) 2012-2016, Geoffrey M. Poore
+Copyright (c) 2012-2026, Geoffrey M. Poore
All rights reserved.
diff --git a/pythontex/pythontex.sty b/pythontex/pythontex.sty
index 990c2c0..d2640c7 100644
--- a/pythontex/pythontex.sty
+++ b/pythontex/pythontex.sty
@@ -8,7 +8,7 @@
%%
%% This is a generated file.
%%
-%% Copyright (C) 2012-2016 by Geoffrey M. Poore
+%% Copyright (C) 2012-2026 by Geoffrey M. Poore
%% --------------------------------------------------------------------------
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
@@ -20,11 +20,10 @@
%%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{pythontex}
- [2017/05/25 v0.16dev execute and typeset Python code and other languages]
-
+ [2026/02/15 v0.19 execute and typeset Python code and other languages]
\newcommand{\pytx@packagename}{PythonTeX}
-\newcommand{\pytx@packageversion}{0.16dev}
+\newcommand{\pytx@packageversion}{0.19}
\RequirePackage{fvextra}
\RequirePackage{etoolbox}
\RequirePackage{xstring}
@@ -847,7 +846,7 @@
}%
\xdef\pytx@type{CC:#2:#1}%
\edef\pytx@cmd{c}%
- \def\pytx@context{}%
+ \pytx@SetContext
\def\pytx@group{none}%
\let\pytx@InlineShow\@empty
\let\pytx@InlineSave\pytx@InlineSaveCode
@@ -1038,6 +1037,22 @@
}%
{\end{VerbatimOut}%
\xdef\pytx@stdfile{\pytx@type_\pytx@session_\pytx@group_\arabic{\pytx@counter}}%
+ \ifcsname pytx@nonpyconsole@\pytx@type\endcsname
+ \ifcsname pytx@code@as@console\endcsname
+ \setcounter{FancyVerbLine}{\value{\pytx@linecount}}%
+ \pytx@FVSet
+ \ifdefstring{\pytx@fvopttmp}{}{}{\expandafter\fvset\expandafter{\pytx@fvopttmp}}%
+ \pytx@ConfigPygments
+ \InputIfFileExists{\pytx@outputdir/\pytx@stdfile.stdout}%
+ {\DepyFile{p:\pytx@outputdir/\pytx@stdfile.stdout}}%
+ {\par\textbf{??~\pytx@packagename~??}\par
+ \PackageWarning{\pytx@packagename}{Non-existent console content}}%
+ \setcounter{\pytx@linecount}{\value{FancyVerbLine}}%
+ \else
+ \fi
+ \let\pytx@EnvAutoprint\relax
+ \else
+ \fi
\setcounter{FancyVerbLine}{\value{pytx@FancyVerbLineTemp}}%
\stepcounter{\pytx@counter}%
\pytx@EnvAutoprint
@@ -1047,12 +1062,16 @@
\ifstrempty{#1}{\edef\pytx@session{default}}{\StrSubstitute{#1}{:}{-}[\pytx@session]}%
\xdef\pytx@counter{pytx@\pytx@type @\pytx@session @\pytx@group}%
\pytx@CheckCounter{\pytx@counter}%
+ \edef\pytx@linecount{\pytx@counter @line}%
+ \pytx@CheckCounter{\pytx@linecount}%
\pytx@WriteCodefileInfo
\begingroup
\obeylines
\@ifnextchar[{\endgroup\pytx@BeginCodeEnv@i}{\endgroup\pytx@BeginCodeEnv@i[]}%
}%
\def\pytx@BeginCodeEnv@i[#1]{%
+ \def\pytx@fvopttmp{#1}%
+ \def\pytx@argspprint{#1}%
\setcounter{pytx@FancyVerbLineTemp}{\value{FancyVerbLine}}%
\let\FVB@VerbatimOut\pytx@FVB@VerbatimOut
\let\FVE@VerbatimOut\pytx@FVE@VerbatimOut
@@ -1069,7 +1088,7 @@
}%
\xdef\pytx@type{CC:#2:#1}%
\edef\pytx@cmd{code}%
- \def\pytx@context{}%
+ \pytx@SetContext
\def\pytx@group{none}%
\pytx@BeginCodeEnv[none]}%
{\end{VerbatimOut}%
@@ -1079,7 +1098,7 @@
\newcommand{\pytx@MakeSubFV}[1]{%
\expandafter\newenvironment{#1sub}{%
\VerbatimEnvironment
- \Depythontex{env:#1sub:om|:p}%
+ \Depythontex{env:#1sub:oo|:p}%
\xdef\pytx@type{#1}%
\edef\pytx@cmd{sub}%
\pytx@SetContext
@@ -1266,6 +1285,27 @@
\newcounter{pytx@#2@default@default}%
}
\@onlypreamble\makepythontexfamily
+\newcommand{\makepythontexfamily@con}[2][text]{%
+ \pgfkeys{/PYTX/family, name=#2con, default, pyglexer=#1, console=true}%
+ \expandafter\xdef\csname pytx@macroformatter@#2con\endcsname{\pytx@tmp@pprinter}%
+ \expandafter\gdef\csname pytx@fvsettings@#2con\endcsname{}%
+ \expandafter\xdef\csname pytx@pyglexer@#2con\endcsname{\pytx@tmp@pyglexer}%
+ \expandafter\xdef\csname pytx@pygopt@#2con\endcsname{\pytx@tmp@pygopt}%
+ \expandafter\xdef\csname pytx@console@#2con\endcsname{\pytx@tmp@console}%
+ \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=#2con|%
+ \csname pytx@pyglexer@#2con\endcsname|%
+ \csname pytx@pygopt@#2con\endcsname}%
+ }%
+ \pytx@MakeCodeFV{#2con}%
+ \expandafter\global\expandafter\let\csname pytx@nonpyconsole@#2con\endcsname\relax
+ \newenvironment{#2console}%
+ {\VerbatimEnvironment
+ \def\pytx@type{#2con}%
+ \let\pytx@code@as@console\relax
+ \begin{#2concode}}%
+ {\end{#2concode}}%
+}
+
\newcommand{\setpythontexpyglexer}[2][]{%
\Depythontex{cmd:setpythontexpyglexer:om:n}%
\ifstrempty{#1}{\def\pytx@pyglexer{#2}}{%
@@ -1308,21 +1348,17 @@
}%
}
\@onlypreamble\setpythontexprettyprinter
-\makepythontexfamily[pyglexer=python]{py}
+\makepythontexfamily[pyglexer=python3]{py}
\makepythontexfamily[pyglexer=pycon, console=true]{pycon}
-\makepythontexfamily[pyglexer=python]{sympy}
+\makepythontexfamily[pyglexer=python3]{sympy}
\makepythontexfamily[pyglexer=pycon, console=true]{sympycon}
-\makepythontexfamily[pyglexer=python]{pylab}
+\makepythontexfamily[pyglexer=python3]{pylab}
\makepythontexfamily[pyglexer=pycon, console=true]{pylabcon}
\renewcommand{\do}[1]{%
\ifstrequal{#1}{ruby}{\makepythontexfamily[pyglexer=ruby]{ruby}}{}%
\ifstrequal{#1}{rb}{\makepythontexfamily[pyglexer=ruby]{rb}}{}%
\ifstrequal{#1}{julia}{\makepythontexfamily[pyglexer=julia]{julia}}{}%
- \ifstrequal{#1}{juliacon}{\pytx@MakeCodeFV{juliacon}%
- \newenvironment{juliaconsole}%
- {\VerbatimEnvironment\begin{juliaconcode}}%
- {\end{juliaconcode}%
- \ifbool{pytx@opt@autoprint}{}{\printpythontex{}}}}{}%
+ \ifstrequal{#1}{juliacon}{\makepythontexfamily@con[jlcon]{julia}}{}%
\ifstrequal{#1}{jl}{\makepythontexfamily[pyglexer=julia]{jl}}{}%
\ifstrequal{#1}{matlab}{\makepythontexfamily[pyglexer=matlab]{matlab}}{}%
\ifstrequal{#1}{octave}{\makepythontexfamily[pyglexer=octave]{octave}}{}%
@@ -1330,6 +1366,14 @@
\ifstrequal{#1}{sage}{\makepythontexfamily[pyglexer=sage]{sage}}{}%
\ifstrequal{#1}{rust}{\makepythontexfamily[pyglexer=rust]{rust}}{}%
\ifstrequal{#1}{rs}{\makepythontexfamily[pyglexer=rust]{rs}}{}%
+ \ifstrequal{#1}{R}{\makepythontexfamily[pyglexer=r]{R}}{}%
+ \ifstrequal{#1}{Rcon}{\makepythontexfamily@con[rconsole]{R}}{}%
+ \ifstrequal{#1}{perl}{\makepythontexfamily[pyglexer=perl]{perl}}{}%
+ \ifstrequal{#1}{pl}{\makepythontexfamily[pyglexer=perl]{pl}}{}%
+ \ifstrequal{#1}{perlsix}{\makepythontexfamily[pyglexer=perl6]{perlsix}}{}%
+ \ifstrequal{#1}{psix}{\makepythontexfamily[pyglexer=perl6]{psix}}{}%
+ \ifstrequal{#1}{javascript}{\makepythontexfamily[pyglexer=js]{javascript}}{}%
+ \ifstrequal{#1}{js}{\makepythontexfamily[pyglexer=js]{js}}{}%
}
\expandafter\docsvlist\expandafter{\pytx@families}
\newbool{pytx@listingenv}
diff --git a/pythontex/pythontex2.py b/pythontex/pythontex2.py
index 38b5c85..c83a81f 100644
--- a/pythontex/pythontex2.py
+++ b/pythontex/pythontex2.py
@@ -13,7 +13,7 @@
Licensed under the BSD 3-Clause License:
-Copyright (c) 2012-2016, Geoffrey M. Poore
+Copyright (c) 2012-2026, Geoffrey M. Poore
All rights reserved.
@@ -62,6 +62,7 @@
from pythontex_engines import *
import textwrap
import platform
+import itertools
if sys.version_info[0] == 2:
try:
@@ -77,7 +78,7 @@
# Script parameters
# Version
-__version__ = '0.16dev'
+__version__ = '0.19'
@@ -436,7 +437,7 @@ def set_kv_pygments(k, v):
elif v in ('false', 'False'):
v = False
else:
- k = option
+ k = options
v = True
opt_dict[k] = v
if family != ':GLOBAL':
@@ -482,7 +483,7 @@ def set_kv_pygments(k, v):
print(' Unknown option "' + key + '"')
temp_data['warnings'] += 1
- # Check for compatility between the .pytxcode and the script
+ # Check for compatibility between the .pytxcode and the script
if 'version' not in settings or settings['version'] != data['version']:
print('* PythonTeX error')
print(' The version of the PythonTeX scripts does not match the last code')
@@ -591,7 +592,7 @@ def get_old_data(data, old_data, temp_data):
f = open(pythontex_data_file, 'rb')
old = pickle.load(f)
f.close()
- # Check for compabilility
+ # Check for compatibility
if 'vitals' in old and data['vitals'] == old['vitals']:
temp_data['loaded_old_data'] = True
old_data.update(old)
@@ -868,12 +869,15 @@ def hash_all(data, temp_data, old_data, engine_dict):
if family in pygments_settings:
if (not pygments_settings_changed[family] and
key in old_typeset_hash_dict and
- typeset_hash_dict[key] == old_typeset_hash_dict[key]):
+ typeset_hash_dict[key] == old_typeset_hash_dict[key] and
+ not modified_dependencies(key, data, old_data, temp_data)):
pygments_update[key] = False
if key in old_pygments_macros:
pygments_macros[key] = old_pygments_macros[key]
if key in old_pygments_files:
pygments_files[key] = old_pygments_files[key]
+ if key in old_dependencies:
+ dependencies[key] = old_dependencies[key]
else:
pygments_update[key] = True
else:
@@ -1213,9 +1217,13 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
# Must double-escape any backslashes so that they survive `shlex.split()`
script = basename
if os.path.isabs(os.path.expanduser(os.path.normcase(outputdir))):
- script_full = os.path.expanduser(os.path.normcase(os.path.join(outputdir, basename)))
+ script_full = os.path.expanduser(os.path.join(outputdir, basename))
else:
- script_full = os.path.expanduser(os.path.normcase(os.path.join(orig_cwd, outputdir, basename)))
+ script_full = os.path.expanduser(os.path.join(orig_cwd, outputdir, basename))
+ if platform.system() == 'Windows':
+ script_full = script_full.replace('/', '\\')
+ else:
+ script_full = script_full.replace('\\', '/')
# `shlex.split()` only works with Unicode after 2.7.2
if (sys.version_info.major == 2 and sys.version_info.micro < 3):
exec_cmd = shlex.split(bytes(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\'))))
@@ -1224,7 +1232,7 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
exec_cmd = shlex.split(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\')))
try:
proc = subprocess.Popen(exec_cmd)
- except (WindowsError, FileNotFoundError) as e:
+ except (OSError, FileNotFoundError) as e:
if platform.system() == 'Windows' and e.errno == 2:
# Batch files won't be found when called without extension. They
# would be found if `shell=True`, but then getting the right
@@ -1275,7 +1283,11 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
for key in code_dict:
family = key.split('#')[0]
# Uncomment the following for debugging, and comment out what follows
- '''run_code(encoding, outputdir, workingdir, code_dict[key],
+ '''run_code(encoding, outputdir,
+ workingdir,
+ cc_dict_begin[family],
+ code_dict[key],
+ cc_dict_end[family],
engine_dict[family].language,
engine_dict[family].commands,
engine_dict[family].created,
@@ -1286,9 +1298,13 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
engine_dict[family].warnings,
engine_dict[family].linenumbers,
engine_dict[family].lookbehind,
- keeptemps, hashdependencies)'''
+ keeptemps, hashdependencies,
+ pygments_settings]))'''
tasks.append(pool.apply_async(run_code, [encoding, outputdir,
- workingdir, code_dict[key],
+ workingdir,
+ cc_dict_begin[family],
+ code_dict[key],
+ cc_dict_end[family],
engine_dict[family].language,
engine_dict[family].commands,
engine_dict[family].created,
@@ -1299,7 +1315,8 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
engine_dict[family].warnings,
engine_dict[family].linenumbers,
engine_dict[family].lookbehind,
- keeptemps, hashdependencies]))
+ keeptemps, hashdependencies,
+ pygments_settings]))
if verbose:
print(' - Code process ' + key.replace('#', ':'))
@@ -1345,11 +1362,15 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
# Add a Pygments process
if pygments_list:
+ # Uncomment the following for debugging
+ # do_pygments(encoding, outputdir, fvextfile, pygments_list,
+ # pygments_settings, typeset_cache, hashdependencies)
tasks.append(pool.apply_async(do_pygments, [encoding, outputdir,
fvextfile,
pygments_list,
pygments_settings,
- typeset_cache]))
+ typeset_cache,
+ hashdependencies]))
if verbose:
print(' - Pygments process')
@@ -1398,6 +1419,8 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
if result['pygments_files'][k]:
new_files = True
break
+ for k, v in result['dependencies'].items():
+ dependencies[k] = v
pygments_macros.update(result['pygments_macros'])
errors += result['errors']
warnings += result['warnings']
@@ -1410,7 +1433,7 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
unresolved_sessions = []
for key in dependencies:
for dep, val in dependencies[key].items():
- if val[0] > start_time:
+ if val[0] is None or val[0] > start_time:
unresolved_dependencies = True
dependencies[key][dep] = (None, None)
unresolved_sessions.append(key.replace('#', ':'))
@@ -1472,10 +1495,11 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
-def run_code(encoding, outputdir, workingdir, code_list, language, commands,
+def run_code(encoding, outputdir, workingdir,
+ cc_begin_list, code_list, cc_end_list, language, commands,
command_created, extension, makestderr, stderrfilename,
code_index, errorsig, warningsig, linesig, stderrlookbehind,
- keeptemps, hashdependencies):
+ keeptemps, hashdependencies, pygments_settings):
'''
Function for multiprocessing code files
'''
@@ -1510,11 +1534,19 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
err_file_name = os.path.expanduser(os.path.normcase(os.path.join(outputdir, basename + '.err')))
out_file = open(out_file_name, 'w', encoding=encoding)
err_file = open(err_file_name, 'w', encoding=encoding)
- script = os.path.expanduser(os.path.normcase(os.path.join(outputdir, basename)))
+ script = os.path.expanduser(os.path.join(outputdir, basename))
+ if platform.system() == 'Windows':
+ script = script.replace('/', '\\')
+ else:
+ script = script.replace('\\', '/')
if os.path.isabs(script):
script_full = script
else:
- script_full = os.path.expanduser(os.path.normcase(os.path.join(os.getcwd(), outputdir, basename)))
+ script_full = os.path.expanduser(os.path.join(os.getcwd(), outputdir, basename))
+ if platform.system() == 'Windows':
+ script_full = script_full.replace('/', '\\')
+ else:
+ script_full = script_full.replace('\\', '/')
# #### Need to revise so that intermediate files can be detected and cleaned up
for f in command_created:
files.append(f.format(file=script, File=script_full))
@@ -1533,8 +1565,11 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
# Add any created files due to the command
# This needs to be done before attempts to execute, to prevent orphans
try:
- proc = subprocess.Popen(exec_cmd, stdout=out_file, stderr=err_file)
- except WindowsError as e:
+ if family != 'Rcon':
+ proc = subprocess.Popen(exec_cmd, stdout=out_file, stderr=err_file)
+ else:
+ proc = subprocess.Popen(exec_cmd, stdout=out_file, stderr=subprocess.STDOUT)
+ except OSError as e:
if e.errno == 2:
# Batch files won't be found when called without extension. They
# would be found if `shell=True`, but then getting the right
@@ -1544,7 +1579,10 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
# under Windows; a list is not required.
exec_cmd_string = ' '.join(exec_cmd)
exec_cmd_string = 'cmd /C "@echo off & call {0} & if errorlevel 1 exit 1"'.format(exec_cmd_string)
- proc = subprocess.Popen(exec_cmd_string, stdout=out_file, stderr=err_file)
+ if family != 'Rcon':
+ proc = subprocess.Popen(exec_cmd_string, stdout=out_file, stderr=err_file)
+ else:
+ proc = subprocess.Popen(exec_cmd_string, stdout=out_file, stderr=subprocess.STDOUT)
else:
raise
@@ -1565,22 +1603,51 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
messages.append('* PythonTeX error')
messages.append(' Missing output file for ' + key_run.replace('#', ':'))
errors += 1
+ elif family == 'juliacon' and proc.returncode == 1:
+ messages.append('* PythonTeX error')
+ messages.append(' Running code for Julia console failed')
+ with open(err_file_name, encoding='utf8') as f:
+ messages.append(f.read())
+ errors += 1
else:
if family == 'juliacon':
with open(out_file_name.rsplit('.', 1)[0] + '.tex', 'r', encoding=encoding) as f:
tex_data_lines = f.readlines()
- inst = 0
+ code_iter = itertools.chain(cc_begin_list, code_list, cc_end_list)
for n, line in enumerate(tex_data_lines):
if line.rstrip() == '\\begin{juliaterm}':
- tex_data_lines[n] = '=>PYTHONTEX:STDOUT#{0}#code#\n'.format(inst) + '\\begin{Verbatim}\n'
- inst += 1
+ c = next(code_iter)
+ tex_data_lines[n] = '=>PYTHONTEX:STDOUT#{0}#code#\n'.format(c.instance)
if n != 0:
tex_data_lines[n-1] = ''
if line.rstrip() == '\\end{juliaterm}':
- tex_data_lines[n] = '\\end{Verbatim}'
+ tex_data_lines[n] = ''
tex_data_lines.append('=>PYTHONTEX:DEPENDENCIES#\n=>PYTHONTEX:CREATED#\n')
with open(out_file_name, 'w', encoding=encoding) as f:
f.write(''.join(tex_data_lines))
+ elif family == 'Rcon':
+ with open(out_file_name, 'r', encoding=encoding) as f:
+ stdout_lines = f.readlines()
+ for n, line in enumerate(stdout_lines):
+ if line.startswith('> =>PYTHONTEX:'):
+ stdout_lines[n] = line[2:]
+ elif '> write("=>PYTHONTEX:' in line:
+ if line.startswith('> write("=>PYTHONTEX:'):
+ stdout_lines[n] = ''
+ else:
+ # cat() and similar functions can result in the
+ # prompt not being at the start of a new line. In
+ # that case, preserve the prompt to accurately
+ # emulate the console. If there is a following
+ # console environment, this effectively amounts
+ # to adding an extra empty line (pressing ENTER)
+ # between the two.
+ stdout_lines[n] = line.split('write("=>PYTHONTEX:', 1)[0]
+ while stdout_lines and (stdout_lines[-1].startswith('>') and not stdout_lines[-1][1:].strip(' \n')):
+ stdout_lines.pop()
+ stdout_lines.append('=>PYTHONTEX:DEPENDENCIES#\n=>PYTHONTEX:CREATED#\n')
+ with open(out_file_name, 'w', encoding=encoding) as f:
+ f.write(''.join(stdout_lines))
f = open(out_file_name, 'r', encoding=encoding)
out = f.read()
@@ -1638,19 +1705,36 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
else:
dependencies[dep] = (os.path.getmtime(dep_file), '')
+ if family in ('juliacon', 'Rcon'):
+ from pygments import highlight
+ from pygments.lexers import get_lexer_by_name
+ from pygments.formatters import LatexFormatter
+ formatter = dict()
+ lexer = dict()
+ for codetype in pygments_settings:
+ if codetype != ':GLOBAL':
+ p = pygments_settings[codetype]['formatter_options'].copy()
+ p['commandprefix'] = 'PYG'
+ formatter[codetype] = LatexFormatter(**p)
+ lexer[codetype] = get_lexer_by_name(pygments_settings[codetype]['lexer'], **p)
for block in out.split('=>PYTHONTEX:STDOUT#')[1:]:
if block:
delims, content = block.split('#\n', 1)
+ if content and not content.endswith('\n'):
+ # Content might not end with a newline. For example,
+ # Rcon with something like cat() as the last function.
+ content += '\n'
instance, command = delims.split('#')
if content or command in ('s', 'sub'):
if instance.endswith('CC'):
- messages.append('* PythonTeX warning')
- messages.append(' Custom code for "' + family + '" attempted to print or write to stdout')
- messages.append(' This is not supported; use a normal code command or environment')
- messages.append(' The following content was written:')
- messages.append('')
- messages.extend([' ' + l for l in content.splitlines()])
- warnings += 1
+ if family not in ('juliacon', 'Rcon'):
+ messages.append('* PythonTeX warning')
+ messages.append(' Custom code for "' + family + '" attempted to print or write to stdout')
+ messages.append(' This is not supported; use a normal code command or environment')
+ messages.append(' The following content was written:')
+ messages.append('')
+ messages.extend([' ' + l for l in content.splitlines()])
+ warnings += 1
elif command == 'i':
content = r'\pytx@SVMCR{pytx@MCR@' + key_run.replace('#', '@') + '@' + instance + '}\n' + content.rstrip('\n') + '\\endpytx@SVMCR\n\n'
macros.append(content)
@@ -1668,6 +1752,8 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
# Remove newline added by printing, prevent
# LaTeX from adding a space after content
content = content.rsplit('\n', 1)[0] + '\\endinput\n'
+ if family in ('juliacon', 'Rcon'):
+ content = highlight(content, lexer[family], formatter[family])
f.write(content)
f.close()
files.append(fname)
@@ -1677,6 +1763,8 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
messages.append('* PythonTeX error')
messages.append(' Missing stderr file for ' + key_run.replace('#', ':'))
errors += 1
+ elif family in ('juliacon', 'Rcon'):
+ pass
else:
# Open error and code files.
f = open(err_file_name, encoding=encoding)
@@ -1715,7 +1803,7 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
index_next = index_now
start_errgobble = None
for n, line in enumerate(err_ud):
- if basename in line:
+ if basename in line and (family not in ('perlsix', 'psix') or '.p6:' in line or '.p6 line' in line):
# Get the gobbleation. This is used to determine if
# other lines containing the basename are a continuation,
# or separate messages.
@@ -1761,7 +1849,7 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
# both the error and warning patterns, default to
# error.
past_line = err_ud[index]
- if (index < n and basename in past_line):
+ if (index < n and basename in past_line and (family not in ('perlsix', 'psix') or '.p6:' in past_line or '.p6 line' in past_line)):
break
for pattern in warningsig:
if pattern in past_line:
@@ -1825,8 +1913,9 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
index_now_last = index_now
index_next_last = index_next
err_key_last_int = -1
+ p6_sorry_search = False
for n, line in enumerate(err_ud):
- if basename in line:
+ if basename in line and (family not in ('perlsix', 'psix') or '.p6:' in line or '.p6 line' in line):
# Determine the corresponding line number in the document
found = False
for pattern in linesig:
@@ -1888,6 +1977,35 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
line = line.replace(fullbasename + '.' + extension, '')
elif stderrfilename == 'genericscript':
line = line.replace(fullbasename + '.' + extension, '
+
+
-
+
General Python interaction
We can typeset code that is passed to Python, and bring back the results.
This can be simple. For example, print('Python says hi!') returns the following:
@@ -62,181 +227,183 @@ General Python interaction
Python says hi!
Python interaction can also be more complex. print(str(2**2**2) + r'\endinput') returns 16. In this case, the printed result includes LaTeX code, which is correctly interpreted by LaTeX to ensure that there is not an extra space after the 16. Printed output is saved to a file and brought back in via \input, and the \endinput command stops input immediately, before LaTeX gets to the end of the line and inserts a space character there, after the 16.
-Printing works, but as the last example demonstrates, you have to be careful about spacing if you have text immediately after the printed content. In that case, it’s usually best to assemble text within a PythonTeX environment and store the text in a variable. Then you can bring in the text later, using the \py command. The \py command brings in a string representation of its argument. First we create the text.
-mytext = '$1 + 1 = {0}$'.format(1 + 1)
+Printing works, but as the last example demonstrates, you have to be careful about spacing if you have text immediately after the printed content. In that case, it’s usually best to assemble text within a PythonTeX environment and store the text in a variable. Then you can bring in the text later, using the \py command. The \py command brings in a string representation of its argument. First we create the text.
+mytext = '$1 + 1 = {0}$'.format(1 + 1)
Then we bring it in: \(1 + 1 = 2\). The \py command can even bring in verbatim content.
We don’t have to typeset the code we’re executing. It can be hidden. And then we can access it later: This is a message from Python.
It is also possible to perform variable substitution or string interpolation. The earlier result could be recreated: \(1 + 1 = 2\).
Pygments highlighting
-PythonTeX supports syntax highlighting via Pygments. Any language supported by Pygments can be highlighted. Unicode is supported. Consider this snippet copied and pasted from a Python 3 interactive session. (Using random strings of Unicode for variable names is probably not a good idea, but PythonTeX will happily highlight it for you.)
->>> âæéöø = 123
->>> ßçñðŠ = 456
->>> âæéöø + ßçñðŠ
-579
+PythonTeX supports syntax highlighting via Pygments. Any language supported by Pygments can be highlighted. Unicode is supported. Consider this snippet copied and pasted from a Python 3 interactive session. (Using random strings of Unicode for variable names is probably not a good idea, but PythonTeX will happily highlight it for you.)
+>>> âæéöø = 123
+>>> ßçñðŠ = 456
+>>> âæéöø + ßçñðŠ
+579
There is also a Pygments command for inline use: \pygment.
Python console environment
-PythonTeX includes an environment that emulates a Python interactive session. Commands are entered within the environment, each line is treated as input to an interactive session, and the result is typeset.
->>> x = 123
->>> y = 345
->>> z = x + y
->>> z
-468
->>> def f(expr):
-... return(expr**4)
-...
->>> f(x)
-228886641
->>> print('Python says hi from the console!')
-Python says hi from the console!
+PythonTeX includes an environment that emulates a Python interactive session. Commands are entered within the environment, each line is treated as input to an interactive session, and the result is typeset.
+>>> x = 123
+>>> y = 345
+>>> z = x + y
+>>> z
+468
+>>> def f(expr):
+... return(expr**4)
+...
+>>> f(x)
+228886641
+>>> print('Python says hi from the console!')
+Python says hi from the console!
It is possible to refer to the values of console variables later on in inline contexts, using the \pycon command. For example, the value of \(z\) was 468.
Basic SymPy interaction
-PythonTeX allows us to perform algebraic manipulations with SymPy and then properly typeset the results.
+PythonTeX allows us to perform algebraic manipulations with SymPy and then properly typeset the results.
We create three variables, and define \(z\) in terms of the other two.
-var('x, y, z')
-z = x + y
+var('x, y, z')
+z = x + y
Now we can access what \(z\) is equal to:
\[z=x + y\]
Many things are possible, including some very nice calculus.
-f = x**3 + cos(x)**5
-g = Integral(f, x)
-\[\int x^{3} + \cos^{5}{\left (x \right )}\, dx=\frac{x^{4}}{4} + \frac{1}{5} \sin^{5}{\left (x \right )} - \frac{2}{3} \sin^{3}{\left (x \right )} + \sin{\left (x \right )}\]
+f = x**3 + cos(x)**5
+g = Integral(f, x)
+\[\int \left(x^{3} + \cos^{5}{\left(x \right)}\right)\, dx=\frac{x^{4}}{4} + \frac{\sin^{5}{\left(x \right)}}{5} - \frac{2 \sin^{3}{\left(x \right)}}{3} + \sin{\left(x \right)}\]
It’s easy to use arbitrary symbols in equations.
-phi = Symbol(r'\phi')
-h = Integral(exp(-phi**2), (phi, 0, oo))
-\[\int_{0}^{\infty} e^{- \phi^{2}}\, d\phi=\frac{\sqrt{\pi}}{2}\]
+phi = Symbol(r'\phi')
+h = Integral(exp(-phi**2), (phi, 0, oo))
+\[\int\limits_{0}^{\infty} e^{- \phi^{2}}\, d\phi=\frac{\sqrt{\pi}}{2}\]
Plots with matplotlib
We can create plots with matplotlib, perfectly matching the plot fonts with the document fonts. No more searching for the code that created a figure!
It is possible to pass page dimensions and similar contextual information from the LaTeX side to the Python side. If you want your figures to be, for example, a particular fraction of the page width, you can pass the value of \textwidth to the Python side, and use it in creating your figures. See \setpythontexcontext in the main documentation for details.
You may want to use matplotlib’s PGF backend when creating plots.
-rc('text', usetex=True)
-rc('font', family='serif')
-rc('font', size=10.0)
-rc('legend', fontsize=10.0)
-rc('font', weight='normal')
-x = linspace(0, 10)
-figure(figsize=(4, 2.5))
-plot(x, sin(x), label='$\sin(x)$')
-xlabel(r'$x\mathrm{-axis}$')
-ylabel(r'$y\mathrm{-axis}$')
-legend(loc='lower right')
-savefig('myplot.png', bbox_inches='tight')
+rc('text', usetex=True)
+rc('font', family='serif')
+rc('font', size=10.0)
+rc('legend', fontsize=10.0)
+rc('font', weight='normal')
+x = linspace(0, 10)
+figure(figsize=(4, 2.5))
+plot(x, sin(x), label='$\sin(x)$')
+xlabel(r'$x\mathrm{-axis}$')
+ylabel(r'$y\mathrm{-axis}$')
+legend(loc='lower right')
+savefig('myplot.png', bbox_inches='tight')
+

+
Basic pylab interaction
-from scipy.integrate import quad
-myintegral = quad(lambda x: e**-x**2, 0, inf)[0]
+from scipy.integrate import quad
+myintegral = quad(lambda x: e**-x**2, 0, inf)[0]
\[\int_0^\infty e^{-x^2}\,dx = 0.886226925452758\]
An automated derivative and integral table
-PythonTeX allows some amazing document automation, such as this derivative and integral table. Try typing that by hand, fast!
-from re import sub
-
-var('x')
-
-# Create a list of functions to include in the table
-funcs = ['sin(x)', 'cos(x)', 'tan(x)',
- 'sin(x)**2', 'cos(x)**2', 'tan(x)**2',
- 'asin(x)', 'acos(x)', 'atan(x)',
- 'sinh(x)', 'cosh(x)', 'tanh(x)']
-
-print(r'\begin{align*}')
-
-for func in funcs:
- # Put in some vertical space when switching to arc and hyperbolic funcs
- if func == 'asin(x)' or func == 'sinh(x)':
- print(r'&\\')
- myderiv = 'Derivative(' + func + ', x)'
- myint = 'Integral(' + func + ', x)'
- print(latex(eval(myderiv)) + '&=' +
- latex(eval(myderiv + '.doit()')) + r'\quad & \quad')
- print(latex(eval(myint)) + '&=' +
- latex(eval(myint+'.doit()')) + r'\\')
-print(r'\end{align*}')
+PythonTeX allows some amazing document automation, such as this derivative and integral table. Try typing that by hand, fast!
+from re import sub
+
+var('x')
+
+# Create a list of functions to include in the table
+funcs = ['sin(x)', 'cos(x)', 'tan(x)',
+ 'sin(x)**2', 'cos(x)**2', 'tan(x)**2',
+ 'asin(x)', 'acos(x)', 'atan(x)',
+ 'sinh(x)', 'cosh(x)', 'tanh(x)']
+
+print(r'\begin{align*}')
+
+for func in funcs:
+ # Put in some vertical space when switching to arc and hyperbolic funcs
+ if func == 'asin(x)' or func == 'sinh(x)':
+ print(r'&\\')
+ myderiv = 'Derivative(' + func + ', x)'
+ myint = 'Integral(' + func + ', x)'
+ print(latex(eval(myderiv)) + '&=' +
+ latex(eval(myderiv + '.doit()')) + r'\quad & \quad')
+ print(latex(eval(myint)) + '&=' +
+ latex(eval(myint+'.doit()')) + r'\\')
+print(r'\end{align*}')
\[\begin{aligned}
-\frac{d}{d x} \sin{\left (x \right )}&=\cos{\left (x \right )}\quad & \quad
-\int \sin{\left (x \right )}\, dx&=- \cos{\left (x \right )}\\
-\frac{d}{d x} \cos{\left (x \right )}&=- \sin{\left (x \right )}\quad & \quad
-\int \cos{\left (x \right )}\, dx&=\sin{\left (x \right )}\\
-\frac{d}{d x} \tan{\left (x \right )}&=\tan^{2}{\left (x \right )} + 1\quad & \quad
-\int \tan{\left (x \right )}\, dx&=- \frac{1}{2} \log{\left (\sin^{2}{\left (x \right )} - 1 \right )}\\
-\frac{d}{d x} \sin^{2}{\left (x \right )}&=2 \sin{\left (x \right )} \cos{\left (x \right )}\quad & \quad
-\int \sin^{2}{\left (x \right )}\, dx&=\frac{x}{2} - \frac{1}{2} \sin{\left (x \right )} \cos{\left (x \right )}\\
-\frac{d}{d x} \cos^{2}{\left (x \right )}&=- 2 \sin{\left (x \right )} \cos{\left (x \right )}\quad & \quad
-\int \cos^{2}{\left (x \right )}\, dx&=\frac{x}{2} + \frac{1}{2} \sin{\left (x \right )} \cos{\left (x \right )}\\
-\frac{d}{d x} \tan^{2}{\left (x \right )}&=\left(2 \tan^{2}{\left (x \right )} + 2\right) \tan{\left (x \right )}\quad & \quad
-\int \tan^{2}{\left (x \right )}\, dx&=- x + \frac{\sin{\left (x \right )}}{\cos{\left (x \right )}}\\
+\frac{d}{d x} \sin{\left(x \right)}&=\cos{\left(x \right)}\quad & \quad
+\int \sin{\left(x \right)}\, dx&=- \cos{\left(x \right)}\\
+\frac{d}{d x} \cos{\left(x \right)}&=- \sin{\left(x \right)}\quad & \quad
+\int \cos{\left(x \right)}\, dx&=\sin{\left(x \right)}\\
+\frac{d}{d x} \tan{\left(x \right)}&=\tan^{2}{\left(x \right)} + 1\quad & \quad
+\int \tan{\left(x \right)}\, dx&=- \log{\left(\cos{\left(x \right)} \right)}\\
+\frac{d}{d x} \sin^{2}{\left(x \right)}&=2 \sin{\left(x \right)} \cos{\left(x \right)}\quad & \quad
+\int \sin^{2}{\left(x \right)}\, dx&=\frac{x}{2} - \frac{\sin{\left(x \right)} \cos{\left(x \right)}}{2}\\
+\frac{d}{d x} \cos^{2}{\left(x \right)}&=- 2 \sin{\left(x \right)} \cos{\left(x \right)}\quad & \quad
+\int \cos^{2}{\left(x \right)}\, dx&=\frac{x}{2} + \frac{\sin{\left(x \right)} \cos{\left(x \right)}}{2}\\
+\frac{d}{d x} \tan^{2}{\left(x \right)}&=\left(2 \tan^{2}{\left(x \right)} + 2\right) \tan{\left(x \right)}\quad & \quad
+\int \tan^{2}{\left(x \right)}\, dx&=- x + \frac{\sin{\left(x \right)}}{\cos{\left(x \right)}}\\
&\\
-\frac{d}{d x} \operatorname{asin}{\left (x \right )}&=\frac{1}{\sqrt{- x^{2} + 1}}\quad & \quad
-\int \operatorname{asin}{\left (x \right )}\, dx&=x \operatorname{asin}{\left (x \right )} + \sqrt{- x^{2} + 1}\\
-\frac{d}{d x} \operatorname{acos}{\left (x \right )}&=- \frac{1}{\sqrt{- x^{2} + 1}}\quad & \quad
-\int \operatorname{acos}{\left (x \right )}\, dx&=x \operatorname{acos}{\left (x \right )} - \sqrt{- x^{2} + 1}\\
-\frac{d}{d x} \operatorname{atan}{\left (x \right )}&=\frac{1}{x^{2} + 1}\quad & \quad
-\int \operatorname{atan}{\left (x \right )}\, dx&=x \operatorname{atan}{\left (x \right )} - \frac{1}{2} \log{\left (x^{2} + 1 \right )}\\
+\frac{d}{d x} \operatorname{asin}{\left(x \right)}&=\frac{1}{\sqrt{1 - x^{2}}}\quad & \quad
+\int \operatorname{asin}{\left(x \right)}\, dx&=x \operatorname{asin}{\left(x \right)} + \sqrt{1 - x^{2}}\\
+\frac{d}{d x} \operatorname{acos}{\left(x \right)}&=- \frac{1}{\sqrt{1 - x^{2}}}\quad & \quad
+\int \operatorname{acos}{\left(x \right)}\, dx&=x \operatorname{acos}{\left(x \right)} - \sqrt{1 - x^{2}}\\
+\frac{d}{d x} \operatorname{atan}{\left(x \right)}&=\frac{1}{x^{2} + 1}\quad & \quad
+\int \operatorname{atan}{\left(x \right)}\, dx&=x \operatorname{atan}{\left(x \right)} - \frac{\log{\left(x^{2} + 1 \right)}}{2}\\
&\\
-\frac{d}{d x} \sinh{\left (x \right )}&=\cosh{\left (x \right )}\quad & \quad
-\int \sinh{\left (x \right )}\, dx&=\cosh{\left (x \right )}\\
-\frac{d}{d x} \cosh{\left (x \right )}&=\sinh{\left (x \right )}\quad & \quad
-\int \cosh{\left (x \right )}\, dx&=\sinh{\left (x \right )}\\
-\frac{d}{d x} \tanh{\left (x \right )}&=- \tanh^{2}{\left (x \right )} + 1\quad & \quad
-\int \tanh{\left (x \right )}\, dx&=x - \log{\left (\tanh{\left (x \right )} + 1 \right )}\\\end{aligned}\]
+\frac{d}{d x} \sinh{\left(x \right)}&=\cosh{\left(x \right)}\quad & \quad
+\int \sinh{\left(x \right)}\, dx&=\cosh{\left(x \right)}\\
+\frac{d}{d x} \cosh{\left(x \right)}&=\sinh{\left(x \right)}\quad & \quad
+\int \cosh{\left(x \right)}\, dx&=\sinh{\left(x \right)}\\
+\frac{d}{d x} \tanh{\left(x \right)}&=1 - \tanh^{2}{\left(x \right)}\quad & \quad
+\int \tanh{\left(x \right)}\, dx&=x - \log{\left(\tanh{\left(x \right)} + 1 \right)}\\\end{aligned}\]
Step-by-step solutions
Using SymPy, it is possible to typeset step-by-step solutions. In this particular case, we also use the mdframed package to place a colored background behind our code.
-x, y, z = symbols('x,y,z')
-f = Symbol('f(x,y,z)')
-
-# Define limits of integration
-x_llim = 0
-x_ulim = 2
-y_llim = 0
-y_ulim = 3
-z_llim = 0
-z_ulim = 4
-
-print(r'\begin{align*}')
-
-# Notice how I define f as a symbol, then later as an actual function
-left = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim))
-f = x*y + y*sin(z) + cos(x+y)
-right = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim))
-print(latex(left) + '&=' + latex(right) + r'\\')
-
-# For each step, I move limits from an outer integral to an inner, evaluated
-# integral until the outer integral is no longer needed
-right = Integral(Integral(f, (z, z_llim, z_ulim)).doit(), (x, x_llim, x_ulim),
- (y, y_llim, y_ulim))
-print('&=' + latex(right) + r'\\')
-
-right = Integral(Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim)).doit(),
- (x, x_llim, x_ulim))
-print('&=' + latex(right) + r'\\')
-
-right = Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim),
- (x, x_llim, x_ulim)).doit()
-print('&=' + latex(right) + r'\\')
-
-print('&=' + latex(N(right)) + r'\\')
-
-print(r'\end{align*}')
+x, y, z = symbols('x,y,z')
+f = Symbol('f(x,y,z)')
+
+# Define limits of integration
+x_llim = 0
+x_ulim = 2
+y_llim = 0
+y_ulim = 3
+z_llim = 0
+z_ulim = 4
+
+print(r'\begin{align*}')
+
+# Notice how I define f as a symbol, then later as an actual function
+left = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim))
+f = x*y + y*sin(z) + cos(x+y)
+right = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim))
+print(latex(left) + '&=' + latex(right) + r'\\')
+
+# For each step, I move limits from an outer integral to an inner, evaluated
+# integral until the outer integral is no longer needed
+right = Integral(Integral(f, (z, z_llim, z_ulim)).doit(), (x, x_llim, x_ulim),
+ (y, y_llim, y_ulim))
+print('&=' + latex(right) + r'\\')
+
+right = Integral(Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim)).doit(),
+ (x, x_llim, x_ulim))
+print('&=' + latex(right) + r'\\')
+
+right = Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim),
+ (x, x_llim, x_ulim)).doit()
+print('&=' + latex(right) + r'\\')
+
+print('&=' + latex(N(right)) + r'\\')
+
+print(r'\end{align*}')
\[\begin{aligned}
-\int_{0}^{4}\int_{0}^{3}\int_{0}^{2} f(x,y,z)\, dx\, dy\, dz&=\int_{0}^{4}\int_{0}^{3}\int_{0}^{2} x y + y \sin{\left (z \right )} + \cos{\left (x + y \right )}\, dx\, dy\, dz\\
-&=\int_{0}^{3}\int_{0}^{2} 4 x y - y \cos{\left (4 \right )} + y + 4 \cos{\left (x + y \right )}\, dx\, dy\\
-&=\int_{0}^{2} 18 x - 4 \sin{\left (x \right )} + 4 \sin{\left (x + 3 \right )} - \frac{9}{2} \cos{\left (4 \right )} + \frac{9}{2}\, dx\\
-&=4 \cos{\left (3 \right )} + 4 \cos{\left (2 \right )} - 4 \cos{\left (5 \right )} - 9 \cos{\left (4 \right )} + 41\\
+\int\limits_{0}^{4}\int\limits_{0}^{3}\int\limits_{0}^{2} f(x,y,z)\, dx\, dy\, dz&=\int\limits_{0}^{4}\int\limits_{0}^{3}\int\limits_{0}^{2} \left(x y + y \sin{\left(z \right)} + \cos{\left(x + y \right)}\right)\, dx\, dy\, dz\\
+&=\int\limits_{0}^{3}\int\limits_{0}^{2} \left(4 x y - y \cos{\left(4 \right)} + y + 4 \cos{\left(x + y \right)}\right)\, dx\, dy\\
+&=\int\limits_{0}^{2} \left(18 x - 4 \sin{\left(x \right)} + 4 \sin{\left(x + 3 \right)} - \frac{9 \cos{\left(4 \right)}}{2} + \frac{9}{2}\right)\, dx\\
+&=4 \cos{\left(3 \right)} + 4 \cos{\left(2 \right)} - 4 \cos{\left(5 \right)} - 9 \cos{\left(4 \right)} + 41\\
&=40.1235865133293\\\end{aligned}\]
Including stderr
-PythonTeX allows code to be typset next to the stderr it produces. This requires the package option makestderr.
-x = 123
-y = 345
-z = x + y +
+PythonTeX allows code to be typset next to the stderr it produces. This requires the package option makestderr.
+x = 123
+y = 345
+z = x + y +
This code causes a syntax error:
File "py_errorsession_9.py", line 3
z = x + y +
^
SyntaxError: invalid syntax
The package option stderrfilename allows the file name that appears in the error message to be customized.
-
+