summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/sagetex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/sagetex
Initial commit
Diffstat (limited to 'macros/latex/contrib/sagetex')
-rw-r--r--macros/latex/contrib/sagetex/CONTRIBUTORS21
-rw-r--r--macros/latex/contrib/sagetex/PKG-INFO12
-rw-r--r--macros/latex/contrib/sagetex/README53
-rw-r--r--macros/latex/contrib/sagetex/example.pdfbin0 -> 285125 bytes
-rw-r--r--macros/latex/contrib/sagetex/example.tex644
-rw-r--r--macros/latex/contrib/sagetex/py-and-sty.dtx1575
-rw-r--r--macros/latex/contrib/sagetex/remote-sagetex.dtx438
-rw-r--r--macros/latex/contrib/sagetex/sagetex.dtx1225
-rw-r--r--macros/latex/contrib/sagetex/sagetex.ins124
-rw-r--r--macros/latex/contrib/sagetex/sagetex.pdfbin0 -> 499983 bytes
-rw-r--r--macros/latex/contrib/sagetex/scripts.dtx520
-rw-r--r--macros/latex/contrib/sagetex/setup.py32
12 files changed, 4644 insertions, 0 deletions
diff --git a/macros/latex/contrib/sagetex/CONTRIBUTORS b/macros/latex/contrib/sagetex/CONTRIBUTORS
new file mode 100644
index 0000000000..bd489e1dc9
--- /dev/null
+++ b/macros/latex/contrib/sagetex/CONTRIBUTORS
@@ -0,0 +1,21 @@
+Listed below, in no particular order, are people that have contributed
+to SageTeX -- code, documentation, suggestions, or anything else.
+
+If you have contributed to SageTeX and aren't listed below, please
+contact the maintainers and we'll add you to the list.
+
+Gonzalo Tornaria
+Joe Wetherell
+Harald Schilly
+Dan Drake
+Jason Grout
+Rob Beezer
+Nicolas Thiéry
+Volker Braun
+Maxim Cournoyer
+Jan Groenewald
+Dima Pasechnik
+Paul Masson
+Frédéric Chapoton
+Karl-Dieter Crisman
+Jérôme Benoit
diff --git a/macros/latex/contrib/sagetex/PKG-INFO b/macros/latex/contrib/sagetex/PKG-INFO
new file mode 100644
index 0000000000..e3840db7b3
--- /dev/null
+++ b/macros/latex/contrib/sagetex/PKG-INFO
@@ -0,0 +1,12 @@
+Metadata-Version: 1.0
+Name: sagetex
+Version: 3.2
+Summary: Embed Sage code and plots into LaTeX
+Home-page: https://github.com/sagemath/sagetex
+Author: SageMath developers
+Author-email: sage-devel@googlegroups.com
+License: GPLv2+
+Description: The SageTeX package allows you to embed code,
+ results of computations, and plots from the Sage mathematics
+ software suite (http://sagemath.org) into LaTeX documents.
+Platform: UNKNOWN
diff --git a/macros/latex/contrib/sagetex/README b/macros/latex/contrib/sagetex/README
new file mode 100644
index 0000000000..fb35a8b4e8
--- /dev/null
+++ b/macros/latex/contrib/sagetex/README
@@ -0,0 +1,53 @@
+This is the SageTeX package. It allows you to embed code, results of
+computations, and plots from the Sage mathematics software suite
+(http://sagemath.org) into LaTeX documents.
+====================================================================
+
+SageTeX is included with Sage, so to use it, you only need to make the
+file sagetex.sty known to TeX; that file will be in
+SAGE_ROOT/local/share/texmf/tex/latex/sagetex, along with
+documentation and examples. See the Sage tutorial at
+http://doc.sagemath.org/html/en/tutorial/sagetex.html
+for a quick usage introduction, and for complete installation
+instructions later on the same page at
+http://doc.sagemath.org/html/en/tutorial/sagetex.html#sec-sagetex-install
+
+The complete documentation is in sagetex.pdf, in
+the SAGE_ROOT/... directory mentioned above.
+
+If you want to extract any of SageTeX's files from the .dtx sources, you
+can do
+
+ 0. Run `latex sagetex.ins'
+
+To regenerate the documentation, do
+
+ 1. Run `latex sagetex.dtx'
+ 2. Run `sage sagetex.sage'
+ 3. Run the indexing commands that the .ins file told you about.
+ 4. Run `latex sagetex.dtx' again.
+
+You can skip step 3 if you don't care about the index. You will need the
+pgf and tikz packages installed to typeset the figures.
+
+The file example.tex has, as you likely guessed, a bunch of examples
+showing you how this package works. You can compile it using a another
+latex-sage-latex cycle as in steps 1-2-4 above. Note that example.tex
+includes some PNG graphics which latex cannot use; to see those, use
+pdflatex instead of regular latex or enable the imagemagick option. (See
+the documentation.)
+
+To use the SageTeX package with your own documents, see the
+"Installation" section of the documentation.
+
+This work builds on a lot of work by others; see the CONTRIBUTORS file
+and the "Credits" section of the documentation for credits. The source
+code may be modified and distributed under the terms of the GPL, version
+2 or later; the documentation may be modified and distributed under a
+Creative Commons Attribution - Share Alike 3.0 License. See the "Copying
+and licenses" section of the documentation.
+
+Please let me know if you find any bugs or have any ideas for
+improvement!
+
+- Dan Drake <dr.dan.drake at gmail>
diff --git a/macros/latex/contrib/sagetex/example.pdf b/macros/latex/contrib/sagetex/example.pdf
new file mode 100644
index 0000000000..4894f323b6
--- /dev/null
+++ b/macros/latex/contrib/sagetex/example.pdf
Binary files differ
diff --git a/macros/latex/contrib/sagetex/example.tex b/macros/latex/contrib/sagetex/example.tex
new file mode 100644
index 0000000000..2c04afdd02
--- /dev/null
+++ b/macros/latex/contrib/sagetex/example.tex
@@ -0,0 +1,644 @@
+% General example LaTeX file for including Sage calculations and plots
+% Build with:
+%
+% (pdf)latex example.tex; sage example.sagetex.sage; pdflatex example.tex
+%
+% Please read README and the documentation of the SageTeX package for
+% more information!
+%
+
+\documentclass{article}
+\title{Examples of embedding Sage in \LaTeX{} with \textsf{Sage\TeX}}
+\author{Dan Drake and others}
+\usepackage{hyperref}
+% If you want to see the examples in the section "Plotting
+% (combinatorial) graphs with TikZ" remove the \begin{comment}
+% and \end{comment} in that section and uncomment the following line.
+%\usepackage{tkz-berge}
+
+
+\usepackage{sagetex}
+%
+% If you want SageTeX to use Imagemagick's `convert' utility to make eps
+% files from png files when generating a dvi file, add the "imagemagick"
+% option above:
+%
+% \usepackage[imagemagick]{sagetex}
+
+\setlength{\sagetexindent}{10ex}
+
+\begin{document}
+\maketitle
+
+\section{Inline Sage, code blocks}
+
+This is an example $2+2=\sage{2+2}$. If you raise the current year mod
+$100$ (which equals $\sage{mod(\the\year, 100)}$) to the power of the
+current day ($\the\day$), you get $\sage{Integer(mod(\the\year,
+100))^\the\day}$. Also, $\the\year$ modulo $42$ is $\sage{\the\year
+\percent 42}$.
+
+Code block which uses a variable \texttt{s} to store the solutions:
+\begin{sageblock}
+ 1+1
+ var('a,b,c')
+ eqn = [a+b*c==1, b-a*c==0, a+b==5]
+ s = solve(eqn, a,b,c)
+\end{sageblock}
+
+Solutions of $\mbox{eqn}=\sage{eqn}$:
+\[
+\sage{s[0]}
+\]
+\[
+\sage{s[1]}
+\]
+
+Now we evaluate the following block:
+\begin{sageblock}
+E = EllipticCurve("37a")
+\end{sageblock}
+You can't do assignment inside \verb|\sage| macros, since Sage doesn't
+know how to typeset the output of such a thing. So you have to use a
+code block. The elliptic curve $E$ given by $\sage{E}$ has discriminant
+$\sage{E.discriminant()}$.
+
+You can do anything in a code block that you can do in Sage and/or
+Python. Here we save an elliptic curve into a file.
+\begin{sageblock}
+try:
+ E = load('E2')
+except IOError:
+ E = EllipticCurve([1,2,3,4,5])
+ E.anlist(100000)
+ E.save('E2')
+\end{sageblock}
+
+The 9999th Fourier coefficient of $\sage{E}$ is
+$\sage{E.anlist(100000)[9999]}$.
+
+The following code block doesn't appear in the typeset file\dots
+\begin{sagesilent}
+ e = 2
+ e = 3*e + 1
+\end{sagesilent}
+but we can refer to whatever we did in that code block: $e=\sage{e}$.
+
+\begin{sageblock}
+ var('x')
+ f(x) = log(sin(x)/x)
+\end{sageblock}
+The Taylor Series of $f$ begins: $\sage{ f.taylor(x, 0, 10) }$.
+
+\section{Plotting}
+
+Here's a very large plot of the elliptic curve $E$.
+
+\sageplot{E.plot(-3,3)}
+
+\begin{sagesilent}
+ # the var line is unecessary unless you've defined x to be something
+ # other than a symbolic variable
+ var('x')
+ f(x) = -x^3+3*x^2+7*x-4
+\end{sagesilent}
+
+You can use variables to hold plot objects and do stuff with them.
+\begin{sageblock}
+ p = plot(f, x, -5, 5)
+\end{sageblock}
+
+Here's a small plot of $f$ from $-5$ to $5$, which I've centered:
+
+\begin{center} \sageplot[scale=.2]{p} \end{center}
+
+On second thought, use a size of $3/4$ the \verb|\textwidth| and don't
+use axes:
+
+\sageplot[width=.75\textwidth]{p, axes=False}
+
+Remember, you're using Sage, and can therefore call upon any of the
+software packages Sage is built out of.
+\begin{sageblock}
+f = maxima('sin(x)^2*exp(x)')
+g = f.integrate('x')
+\end{sageblock}
+Plot $g(x)$, but don't typeset it.
+\begin{sagesilent}
+ # g is a Maxima thingy, it needs to get converted into a Sage object
+ plot1 = plot(g.sage(),x,-1,2*pi)
+\end{sagesilent}
+
+You can specify a file format and options for \verb|includegraphics|.
+The default is for EPS and PDF files, which are the best choice in
+almost all situations. (Although see the section on 3D plotting.)
+
+\sageplot[angle=45, width=.5\textwidth][png]{plot1}
+
+If you use regular \verb|latex| to make a DVI file, you'll see a box,
+because DVI files can't include PNG files. If you use \verb|pdflatex|
+that will work. See the documentation for details.
+
+When using \verb|\sageplot|, you can pass in just about anything that
+Sage can call \verb|.save()| on to produce a graphics file:
+
+\begin{center}
+\sageplot[width=.7\textwidth]{plot1 + plot(f.sage(),x,-1,2*pi,rgbcolor=hue(0.4)), figsize=[5,3]}
+\end{center}
+
+To fiddle with aspect ratio, first save the plot object:
+
+\begin{sageblock}
+ p = plot(x, 0, 1) + circle((0,0), 1)
+ p.set_aspect_ratio(1)
+\end{sageblock}
+
+Now plot it and see the circular circle and nice 45 degree angle:
+
+\sageplot[scale=.33]{p}
+
+Indentation and so on works fine.
+\begin{sageblock}
+ s = 7
+ s2 = 2^s
+ P.<x> = GF(2)[]
+ M = matrix(parent(x),s2)
+ for i in range(s2):
+ p = (1+x)^i
+ pc = p.coefficients(sparse=False)
+ a = pc.count(1)
+ for j in range(a):
+ idx = pc.index(1)
+ M[i,idx+j] = pc.pop(idx)
+
+ matrixprogram = matrix_plot(M,cmap='Greys')
+\end{sageblock}
+And here's the picture:
+
+\sageplot[scale=.5]{matrixprogram}
+
+Reset \texttt{x} in Sage so that it's not a generator for the polynomial
+ring: \sage{var('x')}
+
+
+\subsection{Plotting (combinatorial) graphs with TikZ}
+\label{sec:plotting-graphs-with}
+
+Sage now includes some nice support for plotting graphs using
+\href{http://www.texample.net/tikz/}{TikZ}. Here, we mean things with
+vertices and edges, not graphs of a function of one or two variables.
+
+The graphics in this section depends on the \texttt{tkz-berge} package,
+which is generally only available in newer \TeX{} distributions (for
+example, \TeX Live 2011 and newer). That package depends in turn on
+TikZ 2.0, which is also only available in newer \TeX{} distributions.
+Installing both of those is in some cases nontrivial, so this section is
+disabled by default.
+
+If you have TikZ and \texttt{tkz-berge} and friends, remove the
+\texttt{comment} environments below.
+
+\begin{comment}
+
+First define our graph:
+
+\begin{sageblock}
+ g = graphs.PetersenGraph()
+ g.set_latex_options(tkz_style='Art')
+\end{sageblock}
+
+Now just do \verb|\sage{}| on it to plot it. You'll need to use the
+\texttt{tkz-berge} package for this to work; that package in turn
+depends on \texttt{tkz-graph} and TikZ. See
+\href{http://altermundus.fr/pages/tkz.html}{\texttt{altermundus.fr/pages/tkz.html}};
+if you're using a recent version of \TeX Live, you can use its package
+manager to install those packages, or get them from CTAN:
+\href{http://www.ctan.org/pkg/tkz-berge}{\texttt{www.ctan.org/pkg/tkz-berge}}.
+See
+\href{http://doc.sagemath.org/html/en/reference/sage/graphs/graph_latex.html}{``\LaTeX{}
+ Options for Graphs''} in the Sage reference manual for more details.
+
+\begin{center}
+ \sage{g}
+\end{center}
+
+The above command just outputs a \texttt{tikzpicture} environment, and
+you can control that environment using anything supported by
+TikZ---although the output of \verb|\sage{g}| explicitly hard-codes a
+lot of things and cannot be flexibly controlled in its current form.
+
+\tikzstyle{every picture}=[rotate=45, scale=1/2]
+
+\begin{center}
+ \sage{g}
+\end{center}
+
+\tikzstyle{every picture}=[]
+
+Here's some more graphs, plotted using the usual plot routines.
+
+\sageplot[scale=.5]{graphs.FlowerSnark().plot()}
+
+\begin{sageblock}
+G4 = DiGraph({1:[2,2,3,5], 2:[3,4], 3:[4], 4:[5,7], 5:[6]},\
+ multiedges=True)
+G4plot = G4.plot(layout='circular')
+\end{sageblock}
+
+\sageplot[scale=.5]{G4plot, axes=False}
+
+\end{comment}
+
+\subsection{3D plotting}
+
+3D plotting right now (Sage version 4.3.4) is problematic because
+there's no convenient way to produce vector graphics. We can make PNGs,
+though, so if you pass \verb|sageplot| a graphics object that cannot be
+saved to EPS or PDF format, we will automatically save to a PNG file,
+which can be used when typesetting a PDF file, but not when creating a
+DVI file. However, you can specify the ``\texttt{imagemagick}'' option,
+which will use the Imagemagick \texttt{convert} utility to make EPS
+files. See the documentation for details.
+
+% FIXME: not sure this works with remote sagetex
+
+\begin{sagesilent}
+ x, y = var('x y')
+\end{sagesilent}
+
+Here's a 3D plot whose format we do not specify; it will automatically
+get saved as a PNG file and won't work when using \texttt{latex} to make
+a DVI file.
+
+\sageplot[scale=.5]{plot3d(sin(pi*(x^2+y^2))/2,(x,-1,1),(y,-1,1))}
+
+Here's the (perhaps-not-so-) famous Sage cube graph in 3D.
+
+\begin{sageblock}
+ G = graphs.CubeGraph(5)
+\end{sageblock}
+
+% need empty [] so sageplot knows you want png format, and aren't
+% passing an option to includegraphics
+\sageplot[][png]{G.plot3d()}
+
+\section{Pausing Sage\TeX}
+\label{sec:pausing-sagetex}
+
+Sometimes you want to ``pause'' for a bit while writing your document if
+you have embedded a long calculation or just want to concentrate on the
+\LaTeX{} and ignore any Sage stuff. You can use the \verb|\sagetexpause|
+and \verb|\sagetexunpause| macros to do that.
+
+\sagetexpause
+
+A calculation: $\sage{factor(2^325 + 1)}$ and a code environment that
+simulates a time-consuming calculation. While paused, this will get
+skipped over.
+\begin{sageblock}
+ import time
+ time.sleep(15)
+\end{sageblock}
+
+Graphics are also skipped: \sageplot{plot(2*sin(x^2) + x^2, (x, 0, 5))}
+
+\sagetexunpause
+
+\section{Make Sage write your \LaTeX{} for you}
+
+With \textsf{Sage\TeX}, you can not only have Sage do your math for you,
+it can write parts of your \LaTeX{} document for you! For example, I
+hate writing \texttt{tabular} environments; there's too many fiddly
+little bits of punctuation and whatnot\ldots and what if you want to add
+a column? It's a pain---or rather, it \emph{was} a pain. Just write a
+Sage/Python function that outputs a string of \LaTeX{} code, and use
+\verb|\sagestr|. Here's how to make Pascal's triangle.
+
+\begin{sageblock}
+def pascals_triangle(n):
+ # start of the table
+ s = [r"\begin{tabular}{cc|" + "r" * (n+1) + "}"]
+ s.append(r" & & $k$: & \\")
+ # second row, with k values:
+ s.append(r" & ")
+ for k in [0..n]:
+ s.append("& {0} ".format(k))
+ s.append(r"\\")
+ # the n = 0 row:
+ s.append(r"\hline" + "\n" + r"$n$: & 0 & 1 & \\")
+ # now the rest of the rows
+ for r in [1..n]:
+ s.append(" & {0} ".format(r))
+ for k in [0..r]:
+ s.append("& {0} ".format(binomial(r, k)))
+ s.append(r"\\")
+ # add the last line and return
+ s.append(r"\end{tabular}")
+ return ''.join(s)
+
+# how big should the table be?
+n = 8
+\end{sageblock}
+
+Okay, now here's the table. To change the size, edit \texttt{n} above.
+If you have several tables, you can use this to get them all the same
+size, while changing only one thing.
+
+\begin{center}
+ \sagestr{pascals_triangle(n)}
+\end{center}
+
+\section{Include doctest-like examples in your document}
+
+Here are some examples of using the \texttt{sageexample} environment:
+\begin{sageexample}
+ sage: 2+2
+ 4
+ sage: print('middle')
+ middle
+ sage: factor(x^2 + 2*x + 1)
+ (x + 1)^2
+\end{sageexample}
+Note above that no output from the \texttt{print} statement appears.
+That is because we have to use Python's \texttt{exec} to execute that
+statement (and not \texttt{eval()}), and we can't get the output from
+that.
+
+That said, if you want to see the plain-text output you put into your
+\verb|.tex| file as well as the Sage-computed typeset output, renew the
+\texttt{sageexampleincludetextoutput} command to True:
+\begin{verbatim}
+ \renewcommand{\sageexampleincludetextoutput}{True}
+\end{verbatim}
+\renewcommand{\sageexampleincludetextoutput}{True}
+This can be useful to check that the two outputs are consistent. Here's
+the print statement with text output included:
+\begin{sageexample}
+ sage: print('middle')
+ middle
+\end{sageexample}
+When typesetting your document, the validity of the outputs is not
+checked. In fact, the provided outputs are completely ignored:
+\renewcommand{\sageexampleincludetextoutput}{True}
+\begin{sageexample}
+ sage: is_prime(57)
+ toothpaste
+\end{sageexample}
+\renewcommand{\sageexampleincludetextoutput}{False}%
+Multiline statements with the ``\verb|....:|'' continuation marks are
+supported, as are triple-quoted strings delimited by single quotes
+(double quotes won't work):
+\begin{sageexample}
+ sage: gcd([5656565656,
+ ....: 4747474747,
+ ....: 123456789])
+ 1
+ sage: mystr = '''my
+ ....: string
+ ....: has
+ ....: several
+ ....: lines.'''
+ sage: len(mystr)
+ 28
+ sage: def f(a):
+ ....: '''This function is really quite nice,
+ ....: although perhaps not very useful.'''
+ ....: print("f called with a = {}".format(a))
+ ....: y = integrate(SR(cyclotomic_polynomial(10)) + a, x)
+ ....: return y + 1
+ sage: f(x)
+ f called with a = x
+ 1/5*x^5 - 1/4*x^4 + 1/3*x^3 + x + 1
+\end{sageexample}
+Note that the ``$f$ called with\ldots'' stuff doesn't get typeset, since
+when running Sage on \texttt{example.sagetex.sage}, that gets printed to the
+terminal.
+
+Typesetting your document produces a file named
+\texttt{example\_doctest.sage} containing all the doctest-like examples,
+and you can have Sage check them for you with:
+\begin{verbatim}
+ $ sage -t example_doctest.sage
+\end{verbatim}
+You should get a doctest failure from the ``toothpaste'' line above. The
+line numbers from \texttt{sage -t} refer to the ``\verb|_doctest.sage|''
+file.
+
+Beware that \texttt{sage -t} does not really handle file names with
+special characters in them, particularly dashes, dots, and spaces---this
+ultimately comes from the way Python interprets \texttt{import}
+statements. Also, running doctests on files outside the main Sage
+library does not always work, so contact \texttt{sage-support} if you
+run into troubles.
+
+Some more examples. This environment is implemented a little bit
+differently than the other environments, so it's good to make sure that
+definitions are preserved across multiple uses. This will correctly
+define $a$, but not print its output because the statement is made up of
+a sequence of expressions and we can't use Python's \texttt{eval()}; we
+have to use \texttt{exec} and we can't capture the output from that.
+\begin{sageexample}
+ sage: 1; 2; a=4; 3; a
+ 1
+ 2
+ 3
+ 4
+\end{sageexample}
+However, after that, Sage should remember that $a = \sage{a}$ and be
+able to use that in future \texttt{sageexample} blocks:
+\begin{sageexample}
+ sage: f(a)
+ f called with a = 4
+ 1/5*x^5 - 1/4*x^4 + 1/3*x^3 - 1/2*x^2 + 5*x + 1
+\end{sageexample}
+
+\section{Plotting functions in Ti\emph{k}Z with Sage\TeX}
+
+(The code in this section should work with any reasonable version of
+Ti\emph{k}Z, which means it should work with all but the most terribly
+out-of-date \TeX{} installations---but to make sure we can accomodate
+everyone, the code here is commented out. You can almost certainly
+uncomment and run them. Make sure you do \verb|\usepackage{tikz}| in the
+preamble.)
+
+\begin{comment}
+
+The wonderful graphics package TikZ has the ability to plot functions by
+reading in a sequence of points from an external file---see chapter 18,
+page 193 of the TikZ manual. This facility is designed around files
+produced by Gnuplot, but the file format is so simple that it's very
+easy to use Sage\TeX{} to generate them. First you need a function that
+will evaluate functions and write the results into a file:
+
+
+% set up plotting stuff
+\begin{sageblock}
+ def gnuplot(x, y, tvals_, fn):
+ """
+ Write out a gnuplot-style file of points x(t), y(t).
+ """
+ tvals = list(tvals_)
+ lines = ['#This is a gnuplot-style file written by SageTeX.',
+ '#x: {0}'.format(x),
+ '#y: {0}'.format(y),
+ '#Curve 0, {0} points'.format(len(tvals)),
+ '#x y type']
+ fmt = lambda _: _.n().str(no_sci=2)
+ for t in tvals:
+ try:
+ lines.append('{0} {1} i'.format(fmt(x(t)), fmt(y(t))))
+ except ValueError, ZeroDivisonError:
+ pass
+ with open(fn, 'w') as f:
+ f.write('\n'.join(lines) + '\n')
+\end{sageblock}
+
+There probably should be some more exceptions in that list, and the
+above code doesn't check to make sure it's writing real values, but then
+again, this is just a file of examples!
+
+Then you define callable functions x and y and pass them in, along with
+a sequence of values and a file name. Here's a plot that I used on a
+calculus exam:
+
+\begin{sageblock}
+ r(t) = 1 - 2*sin(3*t)
+ x(t) = r(t)*cos(t)
+ y(t) = r(t)*sin(t)
+ gnuplot(x, y, srange(0, 2*pi + .05, .05), 'example-tikz1.table')
+\end{sageblock}
+
+(Usually you would do that in sagesilent environments, I guess.)
+
+Then you call TikZ with your plot.
+
+\begin{tikzpicture}
+ \draw[very thin,->] (-3.25,0) -- (3.25,0);
+ \draw[very thin,->] (0,-3.25) -- (0,3.25);
+ \draw[smooth] plot file {example-tikz1.table};
+\end{tikzpicture}
+
+For regular Cartesian plots, just pass in the identity function for x:
+
+\begin{sageblock}
+ x = lambda t: t
+ y(t) = t*sin(1/t)
+ gnuplot(x, y, [0.01, 0.02..(0.5)] + [0.55, 0.6..2], 'example-tikz2.table')
+\end{sageblock}
+
+\begin{center}
+\begin{tikzpicture}[scale=3]
+ \draw[very thin,->] (-0.25,0) -- (2,0);
+ \draw[very thin,->] (0,-1/3) -- (0,1);
+ \draw[smooth, red] plot file {example-tikz2.table};
+\end{tikzpicture}
+\end{center}
+
+This style of plotting will become even more useful and powerful when
+the new TikZ Data Visualization library is available---you will be able
+to feed TikZ a bunch of data points, and it automatically make a very
+nice plot for you, including axes, labels, and so on.
+
+\end{comment}
+
+\section{The \texttt{sagecommandline} environment}
+
+When writing a \TeX{} document about Sage, you may want to show some
+examples of commands and their output. But naturally, you are lazy and
+don't want to cut and paste the output into your document. ``Why should
+I have to do anything? Why can't Sage and \TeX{} cooperate and do it for
+me?'' you may cry. Well, they \emph{can} cooperate:
+
+\begin{sagecommandline}
+ sage: 1+1
+ sage: is_prime(57)
+ sage: if is_prime(57):
+ ....: print('prime')
+ ....: else:
+ ....: print('composite')
+\end{sagecommandline}
+
+Note that the output of the commands is not included in the source file,
+but are included in the typeset output.
+
+Because of the way the environment is implemented, not everything is
+exactly like using Sage in a terminal: the two commands below (and the
+``if is prime'' one above, did you notice that?) would produce some
+output, but don't here:
+
+\begin{sagecommandline}
+ sage: x = 2010; len(x.divisors())
+ sage: print('Hola, mundo!')
+\end{sagecommandline}
+
+The difference lies in the Python distinction between statements and
+expressions; we can use \texttt{eval()} for an expression and get its
+output, but we must use \texttt{exec} for a statement and can't get the
+output, if any.
+
+One nice thing is that you can set labels by using an @ sign:
+
+\begin{sagecommandline}
+ sage: l = matrix([[1,0,0],[3/5,1,0],[-2/5,-2,1]])
+ sage: d = diagonal_matrix([15, -1, 4]) #@\label{diagonal}
+ sage: u = matrix([[1,0,1/3],[0,1,2],[0,0,1]]) #@\label{anotherlabel} \# foo
+ sage: l*d*u # this is a comment
+\end{sagecommandline}
+
+And then refer to that label: it was on line \ref{diagonal}, which is on
+page \pageref{diagonal}. Note that the other text after the hash mark on
+that line does not get typeset as a comment, and that you cannot have
+any space between the hash mark and the~@. You will also need to typeset
+your document \emph{twice}
+
+You can also typeset the output by changing the value of
+\verb|\sagecommandlinetextoutput| to False:
+\renewcommand{\sagecommandlinetextoutput}{False}
+\begin{sagecommandline}
+ sage: l*d*u
+ sage: x = var('x')
+ sage: (1-cos(x)^2).trig_simplify()
+\end{sagecommandline}
+
+\renewcommand{\sagecommandlinetextoutput}{True}
+
+The Sage input and output is typeset using the \texttt{listings} package
+with the styles \texttt{SageInput} and \texttt{SageOutput},
+respectively. If you don't like the defaults you can change them. It is
+recommended to derive from \texttt{DefaultSageInput} and
+\texttt{DefaultSageOutput}, for example\ldots
+\lstdefinestyle{SageInput}{style=DefaultSageInput,basicstyle={\color{red}}}
+\lstdefinestyle{SageOutput}{style=DefaultSageOutput,basicstyle={\color{green}}}
+makes things overly colorful:
+\begin{sagecommandline}
+ sage: pi.n(100)
+\end{sagecommandline}
+\lstdefinestyle{SageInput}{style=DefaultSageInput}
+\lstdefinestyle{SageOutput}{style=DefaultSageOutput}
+
+Plotting things doesn't automatically pull in the plot, just the text
+representation of the plot (the equivalent of applying \texttt{str()} to
+it):
+
+\begin{sagecommandline}
+ sage: plot(sin(x), (x, 0, 2*pi))
+\end{sagecommandline}
+
+You can include output, but it will be ignored. This is useful for
+doctesting, as all the \texttt{sagecommandline} environment things get
+put into the ``\texttt{\_doctest.sage}'' file. However, note that if you
+don't include any output, then the corresponding doctest will fail if
+the command produces output. The doctest output from this file will have
+lots of failures because not many of the commands have output included
+in the source \texttt{.tex} file.
+
+The command below has incorrect output included in the \texttt{.tex}
+file; in the PDF, you see the correct Sage-computed answer, but if you
+do \texttt{sage -t example\_doctest.sage} you will get a genuine doctest
+failure.
+\begin{sagecommandline}
+ sage: factor(x^2 + 2*x + 1)
+ (x + 999)^2
+\end{sagecommandline}
+
+\end{document}
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:
diff --git a/macros/latex/contrib/sagetex/remote-sagetex.dtx b/macros/latex/contrib/sagetex/remote-sagetex.dtx
new file mode 100644
index 0000000000..1460c1a69c
--- /dev/null
+++ b/macros/latex/contrib/sagetex/remote-sagetex.dtx
@@ -0,0 +1,438 @@
+% \section{The \texttt{remote-sagetex} script}
+% \label{sec:remote-sagetex-code}
+%
+%
+% Here we describe the Python code for |remote-sagetex.py|. Since its
+% job is to replicate the functionality of using Sage and |sagetex.py|,
+% there is some overlap with the Python module.
+%
+% \iffalse
+%<*remotesagetex>
+% \fi
+%
+% 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}
+from __future__ import print_function
+import json
+import sys
+import time
+import re
+import urllib
+import hashlib
+import os
+import os.path
+import shutil
+import getopt
+from contextlib import closing
+
+#########################################################################
+# You can provide a filename here and the script will read your login #
+# information from that file. The format must be: #
+# #
+# server = 'http://foo.com:8000' #
+# username = 'my_name' #
+# password = 's33krit' #
+# #
+# You can omit one or more of those lines, use " quotes, and put hash #
+# marks at the beginning of a line for comments. Command-line args #
+# take precedence over information from the file. #
+#########################################################################
+login_info_file = None # e.g. '/home/foo/Private/sagetex-login.txt'
+
+
+usage = """Process a SageTeX-generated .sage file using a remote Sage server.
+
+Usage: {0} [options] inputfile.sage
+
+Options:
+
+ -h, --help: print this message
+ -s, --server: the Sage server to contact
+ -u, --username: username on the server
+ -p, --password: your password
+ -f, --file: get login information from a file
+
+If the server does not begin with the four characters `http', then
+`https://' will be prepended to the server name.
+
+You can hard-code the filename from which to read login information into
+the remote-sagetex script. Command-line arguments take precedence over
+the contents of that file. See the SageTeX documentation for formatting
+details.
+
+If any of the server, username, and password are omitted, you will be
+asked to provide them.
+
+See the SageTeX documentation for more details on usage and limitations
+of remote-sagetex.""".format(sys.argv[0])
+
+server, username, password = (None,) * 3
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], 'hs:u:p:f:',
+ ['help', 'server=', 'user=', 'password=', 'file='])
+except getopt.GetoptError as err:
+ print(str(err), usage, sep='\n\n')
+ sys.exit(2)
+
+for o, a in opts:
+ if o in ('-h', '--help'):
+ print(usage)
+ sys.exit()
+ elif o in ('-s', '--server'):
+ server = a
+ elif o in ('-u', '--user'):
+ username = a
+ elif o in ('-p', '--password'):
+ password = a
+ elif o in ('-f', '--file'):
+ login_info_file = a
+
+if len(args) != 1:
+ print('Error: must specify exactly one file. Please specify options first.',
+ usage, sep='\n\n')
+ sys.exit(2)
+
+jobname = os.path.splitext(args[0])[0]
+% \end{macrocode}
+% When we send things to the server, we get everything back as a string,
+% including tracebacks. We can search through output using regexps to
+% look for typical traceback strings, but there's a more robust way: put
+% in a special string that changes every time and is printed when
+% there's an error, and look for that. Then it is massively unlikely
+% that a user's code could produce output that we'll mistake for an
+% actual traceback. System time will work well enough for these
+% purposes. We produce this string now, and we it when parsing the
+% |.sage| file (we insert it into code blocks) and when parsing the
+% output that the remote server gives us.
+% \begin{macrocode}
+traceback_str = 'Exception in SageTeX session {0}:'.format(time.time())
+% \end{macrocode}
+% \begin{macro}{parsedotsage}
+% To figure out what commands to send the remote server, we actually
+% read in the |.sage| file as strings and parse it. This seems a bit
+% strange, but since we know exactly what the format of that file is, we
+% can parse it with a couple flags and a handful of regexps.
+% \begin{macrocode}
+def parsedotsage(fn):
+ with open(fn, 'r') as f:
+% \end{macrocode}
+% Here are the regexps we use to snarf the interesting bits out of the
+% |.sage| file. Below we'll use the |re| module's |match| function so we
+% needn't anchor any of these at the beginning of the line.
+% \begin{macrocode}
+ inline = re.compile(r" _st_.inline\((?P<num>\d+), (?P<code>.*)\)")
+ plot = re.compile(r" _st_.plot\((?P<num>\d+), (?P<code>.*)\)")
+ goboom = re.compile(r" _st_.goboom\((?P<num>\d+)\)")
+ pausemsg = re.compile(r"print.'(?P<msg>SageTeX (un)?paused.*)'")
+ blockbegin = re.compile(r"_st_.blockbegin\(\)")
+ ignore = re.compile(r"(try:)|(except):")
+ in_comment = False
+ in_block = False
+ cmds = []
+% \end{macrocode}
+% Okay, let's go through the file. We're going to make a list of
+% dictionaries. Each dictionary corresponds to something we have to do
+% with the remote server, except for the pause/unpause ones, which we
+% only use to print out information for the user. All the dictionaries
+% have a |type| key, which obviously tells you type they are. The
+% pause/unpause dictionaries then just have a |msg| which we toss out to
+% the user. The ``real'' dictionaries all have the following keys:
+% \begin{itemize}
+% \item |type|: one of |inline|, |plot|, and |block|.
+% \item |goboom|: used to help the user pinpoint errors, just like the
+% |goboom| function (page \pageref{macro:goboom}) does.
+% \item |code|: the code to be executed.
+% \end{itemize}
+% Additionally, the |inline| and |plot| dicts have a |num| key for the
+% label we write to the |.sout| file.
+%
+% Here's the whole parser loop. The interesting bits are for parsing
+% blocks because there we need to accumulate several lines of code.
+% \begin{macrocode}
+ for line in f.readlines():
+ if line.startswith('"""'):
+ in_comment = not in_comment
+ elif not in_comment:
+ m = pausemsg.match(line)
+ if m:
+ cmds.append({'type': 'pause',
+ 'msg': m.group('msg')})
+ m = inline.match(line)
+ if m:
+ cmds.append({'type': 'inline',
+ 'num': m.group('num'),
+ 'code': m.group('code')})
+ m = plot.match(line)
+ if m:
+ cmds.append({'type': 'plot',
+ 'num': m.group('num'),
+ 'code': m.group('code')})
+% \end{macrocode}
+% The order of the next three ``if''s is important, since we need the
+% ``goboom'' line and the ``blockbegin'' line to \emph{not} get included
+% into the block's code. Note that the lines in the |.sage| file already
+% have some indentation, which we'll use when sending the block to the
+% server---we wrap the text in a try/except.
+% \begin{macrocode}
+ m = goboom.match(line)
+ if m:
+ cmds[-1]['goboom'] = m.group('num')
+ if in_block:
+ in_block = False
+ if in_block and not ignore.match(line):
+ cmds[-1]['code'] += line
+ if blockbegin.match(line):
+ cmds.append({'type': 'block',
+ 'code': ''})
+ in_block = True
+ return cmds
+% \end{macrocode}
+% \end{macro}
+% Parsing the |.sage| file is simple enough so that we can write one
+% function and just do it. Interacting with the remote server is a bit
+% more complicated, and requires us to carry some state, so let's make a
+% class.
+%
+% \begin{macro}{RemoteSage}
+% \changes{v2.2.1}{2009/06/20}{Fix stupid bug in \texttt{do\_inline()}
+% so that we actually write output to .sout file}
+%
+% This is pretty simple; it's more or less a translation of the examples
+% in \texttt{sage/server/simple/twist.py}.
+% \begin{macrocode}
+debug = False
+class RemoteSage:
+ def __init__(self, server, user, password):
+ self._srv = server.rstrip('/')
+ sep = '___S_A_G_E___'
+ self._response = re.compile('(?P<header>.*)' + sep +
+ '\n*(?P<output>.*)', re.DOTALL)
+ self._404 = re.compile('404 Not Found')
+ self._session = self._get_url('login',
+ urllib.urlencode({'username': user,
+ 'password':
+ password}))['session']
+% \end{macrocode}
+% In the string below, we want to do ``partial formatting'': we format
+% in the traceback string now, and want to be able to format in the code
+% later. The double braces get ignored by |format()| now, and are picked
+% up by |format()| when we use this later.
+% \begin{macrocode}
+ self._codewrap = """try:
+{{0}}
+except:
+ print('{0}')
+ traceback.print_exc()""".format(traceback_str)
+ self.do_block("""
+ import traceback
+ def __st_plot__(counter, _p_, format='notprovided', **kwargs):
+ if format == 'notprovided':
+ formats = ['eps', 'pdf']
+ else:
+ formats = [format]
+ for fmt in formats:
+ plotfilename = 'plot-%s.%s' % (counter, fmt)
+ _p_.save(filename=plotfilename, **kwargs)""")
+
+ def _encode(self, d):
+ return 'session={0}&'.format(self._session) + urllib.urlencode(d)
+
+ def _get_url(self, action, u):
+ with closing(urllib.urlopen(self._srv + '/simple/' + action +
+ '?' + u)) as h:
+ data = self._response.match(h.read())
+ result = json.loads(data.group('header'))
+ result['output'] = data.group('output').rstrip()
+ return result
+
+ def _get_file(self, fn, cell, ofn=None):
+ with closing(urllib.urlopen(self._srv + '/simple/' + 'file' + '?' +
+ self._encode({'cell': cell, 'file': fn}))) as h:
+ myfn = ofn if ofn else fn
+ data = h.read()
+ if not self._404.search(data):
+ with open(myfn, 'w') as f:
+ f.write(data)
+ else:
+ print('Remote server reported {0} could not be found:'.format(
+ fn))
+ print(data)
+% \end{macrocode}
+% The |code| below gets stuffed between a try/except, so make sure it's
+% indented!
+% \begin{macrocode}
+ def _do_cell(self, code):
+ realcode = self._codewrap.format(code)
+ result = self._get_url('compute', self._encode({'code': realcode}))
+ if result['status'] == 'computing':
+ cell = result['cell_id']
+ while result['status'] == 'computing':
+ sys.stdout.write('working...')
+ sys.stdout.flush()
+ time.sleep(10)
+ result = self._get_url('status', self._encode({'cell': cell}))
+ if debug:
+ print('cell: <<<', realcode, '>>>', 'result: <<<',
+ result['output'], '>>>', sep='\n')
+ return result
+
+ def do_inline(self, code):
+ return self._do_cell(' print(latex({0}))'.format(code))
+
+ def do_block(self, code):
+ result = self._do_cell(code)
+ for fn in result['files']:
+ self._get_file(fn, result['cell_id'])
+ return result
+
+ def do_plot(self, num, code, plotdir):
+ result = self._do_cell(' __st_plot__({0}, {1})'.format(num, code))
+ for fn in result['files']:
+ self._get_file(fn, result['cell_id'], os.path.join(plotdir, fn))
+ return result
+% \end{macrocode}
+% When using the simple server API, it's important to log out so the
+% server doesn't accumulate idle sessions that take up lots of memory.
+% We define a |close()| method and use this class with the |closing|
+% context manager that always calls |close()| on the way out.
+% \begin{macrocode}
+ def close(self):
+ sys.stdout.write('Logging out of {0}...'.format(server))
+ sys.stdout.flush()
+ self._get_url('logout', self._encode({}))
+ print('done')
+% \end{macrocode}
+% \end{macro}
+% Next we have a little pile of miscellaneous functions and variables
+% that we want to have at hand while doing our work. Note that we again
+% use the traceback string in the error-finding regular expression.
+% \begin{macrocode}
+def do_plot_setup(plotdir):
+ printc('initializing plots directory...')
+ if os.path.isdir(plotdir):
+ shutil.rmtree(plotdir)
+ os.mkdir(plotdir)
+ return True
+
+did_plot_setup = False
+plotdir = 'sage-plots-for-' + jobname + '.tex'
+
+def labelline(n, s):
+ return r'\newlabel{@sageinline' + str(n) + '}{{' + s + '}{}{}{}{}}\n'
+
+def printc(s):
+ print(s, end='')
+ sys.stdout.flush()
+
+error = re.compile("(^" + traceback_str + ")|(^Syntax Error:)", re.MULTILINE)
+
+def check_for_error(string, line):
+ if error.search(string):
+ print("""
+**** Error in Sage code on line {0} of {1}.tex!
+{2}
+**** Running Sage on {1}.sage failed! Fix {1}.tex and try again.""".format(
+ line, jobname, string))
+ sys.exit(1)
+% \end{macrocode}
+% Now let's actually start doing stuff.
+% \begin{macrocode}
+print('Processing Sage code for {0}.tex using remote Sage server.'.format(
+ jobname))
+
+if login_info_file:
+ with open(login_info_file, 'r') as f:
+ print('Reading login information from {0}.'.format(login_info_file))
+ get_val = lambda x: x.split('=')[1].strip().strip('\'"')
+ for line in f:
+ print(line)
+ if not line.startswith('#'):
+ if line.startswith('server') and not server:
+ server = get_val(line)
+ if line.startswith('username') and not username:
+ username = get_val(line)
+ if line.startswith('password') and not password:
+ password = get_val(line)
+
+if not server:
+ server = raw_input('Enter server: ')
+
+if not server.startswith('http'):
+ server = 'https://' + server
+
+if not username:
+ username = raw_input('Enter username: ')
+
+if not password:
+ from getpass import getpass
+ password = getpass('Please enter password for user {0} on {1}: '.format(
+ username, server))
+
+printc('Parsing {0}.sage...'.format(jobname))
+cmds = parsedotsage(jobname + '.sage')
+print('done.')
+
+sout = '% This file was *autogenerated* from the file {0}.sage.\n'.format(
+ os.path.splitext(jobname)[0])
+
+printc('Logging into {0} and starting session...'.format(server))
+with closing(RemoteSage(server, username, password)) as sage:
+ print('done.')
+ for cmd in cmds:
+ if cmd['type'] == 'inline':
+ printc('Inline formula {0}...'.format(cmd['num']))
+ result = sage.do_inline(cmd['code'])
+ check_for_error(result['output'], cmd['goboom'])
+ sout += labelline(cmd['num'], result['output'])
+ print('done.')
+ if cmd['type'] == 'block':
+ printc('Code block begin...')
+ result = sage.do_block(cmd['code'])
+ check_for_error(result['output'], cmd['goboom'])
+ print('end.')
+ if cmd['type'] == 'plot':
+ printc('Plot {0}...'.format(cmd['num']))
+ if not did_plot_setup:
+ did_plot_setup = do_plot_setup(plotdir)
+ result = sage.do_plot(cmd['num'], cmd['code'], plotdir)
+ check_for_error(result['output'], cmd['goboom'])
+ print('done.')
+ if cmd['type'] == 'pause':
+ print(cmd['msg'])
+ if int(time.time()) % 2280 == 0:
+ printc('Unscheduled offworld activation; closing iris...')
+ time.sleep(1)
+ print('end.')
+
+with open(jobname + '.sage', 'r') as sagef:
+ h = hashlib.md5()
+ for line in sagef:
+ if (not line.startswith(' _st_.goboom') and
+ not line.startswith("print('SageT")):
+ h.update(bytearray(line,'utf8'))
+% \end{macrocode}
+% Putting the |{1}| in the string, just to replace it with |%|, seems a
+% bit weird, but if I put a single percent sign there, Docstrip won't
+% put that line into the resulting |.py| file---and if I put two percent
+% signs, it replaces them with |\MetaPrefix| which is |##| when this
+% file is generated. This is a quick and easy workaround.
+% \begin{macrocode}
+ sout += """%{0}% md5sum of corresponding .sage file
+{1} (minus "goboom" and pause/unpause lines)
+""".format(h.hexdigest(), '%')
+
+printc('Writing .sout file...')
+with open(jobname + '.sout', 'w') as soutf:
+ soutf.write(sout)
+ print('done.')
+print('Sage processing complete. Run LaTeX on {0}.tex again.'.format(jobname))
+% \end{macrocode}
+
+% \endinput
+%</remotesagetex>
+% Local Variables:
+% mode: doctex
+% TeX-master: "sagetex"
+% End:
diff --git a/macros/latex/contrib/sagetex/sagetex.dtx b/macros/latex/contrib/sagetex/sagetex.dtx
new file mode 100644
index 0000000000..da0b7ff86a
--- /dev/null
+++ b/macros/latex/contrib/sagetex/sagetex.dtx
@@ -0,0 +1,1225 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2008--2015 by Dan Drake <dr.dan.drake (at) gmail (dot) com>
+% -------------------------------------------------------
+%
+% See the "Copying and licenses" section in this file for the terms
+% under which this source code and documentation may be modified and
+% distributed.
+%
+% This package is not licensed under the LPPL, but it seems reasonable
+% to say:
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainers of this work are Sagemath Developers.
+%
+% This work consists of the files sagetex.dtx, py-and-sty.dtx,
+% scripts.dtx, remote-sagetex.dtx, sagetex.ins, example.tex,
+% and the derived files sagetex.sty, sagetex.py, sagetexparse.py,
+% makestatic.py, extractsagecode.py, and remote-sagetex.py.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{sagetex.dtx}
+%</driver>
+%<latex>\NeedsTeXFormat{LaTeX2e}
+%<latex>\ProvidesPackage{sagetex}
+%<python>__version__ = """
+%<*latex|python>
+ [2019/01/09 v3.2 embedding Sage into LaTeX documents]
+%</latex|python>
+%<python>""".strip()
+%<latex>\newcommand{\ST@ver}{2019/01/09 v3.2}
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{sagetex}
+\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{sagetex.dtx}
+\StopEventually{
+\section{Credits and acknowledgments}
+
+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. Many of 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. Thanks to Nicolas Thi\'ery for the initial code and
+contributions to the \texttt{sageexample} environment and Volker Braun
+for the \texttt{sagecommandline} environment.
+
+\section{Copying and licenses}
+\label{sec:copying-licenses}
+
+If you are unnaturally curious about the current state of the \ST
+package, you can visit \url{https://github.com/sagemath/sagetex}. (The
+old Bitbucket and Github dandrake repositories are deprecated.)
+
+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-Share Alike 3.0 License. To view a copy of
+this license, visit \url{http://creativecommons.org/licenses/by-sa/3.0/}
+or send a letter to Creative Commons, 171 Second Street, Suite 300, San
+Francisco, California, 94105, USA.
+
+I am not terribly dogmatic about these licenses, so if you would like to
+do something with \ST that's not possible under these license
+conditions, please contact me. I will likely be receptive to
+suggestions.
+
+\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 page break problems won't occur.
+\fi
+\clearpage
+
+}
+
+\DocInput{py-and-sty.dtx}
+\DocInput{scripts.dtx}
+\DocInput{remote-sagetex.dtx}
+\Finale
+\PrintChanges
+\PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \changes{v1.0}{2008/03/03}{Initial version}
+% \changes{v1.1}{2008/03/05}{Wrapped user-provided Sage code in
+% try/except clauses; plotting now has optional format argument}
+% \changes{v1.2}{2008/03/07}{Imagemagick option; better documentation}
+% \changes{v1.3.1}{2008/03/10}{Internal variables renamed; fixed typos}
+% \changes{v1.4}{2008/03/11}{MD5 fix, percent sign macro, CTAN upload}
+% \changes{v2.0}{2008/12/16}{External Python scripts for parsing
+% SageTeX-ified documents, tons of documentation improvements,
+% sagetex.py refactored, include in Sage as spkg}
+% \changes{v2.0}{2009/01/09}{Miscellaneous fixes, final 2.0 version}
+% \changes{v2.1}{2009/05/12}{Add pausing support}
+% \changes{v2.1}{2009/05/12}{Get version written to .py file}
+% \changes{v2.2}{2009/06/17}{Add remote-sagetex.py script}
+% \changes{v2.3}{2010/10/20}{Add sagecommandline environment}
+%
+% \GetFileInfo{sagetex.sty}
+%
+% \DoNotIndex{\newcommand,\newenvironment,\the}
+%
+% \newcommand{\ST}{\textsf{Sage\TeX}\xspace}
+% \iffalse
+% so I don't have to put \ or {} after \LaTeX:
+% \fi
+% \newcommand{\LTX}{\LaTeX\xspace}
+%
+% \newcommand{\TikZ}{Ti\emph{k}Z\xspace}
+%
+% \newcommand{\warningbox}[1]{\colorbox[rgb]{1, 0.6, 0.6}%
+% {\parbox{.97\textwidth}{#1}}}
+%
+% \tikzstyle{box}=[draw, shape=rectangle, thick]
+%
+% \title{The \ST{} package\thanks{This document corresponds to
+% \ST \fileversion, dated \filedate.}}
+%
+% \author{Dan Drake and others\thanks{Author's website:
+% \href{http://mathsci.kaist.ac.kr/\textasciitilde drake/}
+% {\texttt{mathsci.kaist.ac.kr/$\sim$drake/}}.}}
+%
+% \iffalse
+% Don't put any other code from this file into the .sty or .py
+% file:
+%<*!latex&!python>
+% This lets us use verbatim environments in the documentation.
+% \fi
+%
+% \maketitle
+%
+% \section{Introduction}
+%
+% Why should the Haskell and R folks have all the fun?
+% \href{http://www.haskell.org/haskellwiki/Literate_programming}{Literate
+% Haskell} is a popular way to mix Haskell source code and \LTX
+% documents. (Actually any kind of text or document, but here we're
+% concerned only with \LTX.) You can even embed Haskell code in your
+% document that writes part of your document for you. Similarly, the R
+% statistical computing environment includes
+% \href{http://tug.org/pracjourn/2008-1/zahn/}{Sweave}, which lets you
+% do the same thing with R code and \LTX.
+%
+% The \ST package allows you to do (roughly) the same thing with the
+% Sage mathematics software suite (see \url{http://sagemath.org}) and
+% \LTX. (If you know how to write literate Haskell: the |\eval| command
+% corresponds to |\sage|, and the |code| environment to the |sageblock|
+% environment.) As a simple example, imagine in your document you are
+% writing about how to count license plates with three letters and three
+% digits. With this package, you can write something like this:
+% \begin{quote}
+% |There are $26$ choices for each letter, and $10$ choices for|\\
+% |each digit, for a total of $26^3 \cdot 10^3 =|\\
+% |\sage{26^3*10^3}$ license plates.|
+% \end{quote}
+% and it will produce
+% \begin{quote}
+% There are $26$ choices for each letter, and $10$ choices for each
+% digit, for a total of $26^3 \cdot 10^3 = \sage{26^3 * 10^3}$ license
+% plates.
+% \end{quote}
+% The great thing is, you don't have to do the multiplication. Sage does
+% it for you. This process mirrors one of the great aspects of \LTX:
+% when writing a \LTX document, you can concentrate on the logical
+% structure of the document and trust \LTX and its army of packages to
+% deal with the presentation and typesetting. Similarly, with \ST, you
+% can concentrate on the mathematical structure (``I need the product of
+% $26^3$ and $10^3$'') and let Sage deal with the base-$10$ presentation
+% of the number.
+%
+% A less trivial, and perhaps more useful example is plotting. You can
+% include a plot of the sine curve without manually producing a plot,
+% saving an EPS or PDF file, and doing the |\includegraphics| business
+% with the correct filename yourself. If you write this:
+% \begin{quote}
+% |Here is a lovely graph of the sine curve:|
+%
+% |\sageplot[width=.75\textwidth]{plot(sin(x), x, 0, 2*pi)}|
+% \end{quote}
+% in your \LTX file, it produces
+% \begin{quote}
+% Here is a lovely graph of the sine curve:
+%
+% \sageplot[width=.75\textwidth]{plot(sin(x), x, 0, 2*pi)}
+% \end{quote}
+% Again, you need only worry about the logical/mathematical structure of
+% your document (``I need a plot of the sine curve over the interval
+% $[0, 2\pi]$ here''), while \ST{} takes care of the gritty details of
+% producing the file and sourcing it into your document.
+%
+% \paragraph{But \texttt{\bslash sageplot} isn't magic} I just tried to
+% convince you that \ST makes putting nice graphics into your document
+% very easy; let me turn around and warn you that using graphics
+% \emph{well} is not easy, and no \LTX package or Python script will
+% ever make it easy. What \ST does is make it easy to \emph{use Sage} to
+% create graphics; it doesn't magically make your graphics good,
+% appropriate, or useful. (For instance, look at the sine plot above---I
+% would say that a truly lovely plot of the sine curve would not mark
+% integer points on the $x$-axis, but rather $\pi/2$, $\pi$, $3\pi/2$,
+% and $2\pi$. Incidentally, you can do this in Sage: do
+% |sage.plot.plot?| and look for |ticks| and |tick_formatter|.)
+%
+% Till Tantau has some good commentary on the use of graphics in the
+% \href{http://www.ctan.org/tex-archive/help/Catalogue/entries/pgf.html}{``Guidelines
+% on Graphics'' section of the \textsc{pgf} manual} (chapter 7 of the
+% manual for version 2.10). You should always give careful thought and
+% attention to creating graphics for your document; I have in mind that
+% a good workflow for using \ST for plotting is something like this:
+%
+% \begin{enumerate}
+% \item Figure out what sort of graphic you need to communicate your
+% ideas or information.
+% \item Fiddle around in Sage until you get a graphics object and set
+% of options that produce the graphic you need.
+% \item Copy those commands and options into \ST commands in your
+% \LTX document.
+% \end{enumerate}
+%
+% The \ST{} package's plotting capabilities don't help you find those
+% Sage commands to make your lovely plot, but they do eliminate the need
+% to muck around with saving the result to a file, remembering the
+% filename, including it into your document, and so on. In
+% \autoref{sec:usage}, we will see what what we can do with \ST.
+%
+%
+% \section{Installation}
+% \label{sec:installation}
+% \changes{v2.0}{2009/01/14}{Fixed up installation section, final
+% \emph{final} 2.0}
+% \changes{v2.2.3}{2009/12/29}{Rewrote installation section to reflect
+% inclusion as standard spkg}
+%
+% \newcommand{\sageroot}{\$SAGE\_ROOT}
+%
+% \ST needs two parts to work: a Python module known to Sage, and a \LTX
+% package known to \TeX. These two parts need to come from the same
+% version of \ST to guarantee that everything works properly. As of Sage
+% version 4.3.1, \ST comes included with Sage, so you only need to make
+% \texttt{sagetex.sty}, the \LTX package, known to \TeX. Full details of
+% this are in the Sage tutorial at
+% \href{http://doc.sagemath.org/html/en/tutorial/sagetex.html}{\texttt{doc.sagemath.org/html/en/tutorial/sagetex.html}}
+% in the obviously-named section ``Make \ST known to \TeX''. Here's a
+% brief summary of how to do that:
+%
+% \begin{itemize}
+% \item Copy \texttt{sagetex.sty} to the same directory as your
+% document. This always works, but requires lots of copies of
+% \texttt{sagetex.sty} and is prone to version skew.
+%
+% \item Copy the directory containing \texttt{sagetex.sty} to your home
+% directory with a command like
+% \begin{quotation}
+% \texttt{cp -R \sageroot/local/share/texmf \textasciitilde/}
+% \end{quotation}
+% where \texttt{\sageroot} is replaced with the location of your
+% Sage installation.
+%
+% \item Use the environment variable \texttt{TEXINPUTS} to tell \TeX{}
+% to search the directory containing \texttt{sagetex.sty}; in the bash
+% shell, you can do
+% \begin{quotation}
+% \texttt{export TEXINPUTS=\sageroot/local/share/texmf//:}
+% \end{quotation}
+% You should again replace \texttt{\sageroot} with the location of
+% your Sage installation.
+% \end{itemize}
+%
+% The best method is likely the second; while that does require you to
+% recopy the files every time you update your copy of Sage, it does not
+% depend on your shell, so if you use, say, Emacs with Auc\TeX{} or some
+% other editor environment, everything will still work since \TeX's
+% internal path-searching mechanisms can find \texttt{sagetex.sty}.
+%
+% Note that along with \texttt{sagetex.sty}, this documentation, an
+% example file, and other useful scripts are all located in the
+% directory \texttt{\sageroot/local/share/texmf}.
+%
+% \subsection{\ST and \TeX Live}
+%
+% \ST was included in \TeX Live, which seemed nice, except that the Python
+% module and \LTX package for \ST need to be synchronized and the Python
+% module in Sage was much easier to update than the \LTX style file in
+% \TeX Live. If you are so unlucky as to be using a version of \TeX Live
+% that includes \ST, I strongly recommend using \ST only from what is
+% included with Sage and ignoring what's included with \TeX Live.
+%
+% \subsection{The noversioncheck option}
+% \label{sec:noversioncheck}
+%
+% As of version 2.2.4, \ST automatically checks to see if the versions
+% of the style file and Python module match. This is intended to prevent
+% strange version mismatch problems, but if you would like to use
+% mismatched sources, you can---at your peril---give the
+% |noversioncheck| option when you load the \ST package. Don't be
+% surprised if things don't work when you do this.
+%
+% If you are considering using this option because the Sage script
+% complained and exited, you really should just get the \LTX and Python
+% modules synchronized. Every copy of Sage since version 4.3.2 comes
+% with a copy of |sagetex.sty| that is matched up to Sage's baked-in \ST
+% support, so you can always use that. See the
+% \href{http://doc.sagemath.org/html/en/tutorial/sagetex.html}{\ST section of the Sage
+% tutorial}.
+%
+% \subsection{Using \TeX Shop}
+% \label{sec:using-texshop}
+% \changes{v2.0.1}{2009/03/10}{Add \TeX Shop info}
+%
+% Starting with version 2.25,
+% \href{http://www.uoregon.edu/~koch/texshop/}{\TeX Shop} includes
+% support for \ST. If you move the file |sage.engine| from
+% |~/Library/TeXShop/Engines/Inactive/Sage| to
+% |~/Library/TeXShop/Engines| and put the line
+% \begin{quotation}
+% |%!TEX TS-program = sage|
+% \end{quotation}
+% at the top of your document, then \TeX Shop will automatically run Sage
+% for you when compiling your document.
+%
+% Note that you will need to make sure that \LTX can find |sagetex.sty|
+% using any of the methods above. You also might need to edit the
+% |sage.engine| script to reflect the location of your Sage
+% installation. \TeX Shop includes further documentation in the
+% |~/Library/TeXShop/Engines/Inactive/Sage| folder; be sure to check out
+% the ``About Sage'' PDF there, which has good advice on setting up
+% things so that typesetting \ST-ified documents works automatically,
+% and so that it continues to work when you upgrade your Sage
+% installation.
+%
+% \subsection{Other scripts included with \ST}
+% \label{sec:inst-other-scripts}
+%
+% \ST includes several Python files which may be useful for working with
+% ``\ST-ified'' documents. At this point they have likely bitrotted but
+% are, for now, included for archaeological purposes.
+%
+% The |remote-sagetex.py| script allows you to use \ST on a computer
+% that doesn't have Sage installed; see \autoref{sec:remote-sagetex} for
+% more information.
+%
+% Also included are |makestatic.py| and |extractsagecode.py|, which are
+% convenience scripts that you can use after you've written your
+% document. See \autoref{sec:makestatic-usage} and
+% \autoref{sec:extractsagecode} for information on using those scripts.
+% The file |sagetexparse.py| is a module used by both those scripts.
+% These three files are independent of \ST. If you install from a spkg,
+% these scripts can be found in \texttt{\sageroot/local/share/texmf/}.
+%
+% \section{Usage}
+% \label{sec:usage}
+%
+% Let's begin with a rough description of how \ST works. Naturally the
+% very first step is to put |\usepackage{sagetex}| in the preamble of
+% your document. When you use macros from this package and run \LTX on
+% your file, along with the usual zoo of auxiliary files, a |.sage| file
+% is written with the same basename as your document. This is a Sage
+% source file that uses the Python module from this package and when you
+% run Sage on that file, it will produce a |.sout| and a |.scmd| file.
+% The |.sout| file contains \LTX code that, when you run \LTX on your
+% source file again, will pull in all the results of Sage's computation.
+%
+% The |sagecommandline| environment additionally logs the plain sage
+% commands and output furthermore in a |.scmd| file.
+%
+% All you really need to know is that to typeset your document, you need
+% to run \LTX, then run Sage, then run \LTX again.
+%
+% Also keep in mind that everything you send to Sage is done within one
+% Sage session. This means you can define variables and reuse them
+% throughout your \LTX document; if you tell Sage that |foo| is
+% $12$, then anytime afterwards you can use |foo| in your Sage code and
+% Sage will remember that it's $12$---just like in a regular Sage
+% session.
+%
+% Now that you know that, let's describe what macros \ST provides and
+% how to use them. If you are the sort of person who can't be bothered
+% to read documentation until something goes wrong, you can also just
+% look through the |example.tex| file included with this
+% package.\footnote{Then again, if you're such a person, you're probably
+% not reading this, and are already fiddling with
+% \texttt{example.tex}\dots}\\
+%
+% \noindent\warningbox{\textbf{WARNING!} When you run \LTX on a file
+% named \texttt{\meta{filename}.tex}, the file
+% \texttt{\meta{filename}.sagetex.sage} is created---and will be
+% \emph{automatically overwritten} if it already exists. If you keep
+% Sage scripts in the same directory as your \ST-ified \LTX documents,
+% use a different file name!}
+%
+% \noindent\warningbox{\textbf{WARNING!} Speaking of filenames, \ST
+% really works best on files whose names don't have spaces or other
+% ``funny'' characters in them. \ST \emph{should} work on such
+% files---and you should let us know if it doesn't---but it's safest
+% to stick to files with alphanumeric characters and ``safe''
+% punctuation (i.e., nothing like |<|, |"|, |!|,
+% \texttt{\bslash}, or other characters that would confuse a
+% shell).}
+%
+% \paragraph{The final option} On a similar note, \ST, like many \LTX
+% packages, accepts the |final| option. When passed this option, either
+% directly in the |\usepackage| line, or from the |\documentclass| line,
+% \ST will not write a |.sage| file. It will try to read in the |.sout|
+% file so that the \ST macros can pull in their results. However, this
+% will not allow you to have an independent Sage script with the same
+% basename as your document, since to get the |.sout| file, you need the
+% |.sage| file.
+%
+% \subsection{Inline Sage}
+% \label{sec:sagemacro-usage}
+%
+% \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.
+%
+% For example, if you do |\sage{matrix([[1, 2], [3,4]])^2}|, then that
+% macro will get replaced by
+% \begin{quote}
+% |\left(\begin{array}{rr}|\\
+% |7 & 10 \\|\\
+% |15 & 22|\\
+% |\end{array}\right)|
+% \end{quote}
+% in your document---that \LTX code is exactly exactly what you get
+% from doing
+% \begin{center}
+% |latex(matrix([[1, 2], [3,4]])^2)|
+% \end{center}
+% in Sage.
+%
+% Note that since \LTX will do macro expansion on whatever you give
+% to |\sage|, you can mix \LTX variables and Sage variables! If
+% you have defined the Sage variable |foo| to be $12$ (using, say, the
+% |sageblock| environment), then you can do something like this:
+% \begin{quote}
+% |The prime factorization of the current page number plus foo|\\
+% |is $\sage{factor(foo + \thepage)}$|.
+% \end{quote}
+%
+% Here, I'll do just that right now: the prime factorization of the
+% current page number plus $12$ is $\sage{factor(\thepage + 12)}$.
+% (Wrong answer? See footnote.\footnote{Is the above factorization
+% wrong? If the current page number plus $12$ is one larger than the
+% claimed factorization, another Sage/\LTX cycle on this source file
+% should fix it. Why? The first time you run \LTX on this file, the
+% sine graph isn't available, so the text where I've talked about the
+% prime factorization is back one page. Then you run Sage, and it
+% creates the sine graph and does the factorization. When you run \LTX
+% again, the sine graph pushes the text onto the next page, but it
+% uses the Sage-computed value from the previous page. Meanwhile, the
+% |.sage| file has been rewritten with the correct page number, so if
+% you do another Sage/\LTX cycle, you should get the correct value
+% above. However, in some cases, even \emph{that} doesn't work because
+% of some kind of \TeX{} weirdness in ending the one page a bit short
+% and starting another.}) The |\sage| command doesn't automatically
+% use math mode for its output, so be sure to use dollar signs or a
+% displayed math environment
+% as appropriate.\\
+%
+% \DescribeMacro{\sagestr}
+% \fbox{\texttt{\bslash sagestr}\marg{Sage code}}
+% is identical to |\sage|, but is does \emph{not} run Sage's |latex|
+% function on the code you give it; it simply runs the Sage code and
+% pulls the result into your \LTX file. This is useful for calling
+% functions that return \LTX code; see the example file distributed
+% along with \ST for a demonstration of using this command to easily
+% produce a table.
+%
+% \DescribeMacro{\percent} If you are doing modular arithmetic or string
+% formatting and need a percent sign in a call to |\sage| (or
+% |\sageplot|), you can use |\percent|. Using a bare percent sign won't
+% work because \LTX will think you're starting a comment and get
+% confused; prefixing the percent sign with a backslash won't work
+% because then ``|\%|'' will be written to the |.sage| file and Sage
+% will get confused. The |\percent| macro makes everyone happy.
+%
+% Note that using |\percent| inside the verbatim-like environments
+% described in \autoref{sec:codeblockenv} isn't necessary; a literal
+% ``\percent'' inside such an environment will get written, uh, verbatim
+% to the |.sage| file.
+%
+% \paragraph{Arguments with side effects}
+%
+% Be careful when feeding |\sage| and |\sagestr| arguments that have
+% side effects, since in some situations they can get evaluated more
+% than once; see section \ref{sec:sage-inside-align}.
+%
+%
+% \subsection{Graphics and plotting}
+% \label{sec:graphics-plotting}
+%
+% \noindent \DescribeMacro{\sageplot}
+% \fbox{\texttt{\bslash sageplot}\oarg{ltx opts}\oarg{fmt}\{\meta{graphics
+% obj}, \meta{keyword args}\}}
+% plots the given Sage graphics object and runs an
+% |\includegraphics| command to put it into your document. It does not
+% have to actually be a plot of a function; it can be any Sage graphics
+% object. The options are described in \autoref{t:sageplotopts}.
+%
+% \begin{table}[h]
+% \centering
+% \begin{tabular}{l p{8cm}}
+% Option & Description \\
+% \hline
+% \meta{ltx options} & Any text here is passed directly into the
+% optional arguments (between the square brackets) of an
+% |\includegraphics| command.\\
+% \meta{fmt} & You can optionally specify a file extension here; Sage
+% will then try to save the graphics object to a file with extension
+% \emph{fmt}. If not specified, \ST\ will save to EPS and PDF files;
+% if saving to those formats does not work, \ST will save to a PNG file.\\
+% \meta{graphics obj} & A Sage object on which you can call |.save()|
+% with a graphics filename.\\
+% \meta{keyword args} & Any keyword arguments you put here will
+% all be put into the call to |.save()|.
+% \end{tabular}
+% \caption{Explanation of options for the \texttt{\bslash sageplot}
+% command.}
+% \label{t:sageplotopts}
+% \end{table}
+%
+% This setup allows you to control both the Sage side of things, and the
+% \LTX side. For instance, the command
+% \begin{quote}
+% |\sageplot[angle=30, width=5cm]{plot(sin(x), 0, pi), axes=False,|\\
+% |chocolate=True}|
+% \end{quote}
+% will run the following command in Sage:
+% \begin{quote}
+% |sage: plot(sin(x), 0, pi).save(filename=autogen, axes=False,|\\
+% |chocolate=True)|
+% \end{quote}
+% Then, in your \LTX file, the following command will be issued
+% automatically:
+% \begin{center}
+% |\includegraphics[angle=30, width=5cm]{autogen}|
+% \end{center}
+% You can specify a file format if you like. This must be the
+% \emph{second} optional argument, so you must use empty brackets if
+% you're not passing anything to |\includegraphics|:
+% \begin{center}
+% |\sageplot[][png]{plot(sin(x), x, 0, pi)}|
+% \end{center}
+% The filename is automatically generated, and unless you specify a
+% format, both EPS and PDF files will be generated. This allows you to
+% freely switch between using, say, a DVI viewer (many of which have
+% support for automatic reloading, source specials and make the writing
+% process easier) and creating PDFs for posting on the web or emailing
+% to colleagues. \ST will fall back to creating a PNG file for any
+% graphics object that cannot be saved as an EPS or PDF file; this is
+% useful for three dimensional plot objects, which currently cannot be
+% saved as EPS or PDF files.
+%
+% If you ask for, say, a PNG file (or if one is automatically generated
+% for you as described above), keep in mind that ordinary |latex| and
+% DVI files have no support for PNG files; \ST detects this and will
+% warn you that it cannot find a suitable file if using
+% |latex|.\footnote{We use a typewriter font here to indicate the
+% executables which produce DVI and PDF files, respectively, as
+% opposed to ``\LTX'' which refers to the entire typesetting system.}
+% If you use |pdflatex|, there will be no problems because PDF files can
+% include PNG graphics.
+%
+% When \ST cannot find a graphics file, it inserts this into your
+% document:
+%
+% \begin{center}
+% \framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}
+% \end{center}
+%
+% \noindent That's supposed to resemble the image-not-found graphics
+% used by web browsers and use the traditional ``\textbf{??}'' that \LTX
+% uses to indicate missing references.
+%
+% You needn't worry about the filenames; they are automatically
+% generated and will be put into the directory
+% |sage-plots-for-filename.tex|. You can safely delete that directory
+% anytime; if \ST can't find the files, it will warn you to run Sage to
+% regenerate them.\\
+%
+% \noindent\warningbox{\textbf{WARNING!} When you run Sage on your
+% |.sage| file, all files in the
+% \texttt{sage-plots-for-\meta{filename}.tex} directory \emph{will be
+% deleted!} Do not put any files into that directory that you do not
+% want to get automatically deleted.}
+%
+% \paragraph{The epstopdf option} One of the graphics-related options
+% supported by \ST is |epstopdf|. This option causes \ST to use the
+% |epstopdf| command to convert EPS files into PDF files. Like with the
+% |imagemagick| option, it doesn't check to see if the |epstopdf|
+% command exists or add options: it just runs the command. This option
+% was motivated by a bug in the matplotlib PDF backend which caused it
+% to create invalid PDFs. Ideally, this option should never be
+% necessary; if you do need to use it, file a bug!
+%
+% This option will eventually be removed, so do not use it.
+%
+% \subsubsection{3D plotting}
+%
+% Right now there is, to put it nicely, a bit of tension between the
+% sort of graphics formats supported by |latex| and |pdflatex|, and the
+% graphics formats supported by Sage's 3D plotting systems. \LTX is
+% happiest, and produces the best output, with EPS and PDF files, which
+% are vector formats. Tachyon, Sage's 3D plotting system, produces
+% bitmap formats like BMP and PNG.
+%
+% \ST will automatically fall back to saving plot objects in PNG format
+% if saving to EPS and PDF fails, so it should automatically work with
+% 3D plot objects. However, since |latex| does not support PNGs, when
+% using 3D plotting (and therefore a bitmap format like PNG), \ST will
+% always issue a warning about incompatible graphics if you use |latex|,
+% provided you've processed the |.sage| file and the PNG file exists.
+% The only exception is if you're using the |imagemagick| option below.
+%
+% \paragraph{The imagemagick option} As a response to the above issue,
+% the \ST package has an |imagemagick| option. If you specify this
+% option in the preamble of your document with the usual
+% ``|\usepackage[imagemagick]{sagetex}|'', then when you are compiling
+% your document using |latex|, any |\sageplot| command which requests a
+% non-default format will cause the \ST Python script to convert the
+% resulting file to EPS using the Imagemagick |convert| utility. It does
+% this by executing ``|convert filename.EXT filename.eps|'' in a
+% subshell. It doesn't add any options, check to see if the |convert|
+% command exists or belongs to Imagemagick---it just runs the command.
+%
+% The resulting EPS files are not very high quality, but they will work.
+% This option is not intended to produce good graphics, but to allow you
+% to see your graphics when you use |latex| and DVI files while writing
+% your document.
+%
+% \subsubsection{But that's not good enough!}
+% \label{sec:notgoodenough}
+%
+% The |\sageplot| command tries to be both flexible and easy to use, but
+% if you are just not happy with it, you can always do things manually:
+% inside a |sagesilent| environment (see the next section) you could do
+% \begin{quote}
+% |your special commands|\\
+% |x = your graphics object|\\
+% |x.save(filename=myspecialfile.ext, options, etc)|
+% \end{quote}
+% and then, in your source file, do your own |\includegraphics| command.
+% The \ST package gives you full access to Sage and Python and doesn't
+% turn off anything in \LTX, so you can always do things manually.
+%
+% \subsection{Verbatim-like environments}
+% \label{sec:codeblockenv}
+%
+% The \ST package provides several environments for typesetting and
+% executing blocks of Sage code.\\
+%
+% \DescribeEnv{sageblock} Any text between |\begin{sageblock}| and
+% |\end{sageblock}| will be typeset into your file, and also written into
+% the |.sage| file for execution. This means you can do something like
+% this:
+% \begin{quote}
+% |\begin{sageblock}|\\
+% | var('x')|\\
+% | f(x) = sin(x) - 1|\\
+% | g(x) = log(x)|\\
+% | h(x) = diff(f(x) * g(x), x)|\\
+% |\end{sageblock}|
+% \end{quote}
+% and then anytime later write in your source file
+% \begin{quote}
+% |We have $h(2) = \sage{h(2)}$, where $h$ is the derivative of|\\
+% |the product of $f$ and $g$.|
+% \end{quote}
+% and the |\sage| call will get correctly replaced by $\sage{
+% diff((sin(x) - 1)*log(x), x)(x=1)}$. You can use any Sage or Python
+% commands inside a |sageblock|; all the commands get sent directly to
+% Sage.\\
+%
+% \iffalse meta-comment
+% Sadly, we can't use sageblock or similar environments in this file!
+% If you prefix the lines inside the environment with percent signs,
+% then those percent signs get written to your .sage file. If you
+% *don't* prefix the lines with percent signs, those lines get written
+% into the .sty or .py file. It's just too tricky to get docstrip and
+% the verbatim stuff to play nicely together. I'd have to redefine how
+% those environments work, and get them to strip off initial percents.
+% \fi
+%
+% \DescribeEnv{sagesilent} This environment is like |sageblock|, but it
+% does not typeset any of the code; it just writes it to the |.sage|
+% file. This is useful if you have to do some setup in Sage that is not
+% interesting or relevant to the document you are writing.\\
+%
+% \DescribeEnv{sageverbatim} This environment is the opposite of the one
+% above: whatever you type will be typeset, but not written into the
+% |.sage| file. This allows you to typeset psuedocode, code that will
+% fail, or take too much time to execute, or whatever.\\
+%
+% \DescribeEnv{comment} Logically, we now need an environment that
+% neither typesets nor executes your Sage code\ldots but the |verbatim|
+% package, which is always loaded when using \ST, provides such an
+% environment: |comment|. Another way to do this is to put stuff between
+% |\iffalse| and |\fi|.\\
+%
+% \DescribeMacro{\sagetexindent} There is one final bit to our
+% verbatim-like environments: the indentation. The \ST package defines a
+% length |\sagetexindent|, which controls how much the Sage code is
+% indented when typeset. You can change this length however you like
+% with |\setlength|: do |\setlength{\sagetexindent}{6ex}| or whatever.
+%
+% \DescribeEnv{sageexample} This environment allow you to include
+% doctest-like snippets in your document that will be nicely typeset.
+% For example,
+% \begin{quote}
+% |\begin{sageexample}|\\
+% | sage: 1+1|\\
+% | 2|\\
+% | sage: factor(x^2 + 2*x + 1)|\\
+% | (x + 1)^2|\\
+% |\end{sageexample}|
+% \end{quote}
+% in your document will be typeset with the Sage inputs in the usual
+% fixed-width font, and the outputs will be typeset as if given to a
+% |\sage| macro, as you see below:
+\begin{sageexample}
+ sage: 1+1
+ 2
+ sage: factor(x^2 + 2*x + 1)
+ (x + 1)^2
+\end{sageexample}
+% When typesetting the document, there is no test of the
+% validity of the outputs (that is, typesetting with a typical
+% \LTX-Sage-\LTX cycle does not do doctesting), but when using the
+% |sageexample| environment, an extra file named
+% ``|myfile_doctest.sage|'' is created with the contents of all those
+% environments; it is formatted so that Sage can doctest that file. You
+% should be able to doctest your document with ``|sage -t myfile_doctest.sage|''.
+% (This does not always work; if this fails for you, please contact
+% the sage-support group.)
+%
+% If you would like to see both the original text input and the
+% typeset output, you can issue
+% |\renewcommand{\sageexampleincludetextoutput}{True}| in your
+% document. You can do the same thing with ``False'' to later turn it
+% off. In the above example, this would cause \ST to output both
+% |(x + 1)^2| and $(x + 1)^{2}$ in your typeset document.
+%
+% Just as in doctests, multiline statements are acceptable. The only
+% limitation is that triple-quoted strings delimited by |"""| cannot be
+% used in a |sageexample| environment; instead, you can use
+% triple-quoted strings delimited by |'''|.
+%
+% See the |example.tex| file for many examples and more explanation.
+%
+% The initial implementation of this environment is due to Nicolas M.
+% Thi\'ery.\\
+%
+% \DescribeEnv{sagecommandline} This environment is similar to the
+% sageexample environment in that it allow you to use \ST as a
+% pretty-printing command line, or to include doctest-like snippets in
+% your document. The difference is that the output is typeset as text,
+% much like running Sage on the command line, using the
+% |lstlisting| environment. In particular, this environment
+% provides Python syntax highlighting and line numbers. For example,
+% \begin{quote}
+% |\begin{sagecommandline}|\\
+% | sage: 1+1|\\
+% | 2|\\
+% | sage: factor(x^2 + 2*x + 1)|\\
+% |\end{sagecommandline}|
+% \end{quote}
+% becomes
+\begin{sagecommandline}
+ sage: 1+1
+ 2
+ sage: factor(x^2 + 2*x + 1)
+\end{sagecommandline}
+% You have a choice of either explicitly providing the Sage output or
+% leaving it up to the computer to fill in the blanks. Above, the output
+% for $1+1$ was provided, but the output for the |factor()| command
+% wasn't. Moreover, any Sage comment that starts with a ``at'' sign is
+% escaped to \LTX. In particular, you can use |\label| to mark line
+% numbers in order to |\ref|erence and |\pageref|erence them as usual.
+% See the example file to see this mechanism in action.
+%
+% If you prefer to typeset the output in \LTX, you can set
+% \begin{quote}
+% |\renewcommand{\sagecommandlinetextoutput}{False}|
+% \end{quote}
+% which produces
+\renewcommand{\sagecommandlinetextoutput}{False}
+\begin{sagecommandline}
+ sage: var('a, b, c');
+ sage: ( a*x^2+b*x+c ).solve(x)
+\end{sagecommandline}
+\renewcommand{\sagecommandlinetextoutput}{True}
+% The Sage input and output is typeset using the |listings| package
+% with the styles |SageInput| and |SageOutput|, respectively. If you
+% don't like the defaults you can change them. It is recommended to
+% derive from |DefaultSageInput| and |DefaultSageOutput|, for example
+% \begin{quote}
+% |\lstdefinestyle{SageInput}{style=DefaultSageInput,|\\
+% | basicstyle={\color{red}}}|\\
+% |\lstdefinestyle{SageOutput}{style=DefaultSageOutput,|\\
+% | basicstyle={\color{green}}}|
+% \end{quote}
+% makes things overly colorful:
+\lstdefinestyle{SageInput}{style=DefaultSageInput,basicstyle={\color{red}}}
+\lstdefinestyle{SageOutput}{style=DefaultSageOutput,basicstyle={\color{green}}}
+\begin{sagecommandline}
+ sage: pi.n(100)
+\end{sagecommandline}
+\lstdefinestyle{SageInput}{style=DefaultSageInput}
+\lstdefinestyle{SageOutput}{style=DefaultSageOutput}
+%
+% \subsection{Pausing \ST}
+% \label{sec:pausing-st-usage}
+%
+% Sometimes when you are writing a document, you may wish to temporarily
+% turn off or pause \ST to concentrate more on your document than on the
+% Sage computations, or to simply have your document typeset faster. You
+% can do this with the following commands.
+%
+% \DescribeMacro{\sagetexpause} \DescribeMacro{\sagetexunpause} Use
+% these macros to ``pause'' and ``unpause'' \ST. After issuing this
+% macro, \ST will simply skip over the corresponding calculations.
+% Anywhere a |\sage| macro is used while paused, you will simply see
+% \sagetexpause ``\sage{dummy call to sage to illustrate
+% pausing}'', and anywhere a |\sageplot| macro is used, you will see:\\
+%
+% \noindent
+% \sageplot{dummy call to sageplot to illustrate pausing}
+% \sagetexunpause\\
+%
+% \noindent Anything in the verbatim-like environments of
+% \autoref{sec:codeblockenv} will be typeset or not as usual, but none
+% of the Sage code will be executed.
+%
+% Obviously, you use |\sagetexunpause| to unpause \ST and return to the
+% usual state of affairs. Both commands are idempotent; issuing them
+% twice or more in a row is the same as issuing them once. This means
+% you don't need to precisely match pause and unpause commands: once
+% paused, \ST stays paused until it sees |\sagetexunpause| and
+% vice versa.
+%
+% \section{Other notes}
+%
+% Here are some other notes on using \ST.
+%
+% \subsection{Using the \texttt{sage} macro inside align (and similar) environments}
+% \label{sec:sage-inside-align}
+%
+% The |align|, |align*|, and some other ``fancy'' math environments in
+% the |amsmath| package do some special processing---in particular, they
+% evaluate everything inside twice. This means that if you use |\sage|
+% or |\sagestr| inside such an environment, it will be evaluated twice,
+% and its argument will be put into the generated |.sage| file
+% twice---and if that argument has side effects, those side effects will
+% be executed twice! Doing something such as popping an element from a
+% list will actually pop \emph{two} elements and typeset the second. The
+% solution is to do any processing that has side effects before the
+% |align| environment (in a |sagesilent| environment, say) and to give
+% |\sage| or |\sagestr| an argument with no side effects.
+%
+% Thanks to Bruno Le Floch for reporting this.
+%
+%
+% \subsection{Using \texttt{sage} inside \texttt{caption}}
+% \label{sec:sage-inside-caption}
+%
+% If you want to use |\sage| inside the |\caption| for a figure, you'll
+% need to prepend it with |\protect|, because (in \TeX{} parlance) the
+% |\sage| macro is not ``robust''. For example:
+% \begin{quote}
+% |\caption{this figure illustrates why $2 + 2 = \protect\sage{2 + 2}$.}|
+% \end{quote}
+%
+% \subsection{Using \ST with TeXworks}
+%
+% On Linux and OS X, it's easy to get the
+% \href{https://www.tug.org/texworks/}{\TeX works} editor to work with
+% \ST. You will define a new ``typesetting engine'' following
+% \href{https://github.com/TeXworks/texworks/wiki/AdvancedTypesettingTools#defining-new-typesetting-tools}{these
+% directions}. First, in some convenient location, create a shell
+% script with these contents:
+% \begin{quote}
+% |#!/bin/sh|\\
+% |pdflatex $1.tex|\\
+% |sage $1.sagetex.sage|\\
+% |pdflatex $1.tex|
+% \end{quote}
+% Name it \texttt{sagetex-engine} or something similar. Then, in the
+% Edit $\to$ Preferences menu, click the $+$ button in the Processing
+% tools section. Give the new tool a good name, like ``SageTeX''. In the
+% Program space, browse to your script. Click the $+$ for the Arguments
+% and type \texttt{\$basename} in the resulting box.
+%
+% Then, back in your document, you should be able to select SageTex in
+% the typesetting engine dropdown menu and then typeset.
+%
+% (You can also replace "|sage|" above with the
+% |run-sagetex-if-necessary| script---see
+% \autoref{sec:run-sagetex-if-necessary}.)
+%
+% \subsection{Using Beamer}
+%
+% The \textsc{beamer} package does not play nicely with verbatim-like
+% environments unless you ask it to. To use code block environments in a
+% \textsc{beamer} presentation, do:
+% \begin{quote}
+% |\begin{frame}[fragile]|\\
+% |\begin{sageblock}|\\
+% |# sage stuff|\\
+% |# more stuff \end{sageblock}|\\
+% |\end{frame}|\\
+% \end{quote}
+% For some reason, \textsc{beamer} inserts an extra line break at the
+% end of the environment; if you put the |\end{sageblock}| on the same
+% line as the last line of your code, it works properly. See section
+% 12.9, ``Verbatim and Fragile Text'', in the \textsc{beamer} manual.
+% (Thanks to Franco Saliola for reporting this.)
+%
+% \textsc{beamer}'s overlays and |\sageplot| also need some help in
+% order to work together, as discussed in
+% \href{http://groups.google.com/group/sage-support/browse_thread/thread/9a0a2d60ef1126fd}{this
+% sage-support thread}. If you want a plot to only appear in a certain
+% overlay, you might try something like this in your frame:
+% \begin{quote}
+% |\begin{itemize}|\\
+% |\item item 1|\\
+% |\item item 2|\\
+% |\item \sageplot[height=4cm][png]{(plot_slope_field(2*x,(x,-4,4),|\\
+% | (y,-4,4))+(x^2-2).plot(-2,2))}|\\
+% |\end{itemize}|\\
+% \end{quote}
+% but the plot will appear on all the overlays, instead of the third.
+% The solution is to use the |\visible| macro:
+% \begin{quote}
+% |\begin{itemize}|\\
+% |\item item 1|\\
+% |\item item 2|\\
+% |\item \visible<3->{\sageplot[height=4cm][png]{(plot_slope_field(2*x,(x,-4,4),|\\
+% | (y,-4,4))+(x^2-2).plot(-2,2))}}|\\
+% |\end{itemize}|\\
+% \end{quote}
+% Then the plot will only appear on the third (and later) overlays.
+% (Thanks to Robert Ma{\v r}{\'\i}k for this solution.)
+%
+% \subsection{Using the \texttt{rccol} package}
+%
+% If you are trying to use the |\sage| macro inside a table when using
+% the
+% \href{http://www.ctan.org/tex-archive/macros/latex/contrib/rccol/}{\texttt{rccol}}
+% package, you need to use an extra pair of braces or typesetting will
+% fail. That is, you need to do something like this:
+% \begin{quote}
+% | abc & {\sage{foo.n()}} & {\sage{bar}} \\|
+% \end{quote}
+% with each ``|\sage{}|'' enclosed in an extra |{}|. Thanks to Sette
+% Diop for reporting this.
+%
+% \subsection{Plotting from Mathematica, Maple, etc.}
+%
+% Sage can use Mathematica, Maple, and friends and can tell them to do
+% plotting, but since it cannot get those plots into a Sage graphics
+% object, you cannot use |\sageplot| to use such graphics. You'll need
+% to use the method described in ``But that's not good enough!''
+% (\autoref{sec:notgoodenough}) with some additional bits to get the
+% directory right---otherwise your file will get saved to someplace in a
+% hidden directory.
+%
+% For Mathematica, you can do something like this inside a |sagesilent|
+% or |sageblock| environment:
+% \begin{quote}
+% |mathematica('myplot = commands to make your plot')|\\
+% |mathematica('Export["%s/graphicsfile.eps", myplot]' % os.getcwd())|
+% \end{quote}
+% then put |\includegraphics[opts]{graphicsfile}| in your file.
+%
+% For Maple, you'll need something like
+% \begin{quote}
+% |maple('plotsetup(ps, plotoutput=`%s/graphicsfile.eps`, \|\\
+% | plotoptions=`whatever`);' % os.getcwd())|\\
+% |maple('plot(function, x=1..whatever);')|
+% \end{quote}
+% and then |\includegraphics| as necessary.
+%
+% These interfaces, especially when plotting, can be finicky. The above
+% commands are just meant to be a starting point.
+%
+% \subsection{Sending \ST files to others who don't use Sage}
+% \label{sec:makestatic-usage}
+%
+% \subsubsection{The 21st century way}
+%
+% The SageMathCloud
+% (\href{http://cloud.sagemath.com}{\texttt{cloud.sagemath.com}}) service has
+% full support for \ST, is free to use, and has many fantastic
+% collaboration features. If you somehow want to collaborate on a
+% \ST-enabled \TeX document with a colleague, using SageMathCloud is one
+% of the best and easiest ways to do it. You and your collaborators
+% simply create an account, then make a project for your collaboration,
+% and add all the collaborators to the project. Then you can all enjoy
+% realtime collaborative editing, PDF previews, chat, and more.
+%
+% \subsubsection{The $N$th century way, for $N < 21$}
+%
+% Using anything other than SageMathCloud, |git|, or similar tools these
+% days seems pretty primitive. If emailing |.tex| files back and forth
+% seems perfectly reasonable to you, or if you have to send a file to a
+% journal, the easiest way is to simply include with your document the
+% following files:
+% \begin{enumerate}
+% \item |sagetex.sty|
+% \item the generated |.sout| and |.scmd| files
+% \item the \texttt{sage-plots-for-\meta{filename}.tex} directory and
+% its contents
+% \end{enumerate}
+% As long as |sagetex.sty| is available, your document can be typeset
+% using any reasonable \LTX system. Since it is very common to include
+% graphics files with a paper submission, this is a solution that should
+% always work. (In particular, it will work with arXiv submissions.)
+%
+% There is another option, and that is to use the |makestatic.py| script
+% included with \ST. This script has been unmaintained for some time and
+% likely won't work. If you want or need to use it and run into trouble,
+% email the
+% \href{https://groups.google.com/forum/#!forum/sage-support}{\texttt{sage-support}
+% group} and let us know.
+%
+% Use of the script is quite simple. Copy it and |sagetexparse.py| to
+% the directory with your document, and run
+% \begin{quote}
+% |python makestatic.py inputfile [outputfile]|
+% \end{quote}
+% where |inputfile| is your document. (You can also set the executable
+% bit of |makestatic.py| and use |./makestatic.py|.) This script needs
+% the \href{http://pyparsing.wikispaces.com}{pyparsing} module to be
+% installed.\footnote{If you don't have pyparsing installed, you can
+% simply copy the file
+% \texttt{\sageroot/local/lib/python/matplotlib/pyparsing.py} into
+% your directory.} You may optionally specify |outputfile|; if you do
+% so, the results will be written to that file. If the file exists, it
+% won't be overwritten unless you also specify the |-o| switch.
+%
+% You will need to run this after you've compiled your document and
+% run Sage on the |.sage| file. The script reads in the |.sout| file
+% and replaces all the calls to |\sage| and |\sageplot| with their
+% plain \LTX equivalent, and turns the |sageblock| and |sageverbatim|
+% environments into |verbatim| environments. Any |sagesilent|
+% environment is turned into a |comment| environment. Any
+% |sagecommandline| environment is turned into a |lstlisting|
+% environment, typesetting the relevant part of the |.scmd| file. The
+% resulting document should compile to something identical, or very
+% nearly so, to the original file.
+%
+% One large limitation of this script is that it can't change anything
+% while \ST is paused, since Sage doesn't compute anything for such
+% parts of your document. It also doesn't check to see if pause and
+% unpause commands are inside comments or verbatim environments. If
+% you're going to use |makestatic.py|, just remove all pause/unpause
+% statements.
+%
+% The parsing that |makestatic.py| does is pretty good, but not perfect.
+% Right now it doesn't support having a comma-separated list of
+% packages, so you can't have |\usepackage{sagetex, foo}|. You need to
+% have just |\usepackage{sagetex}|. (Along with package options; those
+% are handled correctly.) If you find other parsing errors, please let
+% me know.
+%
+% \subsection{Extracting the Sage code from a document}
+% \label{sec:extractsagecode}
+%
+% (This script has the same unmaintained-and-probably-doesn't-work
+% status as |makestatic.py|; see above.)
+%
+% This next script is probably not so useful, but having done the above,
+% this was pretty easy. The |extractsagecode.py| script does the
+% opposite of |makestatic.py|, in some sense: given a document, it
+% extracts all the Sage code and removes all the \LTX.
+%
+% Its usage is the same as |makestatic.py|.
+%
+% Note that the resulting file will almost certainly \emph{not} be a
+% runnable Sage script, since there might be \LTX commands in it, the
+% 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.
+%
+% \section{Using \ST without Sage installed}
+% \label{sec:remote-sagetex}
+%
+% (This script has the same unmaintained-and-probably-doesn't-work
+% status as |makestatic.py|; see above.)
+%
+% You may want to edit and typeset a \ST-ified file on a computer that
+% doesn't have Sage installed. How can you do that? We need to somehow
+% run Sage on the |.sage| file. The included script
+% \texttt{remote-sagetex.py} takes advantage of Sage's network
+% transparency and will use a remote server to do all the computations.
+% Anywhere in this manual where you are told to ``run Sage'', instead of
+% actually running Sage, you can run
+% \begin{center}
+% \texttt{python remote-sagetex.py filename.sage}
+% \end{center}
+% The script will ask you for a server, username, and password, then
+% process all your code and write a |.sout| file and graphics files
+% exactly as if you had used a local copy of Sage to process the |.sage|
+% script. (With some minor limitations and differences; see below.)
+%
+% One important point: \emph{the script requires Python 2.6}. It will
+% not work with earlier versions. (It will work with Python 3.0 or later
+% with some trivial changes.)
+%
+% You can provide the server, username and password with the
+% command-line switches |--server|, |--username|, and |--password|, or
+% you can put that information into a file and use the |--file| switch
+% to specify that file. The format of the file must be like the
+% following:
+% \begin{verbatim}
+ # hash mark at beginning of line marks a comment
+ server = "http://example.com:1234"
+ username = 'my_user_name'
+ password = 's33krit'\end{verbatim}
+% As you can see, it's really just like assigning a string to a variable
+% in Python. You can use single or double quotes and use hash marks to
+% start comments. You can't have comments on the same line as an
+% assignment, though. You can omit any of those pieces of information
+% information; the script will ask for anything it needs to know.
+% Information provided as a command line switch takes precedence over
+% anything found in the file.
+%
+% You can keep this file separate from your \LTX documents in a secure
+% location; for example, on a USB thumb drive or in an automatically
+% encrypted directory (like |~/Private| in Ubuntu). This makes it much
+% harder to accidentally upload your private login information to the
+% arXiv, put it on a website, send it to a colleague, or otherwise make
+% your private information public.
+%
+% \subsection{Limitations of \texttt{remote-sagetex.py}}
+% \label{sec:remote-sagetex-limitations}
+%
+% The |remote-sagetex.py| script has several limitations. It completely
+% ignores the |epstopdf| and |imagemagick| flags. The |epstopdf| flag is
+% not a big deal, since it was originally introduced to work around a
+% matplotlib bug which has since been fixed. Not having |imagemagick|
+% support means that you cannot automatically convert 3D graphics to eps
+% format; using |pdflatex| to make PDFs works around this issue.
+%
+%
+% \subsection{Other caveats}
+% \label{sec:remote-sagetex-caveats}
+%
+% Right now, the ``simple server API'' that |remote-sagetex.py| uses is
+% not terribly robust, and if you interrupt the script, it's possible to
+% leave an idle session running on the server. If many idle sessions
+% accumulate on the server, it can use up a lot of memory and cause the
+% server to be slow, unresponsive, or maybe even crash. For now, I
+% recommend that you only run the script manually. It's probably best to
+% not configure your \TeX{} editing environment to automatically run
+% |remote-sagetex.py| whenever you typeset your document, at least not
+% without showing you the output or alerting you about errors.
+%
+
+
+% \iffalse
+% Local Variables:
+% mode: doctex
+% TeX-master: t
+% End:
+% \fi
diff --git a/macros/latex/contrib/sagetex/sagetex.ins b/macros/latex/contrib/sagetex/sagetex.ins
new file mode 100644
index 0000000000..dd8dabb80a
--- /dev/null
+++ b/macros/latex/contrib/sagetex/sagetex.ins
@@ -0,0 +1,124 @@
+%% This is `sagetex.ins', part of the sagetex package.
+%%
+%% Copyright (C) 2008--2015 by Dan Drake <dr.dan.drake@gmail.com>
+%%
+%% This program is free software: you can redistribute it and/or modify
+%% it 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.
+%%
+%% This program is distributed in the hope that it will be useful, but
+%% WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%% General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/latex/sagetex}
+
+\declarepreamble\defaultpreamble
+
+This is a generated file. It is part of the SageTeX package.
+
+Copyright (C) 2008--2015 by Dan Drake <dr.dan.drake@gmail.com>
+
+This program is free software: you can redistribute it and/or modify it
+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.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+
+\endpreamble
+
+\generate{\file{sagetex.sty}{\from{sagetex.dtx}{latex}
+ \from{py-and-sty.dtx}{latex}}}
+
+
+\usedir{PYTHONLIBDIR}
+
+% Define a new preamble with #'s as comment characters for the Python
+% files. I hate copying the same text, but defining a "\boilerplate"
+% macro requires me to manually do \MetaPrefix\space and ^^J everywhere
+% and it's more annoying than this.
+
+\catcode`\#=12
+\def\hash{#}
+\catcode`\#=6
+
+\def\MetaPrefix{\hash\hash}
+\declarepreamble\pypreamble
+
+This is a generated file. It is part of the SageTeX package.
+
+Copyright (C) 2008--2015 by Dan Drake <dr.dan.drake@gmail.com>
+
+This program is free software: you can redistribute it and/or modify it
+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.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+
+\endpreamble
+\usepreamble\pypreamble
+\nopostamble
+
+\generate{\file{sagetex.py}{\from{sagetex.dtx}{python}
+ \from{py-and-sty.dtx}{python}}}
+\generate{\file{sagetexparse.py}{\from{scripts.dtx}{parsermod}}}
+
+
+\usedir{scripts/sagetex}
+
+% Now define a new preamble with the shebang line at the top.
+
+\def\envpypreamble{\hash!/usr/bin/env python^^J\pypreamble}
+\usepreamble\envpypreamble
+
+\generate{\file{run-sagetex-if-necessary.py}{\from{scripts.dtx}{ifnecessaryscript}}}
+\generate{\file{makestatic.py}{\from{scripts.dtx}{staticscript}}}
+\generate{\file{extractsagecode.py}{\from{scripts.dtx}{extractscript}}}
+\generate{\file{remote-sagetex.py}{\from{remote-sagetex.dtx}{remotesagetex}}}
+
+\obeyspaces
+\Msg{******************************************************************}
+\Msg{* *}
+\Msg{* To finish the installation, move the following files *}
+\Msg{* into directories searched by TeX and Sage, respectively: *}
+\Msg{* *}
+\Msg{* sagetex.sty *}
+\Msg{* sagetex.py *}
+\Msg{* *}
+\Msg{* See the documentation for complete installation details. *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file sagetex.dtx through *}
+\Msg{* LaTeX. To produce the change history, run *}
+\Msg{* *}
+\Msg{* makeindex -s gglo.ist -o sagetex.gls sagetex.glo *}
+\Msg{* *}
+\Msg{* and to get the regular index, do *}
+\Msg{* *}
+\Msg{* makeindex -s gind.ist -o sagetex.ind sagetex.idx *}
+\Msg{* *}
+\Msg{* Happy TeXing...and, uh, Saging? *}
+\Msg{* *}
+\Msg{******************************************************************}
+
+\endbatchfile
diff --git a/macros/latex/contrib/sagetex/sagetex.pdf b/macros/latex/contrib/sagetex/sagetex.pdf
new file mode 100644
index 0000000000..ac37a7258b
--- /dev/null
+++ b/macros/latex/contrib/sagetex/sagetex.pdf
Binary files differ
diff --git a/macros/latex/contrib/sagetex/scripts.dtx b/macros/latex/contrib/sagetex/scripts.dtx
new file mode 100644
index 0000000000..aec62a08cb
--- /dev/null
+++ b/macros/latex/contrib/sagetex/scripts.dtx
@@ -0,0 +1,520 @@
+% \section{Included Python scripts}
+% \label{sec:included-scripts}
+%
+% Here we describe the Python code for |run-sagetex-if-necessary|, and
+% also |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{run-sagetex-if-necessary}
+% \label{sec:run-sagetex-if-necessary}
+% \iffalse
+%<*ifnecessaryscript>
+% \fi
+%
+% When working on a document that uses \ST, running Sage every time you
+% typeset your document may take too long, especially since it often
+% won't be necessary. This script is a drop-in replacement for Sage:
+% instead of
+% \begin{center}
+% |sage document.sagetex.sage|
+% \end{center}
+% you can do
+% \begin{center}
+% |run-sagetex-if-necessary.py document.sagetex.sage|
+% \end{center}
+% and it will use the MD5 mechanism described in the |endofdoc| macro
+% (page~{\pageref{macro:endofdoc}). With this, you can set up your editor
+% (\TeX Shop, \TeX Works, etc) to typeset your document with a script
+% that does
+% \begin{quote}
+% |pdflatex $1|\\
+% |run-sagetex-if-necessary.py $1|
+% \end{quote}
+% which will only, of course, run Sage when necessary.
+% \begin{macrocode}
+
+# given a filename f, examines f.sagetex.sage and f.sagetex.sout and
+# runs Sage if necessary.
+
+import hashlib
+import sys
+import os
+import re
+import subprocess
+
+# CHANGE THIS AS APPROPRIATE
+path_to_sage = os.path.expanduser('~/bin/sage')
+# or try to auto-find it:
+# path_to_sage = subprocess.check_output(['which', 'sage']).strip()
+# or just tell me:
+# path_to_sage = '/usr/local/bin/sage'
+
+if sys.argv[1].endswith('.sagetex.sage'):
+ src = sys.argv[1][:-13]
+else:
+ src = os.path.splitext(sys.argv[1])[0]
+
+commented_out = r'^\s*%'
+usepackage = r'\usepackage{sagetex}'
+uses_sagetex = False
+
+# if it doesn't use sagetex, obviously running sage is unnecessary
+with open(src + '.tex') as texf:
+ for line in texf:
+ if not re.search(commented_out, line) and re.search(usepackage, line):
+ uses_sagetex = True
+ break
+
+if not uses_sagetex:
+ print(src + ".tex doesn't seem to use SageTeX, exiting.")
+ sys.exit(0)
+
+# if something goes wrong, assume we need to run Sage
+run_sage = True
+ ignore = r"^( _st_.goboom|print('SageT| ?_st_.current_tex_line))"
+
+try:
+ with open(src + '.sagetex.sage', 'r') as sagef:
+ h = hashlib.md5()
+ for line in sagef:
+ if not re.search(ignore, line):
+ h.update(bytearray(line,'utf8'))
+except IOError:
+ print('{0}.sagetex.sage not found, I think you need to typeset {0}.tex first.'.format(src))
+ sys.exit(1)
+
+try:
+ with open(src + '.sagetex.sout', 'r') as outf:
+ for line in outf:
+ m = re.match('%([0-9a-f]+)% md5sum', line)
+ if m:
+ print('computed md5:', h.hexdigest())
+ print('sagetex.sout md5:', m.group(1))
+ if h.hexdigest() == m.group(1):
+ run_sage = False
+ break
+except IOError:
+ pass
+
+if run_sage:
+ print('Need to run Sage on {0}.'.format(src))
+ sys.exit(subprocess.call([path_to_sage, src + '.sagetex.sage']))
+else:
+ print('Not necessary to run Sage on {0}.'.format(src))
+% \end{macrocode}
+%
+% \subsection{makestatic.py}
+% \label{sec:makestatic}
+% \iffalse
+%</ifnecessaryscript>
+%<*staticscript>
+% \fi
+%
+% Now the |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\n%% replaced with plain LaTeX. Processed %s.\n" % 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}
+% \changes{v2.2}{2009/06/17}{Update parser module to handle pause/unpause}
+%
+% 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|, |\sageplot|, and pause/unpause calls:
+% \begin{macrocode}
+sagemacroparser = r'\sage' + curlybrackets('code')
+sageplotparser = (r'\sageplot'
+ + Optional(squarebrackets)('opts')
+ + Optional(squarebrackets)('format')
+ + curlybrackets('code'))
+sagetexpause = Literal(r'\sagetexpause')
+sagetexunpause = Literal(r'\sagetexunpause')
+% \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
+% list. 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 = (r'\newlabel{@sageinline'
+ + Word(nums)('num')
+ + '}{'
+ + curlybrackets('result')
+ + '{}{}{}{}}')
+% \end{macrocode}
+% We tell it to ignore comments, and hook up the list-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 {}; exiting. Does your .sout file exist?'.format(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.append(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 + '.sagetex.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 = (r'\usepackage'
+ + Optional(squarebrackets)
+ + '{sagetex}')
+ usepackage.setParseAction(replaceWith(r"""% "\usepackage{sagetex}" line was here:
+\RequirePackage{verbatim}
+\RequirePackage{graphicx}
+\newcommand{\sagetexpause}{\relax}
+\newcommand{\sagetexunpause}{\relax}"""))
+% \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(r'\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(r'\begin{verbatim}' + SkipTo(r'\end{verbatim}'))
+ doit.ignore(r'\begin{comment}' + SkipTo(r'\end{comment}'))
+ doit.ignore(r'\sagetexpause' + SkipTo(r'\sagetexunpause'))
+% \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 = r'[width=.75\textwidth]'
+ else:
+ opts = t.opts[0]
+ return (r'\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}
+ env_names = oneOf('sageblock sageverbatim sagesilent')
+ senv = r'\begin{' + env_names('env') + '}' + SkipTo(
+ r'\end{' + matchPreviousExpr(env_names) + '}')('code')
+ senv.leaveWhitespace()
+ senv.setParseAction(self.envout)
+
+ spause = sagetexpause
+ spause.setParseAction(self.pause)
+
+ sunpause = sagetexunpause
+ sunpause.setParseAction(self.unpause)
+
+ doit = smacro | splot | senv | spause | sunpause
+
+ str = ''.join(open(fn + '.tex', 'r').readlines())
+ self.result = ''
+
+ doit.transformString(str)
+
+ def macroout(self, s, l, t):
+ self.result += '# \\sage{} from line %s\n' % lineno(l, s)
+ self.result += t.code[1:-1] + '\n\n'
+
+ def plotout(self, s, l, t):
+ self.result += '# \\sageplot{} from line %s:\n' % lineno(l, s)
+ if t.format is not '':
+ self.result += '# format: %s' % t.format[0][1:-1] + '\n'
+ self.result += t.code[1:-1] + '\n\n'
+
+ def envout(self, s, l, t):
+ self.result += '# %s environment from line %s:' % (t.env,
+ lineno(l, s))
+ self.result += t.code[0] + '\n'
+
+ def pause(self, s, l, t):
+ self.result += ('# SageTeX (probably) paused on input line %s.\n\n' %
+ (lineno(l, s)))
+
+ def unpause(self, s, l, t):
+ self.result += ('# SageTeX (probably) unpaused on input line %s.\n\n' %
+ (lineno(l, s)))
+% \end{macrocode}
+% \end{macro}
+
+% \endinput
+%</parsermod>
+% Local Variables:
+% mode: doctex
+% TeX-master: "sagetex"
+% End:
diff --git a/macros/latex/contrib/sagetex/setup.py b/macros/latex/contrib/sagetex/setup.py
new file mode 100644
index 0000000000..44631f6926
--- /dev/null
+++ b/macros/latex/contrib/sagetex/setup.py
@@ -0,0 +1,32 @@
+from distutils.core import setup
+setup(name='sagetex',
+ description='Embed Sage code and plots into LaTeX',
+ long_description="""The SageTeX package allows you to embed code,
+ results of computations, and plots from the Sage mathematics
+ software suite (http://sagemath.org) into LaTeX documents.""",
+ version='3.2',
+ author='Dan Drake',
+ author_email='dr.dan.drake@gmail.com',
+ maintainer='SageMath developers',
+ maintainer_email='sage-devel@googlegroups.com',
+ url='https://github.com/sagemath/sagetex',
+ license='GPLv2+',
+ py_modules=['sagetex'],
+ data_files = [('share/texmf/tex/latex/sagetex',
+ ['example.tex',
+ 'CONTRIBUTORS',
+ 'extractsagecode.py',
+ 'run-sagetex-if-necessary.py',
+ 'makestatic.py',
+ 'scripts.dtx',
+ 'remote-sagetex.dtx',
+ 'remote-sagetex.py',
+ 'py-and-sty.dtx',
+ 'sagetex.dtx',
+ 'sagetex.ins',
+ 'sagetexparse.py',
+ 'sagetex.sty']),
+ ('share/doc/sagetex', [
+ 'example.tex',
+ 'sagetex.pdf',
+ 'example.pdf'])])