Commits

Anonymous committed f6edb5e

Split main dtx file into three files.

Comments (0)

Files changed (5)

 srcs=../sagetex/example.tex ../sagetex/README ../sagetex/sagetexpackage.dtx ../sagetex/sagetexpackage.ins
 ver=2.0.2
 
-all: ins
+all: ins index
 	latex $(pkg).dtx
 	sage $(pkg).sage
-	makeindex -s gglo.ist -o $(pkg).gls $(pkg).glo 
-	makeindex -s gind.ist -o $(pkg).ind $(pkg).idx
 	latex $(pkg).dtx
 	sage $(pkg).sage
 	latex $(pkg).dtx
 	latex example.tex
 	pdflatex example.tex
 
+index:
+	sed -e 's/usage|hyperpage/usagehyperpage/g' -i sagetexpackage.idx
+	makeindex -s gglo.ist -o $(pkg).gls $(pkg).glo 
+	makeindex -s gind.ist -o $(pkg).ind $(pkg).idx
+
 ins:
 	yes | latex $(pkg).ins
 
+% \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.
+%    \begin{macrocode}
+\RequirePackage{verbatim}
+%    \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.
+%    \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{\sagetexindent}
+\setlength{\sagetexindent}{5ex}
+%    \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.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. The ``|(\jobname.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.
+%    \begin{macrocode}
+\newcommand{\ST@wsf}[1]{\immediate\write\ST@sf{#1}}%
+\ST@wsf{# This file (\jobname.sage) was *autogenerated* from the file \jobname.tex.}%
+\ST@wsf{import sagetex}%
+\ST@wsf{_st_ = sagetex.SageTeXProcessor('\jobname')}}%
+%    \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}
+% 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.sout}{}{\AtEndDocument{\PackageWarningNoLine{sagetex}%
+  {`final' option provided, but \jobname.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. Then, process the options.
+%    \begin{macrocode}
+\DeclareOption{epstopdf}{%
+\AtBeginDocument{%
+\@ifundefined{ST@final}{%
+  \ST@wsf{_st_.useepstopdf = True}}{}}}
+\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.
+%    \begin{macrocode}
+\InputIfFileExists{\jobname.sout}{}{}
+%    \end{macrocode}
+%
+% \subsubsection{The \texttt{\bslash sage} macro}
+% \label{sec:sagemacro}
+%
+% \begin{macro}{\sage}
+% 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.) We can use |^^J| to put linebreaks into the |.sage| file, but
+% \LTX wants to put a space after that, which is why we don't put the
+% ``except'' on its own line here in the source.
+%    \begin{macrocode}
+\newcommand{\sage}[1]{\ST@wsf{%
+try:^^J
+ _st_.inline(\theST@inline, #1)^^Jexcept:^^J
+ _st_.goboom(\the\inputlineno)}%
+%    \end{macrocode}
+% The |inline| function of the Python module is documented on page
+% \pageref{inlinefn}.
+%
+% 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{@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.
+% Finally, step the counter.
+%    \begin{macrocode}
+\@ifundefined{r@@sageinline\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}
+%
+% \subsubsection{The \texttt{\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][width=.75\textwidth]{%
+  \@ifnextchar[{\ST@sageplot[#1]}{\ST@sageplot[#1][notprovided]}}
+%    \end{macrocode}
+% 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@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_.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}
+\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 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}}}%
+\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
+% Sage again.
+%    \begin{macrocode}
+    {\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}
+% \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 Sage}
+%         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}
+%
+% \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_.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.\\
+%
+% Now we deal with some end-of-file 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.
+%    \begin{macrocode}
+\AtEndDocument{\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 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 Sage if it's necessary.
+%    \begin{macrocode}
+{\PackageWarningNoLine{sagetex}{There were undefined Sage formulas
+and/or plots.^^JRun Sage on \jobname.sage, 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 |.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:
+%
+% The |sagetex.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 Sage modules; that way, this error message gets
+% printed whether you run the script with Sage or with Python.
+%    \begin{macrocode}
+import sys
+if __name__ == "__main__":
+  print("""This file is part of the SageTeX package.
+It is not meant to be called directly.
+
+This file will be automatically used by Sage scripts generated from a
+LaTeX document using the sagetex package.""")
+  sys.exit()
+%    \end{macrocode}
+% Import what we need:
+%    \begin{macrocode}
+from sage.misc.latex import latex
+import os
+import os.path
+import hashlib
+import traceback
+import subprocess
+import shutil
+%    \end{macrocode}
+% We define a 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():
+  def __init__(self, jobname):
+    self.progress('Processing Sage code for %s.tex...' % jobname)
+    self.didinitplot    = False
+    self.useimagemagick = False
+    self.useepstopdf    = False
+    self.plotdir        = 'sage-plots-for-' + jobname + '.tex'
+    self.filename       = jobname
+%    \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.
+%    \begin{macrocode}
+    self.souttmp        = open(self.filename + '.sout.tmp', 'w')
+    s = '% This file was *autogenerated* from the file ' + \
+        os.path.splitext(jobname)[0] + '.sage.\n'
+    self.souttmp.write(s)
+%    \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)
+%    \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.
+%    \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 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|.
+%
+% 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 very short function:
+%    \begin{macrocode}
+  def inline(self, counter, s):
+    self.progress('Inline formula %s' % counter)
+    self.souttmp.write('\\newlabel{@sageinline' + str(counter) + '}{{' + \
+                 latex(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}
+% \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 begin...', False)
+  def blockend(self):
+    self.progress('end')
+%    \end{macrocode}
+% \end{macro} 
+% \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 %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.\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-%s.eps' % counter)
+        self.progress('Calling epstopdf to convert plot-%s.eps to PDF' % \
+            counter)
+        subprocess.check_call(['epstopdf', epsfile])
+        continue
+      plotfilename = os.path.join(self.plotdir, 'plot-%s.%s' % (counter, fmt))
+      #print('  plotting %s with args %s' % (plotfilename, kwargs))
+      _p_.save(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 self.useimagemagick:
+        self.progress('Calling Imagemagick to convert plot-%s.%s to EPS' % \
+          (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',\
+      '%s/plot-%s.%s' % (self.plotdir, counter, ext), \
+      '%s/plot-%s.eps' % (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}
+% 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| file.
+%    \begin{macrocode}
+  def goboom(self, line):
+    print('\n**** Error in Sage code on line %s of %s.tex! Traceback\
+ follows.' % (line, self.filename))
+    traceback.print_exc()
+    print('\n**** Running Sage on %s.sage failed! Fix %s.tex and try\
+ again.' % ((self.filename,) * 2))
+    self.souttmp.close()
+    os.remove(self.filename + '.sout.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}
+% 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 calls to
+% |goboom|, so we will strip those lines out. Basically we are doing
+% \begin{center}
+% \verb+grep -v '^ _st_.goboom' filename.sage | md5sum+
+% \end{center}
+% (In fact, what we do below produces exactly the same sum.) 
+%    \begin{macrocode}
+  def endofdoc(self):
+    sagef = open(self.filename + '.sage', 'r')
+    m = hashlib.md5()
+    for line in sagef:
+      if line[0:12] != ' _st_.goboom':
+        m.update(line)
+    s = '%' + m.hexdigest() + '% md5sum of corresponding .sage file\
+ (minus "goboom" lines)\n'
+    self.souttmp.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 + '.sout.tmp', self.filename + '.sout')
+    self.progress('Sage processing complete. Run LaTeX on %s.tex again.' %\
+             self.filename)
+%    \end{macrocode}
+% \end{macro}
+
+% \endinput
+%</python>
+% Local Variables: 
+% mode: doctex
+% TeX-master: "sagetexpackage"
+% End: 

sagetexpackage.dtx

 \usepackage{xspace}
 \usepackage{tikz}
 \usepackage{hyperref}
+% \iffalse
+% Work around a problem with using Docstrip and hyperref; for macros and
+% such described with DescribeMacro and friends, plain Docstrip puts
+% something like this into the .idx file:
+%
+%  \indexentry{sage=\verb!*+\sage+|usage}{5}
+%
+% and defines \usage{}. hyperref comes along and sneakily alters those
+% lines and adds:
+%
+%  \indexentry{sage=\verb!*+\sage+|usage|hyperpage}{5}
+%
+% and makeindex gets confused because you can't have two | things in one
+% indexentry. I could probably figure out how to fix this in LaTeX, but
+% it's easier to run sed on the .idx file to remove the extra | and
+% define a new macro that makes the text italic and puts in the
+% hyperlink.
+%
+% Another option is to forget about all this and just pass the
+% hyperindex=false option to hyperref, but then you don't get
+% hyperlinked page numbers.
+% \fi
+\newcommand{\usagehyperpage}[1]{\textit{\hyperpage{#1}}}
+
 \renewcommand{\subsubsectionautorefname}{section}
 \renewcommand{\subsectionautorefname}{section}
 \EnableCrossrefs         
 \CodelineIndex
 \RecordChanges
 \begin{document}
-  \DocInput{sagetexpackage.dtx}
-  \PrintChanges
-  \PrintIndex
+\DocInput{sagetexpackage.dtx}
+\StopEventually{
+\section{Credits and acknowledgements}
+
+According to the original README file, this system was originally done
+by Gonzalo Tornaria and Joe Wetherell. Later Harald Schilly made some
+improvements and modifications. Almost all the examples in the
+|example.tex| file are from Harald.
+
+Dan Drake rewrote and extended the style file (there is effectively zero
+original code there), made significant changes to the Python module, put
+both files into \textsf{Docstrip} format, and wrote all the
+documentation and extra Python scripts.
+
+Many thanks to Jason Grout for his numerous comments, suggestions, and
+feedback.
+
+\section{Copying and licenses}
+
+If you are unnaturally curious about the current state of the \ST
+package, you can visit \url{http://www.bitbucket.org/ddrake/sagetex/}.
+There is a Mercurial repository and other stuff there.
+
+As for the terms and conditions under which you can copy and modify \ST:
+
+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.
+
+\iffalse meta-comment
+ I've run into a situation where the index wants to start on the very
+ last line of the page, and I actually get errors: ``Package multicol
+ Error: Error saving partial page.'' The problem goes away if I fiddle
+ with some lines so that the index starts elsewhere. Putting in a
+ clearpage below makes the index start nicely in the middle of a page
+ (until my change history gets too long!) and solves all those
+ problems. It can be removed/pulled into this comment if you're
+ confident the pagebreak problems won't occur.
+\clearpage
+\fi
+}
+
+\DocInput{py-and-sty.dtx}
+\DocInput{scripts.dtx}
+\Finale
+\PrintChanges
+\PrintIndex
 \end{document}
 %</driver>
 % \fi
 %
-% \CheckSum{0}
+% \CheckSum{275}
 %
 % \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
 % \changes{v2.0}{2009/01/09}{Miscellaneous fixes, final 2.0 version.}
 %
 % \GetFileInfo{sagetexpackage.dtx}
+% \GetFileInfo{py-and-sty.dtx}
+% \GetFileInfo{scripts.dtx}
 %
 % \DoNotIndex{\newcommand,\newenvironment,\the}
 % 
 %
 % \subsection{Inline Sage}
 %
-% \DescribeMacro{\sage}
+% \DescribeMacro{sage}
 % \fbox{\texttt{\bslash sage}\marg{Sage code}}
 % takes whatever Sage code you give it, runs Sage's |latex| function on
 % it, and puts the result into your document.
 % indentation may not be correct, and the plot options just get written
 % verbatim to the file. Nevertheless, it might be useful if you just
 % want to look at the Sage code in a file.
-%
-%
-% \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>
+% Local Variables: 
+% mode: doctex
+% TeX-master: t
+% End:
 % \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.
-%    \begin{macrocode}
-\RequirePackage{verbatim}
-%    \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.
-%    \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{\sagetexindent}
-\setlength{\sagetexindent}{5ex}
-%    \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.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. The ``|(\jobname.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.
-%    \begin{macrocode}
-\newcommand{\ST@wsf}[1]{\immediate\write\ST@sf{#1}}%
-\ST@wsf{# This file (\jobname.sage) was *autogenerated* from the file \jobname.tex.}%
-\ST@wsf{import sagetex}%
-\ST@wsf{_st_ = sagetex.SageTeXProcessor('\jobname')}}%
-%    \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}
-% 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.sout}{}{\AtEndDocument{\PackageWarningNoLine{sagetex}%
-  {`final' option provided, but \jobname.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. Then, process the options.
-%    \begin{macrocode}
-\DeclareOption{epstopdf}{%
-\AtBeginDocument{%
-\@ifundefined{ST@final}{%
-  \ST@wsf{_st_.useepstopdf = True}}{}}}
-\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.
-%    \begin{macrocode}
-\InputIfFileExists{\jobname.sout}{}{}
-%    \end{macrocode}
-%
-% \subsubsection{The \texttt{\bslash sage} macro}
-% \label{sec:sagemacro}
-%
-% \begin{macro}{\sage}
-% 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.) We can use |^^J| to put linebreaks into the |.sage| file, but
-% \LTX wants to put a space after that, which is why we don't put the
-% ``except'' on its own line here in the source.
-%    \begin{macrocode}
-\newcommand{\sage}[1]{\ST@wsf{%
-try:^^J
- _st_.inline(\theST@inline, #1)^^Jexcept:^^J
- _st_.goboom(\the\inputlineno)}%
-%    \end{macrocode}
-% The |inline| function of the Python module is documented on page
-% \pageref{inlinefn}.
-%
-% 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{@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.
-% Finally, step the counter.
-%    \begin{macrocode}
-\@ifundefined{r@@sageinline\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}
-%
-% \subsubsection{The \texttt{\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][width=.75\textwidth]{%
-  \@ifnextchar[{\ST@sageplot[#1]}{\ST@sageplot[#1][notprovided]}}
-%    \end{macrocode}
-% 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@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_.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}
-\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 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}}}%
-\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
-% Sage again.
-%    \begin{macrocode}
-    {\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}
-% \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 Sage}
-%         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}
-%
-% \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_.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 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.\\
-%
-% Now we deal with some end-of-file 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.
-%    \begin{macrocode}
-\AtEndDocument{\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 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 Sage if it's necessary.
-%    \begin{macrocode}
-{\PackageWarningNoLine{sagetex}{There were undefined Sage formulas
-and/or plots.^^JRun Sage on \jobname.sage, 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 |.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:
-%
-% The |sagetex.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 Sage modules; that way, this error message gets
-% printed whether you run the script with Sage or with Python.
-%    \begin{macrocode}
-import sys
-if __name__ == "__main__":
-  print("""This file is part of the SageTeX package.
-It is not meant to be called directly.
-
-This file will be automatically used by Sage scripts generated from a
-LaTeX document using the sagetex package.""")
-  sys.exit()
-%    \end{macrocode}
-% Import what we need:
-%    \begin{macrocode}
-from sage.misc.latex import latex
-import os
-import os.path
-import hashlib
-import traceback
-import subprocess
-import shutil
-%    \end{macrocode}
-% We define a 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():
-  def __init__(self, jobname):
-    self.progress('Processing Sage code for %s.tex...' % jobname)
-    self.didinitplot    = False
-    self.useimagemagick = False
-    self.useepstopdf    = False
-    self.plotdir        = 'sage-plots-for-' + jobname + '.tex'
-    self.filename       = jobname
-%    \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.
-%    \begin{macrocode}
-    self.souttmp        = open(self.filename + '.sout.tmp', 'w')
-    s = '% This file was *autogenerated* from the file ' + \
-        os.path.splitext(jobname)[0] + '.sage.\n'
-    self.souttmp.write(s)
-%    \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)
-%    \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.
-%    \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 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|.
-%
-% 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 very short function:
-%    \begin{macrocode}
-  def inline(self, counter, s):
-    self.progress('Inline formula %s' % counter)
-    self.souttmp.write('\\newlabel{@sageinline' + str(counter) + '}{{' + \
-                 latex(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}
-% \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 begin...', False)
-  def blockend(self):
-    self.progress('end')
-%    \end{macrocode}
-% \end{macro} 
-% \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 %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.\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-%s.eps' % counter)
-        self.progress('Calling epstopdf to convert plot-%s.eps to PDF' % \
-            counter)
-        subprocess.check_call(['epstopdf', epsfile])
-        continue
-      plotfilename = os.path.join(self.plotdir, 'plot-%s.%s' % (counter, fmt))
-      #print('  plotting %s with args %s' % (plotfilename, kwargs))
-      _p_.save(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 self.useimagemagick:
-        self.progress('Calling Imagemagick to convert plot-%s.%s to EPS' % \
-          (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',\
-      '%s/plot-%s.%s' % (self.plotdir, counter, ext), \
-      '%s/plot-%s.eps' % (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}
-% 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| file.
-%    \begin{macrocode}
-  def goboom(self, line):
-    print('\n**** Error in Sage code on line %s of %s.tex! Traceback\
- follows.' % (line, self.filename))
-    traceback.print_exc()
-    print('\n**** Running Sage on %s.sage failed! Fix %s.tex and try\
- again.' % ((self.filename,) * 2))
-    self.souttmp.close()
-    os.remove(self.filename + '.sout.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}
-% 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 calls to
-% |goboom|, so we will strip those lines out. Basically we are doing
-% \begin{center}
-% \verb+grep -v '^ _st_.goboom' filename.sage | md5sum+
-% \end{center}
-% (In fact, what we do below produces exactly the same sum.) 
-%    \begin{macrocode}
-  def endofdoc(self):
-    sagef = open(self.filename + '.sage', 'r')
-    m = hashlib.md5()
-    for line in sagef:
-      if line[0:12] != ' _st_.goboom':
-        m.update(line)
-    s = '%' + m.hexdigest() + '% md5sum of corresponding .sage file\
- (minus "goboom" lines)\n'
-    self.souttmp.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 + '.sout.tmp', self.filename + '.sout')
-    self.progress('Sage processing complete. Run LaTeX on %s.tex again.' %\
-             self.filename)
-%    \end{macrocode}
-% \end{macro}
-%
-% \iffalse
-%</python>
-%<*staticscript>
-% \fi
-%
-% \section{Included Python scripts}
-%
-% Here we describe the Python code for |makestatic.py|, which removes
-% \ST commands to produce a ``static'' file, and |extractsagecode.py|,
-% which extracts all the Sage code from a |.tex| file.
-%
-% \subsection{makestatic.py}
-%
-% First, |makestatic.py| script. It's about the most basic, generic
-% Python script taking command-line arguments that you'll find. The
-% |#!/usr/bin/env python| line is provided for us by the |.ins| file's
-% preamble, so we don't put it here.
-%    \begin{macrocode}
-import sys
-import time
-import getopt
-import os.path
-from sagetexparse import DeSageTex
-
-def usage():
-  print("""Usage: %s [-h|--help] [-o|--overwrite] inputfile [outputfile]
-
-Removes SageTeX macros from `inputfile' and replaces them with the
-Sage-computed results to make a "static" file. You'll need to have run
-Sage on `inputfile' already.
-
-`inputfile' can include the .tex extension or not. If you provide
-`outputfile', the results will be written to a file of that name.
-Specify `-o' or `--overwrite' to overwrite the file if it exists.
-
-See the SageTeX documentation for more details.""" % sys.argv[0])
-
-try:
-  opts, args = getopt.getopt(sys.argv[1:], 'ho', ['help', 'overwrite'])
-except getopt.GetoptError, err:
-  print str(err)
-  usage()
-  sys.exit(2)
-
-overwrite = False
-for o, a in opts:
-  if o in ('-h', '--help'):
-    usage()
-    sys.exit()
-  elif o in ('-o', '--overwrite'):
-    overwrite = True
-
-if len(args) == 0 or len(args) > 2:
-  print('Error: wrong number of arguments. Make sure to specify options first.\n')
-  usage()
-  sys.exit(2)
-
-if len(args) == 2 and (os.path.exists(args[1]) and not overwrite):
-  print('Error: %s exists and overwrite option not specified.' % args[1])
-  sys.exit(1)
-
-src, ext = os.path.splitext(args[0])
-%    \end{macrocode}
-% All the real work gets done in the line below. Sorry it's not more
-% exciting-looking.
-%    \begin{macrocode}
-desagetexed = DeSageTex(src)
-%    \end{macrocode}
-% This part is cool: we need double percent signs at the beginning of
-% the line because Python needs them (so they get turned into single
-% percent signs) \emph{and} because \textsf{Docstrip} needs them (so the
-% line gets passed into the generated file). It's perfect!
-%    \begin{macrocode}
-header = """\
-%% SageTeX commands have been automatically removed from this file and
-%% replaced with plain LaTeX. Processed %s.
-
-""" % time.strftime('%a %d %b %Y %H:%M:%S', time.localtime())
-
-if len(args) == 2:
-  dest = open(args[1], 'w')
-else:
-  dest = sys.stdout
-
-dest.write(header)
-dest.write(desagetexed.result)
-%    \end{macrocode}
-%
-% \iffalse
-%</staticscript>
-%<*extractscript>
-% \fi
-%
-% \subsection{extractsagecode.py}
-%
-% Same idea as |makestatic.py|, except this does basically the opposite
-% thing.
-%    \begin{macrocode}
-import sys
-import time
-import getopt
-import os.path
-from sagetexparse import SageCodeExtractor
-
-def usage():
-  print("""Usage: %s [-h|--help] [-o|--overwrite] inputfile [outputfile]
-
-Extracts Sage code from `inputfile'.
-
-`inputfile' can include the .tex extension or not. If you provide
-`outputfile', the results will be written to a file of that name,
-otherwise the result will be printed to stdout.
-
-Specify `-o' or `--overwrite' to overwrite the file if it exists.
-
-See the SageTeX documentation for more details.""" % sys.argv[0])
-
-try:
-  opts, args = getopt.getopt(sys.argv[1:], 'ho', ['help', 'overwrite'])
-except getopt.GetoptError, err:
-  print str(err)
-  usage()
-  sys.exit(2)
-
-overwrite = False
-for o, a in opts:
-  if o in ('-h', '--help'):
-    usage()
-    sys.exit()
-  elif o in ('-o', '--overwrite'):
-    overwrite = True
-
-if len(args) == 0 or len(args) > 2:
-  print('Error: wrong number of arguments. Make sure to specify options first.\n')
-  usage()
-  sys.exit(2)
-
-if len(args) == 2 and (os.path.exists(args[1]) and not overwrite):
-  print('Error: %s exists and overwrite option not specified.' % args[1])
-  sys.exit(1)
-
-src, ext = os.path.splitext(args[0])
-sagecode = SageCodeExtractor(src)
-header = """\
-# This file contains Sage code extracted from %s%s.
-# Processed %s.
-
-""" % (src, ext, time.strftime('%a %d %b %Y %H:%M:%S', time.localtime()))
-
-if len(args) == 2:
-  dest = open(args[1], 'w')
-else:
-  dest = sys.stdout
-
-dest.write(header)
-dest.write(sagecode.result)
-%    \end{macrocode}
-%
-% \iffalse
-%</extractscript>
-%<*parsermod>
-% \fi
-%
-% \subsection{The parser module}
-% 
-% Here's the module that does the actual parsing and replacing. It's
-% really quite simple, thanks to the awesome
-% \href{http://pyparsing.wikispaces.com}{Pyparsing module}. The parsing
-% code below is nearly self-documenting! Compare that to fancy regular
-% expressions, which sometimes look like someone sneezed punctuation all
-% over the screen.
-%    \begin{macrocode}
-import sys
-from pyparsing import *
-%    \end{macrocode}
-% First, we define this very helpful parser: it finds the matching
-% bracket, and doesn't parse any of the intervening text. It's basically
-% like hitting the percent sign in Vim. This is useful for parsing \LTX
-% stuff, when you want to just grab everything enclosed by matching
-% brackets.
-%    \begin{macrocode}
-def skipToMatching(opener, closer):
-  nest = nestedExpr(opener, closer)
-  nest.setParseAction(lambda l, s, t: l[s:getTokensEndLoc()])
-  return nest
-
-curlybrackets = skipToMatching('{', '}')
-squarebrackets = skipToMatching('[', ']')
-%    \end{macrocode}
-% Next, parser for |\sage| and |\sageplot| calls:
-%    \begin{macrocode}
-sagemacroparser = '\\sage' + curlybrackets('code')
-sageplotparser = ('\\sageplot'
-                 + Optional(squarebrackets)('opts') 
-                 + Optional(squarebrackets)('format')
-                 + curlybrackets('code'))
-%    \end{macrocode}
-%
-% With those defined, let's move on to our classes.
-%
-% \begin{macro}{SoutParser}
-% Here's the parser for the generated |.sout| file. The code below does
-% all the parsing of the |.sout| file and puts the results into a
-% dictionary. Notice that it's on the order of 10 lines of code---hooray
-% for Pyparsing!
-%    \begin{macrocode}
-class SoutParser():
-  def __init__(self, fn):
-    self.label = {}
-%    \end{macrocode}
-% A label line looks like
-% \begin{quote}
-%  |\newlabel{@sageinline|\meta{integer}|}{|\marg{bunch of \LTX code}|{}{}{}{}}|
-% \end{quote}
-% which makes the parser definition below pretty obvious. We assign some
-% names to the interesting bits so the |newlabel| method can make the
-% \meta{integer} and \meta{bunch of \LTX code} into the keys and values
-% of a dictionary. The |DeSageTeX| class then uses that dictionary to
-% replace bits in the |.tex| file with their Sage-computed results.
-%    \begin{macrocode}
-    parselabel = ('\\newlabel{@sageinline'
-                 + Word(nums)('num')
-                 + '}{'
-                 + curlybrackets('result')
-                 + '{}{}{}{}}')
-%    \end{macrocode}
-% We tell it to ignore comments, and hook up the dictionary-making
-% method. 
-%    \begin{macrocode}
-    parselabel.ignore('%' + restOfLine)
-    parselabel.setParseAction(self.newlabel)
-%    \end{macrocode}
-% A |.sout| file consists of one or more such lines. Now go parse the
-% file we were given.
-%    \begin{macrocode}
-    try:
-      OneOrMore(parselabel).parseFile(fn)
-    except IOError:
-      print 'Error accessing %s; exiting. Does your .sout file exist?' % fn
-      sys.exit(1)
-%    \end{macrocode}
-% Pyparser's parse actions get called with three arguments: the string
-% that matched, the location of the beginning, and the resulting parse
-% object. Here we just add a new key-value pair to the dictionary,
-% remembering to strip off the enclosing brackets from the ``result''
-% bit.
-%    \begin{macrocode}
-  def newlabel(self, s, l, t):
-    self.label[int(t.num)] = t.result[1:-1]
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{DeSageTeX}
-% Now we define a parser for \LTX files that use \ST commands. We assume
-% that the provided |fn| is just a basename.
-%    \begin{macrocode}
-class DeSageTex():
-  def __init__(self, fn):
-    self.sagen = 0
-    self.plotn = 0
-    self.fn = fn
-    self.sout = SoutParser(fn + '.sout')
-%    \end{macrocode}
-% Parse |\sage| macros. We just need to pull in the result from the
-% |.sout| file and increment the counter---that's what |self.sage| does.
-%    \begin{macrocode}
-    smacro = sagemacroparser
-    smacro.setParseAction(self.sage)
-%    \end{macrocode}
-% Parse the |\usepackage{sagetex}| line. Right now we don't support
-% comma-separated lists of packages.
-%    \begin{macrocode}
-    usepackage = ('\\usepackage'
-                 + Optional(squarebrackets)
-                 + '{sagetex}')
-    usepackage.setParseAction(replaceWith("""\\RequirePackage{verbatim}
-\\RequirePackage{graphicx}"""))
-%    \end{macrocode}
-% Parse |\sageplot| macros.
-%    \begin{macrocode}
-    splot = sageplotparser
-    splot.setParseAction(self.plot)
-%    \end{macrocode}
-% The printed environments (|sageblock| and |sageverbatim|) get turned
-% into |verbatim| environments.
-%    \begin{macrocode}
-    beginorend = oneOf('begin end')
-    blockorverb = 'sage' + oneOf('block verbatim')
-    blockorverb.setParseAction(replaceWith('verbatim'))
-    senv = '\\' + beginorend + '{' + blockorverb + '}'
-%    \end{macrocode}
-% The non-printed |sagesilent| environment gets commented out. We could
-% remove all the text, but this works and makes going back to \ST
-% commands (de-de-\ST{}ing?) easier.
-%    \begin{macrocode}
-    silent = Literal('sagesilent')
-    silent.setParseAction(replaceWith('comment'))
-    ssilent = '\\' + beginorend + '{' + silent + '}'
-%    \end{macrocode}
-% The |\sagetexindent| macro is no longer relevant, so remove it from
-% the output (``suppress'', in Pyparsing terms). 
-%    \begin{macrocode}
-    stexindent = Suppress('\\setlength{\\sagetexindent}' + curlybrackets)
-%    \end{macrocode}
-% Now we define the parser that actually goes through the file. It just
-% looks for any one of the above bits, while ignoring anything that
-% should be ignored.
-%    \begin{macrocode}
-    doit = smacro | senv | ssilent | usepackage | splot | stexindent
-    doit.ignore('%' + restOfLine)
-    doit.ignore('\\begin{verbatim}' + SkipTo('\\end{verbatim}'))
-    doit.ignore('\\begin{comment}' + SkipTo('\\end{comment}'))
-%    \end{macrocode}
-% We can't use the |parseFile| method, because that expects a ``complete
-% grammar'' in which everything falls into some piece of the parser.
-% Instead we suck in the whole file as a single string, and run
-% |transformString| on it, since that will just pick out the interesting
-% bits and munge them according to the above definitions.
-%    \begin{macrocode}
-    str = ''.join(open(fn + '.tex', 'r').readlines())
-    self.result = doit.transformString(str)
-%    \end{macrocode}
-% That's the end of the class constructor, and it's all we need to do
-% here. You access the results of parsing via the |result| string.
-%
-% We do have two methods to define. The first does the same thing that
-% |\ref| does in your \LTX file: returns the content of the label and
-% increments a counter.
-%    \begin{macrocode}
-  def sage(self, s, l, t):
-    self.sagen += 1
-    return self.sout.label[self.sagen - 1]
-%    \end{macrocode}
-% The second method returns the appropriate |\includegraphics| command.
-% It does need to account for the default argument.
-%    \begin{macrocode}
-  def plot(self, s, l, t):
-    self.plotn += 1
-    if len(t.opts) == 0:
-      opts = '[width=.75\\textwidth]'
-    else:
-      opts = t.opts[0]
-    return ('\\includegraphics%s{sage-plots-for-%s.tex/plot-%s}' % 
-      (opts, self.fn, self.plotn - 1))
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{SageCodeExtractor}
-% This class does the opposite of the first: instead of removing Sage
-% stuff and leaving only \LTX, this removes all the \LTX and leaves only
-% Sage.
-%    \begin{macrocode}
-class SageCodeExtractor():
-  def __init__(self, fn):
-    smacro = sagemacroparser
-    smacro.setParseAction(self.macroout)
-
-    splot = sageplotparser
-    splot.setParseAction(self.plotout)
-%    \end{macrocode}
-% Above, we used the general parsers for |\sage| and |\sageplot|. We
-% have to redo the environment parsers because it seems too hard to
-% define one parser object that will do both things we want: above, we
-% just wanted to change the environment name, and here we want to suck
-% out the code. Here, it's important that we find matching begin/end
-% pairs; above it wasn't. At any rate, it's not a big deal to redo this
-% parser.
-%    \begin{macrocode}