[comp.text] PicTeX, part 1 of 3

grunwald@uiucdcsm.cs.uiuc.edu (01/18/88)

Several comp.text readers have asked for this, so I'm just dumping it to the
network. This is the source for the PicTeX macros writte by Michael Wichura
at the U. of Chicago. I've asked him if it's O.k. to broadcast this.

The manual for PicTeX is available at the address in the 'README' file.
This note contains part 1 of 3. The 3 files must be cat'd together, and
then unshared (sorry, we only have a simple shar program).
----------------------------------------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh.
# The following files will be created:
#	Pictex/README
#	Pictex/Makefile
#	Pictex/latexpicobjs.tex
#	Pictex/pictex.tex
#	Pictex/postpictex.tex
#	Pictex/prepictex.tex
# This archive created: Sun Jan 17 11:22:30 1988
export PATH; PATH=/bin:$PATH
if test -f 'Pictex/README'
then
	echo shar: over-writing existing file "'Pictex/README'"
fi
cat << \SHAR_EOF > 'Pictex/README'
These macros were provided by Michael Wichura, of the Department
of Statistics at the University of Chicago.

I most emphatically did not develop them. The manual is available from
Michael Wichure at the address below. It's about 80 pages long and contains
many examples.

PiCTeX can be used with LaTeX or plain TeX. The only problems I have
encountered with it are that it can require large buffer spaces in TeX,
particularly if you're using LaTeX & floating your figures.

---

From wichura@galton.uchicago.edu Mon Jan 11 10:40:17 1988
To: grunwald@m.cs.uiuc.edu
Subject: re: Pictex
Status: RO

Dear Dirk

Sure, go ahead and put the macros in a USENET newsgroup. 
That should help get the monkey off your back.  You can tell
people that they can get a prepublication version of the manual for
$15.00 by sending a check to me at the address below. That
will move the monkey to my back, where it belongs.

  Michael J. Wichura
  Department of Statistics
  University of Chicago
  5734 University Avenue
  Chicago, IL. 60637-4931

<text omitted>
SHAR_EOF
if test -f 'Pictex/Makefile'
then
	echo shar: over-writing existing file "'Pictex/Makefile'"
fi
cat << \SHAR_EOF > 'Pictex/Makefile'
LIB	=/usr/local/lib/tex82/localmacros

LAPARTS	= prepictex.tex pictex.tex postpictex.tex
TEXPARTS = latexpicobjs.tex pictex.tex

all:	piclatex.sty $(TEXPARTS)

install: all
	install -c -m 444 latexpicobjs.tex $(LIB)
	install -c -m 444 pictex.tex $(LIB)
	install -c -m 444 prepictex.tex $(LIB)
	install -c -m 444 postpictex.tex $(LIB)
	install -c -m 444 piclatex.sty $(LIB)

piclatex.sty:
	cat $(LAPARTS)  \
	| sed -e '/^%/d' -e '/^[ 	]*$$/d' \
	| cat -s > piclatex.sty

$(LAPARTS) $(TEXPARTS):
	co -q $@

SHAR_EOF
if test -f 'Pictex/latexpicobjs.tex'
then
	echo shar: over-writing existing file "'Pictex/latexpicobjs.tex'"
fi
cat << \SHAR_EOF > 'Pictex/latexpicobjs.tex'
% This is latexpicobjs.tex, Version 1.1  9/11/87

% This file makes the LaTeX line, vector, circle, and oval constructions 
% available to PiCTeX users who are running under plain TeX.
% It is distributed with Leslie Lamport's permission.

% Do not \input the files prepictex.tex and postpictex.tex along with
% this file.

\catcode`@=11 \catcode`!=11

% Save the meaning of plain TeX's \line command
\let\!texline=\line

% load LaTeX line and circle fonts
\font\tenln=line10
\font\tenlnw=linew10
\font\tencirc=circle10
\font\tencircw=circlew10

% set up LaTeX hacks
\let\@tfor=\!tfor
\let\@ifnextchar=\!ifnextchar

