% \iffalse meta-comment
%
% Copyright (C) 2009-2014 by Tim Molteno <tim@physics.otago.ac.nz>
% Shamelessly copied from the excellent sympytex package by
%
% Copyright (C) 2008 by Dan Drake <ddrake@member.ams.org>
% -------------------------------------------------------
%
% See the "Copying and licenses" section for the terms under which this
% source code and documentation may be modified and distributed.
%
% This package is not licensed under the LPPL, but it seems reasonable
% to say:
%
%   This work has the LPPL maintenance status `maintained'.
%   
%   This work consists of the files sympytexpackage.dtx,
%   sympytexpackage.ins, example.tex, and the derived files sympytex.sty
%   and sympytex.py.
% 
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{sympytexpackage.dtx}
%</driver>
%<latex>\NeedsTeXFormat{LaTeX2e}
%<latex>\ProvidesPackage{sympytex}
%<*latex>
  [2014/05/16 v0.3 Added sympy plotting support. Code cleanup]
%</latex>
%<*driver>
\documentclass{ltxdoc}
\usepackage{sympytex}
\usepackage{xspace}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{hyperref}
\EnableCrossrefs         
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{sympytexpackage.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \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
%   Lower-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
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \changes{v0.1}{2009/05/06}{Initial version}
% \changes{v0.2}{2011/08/10}{Added support for matplotlib plots}
% \changes{v0.3}{2014/05/16}{Added support for sympy plotting}
%
% \GetFileInfo{sympytexpackage.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment,\the}
% 
% \newcommand{\ST}{\textsf{sympytex}\xspace}
% \iffalse
% so I don't have to put \ or {} after \LaTeX:
% \fi
% \newcommand{\LTX}{\LaTeX\xspace}
%
% \iffalse
% For some reason, getting a blackslash in a typewriter font to print
% inside an fbox is really hard. Verbatim stuff doesn't work because
% it's fragile. This code works; it's copied out of Scott Pakin's
% dtxtut.tex. 
% 
% There is \textbackslash but I don't like how that looks. 
% \fi
% {\catcode`\|=0 \catcode`\\=12
% |gdef|bslash{\}}
%
% \title{The \ST{} package\thanks{This document
%   corresponds to \textsf{sympytex}~\fileversion, dated \filedate.}}
% \author{Tim Molteno (\texttt{tim@physics.otago.ac.nz}) and others}
%
% \maketitle
%
% \section{Introduction}
%
% The \ST package allows you to embed the symbolic python package
% Sympy (see \url{http://www.sympy.org}) and
% \LTX. 
%
% As a simple example, imagine in your document you are
% writing about how to count license plates with three letters and three
% digits. With this package, you can write something like this:
% \begin{quote}
%  |There are $26$ choices for each letter, and $10$ choices for|\\
%  |each digit, for a total of $26^3*10^3 = \sympy{(26**3 * 10**3)}$|\\
%  |license plates.|
% \end{quote}
% and it will produce
% \begin{quote}
%   There are $26$ choices for each letter, and $10$ choices for each
%   digit, for a total of $\sympy{((26**3) * 10**3)}$ license plates.
% \end{quote}
% The great thing is, you don't have to do the multiplication. Sympy does
% it for you. This process mirrors one of the great aspects of
% \LTX: when writing a \LTX document, you can concentrate on the
% logical structure of the document and trust \LTX and its army of
% packages to deal with the presentation and typesetting. Similarly,
% with \ST, you can concentrate on the mathematical
% structure (``I need the product of $26^3$ and $10^3$'') and let Sympy
% deal with the base-$10$ presentation of the number.
%
% A less trivial, and perhaps more useful example is plotting. You can
% include a plot of the sine curve without manually producing a plot,
% saving an EPS or PDF file, and doing the |\includegraphics|
% business with the correct filename yourself. If you write this:
% \begin{quote}
% |Here is a lovely graph of the sine curve:|\\
% |\sympyplot{plot(sin(x), x, 0, 2*pi, show=False)}|
% \end{quote}
% in your \LTX file, it produces
%
% Here is a lovely graph of the sine curve:
%
% \begin{sympysilent} from sympy import *; x = Symbol('x') \end{sympysilent}
%
% \sympyplot{plot(sin(x), x, 0, 2*pi, show=False)}
%
% Again, you need only worry about the logical/mathematical structure of
% your document (``I need a plot of the sine curve over the interval
% $[0, 2\pi]$ here''), while \ST{} takes care of the gritty details of
% producing the file and sourcing it into your document.
%
% Sympy session. This means you can define variables and reuse them
% \paragraph{But \texttt{\bslash sympyplot} isn't magic} I just tried to
% convince you that \ST makes putting nice graphics into your document
% very easy; let me turn around and warn you that using graphics
% \emph{well} is not easy, and no \LTX package or Python script will
% ever make it easy. What \ST does is make it easy to
% to create graphics; it doesn't magically make your graphics good,
% appropriate, or useful.
% 
% \section{Installation}
%
% The simplest way to ``install'' \ST is to copy the files
% |sympytex.sty| and |sympytex.py| into the same directory
% as your document. This will always work, as \LTX and Python search the
% current directory for files. It is also convenient for zipping up a
% directory to send to a colleague who is not yet enlightened enough to
% be using \ST.
%
% Rather than make lots of copies of those files, you can keep them in
% one place and update the TEXINPUTS and PYTHONPATH environment
% variables appropriately.
%
% Perhaps the best solution is to put the files into a directory
% searched by \TeX{} and friends, and then edit the |sympytex.sty| file
% so that the |.sympy| files we generate update Python's path
% appropriately---look for ``Python path'' in |sympytex.sty|. This is
% suitable for a system-wide installation, or if you are the kind of
% person who keeps a |texmf| tree in your home directory.
%
%
% \section{Usage} \label{s:usage}
% 
% Let's begin with a rough description of how \ST works. Naturally the
% very first step is to put |\usepackage{sympytex}| in the preamble of
% your document. When you use macros from this package and run \LTX on
% your file, along with the usual zoo of auxiliary files, a |.sympy| file
% is written. This is a python source file that uses the |sympytex.py| Python module
% from this package and when execute the python code in that file, it will produce
% a |.sout| file. That file contains \LTX code which, when you run \LTX
% on your source file again, will pull in all the results of Sympy's
% computation.
%
% All you really need to know is that to typeset your document, you need
% to run \LTX, then run Sympy, then run \LTX again. 
%
% Also keep in mind that everything you send to Sympy is done within one
% Sympy session. This means you can define variables and reuse them
% throughout your \LTX document; if you tell Sympy that |foo| is
% $12$, then anytime afterwards you can use |foo| in your Sympy code and
% Sympy will remember that it's $12$---just like in a regular Sympy
% session.
%
% Now that you know that, let's describe what macros \ST provides and
% how to use them. If you are the sort of person who can't be bothered
% to read documentation until something goes wrong, you can also just
% look through the |example.tex| file included with this
% package.\footnote{Then again, if you're such a person, you're probably
% not reading this, and are already fiddling with
% \texttt{example.tex}\dots}
%
% \subsection{Inline Sympy}
%
% \DescribeMacro{\sympy}
% \fbox{\texttt{\bslash sympy}\marg{Sympy code}}
%
% \noindent takes whatever Sympy code you give it, runs Sympy's |latex|
% function on it, and puts the result into your document. 
%
% For example, if you do |\sympy{matrix([[1, 2], [3,4]])^2}|, then that
% macro will get replaced by
% \begin{quote}
% |\left(\begin{array}{rr}|\\
% |7 & 10 \\|\\
% |15 & 22|\\
% |\end{array}\right)|
% \end{quote}
% in your document---that \LTX code is exactly exactly what you get
% from doing
% \begin{center}
% |latex(matrix([[1, 2], [3,4]])^2)|
% \end{center}
% in Sympy.
%
% Note that since \LTX will do macro expansion on whatever you give
% to |\sympy|, you can mix \LTX variables and Sympy variables! If
% you have defined the Sympy variable |foo| to be $12$ (using, say, the
% |sympyblock| environment), then you can do something like this:
% \begin{quote}
% |The prime factorization of the current page number|\\
% |times $2^{17} + 1$  is|\\
% |$\sympy{factorint(\thepage*2**17+1)}$|.
% \end{quote}
% Here, I'll do just that right now: the prime factorization of the
% current page number times $2^{17}+1$ is 
% $\sympy{factorint(\thepage * 2**17 + 1)}$.
%
% The |\sympy| command doesn't automatically use math mode for its
% output, so be sure to use dollar signs or a displayed math environment
% as appropriate.\\
%
% \DescribeMacro{\percent} If you are doing modular arithmetic or string
% formatting and need a percent sign in a call to |\sympy| (or
% |\sympyplot|), you can use |\percent|. Using a bare percent sign won't
% work because \LTX will think you're starting a comment and get
% confused; prefixing the percent sign with a backslash won't work
% because then ``|\%|'' will be written to the |.sympy| file and Sympy
% will get confused. The |\percent| macro makes everyone happy.
%
% Note that using |\percent| inside the verbatim-like environments
% described in \autoref{s:codeblockenv} isn't necessary; a literal
% ``\percent'' inside such an environment will get written, uh, verbatim
% to the |.sympy| file.
%
% \subsection{Graphics and plotting}
%
% \noindent \DescribeMacro{\sympyplot}
% \fbox{\texttt{\bslash sympyplot}\oarg{ltx opts}\oarg{fmt}\{\meta{graphics
% obj}, \meta{keyword args}\}}
%
% \noindent plots the given Sympy graphics object and runs an
% |\includegraphics| command to put it into your document. It does not
% have to actually be a plot of a function; it can be any Sympy graphics
% object. The options are described in \autoref{t:sympyplotopts}.
%
% \begin{table}[h]
%   \centering
%   \begin{tabular}{l p{8cm}}
%   Option & Description \\
%   \hline
%   \meta{ltx options} & Any text here is passed directly into the
%   optional arguments (between the square brackets) of an
%   |\includegraphics| command. If not specified,
%   ``|width=.75\textwidth|'' will be used.\\
%   \meta{fmt} & You can optionally specify a file extension here; Sympy
%   will then try to save the graphics object to a file with extension
%   \emph{fmt}. If not specified, \ST\ will save to EPS and PDF files.\\
%   \meta{graphics obj} & A Sympy object on which you can call |.save()|
%   with a graphics filename.\\
%   \meta{keyword args} & Any keyword arguments you put here will
%   all be put into the call to |.save()|.
%   \end{tabular}
%   \caption{Explanation of options for the \texttt{\bslash sympyplot}
%   command.}
%   \label{t:sympyplotopts}
% \end{table}
%
% This setup allows you to control both the Sympy side of things, and the
% \LTX side. For instance, the command
% \begin{quote}
% |\sympyplot[angle=30, width=5cm]{plot(sin(x), 0, pi), axes=False,|\\
% |chocolate=True}|
% \end{quote}
% will run the following command in Sympy:
% \begin{quote}
% |sympy: plot(sin(x), 0, pi).save(filename=autogen, axes=False,|\\
% |chocolate=True)|
% \end{quote}
% Then, in your \LTX file, the following command will be issued
% automatically:
% \begin{center}
% |\includegraphics[angle=30, width=5cm]{autogen}|
% \end{center}
% You can specify a file format if you like. This must be the
% \emph{second} optional argument, so you must use empty brackets if
% you're not passing anything to |\includegraphics|:
% \begin{center}
% |\sympyplot[][png]{plot(sin(x), x, 0, pi)}|
% \end{center}
% The filename is automatically generated, and unless you specify a
% format, both EPS and PDF files will be generated. This allows you to
% freely switch between using, say, a DVI viewer (many of which have
% support for automatic reloading, source specials and make the writing
% process easier) and creating PDFs for posting on the web or emailing
% to colleagues.
%
% If you ask for, say, a PNG file, keep in mind that ordinary |latex|
% and DVI files have no support for DVI files; \ST detects this and will
% warn you that it cannot find a suitable file if using |latex|. If you
% use |pdflatex|, there will be no problems because PDF files can
% include PNG graphics.
%
% When \ST cannot find a graphics file, it inserts this into your
% document:
%
% \begin{center}
%   \framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}
% \end{center}
% 
% \noindent That's supposed to resemble the image-not-found graphics
% used by web browsers and use the traditional ``\textbf{??}'' that \LTX
% uses to indicate missing references.
%
% You needn't worry about the filenames; they are automatically
% generated and will be put into the directory
% |sympy-plots-for-filename.tex|. You can safely delete that directory
% anytime; if \ST can't find the files, it will warn you to run Sympy to
% regenerate them.\\
%
% \noindent\fbox{\parbox{\textwidth}{\textbf{WARNING!} When you run Sympy
% on your |.sympy| file, all files in the
% \texttt{sympy-plots-for-filename.tex} directory \emph{will be deleted!}
% Do not put any files into that directory that you do not want to get
% automatically deleted.}}
%
%
% \subsection{Verbatim-like environments}
% \label{s:codeblockenv}
%
% The \ST package provides several environments for typesetting and
% executing Sympy code.\\
%
% \DescribeEnv{sympyblock} Any text between |\begin{sympyblock}| and
% |\end{sympyblock}| will be typeset into your file, and also written into
% the |.sympy| file for execution. This means you can do something like
% this:
% \begin{quote}
% |\begin{sympyblock}|\\
% |   var('x')|\\
% |   f = sin(x) - 1|\\
% |   g = log(x)|\\
% |   h = diff(f(x) * g(x), x)|\\
% |\end{sympyblock}|
% \end{quote}
% and then anytime later write in your source file
% \begin{quote}
%   |We have $h(2) = \sympy{h(2)}$, where $h$ is the derivative of|\\
%   |the product of $f$ and $g$.|
% \end{quote}
% and the |\sympy| call will get correctly replaced by $\sympy{
% diff((sin(x) - 1)*log(x), x)}$. You can use any Sympy or Python
% commands inside a |sympyblock|; all the commands get sent directly to
% Sympy.\\
%
% \iffalse meta-comment
%   Sadly, we can't use sympyblock or similar environments in this file!
%   If you prefix the lines inside the environment with percent signs,
%   then those percent signs get written to your .sympy file. If you
%   *don't* prefix the lines with percent signs, those lines get written
%   into the .sty or .py file. It's just too tricky to get docstrip and
%   the verbatim stuff to play nicely together. I'd have to redefine how
%   those environments work, and get them to strip off initial percents. 
% \fi
% 
% \DescribeEnv{sympysilent} This environment is like |sympyblock|, but it
% does not typeset any of the code; it just writes it to the |.sympy|
% file. This is useful if you have to do some setup in Sympy that is not
% interesting or relevant to the document you are writing.\\
%
% \DescribeEnv{sympyverbatim} This environment is the opposite of the one
% above: whatever you type will be typeset, but not written into the
% |.sympy| file. This allows you to typeset psuedocode, code that will
% fail, or take too much time to execute, or whatever.\\
%
% \DescribeEnv{comment} Logically, we now need an environment that
% neither typesets nor executes your Sympy code\ldots but the |verbatim|
% package, which is always loaded when using \ST, provides such an
% environment: |comment|. Another way to do this is to put stuff between
% |\iffalse| and |\fi|.\\
%
% \DescribeMacro{\sympytexindent} There is one final bit to our
% verbatim-like environments: the indentation. The \ST package defines a
% length |\sympytexindent|, which controls how much the Sympy code is
% indented when typeset. You can change this length however you like
% with |\setlength|: do |\setlength{\sympytexindent}{6ex}| or whatever.
% 
%
% \section{Other notes}
%
% Here are some other notes on using \ST.
%
% \paragraph{Using Beamer} The \textsc{beamer} package does not play
% nicely with verbatim-like environments. To use code block environments
% in a \textsc{beamer} presentation, do:
% \begin{quote}
%  |\begin{frame}[fragile]|\\
%  |\begin{sympyblock}|\\
%  |# sympy stuff|\\
%  |# more stuff \end{sympyblock}|\\
%  |\end{frame}|\\
% \end{quote}
% For some reason, \textsc{beamer} inserts an extra line break at the
% end of the environment; if you put the |\end{sympyblock}| on the same
% line as the last line of your code, it works properly.
%
% Thanks to Franco Saliola for reporting this.
%
% \StopEventually{}
%
% \section{Implementation}
%
% There are two pieces to this package: a \LTX style file, and a
% Python module. They are mutually interdependent, so it makes sense to
% document them both here.
%
% \subsection{The style file}
%
% \iffalse
% tell docstrip to put code into the .sty file
%<*latex>
% \fi
%
% All macros and counters intended for use internal to this package
% begin with ``|ST@|''.
%
% Let's begin by loading some packages. The key bits of |sympyblock| and
% friends are stol---um, adapted from the |verbatim| package manual. So
% grab the |verbatim| package.
%    \begin{macrocode}
\RequirePackage{verbatim}
%    \end{macrocode}
% Unsurprisingly, the |\sympyplot| command works poorly without graphics
% support.
%    \begin{macrocode}
\RequirePackage{graphicx}
%    \end{macrocode}
% The |makecmds| package gives us a |\provideenvironment| which we need,
% and we use |ifpdf| and |ifthen| in |\sympyplot| so we know what kind of
% files to look for.
%    \begin{macrocode}
\RequirePackage{makecmds}
\RequirePackage{ifpdf}
\RequirePackage{ifthen}
%    \end{macrocode}
%
% Next set up the counters and the default indent.
%    \begin{macrocode}
\newcounter{ST@inline}
\newcounter{ST@plot}
\setcounter{ST@inline}{0}
\setcounter{ST@plot}{0}
\newlength{\sympytexindent}
\setlength{\sympytexindent}{5ex}
%    \end{macrocode}
%
% \begin{macro}{\ST@epsim}
% By default, we don't use ImageMagick to create EPS files when a
% non-default format is specified.
%    \begin{macrocode}
\newcommand{\ST@epsim}{False}
%    \end{macrocode}
% The expansion of that macro gets put into a Python function call, so
% it works to have it be one of the strings ``|True|'' or ``|False|''.
% \end{macro}
% 
% Declare the |imagemagick| option and process it:
%    \begin{macrocode}
\DeclareOption{imagemagick}{\renewcommand{\ST@epsim}{True}}
\ProcessOptions\relax
%    \end{macrocode}
% The |\relax| is a little incantation suggested by the ``\LaTeXe{} for
% class and package writers'' manual, section 4.7.
%
% It's time to deal with files. Open the |.sympy| file:
%    \begin{macrocode}
\newwrite\ST@sf
\immediate\openout\ST@sf=\jobname.sympy
%    \end{macrocode}
%
% \begin{macro}{\ST@wsf}
% We will write a lot of stuff to that file, so make a convenient
% abbreviation, then use it to put the initial commands into the |.sympy|
% file. If you know what directory |sympytex.py| will be kept in, delete
% the |\iffalse| and |\fi| lines in the generated style file
% (\emph{don't} do it in the |.dtx| file) and change the directory
% appropriately. This is useful if you have a |texmf| tree in your home
% directory or are installing \ST system-wide; then you don't need to
% copy |sympytex.py| into the same directory as your document.
%    \begin{macrocode}
\newcommand{\ST@wsf}[1]{\immediate\write\ST@sf{#1}}
\iffalse
%% To get .sympy files to automatically change the Python path to find
%% sympytex.py, delete the \iffalse and \fi lines surrounding this and
%% change the directory below to where sympytex.py can be found.
\ST@wsf{import sys}
\ST@wsf{sys.path.insert(0, 'directory with sympytex.py')}
\fi
\ST@wsf{import sympy}
\ST@wsf{import sympytex}
\ST@wsf{sympytex.openout('\jobname')}
%    \end{macrocode}
% \end{macro}
% Pull in the |.sout| file if it exists, or do nothing if it doesn't. I
% suppose we could do this inside an |AtBeginDocument| but I don't see
% any particular reason to do that. It will work whenever we load it.
%    \begin{macrocode}
\InputIfFileExists{\jobname.sout}{}{}
%    \end{macrocode}
%
% Now let's define the cool stuff.
%
% \begin{macro}{\sympy}
% This macro combines |\ref|, |\label|, and Sympy all at once. First, we
% use Sympy to get a \LTX representation of whatever you give this
% function. The Sympy script writes a |\newlabel| line into the |.sout|
% file, and we read the output using the |\ref| command. Usually, |\ref|
% pulls in a section or theorem number, but it will pull in arbitrary
% text just as well.
%
% The first thing it does it write its argument into the |.sympy| file,
% along with a counter so we can produce a unique label. We wrap a
% try/except around the function call so that we can provide a more
% helpful error message in case something goes wrong. (In particular, we
% can tell the user which line of the |.tex| file contains the offending
% code.)
%    \begin{macrocode}
\newcommand{\sympy}[1]{%
\ST@wsf{try:}%
\ST@wsf{ sympytex.inline(\theST@inline, #1)}%
\ST@wsf{except:}%
\ST@wsf{ sympytex.goboom(\the\inputlineno)}%
%    \end{macrocode}
% Our use of |\newlabel| and |\ref| seems awfully clever until you load
% the |hyperref| package, which gleefully tries to hyperlink the hell
% out of everything. This is great until it hits one of our special
% |\newlabel|s and gets deeply confused. Fortunately the |hyperref|
% folks are willing to accomodate people like us, and give us a
% |NoHyper| environment.
%    \begin{macrocode}
\begin{NoHyper}\ref{@sympylabel\theST@inline}\end{NoHyper}%
%    \end{macrocode}
% Now check to see if the label has already been defined. (The internal
% implementation of labels in \LTX involves defining a function
% ``|r@@labelname|''.) If it hasn't, we set a flag so that we can tell
% the user to run Sympy on the |.sympy| file at the end of the run.
% Finally, step the counter.
%    \begin{macrocode}
\@ifundefined{r@@sympylabel\theST@inline}{\gdef\ST@rerun{x}}{}%
\stepcounter{ST@inline}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sympyplain}
% This macro combines |\ref|, |\label|, and Sympy all at once. First, we
% use Sympy to get a plain representation of whatever you give this
% function. The Sympy script writes a |\newlabel| line into the |.sout|
% file, and we read the output using the |\ref| command. Usually, |\ref|
% pulls in a section or theorem number, but it will pull in arbitrary
% text just as well.
%
% The first thing it does it write its argument into the |.sympy| file,
% along with a counter so we can produce a unique label. We wrap a
% try/except around the function call so that we can provide a more
% helpful error message in case something goes wrong. (In particular, we
% can tell the user which line of the |.tex| file contains the offending
% code.)
%    \begin{macrocode}
\newcommand{\sympyplain}[1]{%
\ST@wsf{try:}%
\ST@wsf{ sympytex.inlineplain(\theST@inline, #1)}%
\ST@wsf{except:}%
\ST@wsf{ sympytex.goboom(\the\inputlineno)}%
%    \end{macrocode}
% Our use of |\newlabel| and |\ref| seems awfully clever until you load
% the |hyperref| package, which gleefully tries to hyperlink the hell
% out of everything. This is great until it hits one of our special
% |\newlabel|s and gets deeply confused. Fortunately the |hyperref|
% folks are willing to accomodate people like us, and give us a
% |NoHyper| environment.
%    \begin{macrocode}
\begin{NoHyper}\ref{@sympylabel\theST@inline}\end{NoHyper}%
%    \end{macrocode}
% Now check to see if the label has already been defined. (The internal
% implementation of labels in \LTX involves defining a function
% ``|r@@labelname|''.) If it hasn't, we set a flag so that we can tell
% the user to run Sympy on the |.sympy| file at the end of the run.
% Finally, step the counter.
%    \begin{macrocode}
\@ifundefined{r@@sympylabel\theST@inline}{\gdef\ST@rerun{x}}{}%
\stepcounter{ST@inline}}
%    \end{macrocode}
% \end{macro}
%
% The user might load the |hyperref| package after this one (indeed, the
% |hyperref| documentation insists that it be loaded last) or not at
% all---so when we hit the beginning of the document, provide a dummy
% |NoHyper| environment if one hasn't been defined by the |hyperref|
% package.
%    \begin{macrocode}
\AtBeginDocument{\provideenvironment{NoHyper}{}{}}
%    \end{macrocode}
%
% \begin{macro}{\percent} 
% A macro that inserts a percent sign. This is more-or-less stolen from the
% \textsf{Docstrip} manual; there they change the catcode inside a group
% and use |gdef|, but here we try to be more \LaTeX y and use
% |\newcommand|.
%    \begin{macrocode}
\catcode`\%=12
\newcommand{\percent}{%}
\catcode`\%=14
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ST@plotdir}
% A little abbreviation for the plot directory. We don't use
% |\graphicspath| because it's
% \href{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=graphicspath}{
% apparently slow}---also, since we know right where our plots are
% going, no need to have \LTX looking for them.
%    \begin{macrocode}
\newcommand{\ST@plotdir}{sympy-plots-for-\jobname.tex}
%    \end{macrocode}
% \end{macro}
%
% \tikzstyle{box}=[draw, shape=rectangle, thick]
%
% \begin{macro}{\sympyplot}
% \changes{v1.3}{2008/03/08}{Iron out warnings, cool Ti\emph{k}Z flowchart}
% This function is similar to |\sympy|. The neat thing that we take
% advantage of is that commas aren't special for arguments to \LTX
% commands, so it's easy to capture a bunch of keyword arguments that
% get passed right into a Python function.
%
% This macro has two optional arguments, which can't be defined using
% \LTX's |\newcommand|; we use Scott Pakin's brilliant
% \href{http://tug.ctan.org/tex-archive/support/newcommand/}{|newcommand|}
% package to create this macro; the options I fed to his script were
% similar to this:
%\begin{center}
% |MACRO sympyplot OPT[#1={width}] OPT[#2={notprovided}] #3|
%\end{center}
% Observe that we are using a Python script to write \LTX code which
% writes Python code which writes \LTX code. Crazy!
% 
% Here's the wrapper command which does whatever magic we need to get
% two optional arguments.
%    \begin{macrocode}
\newcommand{\sympyplot}[1][width=.75\textwidth]{%
  \@ifnextchar[{\ST@sympyplot[#1]}{\ST@sympyplot[#1][notprovided]}%]
}
%    \end{macrocode}
% That percent sign followed by a square bracket seems necessary; I have
% no idea why.
%
% The first optional argument |#1| will get shoved right into the
% optional argument for |\includegraphics|, so the user has easy control
% over the \LTX aspects of the plotting. We define a
% default size of $3/4$ the textwidth, which seems reasonable. (Perhaps
% a future version of \ST will allow the user to specify in the package
% options a set of default options to be used throughout.) The
% second optional argument |#2| is the file format and allows us to tell
% what files to look for. It defaults to ``notprovided'', which tells
% the Python module to create EPS and PDF files. Everything in |#3| gets
% put into the Python function call, so the user can put in keyword
% arguments there which get interpreted correctly by Python.
%
% \begin{macro}{\ST@sympyplot} Let's see the real code here. We write a
% couple lines to the |.sympy| file, including a counter, input line
% number, and all of the mandatory argument; all this is wrapped in
% another try/except. Note that the |\write| gobbles up line endings, so
% the |sympyplot| bits below get written to the |.sympy| file as one line.
%    \begin{macrocode}
\def\ST@sympyplot[#1][#2]#3{%
\ST@wsf{try:}%
\ST@wsf{ sympytex.initplot('\jobname')}%
\ST@wsf{ sympytex.plot(\theST@plot, #3, format='#2', epsmagick=\ST@epsim)}%
\ST@wsf{except:}%
\ST@wsf{ sympytex.goboom(\the\inputlineno)}%
%    \end{macrocode}
% Now we include the appropriate graphics file. Because the user might
% be producing DVI or PDF files, and have supplied a file format or not,
% and so on, the logic we follow is a bit complicated.
% \autoref{f:sympyplottree} shows what we do; for completeness, we show
% what |\ST@inclgrfx| does in \autoref{f:stig}. This entire
% complicated business is intended to avoid doing an |\includegraphics|
% command on a file that doesn't exist, and to issue warnings
% appropriate to the situation.
%
% \tikzstyle{box}=[draw, shape=rectangle, thick]
%
% \begin{figure}
%   \centering
%   \begin{tikzpicture}
%     \tikzstyle{level 1}=[sibling distance=6cm]
%     \tikzstyle{level 2}=[sibling distance=3cm]
%     \node [box] {DVI or PDF?}
%       child {node [box] {Format provided?}
%         child {node [box] {STig EPS}
%           edge from parent node[left] {no}}
%         child {node [box] {IM option set?}
%           child {node [box, text width=3cm] {Warn that DVI + PNG = bad}
%             edge from parent node[left] {no}}
%           child {node [box] {STig EPS}
%             edge from parent node[right] {yes}}
%           edge from parent node[right] {yes}}
%         edge from parent node[left] {DVI}}
%       child {node [box] {Format provided?}
%         child {node [box] {STig PDF}
%           edge from parent node[left] {no}}
%         child {node [box] {STig \texttt{\#2}}
%           edge from parent node[right] {yes}}
%         edge from parent node[right] {PDF}};
%   \end{tikzpicture}
%   \caption{The logic tree that \texttt{\bslash sympyplot} uses to
%   decide whether to run \texttt{\bslash includegraphics} or to yell at
%   the user. ``Format'' is the \texttt{\#2} argument to \texttt{\bslash
%   sympyplot}, ``STig ext''
%   means a call to \texttt{\bslash ST@inclgrfx} with ``ext'' as the
%   second argument, and ``IM'' is Imagemagick.}
%   \label{f:sympyplottree}
% \end{figure}
%
% If we are creating a PDF, we check to see if the user asked for a
% different format, and use that if necessary:
%    \begin{macrocode}
\ifpdf
  \ifthenelse{\equal{#2}{notprovided}}%
    {\ST@inclgrfx{#1}{pdf}}%
    {\ST@inclgrfx{#1}{#2}}%
%    \end{macrocode}
% Otherwise, we are creating a DVI file, which only supports EPS. If the
% user provided a format anyway, don't include the file (since it won't
% work) and warn the user about this. (Unless the file doesn't exist, in
% which case we do the same thing that |\ST@inclgrfx| does.)
%    \begin{macrocode}
\else
  \ifthenelse{\equal{#2}{notprovided}}%
    {\ST@inclgrfx{#1}{eps}}%
%    \end{macrocode}
% If a format is provided, we check to see if we're using the
% imagemagick option. If so, try to include an EPS file anyway.
%    \begin{macrocode}
    {\ifthenelse{\equal{#2}{eps}}
     {\ST@inclgrfx{#1}{eps}}%
     {\ifthenelse{\equal{\ST@epsim}{True}}
      {\ST@inclgrfx{#1}{eps}}%
%    \end{macrocode}
% If we're not using the imagemagick option, we're going to issue some
% sort of warning, depending on whether the file exists yet or not.
%    \begin{macrocode}
      {\IfFileExists{\ST@plotdir/plot-\theST@plot.#2}%
        {\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}%
         \PackageWarning{sympytex}{Graphics file
         \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space
         cannot be used with DVI output. Use pdflatex or create an EPS
         file. Plot command is}}%
        {\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}%
         \PackageWarning{sympytex}{Graphics file
         \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space
         does not exist}%
         \gdef\ST@rerun{x}}}}}%
\fi
%    \end{macrocode}
% Finally, step the counter and we're done.
%    \begin{macrocode}
\stepcounter{ST@plot}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\ST@inclgrfx}
% This command includes the requested graphics file (|#2| is the
% extension) with the requested options (|#1|) if the file exists. Note
% that it just needs to know the extension, since we use a counter for
% the filename.
%    \begin{macrocode}
\newcommand{\ST@inclgrfx}[2]{%
  \IfFileExists{\ST@plotdir/plot-\theST@plot.#2}%
    {\includegraphics[#1]{\ST@plotdir/plot-\theST@plot.#2}}%
%    \end{macrocode}
% If the file doesn't exist, we insert a little box to indicate it
% wasn't found, issue a warning that we didn't find a graphics file,
% then set a flag that, at the end of the run, tells the user to run
% Sympy again.
%    \begin{macrocode}
    {\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}%
     \PackageWarning{sympytex}{Graphics file
     \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space does not
     exist}%
     \gdef\ST@rerun{x}}}
%    \end{macrocode}
% \autoref{f:stig} makes this a bit clearer. 
% \begin{figure}
%   \centering
%   \begin{tikzpicture}
%     \tikzstyle{level 1}=[sibling distance=4cm]
%     \node [box] {Does EXT file exist?}
%       child {node [box, text width = 2.125cm] {Warn user to rerun Sympy}
%         edge from parent node[left] {no}}
%       child {node [box] {Use \texttt{includegraphics}}
%         edge from parent node[right] {yes}};
%   \end{tikzpicture}
%   \caption{The logic used by the \texttt{\bslash ST@inclgrfx}
%   command.}
%   \label{f:stig}
% \end{figure}
% \end{macro}
%
% \begin{macro}{\ST@beginsfbl}
% This is ``begin |.sympy| file block'', an internal-use abbreviation
% that sets things up when we start writing a chunk of Sympy code to the
% |.sympy| file. It begins with some \TeX{} magic that fixes spacing,
% then puts the start of a try/except block in the |.sympy| file---this
% not only allows the user to indent code without Sympy/Python
% complaining about indentation, but lets us tell the user where things
% went wrong. The last bit is some magic from the |verbatim| package
% manual that makes \LTX respect line breaks.
%    \begin{macrocode}
\newcommand{\ST@beginsfbl}{%
  \@bsphack%
  \ST@wsf{sympytex.blockbegin()}%
  \ST@wsf{try:}%
  \let\do\@makeother\dospecials\catcode`\^^M\active}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ST@endsfbl}
