diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/sagetex/py-and-sty.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/sagetex/py-and-sty.dtx | 907 |
1 files changed, 0 insertions, 907 deletions
diff --git a/Master/texmf-dist/source/latex/sagetex/py-and-sty.dtx b/Master/texmf-dist/source/latex/sagetex/py-and-sty.dtx deleted file mode 100644 index 3798ec58547..00000000000 --- a/Master/texmf-dist/source/latex/sagetex/py-and-sty.dtx +++ /dev/null @@ -1,907 +0,0 @@ -% \section{Implementation} -% \label{sec:implementation} -% -% There are two pieces to this package: a \LTX style file, and a -% Python module. They are mutually interdependent, so it makes sense to -% document them both here. -% -% \subsection{The style file} -% \label{sec:sty-file} -% -% \iffalse -% tell docstrip to put code into the .sty file -%<*latex> -% \fi -% -% All macros and counters intended for use internal to this package -% begin with ``|ST@|''. -% -% \subsubsection{Initialization} -% -% Let's begin by loading some packages. The key bits of |sageblock| and -% friends are stol---um, adapted from the |verbatim| package manual. So -% grab the |verbatim| package. -% \begin{macrocode} -\RequirePackage{verbatim} -% \end{macrocode} -% Unsurprisingly, the |\sageplot| command works poorly without graphics -% support. -% \begin{macrocode} -\RequirePackage{graphicx} -% \end{macrocode} -% The |makecmds| package gives us a |\provideenvironment| which we need, -% and we use |ifpdf| and |ifthen| in |\sageplot| so we know what kind of -% files to look for. -% \begin{macrocode} -\RequirePackage{makecmds} -\RequirePackage{ifpdf} -\RequirePackage{ifthen} -% \end{macrocode} -% -% Next set up the counters, default indent, and flags. -% \begin{macrocode} -\newcounter{ST@inline} -\newcounter{ST@plot} -\setcounter{ST@inline}{0} -\setcounter{ST@plot}{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.sage% -% \end{macrocode} -% \begin{macro}{\ST@wsf} -% We will write a lot of stuff to that file, so make a convenient -% abbreviation, then use it to put the initial commands into the -% |.sage| file. The hash mark below gets doubled when written to the -% file, for some obscure reason related to parameter expansion. It's -% valid Python, though, so I haven't bothered figuring out how to get -% a single hash. We are assuming that the extension is |.tex|; see the -% |initplot| documentation on page~\pageref{initplot} for discussion -% of file extensions. The ``|(\jobname.sage)|'' business is there -% because the comment below will get pulled into the autogenerated -% |.py| file (second order autogeneration!) and I'd like to reduce -% possible confusion if someone is looking around in those files. -% \begin{macrocode} -\newcommand{\ST@wsf}[1]{\immediate\write\ST@sf{#1}}% -\ST@wsf{# This file (\jobname.sage) was *autogenerated* from the file \jobname.tex.}% -\ST@wsf{import sagetex}% -\ST@wsf{_st_ = sagetex.SageTeXProcessor('\jobname')}}% -% \end{macrocode} -% On the other hand, if the |ST@final| flag is set, don't bother with -% any of the file stuff, and make |\ST@wsf| a no-op. -% \begin{macrocode} -{\newcommand{\ST@wsf}[1]{\relax}}} -% \end{macrocode} -% \end{macro} -% Now we declare our options, which mostly just set flags that we check -% at the beginning of the document, and when running the |.sage| file. -% \changes{v2.0}{2008/04/04}{Add \texttt{epstopdf} option} -% \changes{v2.0}{2008/12/16}{Add \texttt{final} option} -% -% The |final| option controls whether or not we write the |.sage| file; -% the |imagemagick| and |epstopdf| options both want to write something -% to that same file. So we put off all the actual file stuff until the -% beginning of the document---by that time, we'll have processed the -% |final| option (or not) and can check the |\ST@final| flag to see what -% to do. (We must do this because we can't specify code that runs if an -% option \emph{isn't} defined.) -% -% For |final|, we set a flag for other guys to check, and if there's no -% |.sout| file, we warn the user that something fishy is going on. -% \begin{macrocode} -\DeclareOption{final}{% - \newcommand{\ST@final}{x}% - \IfFileExists{\jobname.sout}{}{\AtEndDocument{\PackageWarningNoLine{sagetex}% - {`final' option provided, but \jobname.sout^^Jdoesn't exist! No Sage - input will appear in your document. Remove the `final'^^Joption and - rerun LaTeX on your document}}}} -% \end{macrocode} -% For |imagemagick|, we set two flags: one for \LTX and one for Sage. -% It's important that we set |ST@useimagmagick| \emph{before} the -% beginning of the document, so that the graphics commands can check -% that. We do wait until the beginning of the document to do file -% writing stuff. -% \begin{macrocode} -\DeclareOption{imagemagick}{% - \newcommand{\ST@useimagemagick}{x}% - \AtBeginDocument{% - \@ifundefined{ST@final}{% - \ST@wsf{_st_.useimagemagick = True}}{}}} -% \end{macrocode} -% For |epstopdf|, we just set a flag for Sage. Then, process the options. -% \begin{macrocode} -\DeclareOption{epstopdf}{% -\AtBeginDocument{% -\@ifundefined{ST@final}{% - \ST@wsf{_st_.useepstopdf = True}}{}}} -\ProcessOptions\relax -% \end{macrocode} -% The |\relax| is a little incantation suggested by the ``\LaTeXe{} for -% class and package writers'' manual, section 4.7. -% -% Pull in the |.sout| file if it exists, or do nothing if it doesn't. I -% suppose we could do this inside an |AtBeginDocument| but I don't see -% any particular reason to do that. It will work whenever we load it. 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.sout}{}{\typeout{No file \jobname.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} macro} -% \label{sec:sagemacro} -% -% \begin{macro}{\sage} -% This macro combines |\ref|, |\label|, and Sage all at once. First, we -% use Sage to get a \LTX representation of whatever you give this -% function. The Sage script writes a |\newlabel| line into the |.sout| -% file, and we read the output using the |\ref| command. Usually, |\ref| -% pulls in a section or theorem number, but it will pull in arbitrary -% text just as well. -% -% The first thing it does it write its argument into the |.sage| file, -% along with a counter so we can produce a unique label. We wrap a -% try/except around the function call so that we can provide a more -% helpful error message in case something goes wrong. (In particular, we -% can tell the user which line of the |.tex| file contains the offending -% code.) We can use |^^J| to put linebreaks into the |.sage| file, but -% \LTX wants to put a space after that, which is why we don't put the -% ``except'' on its own line here in the source. -% \begin{macrocode} -\newcommand{\sage}[1]{\ST@wsf{% -try:^^J - _st_.inline(\theST@inline, #1)^^Jexcept:^^J - _st_.goboom(\the\inputlineno)}% -% \end{macrocode} -% The |inline| function of the Python module is documented on page -% \pageref{inlinefn}. 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}{\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][width=.75\textwidth]{% - \@ifnextchar[{\ST@sageplot[#1]}{\ST@sageplot[#1][notprovided]}} -% \end{macrocode} -% The first optional argument |#1| will get shoved right into the -% optional argument for |\includegraphics|, so the user has easy control -% over the \LTX aspects of the plotting. We define a default size of -% $3/4$ the textwidth, which seems reasonable. (Perhaps a future version -% of \ST will allow the user to specify in the package options a set of -% default options to be used throughout.) The second optional argument -% |#2| is the file format and allows us to tell what files to look for. -% It defaults to ``notprovided'', which tells the Python module to -% create EPS and PDF files. Everything in |#3| gets put into the Python -% function call, so the user can put in keyword arguments there which -% get interpreted correctly by Python. -% -% \begin{macro}{\ST@sageplot} -% \changes{v2.0}{2008/12/16}{Change to use only keyword arguments: see issue -% 2 on bitbucket tracker} -% Let's see the real code here. We write a couple lines to the |.sage| -% file, including a counter, input line number, and all of the mandatory -% argument; all this is wrapped in another try/except. -% \begin{macrocode} -\def\ST@sageplot[#1][#2]#3{\ST@wsf{try:^^J - _st_.plot(\theST@plot, format='#2', _p_=#3)^^Jexcept:^^J - _st_.goboom(\the\inputlineno)}% -% \end{macrocode} -% The Python |plot| function is documented on page~\pageref{plotfn}. -% -% Now we include the appropriate graphics file. Because the user might -% be producing DVI or PDF files, and have supplied a file format or not, -% and so on, the logic we follow is a bit complicated. -% \autoref{f:sageplottree} shows what we do; for completeness---and -% because I think drawing trees with \TikZ is really cool---we show what -% |\ST@inclgrfx| does in \autoref{f:stig}. This entire complicated -% business is intended to avoid doing an |\includegraphics| command on a -% file that doesn't exist, and to issue warnings appropriate to the -% situation. -% -% \begin{figure} -% \centering -% \begin{tikzpicture} -% \tikzstyle{level 1}=[sibling distance=6cm] -% \tikzstyle{level 2}=[sibling distance=3cm] -% \node [box] {DVI or PDF?} -% child {node [box] {Format provided?} -% child {node [box] {STig EPS} -% edge from parent node[left] {no}} -% child {node [box] {IM option set?} -% child {node [box, text width=3cm] {Warn that DVI + PNG = bad} -% edge from parent node[left] {no}} -% child {node [box] {STig EPS} -% edge from parent node[right] {yes}} -% edge from parent node[right] {yes}} -% edge from parent node[left] {DVI}} -% child {node [box] {Format provided?} -% child {node [box] {STig PDF} -% edge from parent node[left] {no}} -% child {node [box] {STig \texttt{\#2}} -% edge from parent node[right] {yes}} -% edge from parent node[right] {PDF}}; -% \end{tikzpicture} -% \caption{The logic tree that \texttt{\bslash sageplot} uses to -% decide whether to run \texttt{\bslash includegraphics} or to yell at -% the user. ``Format'' is the \texttt{\#2} argument to \texttt{\bslash -% sageplot}, ``STig ext'' -% means a call to \texttt{\bslash ST@inclgrfx} with ``ext'' as the -% second argument, and ``IM'' is Imagemagick.} -% \label{f:sageplottree} -% \end{figure} -% -% If we are creating a PDF, we check to see if the user asked for a -% different format, and use that if necessary: -% \begin{macrocode} -\ifpdf - \ifthenelse{\equal{#2}{notprovided}}% - {\ST@inclgrfx{#1}{pdf}}% - {\ST@inclgrfx{#1}{#2}}% -% \end{macrocode} -% Otherwise, we are creating a DVI file, which only supports EPS. If the -% user provided a format anyway, don't include the file (since it won't -% work) and warn the user about this. (Unless the file doesn't exist, in -% which case we do the same thing that |\ST@inclgrfx| does.) -% \begin{macrocode} -\else - \ifthenelse{\equal{#2}{notprovided}}% - {\ST@inclgrfx{#1}{eps}}% -% \end{macrocode} -% If a format is provided, we check to see if we're using the -% imagemagick option. If not, we're going to issue some sort of warning, -% depending on whether the file exists yet or not. -% \begin{macrocode} - {\@ifundefined{ST@useimagemagick}% - {\IfFileExists{\ST@plotdir/plot-\theST@plot.#2}% - {\ST@missingfilebox% - \PackageWarning{sagetex}{Graphics file - \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space - cannot be used with DVI output. Use pdflatex or create an EPS - file. Plot command is}}% - {\ST@missingfilebox% - \PackageWarning{sagetex}{Graphics file - \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space - does not exist. Plot command is}% - \gdef\ST@rerun{x}}}% -% \end{macrocode} -% Otherwise, we are using Imagemagick, so try to include an EPS file -% anyway. -% \begin{macrocode} - {\ST@inclgrfx{#1}{eps}}}% -\fi -% \end{macrocode} -% 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 insert a little box to indicate it -% wasn't found, issue a warning that we didn't find a graphics file, -% then set a flag that, at the end of the run, tells the user to run -% Sage again. -% \begin{macrocode} - {\ST@missingfilebox% - \PackageWarning{sagetex}{Graphics file - \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space does not - exist. Plot command is}% - \gdef\ST@rerun{x}} -\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, 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}} -% 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_.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.\\ -% -% \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 suppressed file-not-found errors -% for graphics files, and need to tell the user what to do about that. -% -% At any rate, we tell the user to run Sage if it's necessary. -% \begin{macrocode} -{\PackageWarningNoLine{sagetex}{There were undefined Sage formulas -and/or plots.^^JRun Sage on \jobname.sage, and then run -LaTeX on \jobname.tex again}}} -% \end{macrocode} -% -% -% \subsection{The Python module} -% \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: the |sagetex.py| file is intended to be used as a -% module and doesn't do anything useful when called directly, so if -% someone does that, warn them. We do this right away so that we print -% this and exit before trying to import any Sage modules; that way, this -% error message gets printed whether you run the script with Sage or -% with Python. -% \begin{macrocode} -import sys -if __name__ == "__main__": - print("""This file is part of the SageTeX package. -It is not meant to be called directly. - -This file will be automatically used by Sage scripts generated from a -LaTeX document using the SageTeX package.""") - sys.exit() -% \end{macrocode} -% Import what we need: -% \begin{macrocode} -from sage.misc.latex import latex -import os -import os.path -import hashlib -import traceback -import subprocess -import shutil -% \end{macrocode} -% We define a class so that it's a bit easier to carry around internal -% state. We used to just have some global variables and a bunch of -% functions, but this seems a bit nicer and easier. -% \begin{macrocode} -class SageTeXProcessor(): - def __init__(self, jobname): - self.progress('Processing Sage code for %s.tex...' % jobname) - self.didinitplot = False - self.useimagemagick = False - self.useepstopdf = False - self.plotdir = 'sage-plots-for-' + jobname + '.tex' - self.filename = jobname -% \end{macrocode} -% Open a |.sout.tmp| file and write all our output to that. Then, when -% we're done, we move that to |.sout|. The ``autogenerated'' line is -% basically the same as the lines that get put at the top of preparsed -% Sage files; we are automatically generating a file with Sage, so it -% seems reasonable to add it. -% \begin{macrocode} - self.souttmp = open(self.filename + '.sout.tmp', 'w') - s = '% This file was *autogenerated* from the file ' + \ - os.path.splitext(jobname)[0] + '.sage.\n' - self.souttmp.write(s) -% \end{macrocode} -% -% \begin{macro}{progress} -% This function just prints stuff. It allows us to not print a -% linebreak, so you can get ``|start...|'' (little time spent -% processing) ``|end|'' on one line. -% \begin{macrocode} - def progress(self, t,linebreak=True): - if linebreak: - print(t) - else: - sys.stdout.write(t) - 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. -% \begin{macrocode} - if os.path.isdir(self.plotdir): - shutil.rmtree(self.plotdir) - os.mkdir(self.plotdir) - self.didinitplot = True -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{inline} -% \phantomsection\label{inlinefn} -% This function works with |\sage| from the style file (see -% \autoref{sec:sagemacro}) to put Sage output into your \LTX file. -% Usually, when you use |\label|, it writes a line such as -% \begin{center} -% |\newlabel{labelname}{{section number}{page number}}| -% \end{center} -% to the |.aux| file. When you use the |hyperref| package, there are -% more fields in the second argument, but the first two are the same. -% The |\ref| command just pulls in what's in the first field of the -% second argument, so we can hijack this mechanism for our own nefarious -% purposes. The function writes a |\newlabel| line with a label made -% from a counter and the text from running Sage on |s|. -% -% We print out the line number so if something goes wrong, the user can -% more easily track down the offending |\sage| command in the source -% file. -% -% That's a lot of explanation for a very short function: -% \begin{macrocode} - def inline(self, counter, s): - self.progress('Inline formula %s' % counter) - self.souttmp.write('\\newlabel{@sageinline' + str(counter) + '}{{' + \ - latex(s).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}{blockbegin} -% \begin{macro}{blockend} -% \phantomsection\label{blocksbeginend} -% This function and its companion used to write stuff to the |.sout| -% file, but now they just update the user on our progress evaluating a -% code block. The verbatim-like environments of -% \autoref{sec:verbatim-envs} use these functions. -% \begin{macrocode} - def blockbegin(self): - self.progress('Code block begin...', False) - def blockend(self): - self.progress('end') -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{plot} -% \phantomsection\label{plotfn} -% I hope it's obvious that this function does plotting. It's the Python -% counterpart of |\ST@sageplot| described in \autoref{sec:sageplotmacro}. As -% mentioned in the |\sageplot| code, we're taking advantage of two -% things: first, that \LTX doesn't treat commas and spaces in macro -% arguments specially, and second, that Python (and Sage plotting -% functions) has nice support for keyword arguments. The |#3| argument -% to |\sageplot| becomes |_p_| and |**kwargs| below. -% \begin{macrocode} - def plot(self, counter, _p_, format='notprovided', **kwargs): - if not self.didinitplot: - self.initplot() - self.progress('Plot %s' % counter) -% \end{macrocode} -% If the user says nothing about file formats, we default to producing -% PDF and EPS. This allows the user to transparently switch between -% using a DVI previewer (which usually automatically updates when the -% DVI changes, and has support for source specials, which makes the -% writing process easier) and making PDFs.\footnote{Yes, there's -% \texttt{pdfsync}, but full support for that is still rare in Linux, so -% producing EPS and PDF is the best solution for now.} -% \begin{macrocode} - if format == 'notprovided': - formats = ['eps', 'pdf'] - else: - formats = [format] - for fmt in formats: -% \end{macrocode} -% If we're making a PDF and have been told to use |epstopdf|, do so, -% then skip the rest of the loop. -% \begin{macrocode} - if fmt == 'pdf' and self.useepstopdf: - epsfile = os.path.join(self.plotdir, 'plot-%s.eps' % counter) - self.progress('Calling epstopdf to convert plot-%s.eps to PDF' % \ - counter) - subprocess.check_call(['epstopdf', epsfile]) - continue - plotfilename = os.path.join(self.plotdir, 'plot-%s.%s' % (counter, fmt)) - _p_.save(filename=plotfilename, **kwargs) -% \end{macrocode} -% If the user provides a format \emph{and} specifies the |imagemagick| -% option, we try to convert the newly-created file into EPS format. -% \begin{macrocode} - if format != 'notprovided' and self.useimagemagick: - self.progress('Calling Imagemagick to convert plot-%s.%s to EPS' % \ - (counter, format)) - self.toeps(counter, format) -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{toeps} -% This function calls the Imagmagick utility |convert| to, well, convert -% something into EPS format. This gets called when the user has -% requested the ``|imagemagick|'' option to the \ST\ style file and is -% making a graphic file with a nondefault extension. -% \begin{macrocode} - def toeps(self, counter, ext): - subprocess.check_call(['convert',\ - '%s/plot-%s.%s' % (self.plotdir, counter, ext), \ - '%s/plot-%s.eps' % (self.plotdir, counter)]) -% \end{macrocode} -% We are blindly assuming that the |convert| command exists and will do -% the conversion for us; the |check_call| function raises an exception -% which, since all these calls get wrapped in try/excepts in the |.sage| -% file, should result in a reasonable error message if something strange -% happens. -% \end{macro} -% -% \begin{macro}{goboom} -% \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| file. -% \begin{macrocode} - def goboom(self, line): - print('\n**** Error in Sage code on line %s of %s.tex! Traceback\ - follows.' % (line, self.filename)) - traceback.print_exc() - print('\n**** Running Sage on %s.sage failed! Fix %s.tex and try\ - again.' % ((self.filename,) * 2)) - self.souttmp.close() - os.remove(self.filename + '.sout.tmp') - sys.exit(int(1)) -% \end{macrocode} -% We use |int(1)| above to make sure |sys.exit| sees a Python integer; -% see -% \href{http://trac.sagemath.org/sage_trac/ticket/2861#comment:5}{ticket -% \#2861}. -% \changes{v2.0.2}{2008/04/21}{Make sure sys.exit sees a Python integer} -% \end{macro} -% -% \begin{macro}{endofdoc} -% When we're done processing, we have some cleanup tasks. We -% want to put the MD5 sum of the |.sage| file that produced the |.sout| -% file we're about to write into the |.sout| file, so that external -% programs that build \LTX documents can determine if they need to call Sage -% to update the |.sout| file. But there is a problem: we write line -% numbers to the |.sage| file so that we can provide useful error -% messages---but that means that adding non-\ST text to your -% source file will change the MD5 sum, and your program will think it -% needs to rerun Sage even though none of the actual \ST macros -% changed. -% -% How do we include line numbers for our error messages but still allow -% a program to discover a ``genuine'' change to the |.sage| file? -% -% The answer is to only find the MD5 sum of \emph{part} of the |.sage| -% file. By design, the source file line numbers only appear in calls to -% |goboom| and pause/unpause lines, so we will strip those lines out. -% What we do below is exactly equivalent to running -% \begin{center} -% \verb+egrep '^( _st_.goboom|print .SageT)' filename.sage | md5sum+ -% \end{center} -% in a shell. -% \begin{macrocode} - def endofdoc(self): - sagef = open(self.filename + '.sage', 'r') - m = hashlib.md5() - for line in sagef: - if line[0:12] != " _st_.goboom" and line[0:12] != "print 'SageT": - m.update(line) - s = '%' + m.hexdigest() + '% md5sum of corresponding .sage file\ - (minus "goboom" and pause/unpause lines)\n' - self.souttmp.write(s) -% \end{macrocode} -% Now, we do issue warnings to run Sage on the |.sage| file and an -% external program might look for those to detect the need to rerun -% Sage, but those warnings do not quite capture all situations. (If -% you've already produced the |.sout| file and change a |\sage| call, no -% warning will be issued since all the |\ref|s find a |\newlabel|.) -% Anyway, I think it's easier to grab an MD5 sum out of the end of the -% file than parse the output from running |latex| on your file. (The -% regular expression |^%[0-9a-f]{32}%| will find the MD5 sum. Note that -% there are percent signs on each side of the hex string.) -% -% Now we are done with the |.sout.tmp| file. Close it, rename it, and -% tell the user we're done. -% \begin{macrocode} - self.souttmp.close() - os.rename(self.filename + '.sout.tmp', self.filename + '.sout') - self.progress('Sage processing complete. Run LaTeX on %s.tex again.' %\ - self.filename) -% \end{macrocode} -% % \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: "sagetexpackage" -% End: |