%%% ====================================================================
%%%  @LaTeX-style-file{
%%%     author          = "Alan Jeffrey",
%%%     version         = "1.1",
%%%     date            = "02 June 1992",
%%%     time            = "13:39:09 BST",
%%%     filename        = "diagramf.sty",
%%%     address         = "School of Cognitive and Computing Sciences
%%%                        University of Sussex
%%%                        Brighton BN1 9QH
%%%                        UK",
%%%     telephone       = "+44 273 606755 x 3238",
%%%     FAX             = "+44 273 678188",
%%%     checksum        = "50716 222 988 7967",
%%%     email           = "alanje@cogs.sussex.ac.uk",
%%%     codetable       = "ISO/ASCII",
%%%     keywords        = "diagrams, metafont",
%%%     supported       = "yes",
%%%     abstract        = "This is a LaTeX style file for importing
%%%                        diagrams drawn in metafont.",
%%%     docstring       = "This is part of the diagramf package which
%%%                        interfaces TeX and metafont.  It is
%%%                        described in diagramf.tex.
%%%
%%%                        Copyright 1992 Alan Jeffrey.
%%%
%%%                        The checksum field above contains a CRC-16
%%%                        checksum as the first value, followed by the
%%%                        equivalent of the standard UNIX wc (word
%%%                        count) utility output of lines, words, and
%%%                        characters.  This is produced by Robert
%%%                        Solovay's checksum utility.",
%%%     package         = "diagramf",
%%%     dependencies    = "diagramf.mf",
%%%     maintainer      = "Jeremy Gibbons",
%%%     address-maintainer = "Department of Computer Science
%%%                        University of Aukland
%%%                        Private Bag
%%%                        Aukland
%%%                        New Zealand",
%%%     email-maintainer = "jeremy@cs.aukuni.ac.nz",
%%%  }
%%% ====================================================================
%%%
%%% 25 Oct 1990, v1.0: Released version 1.0.
%%%
%%% 29 Oct 1990, v1.01: Discovered I'd put \everylabel into the
%%% diagram rather than the label.  Silly me.
%%%
%%% 30 Oct 1990, v1.02: \diagramf now uses \copy to put down the
%%% diagram rather than \box, so diagrams can be reused.
%%%
%%% 2 Jun 1992, v1.1: Added standard headers.

% This style allows you to use diagrams generated in metafont with TeX
% lables, such as those produced with diagramf.mf.
%
% To use the diagrams generated by example.mf, you say
%
%    \diagramfile{example}
%
% which loads all the diagrams and stores them in boxes.  You can then
% use a diagram by saying (for example)
%
%    \diagramf{2}
%
% which gets you the second diagram.  When you load in another
% file of diagrams, you over-write the previous diagrams.
%
% All the definitions made by \diagramfile are purely local, so if you
% say
%
%    \diagramfile{foo}
%    {\diagramfile{baz}\diagramf{1}}
%    \diagramf{2}
%
% You get diagram 1 from baz, and diagram 2 from foo.
%
% The metafont program for the diagrams contains TeX code for the
% labels, which it spits out to an auxilary .dia file, of the
% form
%
%    \newdiagramfont{example}
%    \newdiagram{2}
%    \diagramlabel{0}{4.88908pt}{0pt}
%    $g \circ h$
%    \enddiagramlabel
%    \diagramchar{2}
%    \endnewdiagram
%
% This says that the font for these diagrams is called example, and
% it contains diagram number 2.  This has one label (number 0),
% which should be positioned at coordinates (4.88909pt, 0pt), and whose
% text is $g \circ h$.  The diagram itself is character 1 in the
% font.
%
% When \diagramfile{example} is called, it loads in example.dia, which
% sets the boxes containing the diagrams, and in turn writes out
% example.dim, containing the dimensions of the lables, for example
%
%    wd#[2][0] := 20.3344pt#;
%    ht#[2][0] := 6.94444pt#;
%    dp#[2][0] := 1.94444pt#;
%
% This is then read by metafont, and we go round the production cycle
% one more time...
%
% Right, that's what we're doing, let's get on with it!

% To begin with, the counters, dimensions, etc. we need.

