From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 2 Sep 2019 13:46:59 +0900
Subject: Initial commit

---
 macros/latex/contrib/sagetex/py-and-sty.dtx | 1575 +++++++++++++++++++++++++++
 1 file changed, 1575 insertions(+)
 create mode 100644 macros/latex/contrib/sagetex/py-and-sty.dtx

(limited to 'macros/latex/contrib/sagetex/py-and-sty.dtx')

diff --git a/macros/latex/contrib/sagetex/py-and-sty.dtx b/macros/latex/contrib/sagetex/py-and-sty.dtx
new file mode 100644
index 0000000000..a27dbc5bd8
--- /dev/null
+++ b/macros/latex/contrib/sagetex/py-and-sty.dtx
@@ -0,0 +1,1575 @@
+% \section{Implementation}
+% \label{sec: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}
+% \label{sec:sty-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@|''.
+%
+% \subsubsection{Initialization}
+%
+% Let's begin by loading some packages. The key bits of |sageblock| and
+% friends are stol---um, adapted from the |verbatim| package manual. So
+% grab the |verbatim| package. We also need the |fancyvrb| package for
+% the |sageexample| environment
+%    \begin{macrocode}
+\RequirePackage{verbatim}
+\RequirePackage{fancyvrb}
+%    \end{macrocode}
+% and |listings| for the |sagecommandline| environment.
+%    \begin{macrocode}
+\RequirePackage{listings}
+\RequirePackage{color}
+\lstdefinelanguage{Sage}[]{Python}
+  {morekeywords={False,sage,True},sensitive=true}
+\lstdefinelanguage{SageOutput}[]{}
+  {morekeywords={False,True},sensitive=true}
+\lstdefinestyle{DefaultSageInputOutput}{
+  nolol,
+  identifierstyle=,
+  name=sagecommandline,
+  xleftmargin=5pt,
+  numbersep=5pt,
+  aboveskip=0pt,
+  belowskip=0pt,
+  breaklines=true,
+  numberstyle=\footnotesize,
+  numbers=right
+}
+\lstdefinestyle{DefaultSageInput}{
+  language=Sage,
+  style=DefaultSageInputOutput,
+  basicstyle={\ttfamily\bfseries},
+  commentstyle={\ttfamily\color{dgreencolor}},
+  keywordstyle={\ttfamily\color{dbluecolor}\bfseries},
+  stringstyle={\ttfamily\color{dgraycolor}\bfseries},
+}
+\lstdefinestyle{DefaultSageOutput}{
+  language=SageOutput,
+  style=DefaultSageInputOutput,
+  basicstyle={\ttfamily},
+  commentstyle={\ttfamily\color{dgreencolor}},
+  keywordstyle={\ttfamily\color{dbluecolor}},
+  stringstyle={\ttfamily\color{dgraycolor}},
+}
+\lstdefinestyle{SageInput}{
+  style=DefaultSageInput,
+}
+\lstdefinestyle{SageOutput}{
+  style=DefaultSageOutput,
+}
+\definecolor{dbluecolor}{rgb}{0.01,0.02,0.7}
+\definecolor{dgreencolor}{rgb}{0.2,0.4,0.0}
+\definecolor{dgraycolor}{rgb}{0.30,0.3,0.30}
+%    \end{macrocode}
+% Unsurprisingly, the |\sageplot| 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 |\sageplot| so we know what kind of
+% files to look for. Since |ifpdf| doesn't detect running under XeTeX
+% (which defaults to producing PDFs), we need |ifxetex|. Hopefully the
+% |ifpdf| package will get support for this and we can drop |ifxetex|.
+% We also work around ancient \TeX{} distributions that don't have
+% |ifxetex| and assume that they don't have XeTeX.
+%    \begin{macrocode}
+\RequirePackage{makecmds}
+\RequirePackage{ifpdf}
+\RequirePackage{ifthen}
+\IfFileExists{ifxetex.sty}{
+  \RequirePackage{ifxetex}
+}{
+  \newboolean{xetex}
+  \setboolean{xetex}{false}}
+%    \end{macrocode}
+%
+% Next set up the counters, default indent, and flags.
+%    \begin{macrocode}
+\newcounter{ST@inline}
+\newcounter{ST@plot}
+\newcounter{ST@cmdline}
+\setcounter{ST@inline}{0}
+\setcounter{ST@plot}{0}
+\setcounter{ST@cmdline}{0}
+\newlength{\sagetexindent}
+\setlength{\sagetexindent}{5ex}
+\newif\ifST@paused
+\ST@pausedfalse
+%    \end{macrocode}
+% Set up the file stuff, which will get run at the beginning of the
+% document, after we know what's happening with the |final| option.
+% First, we open the |.sage| file:
+%    \begin{macrocode}
+\AtBeginDocument{\@ifundefined{ST@final}{%
+\newwrite\ST@sf%
+\immediate\openout\ST@sf=\jobname.sagetex.sage%
+%    \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
+%   |.sage| file. The hash mark below gets doubled when written to the
+%   file, for some obscure reason related to parameter expansion. It's
+%   valid Python, though, so I haven't bothered figuring out how to get
+%   a single hash. We are assuming that the extension is |.tex|; see the
+%   |initplot| documentation on page~\pageref{initplot} for discussion
+%   of file extensions. (There is now the \texttt{currfile} package
+%   (\url{http://www.ctan.org/pkg/currfile/}) which can figure out file
+%   extensions, apparently.) The ``|(\jobname.sagetex.sage)|'' business
+%   is there because the comment below will get pulled into the
+%   autogenerated |.py| file (second order autogeneration!) and I'd like
+%   to reduce possible confusion if someone is looking around in those
+%   files. Finally, we check for version mismatch and bail if the .py
+%   and .sty versions don't match and the user hasn't disabled checking.
+%   Note that we use |^^J| and not |^^J%| when we need indented lines.
+%   Also, |sagetex.py| now includes a |version| variable which
+%   eliminates all the irritating string munging below, and later we can
+%   remove this stuff and just use |sagetex.version|.
+%   \changes{v2.2.4}{2010/02/15}{Add version mismatch checking.}
+%   \changes{v2.3.3}{2012/01/13}{Improve version mismatch checking,
+%   include Mercurial revision in version string.}
+%    \begin{macrocode}
+\newcommand{\ST@wsf}[1]{\immediate\write\ST@sf{#1}}%
+\ST@wsf{%
+# -*- encoding: utf-8 -*-^^J%
+# This file (\jobname.sagetex.sage) was *autogenerated* from \jobname.tex with
+sagetex.sty version \ST@ver.^^J%
+import sagetex^^J%
+_st_ = sagetex.SageTeXProcessor('\jobname', version='\ST@ver', version_check=\ST@versioncheck)}}%
+%    \end{macrocode}
+% On the other hand, if the |ST@final| flag is set, don't bother with
+% any of the file stuff, and make |\ST@wsf| a no-op.
+%    \begin{macrocode}
+{\newcommand{\ST@wsf}[1]{\relax}}}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ST@dodfsetup}
+%   The |sageexample| environment writes stuff out to a different file
+%   formatted so that one can run doctests on it. We define a macro that
+%   only sets this up if necessary.
+%    \begin{macrocode}
+\newcommand{\ST@dodfsetup}{%
+\@ifundefined{ST@diddfsetup}{%
+\newwrite\ST@df%
+\immediate\openout\ST@df=\jobname_doctest.sage%
+\immediate\write\ST@df{r"""^^J%
+This file was *autogenerated* from \jobname.tex with sagetex.sty^^J%
+version \ST@ver. It contains the contents of all the^^J%
+sageexample environments from \jobname.tex. You should be able to^^J%
+doctest this file with "sage -t \jobname_doctest.sage".^^J%
+^^J%
+It is always safe to delete this file; it is not used in typesetting your^^J%
+document.^^J}%
+\AtEndDocument{\immediate\write\ST@df{"""}}%
+\gdef\ST@diddfsetup{x}}%
+{\relax}}
+%    \end{macrocode}
+% \changes{v2.2.5}{2010/03/25}{Write sageexample environment contents to
+% a separate file, formatted for doctesting}
+% \end{macro}
+%
+% \begin{macro}{\ST@wdf}
+%   This is the compansion to |\ST@wsf|; it writes to the doctest file,
+%   assuming that is has been set up. We ignore the |final| option here
+%   since nothing in this file is relevant to typesetting the document.
+%    \begin{macrocode}
+\newcommand{\ST@wdf}[1]{\immediate\write\ST@df{#1}}
+%    \end{macrocode}
+% \end{macro}
+%
+% Now we declare our options, which mostly just set flags that we check
+% at the beginning of the document, and when running the |.sage| file.
+% \changes{v2.0}{2008/04/04}{Add \texttt{epstopdf} option}
+% \changes{v2.0}{2008/12/16}{Add \texttt{final} option}
+%
+% The |final| option controls whether or not we write the |.sage| file;
+% the |imagemagick| and |epstopdf| options both want to write something
+% to that same file. So we put off all the actual file stuff until the
+% beginning of the document---by that time, we'll have processed the
+% |final| option (or not) and can check the |\ST@final| flag to see what
+% to do. (We must do this because we can't specify code that runs if an
+% option \emph{isn't} defined.)
+%
+% For |final|, we set a flag for other guys to check, and if there's no
+% |.sout| file, we warn the user that something fishy is going on.
+%    \begin{macrocode}
+\DeclareOption{final}{%
+  \newcommand{\ST@final}{x}%
+  \IfFileExists{\jobname.sagetex.sout}{}{\AtEndDocument{\PackageWarningNoLine{sagetex}%
+  {`final' option provided, but \jobname.sagetex.sout^^Jdoesn't exist! No Sage
+    input will appear in your document. Remove the `final'^^Joption and
+    rerun LaTeX on your document}}}}
+%    \end{macrocode}
+% For |imagemagick|, we set two flags: one for \LTX and one for Sage.
+% It's important that we set |ST@useimagmagick| \emph{before} the
+% beginning of the document, so that the graphics commands can check
+% that. We do wait until the beginning of the document to do file
+% writing stuff.
+%    \begin{macrocode}
+\DeclareOption{imagemagick}{%
+  \newcommand{\ST@useimagemagick}{x}%
+  \AtBeginDocument{%
+  \@ifundefined{ST@final}{%
+    \ST@wsf{_st_.useimagemagick = True}}{}}}
+%    \end{macrocode}
+% For |epstopdf|, we just set a flag for Sage.
+%    \begin{macrocode}
+\DeclareOption{epstopdf}{%
+\AtBeginDocument{%
+\@ifundefined{ST@final}{%
+  \ST@wsf{_st_.useepstopdf = True}}{}}}
+%    \end{macrocode}
+% By default, we check to see if the .py and .sty file versions match.
+% But we let the user disable this.
+%    \begin{macrocode}
+\newcommand{\ST@versioncheck}{True}
+\DeclareOption{noversioncheck}{%
+  \renewcommand{\ST@versioncheck}{False}}
+\ProcessOptions\relax
+%    \end{macrocode}
+% The |\relax| is a little incantation suggested by the ``\LaTeXe{} for
+% class and package writers'' manual, section 4.7.
+%
+% 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. If
+% the |.sout| file isn't found, print the usual \TeX-style message. This
+% allows programs
+% (\href{http://www.phys.psu.edu/~collins/software/latexmk-jcc/}{\texttt{Latexmk}}, for example)
+% that read the |.log| file or terminal output to detect
+% the need for another typesetting run to do so. If the ``\texttt{No
+%   file foo.sout}'' line doesn't work for some software package, please
+% let me know and I can change it to use |PackageInfo| or whatever.
+%    \begin{macrocode}
+\InputIfFileExists{\jobname.sagetex.sout}{}
+{\typeout{No file \jobname.sagetex.sout.}}
+%    \end{macrocode}
+% \changes{v2.1.1}{2009/05/14}{Add typeout if .sout file not found}
+%
+% 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. We need this for the |\sage| macro below.
+%    \begin{macrocode}
+\AtBeginDocument{\provideenvironment{NoHyper}{}{}}
+%    \end{macrocode}
+%
+% \subsubsection{The \texttt{\protect\bslash sage} and
+% \texttt{\protect\bslash sagestr} macros}
+% \label{sec:sagemacro}
+%
+% \begin{macro}{\ST@sage}
+% \changes{v2.1.1}{2009/05/14}{Add ST@sage, sagestr, and refactor.}
+% This macro combines |\ref|, |\label|, and Sage all at once. First, we
+% use Sage to get a \LTX representation of whatever you give this
+% function. The Sage 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 |.sage| 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.) Note the difference between |^^J| and |^^J%|: the newline
+% immediately after the former puts a space into the output, and the
+% percent sign in the latter supresses this.
+%    \begin{macrocode}
+\newcommand{\ST@sage}[1]{\ST@wsf{%
+try:^^J
+ _st_.current_tex_line = \the\inputlineno^^J
+ _st_.inline(\theST@inline, #1)^^J%
+except:^^J
+ _st_.goboom(\the\inputlineno)}%
+%    \end{macrocode}
+% The |inline| function of the Python module is documented on page
+% \pageref{inlinefn}. Back in \LTX-land: if paused, say so.
+%    \begin{macrocode}
+\ifST@paused
+  \mbox{(Sage\TeX{} is paused)}%
+%    \end{macrocode}
+% Otherwise\ldots 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}
+\else
+  \begin{NoHyper}\ref{@sageinline\theST@inline}\end{NoHyper}%
+%    \end{macrocode}
+% Now check if the label has already been defined. (The internal
+% implementation of labels in \LTX involves defining a macro called
+% ``|r@@labelname|''.) If it hasn't, we set a flag so that we can tell
+% the user to run Sage on the |.sage| file at the end of the run.
+%    \begin{macrocode}
+  \@ifundefined{r@@sageinline\theST@inline}{\gdef\ST@rerun{x}}{}%
+\fi
+%    \end{macrocode}
+% In any case, the last thing to do is step the counter.
+%    \begin{macrocode}
+\stepcounter{ST@inline}}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sage}
+% This is the user-visible macro; it runs Sage's |latex()| on its
+% argument.
+%    \begin{macrocode}
+\newcommand{\sage}[1]{\ST@sage{latex(#1)}}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sagestr}
+% Like above, but doesn't run |latex()| on its argument.
+%    \begin{macrocode}
+\newcommand{\sagestr}[1]{\ST@sage{#1}}
+%    \end{macrocode}
+%
+% \end{macro}
+%
+% \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}
+%
+% \subsubsection{The \texttt{\protect\bslash sageplot} macro and friends}
+% \label{sec:sageplotmacro}
+%
+% Plotting is rather more complicated, and requires several helper
+% macros that accompany |\sageplot|.
+%
+% \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}{sage-plots-for-\jobname.tex}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ST@missingfilebox}
+% The code that makes the ``file not found'' box. This shows up in a
+% couple places below, so let's just define it once.
+%    \begin{macrocode}
+\newcommand{\ST@missingfilebox}{\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\sageplot}
+% \changes{v1.3}{2008/03/08}{Iron out warnings, cool \TikZ flowchart}
+% This function is similar to |\sage|. 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 sageplot 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{\sageplot}[1][]{%
+  \@ifnextchar[{\ST@sageplot[#1]}{\ST@sageplot[#1][notprovided]}}
+%    \end{macrocode}
+% \changes{v2.3.2}{2011/06/17}{Remove ``.75 textwidth'' default option}
+% 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. (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@sageplot}
+% \changes{v2.0}{2008/12/16}{Change to use only keyword arguments: see issue
+% 2 on bitbucket tracker}
+% Let's see the real code here. We write a couple lines to the |.sage|
+% file, including a counter, input line number, and all of the mandatory
+% argument; all this is wrapped in another try/except.
+%    \begin{macrocode}
+\def\ST@sageplot[#1][#2]#3{\ST@wsf{try:^^J
+ _st_.current_tex_line = \the\inputlineno^^J
+ _st_.plot(\theST@plot, format='#2', _p_=#3)^^Jexcept:^^J
+ _st_.goboom(\the\inputlineno)}%
+%    \end{macrocode}
+% The Python |plot| function is documented on page~\pageref{plotfn}.
+%
+% 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:sageplottree} shows what we do; for completeness---and
+% because I think drawing trees with \TikZ is really cool---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.
+%
+% \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 sageplot} uses to
+%   decide whether to run \texttt{\bslash includegraphics} or to yell at
+%   the user. ``Format'' is the \texttt{\#2} argument to \texttt{\bslash
+%   sageplot}, ``STig ext''
+%   means a call to \texttt{\bslash ST@inclgrfx} with ``ext'' as the
+%   second argument, and ``IM'' is Imagemagick.}
+%   \label{f:sageplottree}
+% \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}
+\ifthenelse{\boolean{pdf} \or \boolean{xetex}}{
+  \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}
+{ \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 not, we're going to issue some sort of warning,
+% depending on whether the file exists yet or not.
+%    \begin{macrocode}
+    {\@ifundefined{ST@useimagemagick}%
+      {\IfFileExists{\ST@plotdir/plot-\theST@plot.#2}%
+        {\ST@missingfilebox%
+         \PackageWarning{sagetex}{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}}%
+        {\ST@missingfilebox%
+         \PackageWarning{sagetex}{Graphics file
+         \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space
+         does not exist. Plot command is}%
+         \gdef\ST@rerun{x}}}%
+%    \end{macrocode}
+% Otherwise, we are using Imagemagick, so try to include an EPS file
+% anyway.
+%    \begin{macrocode}
+    {\ST@inclgrfx{#1}{eps}}}}
+%    \end{macrocode}
+% Step the counter and we're done with the usual work.
+%    \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. If we are paused, it just puts in a little box saying
+% so.
+%    \begin{macrocode}
+\newcommand{\ST@inclgrfx}[2]{\ifST@paused
+  \fbox{\rule[-1cm]{0cm}{2cm}Sage\TeX{} is paused; no graphic}
+\else
+  \IfFileExists{\ST@plotdir/plot-\theST@plot.#2}%
+    {\includegraphics[#1]{\ST@plotdir/plot-\theST@plot.#2}}%
+%    \end{macrocode}
+% If the file doesn't exist, we try one more thing before giving up: the
+% Python module will automatically fall back to saving as a PNG file if
+% saving as an EPS or PDF file fails. So if making a PDF, we look for a
+% PNG file.
+%
+% If the file isn't there, 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 Sage again.
+%    \begin{macrocode}
+    {\IfFileExists{\ST@plotdir/plot-\theST@plot.png}%
+       {\ifpdf
+           \ST@inclgrfx{#1}{png}
+         \else
+           \PackageWarning{sagetex}{Graphics file
+           \ST@plotdir/plot-\theST@plot.png on page \thepage\space not
+            supported; try using pdflatex. Plot command is}%
+        \fi}%
+       {\ST@missingfilebox%
+       \PackageWarning{sagetex}{Graphics file
+       \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space does not
+       exist. Plot command is}%
+       \gdef\ST@rerun{x}}}
+\fi}
+%    \end{macrocode}
+% \autoref{f:stig} makes this a bit clearer.
+% \begin{figure}
+%   \centering
+%   \begin{tikzpicture}
+%     \tikzstyle{level 1}=[sibling distance=4cm]
+%     \node [box] {Paused?}
+%       child {node [box] {Insert ``we're paused'' box}
+%         edge from parent node[left] {yes}}
+%       child {node [box] {Does EXT file exist?}
+%         child {node [box] {Does a PNG file exist?}
+%           child {node [box] {Making a PDF?}
+%             child {node [box] {\texttt{includegraphics} PNG}
+%               edge from parent node[left] {yes}}
+%             child {node [box, text width=2cm] {Warning: DVI, PNG incompatible}
+%               edge from parent node[left] {no}}
+%             edge from parent node[left] {yes}}
+%           child {node [box, text width = 2.125cm] {Warn user to rerun Sage}
+%             edge from parent node[left] {no}}
+%           edge from parent node[left] {no}}
+%         child {node [box] {Use \texttt{includegraphics}}
+%           edge from parent node[right] {yes}}
+%         edge from parent node[right] {no}};
+%   \end{tikzpicture}
+%   \caption{The logic used by the \texttt{\bslash ST@inclgrfx}
+%   command.}
+%   \label{f:stig}
+% \end{figure}
+% \end{macro}
+%
+% \subsubsection{Verbatim-like environments}
+% \label{sec:verbatim-envs}
+%
+% \begin{macro}{\ST@beginsfbl}
+% This is ``begin |.sage| file block'', an internal-use abbreviation
+% that sets things up when we start writing a chunk of Sage code to
+% the |.sage| file. It begins with some \TeX{} magic that fixes
+% spacing, then puts the start of a try/except block in the |.sage|
+% file---this not only allows the user to indent code without
+% Sage/Python complaining about indentation, but lets us tell the user
+% where things went wrong. The |blockbegin| and |blockend| functions
+% are documented on page~\pageref{blocksbeginend}. 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{%
+_st_.current_tex_line = \the\inputlineno^^J%
+_st_.blockbegin()^^Jtry:}%
+  \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:^^J
+ _st_.goboom(\the\inputlineno)^^J_st_.blockend()}}
+%    \end{macrocode}
+% \end{macro}
+%
+% Now let's define the ``verbatim-like'' environments. There are four
+% possibilities, corresponding to the two independent choices of
+% typesetting the code or not, and writing to the |.sage| file or not.
+%
+% \begin{environment}{sageblock}
+% This environment does both: it typesets your code and puts it into the
+% |.sage| file for execution by Sage.
+%    \begin{macrocode}
+\newenvironment{sageblock}{\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 |.sage| 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{\sagetexindent}\the\verbatim@line\par}%
+\verbatim}%
+%    \end{macrocode}
+% At the end of the environment, we put a chunk into the |.sage| file
+% and stop the verbatim environment.
+%    \begin{macrocode}
+{\ST@endsfbl\endverbatim}
+%    \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{sagesilent}
+% This is from the |verbatim| package manual. It's just like the above,
+% except we don't typeset anything.
+%    \begin{macrocode}
+\newenvironment{sagesilent}{\ST@beginsfbl%
+\def\verbatim@processline{\ST@wsf{ \the\verbatim@line}}%
+\verbatim@start}%
+{\ST@endsfbl\@esphack}
+%    \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{sageverbatim}
+% The opposite of |sagesilent|. This is exactly the same as the verbatim
+% environment, except that we include some indentation to be consistent
+% with other typeset Sage code.
+%    \begin{macrocode}
+\newenvironment{sageverbatim}{%
+\def\verbatim@processline{\hspace{\sagetexindent}\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 |.sage| file. The verbatim package's
+% |comment| environment does that.\\
+%
+% \begin{environment}{sageexample}
+%   Finally, we have an environment which is mostly-but-not-entirely
+%   verbatim; this is the example environment, which takes input like
+%   Sage doctests, and prints out the commands verbatim but nicely
+%   typesets the output of those commands. This and the corresponding
+%   Python function are originally due to Nicolas M. Thi\'ery.
+%    \begin{macrocode}
+\newcommand{\sageexampleincludetextoutput}{False}
+\newenvironment{sageexample}{%
+   \ST@wsf{%
+try:^^J
+ _st_.current_tex_line = \the\inputlineno^^J
+ _st_.doctest(\theST@inline, r"""}%
+   \ST@dodfsetup%
+   \ST@wdf{Sage example, line \the\inputlineno::^^J}%
+   \begingroup%
+   \@bsphack%
+   \let\do\@makeother\dospecials%
+   \catcode`\^^M\active%
+   \def\verbatim@processline{%
+     \ST@wsf{\the\verbatim@line}%
+     \ST@wdf{\the\verbatim@line}%
+   }%
+   \verbatim@start%
+}
+{
+  \@esphack%
+  \endgroup%
+  \ST@wsf{%
+    """, globals(), locals(), \sageexampleincludetextoutput)^^Jexcept:^^J
+    _st_.goboom(\the\inputlineno)}%
+  \ifST@paused%
+    \mbox{(Sage\TeX{} is paused)}%
+  \else%
+    \begin{NoHyper}\ref{@sageinline\theST@inline}\end{NoHyper}%
+    \@ifundefined{r@@sageinline\theST@inline}{\gdef\ST@rerun{x}}{}%
+  \fi%
+  \ST@wdf{}%
+  \stepcounter{ST@inline}}
+%    \end{macrocode}
+% \changes{v2.2.4}{2010/03/14}{Add first support for
+%   \texttt{sageexample} environment}
+% \end{environment}
+%
+%
+% \begin{environment}{sagecommandline}
+% This environment is similar to the |sageexample| environment, but
+% typesets the Sage output as text with Python syntax highlighting.
+%    \begin{macrocode}
+\newcommand{\sagecommandlinetextoutput}{True}
+\newlength{\sagecommandlineskip}
+\setlength{\sagecommandlineskip}{8pt}
+\newenvironment{sagecommandline}{%
+   \ST@wsf{%
+try:^^J
+ _st_.current_tex_line = \the\inputlineno^^J
+ _st_.commandline(\theST@cmdline, r"""}%
+   \ST@dodfsetup%
+   \ST@wdf{Sage commandline, line \the\inputlineno::^^J}%
+   \begingroup%
+   \@bsphack%
+   \let\do\@makeother\dospecials%
+   \catcode`\^^M\active%
+   \def\verbatim@processline{%
+     \ST@wsf{\the\verbatim@line}%
+     \ST@wdf{\the\verbatim@line}%
+   }%
+   \verbatim@start%
+}
+{
+  \@esphack%
+  \endgroup%
+  \ST@wsf{%
+    """, globals(), locals(), \sagecommandlinetextoutput)^^Jexcept:^^J
+    _st_.goboom(\the\inputlineno)}%
+  \ifST@paused%
+    \mbox{(Sage\TeX{} is paused)}%
+  \else%
+    \begin{NoHyper}\ref{@sagecmdline\theST@cmdline}\end{NoHyper}%
+    \@ifundefined{r@@sagecmdline\theST@cmdline}{\gdef\ST@rerun{x}}{}%
+  \fi%
+  \ST@wdf{}%
+  \stepcounter{ST@cmdline}}
+%    \end{macrocode}
+% \end{environment}
+%
+% \subsubsection{Pausing \ST}
+% \label{sec:pausing-sagetex}
+%
+% How can one have Sage to stop processing \ST output for a little
+% while, and then start again? At first I thought I would need some sort
+% of ``goto'' statement in Python, but later realized that there's a
+% dead simple solution: write triple quotes to the |.sage| file to
+% comment out the code. Okay, so this isn't \emph{really} commenting out
+% the code; PEP 8 says block comments should use ``|#|'' and Sage will
+% read in the ``commented-out'' code as a string literal. For the
+% purposes of \ST, I think this is a good decision, though, since (1)
+% the pausing mechanism is orthogonal to everything else, which makes it
+% easier to not screw up other code, and (2) it will always work.
+%
+% This illustrates what I really like about \ST: it mixes \LTX and
+% Sage/Python, and often what is difficult or impossible in one system
+% is trivial in the other.
+%
+% \begin{macro}{sagetexpause}
+% This macro pauses \ST by effectively commenting out code in the
+% |.sage| file. When running the corresponding |.sage| file, Sage will
+% skip over any commands issued while \ST is paused.
+%    \begin{macrocode}
+\newcommand{\sagetexpause}{\ifST@paused\relax\else
+\ST@wsf{print('SageTeX paused on \jobname.tex line \the\inputlineno')^^J"""}
+\ST@pausedtrue
+\fi}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{sagetexunpause}
+% This is the obvious companion to |\sagetexpause|.
+%    \begin{macrocode}
+\newcommand{\sagetexunpause}{\ifST@paused
+\ST@wsf{"""^^Jprint('SageTeX unpaused on \jobname.tex line \the\inputlineno')}
+\ST@pausedfalse
+\fi}
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{End-of-document cleanup}
+% \label{sec:end-of-doc-cleanup}
+%
+% We tell the Sage 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. We check to see if
+% we're paused first, so that we can finish the triple-quoted string in
+% the |.sage| file.
+%    \begin{macrocode}
+\AtEndDocument{\ifST@paused
+\ST@wsf{"""^^Jprint('SageTeX unpaused at end of \jobname.tex')}
+\fi
+\ST@wsf{_st_.endofdoc()}%
+\@ifundefined{ST@rerun}{}%
+%    \end{macrocode}
+% Otherwise, we issue a warning to tell the user to run Sage on the
+% |.sage| 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 Sage 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{Sage}. We also suppress 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 Sage if it's necessary.
+%    \begin{macrocode}
+{\typeout{*********************************************************************}
+\PackageWarningNoLine{sagetex}{there were undefined Sage formulas and/or
+plots.^^JRun Sage on \jobname.sagetex.sage, and then run LaTeX on \jobname.tex
+again}}
+\typeout{*********************************************************************}}
+%    \end{macrocode}
+%
+%
+% \subsection{The Python module}
+% \label{sec:py-file}
+%
+% \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 |.sage| file and reads them from
+% the |.sout| file. The Python module provides functions that help
+% produce the |.sout| file from the |.sage| 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 (single) percent sign;
+% there are no troubles otherwise.\\
+%
+% On to the code. Munge the version string (which we get from
+% \texttt{sagetex.dtx}) to extract what we want, then import what we
+% need:
+%    \begin{macrocode}
+pyversion = ' '.join(__version__.strip('[').split()[0:2])
+from sage.misc.latex import latex
+from sage.repl.preparse import preparse
+import sys
+import os
+import os.path
+import hashlib
+import traceback
+import subprocess
+import shutil
+import re
+from collections import defaultdict
+%    \end{macrocode}
+% Define an exception class for version mismatches. I suppose I could
+% just use |ValueError|, but this is easy enough:
+%    \begin{macrocode}
+class VersionError(Exception):
+    pass
+%    \end{macrocode}
+% Sometimes our macros that write things to the |.sout| file get
+% evaluated twice, most commonly in the ``fancy'' AMS environments such
+% as |align| and |multline|. So we need to keep track of the counters
+% we've seen so we don't write labels to the |.sout| file more than
+% once. We have more than one kind of label, so a dictionary is the
+% natural way to store the counters we've seen for each kind of label.
+% For convenience let's make a dictionary subclass for which (1) values
+% default to $-1$, and (2) there's an |increment(key)| function that just
+% increments the value corresponding to the key.
+%    \begin{macrocode}
+class MyDict(defaultdict):
+    def __init__(self, *args, **kwargs):
+        defaultdict.__init__(self, *args, **kwargs)
+        self.default_factory = lambda: -1
+
+    def increment(self, key):
+        self[key] = self[key] + 1
+%    \end{macrocode}
+% Here's a helper function used by |doctest|; it works ike |j.join(xs)|,
+% but ensures exactly one copy of |j| between the strings in |xs|.
+% Intended for |j| to be a single character, particularly newline so
+% that you can join things with no extra blank lines.
+%    \begin{macrocode}
+def joinone(j, xs_):
+    if len(xs_) >= 2:
+        xs = ([xs_[0].rstrip(j)] +
+              [x.strip(j) for x in xs_[1:-1]] +
+              [xs_[-1].lstrip(j)])
+    else:
+        xs = xs_
+    return j.join(xs)
+%    \end{macrocode}
+% Another helper, used by |commandline| (and maybe, someday,
+% |doctest|?). In each line, we look for a possibly empty sequence of
+% spaces followed by a non-whitespace character, so we can distinguish
+% between whitespace-only lines (which we ignore) and lines that have no
+% leading spaces.
+%
+% One tiny possible problem: you might have a line of only, say, two
+% spaces, but perhaps the ``real'' lines all start with at least three
+% spaces. Then you would, for that line, do |line[2:]|. That seems like
+% it might raise an error, since the line only has indices 0 and 1, but
+% Python's indexing handles this perfectly: in that case, |line[2:]|
+% will be the empty string, which is fine for our purposes.
+%    \begin{macrocode}
+def strip_common_leading_spaces(s):
+    lines = s.splitlines()
+    lead = min(m.end() for m in
+                  [re.match(' *\S', line) for line in lines]
+                  if m is not None) - 1
+    return '\n'.join(line[lead:] for line in lines)
+%    \end{macrocode}
+%
+% \subsubsection{The \texttt{SageTeXProcessor} class}
+% \label{sec:sagetexprocessorclass}
+%
+% The star of the show, as it were. We define a |SageTeXProcessor| class
+% so that it's a bit easier to carry around internal state. We used to
+% just have some global variables and a bunch of functions, but this
+% seems a bit nicer and easier.
+%    \begin{macrocode}
+class SageTeXProcessor():
+%    \end{macrocode}
+% If the original |.tex| file has spaces in its name, the |\jobname|
+% we get is surrounded by double quotes, so fix that. Technically, it
+% is possible to have double quotes in a legitimate filename, but
+% dealing with that sort of quoting is
+% \href{http://tug.org/pipermail/xetex/2006-August/004712.html}{unpleasant}.
+% And yes, we're ignoring the possibility of tabs and other whitespace
+% in the filename. Patches for handling pathological filenames welcome.
+%
+% \changes{v2.3.1}{2011/02/02}{Handle filenames with
+% spaces in SageTeXProcessor and sagecommandline env.}
+% \changes{v2.3.2}{2012/01/13}{Improve version mismatch check. Fixes
+% trac ticket 8035.}
+%    \begin{macrocode}
+  def __init__(self, jobname, version=None, version_check=True):
+    if version != pyversion:
+      errstr = """versions of .sty and .py files do not match.
+{0}.sagetex.sage was generated by sagetex.sty version "{1}", but
+is being processed by sagetex.py version "{2}".
+Please make sure that TeX is using the sagetex.sty 
+from your current version of Sage; see
+http://doc.sagemath.org/html/en/tutorial/sagetex.html.""".format(jobname,
+  version, pyversion)
+      if version_check:
+        raise VersionError(errstr)
+      else:
+        print('**** WARNING! Skipping version check for .sty and .py files, and')
+        print(errstr)
+    if ' ' in jobname:
+      jobname = jobname.strip('"')
+    self.progress('Processing Sage code for {0}.tex...'.format(jobname))
+    self.didinitplot = False
+    self.useimagemagick = False
+    self.useepstopdf = False
+    self.plotdir = 'sage-plots-for-' + jobname + '.tex'
+    self.filename = jobname
+    self.name = os.path.splitext(jobname)[0]
+    autogenstr = """% This file was *autogenerated* from {0}.sagetex.sage with
+ % sagetex.py version {1}\n""".format(self.name, version)
+%    \end{macrocode}
+% Don't remove the space before the percent sign above!
+%
+% \LTX environments such as |align| evaluate their arguments twice after
+% doing |\savecounters@|, so if you do |\sage| inside such an environment,
+% it will result in two labels with the same name in the |.sout| file and
+% the user sees a warning when typesetting. So we keep track of the
+% largest label we've seen so that we don't write two labels with the same
+% name.
+%    \begin{macrocode}
+    self.max_counter_seen = MyDict()
+%    \end{macrocode}
+% Open a |.sout.tmp| file and write 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
+% Sage files; we are automatically generating a file with Sage, so it
+% seems reasonable to add it. Add in the version to help debugging
+% version mismatch problems.
+%    \begin{macrocode}
+    self.souttmp = open(self.filename + '.sagetex.sout.tmp', 'w')
+    self.souttmp.write(autogenstr)
+%    \end{macrocode}
+% In addition to the |.sout| file, the |sagecommandline| also needs a
+% |.scmd| file. As before, we use a |.scmd.tmp| file and rename it
+% later on. We store the position so that |commandline| can tell the
+% |listings| package what lines in the |.scmd| file to pull in.
+%    \begin{macrocode}
+    self.scmdtmp = open(self.filename + '.sagetex.scmd.tmp', 'w')
+    self.scmdtmp.write(autogenstr)
+    self.scmdpos = 3
+%    \end{macrocode}
+%
+% \begin{macro}{progress}
+% This function just 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(self, t,linebreak=True):
+    if linebreak:
+      print(t)
+    else:
+      sys.stdout.write(t)
+      sys.stdout.flush()
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{initplot}
+% \phantomsection\label{initplot}
+% We only want to create the plots directory if the user actually plots
+% something. This function creates the directory and sets the
+% |didinitplot| 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(self):
+    self.progress('Initializing plots directory')
+%    \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, We could find out the correct extension,
+% but it would involve a lot of irritating mucking around---on
+% |comp.text.tex|, the best solution I found for finding the file
+% extension is to look through the |.log| file. (Although see the
+% \texttt{currfile} package.)
+%    \begin{macrocode}
+    if os.path.isdir(self.plotdir):
+      shutil.rmtree(self.plotdir)
+    os.mkdir(self.plotdir)
+    self.didinitplot = True
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{inline}
+% \phantomsection\label{inlinefn}
+% This function works with |\sage| from the style file (see
+% \autoref{sec:sagemacro}) to put Sage 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 fields are the
+% same. The |\ref| command just pulls in what's in the first field of
+% the second argument, 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 Sage on |s|.
+%
+% When the user does |\sage| inside certain displayed math environments
+% (|align| is the most common culprit) this function will get called
+% twice with exactly the same arguments. We check to see what labels
+% we've seen and immediately bail if we've written this label before.
+%
+% The |labelname| defaults to the the name used by the usual |\sage|
+% inline macro, but this function is also used by the |sagecommandline|
+% environment. It's important to keep the corresponding labels separate,
+% because |\sage| macros often (for example) appear inside math mode,
+% and the labels from |sagecommandline| contain a |lstlistings|
+% environment---pulling such an environment into math mode produces
+% strange, unrecoverable errors, and if you can't typeset your file, you
+% can't produce an updated |.sagetex.sage| file to run Sage on to
+% produce a reasonable |.sagetext.sout| file that will fix the label
+% problem. So it works much better to use distinct labels for such
+% things.
+% \changes{v2.3.3}{2012/01/16}{check label name when comparing against
+% maximum counter seen; trac ticket 12267}
+%
+% We print out the line number so if something goes wrong, the user can
+% more easily track down the offending |\sage| command in the source
+% file.
+%
+% That's a lot of explanation for a short function:
+%    \begin{macrocode}
+  def inline(self, counter, s, labelname='sageinline'):
+      if counter <= self.max_counter_seen[labelname]:
+          return
+      else:
+          self.max_counter_seen.increment(labelname)
+      if labelname == 'sageinline':
+          self.progress('Inline formula {0} (line {1})'.format(counter, self.current_tex_line))
+      elif labelname == 'sagecmdline':
+          pass # output message already printed
+      else:
+          raise ValueError('inline() got a bad labelname "{0}"'.format(labelname))
+      self.souttmp.write(r'\newlabel{@' + labelname + str(counter) + 
+                         '}{{%\n' + s.rstrip() + '}{}{}{}{}}\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}{savecmd}
+%   Analogous to |inline|, this method saves the input string |s| to the
+%   |souttmp| file. It returns the first and last line of the
+%   newly-added output so that |commandline| can tell the |listings|
+%   package where to get stuff.
+%    \begin{macrocode}
+  def savecmd(self, s):
+      self.scmdtmp.write(s.rstrip() + "\n")
+      begin = self.scmdpos
+      end = begin + len(s.splitlines()) - 1
+      self.scmdpos = end + 1
+      return begin, end
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{blockbegin}
+% \begin{macro}{blockend}
+% \phantomsection\label{blocksbeginend}
+% 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. The verbatim-like environments of
+% \autoref{sec:verbatim-envs} use these functions.
+%    \begin{macrocode}
+  def blockbegin(self):
+    self.progress('Code block (line {}) begin...'.format(self.current_tex_line), False)
+  def blockend(self):
+    self.progress('end')
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{splitsagecmds}
+%   Given a string |s| of doctest-like Sage code, this function returns
+%   a list of tuples |(i, j, cmd)|, where |cmd| is a string representing
+%   a Sage command, with the initial prompt and continuation lines
+%   stripped, |i| is the position in |s| where |cmd| starts, and |j| is
+%   the starting position in |s| of the purported output from the
+%   command that was included in |s|.
+%
+%   This is used by |doctest| and |commandline|, below.
+%
+%   For example, this turns the string
+%   \begin{quote}
+%   |'''|\\
+%   |    sage: 1+1|\\
+%   |    2|\\
+%   |    sage: y = 1729|\\
+%   |    sage: 10^3 + 9^3 == 12^3 + 1^3 == y|\\
+%   |    sage: gcd(9999999,|\\
+%   |    ....: 123456)|\\
+%   |    3|\\
+%   |    sage: factor(x^2 + 2*x + 1)|\\
+%   |    (x + 1)^2|\\
+%   |'''|
+%   \end{quote}
+%   into
+%   \begin{quote}
+%   |[(0, 18, '1+1'),|\\
+%   | (28, 51, 'y = 1729'),|\\
+%   | (51, 95, '10^3 + 9^3 == 12^3 + 1^3 == y'),|\\
+%   | (95, 144, 'gcd(9999999,\n123456)'),|\\
+%   | (154, 190, 'factor(x^2 + 2*x + 1)')]|
+%   \end{quote}
+%   You can reconstruct the sequence of commands and their output with
+%   something like
+%   \begin{quote}
+%   |splitup = split_sage_cmds(s)|\\
+%   |oldout = splitup[0][1]|\\
+%   |print('=' * 50)|\\
+%   |print('==== Command:')|\\
+%   |print(s[splitup[0][0]:oldout])|\\
+%   |for start, out, _ in splitup[1:]:|\\
+%   |    print('==== Given output:')|\\
+%   |    print(s[oldout:start])|\\
+%   |    print('=' * 50)|\\
+%   |    print('==== Command:')|\\
+%   |    print(s[start:out])|\\
+%   |    oldout = out|\\
+%   |print('==== Given output:')|\\
+%   |print(s[oldout:])|
+%   \end{quote}
+%    \begin{macrocode}
+  def split_sage_cmds(self, s):
+      prompt = '\n' + r'\s*sage: '
+      oldcont = r'\s*\.\.\.'
+      cont = r'\s*\.\.\.\.: '
+%    \end{macrocode}
+% Prepending a newline to |s| ensures that the list from |re.split()|
+% begins with something we can ignore---and so that the |re.split()|
+% returns $n+1$ groups for $n$ matches, so therefore |split| and
+% |starts| match up.
+%    \begin{macrocode}
+      split = re.split(prompt, '\n' + s)[1:]
+      starts = [m.start() - 1 for m in re.finditer(prompt, '\n' + s)]
+%    \end{macrocode}
+% The prepended newline messes up the first element of |starts|, fix
+% that:
+%    \begin{macrocode}
+      starts[0] = re.search(prompt, s).start()
+%    \end{macrocode}
+% Now find where the outputs start. We need this because |doctest()| may
+% or may not print the outputs. The idea is: for each |start|ing
+% position, advance over the prompt that we know is there, then look for
+% the rightmost continuation marker between the current prompt and the
+% next one, and \emph{then} look for the newline following that. That
+% position is where the output begins.
+%    \begin{macrocode}
+      outputs = []
+      for i, j in zip(starts, starts[1:] + [len(s)]):
+          k = i + re.match(prompt, s[i:j]).end()
+          try:
+              k += [m.end() for m in re.finditer(cont, s[k:j])][-1]
+          except IndexError:
+              pass
+          end = s.find('\n', k)
+          outputs.append(end)
+%    \end{macrocode}
+% Now we take each command group, split it up, and look for all the
+% continuation lines. We append those, stripping off the continuation
+% marks. We also do some error checking so that users with documents
+% that use the old |...| continuation marks get a reasonable error
+% message.
+%    \begin{macrocode}
+      ret = []
+      for start, end, g in zip(starts, outputs, split):
+          lines = g.splitlines()
+          cmd = lines[:1]
+          for line in lines[1:]:
+              has_old_cont = re.match(oldcont, line)
+              has_cont = re.match(cont, line)
+              if has_old_cont and not has_cont:
+                  raise SyntaxError(""" SageTeX no longer supports "..." for line continuation in sagexample and
+sagecommandline environments. Use "....:", which matches what the Sage
+interpreter uses. See the documentation and example file in
+SAGE_ROOT/local/share/doc/sagetex.""")
+              if has_cont:
+                  cmd.append(line[has_cont.end():])
+          ret.append((start, end, '\n'.join(cmd)))
+      return ret
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{doctest}
+%   This function handles the |sageexample| environment, which typesets
+%   Sage code and its output. We call it |doctest| because the format is
+%   just like that for doctests in the Sage library.
+%
+%  The idea is:
+% \begin{enumerate}
+% \item Get the literal text for each command, wrap that in
+%   |SaveVerbatim|, write that (possibly with its associated output from
+%   the |.tex| file) to the |sout| file.
+% \item Accumulate a corresponding |UseVerbatim| and typeset output so
+%   that we can call |inline()| at the end and pull in all this stuff.
+% \item For the output: try to |eval()| the processed command (the one
+%   with the prompts and continuation marks stripped). If that succeeds,
+%   we run |latex()| on it and display that below the verbatim text from
+%   above. If that fails, it's because you have a statement and not an
+%   expression---there's no output from such a thing (well, none that we
+%   can capture, anyway) so no need to typeset output.
+% \end{enumerate}
+%    \begin{macrocode}
+  def doctest(self, counter, s, globals, locals, include_text_output):
+      self.progress('Sage example {0} (line {1})'.format(counter, self.current_tex_line))
+      splitup = self.split_sage_cmds(s)
+      tex_strs = []
+      for i in range(len(splitup)):
+          boxname = '@sageinline{}-code{}'.format(counter, i)
+          to_tmp = [r'\begin{SaveVerbatim}{' + boxname + '}',
+                    s[splitup[i][0]:splitup[i][1]]]
+          if include_text_output:
+              try:
+                  to_tmp.append(s[splitup[i][1]:splitup[i+1][0]])
+              except IndexError:
+                  to_tmp.append(s[splitup[i][1]:])
+          to_tmp.append('\\end{SaveVerbatim}\n')
+          self.souttmp.write(joinone('\n', to_tmp))
+%    \end{macrocode}
+% Now we build up something that we can send to |inline()|, which will
+% pull it into the document using its usual label mechanism.
+%
+% The verbatim stuff seems to end with a bit of vertical space, so don't
+% start the displaymath environment with unnecessary vertical
+% space---the displayskip stuff is from \S 11.5 of Herbert Vo\ss's
+% ``\href{http://www.ctan.org/tex-archive/info/math/voss/mathmode/}{Math
+% Mode}''.
+%    \begin{macrocode}
+          tex_strs.append(r'\UseVerbatim{' + boxname + '}')
+          try:
+              result = eval(preparse(splitup[i][2]), globals, locals)
+              tex_strs += [r'\abovedisplayskip=0pt plus 3pt ',
+                           r'\abovedisplayshortskip=0pt plus 3pt ',
+                           r'\begin{displaymath}',
+                           latex(result),
+                           r' \end{displaymath}']
+          except SyntaxError:
+              exec(preparse(splitup[i][2]), globals, locals)
+      self.inline(counter, '\n'.join(tex_strs))
+%    \end{macrocode}
+% \changes{v2.2.5}{2010/03/25}{Fix up spacing in sageexample displaymath envs}
+% \changes{v3.0}{2015/08/26}{sageexample and sagecommandline now require
+% ``...:'' for continuation lines, not ``...''; matches the actual
+% Sage interpreter}
+% \end{macro}
+%
+% \begin{macro}{commandline}
+%   This function handles the |commandline| environment, which typesets
+%   Sage code, computes its output, and typesets that too. This is very
+%   similar to |doctest| and I hope to someday combine them into one.
+%
+%   Even if I can't refactor these two functions (and their associated
+%   environments) into one, I would like to eliminate the |.scmd| file
+%   that this function uses, since exactly the same bits of Sage code
+%   get written to both the |.scmd| file and the |_doctest.sage| file.
+%   The reason this isn't trivial is because we need to keep track of
+%   which line number we're on so that we can give the |listings|
+%   package a start and end line to extract, and right now the
+%   |_doctest.sage| file is written to by \LaTeX{} and we can't track
+%   the line number.
+%
+%   In any case, here's what we do: after splitting up the provided
+%   string using |split_sage_cmds|, we iterate over each of the
+%   commands and:
+%   \begin{enumerate}
+%   \item Put the original input command into the |.scmd| file with
+%     |savecmd|.
+%   \item Use the |begin| and |end| line numbers to append a
+%     |lstinputlisting| command to the \TeX{} commands we'll eventually
+%     hand off to |inline|.
+%   \item Evaluate the command using |eval()| or |exec|, as necessary.
+%     If we're doing plain text format, we send the output to the
+%     |.scmd| file and add a \TeX{} command to pull that back in---if we
+%     need typeset output, then we just hit the output with |latex()|
+%     and add that to the list of \TeX{} commands.
+%   \end{enumerate}
+%   Observe that we detect spaces in the filename and quote that for
+%   \TeX{} if we need to.
+%    \begin{macrocode}
+  def commandline(self, counter, s, globals, locals, text_output):
+      self.progress('Sage commandline {0} (line {1})'.format(counter, self.current_tex_line))
+      scmd_fn = self.name + '.sagetex.scmd'
+      if ' ' in scmd_fn:
+          scmd_fn = '"{}"'.format(scmd_fn)
+
+      splitup = self.split_sage_cmds(s)
+      skip = r'\vspace{\sagecommandlineskip}'
+      tex_strs = [skip]
+      lstinput = r'\lstinputlisting[firstline={0},lastline={1},firstnumber={2},style=SageInput{escape}]{{{3}}}'
+      for i in range(len(splitup)):
+          orig_input = s[splitup[i][0]:splitup[i][1]]
+          begin, end = self.savecmd(strip_common_leading_spaces(orig_input.strip('\n')))
+          if '#@' in orig_input:
+              escapeoption = ',escapeinside={\\#@}{\\^^M}'
+          else:
+              escapeoption = ''
+          tex_strs.append(lstinput.format(begin, end, begin - 2, scmd_fn, escape=escapeoption))
+          try:
+              result = eval(preparse(splitup[i][2]), globals, locals)
+              if text_output:
+                  begin, end = self.savecmd(str(result))
+                  tex_strs.append(lstinput.format(begin, end, begin - 2, scmd_fn, escape=''))
+              else:
+                  tex_strs.append(r'\begin{displaymath}' +
+                                  latex(result) +
+                                  r'\end{displaymath}')
+          except SyntaxError:
+              exec(preparse(splitup[i][2]), globals, locals)
+      if 'displaymath' not in tex_strs[-1]:
+          tex_strs.append(skip)
+      self.inline(counter, '\n'.join(tex_strs), labelname='sagecmdline')
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{plot}
+% \phantomsection\label{plotfn}
+% I hope it's obvious that this function does plotting. It's the Python
+% counterpart of |\ST@sageplot| described in \autoref{sec:sageplotmacro}. As
+% mentioned in the |\sageplot| 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 Sage plotting
+% functions) has nice support for keyword arguments. The |#3| argument
+% to |\sageplot| becomes |_p_| and |**kwargs| below.
+%    \begin{macrocode}
+  def plot(self, counter, _p_, format='notprovided', **kwargs):
+      if not self.didinitplot:
+          self.initplot()
+      self.progress('Plot {0} (line {1})'.format(counter, self.current_tex_line))
+%    \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.\footnote{Yes, there's
+% \texttt{pdfsync}, but full support for that is still rare in Linux, so
+% producing EPS and PDF is the best solution for now.}
+%    \begin{macrocode}
+      if format == 'notprovided':
+          formats = ['eps', 'pdf']
+      else:
+          formats = [format]
+      for fmt in formats:
+%    \end{macrocode}
+% If we're making a PDF and have been told to use |epstopdf|, do so,
+% then skip the rest of the loop.
+%    \begin{macrocode}
+          if fmt == 'pdf' and self.useepstopdf:
+              epsfile = os.path.join(self.plotdir, 'plot-{0}.eps'.format(counter))
+              self.progress('Calling epstopdf to convert plot-{0}.eps to PDF'.format(
+                            counter))
+              subprocess.check_call(['epstopdf', epsfile])
+              continue
+%    \end{macrocode}
+% Some plot objects (mostly 3-D plots) do not support saving to EPS or
+% PDF files (yet), but everything can be saved to a PNG file. For the
+% user's convenience, we catch the error when we run into such an
+% object, save it to a PNG file, then exit the loop.
+%    \begin{macrocode}
+          plotfilename = os.path.join(self.plotdir, 'plot-{0}.{1}'.format(counter, fmt))
+          try:
+              _p_.save(filename=plotfilename, **kwargs)
+          except ValueError as inst:
+              if re.match('filetype .*not supported by save', str(inst)):
+                  newfilename = plotfilename[:-3] + 'png'
+                  print('  saving {0} failed; saving to {1} instead.'.format(
+                                                    plotfilename, newfilename))
+                  _p_.save(filename=newfilename, **kwargs)
+                  break
+              else:
+                  raise
+%    \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 self.useimagemagick:
+              self.progress('Calling Imagemagick to convert plot-{0}.{1} to EPS'.format(
+                counter, format))
+              self.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(self, counter, ext):
+    subprocess.check_call(['convert',\
+      '{0}/plot-{1}.{2}'.format(self.plotdir, counter, ext), \
+      '{0}/plot-{1}.eps'.format(self.plotdir, 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 |.sage|
+% file, should result in a reasonable error message if something strange
+% happens.
+% \end{macro}
+%
+% \begin{macro}{goboom}
+% \phantomsection\label{macro:goboom}
+% When a chunk of Sage 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 |.sage| file (which is
+% autogenerated) which itself 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| and |.scmd.tmp| file.
+%    \begin{macrocode}
+  def goboom(self, line):
+    print('\n**** Error in Sage code on line {0} of {1}.tex! Traceback\
+ follows.'.format(line, self.filename))
+    traceback.print_exc()
+    print('\n**** Running Sage on {0}.sage failed! Fix {0}.tex and try\
+ again.'.format(self.filename))
+    self.souttmp.close()
+    os.remove(self.filename + '.sagetex.sout.tmp')
+    self.scmdtmp.close()
+    os.remove(self.filename + '.sagetex.scmd.tmp')
+    sys.exit(int(1))
+%    \end{macrocode}
+% We use |int(1)| above to make sure |sys.exit| sees a Python integer;
+% see
+% \href{http://trac.sagemath.org/sage_trac/ticket/2861#comment:5}{ticket
+% \#2861}.
+% \changes{v2.0.2}{2008/04/21}{Make sure sys.exit sees a Python integer}
+% \end{macro}
+%
+% \begin{macro}{endofdoc}
+% \phantomsection\label{macro:endofdoc}
+% When we're done processing, we have some cleanup tasks. We
+% want to put the MD5 sum of the |.sage| file that produced the |.sout|
+% file we're about to write into the |.sout| file, so that external
+% programs that build \LTX documents can determine if they need to call Sage
+% to update the |.sout| file. But there is a problem: we write line
+% numbers to the |.sage| file so that we can provide useful error
+% messages---but that means that adding non-\ST text to your
+% source file will change the MD5 sum, and your program will think it
+% needs to rerun Sage even though none of the actual \ST macros
+% changed.
+%
+% How do we include line numbers for our error messages but still allow
+% a program to discover a ``genuine'' change to the |.sage| file?
+%
+% The answer is to only find the MD5 sum of \emph{part} of the |.sage|
+% file. By design, the source file line numbers only appear in (1) calls
+% to |goboom|, (2) lines with |_st_.current_tex_line|, and (3)
+% pause/unpause lines, so we will strip those lines out. What we do
+% below is exactly equivalent to running
+% \begin{center}
+% \verb+egrep -v '^( _st_.goboom| ?_st_.current_tex_line|print(.SageT)' filename.sage | md5sum+
+% \end{center}
+% in a shell. The included |run-sagetex-if-necessary| uses this
+% mechanism to, well, only run Sage when necessary; see
+% \autoref{sec:run-sagetex-if-necessary}.
+%    \begin{macrocode}
+  def endofdoc(self):
+    sagef = open(self.filename + '.sagetex.sage', 'r')
+    m = hashlib.md5()
+    for line in sagef:
+      if not line.startswith((" _st_.goboom",
+                              "print('SageT",
+                              "_st_.current_tex_line",
+                              " _st_.current_tex_line")):
+          m.update(bytearray(line,'utf8'))
+%    \end{macrocode}
+% (The |current_tex_line| thing appears twice because it may appear
+% indented one space or not, depending on whether it's used before
+% |blockbegin| or not.)
+%    \begin{macrocode}
+    s = '%' + m.hexdigest() + '% md5sum of corresponding .sage file\
+ (minus "goboom", "current_tex_line", and pause/unpause lines)\n'
+    self.souttmp.write(s)
+    self.scmdtmp.write(s)
+%    \end{macrocode}
+% Now, we do issue warnings to run Sage on the |.sage| file and an
+% external program might look for those to detect the need to rerun
+% Sage, but those warnings do not quite capture all situations. (If
+% you've already produced the |.sout| file and change a |\sage| 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. Note that
+% there are percent signs on each side of the hex string.)
+%
+% Now we are done with the |.sout.tmp| file. Close it, rename it, and
+% tell the user we're done.
+%    \begin{macrocode}
+    self.souttmp.close()
+    os.rename(self.filename + '.sagetex.sout.tmp', self.filename + '.sagetex.sout')
+    self.scmdtmp.close()
+    os.rename(self.filename + '.sagetex.scmd.tmp', self.filename + '.sagetex.scmd')
+    self.progress('Sage processing complete. Run LaTeX on {0}.tex again.'.format(
+             self.filename))
+%    \end{macrocode}
+% % \changes{v2.1.1}{2009/05/14}{Fix bug in finding md5 sum introduced by
+% pause facility}
+% \end{macro}
+
+% \endinput
+%</python>
+% Local Variables:
+% mode: doctex
+% TeX-master: "sagetex.dtx"
+% End:
-- 
cgit v1.2.3

