summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/prerex/prerex.sty
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-07-10 00:52:57 +0000
committerKarl Berry <karl@freefriends.org>2010-07-10 00:52:57 +0000
commit825549ad3c7c34ef26e37e0a727a8cd375fb8d6c (patch)
tree6b3577fa12ef82b1b2307256e5753ead90ee1a7a /Master/texmf-dist/tex/latex/prerex/prerex.sty
parentc710176b35237a04981f6873b232f50d4cb8da90 (diff)
prerex 6.01, macros only for this release (28jun10)
git-svn-id: svn://tug.org/texlive/trunk@19330 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/prerex/prerex.sty')
-rw-r--r--Master/texmf-dist/tex/latex/prerex/prerex.sty597
1 files changed, 597 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/prerex/prerex.sty b/Master/texmf-dist/tex/latex/prerex/prerex.sty
new file mode 100644
index 00000000000..f868d548766
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/prerex/prerex.sty
@@ -0,0 +1,597 @@
+%% This is file 'prerex.sty'
+%%
+%% Copyright (C) 2006-10 R. D. Tennent, rdt@cs.queensu.ca
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2003/12/01 or later.
+%%
+%% This work has the LPPL maintenance status "author-maintained".
+%
+% Instructions supported inside \begin{chart} ... \end{chart}:
+%
+% \[req]{half|full}course x,y: {course code}{course title}{timetable code}
+%
+% \mini x,y: {course code}
+%
+% solid arrow: \prereq x0,y0,x1,y1: \prereqc x0,y0,x1,y1;curvature:
+% dotted arrow: \coreq x0,y0,x1,y1: \coreqc x0,y0,x1,y1;curvature:
+% dashed arrow: \recomm x0,y0,x1,y1: \recommc x0,y0,x1,y1;curvature:
+%
+% \text x,y: {line of text}
+%
+% \grid coordinate grid background
+%
+% Stand-alone instructions (for explanatory notes):
+%
+% \solidarrow in-line solid arrow
+% \dottedarrow in-line dotted arrow
+% \dashedarrow in-line dashed arrow
+%
+% \lightbox in-line light course box
+% \boldbox in-line bold course box
+%
+% The following defaults are defined in prerex.sty (but may be re-defined by the user):
+%
+% \newcommand{\DefaultCurvature}{20}
+%
+% where the argument should be in the range 0-100; 0 means no curvature.
+%
+% \newcommand{\CourseURL}[3]{file:#3.html}
+%
+% where the arguments supplied at the call are the x and y coordinates
+% and the course code.
+%
+% \newcommand{\background}{yellow!15}
+%
+% \setlength{\unit}{5.7816pt} length of a coordinate unit; gives 10 pixels per unit at 125dpi
+% \newcommand{\dpi}{125}
+% \newcommand\PixelsPerUnit{10}
+% \setcounter{diagheight}{75} but reduced to 65 in landscape mode
+% \newcommand{\solidwidth}{0.5pt}
+% \newcommand{\dottedwidth}{0.8pt}
+% \newcommand{\dashedwidth}{0.5pt}
+% \newcommand{\boldwidth}{1.0pt}
+% \newcommand{\smallersize}{\relsize{-3}}
+%
+% The nominal diagram width is 10 + (\textwidth divided by \unit).
+%
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{prerex}[2010/06/25 v6.0 LaTeX style for prerequisite charts, pgf version]
+
+% Changelog:
+%
+% Version 6.0
+% Version 5.7
+%
+% added implementation details to documentation
+% generated script now only crops the chart image
+%
+% Version 5.6
+% Version 5.5
+%
+% version increased to keep pace with previewer/vprerex
+%
+% Version 5.4
+%
+% code clean-up
+%
+% Version 5.3
+%
+% produces an image-generating script in \jobname.sh
+%
+% Version 5.2
+%
+% use \grid and \foreach (tikz) instead of \multido
+% half-course boxes now have a minimum height (5 units) to improve uniformity
+%
+% Version 5.1
+%
+% generates image-map data in \jobname_n.html for nth chart when n>1
+%
+% Version 5.0
+%
+% also generates \jobname.html with image-map data for all node URLs
+% new configuration commands \dpi and \PixelsPerUnit
+% default \unit length adjusted to give 10 pixels per coordinate unit at 125 dpi
+%
+% Version 4.4
+%
+% increase ysep parameter to 1.8pt to separate course-code or text and arrow tails for minis
+% and text boxes
+%
+% Version 4.3
+%
+% introduce \smallersize configuration command
+%
+% Version 4.2
+%
+% using tinting with xcolor package to ease background-color changes
+%
+% Version 4.1
+%
+% Version 4.0
+%
+% Implement the \text command to place a line of text (centered at the coordinates) in a chart
+%
+% Version 3.8.1:
+%
+% adjust arraystretch factors to work with long-ascender fonts such as Futura
+% adjust inner sep parameters to work with oblique/italic fonts
+% remove workaround for pgf-1.10 bug described at
+% http://sourceforge.net/forum/forum.php?thread_id=1621660&forum_id=477363
+% require version 1.18 (or later) of pgf
+%
+% Version 3.8:
+%
+% require version 1.10 (or later) of pgf
+%
+% Version 3.7:
+%
+% anchor nodes must be non-null for latex/dvips
+%
+% Version 3.6:
+%
+% first pgf-based version
+%
+% Version 3.5:
+% Version 3.4:
+%
+% introduce arrow borders to improve the appearance of crossing arrows
+% change default widths to artifacts created when arrow borders
+% occlude box boundaries
+%
+% Version 3.3:
+%
+% arrows (as well as course boxes and minis) are hyperlinked with coordinate URIs
+%
+% Version 3.2:
+%
+% Version 3.1:
+%
+% Version 3.0:
+%
+% "anchor" hyperlinks are added to coordinate grid to allow computation of
+% chart coordinates at mouse clicks
+%
+% Version 2.0:
+%
+% CourseURL now takes 3 arguments
+% box/mini coordinates displayed in (some) PDF viewers when grid on
+%
+% Version 1.0.2:
+%
+% using \relsize{-3} rather than \scriptsize
+% using \textsf in \lightbox and \boldbox
+%
+% Version 1.0.1:
+%
+% using \RequirePackage rather than \usepackage (suggested by Herbert Voss)
+%
+
+\newlength{\unit}
+
+\setlength{\unit}{5.7816pt} % 10 pixels per unit at 125dpi; 1pt = (1/72.27) in.
+\newcommand{\PixelsPerUnit}{10}
+\newcommand{\dpi}{125}
+
+\RequirePackage{relsize}
+\RequirePackage{calc}
+\RequirePackage{pgf}[2007/06/12]
+\RequirePackage{tikz}\usetikzlibrary{arrows}
+\RequirePackage{ifthen}
+\RequirePackage{textcomp}
+\RequirePackage{zref-savepos}
+\PassOptionsToPackage{urlcolor=black,colorlinks}{hyperref}
+\RequirePackage{hyperref}
+
+\RequirePackage{xcolor}
+\definecolor{light}{gray}{0.5}
+\definecolor{somewhatlight}{gray}{0.7}
+\definecolor{verylight}{gray}{0.85}
+\definecolor{white}{rgb}{1.0,1.0,1.0} % not transparent, hides grid
+
+\newcommand{\DefaultCurvature}{20} % 0 for no curvature
+\newcommand{\CourseURL}[3]{file:#3.html}
+\newcommand{\background}{yellow!15}
+
+\newcommand{\solidwidth}{0.5pt}
+\newcommand{\boldwidth}{1.0pt}
+\newcommand{\dottedwidth}{0.8pt}
+\newcommand{\dashedwidth}{0.5pt}
+\newcommand{\smallersize}{\relsize{-3}}
+
+\newcounter{@myangle}
+\newcounter{@inangle}
+\newcounter{@dx}
+\newcounter{@dy}
+
+\newif\ifgridon
+\gridonfalse
+\newcounter{@gridwidth}
+\newcounter{@gridright}
+\newcounter{@gridheight}
+\newcounter{@gridtop}
+
+\newcounter{@diagwidth}
+\newcounter{diagheight}
+
+\setcounter{diagheight}{75}
+\ifdim\paperwidth>\paperheight
+ \setcounter{diagheight}{65}
+\fi
+
+\newcounter{chart} % in case there is more than one chart in the document
+\newcounter{xNW}\newcounter{yNW} % coordinates of NW corner of a node
+\newcounter{xSE}\newcounter{ySE} % coordinates of SE corner of a node
+
+\def\@unitmult{\unit * 5} % used for the grid and as the minimum height of half-course boxes
+
+\def\@outputImapData#1,#2:#3#4#5{%
+% #1,#2 coordinates
+% #3 URL
+% #4 horizontal delta
+% #5 vertical delta
+%
+\setcounter{xNW}{\dpi * \ratio{\zposx{gridOrigin_\thechart}sp}{1in}}% # of pixels from left edge to origin
+\addtocounter{xNW}{(#1-#4)*\PixelsPerUnit}% add # pixels from origin to node (-#4 units)
+\setcounter{xSE}{\dpi * \ratio{\zposx{gridOrigin_\thechart}sp}{1in}}%
+\addtocounter{xSE}{(#1+#4)*\PixelsPerUnit}% add # pixels from origin to node (+#4 units)
+
+\setcounter{yNW}{ \dpi * \ratio{\paperheight}{1in}} % # of pixels for the whole page
+\addtocounter{yNW}{ 0 - \dpi * \ratio{\zposy{gridOrigin_\thechart}sp}{1in}} % subtract # pixels from bottom edge to origin
+\addtocounter{yNW}{0 - (#2 - #5) * \PixelsPerUnit } % subtract # of pixels from origin to node (-#5)
+\setcounter{ySE}{ \dpi * \ratio{\paperheight}{1in}}
+\addtocounter{ySE}{0 - \dpi * \ratio{\zposy{gridOrigin_\thechart}sp}{1in}}
+\addtocounter{ySE}{0 - (#2 + #5) * \PixelsPerUnit } % subtract # of pixels from origin to node (+#5)
+
+\immediate\write\@imapfile{<area shape=rect coords="\thexNW,\theyNW,\thexSE,\theySE" href="\CourseURL{#1}{#2}{#3}" target="_new">}%
+}
+
+\def\@halfcourse#1,#2:#3#4#5{%
+\node[draw,thin,fill=\background,rounded corners=2pt,inner ysep=0.5pt,minimum height=\@unitmult](x#1y#2) at (#1,#2)%
+{\textsf{%
+\renewcommand{\arraystretch}{0.8}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}%
+};%
+\@outputImapData#1,#2:{#3}{4}{2}%
+}
+
+\def\@reqhalfcourse#1,#2:#3#4#5{%
+\node[draw,line width=\boldwidth,fill=\background,rounded corners=2pt,inner ysep=0.5pt,minimum height=\@unitmult](x#1y#2) at (#1,#2)%
+{\textsf{\textbf{%
+\renewcommand{\arraystretch}{0.8}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}%
+}};%
+\@outputImapData#1,#2:{#3}{4}{2}%
+}
+
+\def\@fullcourse#1,#2:#3#4#5{%
+\node[draw,thin,fill=\background,rounded corners=2pt,inner ysep=0.5pt](x#1y#2) at (#1,#2)%
+{\textsf{%
+\renewcommand{\arraystretch}{1.7}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}%
+};%
+\@outputImapData#1,#2:{#3}{4}{5}%
+}
+
+
+\def\@reqfullcourse#1,#2:#3#4#5{%
+\node[draw,line width=\boldwidth,fill=\background,rounded corners=2pt,inner ysep=0.5pt](x#1y#2) at (#1,#2)%
+{\textsf{\textbf{%
+\renewcommand{\arraystretch}{1.7}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}}%
+};%
+\@outputImapData#1,#2:{#3}{4}{5}%
+}
+
+
+\def\@mini#1,#2:#3{%
+\node[fill=white,draw=white,inner ysep=1.8pt](x#1y#2) at (#1,#2)%
+{\textsf{%
+\href{\CourseURL{#1}{#2}{#3}}{%
+\mbox{\smallersize#3}}}};%
+\@outputImapData#1,#2:{#3}{2}{1}%
+}
+
+\def\@text#1,#2:#3{%
+% include coordinates if grid on, but don't hyperlink if grid off
+\ifgridon
+ \node[fill=white,draw=white,inner ysep=1.8pt](x#1y#2) at (#1,#2)%
+{\href{coord: #1,#2}{\mbox{#3}}};%
+\else
+ \node[fill=white,draw=white,inner ysep=1.8pt](x#1y#2) at (#1,#2){\mbox{#3}};%
+\fi
+}
+
+\def\@prereq#1,#2,#3,#4:{%
+ \setcounter{@dy}{#2-#4}
+ \ifnum\the@dy<10
+ \@straight#1,#2,#3,#4:
+ \else\ifnum#1=#3
+ \@straight#1,#2,#3,#4:
+ \else\ifnum#2=#4
+ \@straight#1,#2,#3,#4:
+ \else
+ \@prereqc#1,#2,#3,#4;\DefaultCurvature:
+ \fi\fi\fi
+}
+
+\def\@prereqc#1,#2,#3,#4;#5:{%
+ \ifnum#5=0
+ \@straight#1,#2,#3,#4:
+ \else
+ \@curved#1,#2,#3,#4;#5:
+ \fi
+}
+
+\def\@recomm#1,#2,#3,#4:{%
+ \setcounter{@dy}{#2-#4}
+ \ifnum\the@dy<10
+ \@straightDashed#1,#2,#3,#4:
+ \else\ifnum#1=#3
+ \@straightDashed#1,#2,#3,#4:
+ \else\ifnum#2=#4
+ \@straightDashed#1,#2,#3,#4:
+ \else
+ \@recommc#1,#2,#3,#4;\DefaultCurvature:
+ \fi\fi\fi
+}
+
+\def\@recommc#1,#2,#3,#4;#5:{%
+ \ifnum#5=0
+ \@straightDashed#1,#2,#3,#4:
+ \else
+ \@curvedDashed#1,#2,#3,#4;#5:
+ \fi
+}
+
+\def\@coreq#1,#2,#3,#4:{%
+ \setcounter{@dy}{#2-#4}
+ \ifnum\the@dy<10
+ \@straightDotted#1,#2,#3,#4:
+ \else\ifnum#1=#3
+ \@straightDotted#1,#2,#3,#4:
+ \else\ifnum#2=#4
+ \@straightDotted#1,#2,#3,#4:
+ \else
+ \@coreqc#1,#2,#3,#4;\DefaultCurvature:
+ \fi\fi\fi
+}
+
+\def\@coreqc#1,#2,#3,#4;#5:{%
+ \ifnum#5=0
+ \@straightDotted#1,#2,#3,#4:
+ \else
+ \@curvedDotted#1,#2,#3,#4;#5:
+ \fi
+}
+
+
+
+\def\@straight#1,#2,#3,#4:{%
+\ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) -- (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}};
+\else
+ \draw[draw=white,line width=1.5pt](x#1y#2) -- (x#3y#4) ;
+\fi
+ \draw[-latex',draw=white,very thin](x#1y#2) -- (x#3y#4) ;
+ \draw[line width=\solidwidth](x#1y#2) -- (x#3y#4) ;
+}
+
+
+\def\@curved#1,#2,#3,#4;#5:{
+
+ \ifnum#3<#1
+ \setcounter{@dx}{#1-#3}
+ \setcounter{@myangle}{(-#5) * \the@dx * \the@dy * 2}
+ \else
+ \setcounter{@dx}{#3-#1}
+ \setcounter{@myangle}{#5 * \the@dx * \the@dy * 2}
+ \fi
+ \setcounter{@myangle}{\the@myangle / ((\the@dx + \the@dy) * (\the@dx + \the@dy))}
+ \setcounter{@inangle}{180 - \the@myangle}
+ \ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}} ;
+ \else
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \fi
+ \draw[-latex',draw=white,very thin](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \draw[line width=\solidwidth](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+}
+
+\def\@straightDashed#1,#2,#3,#4:{%
+\ifgridon
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}};
+\else
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4);
+\fi
+\draw[-latex',draw=white,very thin] (x#1y#2) -- (x#3y#4);
+\draw[dashed,line width=\dashedwidth] (x#1y#2) -- (x#3y#4);
+}
+
+\def\@curvedDashed#1,#2,#3,#4;#5:{
+ \ifnum#3<#1
+ \setcounter{@dx}{#1-#3}
+ \setcounter{@myangle}{(-#5) * \the@dx * \the@dy * 2}
+ \else
+ \setcounter{@dx}{#3-#1}
+ \setcounter{@myangle}{#5 * \the@dx * \the@dy * 2}
+ \fi
+ \setcounter{@myangle}{\the@myangle / ((\the@dx + \the@dy) * (\the@dx + \the@dy))}
+ \setcounter{@inangle}{180 - \the@myangle}
+ \ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}} ;
+ \else
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \fi
+ \draw[-latex',draw=white,very thin](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \draw[dashed,line width=\dashedwidth](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+}
+
+\def\@straightDotted#1,#2,#3,#4:{%
+\ifgridon
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}};
+\else
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4);
+\fi
+\draw[-latex',draw=white,very thin] (x#1y#2) -- (x#3y#4);
+\draw[loosely dotted,line width=\dottedwidth] (x#1y#2) -- (x#3y#4);
+}
+
+\def\@curvedDotted#1,#2,#3,#4;#5:{
+ \ifnum#3<#1
+ \setcounter{@dx}{#1-#3}
+ \setcounter{@myangle}{(-#5) * \the@dx * \the@dy * 2}
+ \else
+ \setcounter{@dx}{#3-#1}
+ \setcounter{@myangle}{#5 * \the@dx * \the@dy * 2}
+ \fi
+ \setcounter{@myangle}{\the@myangle / ((\the@dx + \the@dy) * (\the@dx + \the@dy))}
+ \setcounter{@inangle}{180 - \the@myangle}
+ \ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}} ;
+ \else
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \fi
+ \draw[-latex',draw=white,very thin](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \draw[loosely dotted,line width=\dottedwidth](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+}
+
+\def\solidarrow{%
+\tikz[x=\unit,y=\unit,baseline=-0.5ex]
+\draw[-latex',line width =\solidwidth] (0,0) -- (4,0);
+}
+
+\def\dottedarrow{%
+\tikz[x=\unit,y=\unit,baseline=-0.5ex]
+\draw[loosely dotted,line width=\dottedwidth,-latex'] (0,0) -- (4,0);
+}
+
+\def\dashedarrow{%
+\tikz[x=\unit,y=\unit,baseline=-0.5ex]
+\draw[dashed,line width=\dashedwidth,-latex'] (0,0) -- (4,0);
+}
+
+\def\lightbox{%
+\tikz[thin,baseline=-0.5ex]\node[draw,fill=\background,rounded corners=2pt,inner sep=1.5pt]
+{\textsf{light}};}
+
+\def\boldbox{%
+\tikz[baseline=-0.65ex]\node[draw,line width=\boldwidth,fill=\background,rounded corners=2pt,inner sep=1.8pt]
+{\textsf{\textbf{bold}}};}
+
+\def\@grid{
+ \gridontrue
+ \renewcommand{\CourseURL}[3]{coord: ##1,##2} % "coord:" makes it look like a URI
+
+ \draw[line width=0.3pt,draw=verylight] (0,0) grid [step=1] (\value{@gridright},\value{@gridtop});
+ \draw[line width=0.4pt,draw=somewhatlight] (0,0) grid [step=5] (\value{@gridright},\value{@gridtop});
+
+ \foreach \i in {0,10,...,\value{@gridright}}
+ \node at (\i,-4){\mbox{\textsf{\small \i}}};
+
+ \foreach \i in {0,10,...,\value{@gridtop}}
+ \node at (-5,\i){\mbox{\textsf{\small \i}}};
+
+ \foreach \i in {0,10,...,\value{@gridright}}
+ \node at (\i,\value{@gridtop}+4){\mbox{\textsf{\small \i}}};
+
+ \foreach \i in {0,10,...,\value{@gridtop}}
+ \node at (\value{@gridright}+5,\i){\mbox{\textsf{\small \i}}};
+
+ % anchors are to allow computation of coordinates from mouse clicks in kpdf/okular:
+ % latex/dvips requires non-null href box
+ \node at (-5,-4) {\href{anchor: -5,-4}{\kern1sp}};
+ \setcounter{@gridtop}{\value{@gridtop} + 4}
+ \setcounter{@gridright}{\value{@gridright} + 5}
+ \node at (\the@gridright,\the@gridtop) {\href{anchor: \the@gridright,\the@gridtop}{\kern1sp}};
+}
+
+%
+%
+% \begin{chart} ... \end{chart}
+%
+%
+
+\newenvironment{chart}
+{ \setcounter{@diagwidth}{10 + 1 * \ratio{\textwidth}{\unit}}
+
+ \newwrite\@imapfile % image-map data
+ \newwrite\@scriptfile % shell script to generate image file
+ \ifthenelse{\value{chart} = 0}
+ { \immediate\openout\@imapfile=\jobname.map
+ \immediate\write\@imapfile{<map name="\jobname">}
+ }
+ { \immediate\openout\@imapfile=\jobname_\thechart.map
+ \immediate\write\@imapfile{<map name="\jobname_\thechart">}
+ }
+
+ \let\halfcourse=\@halfcourse
+ \let\reqhalfcourse=\@reqhalfcourse
+ \let\fullcourse=\@fullcourse
+ \let\reqfullcourse=\@reqfullcourse
+ \let\mini=\@mini
+ \let\text=\@text
+ \let\prereq=\@prereq
+ \let\prereqc=\@prereqc
+ \let\coreq=\@coreq
+ \let\coreqc=\@coreqc
+ \let\recomm=\@recomm
+ \let\recommc=\@recommc
+ \let\grid=\@grid
+ \begin{tikzpicture}[x=\unit,y=\unit]
+ \tikzstyle{every rectangle node}=[inner xsep=1.8pt]
+ \setcounter{@gridwidth}{(\the@diagwidth-5) / 10}
+ \setcounter{@gridright}{10 * \value{@gridwidth}}
+ \setcounter{@gridheight}{\thediagheight / 10}
+ \setcounter{@gridtop}{10 * \value{@gridheight} }
+ \useasboundingbox (0,-2) rectangle (\value{@gridright},\value{@gridtop});
+ node at (0,0) {\kern1sp\zsavepos{gridOrigin_\thechart}};
+ % access absolute page coordinates of the origin using \zposx and \zposy
+}
+{
+ \end{tikzpicture}
+ \write\@imapfile{</map>}
+ \closeout\@imapfile
+ \zsavepos{EndOfChart_\thechart} % determine cropping coordinates
+ \ifdim\paperwidth<\paperheight
+ % portrait mode
+ \setcounter{xSE}{\dpi * \ratio{\zposx{EndOfChart_\thechart}sp}{1in}}%
+ \setcounter{ySE}{ \dpi * \ratio{\paperheight}{1in}}
+ \addtocounter{ySE}{0 - \dpi * \ratio{\zposy{EndOfChart_\thechart}sp}{1in}}
+ \addtocounter{ySE}{0 + 2 * \PixelsPerUnit } % bottom margin
+ \else
+ % landscape mode
+ \setcounter{xSE}{ \dpi * \ratio{\paperwidth}{1in}}
+ \addtocounter{xSE}{0 - \dpi * \ratio{\zposx{EndOfChart_\thechart}sp}{1in}}%
+ \addtocounter{xSE}{0 + 2 * \PixelsPerUnit } % bottom margin
+ \setcounter{ySE}{ \dpi * \ratio{\paperheight}{1in}}
+ \addtocounter{ySE}{ 0 - \dpi * \ratio{\zposy{EndOfChart_\thechart}sp}{1in}}
+ \fi
+ \edef\HasH{\expandafter\@gobble\string\#}
+ \ifthenelse{\value{chart} = 0}
+ { % generate a script to crop a chart image
+ \immediate\openout\@scriptfile=\jobname.sh
+ \immediate\write\@scriptfile{\HasH!/bin/sh}
+ % defer remaining output till cropping coordinates are available
+ \write\@scriptfile{mogrify -crop \thexSE x\theySE +0+0 \jobname.png}
+ \write\@scriptfile{exit 0}
+ \closeout\@scriptfile
+ }
+ { % more than one chart; unlikely a script would be usable
+ }
+ \stepcounter{chart}
+}