% The companion to |\ST@beginsfbl|. 
%    \begin{macrocode}
\newcommand{\ST@endsfbl}{%
\ST@wsf{except:}%
\ST@wsf{ sympytex.goboom(\the\inputlineno)}%
\ST@wsf{sympytex.blockend()}}
%    \end{macrocode}
% \end{macro}
%
% Now let's define the ``verbatim-like'' environments. There are four
% possibilities, corresponding to two independent choices of
% typesetting the code or not, and writing to the |.sympy| file or not.
%
% \begin{environment}{sympyblock}
% This environment does both: it typesets your code and puts it into the
% |.sympy| file for execution by Sympy.
%    \begin{macrocode}
\newenvironment{sympyblock}{\ST@beginsfbl%
%    \end{macrocode}
% The space between |\ST@wsf{| and |\the| is crucial! It, along with the
% ``|try:|'', is what allows the user to indent code if they like.
% This line sends stuff to the |.sympy| file.
%    \begin{macrocode}
\def\verbatim@processline{\ST@wsf{ \the\verbatim@line}%
%    \end{macrocode}
% Next, we typeset your code and start the verbatim environment.
%    \begin{macrocode}
\hspace{\sympytexindent}\the\verbatim@line\par}%
\verbatim}%
%    \end{macrocode}
% At the end of the environment, we put a chunk into the |.sympy| file
% and stop the verbatim environment.
%    \begin{macrocode}
{\ST@endsfbl\endverbatim}
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{sympysilent}
% This is from the |verbatim| package manual. It's just like the above,
% except we don't typeset anything.
%    \begin{macrocode}
\newenvironment{sympysilent}{\ST@beginsfbl%
\def\verbatim@processline{\ST@wsf{ \the\verbatim@line}}%
\verbatim@start}%
{\ST@endsfbl\@esphack}
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{sympyverbatim}
% The opposite of |sympysilent|. This is exactly the same as the verbatim
% environment, except that we include some indentation to be consistent
% with other typeset Sympy code.
%    \begin{macrocode}
\newenvironment{sympyverbatim}{%
\def\verbatim@processline{\hspace{\sympytexindent}\the\verbatim@line\par}%
\verbatim}%
{\endverbatim}
%    \end{macrocode}
% \end{environment}
%
% Logically, we now need an environment which neither typesets
% \emph{nor} writes code to the |.sympy| file. The verbatim package's
% |comment| environment does that.\\
%
% Now we deal with some end-of-file cleanup.
%
% We tell the Sympy script to write some information to the |.sout| file,
% then check to see if |ST@rerun| ever got defined. If not, all the
% inline formulas and plots worked, so do nothing.
%    \begin{macrocode}
\AtEndDocument{\ST@wsf{sympytex.endofdoc()}%
\@ifundefined{ST@rerun}{}%
%    \end{macrocode}
% Otherwise, we issue a warning to tell the user to run Sympy on the
% |.sympy| file. Part of the reason we do this is that, by using |\ref|
% to pull in the inlines, \LTX will complain about undefined
% references if you haven't run the Sympy script---and for many \LTX
% users, myself included, the warning ``there were undefined
% references'' is a signal to run \LTX again. But to fix these
% particular undefined references, you need to run \emph{Sympy}. We also
% suppressed file-not-found errors for graphics files, and need to tell
% the user what to do about that.
%
% At any rate, we tell the user to run Sympy if it's necessary.
%    \begin{macrocode}
{\PackageWarningNoLine{sympytex}{There were undefined Sympy formulas
and/or plots}%
\PackageWarningNoLine{sympytex}{Run python on \jobname.sympy, and then run
LaTeX on \jobname.tex again}}}
%    \end{macrocode}
%
%
% \subsection{The Python module}
%
% \iffalse
% Hey, docstrip! Stop putting code into the .sty file, and start
% putting it into the .py file.
%</latex>
%<*python>
% Thanks.
% \fi
%
% The style file writes things to the |.sympy| file and reads them from
% the |.sout| file. The Python module provides functions that help
% produce the |.sout| file from the |.sympy| file.
%
% \paragraph{A note on Python and \textsf{Docstrip}} There is one tiny
% potential source of confusion when documenting Python code with
% \textsf{Docstrip}: the percent sign. If you have a long line of Python
% code which includes a percent sign for string formatting and you break
% the line with a backslash and begin the next line with a percent sign,
% that line \emph{will not} be written to the output file. This is only
% a problem if you \emph{begin} the line with a percent sign; there are
% no troubles otherwise.\\
%
% On to the code:
%
% The |sympytex.py| file is intended to be used as a module and doesn't
% do anything useful when called directly, so if someone does that, warn
% them. We do this right away so that we print this and exit before
% trying to import any Sympy modules; that way, this error message gets
% printed whether you run the script with Sympy or with Python.
%    \begin{macrocode}
import sys
if __name__ == "__main__":
  print("""This file is part of the SympyTeX package.
It is not meant to be called directly.

This file will be used by Sympy scripts generated from a LaTeX document
using the sympytex package. Keep it somewhere where Sympy and Python can
find it and it will automatically be imported.""")
  sys.exit()
%    \end{macrocode}
% We start with some imports and definitions of our global variables.
% This is a relatively specialized use of Sympy, so using global
% variables isn't a bad idea. Plus I think when we import this module,
% they will all stay inside the |sympytex| namespace anyway.
%    \begin{macrocode}
import sympy
from sympy.plotting.plot import plot, Plot
import os
import os.path
import hashlib
import traceback
import subprocess
import shutil
initplot_done = False
dirname       = None
filename      = ""
%    \end{macrocode}
% \begin{macro}{ttexprint}
% This function gets around the insertion of begin/end math symbols that
% sympy puts into its latex output
%    \begin{macrocode}
from string import strip
def ttexprint(exp):
  return strip(sympy.latex(exp, mode='inline'),'$')
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{progress}
% This function justs prints stuff. It allows us to not print a
% linebreak, so you can get ``|start...|'' (little time spent
% processing) ``|end|'' on one line.
%    \begin{macrocode}
def progress(t,linebreak=True):
  if linebreak:
    print(t)
  else:
    sys.stdout.write(t)
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{openout}
% This function opens a |.sout.tmp| file and writes all our output to
% that. Then, when we're done, we move that to |.sout|. The
% ``autogenerated'' line is basically the same as the lines that get put
% at the top of preparsed sympy files; we are automatically generating a
% file with sympy, so it seems reasonable to add it.
%    \begin{macrocode}
def openout(f):
  global filename
  filename = f
  global _file_
  _file_ = open(f + '.sout.tmp', 'w')
  s = '% This file was *autogenerated* from the file ' + \
        os.path.splitext(filename)[0] + '.sympy.\n'
  _file_.write(s)
  progress('Processing Sympy code for %s.tex...' % filename)
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{initplot}
% We only want to create the plots directory if the user actually plots
% something. This function creates the directory and sets the
% |initplot_done| flag after doing so. We make a directory based on the
% \LTX file being processed so that if there are multiple |.tex|
% files in a directory, we don't overwrite plots from another file.
%    \begin{macrocode}
def initplot(f):
  global initplot_done
  if not initplot_done:
    progress('Initializing plots directory')
    global dirname
%    \end{macrocode}
% We hard-code the |.tex| extension, which is fine in the overwhelming
% majority of cases, although it does cause minor confusion when
% building the documentation. If it turns out lots of people use, say, a
% |ltx| extension or whatever, I think we could find out the correct
% extension, but it would involve a lot of irritating mucking around.
%    \begin{macrocode}
    dirname = 'sympy-plots-for-' + f + '.tex'
    if os.path.isdir(dirname):
      shutil.rmtree(dirname)
    os.mkdir(dirname)
    initplot_done = True
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{inline}
% This function works with |\sympy| from the style file to put Sympy
% output into your \LTX file. Usually, when you use |\label|, it
% writes a line such as
% \begin{center}
%   |\newlabel{labelname}{{section number}{page number}}|
% \end{center}
% to the |.aux| file. When you use the |hyperref| package, there are
% more fields in the second argument, but the first two are the same.
% The |\ref| command just pulls in what's in the first field, so we can
% hijack this mechanism for our own nefarious purposes. The function
% writes a |\newlabel| line with a label made from a counter and the
% text from running Sympy on |s|. 
%
% We print out the line number so if something goes wrong, the user can
% more easily track down the offending |\sympy| command in the source
% file.
%
% That's a lot of explanation for a very short function:
%    \begin{macrocode}
def inline(counter, s):
  progress('Inline formula %s' % counter)
  _file_.write('\\newlabel{@sympylabel' + str(counter) + '}{{' + \
               ttexprint(s) + '}{}{}{}{}}\n')
%    \end{macrocode}
% We are using five fields, just like |hyperref| does, because that
% works whether or not |hyperref| is loaded. Using two fields, as in plain
% \LTX, doesn't work if |hyperref| is loaded.
% \end{macro}
%
% \begin{macro}{inlineplain}
% This function works with |\sympy| from the style file to put Sympy
% output into your \LTX file. This does not format the output!
%
% We print out the line number so if something goes wrong, the user can
% more easily track down the offending |\sympy| command in the source
% file.
%
% That's a lot of explanation for a very short function:
%    \begin{macrocode}
def inlineplain(counter, s):
  progress('Inline Plain formula %s' % counter)
  _file_.write('\\newlabel{@sympylabel' + str(counter) + '}{{' + \
               str(s) + '}{}{}{}{}}\n')
%    \end{macrocode}
% We are using five fields, just like |hyperref| does, because that
% works whether or not |hyperref| is loaded. Using two fields, as in plain
% \LTX, doesn't work if |hyperref| is loaded.
% \end{macro}
%
% \begin{macro}{blockbegin}
% \begin{macro}{blockend}
% This function and its companion used to write stuff to the |.sout|
% file, but now they just update the user on our progress evaluating a
% code block.
%    \begin{macrocode}
def blockbegin():
  progress('Code block begin...', False)
def blockend():
  progress('end')
%    \end{macrocode}
% \end{macro} 
% \end{macro} 
%
% \begin{macro}{plot}
% I hope it's obvious that this function does plotting. As mentioned in
% the |\sympyplot| code, we're taking advantage of two things: first,
% that \LTX doesn't treat commas and spaces in macro arguments
% specially, and second, that Python (and Sympy plotting functions) has
% nice support for keyword arguments. The |#3| argument to |\sympyplot|
% becomes |p| and |**kwargs| below.
%    \begin{macrocode}
def plot(counter, p, format='notprovided', epsmagick=False, **kwargs):
  global dirname
  progress('Plot %s' % counter)
%    \end{macrocode}
% If the user says nothing about file formats, we default to producing
% PDF and EPS. This allows the user to transparently switch between
% using a DVI previewer (which usually automatically updates when the
% DVI changes, and has support for source specials, which makes the
% writing process easier) and making PDFs. 
%    \begin{macrocode}
  if format == 'notprovided':
    formats = ['eps', 'pdf']
  else:
    formats = [format]
  for fmt in formats:
    plotfilename = os.path.join(dirname, 'plot-%s.%s' % (counter, fmt))
    print('  plotting %s with args %s' % (plotfilename, kwargs))
    if (isinstance(p, Plot)):
      p.save(plotfilename)
    else:
      p.savefig(filename=plotfilename, **kwargs)
%    \end{macrocode}
% If the user provides a format \emph{and} specifies the |imagemagick|
% option, we try to convert the newly-created file into EPS format.
%    \begin{macrocode}
    if format != 'notprovided' and epsmagick is True:
      print('Calling Imagemagick to convert plot-%s.%s to EPS' % \
        (counter, format))
      toeps(counter, format)
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{toeps}
% This function calls the Imagmagick utility |convert| to, well, convert
% something into EPS format. This gets called when the user has
% requested the ``|imagemagick|'' option to the \ST\ style file and is
% making a graphic file with a nondefault extension.
%    \begin{macrocode}
def toeps(counter, ext):
  global dirname
  subprocess.check_call(['convert',\
    '%s/plot-%s.%s' % (dirname, counter, ext), \
    '%s/plot-%s.eps' % (dirname, counter)])
%    \end{macrocode}
% We are blindly assuming that the |convert| command exists and will do
% the conversion for us; the |check_call| function raises an exception
% which, since all these calls get wrapped in try/excepts in the |.sympy|
% file, should result in a reasonable error message if something strange
% happens.
% \end{macro}
%
% \begin{macro}{goboom}
% When a chunk of Sympy code blows up, this function bears the bad news
% to the user. Normally in Python the traceback is good enough for this,
% but in this case, we start with a |.sympy| file (which is
% autogenerated) which autogenerates a |.py| file---and the tracebacks
% the user sees refer to that file, whose line numbers are basically
% useless. We want to tell them where in the \LTX file things went
% bad, so we do that, give them the traceback, and exit after removing
% the |.sout.tmp| file.
%    \begin{macrocode}
def goboom(line):
  global filename
  print('\n**** Error in Sympy code on line %s of %s.tex! Traceback\
 follows.' % (line, filename))
  traceback.print_exc()
  print('\n**** Running Sympy on %s.sympy failed! Fix %s.tex and try\
 again.' % (filename, filename))
  os.remove(filename + '.sout.tmp')
  sys.exit(1)
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{endofdoc}
% When we're done processing, we have a couple little cleanup tasks. We
% want to put the MD5 sm of the |.sympy| file that produced the |.sout|
% file we're about to write into the |.sout| file, so that external
% programs that build \LTX documents can tell if they need to call Sympy
% to update the |.sout| file. But there is a problem: we write line
% numbers to the |.sympy| file so that we can provide useful error
% messages---but that means that adding, say, a line break to your
% source file will change the MD5 sum, and your program will think it
% needs to rerun Sympy even though none of the actual calls to Sympy have
% changed.
%
% How do we include line numbers for our error messages but still allow
% a program to discover a ``genuine'' change to the |.sympy| file? 
%
% The answer is to only find the MD5 sum of \emph{part} of the |.sympy|
% file. By design, the source file line numbers only appear in calls to
% |goboom|, so we will strip those lines out. Basically we are doing
% \begin{center}
% \verb+grep -v '^ sympytex.goboom' filename.sympy | md5sum+
% \end{center}
% (In fact, what we do below produces exactly the same sum.) 
%    \begin{macrocode}
def endofdoc():
  global filename
  sympyf = open(filename + '.sympy', 'r')
  m = hashlib.md5()
  for line in sympyf:
    if line[0:15] != ' sympytex.goboom':
      m.update(line)
  s = '%' + m.hexdigest() + '% md5sum of .sympy file (minus "goboom" \
lines) that produced this\n'
  _file_.write(s)
%    \end{macrocode}
% Now, we do issue warnings to run Sympy on the |.sympy| file and an
% external program might look for those to detect the need to rerun
% Sympy, but those warnings do not quite capture all situations. (If
% % you've already produced the |.sout| file and change a |\sympy| call, no
% warning will be issued since all the |\ref|s find a |\newlabel|.)
% Anyway, I think it's easier to grab an MD5 sum out of the end of the
% file than parse the output from running |latex| on your file. (The
% regular expression |^%[0-9a-f]{32}%| will find the MD5 sum.)
%
% Now we are done with the |.sout| file. Close it, rename it, and tell
% the user we're done.
%    \begin{macrocode}
  _file_.close()
  os.rename(filename + '.sout.tmp', filename + '.sout')
  progress('Sympy processing complete. Run LaTeX on %s.tex again.' %\
           filename)
%    \end{macrocode}
% \end{macro}
%
% \section{Credits and acknowledgements}
%
% This is competely based around the excellent sagetex package for
% embedding sage into LaTeX. All credit to Dan Drake and others.
%
% \section{Copying and licenses}
%
% The \emph{source code} of the \ST package may be redistributed and/or
% modified under the terms of the GNU General Public License as
% published by the Free Software Foundation, either version 2 of the
% License, or (at your option) any later version. To view a copy of this
% license, see \url{http://www.gnu.org/licenses/} or send a letter to
% the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
% Boston, MA 02110-1301, USA.
%
% The \emph{documentation} of the \ST package is licensed under the
% Creative Commons Attribution-Noncommercial-Share Alike 3.0 License. To
% view a copy of this license, visit
% \url{http://creativecommons.org/licenses/by-nc-sa/3.0/} or send a
% letter to Creative Commons, 171 Second Street, Suite 300, San
% Francisco, California, 94105, USA.