\documentclass[12pt]{article}
\usepackage{hybrid}

\begin{document}

\lstset{%
basicstyle={\tts},basewidth={0.50em},
numbers=none,numberstyle=\tiny,numbersep=10pt,
aboveskip=10pt,belowskip=0pt,
frame=single,framesep=2pt,framerule=0pt}

\bgcolour{grey95}

\begin{center}
   {\Large\bf A hybrid LaTeX collection.}\\[20pt]
   {Leo Brewin}\\[5pt]
   {School of Mathematics, Monash University}\\[5pt]
   {\tts Leo.Brewin@monash.edu}\\[5pt]
   {August 2018}\\[10pt]
   {Version 0.1}\\[10pt]
   {\href{https://github.com/leo-brewin/hybrid-latex}{https://github.com/leo-brewin/hybrid-latex}}\\[20pt]
   {\bf\small Abstract}\\[10pt]
   {\small\MyPar{0.80}%
      {This collection of LaTeX packages and Python scripts provides simple
      tools to allow active Python to be embedded in a LaTeX document.
      It does this by defining
      a number of simple macros and Python scripts that build a bridge between
      the output generated by the active code and the LaTeX code. Each language
      is defined independently of the other languages. The scripts and macros
      for one language are almost identical to those for the other languages in
      the collection differing only in the names of the macros and some minor
      language specific tweaks.
      This makes it a simple matter to extend the collection to other languages.}}
\end{center}

\vskip 1cm

\parindent=0pt
\parskip=0pt plus 0pt minus 0pt

\tableofcontents

\vfill

\clearpage

\parindent=0pt
\parskip=8pt plus 2pt minus 1pt

\section{Introduction}

Programs like Mathematica, Maple, Python and so on do a wonderful job of symbolic,
numeric and graphical computations. On the other hand, LaTeX produces exceptional
typeset documents but is less adept at symbolic and other forms of computation. It
is a case of horses for courses. A common approach is to use one or more codes (in
Python, Maple etc.) to do the computations and a separate LaTeX code to collect and
document the results. It seems reasonable then to attempt to consolidate these
separate codes into a single hybrid LaTeX document. That is the main purpose of
this collection -- to provide tools that support active code within a LaTeX
document.

This document describes the CTAN version of this package. An extended version
of the pacakge that allows inclusion of Python, Mathematica, Maple, Matlab and
Cadabra code can be found on the
{\href{https://github.com/leo-brewin/hybrid-latex}{GitHub repository}}.

\section{The pyLaTeX package}

There are other packages that do the same job, such as
\href{https://github.com/gpoore/pythontex}{\PythonTeX} and
\href{https://github.com/sagemath/sagetex}{\SageTeX}. In each case the journey from
source to pdf is similar; the Python code is mined from the LaTeX source, passed
over to Python and the output feed back into the LaTeX source. The packages differ
in both the tools used to mine the Python code and the manner in which the output
is made visible to the LaTeX source.

In both \PythonTeX\ and \SageTeX, the Python code is mined using a first pass of
LaTeX whereas \pyLaTeX\ uses a Python script to do the same job. There are two main
reasons for adopting Python as the code miner. First, it is much easier to extend
\pyLaTeX\ to incorporate other foreign languages (such as Mathematica, Matlab,
Cadabra etc.). Doing so in \PythonTeX\ and \SageTeX\ requires careful tweaking of
the underlying LaTeX class files -- such adventures requires a solid understanding
of the LaTeX programming language and is not for the faint of heart. The second
reason is that LaTeX is not the ideal tool to mine Python (or any other code) from
a LaTeX document. There are much better text processing tools (such as Python) that
can do the same job while being much easier (for the developer) to read, debug and
extend.

There are also some important differences in the way the end user accesses the
Python output for use in the LaTeX source. In \PythonTeX\ and \SageTeX\ the Python
output is saved to a collection of files (roughly one file per Python code block)
while \pyLaTeX\ creates a single file. In all cases the contents of these files are
made available to the LaTeX source by way of special LaTeX macros. The \PythonTeX\
and \SageTeX\ output files are tightly coupled to the original LaTeX source. This
means that their contents can not be easily shared with other LaTeX sources
(without manual intervention). In contrast, the \pyLaTeX\ output is a single file
that contains a collection of LaTeX macros, one for each piece of (tagged) Python
output, that can be read by any other LaTeX source. Thus a user could split a
larger LaTeX source into a collection of smaller sources (e.g., chapters of a book)
with the Python output included as needed. An example of this sharing of Python
output can be found in the examples directory. The file {\tts summary.tex} does no
symbolic calculations of its own but instead pulls in selected parts of the Python
output from other examples in that directory.

Another important difference between \pyLaTeX\ and \PythonTeX\ and \SageTeX\ is
that \pyLaTeX\ uses tags to nominate which pieces of the Python output should be
made available to the LaTeX source. Both \PythonTeX\ and \SageTeX\ allow all Python
output to accessed in the LaTeX source. The problem with that method is that it is
not possible to record the history of a single Python expression. For example, if
the Python code computes the expression {\tts foo} five times then only the fifth
instance will be seen by LaTeX.

\section{Requirements}

\subsection{Latex}
The \pyLaTeX\ package draws on a number of latex packages all of which should be
available in any recent LaTeX distribution. The examples described in this document
were run using the {\tts TeXLive-2018} distribution for macOS.

The \pyLaTeX\ package provides both a normal style file, {\tts pylatex.sty} and a
class file {\tts pylatex.cls}. The preamble to the style file contains the
following declarations.

\vskip 12pt

\begin{latex}
   \usepackage{comment}
   \usepackage{listings}
   \usepackage{keyval}
   \usepackage{etoolbox}
   \usepackage{xcolor}
   \usepackage{pymacros}
\end{latex}

The {\tts pymacros} package is a key part of the \pyLaTeX\ collection as it defines
the core macros for \pyLaTeX.

The class file first includes the style file then executes the following statements

\vskip 12pt

\begin{latex}
   \usepackage[papersize={297mm,210mm},
               hmargin=2cm,tmargin=1.0cm,bmargin=1.5cm]{geometry}
   \usepackage{amsmath}
   \usepackage{amssymb}
   \usepackage{hyperref}
   \usepackage{breqn}
\end{latex}

The extra packages included in the class file are not essential but have proven
useful in many cases and thus are included as a convenient default. Note that the
options to the geometry package sets the output to A4 landscape format. This can be
changed, either by editing the class file or by including a line like the following
somewhere in the preamble of the users document.

\vskip 6pt

\begin{latex}
  \geometry{margin=2.0cm,paperheight=25cm}
\end{latex}

\subsection{Python}
There are no particular requirements on the Python environment in order to use the
\pyLaTeX\ package though the examples listed below do require {\tts sympy} version
1.1.1 or later. The simple measure is that if your embedded Python code can be run
in your normal Python environment then that same code should work equally well
using \pyLaTeX. All of the examples described in this document were run under macOS
using the default Apple Python environment (Python 2.7) as well as under the
Anaconda 5.2 (Python3.6) environment.

\section{Setup}

There is no setup tool as you only have a few files to install. The following files
can be found inside the {\tts Python} directory of the hybrid collection.

\begin{tabular}{rl}
{\tts shell/pylatex.sh}:&Copied to anywhere that is visible on your path.\\[5pt]
{\tts python/pypostproc.py}:&Copied to anywhere that is visible on your path.\\
{\tts python/pypreproc.py}:&Ditto\\
{\tts python/merge-tex.py}:&Ditto\\[5pt]
{\tts latex/pylatex.cls}:&Copied to anywhere that is visible to LaTeX.\\
{\tts latex/pylatex.sty}:&Ditto\\
{\tts latex/pymacros.sty}:&Ditto
\end{tabular}

For example, the shell and Python scripts could be copied to {\tts
\$HOME/local/sh/} while the LaTeX files could be copied to {\tts
\$HOME/tex/inputs/}. Provided those directories are on the appropriate paths (i.e.,
PATH and TEXINPUTS), that should be all that needs doing.

Note that each of the Python scripts uses the following shebang (i.e., the first
line in the file)

\begin{lstlisting}
#!/usr/local/bin/python3
\end{lstlisting}

You may need to change this to match the path to your version of {\tts python3}.

\section{Compiling}
To compile the file {\tts foo.tex} use

\begin{lstlisting}
   pylatex.sh -i foo
\end{lstlisting}

The {\tts pylatex.sh} script will call Pyhton and LaTeX as required to produce the
pdf output. Along the way a number of intermediate files will be created (most of
which will be deleted by default). Using the above command will produce not only
the pdf but also {\tts foo.pytex}. This file contains a list of macros, one for
each \pyLaTeX\ tag in {\tts foo.tex}, that are executed when the \pyLaTeX\ macros
such as {\tts\verb|\py{bah}|} are called (in this case {\tts bah} is a tag
associated with part of the Python code in the {\tts foo.tex} source). This same
file can also be included in other LaTeX files using
{\tts\verb|\input{foo.pytex}|}. This makes the Python output from {\tts foo.tex}
available to other LaTeX files.

Executing {\tts pylatex.sh} with the {\tts -h} flag will produce the following
usage information.

\begin{lstlisting}
   usage : pylatex.sh -i file [-I<path to pymacros.sty>]
                              [-P<path to python>] [-s] [-k] [-x] [-h]
   options :  -i file : source file (without .tex extension)
              -I file : full path to pymacros.sty file
              -P path : where to find the Python binary
              -s : silent, don't open the pdf file
              -k : keep all temporary files
              -x : don't call latex
              -h : this help message
   example : pylatex.sh -i file -P/usr/local/bin/python
\end{lstlisting}

The intermediate files produced by the {\tts -k} option are (excluding the
standard LaTeX files)

\bgroup
\def\MYn{\vrule height  0pt depth  5pt width 0pt}
\def\MYN{\vrule height  0pt depth  0pt width 0pt}
\begin{tabular}{rl}
   {\tts foo.py:}&\MyPar{0.75}%
      {A copy of all the Python code stripped bare of (most) tags.}\\
   {\tts foo_.py:}&\MyPar{0.75}%
      {Similar to {\tts foo.py} but with additional Python code to catch Python
      output for the \pyLaTeX\ tags.}\\
   {\tts foo.pyidx:}&\MyPar{0.75}%
      {An index of all \pyLaTeX\ tags.}\\
   {\tts foo.pytex:}&\MyPar{0.75}%
      {A set of macros, one for each tag, expanding to the Python output.}\\
   {\tts foo.pytxt:}&\MyPar{0.75}%
      {The raw Python output from {\tts foo_.py}.}
\end{tabular}
\egroup

The {\tts -k} option is useful in cases where there is a bug in the users Python
code. This option will force {\tts pylatex.sh} to retain all intermediate files,
in particular the mined Python code {\tts foo.py}. This file can then be debugged
and in turn the original LaTeX source can be corrected.

The {\tts -I} option can be used in cases where the output from {\tts foo.tex} is
intended for use in other LaTeX sources that do not use the \pyLaTeX\ style file
{\tts pylatex.sty}. This could be useful for sharing results with colleagues who
have not installed the \pyLaTeX\ package or when submitting a paper to a journal.
The nett effect of the {\tts -I} option is to prepend the {\tts foo.pytex} file
with the LaTeX definitions for all of the \pyLaTeX\ macros. Another approach would
be to not use the {\tts -I} but share both the {\tts foo.pytex} and {\tts
pymacros.sty} file with colleagues or journals.

The only files that must be kept are {\tts foo.tex} (obviously) and {\tts
foo.pytex}. This pair of files alone is sufficient for successful execution of
LaTeX. The file {\tts foo.pytex} only needs to be recreated (using {\tts
pylatex.sh}) when changes have been made to the Python code in {\tts foo.tex}.

It is important to note that the Python code mined from the LaTeX source will be
written to a single file. Thus it is important that all parts of this file
interact harmoniously. If there is any possibility that one part of the (combined)
code may adversely effect other parts then some action must be taken. One solution
is to use language features of Python to avoid the clash, such as placing
conflicting code in separate functions. Another solution is to move the
conflicting code to separate LaTeX documents, run {\tts pylatex.sh} over each
document, then include the results in the original LaTeX source using
{\tts\verb|\input|} on the corresponding {\tts .pytex} files.

\subsection{Caution}

Be very careful -- each of the above named temporary files will overwrite any
existing files of the same name. An easy road to disaster lies this way. Suppose
you have an existing Python file named {\tts foo.py} and suppose you wish to catch
its output for later use in some other LaTeX document. You might start by creating
a wrapper file, {\tts foo.tex}, such as the following

\vspace{10pt}

\PySetup{action=verbatim}

% note: the * in the 1st column is to ensure the python preprocessor does not respond
%       to any of the \begin{...} or \end{...} lines. The \end{document} line is the
%       real problem as it terminates the preprocessing.

\bgroup
\bgcolour{white}
\begin{latex}
*  \documentclass[12pt]{pylatex}
*  \begin{document}
*     \begin{python}
*        \Input{foo.py}
*     \end{python}
*  \end{document}
\end{latex}
\egroup

\PySetup{action=show}

The {\tts pylatex.sh} will expand the {\tts\verb|\Input{foo.py}|} command to
include the contents of {\tts foo.py}. No damage done -- so far. But now {\tts
pylatex.sh} will read the newly merged file and will create its own version of
{\tts foo.py} without \emph{any} of the \pyLaTeX\ tags. Thus any subsequent
processing of {\tts foo.tex} will \emph{not} capture any Python output -- because
all of the Python tags have been deleted.

\subsection{The pypreproc.py and pypostproc.py scripts}

The job of the {\tts pypreproc.py} script is to harvest the Python code from the
LaTeX source. For a source named {\tt foo.tex} the script could be run using

\begin{lstlisting}
   pypreproc.py -i foo
\end{lstlisting}

This will produce {\tts foo.py, foo_.py} and {\tts foo.pyidx}. The file {\tts
foo.py} is an almost\footnote{It may retain a few comments.} exact copy of the
active Python code while {\tts foo_.py} is a version of {\tts foo.py} containing
extra Python commands to catch the nominated Python output. This file is passed to
Python to create the {\tts foo.pytxt} file which in turn is passed to {\tts
pypostproc.py} using

\begin{lstlisting}
   pypostproc.py -i foo
\end{lstlisting}

which should create the {\tts foo.pytex} file.

The pre and post processor scripts, {\tts pypreproc.py} and {\tts pypreproc.py},
would rarely be used on their own. Though if something fails in the execution of
the {\tts pylatex.sh} script it might prove useful to run these scripts on their
own. Bug reports are always welcome (working on the time proven axiom that no code
is ever bug free).

\subsection{The merge-tex.py script}

A common practice when writing LaTeX documents is to use a driver file to pull in
other smaller LaTeX documents (e.g., a driver for a book could pull in the
chapters as separate documents). Each of the chapters could contain some active
Python code -- so how can such code be made visible to the Python preprocessor
{\tts pypreproc.py}? That is the job of the {\tts merge-tex.py} script. It will
read each file and copy the contents to a single merged file (named {\tts
.merged.tex}). This file is then read by {\tts pypreproc.py}. Not all included
files will contain active Python code so {\tts merge-tex.py} only looks for lines
like {\tts\verb|\Input{foo.tex}|}. Other files included using {\tts\verb|\input|}
or {\tts\verb|\include|} are ignored by {\tts merge-tex.py}. Thus the {\tts
.merged.tex} need not be a faithful copy of the original source -- but that is not
a problem since {\tts .merged.tex} exists solely for {\tts pypreproc.py} to
harvest the active code after which it is no longer used.

The {\tts merge-tex.py} script is language agnostic -- all it does is read its
input and respond to any {\tts \verb|\Input|} lines. If the input file is {\tts
foo.tex} then a merged file {\tts bah.tex} can be created using

\begin{lstlisting}
   merge-tex.py -i foo.tex -o bah.tex
\end{lstlisting}

Note that the {\tts .tex} file extensions \emph{are} required (unlike {\tts
pypreproc.py} and {\tts pypostproc.py}).

Note also that {\tts merge-tex.py} will follow nested files up to 10 deep.

\section{Usage}

Using \pyLaTeX\ entails the addition of user defined tags, in the form of Python
comments, within the LaTeX source. These tags serve to connect the Python output
to the LaTeX source. A typical example is shown in the following code.

\vspace{10pt}

\PySetup{action=verbatim}

% Note: The * in the 1st column is to ensure the python preprocessor does not respond
%       to any of the \begin{...} or \end{...} lines. The \end{document} line is the
%       real problem as it terminates the preprocessing.
%       The * is hidden from LaTeX by way of the listinings option gobble=2.

\bgroup
\bgcolour{white}
\latexstyle
\begin{latex}
*  \documentclass[12pt]{pylatex}
*  \begin{document}
*     \begin{python}
\end{latex}
\pythonstyle
\begin{python}
*        from sympy import *
*        x = Symbol('x')
*        ans    = exp(-x)                # py (ans.01,ans)
*        taylor = ans.series(x, 0, 4)    # py (ans.02,taylor)
*        taylor = ans.series(x, 0, 8)    # py (ans.03,taylor)
\end{python}
\latexstyle
\begin{latex}
*     \end{python}
*     \begin{align*}
*        &\py*{ans.01}\\
*        &\py*{ans.02}\\
*        &\py*{ans.03}
*     \end{align*}
*  \end{document}
\end{latex}
\egroup

\PySetup{action=show}

This will lead to a pdf file that contains not just the Python output but also,
for reference, a copy of the Python source (though this can be suppressed, see the
section \hyperlink{sec:custom}{below} on customisation).

\vspace{5pt}

\begin{python}
   from sympy import *
   x = Symbol('x')
   ans    = exp(-x)                # py (ans.01,ans)
   taylor = ans.series(x, 0, 4)    # py (ans.02,taylor)
   taylor = ans.series(x, 0, 8)    # py (ans.03,taylor)
\end{python}
\vspace{-10pt}
\begin{align*}
   &\py*{ans.01}\\
   &\py*{ans.02}\\
   &\py*{ans.03}
\end{align*}

The key elements to note are the \pyLaTeX\ tags (e.g., {\tts py(ans.01,ans)}) and
the Python environment block. The tags are always part of a Python comment and are
always of the form {\tts py(foo,bah)} where {\tts bah} is a Python symbol (or any
printable entity) and {\tts foo} is the tag (later used in the LaTeX source). The
\pyLaTeX\ tag can be any string of characters from the set {\tts a-zA-Z0-9.\_}. In
the above example there are three tags, {\tts ans.01, ans.02} and {\tts ans.03}.
The dot postfix is not essential but it provides a simple way to record a sequence
of Python outputs. These tags are used later in the body of the LaTeX code and are
accessed in the above example using the \pyLaTeX\ macro {\tts\verb|\py|}. This
macro takes just one argument namely the corresponding \pyLaTeX\ tag. The macro
{\tts\verb|\py{foo}|} will expand to the Python output for the tag {\tts foo}.
Other macros are provided such as {\tts\verb|\py*{foo}|} which will expand to
{\tts foo := } followed by the Python output. The full set of macros are described
in the section \hyperlink{sec:pylatexmacros}{LaTeX macros}.

The \pyLaTeX\ tags can be placed anywhere within the Python block. In the above
example the tags were placed on the same line as the Python code. This is just for
aesthetic effect -- they could equally well have been located on following lines.
The \pyLaTeX\ tags should be unique within the LaTeX file. If the same tag name is
used more than once the output associated with that tag will be from the last
instance of that tag.

Note that the {\tts pypreproc.py} script will interpret {\tts py(foo)} as a
shorthand for {\tts py(foo,foo)}.

\subsection{Undefined tags}

If any of the \pyLaTeX\ macros are called for a tag that was \emph{not} defined
then \hbox{(??)} will be printed. Note that this may cause a LaTeX syntax error
when the \hbox{(??)} appears in an unexpected context (e.g., in cases where the
output of {\tts\verb|\py|} was expected to expand to one or more
{\tts\verb|\\|}'s).

\subsection{Tagged blocks}

There is a second form of tag, known as a tagged block, in which a block of Python
code is enclosed in a matching {\tts\verb|# pyBeg(foo)|},
{\tts\verb|# pyEnd(foo)|} pair. An example of a tagged block can be seen in the
following code. The tag is given the name {\tts Pascal} and can be accessed in the
LaTeX code using any of the \pyLaTeX\ macros, in this case {\tts\verb|\py|}. The
intention of tagged blocks is that they can be used to capture any Python output
generated within the tagged block (except the output that is caught by simple tags
such as shown in the previous example).

Here is a short example\footnote{This example is very \emph{inefficient} as it
uses recursive calls for \emph{every} element in the table.} that demonstrates the
use of a single tagged block.

\vspace{10pt}

\PySetup{action=verbatim}

% note: the * in the 1st column is to ensure the python preprocessor does not respond
%       to any of the \begin{...} or \end{...} lines. The \end{document} line is the
%       real problem as it terminates the preprocessing.

\bgroup
\bgcolour{white}
\latexstyle
\begin{latex}
*  \documentclass[12pt]{pylatex}
*  \begin{document}
*
*     \begin{python}
\end{latex}
\pythonstyle
\begin{python}
*        def build(n):
*            if n==0:
*               return [1]
*            else:
*               P = build(n-1)
*               return [1] + [P[i]+P[i+1] for i in range(n-1)] + [1]
*
*        def display(n):
*            for i in range(n):
*                ans = ""
*                for j in range(0,len(build(i))):
*                   ans = ans + "\m{" + str(build(i)[j]) + "}"
*                print (ans+"\cr")
*
*        # pyBeg (Pascal)
*        display(7)
*        # pyEnd (Pascal)
\end{python}
\latexstyle
\begin{latex}
*     \end{python}
*
*     \def\m#1{\hbox to 1cm{\hfill #1\hfill}}
*     \halign{\hbox to \textwidth{\hfill#\hfill}\cr\py{Pascal}}
*
*  \end{document}
\end{latex}
\egroup

\PySetup{action=hide}

\begin{python}
  def build(n):
      if n==0:
         return [1]
      else:
         P = build(n-1)
         return [1] + [P[i]+P[i+1] for i in range(n-1)] + [1]

  def display(n):
      for i in range(n):
          ans = ""
          for j in range(0,len(build(i))):
             ans = ans + "\m{" + str(build(i)[j]) + "}"
          print (ans+"\cr")

  # pyBeg (Pascal)
  display(7)
  # pyEnd (Pascal)
\end{python}

\clearpage

\PySetup{action=show}

The output of the above code (excluding the echoed Python code) is Pascal's triangle (as expected).

\def\m#1{\hbox to 1cm{\hfill #1\hfill}}
\halign{\hbox to \textwidth{\hfill#\hfill}\cr\py{Pascal}}

All Python code must be contained within the Python environment block, i.e.,
within a {\tts\verb|\begin{python}|} {\tts\verb|...|} {\tts\verb|\end{python}|}
pair. There is no facility to allow \emph{inline} execution of Python code (though
this is allowed in other packages, notably \PythonTeX). The reason for taking this
approach was to force a clear separation between native LaTex code and active
Python blocks. This makes it easier to locate the Python code. If an inline
calculation is needed then it is a simple matter of including the Python code in a
Python block and using a tag to catch and display the result.

Tagged blocks can be nested (though it is not clear what use this might serve) and
they can contain simple tags. The simple tags will always take priority over
tagged blocks in capturing Python output. Tagged blocks should respect the usual
rules of begin-end blocks -- they can nested but they must not overlap. The Python
pre and post processors (within the {\tts pylatex.sh} script) will report errors
when tagged blocks are not properly structured (i.e., overlapping, unmatched {\tts
pyBeg/pyEnd} items etc.).

\subsection{LaTeX macros}
\hypertarget{sec:pylatexmacros}{}

The \pyLaTeX\ package provides a number commands for typesetting tagged expressions.

\newbox\Slashpya
\setbox\Slashpya=\hbox{\tts\verb|\py{foo}|}

\newbox\Slashpyb
\setbox\Slashpyb=\hbox{\tts\verb|\py*{foo}|}

\newbox\SlashPya
\setbox\SlashPya=\hbox{\tts\verb|\Py{foo}|}

\newbox\SlashPyb
\setbox\SlashPyb=\hbox{\tts\verb|\Py*[bah]{foo}|}

\newbox\Slashhfill
\setbox\Slashhfill=\hbox{\tts\verb|[\hfill]|}

\newbox\SlashPySetup
\setbox\SlashPySetup=\hbox{\tts\verb|\PySetup{key=value}|}

\newbox\SlashDmatha
\setbox\SlashDmatha=\hbox{\tts\verb|\Dmath[bah]{foo}|}

\newbox\SlashDmathb
\setbox\SlashDmathb=\hbox{\tts\verb|\Dmath*[bah]{foo}|}

\newbox\SlashttTag
\setbox\SlashttTag=\hbox{\tts\verb|\ttTag{foo}|}

\newbox\SlashInput
\setbox\SlashInput=\hbox{\tts\verb|\Input{foo.tex}|}

\begin{longtable}{rl}
   {\copy\Slashpya}&\MyPar{0.70}{%
       Display the value of {\tts foo} without any additional decorations.}\\
   {\copy\Slashpyb}&\MyPar{0.70}{%
       Similar to \copy\Slashpya\ but adds {\tts foo$\colonEq$}
       immediately to the left of {\tts foo}.}\\
   {\copy\SlashPya}&\MyPar{0.70}{%
       Display the value of {\tts foo} and set the equation tag to be ({\tts
       foo}). Since this macro creates its own equation tag it should not be used
       in any maths environment that also creates an equation tag (e.g., {\tts
       align, equation} etc.) It can not be used in any of the {\tts breqn}
       environments ({\tts breqn} will report a package error).}\\
   {\copy\SlashPyb}&\MyPar{0.70}{%
       Use this version of \copy\SlashPya\ in any of the (starred) {\tts breqn}
       environments. The optional argument {\tts [bah]} specifies the spacing
       between the end of {\tts foo} and the right hand edge of the tag. The
       default is \copy\Slashhfill\ which forces the tag to the far right.}\\
   {\copy\SlashDmatha}&\MyPar{0.70}{%
       This is a shortcut for the {\tts dmath} environment. The optional and
       required arguments of \copy\SlashDmatha\ are passed onto the {\tts dmath}
       environment. See page (\pageref{ex:Dmath}) for an example.}\\
   {\copy\SlashDmathb}&\MyPar{0.70}{%
       This is similar to \copy\SlashDmatha\ but with the one small change that it
       applies to the {\tts dmath*} environment.}\\
   {\copy\SlashttTag}&\MyPar{0.70}{%
       This is a simple macro that typesets a tag name such as {\tts foo} in a
       small typewriter font enclosed in matching parenthesis, e.g., ({\tts
       foo}).}\\
   {\copy\SlashPySetup}&\MyPar{0.70}{%
       This command takes one argument in the form of a key=value pair. Its
       purpose is to set global options for the following Python blocks. The
       current list of options is limited to one key with three values. These are
       described in the following section.}\\
\end{longtable}

\subsection{Custom formats}
\hypertarget{sec:custom}{}

The \pyLaTeX\ package allows for some minor customisation of the formatting of the Python code. The macro
{\tts\verb|\PySetup|} can be used to set the preferred options using key-value pairs. There is only
one key as described in the following table.

\begin{tabular}{rl}
   {\tts action=show}&%
         \MyPar{0.70}{Make the Python code visible and active (i.e., cancel the
         {\tts hide} and {\tts verbatim} actions).}\\
   {\tts action=hide}&%
         \MyPar{0.70}{Hide the python code but still allow the Python code to be
         active.}\\
   {\tts action=verbatim}&%
         \MyPar{0.70}{This will make the Python code inactive (i.e., it will not
         be passed to Python).}\\[5pt]
\end{tabular}

Multiple calls to {\tts\verb|\PySetup|} can be made and apply to all subsequent
Python environments or until changed by a later call to {\tts\verb|\PySetup|}. The
default value is {\tts action=show}.

The \pyLaTeX\ package uses the {\tts listings} package which allows further
formatting changes to be made. For example, to add line numbers and a shaded
background to the Python code use

\begin{lstlisting}
   \lstset{numbers=left,backgroundcolor=\color{lightgrey}}
\end{lstlisting}

Many other options are available, see the {\tts listings} documentation for full
details.

\subsection{Python indentation}

Python has very strict (but simple) indentation rules that must be observed not
only within a single Python block but across all Python blocks. Why? Because all
of the Python blocks will be collected into a separate single Python code and that
code must observe the Python indentation rules.

\subsection{Error reporting}

None of the packages in this collection treat errors from the active code with any
degree of aplomb -- at best they report that an error occurred, at worst they
silently ignore the error leaving {\tts pdflatex} to pick up the pieces. This is
far from ideal. If in doubt, run the main script (e.g., {\tts pylatex.sh}) using
the {\tts -k -x} command line options then inspect the file {\tts foo.pytxt} for
any errors. If there are errors then you can debug the extracted code {\tts
foo.py} later returning the corrected code back to the LaTeX source {\tts foo.tex}.

\subsection{Matplotlib and macOS}

There is a well known issue when using Matplotlib on macOS where some Matplotlib
codes may fail. The
\href{https://matplotlib.org/faq/osx_framework.html}{Matplotlib documentation}
provides a number of suggestions including to use {\tts pythonw} rather than {\tts
python}. For such cases use the {\tts -P} flag to set the path to the {\tts
pythonw} command when invoking the {\tts pylatex.sh}. This has been tried and
tested under the Anaconda Python3 environment for macOS.

\section{Examples}

The {\tts examples} directory contains a small collection of complete \pyLaTeX\
codes that showcase the various features of the \pyLaTeX\ package. The Python
source contains inline comments that result in long lines of text that do not
comfortably fit on an A4 page in portrait mode. Thus most of the examples have
been formatted in A4 landscape mode (this is the default setting for the \pyLaTeX\
class). Consequently it is not practical to include those examples in this file.
The following table provides a very brief summary of each example (with hyperlinks
to the corresponding pdf's in {\tts ../python/examples/}).

\newbox\exa
\setbox\exa=\hbox{\href{../python/examples/example-01.pdf}{Example 1}}

\newbox\exb
\setbox\exb=\hbox{\href{../python/examples/example-02.pdf}{Example 2}}

\newbox\exc
\setbox\exc=\hbox{\href{../python/examples/example-03.pdf}{Example 3}}

\newbox\exd
\setbox\exd=\hbox{\href{../python/examples/example-04.pdf}{Example 4}}

\newbox\exe
\setbox\exe=\hbox{\href{../python/examples/example-05.pdf}{Example 5}}

\newbox\exf
\setbox\exf=\hbox{\href{../python/examples/example-06.pdf}{Example 6}}

\newbox\exg
\setbox\exg=\hbox{\href{../python/examples/example-07.pdf}{Example 7}}

\newbox\exh
\setbox\exh=\hbox{\href{../python/examples/example-08.pdf}{Example 8}}

\newbox\exi
\setbox\exi=\hbox{\href{../python/examples/example-09.pdf}{Example 9}}

\newbox\exz
\setbox\exz=\hbox{\href{../python/examples/summary.pdf}{Summary}}

\begin{longtable}{rl}
   \box\exa:&\MyPar{0.80}%
      {This is a collection of basic mathematical computations. It contains
      examples of simple tags and tagged blocks.}\\
   \box\exb:&\MyPar{0.80}%
      {This is the first of two examples drawn from the \PythonTeX\ website
      \href{https://github.com/gpoore/pythontex/}{(here)}. It shows a nice example
      of using a tagged block.}\\
   \box\exc:&\MyPar{0.80}%
      {This is the second example taken from the \PythonTeX\ website
      \href{https://github.com/gpoore/pythontex/}{(here)}. It shows a step-by-step
      computation of a simple triple integral.}\\
   \box\exd:&\MyPar{0.80}%
      {This example shows how {\tts Matplotlib} and friends can be used to
      construct a simple xy-plot.}\\
   \box\exe:&\MyPar{0.80}%
      {This example shows how problems with the placement of equation tags can be
      resolved by careful choice of the optional argument to
      {\copy\SlashPyStar}.}\\
   \box\exf:&\MyPar{0.80}%
      {This is a simple example that uses Python to compute the first few
      iterations of a Newton-Raphson method.}\\
   \box\exg:&\MyPar{0.80}%
      {This example contains a single tag-block. It captures basic system data.}\\
   \box\exh:&\MyPar{0.80}%
      {This example shows how to completely hide the Python code as well a trick
      for hiding just the tags.}\\
   \box\exi:&\MyPar{0.80}%
      {This example is a proof of concept example. It shows one approach for
      passing LaTeX information to the Python code. The code is not elegant but it
      does the job.}\\
   \box\exz:&\MyPar{0.80}%
      {There is no Python code in this example. Instead, the results from the
      above examples are included by inputting the corresponding {\tts .pytex}
      file.}
\end{longtable}

\section{Splitting long lines using breqn}

On some occasions the output from a computation may be too long to fit comfortably
on one line. In such cases some form of line splitting is required. A less than
ideal approach is to manually edit the output by inserting carefully chosen line
breaks. Not only is this approach tedious and inelegant it also requires the line
breaks to be reset whenever the document format is changed (e.g., from A4 to
letter size) or when some of the computations are changed (e.g., showing twice as
many terms in a series expansion).

A better approach is to use the {\tts breqn} package which uses sophisticated
algorithms to find good line breaks with minimal input from the user. In many
cases {\tts breqn} will produce an acceptable output. But it is not without its
own limitations\footnote{The {\tts breqn} documentation does note that it is a
work in progress.} as some of the following examples will demonstrate. The fact is
that there are no algorithms that will guarantee prefect line splitting as there
will always be some subjective element in what constitutes a good line break. The
following series of examples are intended as guide of what to expect when using
{\tts breqn} and also to demonstrate some possible remedies.

Here is a simple example based on a truncated Taylor series expansion of $1/(1+x)$
around $x=0$.
\bgroup
\lstset{gobble=2,numbers=left}
\begin{python}
   from sympy import *
   x = Symbol('x')
   ans    = 1/(1+x)                 # py (fun,ans)
   taylor = ans.series(x, 0,  6)    # py (ans.101,taylor)
   taylor = ans.series(x, 0,  9)    # py (ans.102,taylor)
   taylor = ans.series(x, 0, 12)    # py (ans.103,taylor)
   taylor = ans.series(x, 0, 15)    # py (ans.104,taylor)
   taylor = ans.series(x, 0, 30)    # py (ans.105,taylor)
\end{python}
\egroup
For an expansion with only a handful of terms the usual {\tts align} environment
produces an acceptable output as demonstrated in the following code and output.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{align*}
      \py{fun} &= \py {ans.101}\tag{\ttTag{ans.101}}\\
               &= \py {ans.102}\tag{\ttTag{ans.102}}\\
               &= \py {ans.103}\tag{\ttTag{ans.103}}
   \end{align*}
\end{latex}
\egroup
\begin{align*}
   \py{fun} &= \py {ans.101}\tag{\ttTag{ans.101}}\\
            &= \py {ans.102}\tag{\ttTag{ans.102}}\\
            &= \py {ans.103}\tag{\ttTag{ans.103}}
\end{align*}
In this and the following examples the equation tags have been explicitly matched
to the corresponding {\tts sympy} expressions. This makes it somewhat easier to
follow the progress of a computation. The normal equation numbering (e.g., (1),
(2) etc.) can be recovered by deleting the calls to {\tts\verb!\tag{...}!}. The
{\tts\verb|\ttTag|} macro, defined in the \pyLaTeX\ package, does as its name
suggests -- typesets the tag in the {\tts\verb|\tt|} font.

The above works well for short expressions but for longer expressions it is much
better to use the {\tts breqn} package. The key points to note in the following
example are the use of the {\tts dmath} environment and the manner in which the
equation tags have been set.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \usepackage{breqn}
   ...
   \begin{dmath}[number={\ttTag{ans.105}}]
      \py {fun} = \py {ans.105}
   \end{dmath}
\end{latex}
\egroup
The corresponding output is
\Dmath[number={\ttTag{ans.105}}]{\py{fun} = \py{ans.105}}

The {\tts dmath} environment is one of a number environments provided by the {\tts
breqn} package. Its job is to chose sensible line breaks that produce a pleasant
output (though what constitutes \emph{pleasant} may be up for debate). Note that
all of the {\tts breqn} environments do \emph{not} support the {\tts\verb!\tag!}
macro for setting equation tags. The only way to do so is through the
{\tts\verb!number={...}!} optional argument as shown in the above example. To
suppress the equation label use the {\tts dmath*} environment.

\bgroup
\advance\leftskip1cm
\advance\rightskip1cm
\hypertarget{landing}{{\bf Note:}}
This sentence may seem out of place but its purpose is to demonstrate a claim made
later is this documentation that, with a suitably modified label macro, the {\tts
hyperref} package can be used to jump to the correct page when clicking on a
hyperlink for an equation. For example, clicking on this link \eqref{eq:target}
should take us to page \pageref{eq:target}. But now, back to the main discussion.
\par
\egroup

The {\tts breqn} package also provides a {\tts dgroup} environment. This can be
used to group a sequence of {\tts dmath} environments to align the output on a
targeted symbol (usually the first equals sign). Here is a short example

\vskip 12pt

\bgroup
\bgcolour{white}
\lstlatex{numbers=left}
\begin{latex}
   \begin{dgroup}
      \begin{dmath}[number={\ttTag{ans.103}}] \py {fun}  = \py {ans.103} \end{dmath}
      \begin{dmath}[number={\ttTag{ans.104}}]         {} = \py {ans.104} \end{dmath}
      \begin{dmath}[number={\ttTag{ans.105}}]         {} = \py {ans.105} \end{dmath}
   \end{dgroup}
\end{latex}
\egroup

and here is the corresponding output
\begin{dgroup}
   \begin{dmath}[number={\ttTag{ans.103}}] \py {fun}  = \py {ans.103} \end{dmath}
   \begin{dmath}[number={\ttTag{ans.104}}]         {} = \py {ans.104} \end{dmath}
   \begin{dmath}[number={\ttTag{ans.105}}]         {} = \py {ans.105} \end{dmath}
\end{dgroup}

There are a few points to be made here. First is the less then ideal placement of
tags. Second is the somewhat ungainly syntax. Both of these points will be
discussed in more detail shortly. Next, notice the {\tts\verb!{}!} preceding the
equal signs in lines 3 and 4. This supplies an empty left hand side for each
equation and is essential to ensure proper alignment (on the equals sign) across
all three equations. Unlike other maths environments, {\tts breqn} does not allow
you to specify which symbol to use as the alignment target -- that choice is made
deep within the inner workings of {\tts dmath} and friends. It will choose symbols
including {\tts\verb!=-+:()!}. If you wish to tell {\tts dmath} to not use a
particular symbol you can wrap that symbol inside {\tts\verb!\hiderel!} as in the
following example.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dgroup*}
      \begin{dmath*} f(x) \hiderel{=} \py {fun} = \py {ans.101} \end{dmath*}
      \begin{dmath*}                         {} = \py {ans.102} \end{dmath*}
   \end{dgroup*}
\end{latex}
\egroup
\begin{dgroup*}
   \begin{dmath*} f(x) \hiderel{=} \py {fun} = \Py*{ans.101} \end{dmath*}
   \begin{dmath*}                         {} = \Py*{ans.102} \end{dmath*}
\end{dgroup*}

Consider now the earlier example in which the equation tags were not well placed
and where the syntax was described as ungainly. The syntax can be tidied slightly
using one of the features of the {\tts breqn} package -- it allows the {\tts
dmath} and {\tts dmath*} environments to be wrapped in user defined macros such as

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \newcommand*{\Dmath}[2][]{\begin{dmath}[#1]#2\end{dmath}}
\end{latex}
\egroup
This defines {\tts\verb!\Dmath!} as a macro that takes one required argument and
one optional argument (both of which are passed on to {\tts dmath}). It is not a
huge saving but even so it does save a few keystrokes. Here is one of the previous
examples rewritten using {\tts\verb!\Dmath!}.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dgroup}
      \Dmath[number={\ttTag{ans.103}}]{ \py {fun}  = \py {ans.103} }
      \Dmath[number={\ttTag{ans.104}}]{         {} = \py {ans.104} }
      \Dmath[number={\ttTag{ans.105}}]{         {} = \py {ans.105} }
   \end{dgroup}
\end{latex}
\egroup
The \pyLaTeX\ package defines {\tts\verb|\Dmath|} for the {\tts dmath} environment
as well as {\tts\verb|\Dmath*|} as a shortcut for the {\tts dmath*} environment.

The use of {\tts\verb|\Dmath*|} does save some keystrokes but it does not fix the
problem where the text is obscured by the tag. There seems to be no simple way to
tell {\tts breqn} to avoid such problems while retaining {\tts breqn}'s method of
placing the tags. The {\tts\verb|\Py*|} macro avoids this problem by presenting
{\tts dmath*} with a concatenated string built from the text (e.g., the output of
{\tts\verb|\py{foo}|}), some flexible white space (usually {\tts\verb|\hfill|})
and the tag (e.g., {\tts foo}). This string is processed by {\tts dmath*} and line
splits are inserted at its discretion. This will guarantee that the all of the
text and the tag will be displayed. The user defined whitespace can always be
chosen so that the tag does not overlap the text. This is a bare minimum of what
could be deemed an acceptable output -- non overlap of the text and the tag. The
output might not be optimal but at least it is readable. Here is the same example
as above but this time using {\tts\verb|\Py*|} to display the text and the tags.

\vskip 12pt

\pglabel{ex:Dmath}
\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dgroup*}
      \Dmath*{ \py {fun}  = \Py* {ans.103} }
      \Dmath*{         {} = \Py*[\hskip 2cm] {ans.104} }
      \Dmath*{         {} = \Py*[\hskip 3cm] {ans.105} }
   \end{dgroup*}
\end{latex}
\egroup
\begin{dgroup*}
   \Dmath*{ \py {fun}  = \Py* {ans.103} }
   \Dmath*{         {} = \Py*[\hskip 2cm] {ans.104} }
   \Dmath*{         {} = \Py*[\hskip 3cm] {ans.105} }
\end{dgroup*}
The whitespace between the text and the tag is passed through the optional
argument of {\tts\verb|\Py*|} with the default set as {\tts\verb|\hfill|}. The
inner workings of {\tts\verb|\Py*|} sets the tag using {\tts\verb|\llap|} and thus
the whitespace optional argument measures the space between the right hand edge of
the tag and left hand end of the equation text. Note also that this example uses
the starred version of {\tts dgroup} and {\tts\verb|\Dmath*|}. This is to ensure
that {\tts breqn} plays no part in forming the tag (as that is handled by
{\tts\verb|\Py*|}).

The \pyLaTeX\ package defines both {\tts\verb|\Py|} and {\tts\verb|\Py*|}. The
{\tts\verb|\Py|} macro is intended for use only in the starred maths environments
(e.g., {\tts align*, equation*} etc.). Like {\tts\verb|\Py*|}, it also sets the
equation tag to match the expression but it does so using standard methods
(internally it calls {\tts\verb|\tag|}). This last point (that {\tts\verb|\Py*|}
uses {\tts\verb|\tag|}) also means that it can not be used in any of the {\tts
breqn} environments (doing so will cause LaTeX to issue a {\tts breqn} package
error).

Both {\tts\verb|\Py|} and {\tts\verb|\Py*|} support the usual method of labelling
and referencing equations using {\tts\verb|\label{foo}|} and
{\tts\verb|\ref{foo}|}. However, there are good reasons to use a modified version
of the {\tts\verb|\label|} macro (as described below) to improve the accuracy of
the label-reference pairs when using hyperlinks (i.e., so that the reference
points to the correct page where the label was issued).

\subsection{Hyperref, hyperlinks and breqn}

The {\tts breqn} package does support the {\tts hyperref} package though as
discussed
\href{https://tex.stackexchange.com/questions/193380/hyperref-pageref-links-point-t
o-first-page}{(here)} the hyperlinks to an equation may not work as expected
(clicking on a link may take you to the wrong page). The suggested fix is to
define equation labels via a modified label macro such as the following

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \newcommand{\pglabel}[1]{\phantomsection\label{#1}}
\end{latex}
\egroup
An example of its use might be

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dmath}[number={\ttTag{ans.105}}]
      \py{fun} = \py{ans.105} \pglabel{eq:target}
   \end{dmath}
\end{latex}
\egroup
\begin{dmath}[number={\ttTag{ans.105}}]
   \py{fun} = \py{ans.105} \pglabel{eq:target}
\end{dmath}
Then clicking on the link defined by {\tts\verb!\ref{eq:target}!} will bring the
reader to this page. An example of such a link was seen earlier in this document
(click \hyperlink{landing}{here} to jump back to that page).

\section{Licence}

This software is licensed under the MIT License (MIT). Please see the {\tts
LICENCE.txt} file for more information.

\section{Version history}
\leftline{\bf v0.1 (2018/08/22)}% 22 Aug 2018
\begin{itemize}
\item Initial public release.
\end{itemize}

\end{document}