\def\@whilenoop#1{}
\def\@whiledim#1\do #2{\ifdim #1\relax#2\@iwhiledim{#1\relax#2}\fi}
\def\@iwhiledim#1{\ifdim #1\let\@nextwhile=\@iwhiledim 
        \else\let\@nextwhile=\@whilenoop\fi\@nextwhile{#1}}

\def\@ifstar#1#2{\@ifnextchar *{\def\@tempa*{#1}\@tempa}{#2}}

\def\@height{height}
\def\@depth{depth}
\def\@width{width}


% The following are slightly modified versions of the LaTeX
% \@badlinearg and \@warning commands.
\def\!@badlinearg{%
   \errmessage{Bad LaTeX \string\line\space or \string\vector
   \space argument. See the LaTeX manual for an explanation.}}
\def\!@warning#1{\immediate\write16{LaTeX Warning: #1.}\ignorespaces}

% allocate registers
\newdimen\@tempdima
\newdimen\@tempdimb
\newcount\@tempcnta
\newcount\@tempcntb
\newbox\@tempboxa

% Until further notice (near the end) what follows are 
% (slightly modified versions of) LaTeX's line/vector/circle/oval macros.
% See the latex.tex macro package for commentary.
\newdimen\@wholewidth
\newdimen\@halfwidth
\newdimen\unitlength \unitlength =1pt

\def\thinlines{%
  \let\@linefnt\tenln \let\@circlefnt\tencirc
  \@wholewidth\fontdimen8\tenln \@halfwidth .5\@wholewidth}
\def\thicklines{%
  \let\@linefnt\tenlnw \let\@circlefnt\tencircw
  \@wholewidth\fontdimen8\tenlnw \@halfwidth .5\@wholewidth}

\newif\if@negarg

\def\line(#1,#2)#3{%
  \@xarg #1\relax 
  \@yarg #2\relax
  \@linelen=#3\unitlength
  \ifnum\@xarg =0 
    \@vline 
  \else 
    \ifnum\@yarg =0 
      \@hline 
    \else 
      \@sline
    \fi
  \fi}

\def\@sline{%
  \ifnum\@xarg< 0 
    \@negargtrue 
    \@xarg -\@xarg 
    \@yyarg -\@yarg
  \else 
    \@negargfalse 
    \@yyarg \@yarg 
  \fi
  \ifnum \@yyarg >0 
    \@tempcnta\@yyarg 
  \else 
    \@tempcnta -\@yyarg 
  \fi
  \ifnum\@tempcnta>6 
    \!@badlinearg
    \@tempcnta0 
  \fi
  \ifnum\@xarg>6 
    \!@badlinearg
    \@xarg 1 
  \fi
  \setbox\@linechar\hbox{\@linefnt\@getlinechar(\@xarg,\@yyarg)}%
  \ifnum \@yarg >0 
    \let\@upordown\raise 
    \@clnht\z@
  \else
    \let\@upordown\lower 
    \@clnht \ht\@linechar
  \fi
  \@clnwd=\wd\@linechar
  \if@negarg 
    \hskip -\wd\@linechar 
    \def\@tempa{\hskip -2\wd\@linechar}%
  \else
    \let\@tempa\relax 
  \fi
  \@whiledim \@clnwd <\@linelen \do
    {\@upordown\@clnht\copy\@linechar
    \@tempa
    \advance\@clnht \ht\@linechar
    \advance\@clnwd \wd\@linechar}%
  \advance\@clnht -\ht\@linechar
  \advance\@clnwd -\wd\@linechar
  \@tempdima\@linelen
  \advance\@tempdima -\@clnwd
  \@tempdimb\@tempdima
  \advance\@tempdimb -\wd\@linechar
  \if@negarg 
    \hskip -\@tempdimb 
  \else 
    \hskip \@tempdimb 
  \fi
  \multiply\@tempdima \@m
  \@tempcnta \@tempdima 
  \@tempdima \wd\@linechar 
  \divide\@tempcnta \@tempdima
  \@tempdima \ht\@linechar 
  \multiply\@tempdima \@tempcnta
  \divide\@tempdima \@m
  \advance\@clnht \@tempdima
  \ifdim \@linelen <\wd\@linechar
    \hskip \wd\@linechar
  \else
    \@upordown\@clnht\copy\@linechar
  \fi}

\def\@hline{%
  \ifnum \@xarg <0 \hskip -\@linelen \fi
  \vrule \@height \@halfwidth \@depth \@halfwidth \@width \@linelen
  \ifnum \@xarg <0 \hskip -\@linelen \fi}

\def\@getlinechar(#1,#2){%
  \@tempcnta#1\relax
  \multiply\@tempcnta 8
  \advance\@tempcnta -9 
  \ifnum #2>0 
    \advance\@tempcnta #2\relax
  \else
    \advance\@tempcnta -#2\relax
    \advance\@tempcnta 64 
  \fi
  \char\@tempcnta}

\def\vector(#1,#2)#3{%
  \@xarg #1\relax 
  \@yarg #2\relax
  \@tempcnta \ifnum\@xarg<0 -\@xarg\else\@xarg\fi
  \ifnum\@tempcnta<5\relax
    \@linelen=#3\unitlength
    \ifnum\@xarg =0 
      \@vvector 
    \else 
      \ifnum\@yarg =0 
        \@hvector 
      \else 
        \@svector
      \fi
    \fi
  \else
    \!@badlinearg
  \fi}

\def\@hvector{%
  \@hline
  \hbox to 0pt{%
    \@linefnt 
    \ifnum \@xarg <0 
      \@getlarrow(1,0)\hss
    \else
      \hss\@getrarrow(1,0)%
    \fi}}

\def\@vvector{\ifnum \@yarg <0 \@downvector \else \@upvector \fi}

\def\@svector{%
  \@sline
  \@tempcnta\@yarg 
  \ifnum\@tempcnta <0 
    \@tempcnta=-\@tempcnta
  \fi
  \ifnum\@tempcnta <5
    \hskip -\wd\@linechar
    \@upordown\@clnht \hbox{%
      \@linefnt  
      \if@negarg 
        \@getlarrow(\@xarg,\@yyarg) 
      \else 
        \@getrarrow(\@xarg,\@yyarg) 
      \fi}%
  \else
    \!@badlinearg
  \fi}

\def\@getlarrow(#1,#2){%
  \ifnum #2 =\z@ 
    \@tempcnta='33
  \else
    \@tempcnta=#1\relax
    \multiply\@tempcnta \sixt@@n 
    \advance\@tempcnta -9 
    \@tempcntb=#2\relax
    \multiply\@tempcntb \tw@
    \ifnum \@tempcntb >0 
      \advance\@tempcnta \@tempcntb\relax
    \else\advance\@tempcnta -\@tempcntb
      \advance\@tempcnta 64
    \fi
  \fi
  \char\@tempcnta}

\def\@getrarrow(#1,#2){%
  \@tempcntb=#2\relax
  \ifnum\@tempcntb < 0 
    \@tempcntb=-\@tempcntb\relax
  \fi
  \ifcase \@tempcntb\relax 
    \@tempcnta='55 
  \or 
    \ifnum #1<3 
      \@tempcnta=#1\relax
      \multiply\@tempcnta 24 
      \advance\@tempcnta -6 
    \else 
      \ifnum #1=3 
        \@tempcnta=49
      \else
        \@tempcnta=58 
      \fi
    \fi
  \or 
    \ifnum #1<3 
      \@tempcnta=#1\relax
      \multiply\@tempcnta 24 
      \advance\@tempcnta -3 
    \else 
      \@tempcnta=51
    \fi
  \or 
    \@tempcnta=#1\relax
    \multiply\@tempcnta \sixt@@n 
    \advance\@tempcnta -\tw@ 
  \else
    \@tempcnta=#1\relax
    \multiply\@tempcnta \sixt@@n 
    \advance\@tempcnta 7 
  \fi
  \ifnum #2<0 
    \advance\@tempcnta 64 
  \fi
  \char\@tempcnta}

\def\@vline{%
  \ifnum \@yarg <0 
    \@downline 
  \else 
    \@upline
  \fi}

\def\@upline{%
  \hbox to \z@{%
    \hskip -\@halfwidth 
    \vrule \@width \@wholewidth \@height \@linelen \@depth \z@\hss}}

\def\@downline{%
  \hbox to \z@{%
    \hskip -\@halfwidth 
    \vrule \@width \@wholewidth \@height \z@ \@depth \@linelen \hss}}

\def\@upvector{%
  \@upline
  \setbox\@tempboxa\hbox{%
    \@linefnt\char'66}%
    \raise \@linelen \hbox to\z@{\lower \ht\@tempboxa\box\@tempboxa\hss}}

\def\@downvector{%
  \@downline
  \lower \@linelen \hbox to \z@{\@linefnt\char'77\hss}}


\newif\if@ovt 
\newif\if@ovb 
\newif\if@ovl 
\newif\if@ovr 
\newdimen\@ovxx
\newdimen\@ovyy
\newdimen\@ovdx
\newdimen\@ovdy
\newdimen\@ovro
\newdimen\@ovri

\def\@getcirc#1{%
  \@tempdima #1\relax 
  \@tempcnta\@tempdima
  \@tempdima 4pt\relax 
  \divide\@tempcnta\@tempdima
  \ifnum \@tempcnta > 10\relax 
    \@tempcnta 10\relax
  \fi
  \ifnum \@tempcnta >\z@ 
    \advance\@tempcnta \m@ne
  \else 
    \!@warning{Oval too small}%
  \fi
  \multiply\@tempcnta 4\relax
  \setbox \@tempboxa \hbox{\@circlefnt \char \@tempcnta}%
  \@tempdima \wd \@tempboxa}

\def\@put#1#2#3{%
  \raise #2\hbox to \z@{\hskip #1#3\hss}}

\def\oval(#1,#2){%
  \@ifnextchar[{\@oval(#1,#2)}{\@oval(#1,#2)[]}}

\def\@oval(#1,#2)[#3]{%
  \begingroup
    \boxmaxdepth \maxdimen
    \@ovttrue \@ovbtrue \@ovltrue \@ovrtrue
    \@tfor\@tempa :=#3\do{%
      \csname @ov\@tempa false\endcsname}%
    \@ovxx #1\unitlength 
    \@ovyy #2\unitlength
    \@tempdimb \ifdim \@ovyy >\@ovxx \@ovxx\else \@ovyy \fi
    \@getcirc \@tempdimb
    \@ovro \ht\@tempboxa 
    \@ovri \dp\@tempboxa
    \@ovdx\@ovxx 
    \advance\@ovdx -\@tempdima 
    \divide\@ovdx \tw@
    \@ovdy\@ovyy 
    \advance\@ovdy -\@tempdima 
    \divide\@ovdy \tw@
    \@circlefnt 
    \setbox\@tempboxa \hbox{%
      \if@ovr 
        \@ovvert32\kern -\@tempdima 
      \fi
      \if@ovl 
        \kern \@ovxx 
        \@ovvert01\kern -\@tempdima 
        \kern -\@ovxx 
      \fi
      \if@ovt 
        \@ovhorz \kern -\@ovxx 
      \fi
      \if@ovb 
        \raise \@ovyy \@ovhorz 
      \fi}%
    \advance\@ovdx\@ovro
    \advance\@ovdy\@ovro 
    \ht\@tempboxa\z@ 
    \dp\@tempboxa\z@
    \@put{-\@ovdx}{-\@ovdy}{\box\@tempboxa}%
  \endgroup}

\def\@ovvert#1#2{%
  \vbox to \@ovyy{%
    \if@ovb 
      \@tempcntb \@tempcnta 
      \advance \@tempcntb by #1\relax
      \kern -\@ovro 
      \hbox{\char \@tempcntb}%
      \nointerlineskip
    \else 
      \kern \@ovri 
      \kern \@ovdy 
    \fi
    \leaders\vrule width \@wholewidth\vfil 
    \nointerlineskip
    \if@ovt 
      \@tempcntb \@tempcnta 
      \advance \@tempcntb by #2\relax
      \hbox{\char \@tempcntb}%
    \else 
      \kern \@ovdy 
      \kern \@ovro 
    \fi}}

\def\@ovhorz{%
  \hbox to \@ovxx{%
    \kern \@ovro
    \if@ovr 
    \else 
      \kern \@ovdx 
    \fi
    \leaders \hrule height \@wholewidth \hfil
    \if@ovl 
    \else 
      \kern \@ovdx 
    \fi
    \kern \@ovri}}

\def\circle{%
  \@ifstar{\@dot}{\@circle}}
\def\@circle#1{%
  \begingroup 
    \boxmaxdepth \maxdimen 
    \@tempdimb #1\unitlength
    \ifdim \@tempdimb >15.5pt\relax 
      \@getcirc\@tempdimb
      \@ovro\ht\@tempboxa 
      \setbox\@tempboxa\hbox{%
        \@circlefnt
        \advance\@tempcnta\tw@ 
        \char \@tempcnta
        \advance\@tempcnta\m@ne 
        \char \@tempcnta 
        \kern -2\@tempdima
        \advance\@tempcnta\tw@
        \raise \@tempdima \hbox{\char\@tempcnta}%
        \raise \@tempdima \box\@tempboxa}%
      \ht\@tempboxa\z@ 
      \dp\@tempboxa\z@
      \@put{-\@ovro}{-\@ovro}{\box\@tempboxa}%
    \else  
      \@circ\@tempdimb{96}%
    \fi
  \endgroup}

\def\@dot#1{%
  \@tempdimb #1\unitlength 
  \@circ\@tempdimb{112}}

\def\@circ#1#2{%
  \@tempdima #1\relax 
  \advance\@tempdima .5pt\relax
  \@tempcnta\@tempdima 
  \@tempdima 1pt\relax
  \divide\@tempcnta\@tempdima 
  \ifnum\@tempcnta > 15\relax 
  \@tempcnta 15\relax \fi    
  \ifnum 
    \@tempcnta >\z@ 
    \advance\@tempcnta\m@ne
  \fi
  \advance\@tempcnta #2\relax
  \@circlefnt 
  \char\@tempcnta}

\thinlines   

\newcount\@xarg
\newcount\@yarg
\newcount\@yyarg
\newcount\@multicnt 
\newdimen\@xdim
\newdimen\@ydim
\newbox\@linechar
\newdimen\@linelen
\newdimen\@clnwd
\newdimen\@clnht

% That's the end of the definitions of lines/vectors/circles/ovals.


% Save LaTeX's meaning of \line
\let\!latexline=\line

% Set variable meaning of line
\def\line{\!ifnextchar(\!latexline\!texline}

\catcode`@=12 \catcode`!=12
SHAR_EOF
if test -f 'Pictex/pictex.tex'
then
	echo shar: over-writing existing file "'Pictex/pictex.tex'"
fi
cat << \SHAR_EOF > 'Pictex/pictex.tex'
% This is PiCTeX, Version 1.1   9/21/87
 
% CAVEAT: The PiCTeX manual often has a more lucid explanation
%   of any given topic than you will find in the internal documentation
%   of the macros.
 
% PiCTeX's commands can be classified into two groups: (1) public (or
%   external), and (2) private (or internal). The public macros are
%   discussed at length in the manual. The only discussion of the private
%   macros is the internal documentation. The private macros all have
%   names beginning with an exclamation point (!) of category code 11. 
%   Since in normal usage "!" has category code 12, these macros can't
%   be accessed or modified by the general user.
 
% The macros are organized into thematically related groups. For example,
%   the macros dealing with dots & dashes are all in the DASHPATTERN group.
%   The table below shows which macros are in which groups. The table
%   covers all public macros, and many (but not all) of PiCTeX's upper level
%   private macros. Following the table, the various groups are listed
%   in the order in which they appear in the table.
 
% *********************** TABLE OF GROUPS OF MACROS **********************
 
% HACKS:  Utility macros
%    \PiC
%    \PiCTeX
%    \placevalueinpts 
%    \!!loop 
%    \!cfor
%    \!copylist
%    \!ecfor
%    \!etfor
%    \!getnext
%    \!getnextvalueof
%    \!ifempty
%    \!ifnextchar
%    \!leftappend
%    \!listaddon 
%    \!loop
%    \!lop
%    \!mlap
%    \!not
%    \!removept
%    \!rightappend
%    \!tfor 
%    \!vmlap
%    \!wlet
 
% ALLOCATION:  Allocates registers
 
% AREAS: Deals with plot areas 
%    \axis
%    \grid 
%    \invisibleaxes
%    \normalgraphs 
%    \plotheading 
%    \setplotarea
%    \visibleaxes
 
% ARROWS:  Draws arrows
%    \arrow
%    \betweenarrows
 
% BARS:  Draws bars
%    \putbar 
%    \setbars
 
% BOXES:  Draws rectangles
%    \frame
%    \putrectangle 
%    \rectangle
%    \shaderectangleson
%    \shaderectanglesoff
 
% CURVES:  Upper level plot commands
%    \hshade 
%    \plot 
%    \sethistograms
%    \setlinear
%    \setquadratic
%    \vshade
 
% DASHPATTERNS:  Sets up dash patterns
%    \findlength 
%    \setdashes 
%    \setdashesnear
%    \setdashpattern
%    \setdots 
%    \setdotsnear 
%    \setsolid
%    \!dashingoff
%    \!dashingon
 
% DIVISION:  Does long division of dimension registers
%    \Divide 
%    \!divide
 
% ELLIPSES:  Draws ellipses and circles
%    \circulararc 
%    \ellipticalarc 
 
% RULES:  Draws rules, i.e., horizontal & vertical lines
%    \putrule 
%    \!putdashedhline
%    \!putdashedvline
%    \!puthline 
%    \!putsolidhline  
%    \!putsolidvline  
%    \!putvline
 
% LINEAR ARC:  Draws straight lines -- solid and dashed
%    \inboundscheckoff
%    \inboundscheckon
%    \!advancedashing 
%    \!drawlinearsegment
%    \!initinboundscheck
%    \!linearsolid
%    \!lineardashed
%    \!ljoin
%    \!plotifinbounds     
%    \!start 
 
% LOGTEN:  Log_10 function
%    \!logten
 
% PICTURES:  Basic setups for PiCtures; \put commands
%    \accountingoff
%    \accountingon
%    \beginpicture
%    \endpicture    
%    \endpicturesave 
%    \lines
%    \multiput
%    \put 
%    \setcoordinatemode
%    \setcoordinatesystem
%    \setdimensionmode
%    \stack 
%    \Lines
%    \Xdistance
%    \Ydistance
%    \!dimenput
%    \!ifcoordmode
%    \!ifdimenmode
%    \!setcoordmode
%    \!setdimenmode
%    \!setputobject
   
% PLOTTING:  Things to do with plotting
%    \dontsavelinesandcurves
%    \replot
%    \savelinesandcurves 
%    \setplotsymbol
%    \writesavefile 
%    \!plot
 
% PYTHAGORAS:  Euclidean distance function
%    \placehypotenuse 
%    \!Pythag
 
% QUADRATIC ARC:  Draws a quadratic arc
%    \!qjoin 
 
% ROTATIONS:  Handles rotations
%    \startrotation 
%    \stoprotation
%    \!rotateaboutpivot
%    \!rotateonly
 
% SHADING:  Handles shading
%    \setshadegrid 
%    \setshadesymbol
%    \!lshade
%    \!qshade
%    \!starthshade
%    \!startvshade  
 
% TICKS:  Draws ticks on graphs
%    \gridlines
%    \loggedticks
%    \nogridlines
%    \ticksin
%    \ticksout
%    \unloggesticks
 
% ***************** END OF TABLE OF GROUPS OF MACROS ********************


\catcode`!=11 %  ***** THIS MUST NEVER BE OMITTED
% *******************************
% *** HACKS  (Utility macros) ***
% *******************************
 
% ** User commands
% **   \PiC{P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC}
% **   \PiCTeX{\PiC\kern-.11em\TeX}
% **   \placevalueinpts of <DIMENSION REGISTER> in {CONTROL SEQUENCE}
  
% ** Internal commands
% **   \!ifnextchar{CHARACTER}{TRUE ACTION}{FALSE ACTION}
% **   \!tfor NAME := LIST \do {BODY}
% **   \!etfor NAME:= LIST \do {BODY}
% **   \!cfor NAME := LIST \do {BODY}
% **   \!ecfor NAME:= LIST \do {BODY}
% **   \!ifempty{MACRO}{TRUE ACTION}{FALSE ACTION}
% **   \!getnext\\ITEMfrom\LIST
% **   \!getnextvalueof\DIMEN\from\LIST
% **   \!copylist\LISTMACRO_A\to\LISTMACRO_B
% **   \!wlet\CONTROL_SEQUENCE_A=\CONTROL_SEQUENCE_B
% **   \!listaddon ITEM LIST
% **   \!rightappendITEM\withCS\to\LISTMACRO
% **   \!leftappendITEM\withCS\to\LISTMACRO
% **   \!lop\LISTMACRO\to\ITEM
% **   \!loop ... repeat
% **   \!!loop ... repeat
% **   \!removept{DIMENSION REGISTER}{CONTROL SEQUENCE}
% **   \!mlap{...}  
% **   \!vmlap{...}
% **   \!not{TEK if-CONDITION}

% ** First, here are the the PiCTeX logo, and the syllable PiC:
\def\PiC{P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC}
\def\PiCTeX{\PiC\kern-.11em\TeX}

% ** The following macro expands to parameter #2 or parameter #3 according to
% ** whether the next non-blank character following the macro is or is not #1. 
% ** Blanks following the macro are gobbled.
\def\!ifnextchar#1#2#3{%
  \let\!testchar=#1%
  \def\!first{#2}%
  \def\!second{#3}%
  \futurelet\!nextchar\!testnext}
\def\!testnext{%
  \ifx \!nextchar \!spacetoken 
    \let\!next=\!skipspacetestagain
  \else
    \ifx \!nextchar \!testchar
      \let\!next=\!first
    \else 
      \let\!next=\!second 
    \fi 
  \fi
  \!next}
\def\\{\!skipspacetestagain} 
  \expandafter\def\\ {\futurelet\!nextchar\!testnext} 
\def\\{\let\!spacetoken= } \\  %  ** set \spacetoken to a space token
 
 
% ** Borrow the "tfor" macro from Latex:
% **   \!tfor NAME := LIST \do {BODY}
% **   if, before expansion, LIST = T1 ... Tn,  where each  Ti  is a token
% **   or  {...},  then executes  BODY  n  times, with  NAME = Ti  on the
% **   i-th iteration.  Works for  n=0.
\def\!tfor#1:=#2\do#3{%
  \edef\!fortemp{#2}%
  \ifx\!fortemp\!empty 
    \else
    \!tforloop#2\!nil\!nil\!!#1{#3}%
  \fi}
\def\!tforloop#1#2\!!#3#4{%
  \def#3{#1}%
  \ifx #3\!nnil
    \let\!nextwhile=\!fornoop
  \else
    #4\relax
    \let\!nextwhile=\!tforloop
  \fi 
  \!nextwhile#2\!!#3{#4}}
 
 
% **   \!etfor NAME:= LIST\do {BODY}
% **   This is like \!cfor, but LIST is any balanced token list whose complete
% **     expansion has the form  T1 ... Tn
\def\!etfor#1:=#2\do#3{%
  \def\!!tfor{\!tfor#1:=}%
  \edef\!!!tfor{#2}%
  \expandafter\!!tfor\!!!tfor\do{#3}}
 
 
% **   modify the Latex \tfor (token-for) loop to a \cfor (comma-for) loop.
% **   \!cfor NAME := LIST \do {BODY}
% **     if, before expansion, LIST = a1,a2,...an, then executes  BODY n times,
% **     with  NAME = ai  on the i-th iteration.  Works for  n=0.
\def\!cfor#1:=#2\do#3{%
  \edef\!fortemp{#2}%
  \ifx\!fortemp\!empty 
  \else
    \!cforloop#2,\!nil,\!nil\!!#1{#3}%
  \fi}
\def\!cforloop#1,#2\!!#3#4{%
  \def#3{#1}%
  \ifx #3\!nnil
    \let\!nextwhile=\!fornoop 
  \else
    #4\relax
    \let\!nextwhile=\!cforloop
  \fi
  \!nextwhile#2\!!#3{#4}}
 
 
% **   \!ecfor NAME:= LIST\do {BODY}
% **   This is like \!cfor, but LIST is any balanced token list whose complete
% **     expansion has the form  a1,a2,...,an.
\def\!ecfor#1:=#2\do#3{%
  \def\!!cfor{\!cfor#1:=}%
  \edef\!!!cfor{#2}%
  \expandafter\!!cfor\!!!cfor\do{#3}}
 
 
\def\!empty{}
\def\!nnil{\!nil}
\def\!fornoop#1\!!#2#3{}
 
 
% **  \!ifempty{ARG}{TRUE ACTION}{FALSE ACTION}
\def\!ifempty#1#2#3{%
  \edef\!emptyarg{#1}%
  \ifx\!emptyarg\!empty
    #2%
  \else
    #3%
  \fi}
 
% **  \!getnext\\ITEMfrom\LIST
% **    \LIST has the form \\{item1}\\{item2}\\{item3}...\\{itemk}
% **    This routine sets \ITEM to item1, and cycles \LIST to
% **    \\{item2}\\{item3}...\\{itemk}\\{item1}
\def\!getnext#1\from#2{%
  \expandafter\!gnext#2\!#1#2}%
\def\!gnext\\#1#2\!#3#4{%
  \def#3{#1}%
  \def#4{#2\\{#1}}%
  \ignorespaces}
 
 
% ** \!getnextvalueof\DIMEN\from\LIST
% **   Similar to !getnext.  
% **   \LIST has the form \\{dimen1}\\{dimen2}\\{dimen3} ... 
% **   \DIMEN is a dimension register
% **   Works also for counts
%
\def\!getnextvalueof#1\from#2{%
  \expandafter\!gnextv#2\!#1#2}%
\def\!gnextv\\#1#2\!#3#4{%
  #3=#1%
  \def#4{#2\\{#1}}%
  \ignorespaces}
 
 
% ** \!copylist\LISTMACROA\to\LISTMACROB
% **   makes the replacement text of LISTMACRO B identical to that of
% **   list macro A.
\def\!copylist#1\to#2{%
  \expandafter\!!copylist#1\!#2}
\def\!!copylist#1\!#2{%
  \def#2{#1}\ignorespaces}
 
 
% **  \!wlet\CSA=\CSB
% **  lets control sequence \CSB = control sequence \CSA, and writes a
% **    message to that effect in the log file using plain TEK's \wlog
\def\!wlet#1=#2{%
  \let#1=#2 
  \wlog{\string#1=\string#2}}
 
% ** \!listaddon ITEM LIST
% ** LIST <-- LIST \\ ITEM
\def\!listaddon#1#2{%
  \expandafter\!!listaddon#2\!{#1}#2}
\def\!!listaddon#1\!#2#3{%
  \def#3{#1\\#2}}
 
% **  \!rightappendITEM\to\LISTMACRO
% **    \LISTMACRO --> \LISTMACRO\\{ITEM}
%\def\!rightappend#1\to#2{\expandafter\!!rightappend#2\!{#1}#2}
%\def\!!rightappend#1\!#2#3{\def#3{#1\\{#2}}}
 
 
% **  \!rightappendITEM\withCS\to\LISTMACRO
% **    \LISTMACRO --> \LISTMACRO||CS||{ITEM}
\def\!rightappend#1\withCS#2\to#3{\expandafter\!!rightappend#3\!#2{#1}#3}
\def\!!rightappend#1\!#2#3#4{\def#4{#1#2{#3}}}
 
 
% **  \!leftappendITEM\withCS\to\LISTMACRO
% **    \LISTMACRO --> CS||{ITEM}||\LISTMACRO
\def\!leftappend#1\withCS#2\to#3{\expandafter\!!leftappend#3\!#2{#1}#3}
\def\!!leftappend#1\!#2#3#4{\def#4{#2{#3}#1}}
 
 
% **  \!lop\LISTMACRO\to\ITEM
% **    \\{item1}\\{item2}\\{item3} ... --> \\{item2}\\{item3} ...
% **    item1 --> \ITEM
\def\!lop#1\to#2{\expandafter\!!lop#1\!#1#2}
\def\!!lop\\#1#2\!#3#4{\def#4{#1}\def#3{#2}}
 
 
% **  \!placeNUMBER\of\LISTMACRO\in\ITEM
% **    the NUMBERth item of \LISTMACRO --> replacement text of \ITEM
%\def\!place#1\of#2\in#3{\def#3{\outofrange}%
%{\count0=#1\def\\##1{\advance\count0-1 \ifnum\count0=0 \gdef#3{##1}\fi}#2}}
 
 
% **  Following code converts a commalist to a list macro, with all items 
% **    fully expanded.
%\!ecfor\item:=\commalist\do{\expandafter\!rightappend\item\to\list}
 
 
% ** \!loop ... repeat
% ** This is exactly like TEX's \loop ... repeat.  It can be used in nesting
% ** two loops, without puting the inner one inside a group.
\def\!loop#1\repeat{\def\!body{#1}\!iterate}
\def\!iterate{\!body\let\!next=\!iterate\else\let\!next=\relax\fi\!next}
 
% ** \!!loop ... repeat
% ** This is exactly like TEX's \loop ... repeat.  It can be used in nesting
% ** two loops, without puting the inner one inside a group.
\def\!!loop#1\repeat{\def\!!body{#1}\!!iterate}
\def\!!iterate{\!!body\let\!!next=\!!iterate\else\let\!!next=\relax\fi\!!next}
%  (\multiput uses \!!loop)
 
% ** \!removept{DIMENREG}{\CS}
% ** Defines the control sequence CS to be the value (in points) in the
% ** dimension register DIMENREG (but without the "pt" TEK usually adds)
% ** E.g., after  \dimen0=12.3pt \!removept\dimen0\A, \A expands to 12.3
\def\!removept#1#2{\edef#2{\expandafter\!!removePT\the#1}}
{\catcode`p=12 \catcode`t=12 \gdef\!!removePT#1pt{#1}}

% ** \pladevalueinpts of <DIMENSION REGISTER> in {CONTROL SEQUENCE}
\def\placevalueinpts of <#1> in #2 {%
  \!removept{#1}{#2}}
 
% ** \!mlap{...}  \!vmlap{...}
% ** Center  ...  in a box of width 0.
\def\!mlap#1{\hbox to 0pt{\hss#1\hss}}
\def\!vmlap#1{\vbox to 0pt{\vss#1\vss}}
 
% ** \!not{TEK if-CONDITION}
% ** By a TEK if-CONDITION is meant something like 
% **     \ifnum\N<0,   or   \ifdim\A>\B
% ** \!not produces an if-condition which is false if the original condition
% ** is true, and true if the original condition is false.
\def\!not#1{%
  #1\relax
    \!switchfalse
  \else
    \!switchtrue
  \fi
  \if!switch
  \ignorespaces}
 

% *******************
% *** ALLOCATIONS ***
% *******************

% This section allocates all the registers PiCTeX uses. Following
% each allocation is a string of the form  ....N.D...L......... ;
% the various letters show which sections of PiCTeX make explicit
% reference to that register, according to the following code:
 
%   H Hacks
%   A Areas
%   W arroWs
%   B Bars
%   X boXes
%   C Curves
%   D Dashpattterns
%   V diVision
%   E Ellipses
%   U rUles
%   L Linear arc
%   G loGten
%   P Pictures
%   O plOtting
%   Y pYthagoras
%   Q Quadratic arc
%   R Rotations
%   S Shading
%   T Ticks

% Turn off messages from TeX's allocation macros
\let\!!!wlog=\wlog              % "\wlog" is defined in plain TeX
\def\wlog#1{}    

\newdimen\headingtoplotskip     %.A.................
\newdimen\linethickness         %.A..X....U........T
\newdimen\longticklength        %.A................T
\newdimen\plotsymbolspacing     %......D...L....Q...
\newdimen\shortticklength       %.A................T
\newdimen\stackleading          %.A..........P......
\newdimen\tickstovaluesleading  %.A................T
\newdimen\totalarclength        %......D...L....Q...
\newdimen\valuestolabelleading  %.A.................

\newbox\!boxA                   %.AW...............T
\newbox\!boxB                   %..W................
\newbox\!picbox                 %............P......
\newbox\!plotsymbol             %..........L..O.....
\newbox\!putobject              %............PO...S.
\newbox\!shadesymbol            %.................S.

\newcount\!countA               %.A....D..UL....Q.ST
\newcount\!countB               %......D..U.....Q.ST
\newcount\!countC               %...............Q..T
\newcount\!countD               %...................
\newcount\!countE               %.............O....T
\newcount\!countF               %.............O....T
\newcount\!countG               %..................T
\newcount\!fiftypt              %.........U.........
\newcount\!intervalno           %..........L....Q...
\newcount\!npoints              %..........L........
\newcount\!nsegments            %.........U.........
\newcount\!ntemp                %............P......
\newcount\!parity               %.................S.
\newcount\!scalefactor          %..................T
\newcount\!tfs                  %.......V...........
\newcount\!tickcase             %..................T

\newdimen\!Xleft                %............P......
\newdimen\!Xright               %............P......
\newdimen\!Xsave                %.A................T
\newdimen\!Ybot                 %............P......
\newdimen\!Ysave                %.A................T
\newdimen\!Ytop                 %............P......
\newdimen\!angle                %........E..........
\newdimen\!arclength            %..W......UL....Q...
\newdimen\!areabloc             %.A........L........
\newdimen\!arealloc             %.A........L........
\newdimen\!arearloc             %.A........L........
\newdimen\!areatloc             %.A........L........
\newdimen\!bshrinkage           %.................S.
\newdimen\!checkbot             %..........L........
\newdimen\!checkleft            %..........L........
\newdimen\!checkright           %..........L........
\newdimen\!checktop             %..........L........
\newdimen\!dimenA               %.AW.X.DVEUL..OYQRST
\newdimen\!dimenB               %....X.DVEU...O.QRS.
\newdimen\!dimenC               %..W.X.DVEU......RS.
\newdimen\!dimenD               %..W.X.DVEU....Y.RS.
\newdimen\!dimenE               %..W........G..YQ.S.
\newdimen\!dimenF               %...........G..YQ.S.
\newdimen\!dimenG               %...........G..YQ.S.
\newdimen\!dimenH               %...........G..Y..S.
\newdimen\!dimenI               %...BX.........Y....
\newdimen\!distacross           %..........L....Q...
\newdimen\!downlength           %..........L........
\newdimen\!dp                   %.A..X.......P....S.
\newdimen\!dshade               %.................S.
\newdimen\!dxpos                %..W......U..P....S.
\newdimen\!dxprime              %...............Q...
\newdimen\!dypos                %..WB.....U..P......
\newdimen\!dyprime              %...............Q...
\newdimen\!ht                   %.A..X.......P....S.
\newdimen\!leaderlength         %......D..U.........
\newdimen\!lshrinkage           %.................S.
\newdimen\!midarclength         %...............Q...
\newdimen\!offset               %.A................T
\newdimen\!plotheadingoffset    %.A.................
\newdimen\!plotsymbolxshift     %..........L..O.....
\newdimen\!plotsymbolyshift     %..........L..O.....
\newdimen\!plotxorigin          %..........L..O.....
\newdimen\!plotyorigin          %..........L..O.....
\newdimen\!rootten              %...........G.......
\newdimen\!rshrinkage           %.................S.
\newdimen\!shadesymbolxshift    %.................S.
\newdimen\!shadesymbolyshift    %.................S.
\newdimen\!tenAa                %...........G.......
\newdimen\!tenAc                %...........G.......
\newdimen\!tenAe                %...........G.......
\newdimen\!tshrinkage           %.................S.
\newdimen\!uplength             %..........L........
\newdimen\!wd                   %....X.......P....S.
\newdimen\!wmax                 %...............Q...
\newdimen\!wmin                 %...............Q...
\newdimen\!xB                   %...............Q...
\newdimen\!xC                   %...............Q...
\newdimen\!xE                   %..W.....E.L....Q.S.
\newdimen\!xM                   %..W.....E......Q.S.
\newdimen\!xS                   %..W.....E.L....Q.S.
\newdimen\!xaxislength          %.A................T
\newdimen\!xdiff                %..........L........
\newdimen\!xleft                %............P......
\newdimen\!xloc                 %..WB.....U.......S.
\newdimen\!xorigin              %.A........L.P....S.
\newdimen\!xpivot               %................R..
\newdimen\!xpos                 %..........L.P..Q.ST
\newdimen\!xprime               %...............Q...
\newdimen\!xright               %............P......
\newdimen\!xshade               %.................S.
\newdimen\!xshift               %..W.........PO...S.
\newdimen\!xtemp                %............P......
\newdimen\!xunit                %.AWBX...EUL.P..QRS.
\newdimen\!xxE                  %........E..........
\newdimen\!xxM                  %........E..........
\newdimen\!xxS                  %........E..........
\newdimen\!xxloc                %..WB....EU.........
\newdimen\!yB                   %...............Q...
\newdimen\!yC                   %...............Q...
\newdimen\!yE                   %..W.....E.L....Q...
\newdimen\!yM                   %..W.....E......Q...
\newdimen\!yS                   %..W.....E.L....Q...
\newdimen\!yaxislength          %.A................T
\newdimen\!ybot                 %............P......
\newdimen\!ydiff                %..........L........
\newdimen\!yloc                 %..WB.....U.......S.
\newdimen\!yorigin              %.A........L.P....S.
\newdimen\!ypivot               %................R..
\newdimen\!ypos                 %..........L.P..Q.ST
\newdimen\!yprime               %...............Q...
\newdimen\!yshade               %.................S.
\newdimen\!yshift               %..W.........PO...S.
\newdimen\!ytemp                %............P......
\newdimen\!ytop                 %............P......
\newdimen\!yunit                %.AWBX...EUL.P..QRS.
\newdimen\!yyE                  %........E..........
\newdimen\!yyM                  %........E..........
\newdimen\!yyS                  %........E..........
\newdimen\!yyloc                %..WB....EU.........
\newdimen\!zpt                  %.AWBX.DVEULGP.YQ.ST

\newif\if!axisvisible           %.A.................
\newif\if!gridlinestoo          %..................T
\newif\if!keepPO                %...................
\newif\if!placeaxislabel        %.A.................
\newif\if!switch                %H..................
\newif\if!xswitch               %.A................T

\newtoks\!axisLaBeL             %.A.................
\newtoks\!keywordtoks           %.A.................

\newwrite\!replotfile           %.............O.....

\newhelp\!keywordhelp{The keyword mentioned in the error message in unknown. 
Replace NEW KEYWORD in the indicated response by the keyword that 
should have been specified.}    %.A.................

% The following commands assign alternate names to some of the 
% above registers.  "\!wlet"  is defined in  Hacks.
\!wlet\!!origin=\!xM                   %.A................T
\!wlet\!!unit=\!uplength               %.A................T
\!wlet\!Lresiduallength=\!dimenG       %.........U.........
\!wlet\!Rresiduallength=\!dimenF       %.........U.........
\!wlet\!axisLength=\!distacross        %.A................T
\!wlet\!axisend=\!ydiff                %.A................T
\!wlet\!axisstart=\!xdiff              %.A................T
\!wlet\!axisxlevel=\!arclength         %.A................T
\!wlet\!axisylevel=\!downlength        %.A................T
\!wlet\!beta=\!dimenE                  %...............Q...
\!wlet\!gamma=\!dimenF                 %...............Q...
\!wlet\!shadexorigin=\!plotxorigin     %.................S.
\!wlet\!shadeyorigin=\!plotyorigin     %.................S.
\!wlet\!ticklength=\!xS                %..................T
\!wlet\!ticklocation=\!xE              %..................T
\!wlet\!ticklocationincr=\!yE          %..................T
\!wlet\!tickwidth=\!yS                 %..................T
\!wlet\!totalleaderlength=\!dimenE     %.........U.........
\!wlet\!xone=\!xprime                  %....X..............
\!wlet\!xtwo=\!dxprime                 %....X..............
\!wlet\!ySsave=\!yM                    %...................
\!wlet\!ybB=\!yB                       %.................S.
\!wlet\!ybC=\!yC                       %.................S.
\!wlet\!ybE=\!yE                       %.................S.
\!wlet\!ybM=\!yM                       %.................S.
\!wlet\!ybS=\!yS                       %.................S.
\!wlet\!ybpos=\!yyloc                  %.................S.
\!wlet\!yone=\!yprime                  %....X..............
\!wlet\!ytB=\!xB                       %.................S.
\!wlet\!ytC=\!xC                       %.................S.
\!wlet\!ytE=\!downlength               %.................S.
\!wlet\!ytM=\!arclength                %.................S.
\!wlet\!ytS=\!distacross               %.................S.
\!wlet\!ytpos=\!xxloc                  %.................S.
\!wlet\!ytwo=\!dyprime                 %....X..............


% Initial values for registers
\!zpt=0pt                              % static
\!xunit=1pt
\!yunit=1pt
\!arearloc=\!xunit
\!areatloc=\!yunit
\!dshade=5pt
\!leaderlength=24in
\!tfs=256                              % static
\!wmax=5.3pt                           % static
\!wmin=2.7pt                           % static
\!xaxislength=\!xunit
\!xpivot=\!zpt
\!yaxislength=\!yunit 
\!ypivot=\!zpt
\plotsymbolspacing=.4pt
  \!dimenA=50pt \!fiftypt=\!dimenA     % static

\!rootten=3.162278pt                   % static
\!tenAa=8.690286pt                     % static  (A5)
\!tenAc=2.773839pt                     % static  (A3)
\!tenAe=2.543275pt                     % static  (A1)

% Initial values for control sequences
\def\!cosrotationangle{1}      %................R..
\def\!sinrotationangle{0}      %................R..
\def\!xpivotcoord{0}           %................R..
\def\!xref{0}                  %............P......
\def\!xshadesave{0}            %.................S.
\def\!ypivotcoord{0}           %................R..
\def\!yref{0}                  %............P......
\def\!yshadesave{0}            %.................S.
\def\!zero{0}                  %..................T

% Reset TeX to report allocations
\let\wlog=\!!!wlog
%  *************************************
%  ***  AREAS: Deals with plot areas ***
%  *************************************
%
%  ** User commands
%  **   \setplotarea x from LEFT XCOORD to RIGTH XCOORD, y from BOTTOM YCOORD
%  **      to TOP YCOORD
%  **   \axis BOTTOM-LEFT-TOP-RIGHT  [SHIFTEDTO xy=COORD] [VISIBLE-INVISIBLE]
%  **      [LABEL {label}] [TICKS] /
%  **   \visibleaxes
%  **   \invisibleaxes
%  **   \plotheading {HEADING}
%  **   \grid {# of columns} {# of rows}
%  **   \normalgraphs 
  
%  **  \normalgraphs
%  **    Sets defaults for graph setup. See Subsection 3.4 of manual.
\def\normalgraphs{%
  \longticklength=.4\baselineskip
  \shortticklength=.25\baselineskip
  \tickstovaluesleading=.25\baselineskip
  \valuestolabelleading=.8\baselineskip
  \linethickness=.4pt
  \stackleading=.17\baselineskip
  \headingtoplotskip=1.5\baselineskip
  \visibleaxes
  \ticksout
  \nogridlines
  \unloggedticks}
%
% **  \setplotarea x from LEFT XCOORD to RIGTH XCOORD, y from BOTTOM YCOORD
% **    to TOP YCOORD
% **  Reserves space in PICBOX for a rectangular box with the indicated
% **   coordinates.  Must be specified before calls to  \axis, 
% **   \grid, \plotheading.
% **  See Subsection 3.1 of the manual.
\def\setplotarea x from #1 to #2, y from #3 to #4 {%
  \!arealloc=\!M{#1}\!xunit \advance \!arealloc -\!xorigin
  \!areabloc=\!M{#3}\!yunit \advance \!areabloc -\!yorigin
  \!arearloc=\!M{#2}\!xunit \advance \!arearloc -\!xorigin
  \!areatloc=\!M{#4}\!yunit \advance \!areatloc -\!yorigin
  \!initinboundscheck
  \!xaxislength=\!arearloc  \advance\!xaxislength -\!arealloc
  \!yaxislength=\!areatloc  \advance\!yaxislength -\!areabloc
  \!plotheadingoffset=\!zpt
  \!dimenput {{\setbox0=\hbox{}\wd0=\!xaxislength\ht0=\!yaxislength\box0}}
     [bl] (\!arealloc,\!areabloc)}
%
% ** \visibleaxes, \invisibleaxes 
% ** Switches for setting visibility of subsequent axes.
% ** See Subsection 3.2 of the manual.
\def\visibleaxes{%
  \def\!axisvisibility{\!axisvisibletrue}}
\def\invisibleaxes{%
  \def\!axisvisibility{\!axisvisiblefalse}}
%
% ** The next few macros enable the user to fix up an erroneous keyword
% **   in the \axis command.
%  \newhelp is in ALLOCATIONS
%  \newhelp\!keywordhelp{The keyword mentioned in the error message in unknown. 
%  Replace NEW KEYWORD in the indicated response by the keyword that 
%  should have been specified.}

\def\!fixkeyword#1{%
  \errhelp=\!keywordhelp
  \errmessage{Unrecognized keyword `#1': \the\!keywordtoks{NEW KEYWORD}'}}

%  \newtoks\!keywordtoks    In ALLOCATIONS.
\!keywordtoks={enter `i\fixkeyword}

\def\fixkeyword#1{%
  \!nextkeyword#1 }

% ** \axis BOTTOM-LEFT-TOP-RIGHT  [SHIFTEDTO xy=COORD] [VISIBLE-INVISIBLE]
% **   [LABEL {label}] [TICKS] /
% ** Exactly one of the keywords BOTTOM, LEFT, TOP, RIGHT must be
% ** specified. Axis is drawn along the indicated edge of the current
% ** plot area, shifted if the SHIFTEDTO option is used, visible or
% ** invisible according the selected option, with an optional LABEL,
% ** and optional TICKS (see ticks.tex for the options avialabel with
% ** TICKS). The TICKS option must be the last one specified. The \axis
% ** MUST be terminated with a / followed by a space.
% ** See Subsection 3.2 of the manual for more information.

% ** The various options of the \axis command are processed by the
% ** \!nextkeyword macro defined below. For example, 
% ** `\!nextkeyword shiftedto ' expands to `\!axisshiftedto'.
\def\axis {%
  \def\!nextkeyword##1 {%
    \expandafter\ifx\csname !axis##1\endcsname \relax
      \def\!next{\!fixkeyword{##1}}%
    \else
      \def\!next{\csname !axis##1\endcsname}%
    \fi
    \!next}%
  \!offset=\!zpt
  \!axisvisibility
  \!placeaxislabelfalse
  \!nextkeyword}

% ** This and the various macros that follow handle the keyword
% ** specifications on the \axis command
% ** See Subsection 3.2 of the manual.
\def\!axisbottom{%
  \!axisylevel=\!areabloc
  \def\!tickxsign{0}%
  \def\!tickysign{-}%
  \def\!axissetup{\!axisxsetup}%
  \def\!axislabeltbrl{t}%
  \!nextkeyword}

\def\!axistop{%
  \!axisylevel=\!areatloc
  \def\!tickxsign{0}%
  \def\!tickysign{+}%
  \def\!axissetup{\!axisxsetup}%
  \def\!axislabeltbrl{b}%
  \!nextkeyword}

\def\!axisleft{%
  \!axisxlevel=\!arealloc
  \def\!tickxsign{-}%
  \def\!tickysign{0}%
  \def\!axissetup{\!axisysetup}%
  \def\!axislabeltbrl{r}%
  \!nextkeyword}

\def\!axisright{%
  \!axisxlevel=\!arearloc
  \def\!tickxsign{+}%
  \def\!tickysign{0}%
  \def\!axissetup{\!axisysetup}%
  \def\!axislabeltbrl{l}%
  \!nextkeyword}

\def\!axisshiftedto#1=#2 {%
  \if 0\!tickxsign
    \!axisylevel=\!M{#2}\!yunit
    \advance\!axisylevel -\!yorigin
  \else
    \!axisxlevel=\!M{#2}\!xunit
    \advance\!axisxlevel -\!xorigin
  \fi
  \!nextkeyword}

\def\!axisvisible{%
  \!axisvisibletrue  
  \!nextkeyword}

\def\!axisinvisible{%
  \!axisvisiblefalse
  \!nextkeyword}

\def\!axislabel#1 {%
  \!axisLaBeL={#1}%
  \!placeaxislabeltrue
  \!nextkeyword}

\expandafter\def\csname !axis/\endcsname{%
  \!axissetup % This could done already by "ticks"; if so, now \relax
  \if!placeaxislabel
    \!placeaxislabel
  \fi
  \if +\!tickysign %                 ** (A "top" axis)
    \!dimenA=\!axisylevel
    \advance\!dimenA \!offset %      ** dimA = top of the axis structure
    \advance\!dimenA -\!areatloc %   ** dimA = excess over the plot area
    \ifdim \!dimenA>\!plotheadingoffset
      \!plotheadingoffset=\!dimenA % ** Greatest excess over the plot area
    \fi
  \fi}

% ** \grid {c} {r} 
% ** Partitions the plot area into c columns and r rows; see Subsection 3.3
% ** of the manual.
% ** (Other grid patterns can be drawn with the TICKS option of the \axis 
% ** command.
\def\grid #1 #2 {%
  \!countA=#1\advance\!countA 1
  \axis bottom invisible ticks length <\!zpt> andacross quantity {\!countA} /
  \!countA=#2\advance\!countA 1
  \axis left   invisible ticks length <\!zpt> andacross quantity {\!countA} / }

% ** \plotheading{HEADING}
% ** Places HEADING centered above the top of the plotarea (and above
% ** any top axis ticks marks, tick labels, and axis label); see
% ** Subsection 3.3 of the manual.
\def\plotheading#1 {%
  \advance\!plotheadingoffset \headingtoplotskip
  \!dimenput {#1} [B] <.5\!xaxislength,\!plotheadingoffset>
    (\!arealloc,\!areatloc)}

% ** From here on, the routines are internal.
\def\!axisxsetup{%
  \!axisxlevel=\!arealloc
  \!axisstart=\!arealloc
  \!axisend=\!arearloc
  \!axisLength=\!xaxislength
  \!!origin=\!xorigin
  \!!unit=\!xunit
  \!xswitchtrue
  \if!axisvisible 
    \!makeaxis
  \fi}

\def\!axisysetup{%
  \!axisylevel=\!areabloc
  \!axisstart=\!areabloc
  \!axisend=\!areatloc
  \!axisLength=\!yaxislength
  \!!origin=\!yorigin
  \!!unit=\!yunit
  \!xswitchfalse
  \if!axisvisible