diff options
author | Karl Berry <karl@freefriends.org> | 2008-03-14 00:26:22 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2008-03-14 00:26:22 +0000 |
commit | 8df6f8b096486d3886fc2a42ba79a6f5a4c587f7 (patch) | |
tree | 6ff8b7ceae6c40b7db55ed005ba81e49ecd490ad /Master/texmf-dist/source/latex | |
parent | 3d96fa2455c0dbac611ab90f9ae59854fb40d3d9 (diff) |
new latex package sagetex (12mar08)
git-svn-id: svn://tug.org/texlive/trunk@6962 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex')
-rw-r--r-- | Master/texmf-dist/source/latex/sagetex/sagetexpackage.dtx | 1339 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/sagetex/sagetexpackage.ins | 93 |
2 files changed, 1432 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/sagetex/sagetexpackage.dtx b/Master/texmf-dist/source/latex/sagetex/sagetexpackage.dtx new file mode 100644 index 00000000000..95be02d58d0 --- /dev/null +++ b/Master/texmf-dist/source/latex/sagetex/sagetexpackage.dtx @@ -0,0 +1,1339 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008 by Dan Drake <ddrake@member.ams.org> +% ------------------------------------------------------- +% +% See the "Copying and licenses" section for the terms under which this +% source code and documentation may be modified and distributed. +% +% This package is not licensed under the LPPL, but it seems reasonable +% to say: +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Dan Drake. +% +% This work consists of the files sagetexpackage.dtx, +% sagetexpackage.ins, example.tex, and the derived files sagetex.sty +% and sagetex.py. +% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{sagetexpackage.dtx} +%</driver> +%<latex>\NeedsTeXFormat{LaTeX2e} +%<latex>\ProvidesPackage{sagetex} +%<*latex> + [2008/03/12 v1.4 embedding Sage into LaTeX documents] +%</latex> +%<*driver> +\documentclass{ltxdoc} +\usepackage{sagetex} +\usepackage{xspace} +\usepackage{tikz} +\usepackage{hyperref} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{sagetexpackage.dtx} + \PrintChanges + \PrintIndex +\end{document} +%</driver> +% \fi +% +% \CheckSum{0} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \changes{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} +% +% \GetFileInfo{sagetexpackage.dtx} +% +% \DoNotIndex{\newcommand,\newenvironment,\the} +% +% \newcommand{\ST}{\textsf{sagetex}\xspace} +% \iffalse +% so I don't have to put \ or {} after \LaTeX: +% \fi +% \newcommand{\LTX}{\LaTeX\xspace} +% +% \iffalse +% For some reason, getting a blackslash in a typewriter font to print +% inside an fbox is really hard. Verbatim stuff doesn't work because +% it's fragile. This code works; it's copied out of Scott Pakin's +% dtxtut.tex. +% +% There is \textbackslash but I don't like how that looks. +% \fi +% {\catcode`\|=0 \catcode`\\=12 +% |gdef|bslash{\}} +% +% \title{The \ST{} package\thanks{This document +% corresponds to \textsf{sagetex}~\fileversion, dated \filedate.}} +% \author{Dan Drake (\texttt{ddrake@member.ams.org}) and others} +% +% \maketitle +% +% \section{Introduction} +% +% Why should the Haskell 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. (Well, 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. +% +% 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*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 $\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{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{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$.) +% +% Till Tantau has some good commentary on the use of graphics in +% \href{http://www.ctan.org/tex-archive/graphics/pgf/}{section 6 of the +% \textsc{pgf} manual}. 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{s:usage}, we will see what what we can do with \ST. +% +% +% \section{Installation} +% +% The simplest way to ``install'' \ST is to copy the files +% |sagetex.sty| and |sagetex.py| into the same directory +% as your document. This will always work, as \LTX and Python search the +% current directory for files. It is also convenient for zipping up a +% directory to send to a colleague who is not yet enlightened enough to +% be using \ST. +% +% Rather than make lots of copies of those files, you can keep them in +% one place and update the TEXINPUTS and PYTHONPATH environment +% variables appropriately. +% +% Perhaps the best solution is to put the files into a directory +% searched by \TeX{} and friends, and then edit the |sagetex.sty| file +% so that the |.sage| files we generate update Python's path +% appropriately---look for ``Python path'' in |sagetex.sty|. This is +% suitable for a system-wide installation, or if you are the kind of +% person who keeps a |texmf| tree in your home directory. +% +% +% \section{Usage} \label{s:usage} +% +% Let's begin with a rough description of how \ST works. Naturally the +% very first step is to put |\usepackage{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. 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| file. That file contains \LTX code which, when you run \LTX +% on your source file again, will pull in all the results of Sage's +% computation. +% +% 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} +% +% \subsection{Inline Sage} +% +% \DescribeMacro{\sage} +% \fbox{\texttt{\bslash sage}\marg{Sage code}} +% +% \noindent 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 plus foo is|\\ +% |$\sage{factor(foo + \thepage)}$|. +% \end{quote} +% Here, I'll do just that right now: the prime factorization of the +% current page plus $12$ is $\sage{factor(\thepage + 12)}$. +% +% 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{\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{s:codeblockenv} isn't necessary; a literal +% ``\percent'' inside such an environment will get written, uh, verbatim +% to the |.sage| file. +% +% \subsection{Graphics and plotting} +% +% \noindent \DescribeMacro{\sageplot} +% \fbox{\texttt{\bslash sageplot}\oarg{ltx opts}\oarg{fmt}\{\meta{graphics +% obj}, \meta{keyword args}\}} +% +% \noindent 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. If not specified, +% ``|width=.75\textwidth|'' will be used.\\ +% \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.\\ +% \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. +% +% If you ask for, say, a PNG file, keep in mind that ordinary |latex| +% and DVI files have no support for DVI files; \ST detects this and will +% warn you that it cannot find a suitable file if using |latex|. If you +% use |pdflatex|, there will be no problems because PDF files can +% include PNG graphics. +% +% When \ST cannot find a graphics file, it inserts this into your +% document: +% +% \begin{center} +% \framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}} +% \end{center} +% +% \noindent That's supposed to resemble the image-not-found graphics +% used by web browsers and use the traditional ``\textbf{??}'' that \LTX +% uses to indicate missing references. +% +% You needn't worry about the filenames; they are automatically +% generated and will be put into the directory +% |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\fbox{\parbox{\textwidth}{\textbf{WARNING!} When you run Sage +% on your |.sage| file, all files in the +% \texttt{sage-plots-for-filename.tex} directory \emph{will be deleted!} +% Do not put any files into that directory that you do not want to get +% automatically deleted.}} +% +% \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.\footnote{We +% use a typewriter font here to indicate the binaries which produce DVI +% and PDF files, respectively, as opposed to ``\LTX'' which refers to +% the entire typesetting system.} \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. +% +% Because of this, when producing 3D plots with |\sageplot|, +% \emph{you must specify a file format}. The PNG format is compressed +% and lossless and is by far the best choice, so use that whenever +% possible. (Right now, it is always possible.) If you do not specify a +% file format, or specify one that Tachyon does not understand, it will +% produce files in the Targa format with an incorrect extension and \LTX +% (both |latex| and |pdflatex|) will be profoundly confused. Don't do +% that. +% +% Since |latex| does not support PNGs, when using 3D plotting (and +% therefore a bitmap format like PNG), \ST will \emph{always} issue a +% warning about incompatible graphics if you use |latex|, provided +% you've processed the |.sage| file and the PNG file exists. (Running +% |pdflatex| on the same file will work, since PDF files can include PNG +% files.) +% +% \paragraph{The imagemagick option} As a response to the above issue, +% the \ST package has one option: |imagemagick|. 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. +% +% \paragraph{But that's not good enough!} \label{s: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{s:codeblockenv} +% +% The \ST package provides several environments for typesetting and +% executing 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 = sin(x) - 1|\\ +% | g = log(x)|\\ +% | h = 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)(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. +% +% +% \section{Other notes} +% +% Here are some other notes on using \ST. +% +% \paragraph{Using Beamer} The \textsc{beamer} package does not play +% nicely with verbatim-like environments. To use code block environments +% in a \textsc{beamer} presentation, do: +% \begin{quote} +% |\begin{frame}[fragile]|\\ +% |\begin{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. +% +% Thanks to Franco Saliola for reporting this. +% +% \paragraph{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!'' +% (\hyperref[s:notgoodenough]{page~\pageref*{s: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('plot = commands to make your plot')|\\ +% |mathematica('Export["%s/graphicsfile.eps", plot]' % 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. +% +% +% \StopEventually{} +% +% \section{Implementation} +% +% There are two pieces to this package: a \LTX style file, and a +% Python module. They are mutually interdependent, so it makes sense to +% document them both here. +% +% \subsection{The style file} +% +% \iffalse +% tell docstrip to put code into the .sty file +%<*latex> +% \fi +% +% All macros and counters intended for use internal to this package +% begin with ``|ST@|''. +% +% Let's begin by loading some packages. The key bits of |sageblock| and +% friends are stol---um, adapted from the |verbatim| package manual. So +% grab the |verbatim| package. +% \begin{macrocode} +\RequirePackage{verbatim} +% \end{macrocode} +% Unsurprisingly, the |\sageplot| command works poorly without graphics +% support. +% \begin{macrocode} +\RequirePackage{graphicx} +% \end{macrocode} +% The |makecmds| package gives us a |\provideenvironment| which we need, +% and we use |ifpdf| and |ifthen| in |\sageplot| so we know what kind of +% files to look for. +% \begin{macrocode} +\RequirePackage{makecmds} +\RequirePackage{ifpdf} +\RequirePackage{ifthen} +% \end{macrocode} +% +% Next set up the counters and the default indent. +% \begin{macrocode} +\newcounter{ST@inline} +\newcounter{ST@plot} +\setcounter{ST@inline}{0} +\setcounter{ST@plot}{0} +\newlength{\sagetexindent} +\setlength{\sagetexindent}{5ex} +% \end{macrocode} +% +% \begin{macro}{\ST@epsim} +% By default, we don't use ImageMagick to create EPS files when a +% non-default format is specified. +% \begin{macrocode} +\newcommand{\ST@epsim}{False} +% \end{macrocode} +% The expansion of that macro gets put into a Python function call, so +% it works to have it be one of the strings ``|True|'' or ``|False|''. +% \end{macro} +% +% Declare the |imagemagick| option and process it: +% \begin{macrocode} +\DeclareOption{imagemagick}{\renewcommand{\ST@epsim}{True}} +\ProcessOptions\relax +% \end{macrocode} +% The |\relax| is a little incantation suggested by the ``\LaTeXe{} for +% class and package writers'' manual, section 4.7. +% +% It's time to deal with files. Open the |.sage| file: +% \begin{macrocode} +\newwrite\ST@sf +\immediate\openout\ST@sf=\jobname.sage +% \end{macrocode} +% +% \begin{macro}{\ST@wsf} +% We will write a lot of stuff to that file, so make a convenient +% abbreviation, then use it to put the initial commands into the |.sage| +% file. If you know what directory |sagetex.py| will be kept in, delete +% the |\iffalse| and |\fi| lines in the generated style file +% (\emph{don't} do it in the |.dtx| file) and change the directory +% appropriately. This is useful if you have a |texmf| tree in your home +% directory or are installing \ST system-wide; then you don't need to +% copy |sagetex.py| into the same directory as your document. +% \begin{macrocode} +\newcommand{\ST@wsf}[1]{\immediate\write\ST@sf{#1}} +\iffalse +%% To get .sage files to automatically change the Python path to find +%% sagetex.py, delete the \iffalse and \fi lines surrounding this and +%% change the directory below to where sagetex.py can be found. +\ST@wsf{import sys} +\ST@wsf{sys.path.insert(0, 'directory with sagetex.py')} +\fi +\ST@wsf{import sagetex} +\ST@wsf{sagetex.openout('\jobname')} +% \end{macrocode} +% \end{macro} +% Pull in the |.sout| file if it exists, or do nothing if it doesn't. I +% suppose we could do this inside an |AtBeginDocument| but I don't see +% any particular reason to do that. It will work whenever we load it. +% \begin{macrocode} +\InputIfFileExists{\jobname.sout}{}{} +% \end{macrocode} +% +% Now let's define the cool stuff. +% +% \begin{macro}{\sage} +% This macro combines |\ref|, |\label|, and Sage all at once. First, we +% use Sage to get a \LTX representation of whatever you give this +% function. The Sage script writes a |\newlabel| line into the |.sout| +% file, and we read the output using the |\ref| command. Usually, |\ref| +% pulls in a section or theorem number, but it will pull in arbitrary +% text just as well. +% +% The first thing it does it write its argument into the |.sage| file, +% along with a counter so we can produce a unique label. We wrap a +% try/except around the function call so that we can provide a more +% helpful error message in case something goes wrong. (In particular, we +% can tell the user which line of the |.tex| file contains the offending +% code.) +% \begin{macrocode} +\newcommand{\sage}[1]{% +\ST@wsf{try:}% +\ST@wsf{ sagetex.inline(\theST@inline, #1)}% +\ST@wsf{except:}% +\ST@wsf{ sagetex.goboom(\the\inputlineno)}% +% \end{macrocode} +% Our use of |\newlabel| and |\ref| seems awfully clever until you load +% the |hyperref| package, which gleefully tries to hyperlink the hell +% out of everything. This is great until it hits one of our special +% |\newlabel|s and gets deeply confused. Fortunately the |hyperref| +% folks are willing to accomodate people like us, and give us a +% |NoHyper| environment. +% \begin{macrocode} +\begin{NoHyper}\ref{@sagelabel\theST@inline}\end{NoHyper}% +% \end{macrocode} +% Now check to see if the label has already been defined. (The internal +% implementation of labels in \LTX involves defining a function +% ``|r@@labelname|''.) If it hasn't, we set a flag so that we can tell +% the user to run Sage on the |.sage| file at the end of the run. +% Finally, step the counter. +% \begin{macrocode} +\@ifundefined{r@@sagelabel\theST@inline}{\gdef\ST@rerun{x}}{}% +\stepcounter{ST@inline}} +% \end{macrocode} +% \end{macro} +% The user might load the |hyperref| package after this one (indeed, the +% |hyperref| documentation insists that it be loaded last) or not at +% all---so when we hit the beginning of the document, provide a dummy +% |NoHyper| environment if one hasn't been defined by the |hyperref| +% package. +% \begin{macrocode} +\AtBeginDocument{\provideenvironment{NoHyper}{}{}} +% \end{macrocode} +% +% \begin{macro}{\percent} +% A macro that inserts a percent sign. This is more-or-less stolen from the +% \textsf{Docstrip} manual; there they change the catcode inside a group +% and use |gdef|, but here we try to be more \LaTeX y and use +% |\newcommand|. +% \begin{macrocode} +\catcode`\%=12 +\newcommand{\percent}{%} +\catcode`\%=14 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ST@plotdir} +% A little abbreviation for the plot directory. We don't use +% |\graphicspath| because it's +% \href{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=graphicspath}{ +% apparently slow}---also, since we know right where our plots are +% going, no need to have \LTX looking for them. +% \begin{macrocode} +\newcommand{\ST@plotdir}{sage-plots-for-\jobname.tex} +% \end{macrocode} +% \end{macro} +% +% \tikzstyle{box}=[draw, shape=rectangle, thick] +% +% \begin{macro}{\sageplot} +% \changes{v1.3}{2008/03/08}{Iron out warnings, cool Ti\emph{k}Z flowchart} +% This function is similar to |\sage|. The neat thing that we take +% advantage of is that commas aren't special for arguments to \LTX +% commands, so it's easy to capture a bunch of keyword arguments that +% get passed right into a Python function. +% +% This macro has two optional arguments, which can't be defined using +% \LTX's |\newcommand|; we use Scott Pakin's brilliant +% \href{http://tug.ctan.org/tex-archive/support/newcommand/}{|newcommand|} +% package to create this macro; the options I fed to his script were +% similar to this: +%\begin{center} +% |MACRO sageplot OPT[#1={width}] OPT[#2={notprovided}] #3| +%\end{center} +% Observe that we are using a Python script to write \LTX code which +% writes Python code which writes \LTX code. Crazy! +% +% Here's the wrapper command which does whatever magic we need to get +% two optional arguments. +% \begin{macrocode} +\newcommand{\sageplot}[1][width=.75\textwidth]{% + \@ifnextchar[{\ST@sageplot[#1]}{\ST@sageplot[#1][notprovided]}%] +} +% \end{macrocode} +% That percent sign followed by a square bracket seems necessary; I have +% no idea why. +% +% The first optional argument |#1| will get shoved right into the +% optional argument for |\includegraphics|, so the user has easy control +% over the \LTX aspects of the plotting. We define a +% default size of $3/4$ the textwidth, which seems reasonable. (Perhaps +% a future version of \ST will allow the user to specify in the package +% options a set of default options to be used throughout.) The +% second optional argument |#2| is the file format and allows us to tell +% what files to look for. It defaults to ``notprovided'', which tells +% the Python module to create EPS and PDF files. Everything in |#3| gets +% put into the Python function call, so the user can put in keyword +% arguments there which get interpreted correctly by Python. +% +% \begin{macro}{\ST@sageplot} 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. Note that the |\write| gobbles up line endings, so +% the |sageplot| bits below get written to the |.sage| file as one line. +% \begin{macrocode} +\def\ST@sageplot[#1][#2]#3{% +\ST@wsf{try:}% +\ST@wsf{ sagetex.initplot('\jobname')}% +\ST@wsf{ sagetex.plot(\theST@plot, #3, format='#2', epsmagick=\ST@epsim)}% +\ST@wsf{except:}% +\ST@wsf{ sagetex.goboom(\the\inputlineno)}% +% \end{macrocode} +% Now we include the appropriate graphics file. Because the user might +% be producing DVI or PDF files, and have supplied a file format or not, +% and so on, the logic we follow is a bit complicated. +% \autoref{f:sageplottree} shows what we do; for completeness, we show +% what |\ST@inclgrfx| does in \autoref{f:stig}. This entire +% complicated business is intended to avoid doing an |\includegraphics| +% command on a file that doesn't exist, and to issue warnings +% appropriate to the situation. +% +% \tikzstyle{box}=[draw, shape=rectangle, thick] +% +% \begin{figure} +% \centering +% \begin{tikzpicture} +% \tikzstyle{level 1}=[sibling distance=6cm] +% \tikzstyle{level 2}=[sibling distance=3cm] +% \node [box] {DVI or PDF?} +% child {node [box] {Format provided?} +% child {node [box] {STig EPS} +% edge from parent node[left] {no}} +% child {node [box] {IM option set?} +% child {node [box, text width=3cm] {Warn that DVI + PNG = bad} +% edge from parent node[left] {no}} +% child {node [box] {STig EPS} +% edge from parent node[right] {yes}} +% edge from parent node[right] {yes}} +% edge from parent node[left] {DVI}} +% child {node [box] {Format provided?} +% child {node [box] {STig PDF} +% edge from parent node[left] {no}} +% child {node [box] {STig \texttt{\#2}} +% edge from parent node[right] {yes}} +% edge from parent node[right] {PDF}}; +% \end{tikzpicture} +% \caption{The logic tree that \texttt{\bslash sageplot} uses to +% decide whether to run \texttt{\bslash includegraphics} or to yell at +% the user. ``Format'' is the \texttt{\#2} argument to \texttt{\bslash +% sageplot}, ``STig ext'' +% means a call to \texttt{\bslash ST@inclgrfx} with ``ext'' as the +% second argument, and ``IM'' is Imagemagick.} +% \label{f:sageplottree} +% \end{figure} +% +% If we are creating a PDF, we check to see if the user asked for a +% different format, and use that if necessary: +% \begin{macrocode} +\ifpdf + \ifthenelse{\equal{#2}{notprovided}}% + {\ST@inclgrfx{#1}{pdf}}% + {\ST@inclgrfx{#1}{#2}}% +% \end{macrocode} +% Otherwise, we are creating a DVI file, which only supports EPS. If the +% user provided a format anyway, don't include the file (since it won't +% work) and warn the user about this. (Unless the file doesn't exist, in +% which case we do the same thing that |\ST@inclgrfx| does.) +% \begin{macrocode} +\else + \ifthenelse{\equal{#2}{notprovided}}% + {\ST@inclgrfx{#1}{eps}}% +% \end{macrocode} +% If a format is provided, we check to see if we're using the +% imagemagick option. If so, try to include an EPS file anyway. +% \begin{macrocode} + {\ifthenelse{\equal{\ST@epsim}{True}} + {\ST@inclgrfx{#1}{eps}}% +% \end{macrocode} +% If we're not using the imagemagick option, we're going to issue some +% sort of warning, depending on whether the file exists yet or not. +% \begin{macrocode} + {\IfFileExists{\ST@plotdir/plot-\theST@plot.#2}% + {\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}% + \PackageWarning{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}}% + {\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}% + \PackageWarning{sagetex}{Graphics file + \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space + does not exist}% + \gdef\ST@rerun{x}}}}% +\fi +% \end{macrocode} +% Finally, step the counter and we're done. +% \begin{macrocode} +\stepcounter{ST@plot}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ST@inclgrfx} +% This command includes the requested graphics file (|#2| is the +% extension) with the requested options (|#1|) if the file exists. Note +% that it just needs to know the extension, since we use a counter for +% the filename. +% \begin{macrocode} +\newcommand{\ST@inclgrfx}[2]{% + \IfFileExists{\ST@plotdir/plot-\theST@plot.#2}% + {\includegraphics[#1]{\ST@plotdir/plot-\theST@plot.#2}}% +% \end{macrocode} +% If the file doesn't exist, we insert a little box to indicate it +% wasn't found, issue a warning that we didn't find a graphics file, +% then set a flag that, at the end of the run, tells the user to run +% Sage again. +% \begin{macrocode} + {\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}% + \PackageWarning{sagetex}{Graphics file + \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space does not + exist}% + \gdef\ST@rerun{x}}} +% \end{macrocode} +% \autoref{f:stig} makes this a bit clearer. +% \begin{figure} +% \centering +% \begin{tikzpicture} +% \tikzstyle{level 1}=[sibling distance=4cm] +% \node [box] {Does EXT file exist?} +% child {node [box, text width = 2.125cm] {Warn user to rerun Sage} +% edge from parent node[left] {no}} +% child {node [box] {Use \texttt{includegraphics}} +% edge from parent node[right] {yes}}; +% \end{tikzpicture} +% \caption{The logic used by the \texttt{\bslash ST@inclgrfx} +% command.} +% \label{f:stig} +% \end{figure} +% \end{macro} +% +% \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 last bit is some magic from the |verbatim| package +% manual that makes \LTX respect line breaks. +% \begin{macrocode} +\newcommand{\ST@beginsfbl}{% + \@bsphack% + \ST@wsf{sagetex.blockbegin()}% + \ST@wsf{try:}% + \let\do\@makeother\dospecials\catcode`\^^M\active} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ST@endsfbl} +% The companion to |\ST@beginsfbl|. +% \begin{macrocode} +\newcommand{\ST@endsfbl}{% +\ST@wsf{except:}% +\ST@wsf{ sagetex.goboom(\the\inputlineno)}% +\ST@wsf{sagetex.blockend()}} +% \end{macrocode} +% \end{macro} +% +% Now let's define the ``verbatim-like'' environments. There are four +% possibilities, corresponding to two independent choices of +% typesetting the code or not, and writing to the |.sage| file or not. +% +% \begin{environment}{sageblock} +% This environment does both: it typesets your code and puts it into the +% |.sage| file for execution by Sage. +% \begin{macrocode} +\newenvironment{sageblock}{\ST@beginsfbl% +% \end{macrocode} +% The space between |\ST@wsf{| and |\the| is crucial! It, along with the +% ``|try:|'', is what allows the user to indent code if they like. +% This line sends stuff to the |.sage| file. +% \begin{macrocode} +\def\verbatim@processline{\ST@wsf{ \the\verbatim@line}% +% \end{macrocode} +% Next, we typeset your code and start the verbatim environment. +% \begin{macrocode} +\hspace{\sagetexindent}\the\verbatim@line\par}% +\verbatim}% +% \end{macrocode} +% At the end of the environment, we put a chunk into the |.sage| file +% and stop the verbatim environment. +% \begin{macrocode} +{\ST@endsfbl\endverbatim} +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{sagesilent} +% This is from the |verbatim| package manual. It's just like the above, +% except we don't typeset anything. +% \begin{macrocode} +\newenvironment{sagesilent}{\ST@beginsfbl% +\def\verbatim@processline{\ST@wsf{ \the\verbatim@line}}% +\verbatim@start}% +{\ST@endsfbl\@esphack} +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{sageverbatim} +% The opposite of |sagesilent|. This is exactly the same as the verbatim +% environment, except that we include some indentation to be consistent +% with other typeset Sage code. +% \begin{macrocode} +\newenvironment{sageverbatim}{% +\def\verbatim@processline{\hspace{\sagetexindent}\the\verbatim@line\par}% +\verbatim}% +{\endverbatim} +% \end{macrocode} +% \end{environment} +% +% Logically, we now need an environment which neither typesets +% \emph{nor} writes code to the |.sage| file. The verbatim package's +% |comment| environment does that.\\ +% +% Now we deal with some end-of-file cleanup. +% +% We tell the Sage script to write some information to the |.sout| file, +% then check to see if |ST@rerun| ever got defined. If not, all the +% inline formulas and plots worked, so do nothing. +% \begin{macrocode} +\AtEndDocument{\ST@wsf{sagetex.endofdoc()}% +\@ifundefined{ST@rerun}{}% +% \end{macrocode} +% Otherwise, we issue a warning to tell the user to run Sage on the +% |.sage| file. Part of the reason we do this is that, by using |\ref| +% to pull in the inlines, \LTX will complain about undefined +% references if you haven't run the Sage script---and for many \LTX +% users, myself included, the warning ``there were undefined +% references'' is a signal to run \LTX again. But to fix these +% particular undefined references, you need to run \emph{Sage}. We also +% suppressed file-not-found errors for graphics files, and need to tell +% the user what to do about that. +% +% At any rate, we tell the user to run Sage if it's necessary. +% \begin{macrocode} +{\PackageWarningNoLine{sagetex}{There were undefined Sage formulas +and/or plots}% +\PackageWarningNoLine{sagetex}{Run Sage on \jobname.sage, and then run +LaTeX on \jobname.tex again}}} +% \end{macrocode} +% +% +% \subsection{The Python module} +% +% \iffalse +% Hey, docstrip! Stop putting code into the .sty file, and start +% putting it into the .py file. +%</latex> +%<*python> +% Thanks. +% \fi +% +% The style file writes things to the |.sage| file and reads them from +% the |.sout| file. The Python module provides functions that help +% produce the |.sout| file from the |.sage| file. +% +% \paragraph{A note on Python and \textsf{Docstrip}} There is one tiny +% potential source of confusion when documenting Python code with +% \textsf{Docstrip}: the percent sign. If you have a long line of Python +% code which includes a percent sign for string formatting and you break +% the line with a backslash and begin the next line with a percent sign, +% that line \emph{will not} be written to the output file. This is only +% a problem if you \emph{begin} the line with a percent sign; there are +% no troubles otherwise.\\ +% +% On to the code: +% +% The |sagetex.py| file is intended to be used as a module and doesn't +% do anything useful when called directly, so if someone does that, warn +% them. We do this right away so that we print this and exit before +% trying to import any Sage modules; that way, this error message gets +% printed whether you run the script with Sage or with Python. +% \begin{macrocode} +import sys +if __name__ == "__main__": + print("""This file is part of the SageTeX package. +It is not meant to be called directly. + +This file will be used by Sage scripts generated from a LaTeX document +using the sagetex package. Keep it somewhere where Sage and Python can +find it and it will automatically be imported.""") + sys.exit() +% \end{macrocode} +% We start with some imports and definitions of our global variables. +% This is a relatively specialized use of Sage, so using global +% variables isn't a bad idea. Plus I think when we import this module, +% they will all stay inside the |sagetex| namespace anyway. +% \begin{macrocode} +from sage.misc.latex import latex +import os +import os.path +import hashlib +import traceback +import subprocess +import shutil +initplot_done = False +dirname = None +filename = "" +% \end{macrocode} +% +% \begin{macro}{progress} +% This function justs prints stuff. It allows us to not print a +% linebreak, so you can get ``|start...|'' (little time spent +% processing) ``|end|'' on one line. +% \begin{macrocode} +def progress(t,linebreak=True): + if linebreak: + print(t) + else: + sys.stdout.write(t) +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{openout} +% This function opens a |.sout.tmp| file and writes all our output to +% that. Then, when we're done, we move that to |.sout|. The +% ``autogenerated'' line is basically the same as the lines that get put +% at the top of preparsed Sage files; we are automatically generating a +% file with Sage, so it seems reasonable to add it. +% \begin{macrocode} +def openout(f): + global filename + filename = f + global _file_ + _file_ = open(f + '.sout.tmp', 'w') + s = '% This file was *autogenerated* from the file ' + \ + os.path.splitext(filename)[0] + '.sage.\n' + _file_.write(s) + progress('Processing Sage code for %s.tex...' % filename) +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{initplot} +% We only want to create the plots directory if the user actually plots +% something. This function creates the directory and sets the +% |initplot_done| flag after doing so. We make a directory based on the +% \LTX file being processed so that if there are multiple |.tex| +% files in a directory, we don't overwrite plots from another file. +% \begin{macrocode} +def initplot(f): + global initplot_done + if not initplot_done: + progress('Initializing plots directory') + global dirname +% \end{macrocode} +% We hard-code the |.tex| extension, which is fine in the overwhelming +% majority of cases, although it does cause minor confusion when +% building the documentation. If it turns out lots of people use, say, a +% |ltx| extension or whatever, I think we could find out the correct +% extension, but it would involve a lot of irritating mucking around. +% \begin{macrocode} + dirname = 'sage-plots-for-' + f + '.tex' + if os.path.isdir(dirname): + shutil.rmtree(dirname) + os.mkdir(dirname) + initplot_done = True +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{inline} +% This function works with |\sage| from the style file to put Sage +% output into your \LTX file. Usually, when you use |\label|, it +% writes a line such as +% \begin{center} +% |\newlabel{labelname}{{section number}{page number}}| +% \end{center} +% to the |.aux| file. When you use the |hyperref| package, there are +% more fields in the second argument, but the first two are the same. +% The |\ref| command just pulls in what's in the first field, so we can +% hijack this mechanism for our own nefarious purposes. The function +% writes a |\newlabel| line with a label made from a counter and the +% text from running Sage on |s|. +% +% We print out the line number so if something goes wrong, the user can +% more easily track down the offending |\sage| command in the source +% file. +% +% That's a lot of explanation for a very short function: +% \begin{macrocode} +def inline(counter, s): + progress('Inline formula %s' % counter) + _file_.write('\\newlabel{@sagelabel' + str(counter) + '}{{' + \ + latex(s) + '}{}{}{}{}}\n') +% \end{macrocode} +% We are using five fields, just like |hyperref| does, because that +% works whether or not |hyperref| is loaded. Using two fields, as in plain +% \LTX, doesn't work if |hyperref| is loaded. +% \end{macro} +% +% \begin{macro}{blockbegin} +% \begin{macro}{blockend} +% This function and its companion used to write stuff to the |.sout| +% file, but now they just update the user on our progress evaluating a +% code block. +% \begin{macrocode} +def blockbegin(): + progress('Code block begin...', False) +def blockend(): + progress('end') +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{plot} +% I hope it's obvious that this function does plotting. As mentioned in +% the |\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(counter, p, format='notprovided', epsmagick=False, **kwargs): + global dirname + progress('Plot %s' % counter) +% \end{macrocode} +% If the user says nothing about file formats, we default to producing +% PDF and EPS. This allows the user to transparently switch between +% using a DVI previewer (which usually automatically updates when the +% DVI changes, and has support for source specials, which makes the +% writing process easier) and making PDFs. +% \begin{macrocode} + if format == 'notprovided': + formats = ['eps', 'pdf'] + else: + formats = [format] + for fmt in formats: + plotfilename = os.path.join(dirname, 'plot-%s.%s' % (counter, fmt)) + #print(' plotting %s with args %s' % (plotfilename, kwargs)) + p.save(filename=plotfilename, **kwargs) +% \end{macrocode} +% If the user provides a format \emph{and} specifies the |imagemagick| +% option, we try to convert the newly-created file into EPS format. +% \begin{macrocode} + if format != 'notprovided' and epsmagick is True: + print('Calling Imagemagick to convert plot-%s.%s to EPS' % \ + (counter, format)) + toeps(counter, format) +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{toeps} +% This function calls the Imagmagick utility |convert| to, well, convert +% something into EPS format. This gets called when the user has +% requested the ``|imagemagick|'' option to the \ST\ style file and is +% making a graphic file with a nondefault extension. +% \begin{macrocode} +def toeps(counter, ext): + global dirname + subprocess.check_call(['convert',\ + '%s/plot-%s.%s' % (dirname, counter, ext), \ + '%s/plot-%s.eps' % (dirname, counter)]) +% \end{macrocode} +% We are blindly assuming that the |convert| command exists and will do +% the conversion for us; the |check_call| function raises an exception +% which, since all these calls get wrapped in try/excepts in the |.sage| +% file, should result in a reasonable error message if something strange +% happens. +% \end{macro} +% +% \begin{macro}{goboom} +% When a chunk of Sage code blows up, this function bears the bad news +% to the user. Normally in Python the traceback is good enough for this, +% but in this case, we start with a |.sage| file (which is +% autogenerated) which autogenerates a |.py| file---and the tracebacks +% the user sees refer to that file, whose line numbers are basically +% useless. We want to tell them where in the \LTX file things went +% bad, so we do that, give them the traceback, and exit after removing +% the |.sout.tmp| file. +% \begin{macrocode} +def goboom(line): + global filename + print('\n**** Error in Sage code on line %s of %s.tex! Traceback\ + follows.' % (line, filename)) + traceback.print_exc() + print('\n**** Running Sage on %s.sage failed! Fix %s.tex and try\ + again.' % (filename, filename)) + os.remove(filename + '.sout.tmp') + sys.exit(1) +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{endofdoc} +% When we're done processing, we have a couple little cleanup tasks. We +% want to put the MD5 sm of the |.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 tell 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, say, a line break 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 calls to Sage have +% changed. +% +% How do we include line numbers for our error messages but still allow +% a program to discover a ``genuine'' change to the |.sage| file? +% +% The answer is to only find the MD5 sum of \emph{part} of the |.sage| +% file. By design, the source file line numbers only appear in calls to +% |goboom|, so we will strip those lines out. Basically we are doing +% \begin{center} +% \verb+grep -v '^ sagetex.goboom' filename.sage | md5sum+ +% \end{center} +% (In fact, what we do below produces exactly the same sum.) +% \begin{macrocode} +def endofdoc(): + global filename + sagef = open(filename + '.sage', 'r') + m = hashlib.md5() + for line in sagef: + if line[0:15] != ' sagetex.goboom': + m.update(line) + s = '%' + m.hexdigest() + '% md5sum of .sage file (minus "goboom" \ +lines) that produced this\n' + _file_.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.) +% +% Now we are done with the |.sout| file. Close it, rename it, and tell +% the user we're done. +% \begin{macrocode} + _file_.close() + os.rename(filename + '.sout.tmp', filename + '.sout') + progress('Sage processing complete. Run LaTeX on %s.tex again.' %\ + filename) +% \end{macrocode} +% \end{macro} +% +% \section{Credits and acknowledgements} +% +% According to the original README file, this system was originally +% done by Gonzalo Tornaria and Joe Wetherell. Later Harald Schilly made +% some improvements and modifications. Almost all the examples in the +% |example.tex| file are from Harald. +% +% Dan Drake rewrote and extended the style file (there is almost zero +% original code there), made significant changes to the Python module, +% put both files into \textsf{Docstrip} format, and wrote all the +% documentation. +% +% Many thanks to Jason Grout for his numerous comments, suggestions, and +% feedback. +% +% \section{Copying and licenses} +% +% The \emph{source code} of the \ST package may be redistributed and/or +% modified under the terms of the GNU General Public License as +% published by the Free Software Foundation, either version 2 of the +% License, or (at your option) any later version. To view a copy of this +% license, see \url{http://www.gnu.org/licenses/} or send a letter to +% the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +% Boston, MA 02110-1301, USA. +% +% The \emph{documentation} of the \ST package is licensed under the +% Creative Commons Attribution-Noncommercial-Share Alike 3.0 License. To +% view a copy of this license, visit +% \url{http://creativecommons.org/licenses/by-nc-sa/3.0/} or send a +% letter to Creative Commons, 171 Second Street, Suite 300, San +% Francisco, California, 94105, USA. diff --git a/Master/texmf-dist/source/latex/sagetex/sagetexpackage.ins b/Master/texmf-dist/source/latex/sagetex/sagetexpackage.ins new file mode 100644 index 00000000000..b91433f7b34 --- /dev/null +++ b/Master/texmf-dist/source/latex/sagetex/sagetexpackage.ins @@ -0,0 +1,93 @@ +%% This is `sagetexpackage.ins', part of the sagetex package. +% +%% Copyright (C) 2008 by Dan Drake <ddrake@member.ams.org> +%% +%% 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. + +Copyright (C) 2008 by Dan Drake <ddrake@member.ams.org> + +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 + +% We use a name other than `sagetex' because when using the sagetex +% package in a file called `foo.dtx', a file `foo.py' will be produced +% -- and below, we generate a file called sagetex.py. Thus we use a name +% other than `sagetex.dtx' so that building the documentation doesn't +% clobber the very Python file we need to build the documentation! + +\generate{\file{sagetex.sty}{\from{sagetexpackage.dtx}{latex}}} + + +% Some trickery to get triple quotes around the {pre,post}amble. This is +% a modification of what the Docstrip manual suggests; their method +% resulted in some bits being printed twice because, I think, of a +% problem in \declare{pre,post}amble. At any rate, this gives us a +% properly commented Python file with the same preamble as the .sty +% file. + +\edef\defaultpreamble{"""^^J% + \defaultpreamble^^J% + """} +\edef\defaultpostamble{"""^^J% + \defaultpostamble^^J% + """} + +\generate{\file{sagetex.py}{\from{sagetexpackage.dtx}{python}}} + +\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 sagetexpackage.gls sagetexpackage.glo *} +\Msg{* *} +\Msg{* and to get the regular index, do *} +\Msg{* *} +\Msg{* makeindex -s gind.ist -o sagetexpackage.ind sagetexpackage.idx *} +\Msg{* *} +\Msg{* Happy TeXing...and, uh, Saging? *} +\Msg{* *} +\Msg{******************************************************************} + +\endbatchfile |