\newwrite\dimensionsfile  % The .dim output file
\newcount\diagramnumber   % The number of the diagram
\newcount\labelnumber     % The number of the label
\newdimen\labelxoffset    % The x-coordinate of the label
\newdimen\labelyoffset    % The y-coordinate of the label
\newtoks\everylabel       % Tokens put in every label (a la \everymath)


% A handy macro for hacking around with \csname's...
% \csnameafter\foo{baz} expands out to \foo\baz.

\def\csnameafter#1#2{\expandafter#1\csname#2\endcsname}

% \percent is a % mark, only with catcode 11 (i.e. a letter),
% similarly \hashmark.

{\catcode`\%=11\gdef\percent{%}}
{\catcode`\#=11\gdef\hashmark{#}}

% \allocatebox{foo} gets a new box \foo, if \foo is undefined.

\def\allocatebox#1%
   {\@ifundefined{#1}{\csnameafter\newbox{#1}}{}}

% In order to do this, \newbox has to be non-\outer, grumble grumble
% why was it ever \outer in the first place grumble grumble...

\def\newbox{\alloc@4\box\chardef\insc@unt}

% When you say \diagramfile{example} we open
% example.dim for output, read in example.dia, and then close
% example.dia.

\def\diagramfile#1%
   {\immediate\openout\dimensionsfile #1.dim%
    \immediate\write\dimensionsfile{\percent Filename: #1.dim}%
    \immediate\write\dimensionsfile{\percent Generated by: diagramf.sty}%
    \immediate\write\dimensionsfile{\percent Date: \today}%
    \@input{#1.dia}%
    \immediate\closeout\dimensionsfile
    \typeout{Dimensions written on #1.dim.}}

% The first command in FONTNAME.dia should be
% \newdiagramfont{FONTNAME}---this causes us to load the font in.
% (Exercise for the reader: why isn't this done by \diagramfile?  Hint: if
% we run LaTeX before running metafont, neither FONTNAME.dia nor
% FONTNAME.tfm will exist.)

\def\newdiagramfont#1{\font\diagramfont=#1\relax}

% Then the macro that defines a diagram.  \newdiagram{N} makes us
% define \diagramnumber to be N, allocate a new box \diagram-N, and
% set the box to whatever comes between here and the \endnewdiagram.

\def\newdiagram#1%
   {\diagramnumber=#1
    \allocatebox{diagram-#1}%
    \csnameafter\setbox{diagram-#1}\hbox\bgroup}

\def\endnewdiagram
   {\egroup}

% Within the \newdiagram we can have commands to set labels, of the
% form \diagramlabel{N}{X}{Y}...\enddiagramlabel.  To begin with, we
% set \labelnumber to N, \labelxoffset to X, \labelyoffset to Y, then
% set box 0 to be everything up to the \enddiagramlabel.

\def\diagramlabel#1#2#3%
   {\labelnumber=#1
    \labelxoffset=#2
    \labelyoffset=#3
    \setbox0\hbox\bgroup\the\everylabel}

% When we have set the box containing the label, we write its
% dimensions on the .dim file, move the box to coordinates
% (\labelxoffset, \labelyoffset), reduce it to zero size, and set it.

\def\enddiagramlabel
   {\egroup
    \immediate\write\dimensionsfile
       {wd\hashmark[\the\diagramnumber][\the\labelnumber]
            := \the\wd0\hashmark;}%
    \immediate\write\dimensionsfile
       {ht\hashmark[\the\diagramnumber][\the\labelnumber]
            := \the\ht0\hashmark;}%
    \immediate\write\dimensionsfile
       {dp\hashmark[\the\diagramnumber][\the\labelnumber]
            := \the\dp0\hashmark;}%
    \setbox0\hbox{\kern\labelxoffset\raise\labelyoffset\box0}%
    \wd0=0pt \ht0=0pt \dp0=0pt
    \box0}

% The other command you can have within a diagram is \diagramchar{N}
% which just causes us to set character N of \diagramfont.

\def\diagramchar#1%
   {{\diagramfont\char#1\relax}}

% Finally, to set a diagram, you just say \diagramf{N} which causes us
% to leave vertical mode (in the same fashion as \mbox) and set box
% \diagram-N.

\def\diagramf#1%
   {\leavevmode
    \@ifundefined
       {diagram-#1}
       {??\@warning{Diagram #1 on page \thepage\space undefined}}
       {\csnameafter\copy{diagram-#1}}}