% \iffalse
% Copyright 2002--2003, Daniel H. Luecking
%
% Mfpic consists of the 3 files mfpic.dtx, grafbase.dtx and mfpic.ins
% and the 5 files they generate: mfpic.tex, mfpic.sty, grafbase.mf,
% grafbase.mp, and dvipsnam.mp.
%
% Mfpic may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.2 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.2 or later is part of all distributions of LaTeX version
% 1999/12/01 or later.
%
% Documentation, examples, and ancillary files are separate and not
% covered by this license. See readme.1st for a complete list. See
% individual files for any copyright and license restrictions.
%
% With respect to the proposed draft LPPL-1.3: mfpic has maintenance
% status "maintained". The Current Maintainer is Daniel H. Luecking. There
% are several Base Interpreters: TeX, LaTeX, MetaPost and Metafont.
%
%<*driver>
\documentclass[draft]{ltxdoc}

\def\fileversion{0.7a beta}
\def\filedate{2004/04/16}

\addtolength{\textwidth}{.5878pt}

\def\mytt{\mdseries\ttfamily}
\renewcommand\marg[1]{{\mytt \{#1\}}}
\renewcommand\oarg[1]{{\mytt  [#1]}}
\renewcommand\parg[1]{{\mytt  (#1)}}
\renewcommand{\meta}[1]{{$\langle$\rmfamily\itshape#1$\rangle$}}
\DeclareRobustCommand\cs[1]{{\mytt\char`\\#1}}
\def\prog#1{{\mdseries\scshape #1}}
\def\grafbase{\prog{grafbase}}
\def\mfpic{\prog{mfpic}}
\def\Mfpic{\prog{Mfpic}}
\def\MF{\prog{meta\-font}}
\def\MP{\prog{meta\-post}}
\def\CMF{\prog{Meta\-font}}
\def\CMP{\prog{Meta\-post}}
\def\opt#1{{\sffamily\upshape#1}}
\def\mfc#1{{\mytt#1}}
\let\env\mfc
\let\file\mfc
\let\gbc\mfc
\renewcommand\{{\char`\{}
\renewcommand\}{\char`\}}
\renewcommand\|{${}\mathrel{|}{}$}

\makeatletter
\newcommand\bsl{{\mytt\@backslashchar}}
% Stupid lists!
\def\@listi{\leftmargin\leftmargini
  \parsep \z@ \@plus\p@ \@minus\z@
  \topsep 4\p@ \@plus\p@ \@minus2\p@
  \itemsep\parsep}
\let\@listI\@listi \@listi
\renewcommand\labelitemi{\normalfont\bfseries \textendash}
\renewcommand\labelitemii{\textasteriskcentered}
\renewcommand\labelitemiii{\textperiodcentered}
\leftmargini\parindent
% Stupid index!
\def\IndexParms{%
  \parindent \z@ \columnsep 15pt
  \parskip 0pt plus 1pt
  \rightskip 5pt plus2em \mathsurround \z@
  \parfillskip=-5pt \small
  % less hanging:
  \def\@idxitem{\par\hangindent 20pt}%
  \def\subitem{\@idxitem\hspace*{15pt}}%
  \def\subsubitem{\@idxitem\hspace*{25pt}}%
  \def\indexspace{\par\vspace{10pt plus 2pt minus 3pt}}}
\makeatother

\def\pdfTeX{\textrm{pdf\kern.04em\TeX}}
\def\pdfLaTeX{\textrm{pdf\kern.06em\LaTeX}}
\def\ConTeXt{\textrm{Con\kern-.16em\TeX\kern-0.06em t}}
\def\PiCTeX{\textrm{P\kern-.13em\lower.3ex\hbox{I}C\TeX}}

\title{The \mfpic{} package\thanks{This file has version number
        \fileversion, last revised \filedate. The code described here
        was developed by several people, notably Thomas Leathrum,
        Geoffrey Tobin and Dan Luecking. Dan wrote this documentation.}}
\author{Dan Luecking}
\date{\filedate}
\DisableCrossrefs
\CodelineIndex
\AlsoImplementation

\begin{document}
  \DeleteShortVerb{\|}
  \DocInput{mfpic.dtx}
\end{document}
%</driver>
%\fi
%
% \CheckSum{4392}
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \catcode`\_=12
% \maketitle
%
% \begin{abstract}
% An environment, \env{mfpic}, is defined, within which commands can
% be used for drawing pictures, especially graphs of mathematical
% functions. These commands actually write code to an external file
% which can be processed through \MF{} or \MP{} (depending on package
% options) to produce the picture. The picture is then included on a
% second pass through \TeX.
%
% This file documents the source code. See \file{mfpicdoc.tex} for the
% user documentation.
% \end{abstract}
%
% \StopEventually{\PrintIndex}
% \tableofcontents
%
%
% \section{Introductory setup}\label{intro}
%
% \Mfpic{} is designed to work with plain \TeX, \LaTeX, \pdfTeX, and
% \pdfLaTeX.
%
% \subsection{Versions numbers, category codes, etc.}\label{category}
%
% Almost all the various category code settings we do were prompted by
% an \mfpic{} user who had sent a bug report and had to send along his
% modified version of \file{mfpic.tex}. It had been modified so that
% \cs{message}\,s and \cs{write}\,s would do the right thing in latex
% files where various punctuation were made active (e.g., with
% \file{french.sty}).
%
% \DescribeMacro{\mfpfileversion}
% \DescribeMacro{\mfpfiledate}
% \DescribeMacro{\mfpicversion}
% We keep track of version numbers here. We use \cs{mfpfileversion}
% because \cs{fileversion} is used by very many \LaTeX{} packages.
% This is important, because later we write the version information to the
% output file, The \cs{mfpicversion} is 100 times the numeric part of the
% version. The output file can compare this number with the corresponding
% value in \file{grafbase} and detect installations where there is a
% mismatch.
%    \begin{macrocode}
%<*tex>
{\catcode\lq\.12 \catcode\lq\/12%
\gdef\mfpfileversion{0.7a beta}%
\gdef\mfpfiledate{2004/04/16}%
\gdef\mfpicversion{70}}%
\ifx\MFPicpackagE\UndEfInEd\else\expandafter\endinput\fi%
%    \end{macrocode}
%
% A bug in older versions of some support files is triggered by the macro
% \cs{+}, which is an \cs{outer} macro in plain \TeX. Here we save the
% current definition and then give it a nonouter meaning.
%    \begin{macrocode}
\let\mfpsaveplus\+%
\let\+\tabalign%
%    \end{macrocode}
%
% \DescribeMacro{\MFPrestorecode}
% We now get rid of unusually catcoded punctuation, space and EOL.
% We save all the current category codes in the macro \cs{MFPicpackagE}
% and restore them at the end by executing this command.
% We try to assume only: that letters, numbers,
% `\texttt\bsl', `\texttt\{', `\texttt\}', `\texttt\#' and
% `\texttt\%' have the usual categories. Styles (e.g., \prog{french})
% that make punctuation active foul up \cs{write}\,s of MF/MP code. This can
% still occur in user-generated \cs{write}\,s, so maybe some code should be
% added in \cs{mfpic} or \cs{mfsrc} command too.
%    \begin{macrocode}
\edef\MFPrestoreequal{\catcode61\space\the\catcode61\relax}%
\catcode61 12\relax%
\edef\MFPrestorespace{\catcode32=\the\catcode32\relax}%
\catcode32=10\relax%
\edef\MFPrestoreEOL{\catcode13=\the\catcode13\relax}%
\catcode13=5\relax
\edef\MFPrestorelq{\catcode96=\the\catcode96\relax}%
\catcode96=12
\def\MFPrestorecode#1{\catcode`\string#1=\the\catcode`#1\relax}%
%    \end{macrocode}
%
% \DescribeMacro{\MFPicpackagE}
% This will be invoked at the end of the file to restore all the catcodes.
% This will fail if some of these characters have really bad codes
% (comment or escape, for example) but that would likely be the case only
% if {\tt\bsl} or {\tt\%} have some different codes and then everything
% above here would fail.
%    \begin{macrocode}
\edef\MFPicpackagE{%
  \MFPrestorecode{@}\MFPrestorecode{-}%
  \MFPrestorecode{:}\MFPrestorecode{;}%
  \MFPrestorecode{.}\MFPrestorecode{,}%
  \MFPrestorecode{!}\MFPrestorecode{?}%
  \MFPrestorecode{(}\MFPrestorecode{)}%
  \MFPrestorecode{[}\MFPrestorecode{]}%
  \MFPrestorecode{'}\MFPrestorecode{/}%
  \MFPrestorecode{"}\MFPrestorecode{*}%
  \MFPrestorecode{$}\MFPrestorecode{+}%
  \MFPrestorecode{_}\MFPrestorecode{>}%
  \MFPrestorecode{<}\MFPrestorecode{~}%
  \MFPrestorelq\MFPrestoreEOL\MFPrestorespace
  \MFPrestoreequal\catcode 10=\number\catcode10}%
%    \end{macrocode}
%
% Set everything to normal except \texttt @=letter, \mfc{_}=other, and
% \texttt \textasciitilde=other. Do this by putting the settings in a
% macro and invoking the macro. That makes it possibly to redo the
% settings inside some other macro, should that ever become necessary.
% Characters 10 and 13 are \verb|^^J| and \verb|^^M|, control-J and
% control-M.
%
%    \begin{macrocode}
\catcode`\@=11
\ifx\@makeother\UndEfInEd \def\@makeother#1{\catcode`#1=12\relax}\fi
\def\mfp@sanitize{%
\catcode10=12\catcode13=5\catcode`\$=3\catcode`\ =10
\@makeother\:\@makeother\;\@makeother\.\@makeother\,%
\@makeother\!\@makeother\?\@makeother\(\@makeother\)%
\@makeother\[\@makeother\]%
\@makeother\'\@makeother\/\@makeother\"\@makeother\*%
\@makeother\_\@makeother\`\@makeother\+\@makeother\=%
\@makeother\>\@makeother\<\@makeother\~\@makeother\-}%
\mfp@sanitize
\edef\restorenewlinechar{\newlinechar=\number\newlinechar\relax}%
\chardef\mfp@ctrlJ10 \chardef\mfp@ctrlM13
\newlinechar\mfp@ctrlJ\def\@nl{^^J}%
%    \end{macrocode}
%
% \subsection{Debugging and messages}\label{debug}
%
% \DescribeMacro{\ifmfpicdebug}
% \DescribeMacro{\mfpicdebug}
% To turn on debugging before option processing, the user must make sure
% \cs{mfpicdebug} is defined. \cs{mfp@DBlog} writes it contents to the
% log file only if debugging is on.
%    \begin{macrocode}
\newif\ifmfpicdebug
\ifx\mfpicdebug\UndEfInEd \mfpicdebugfalse
\else \mfpicdebugtrue
\fi
\def\mfp@DBlog#1{%
  \ifmfpicdebug{\let\@msgbreak\mfp@errbrk\wlog{Mfpic debug: #1}}\fi}%
%    \end{macrocode}
% Various kinds of messages to the screen and log file. \cs{mfp@msg} is only
% used in the definition of the others and to write a blank line. We
% always use the second, which identifies the source of the message, or
% the third, which adds the word `warning'. The fourth is for errors
% and provides for help if a user presses `\texttt h' in response to the
% message. The bit with the spaces is to get a hanging indentation with
% text properly aligned on screen.
%    \begin{macrocode}
\def\mfp@msg#1{{\newlinechar\mfp@ctrlJ\immediate\write16{#1}}}%
\def\@msgbreak{^^J}%
\def\mfp@spaces{\space\space\space\space\space\space}%
%
\def\mfp@msgbrk{^^J\mfp@spaces\space}%
\def\mfp@errbrk{\mfp@msgbrk\mfp@spaces}%
\def\mfp@warnbrk{\mfp@errbrk\space\space}%
%
\def\Mfpic@msg#1{{\let\@msgbreak=\mfp@msgbrk
  \mfp@msg{Mfpic: #1 }}}%
\def\Mfpic@warn#1{{\let\@msgbreak=\mfp@warnbrk
  \mfp@msg{^^JMfpic warning: #1}}}%
\def\mfp@errmsg#1#2{{\newlinechar\mfp@ctrlJ
   \let\@msgbreak\mfp@errbrk
   \errhelp{#2}\errmessage{Mfpic error: #1}}}%
%    \end{macrocode}
%
% In \TeX{} 3.x we can identify the line being processed when a message is
% issued. We do not support \TeX{} 2.x.  The command \cs{@mfplineno} is
% for information written into the output file.
%    \begin{macrocode}
\def\@online{ on line \number\inputlineno}%
\def\@mfplineno{line \number\inputlineno\space in TeX source}%
%    \end{macrocode}
%
% \subsection{Detecting the format}\label{format}
%
% To detect its environment, \mfpic{} needs to test whether certain
% commands are defined. The \cs{@xp} is usually used to `expand away'
% the rest of a conditional. \cs{@XP} does this from two levels deep in
% a conditional. (We use \cs{@xp}\cs{@XP}\cs{@xp} later to expand
% away from three levels.) Since it uses \cs{@firstoftwo} and
% \cs{@secondoftwo}, we cannot use it to check their existence.
%    \begin{macrocode}
\ifx\@firstoftwo\UndEfInEd \long\def\@firstoftwo#1#2{#1}\fi
\ifx\@secondoftwo\UndEfInEd \long\def\@secondoftwo#1#2{#2}\fi
\let\@xp\expandafter
\def\@XP{\@xp\@xp\@xp}%
\def\mfp@ifdefined#1{%
  \ifx#1\UndEfInEd \@xp\@secondoftwo
  \else\ifx#1\relax \@XP\@secondoftwo
  \else \@XP\@firstoftwo
  \fi\fi}%
\mfp@ifdefined\@firstofone{}{\long\def\@firstofone#1{#1}}%
%    \end{macrocode}
%
% We test for the format. If all tests fail we assume plain\TeX{} or
% something compatible. Mainly this is needed to support \LaTeX. I've done
% a few things to work around \ConTeXt, but its been a moving target and
% \mfpic{} didn't work in \ConTeXt{} the last time I tried.
%
% Here we see if \cs{documentstyle} is defined, and then make sure
% we are not in \AmSTeX{}. Probably there is a better command to test,
% and perhaps we should just test whether the functionality required is
% present, but I'm not really sure how best to do either of those.
%    \begin{macrocode}
\newif\if@mfp@latex \@mfp@latexfalse
\mfp@ifdefined\documentstyle
 {{\def\x{AmS-TeX}%
  \ifx \fmtname\x \mfp@DBlog{AmS-TeX detected.}%
  \else
    \global\@mfp@latextrue \mfp@DBlog{LaTeX detected.}%
  \fi}}%
 {\mfp@DBlog{Neither LaTeX2e nor LaTeX209 nor AmS-TeX.}}%
%    \end{macrocode}
%
% We are in \LaTeXe{}, as opposed to \LaTeX2.09, if \cs{documentclass}
% is defined.
%    \begin{macrocode}
\newif\if@mfp@latexe \@mfp@latexefalse
\mfp@ifdefined\documentclass
 {\@mfp@latexetrue \mfp@DBlog{LaTeX2e detected.}}%
 {\mfp@DBlog{Not LaTeX2e.}}%
%    \end{macrocode}
%
% We now test \cs{pdfoutput} to see if pdf support is needed.
%    \begin{macrocode}
\newif\if@mfp@pdf \@mfp@pdffalse
\mfp@ifdefined\pdfoutput
 {\mfp@DBlog{PdfTeX detected...}%
  \ifcase\pdfoutput
    \mfp@DBlog{...with dvi output.}%
  \else
    \@mfp@pdftrue \mfp@DBlog{...with PDF output.}%
  \fi}%
 {\mfp@DBlog{Not pdfTeX.}}%
%    \end{macrocode}
%
% \subsection{Blank line and spacing hacks}\label{spacing}
%
% In order for commands to always read their arguments correctly,
% we need EOLs to have their normal category codes, but then a
% blank line will end a paragraph, and we would like blank lines to be
% ignored inside an \env{mfpic} environment. Therefore we turn off
% \cs{par} inside that environment, and then need(?) to turn it back on
% inside \cs{tlabel} and \cs{tcaption}. \cs{@@par} (in \LaTeX) and
% \cs{endgraf} (in plain \TeX) should equal the primitive \cs{par}.
%    \begin{macrocode}
\if@mfp@latex \else \let\@@par\endgraf \fi
\def\mfp@restorepar{\let\par\@@par}%
%    \end{macrocode}
%
% Some \mfpic{} commands end with \cs{ignorespaces}. For some others a
% better choice is the \LaTeX{} strategy of conditionally ignoring spaces.
%    \begin{macrocode}
\if@mfp@latex\else
  \def\@namedef#1{\@xp\def\csname #1\endcsname}%
  \def\@nameuse#1{\csname #1\endcsname}%
\fi
\mfp@ifdefined\@bsphack{}%
 {\@nameuse{newskip}\@savsk
  \@nameuse{newcount}\@savsf
  \def\@bsphack{\relax
    \ifhmode \@savsk\lastskip \@savsf\spacefactor \fi}%
  \def\@esphack{\relax
    \ifhmode \spacefactor\@savsf
    \ifdim\@savsk>\z@ \ignorespaces
    \fi\fi}}%
%    \end{macrocode}
%
% We sometimes (either by accident or by choice) redefine things defined
% in some formats. For the accidental redefinitions we want to be told,
% and since we cannot assume \LaTeX{} with its \cs{newcommand}, we define
% a simple check and print a warning when it happens.
%    \begin{macrocode}
\mfp@DBlog{Defining test for previous definitions of macros.}%
\mfp@ifdefined\mfp@testdef
  {\Mfpic@warn{%
    Hey!  How can \string\mfp@testdef\space already be defined? %
    \@msgbreak I'll redefine it anyway!}}%
  {}%
\def\mfp@testdef#1{%
  \ifx#1\UndEfInEd
  \else\ifx#1\relax
    \Mfpic@warn{\string #1 was previouly defined to be \string\relax.}%
  \else
    \Mfpic@warn{\string #1 is already defined!}%
  \fi\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\newdef}
% \DescribeMacro{\newlet}
% Is the proposed definer of new definitions itself not new? Well,
% we'd like a warning, but go ahead and define it anyway. All
% \cs{newdef} does is check whether the macro being defined is already
% defined, raise a warning (but \emph{not} an error) and define it
% anyway. We do something similar with \cs{let}.
%    \begin{macrocode}
\mfp@testdef\newdef
\mfp@testdef\newlet
\def\newdef#1{\mfp@testdef#1\def#1}%
\newdef\newlet#1{\mfp@testdef#1\let#1}%
%    \end{macrocode}
%
%
% \section{Configuring \mfpic{} behavior}\label{configuring}
%
% \subsection{Options}\label{options}
%
% \DescribeMacro{ifmfpmpost}
% I have decided to make this a user-level macro so that a user can
% write code that behaves one way for \MP{} and another for \MF. However
% the commands to change the setting are private.
%
% Our switch to turn \MP{} support on or off needs to be global, so it
% can't be a normal \cs{newif}.
%    \begin{macrocode}
\global\let\ifmfpmpost\iffalse
\newdef\mfp@mposttrue {\global\let\ifmfpmpost\iftrue}%
\newdef\mfp@mpostfalse{\global\let\ifmfpmpost\iffalse}%
\newdef\mfp@ifmpost{%
  \ifmfpmpost\@xp\@firstoftwo\else\@xp\@secondoftwo\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\usemetafont}
% We make a user-level commands for switching to the appropriate drawing
% program. This is necessary for plain\TeX, but also used internally by
% \mfpic. \CMF{} is the default. This command needs to not only clear the
% boolean \cs{ifmfpmpost}, but also restore the default graphics inclusion
% commands. Actually, it doesn't \emph{need} to unless \cs{usemetapost}
% was previously issued to change the default. This would normally not
% happen unless the user wanted to close the current graph file and open a
% new one for \MF.
%
% \MP{} support requires macros for including EPS graphics. What works
% best depends on the format, so we delay the definition of
% \cs{usemetapost} until the \LaTeX{} options section, but we define the
% error message here.
%    \begin{macrocode}
\newdef\usemetafont{\mfp@mpostfalse
  \def\preparemfpicgraphic##1{}%
  \def\setmfpicgraphic##1{\@graphfont\char\mfp@count}%
  \def\getmfpicoffset##1{}}%
\newdef\MPtoolate@error{%
  \mfp@errmsg {Command \string\usemetapost\space too late.}%
   {It is too late to select the metapost option.^^J%
    It must be selected before the \opengraphsfile command.^^J%
    If you proceed, the metafont option will be assumed.}}%
%    \end{macrocode}
%
% Some options need an open \file{.mf} or \file{.mp} file before they
% can do anything. This means the \cs{opengraphsfile} command must have
% been issued but not \cs{closegraphsfile}. Since those commands define and
% undefine \cs{mfp@filename}, we use that as our test.
%    \begin{macrocode}
\newdef\@ifmfpfileisopen{\mfp@ifdefined\mfp@filename}%
%    \end{macrocode}
%
% \DescribeMacro{\setmfvariable}
% \DescribeMacro{\setmpvariable}
% A useful abbreviation for a common requirement: declaring and setting
% a \MF{} variable. I have decided to change it to a user level macro for
% power users. \cs{setmpvariable} is another name for it. It takes three
% arguments: the type of variable, the variable itself, and its value.
% Example: \cs{setmfvariable}\marg{numeric}\marg{shadewd}\marg{.7pt}.
% Since it \mfc{save}\,s the variable, it must not have a suffix. This is
% not a big problem since mostly it is for internal use. We document
% that fact for power users and advise ordinary users on the naming of
% \MF{} variables.
%
% \DescribeMacro{\setmfboolean}
% \DescribeMacro{\setmfnumeric}
% \DescribeMacro{\setmfcolor}
% Abbreviations for the most common internal uses. In the case of \MF,
% color is the same numeric, but in \MP{} it is a separate variable type.
%    \begin{macrocode}
\newdef\setmfvariable#1#2#3{%
  \@ifmfpfileisopen{\mfcmd{setvariable (#1) (#2) (#3)}}{}}%
\newlet\setmpvariable\setmfvariable
\newdef\setmfboolean#1#2{\setmfvariable{boolean}{#1}{#2}}%
\newdef\setmfnumeric#1#2{\setmfvariable{numeric}{#1}{#2}}%
\newdef\setmfcolor#1#2{\setmfvariable{color}{#1}{#2}}%
%    \end{macrocode}
%
% The command \cs{setmfvariable} arranges for the value of
% that variable to be localized to each figure if set inside one, but
% it is global otherwise. We have to be careful that \TeX{} and \MF{}
% stay in sync, as they have different understandings as to what is
% global and what is not. So we define a switch that will be set at the
% start of an \env{mfpic} environment to test if a command is issued
% inside one.
%
% We also define here \texttt{true} and \texttt{false} as macros. These
% are strings we need to write to the output frequently.
%    \begin{macrocode}
\let\ifin@mfpicenv\iffalse
\newdef\mfp@local{\relax\ifin@mfpicenv\else\global\fi}%
\newdef\mf@T{true}%
\newdef\mf@F{false}%
\newdef\mfp@let{\mfp@local\let}%
\newdef\mfp@def{\mfp@local\def}%
%    \end{macrocode}
%
% \DescribeMacro{\usecenteredcaptions}
% \DescribeMacro{\nocenteredcaptions}
% This (\opt{centeredcaptions}) is the simplest option. Other options
% follow a similar pattern: user-level commands are defined for
% turning on (and sometimes turning off) the option. Selection of
% centered captions can be turned on or off at will throughout a
% document.
%    \begin{macrocode}
\newdef\usecenteredcaptions{\mfp@let\if@mfp@centcapt\iftrue}%
\newdef\nocenteredcaptions {\mfp@let\if@mfp@centcapt\iffalse}%
\nocenteredcaptions
%    \end{macrocode}
%
% This common code is repeated almost verbatim four times, so we define
% the following abbreviation. The first two arguments are the commands
% to turn the option on and off. The third and fourth are the \TeX{} and
% \MF{} booleans to switch. In all cases, the default for the option is
% \emph{off}, so we run \texttt{\#2} at the end.
%    \begin{macrocode}
\newdef\mfp@makeoption#1#2#3#4{%
  \newdef#1{\mfp@let#3\iftrue\setmfboolean{#4}\mf@T}%
  \newdef#2{\mfp@let#3\iffalse\setmfboolean{#4}\mf@F}
  #2}%
%    \end{macrocode}
%
% \DescribeMacro{\clipmfpic}
% \DescribeMacro{\noclipmfpic}
% The \opt{clip} option shows only what's inside the rectangle
% given in the \cs{mfpic} command. It can be turned on or off for
% each figure independently. The default is the old behavior: no
% clipping.
%
% If the output file has not been opened, \cs{setmfboolean} does nothing.
% But the \cs{opengraphsfile} code checks the boolean and writes the
% appropriate code.
%    \begin{macrocode}
\mfp@makeoption\clipmfpic\noclipmfpic\if@mfp@clip{clipall}%
%    \end{macrocode}
%
% \DescribeMacro{\usetruebbox}
% \DescribeMacro{\notruebbox}
% The \opt{truebbox} option lets \MP{} set the true bounding box (which
% may differ from the numbers defined through \cs{mfpic}).
%
% We don't need to be too careful with the scope of truebbox. As
% currently written, \TeX{} never needs to know the setting except to pass
% the information on to \cs{opengraphsfile} if the option is set before
% then. However, we treat it like most other settings, turning on or off
% an appropriate \TeX{} boolean, in case it ever becomes necessary to know
% the setting. It is local to any \env{mfpic}, global otherwise. The
% default is to have \opt{truebbox} turned off.
%    \begin{macrocode}
\mfp@makeoption\usetruebbox\notruebbox\if@mfp@truebbox{truebbox}%
%    \end{macrocode}
%
% Some options and commands require the \opt{metapost} option be in
% effect. We define a generic error message for such cases. If a command
% or option requires \MP, but the \opt{metapost} option is not set, the
% option is ignored, or the command aborted.
%    \begin{macrocode}
\newdef\noMP@error#1{%
  \mfp@errmsg {Metafont does not support #1, use MetaPost.}%
   {Metafont doesn't support #1. Perhaps you forgot to turn on^^J%
    MetaPost support by using the metapost option or issuing the^^J%
    command \usemetapost. For now, I will ignore it.}}%
%    \end{macrocode}
%
% \DescribeMacro{\usemplabels}
% \DescribeMacro{\nomplabels}
% An option to let \MP{} create labels, \opt{mplabels} mostly just
% switches between two versions of \cs{tlabel} so no \MP{} booleans
% are set and so syncronization of scope is not an issue. The default
% is the old behavior: labels are placed by \TeX. The actual setting is
% delayed until \cs{opengraphsfile} so the order of these commands and
% \cs{usemetapost} is not significant (before \cs{opengraphsfile}).
%
% Because of the frequent need to check this setting, we define
% \cs{@ifmplabels} to execute one of two alternatives based on it.
%    \begin{macrocode}
\newdef\usemplabels{\mfp@let\if@mfp@mplabels\iftrue
  \@ifmfpfileisopen
   {\mfp@ifmpost{}%
     {\noMP@error{mplabels}\global\let\if@mfp@mplabels\iffalse}}{}}%
\newdef\nomplabels{\mfp@let\if@mfp@mplabels\iffalse}%
\newdef\@ifmplabels{%
  \if@mfp@mplabels\@xp\@firstoftwo\else\@xp\@secondoftwo\fi}%
\nomplabels
%    \end{macrocode}
%
% \DescribeMacro{\overlaylabels}
% \DescribeMacro{\nooverlaylabels}
% These control an option to defer adding labels (in \MP) until the end
% of the picture. That means they don't get clipped or covered up by any
% drawing elements. Neither of these commands affect \MF, but they write
% to the output file anyway if issued after \cs{opengraphsfile}.
%    \begin{macrocode}
\mfp@makeoption%
  \overlaylabels\nooverlaylabels\if@mfp@overlabels{overlaylabels}%
%    \end{macrocode}
%
% \DescribeMacro{\clearsymbols}
% \DescribeMacro{\noclearsymbols}
% These determine whether the symbols drawn by \cs{plotsymbol} and
% \cs{plotnodes} should have their interiors erased before being drawn.
%    \begin{macrocode}
\mfp@makeoption%
  \clearsymbols\noclearsymbols\if@mfp@clearsym{clearsymbols}%
%    \end{macrocode}
%
% \subsection{Graphic inclusion}\label{graphic}
%
% \DescribeMacro{\mfpicllx}
% \DescribeMacro{\mfpiclly}
% The code to include a figure has been divided into three parts. Under
% \opt{metapost} we need to both include the figure and save the
% bounding box coordinates of the lower left corner. Here we initialize
% the macros that hold these coordinates.
%    \begin{macrocode}
\def\mfpicllx{0}%
\def\mfpiclly{0}%
%    \end{macrocode}
%
% \DescribeMacro{\preparemfpicgraphic}
% Most EPS inclusion macros make the bounding box information available,
% and so after the inclusion command we just save it in the above two
% macros. However, \LaTeX's \cs{includegraphics} does not, so we have to
% issue a command before the inclusion to force it to become available.
% That command is \cs{preparemfpicgraphic}. Usually it does nothing,
% but in the \LaTeXe{} case it locally redefines one of the graphics
% packages internal macros.
%
% \DescribeMacro{\setmfpicgraphic}
% This command includes the graphic. The \mfpic{} default (for the
% \opt{metafont} option) is set by running \cs{usemetafont}.
%
% \DescribeMacro{\getmfpicoffset}
% This one saves the lower left corner in the macros \cs{mfpicllx} and
% \cs{mfpiclly}. In the case described above, that is accomplished by
% the redefined internal command, so this command does nothing.
%
% The command \cs{@setmfpicgraphic} is a wrapper around the inclusion
% code. It takes the name of the graphic file and passes it along to the
% above three commands. Those three commands can be redefined by the
% user for special circumstances. The user is then responsible to make
% sure \cs{mfpicllx} and \cs{mfpiclly} are properly set when necessary.
% Redefining one may necessitate redefining one or both of the others.
%
% The definition of these three is delayed to the option processing
% section, except under the \MF{} default: \cs{usemetafont} defines them.
%    \begin{macrocode}
\newdef\@setmfpicgraphic#1{%
  \preparemfpicgraphic{#1}\setmfpicgraphic{#1}\getmfpicoffset{#1}}%
\usemetafont
%    \end{macrocode}
%
% \DescribeMacro{\setfilename}
% The user can also change \cs{setfilename} to modify the assumed
% filenames of the graphics output by \MP. The default is to concatenate
% the output file's basename with the picture number.
%    \begin{macrocode}
\newdef\setfilename#1#2{#1.#2}%
%    \end{macrocode}
%
% \DescribeMacro{\ifmfpicdraft}
% \DescribeMacro{\mfpicdraft}
% \DescribeMacro{\mfpicfinal}
% \DescribeMacro{\mfpicnowrite}
% The \opt{draft}, \opt{final} and \opt{nowrite} options override
% \mfpic's attempts to automatically detect whether the eps
% files should be included. The \opt{final} option can also be used to
% override a global draft option. Each of these sets the user level
% if-command \cs{ifmfpicdraft}, which is retained for backward
% compatibility. These settings are global since they are intended to
% be set for the whole document. The four commands
% \cs{@mfp@draft/finaltrue/false} are used to communicate with the
% \cs{opengraphsfile} command, in case the user-level commands occur before
% then.
%    \begin{macrocode}
\newif\ifmfpicdraft
\newif\if@mfp@draft
\newif\if@mfp@final
\newif\if@mfp@nowrite
\newdef\mfpicdraft{%
  \@ifmfpfileisopen{\global\mfpicdrafttrue}%
   {\global\@mfp@drafttrue}}%
\newdef\mfpicfinal{%
  \@ifmfpfileisopen{\global\mfpicdraftfalse}%
    {\global\@mfp@finaltrue}}%
\newdef\mfpicnowrite{%
  \@ifmfpfileisopen
   {\mfp@errmsg
     {Improper use of command \string\mfpicnowrite\@online.}%
     {You must issue the command \mfpicnowrite prior to
        \opengraphsfile. It will be ignored now.}}%
   {\global\@mfp@nowritetrue}}%
%    \end{macrocode}
%
% \subsection{\CMP{} graphics and \LaTeX{} options}\label{latex}
%
% Code dependent on \LaTeXe. Mostly this is the option processing
% facilities.
%    \begin{macrocode}
\if@mfp@latexe
  \ProvidesPackage{mfpic}[2004/04/16 v0.7a beta.]%
  \DeclareOption{draft}{\mfpicdraft}%
  \DeclareOption{final}{\mfpicfinal}%
  \DeclareOption{nowrite}{\mfpicnowrite}%
  \DeclareOption{metapost}{\mfp@mposttrue}%
  \DeclareOption{metafont}{\usemetafont}%
  \DeclareOption{centeredcaptions}{\usecenteredcaptions}%
  \DeclareOption{clip}{\clipmfpic}%
  \DeclareOption{truebbox}{\usetruebbox}%
  \DeclareOption{mplabels}{\usemplabels}%
  \DeclareOption{overlaylabels}{\overlaylabels}%
  \DeclareOption{clearsymbols}{\clearsymbols}%
  \DeclareOption{debug}{\mfpicdebugtrue}%
  \DeclareOption*{%
    \@ifpackageloaded{graphics}%
     {\Mfpic@warn{Unrecognized option \CurrentOption.}}%
     {\Mfpic@msg{Passing option \CurrentOption\space to %
      graphics package.}%
      \PassOptionsToPackage{\CurrentOption}{graphics}}}%
%    \end{macrocode}
% If \file{mfpic.cfg} exists, it will be input at this point. Then,
% we \cs{ProcessOptions}, using the *-form because it allows package
% options to take precedence over global options. Thus \mfpic's
% \opt{final} option can counteract the \mfpic-specific side effects of a
% global \opt{draft} option.
%    \begin{macrocode}
  \InputIfFileExists{mfpic.cfg}{}{}%
  \ProcessOptions*\relax
%    \end{macrocode}
%
% \DescribeMacro{\usemetapost}
% Finally, one of the definitions of \cs{usemetapost}. The other is
% for use outside \LaTeXe, when the \prog{graphics} package cannot be
% assumed to be available.
%    \begin{macrocode}
  \def\usemetapost{%
    \@ifmfpfileisopen{\mfp@mpostfalse\MPtoolate@error}%
     {\mfp@mposttrue \RequirePackage{graphics}%
%    \end{macrocode}
%
% Unlike all the other eps inclusion macros, \cs{includegraphics} does
% not make the bounding box coordinates available: \cs{Gin@llx} and the
% others are defined, but are local to a group surrounding the internals
% of \cs{includegraphics}. We locally modify one graphics package internal
% macro to globally save the information we need. Here we save the
% original definition and define our replacement. This definitely needs
% to come after the above \cs{RequirePackage} command.
%    \begin{macrocode}
      \global\let\mfp@save@parse@bb\Gread@parse@bb
      \gdef\mfp@parse@bb##1 ##2 ##3 ##4 ##5\\{%
        \mfp@save@parse@bb##1 ##2 ##3 ##4 ##5\\%
        \xdef\mfpicllx{\Gin@llx}\xdef\mfpiclly{\Gin@lly}}%
%    \end{macrocode}
%
% The \prog{graphics} package (as opposed to the \prog{graphicx} package)
% is far too dependent on actual extensions. Since we don't want to
% force our users to rename all the graphics output by \MP, we have to
% force \cs{includegraphics} to treat the current extension (some number)
% as if it were `{\tt eps}' or `{\tt mps}' according to the context. We
% decide which at this point.
%    \begin{macrocode}
      \if@mfp@pdf \gdef\mfp@Gtype{mps}%
      \else       \gdef\mfp@Gtype{eps}%
      \fi
%    \end{macrocode}
%
% The code we add to \cs{setmfpicgraphic} replaces \cs{Gread@parse@bb} with
% our own version.
%    \begin{macrocode}
      \gdef\preparemfpicgraphic##1{%
        \let\Gread@parse@bb\mfp@parse@bb}%
      \gdef\getmfpicoffset##1{}%
      \gdef\setmfpicgraphic##1{\includegraphics{##1}}}}%
%    \end{macrocode}
%
% \cs{ProcessOptions} doesn't allow \cs{RequirePackage}\marg{graphics},
% so the above and the following were not simply put inside
% \cs{DeclareOption}\marg{metapost}. The \cs{AtEndDocument} command will
% close the output file if the user forgot.
%    \begin{macrocode}
  \mfp@ifmpost{\usemetapost}{}%
  \AtEndDocument{\@closegraphsfile}%
%    \end{macrocode}
%
% Now those cases outside \LaTeXe{} that we try to support.
%    \begin{macrocode}
\else
  \Mfpic@msg{\mfpfiledate\space v\mfpfileversion.}%
%    \end{macrocode}
%
% \DescribeMacro{\usemetapost}
% The definition of \cs{usemetapost} depends on the setting of
% \cs{if@mfp@pdf}: \file{epsf.tex} is used for regular \TeX{} and
% \file{supp-pdf.tex} for \pdfTeX.
%    \begin{macrocode}
  \if@mfp@pdf
    \def\usemetapost{%
      \@ifmfpfileisopen{\mfp@mpostfalse\MPtoolate@error}%
       {\mfp@mposttrue
        \mfp@ifdefined\convertMPtoPDF{}{\input supp-pdf\relax}%
%    \end{macrocode}
% The command \cs{convertMPtoPDF} takes the filename and and two
% scaling factors. It parses the files PS contents to PDF code. It leaves
% the bounding box info in macros \cs{MPllx}, etc.
%    \begin{macrocode}
        \gdef\setmfpicgraphic##1{\convertMPtoPDF{##1}{1}{1}}%
        \gdef\getmfpicoffset##1{%
          \xdef\mfpicllx{\MPllx}\xdef\mfpiclly{\MPlly}}}}%
  \else
%    \end{macrocode}
% The final case is the generic plain\TeX, \AmSTeX, or \LaTeX2.09. Our
% code uses the macros from \file{epsf.tex}, which should be present in
% every installation that includes \prog{dvips}. The command
% \cs{epsfbox} takes the filename, writes a \cs{special} for
% \prog{dvips} (and other programs) and saves the bounding box
% coordinates in \cs{epsfllx}, etc.
%    \begin{macrocode}
    \def\usemetapost{%
      \@ifmfpfileisopen{\mfp@mpostfalse\MPtoolate@error}%
       {\mfp@mposttrue
        \mfp@ifdefined\epsfbox {}{\input epsf\relax}%
        \gdef\setmfpicgraphic##1{\epsfbox{##1}}%
        \gdef\getmfpicoffset##1{%
          \xdef\mfpicllx{\epsfllx}\xdef\mfpiclly{\epsflly}}}}%
  \fi
\fi
%    \end{macrocode}
%
%
% \section{Optional parameter handling}\label{optional}
%
% We borrow \LaTeX's \cs{@ifnextchar} to have the advantage of
% skipping spaces and EOLs, but we skip \cs{relax} as well. The reason for
% this last is that an EOL will be set equal to \cs{relax} in certain
% contexts and we want option handling to work the same there as
% elsewhere. This could be a mistake, since \cs{relax} is a common method
% to halt such things. However, there should be no occasion in an
% \env{mfpic} environment where one would want a `\texttt[' to follow a
% command and \emph{not} be an optional argument. In text label commands
% we restore the meaning of blank lines, and EOLs ought to be normal.
%
% The first argument of \cs{mfp@ifnextchar} is the token being checked. It
% doesn't have to be a character and we sometimes use \cs{mfp@ifnextchar}
% to check whether a certain command follows. However, it is usually
% `\texttt['. The next argument is the code to run if that character is
% present, the last is code to use if the character is not present. The
% first argument must end with code that handles the character.
%
% The reason for the \cs{long} in the code when the next token is
% \cs{relax} is that it may be \cs{par} which has been \cs{let} equal to
% \cs{relax} in \env{mfpic} environments.
%    \begin{macrocode}
\mfp@DBlog{Handlers for optional parameters.}%
\long\def\mfp@ifnextchar#1#2#3{%
  \let\mfptmp@d=#1\def\mfptmp@a{#2}%
  \def\mfptmp@b{#3}\mfp@checknext}%
\def\mfp@checknext{\futurelet\@let@token\mfp@ifnch}%
\def\mfp@ifnch{%
  \ifx\@let@token\@sptoken
    \let\mfptmp@c\eatspace@checknext
  \else\ifx\@let@token\relax
    \long\def\mfptmp@c##1{\mfp@checknext}%
  \else\ifx\@let@token\mfptmp@d
    \let\mfptmp@c\mfptmp@a
  \else
    \let\mfptmp@c\mfptmp@b
  \fi\fi\fi\mfptmp@c}%
\begingroup
  \def\:{\global\let\@sptoken= }\: %
  \def\:{\eatspace@checknext}\@xp\gdef\: {\mfp@checknext}%
\endgroup
%    \end{macrocode}
%
% I've taken to making an empty optional argument the default for a lot
% of commands. I wanted to make it possible to have the same result for
% empty brackets (i.e., \texttt{[]}) as for omitted brackets.
% The following helps check for emptyness. It uses a simple \cs{if} so
% that \texttt{\#1} will be expanded. I use a non-active
% \texttt{\textasciitilde} to test for emptyness because, even if a tilde
% should accidentally occur in \texttt{\#1}, it will most likely be active
% and expand to something else. In fact, in plain \TeX,
% \cs{mfp@ifempty}\marg{\textasciitilde} will compare
% \texttt{\textasciitilde} to \cs{penalty} and in \LaTeX{} to
% \cs{unhbox}.
%
% The \cs{@ifmtarg} macro is borrowed from \file{ifmtarg.sty}.
% It is used when a space should count as empty, but expansion isn't
% wanted.
%    \begin{macrocode}
\newdef\mfp@ifempty#1{%
  \if~#1~\@xp\@firstoftwo\else\@xp\@secondoftwo\fi}%
\begingroup
\catcode`Q=3
\long\gdef\@ifmtarg#1{\@xifmtarg#1QQ\@secondoftwo\@firstoftwo\@nil}%
\long\gdef\@xifmtarg#1#2Q#3#4#5\@nil{#4}%
\endgroup
\newdef\@ifmtsub#1#2{\@ifmtarg{#1}{#2}{#1}}%
\newdef\mfp@mtsub#1#2{\mfp@ifempty{#1}{#2}{#1}}%
%    \end{macrocode}
%
% The following is a historical holdover. Originally all optional arguments
% were handled through \cs{do@ptparam}. Then there arose cases that did not
% fit its assumptions and I wrote \cs{alt@ptparam}. Then, it became more
% efficient to have \cs{mfp@ifnextchar} (defined above) and now
% this command is defined in terms of it.
%
% The first argument of \cs{do@ptparam} is the command to use and the
% second is a default value of the optional argument. The command must be
% defined, and it must be a command whose first argument is delimited by
% `{\tt[}' and `{\tt]}'. Currently this is no longer used: all commands
% use one of the variants below.
%    \begin{macrocode}
\newdef\do@ptparam#1#2{\mfp@ifnextchar[{#1}{#1[#2]}}%
%    \end{macrocode}
%
% These are variations on the above. In \cs{simple@opt}, if an optional
% argument is present, we check to see if it is empty and substitute the
% default if it is. This was so named because I intended that it be used
% only if the optional argument required no further parsing (because it
% turned the argument into a nondelimited one). But now we use it even
% then and the few commands that require further parsing handle it more or
% less ad hoc.
%
% \cs{null@opt} is a convenient abbreviation for a common case: the
% default option is null.
%    \begin{macrocode}
\newdef\simple@opt#1#2{%
  \mfp@ifnextchar[{\process@opt{#1}{#2}}{#1{#2}}}%
\newdef\process@opt#1#2[#3]{%
  \mfp@ifempty{#3}{#1{#2}}{#1{#3}}}%
\newdef\null@opt#1{\mfp@ifnextchar[{#1}{#1[]}}%
%    \end{macrocode}
%
% Quite a few \mfpic{} commands stuff several parameters into a
% single optional argument. Generally, these commands can be coded to
% proceed gracefully if the last parameter is missing (substituting a
% default). However, if more than that are missing, \TeX{} gobbles the
% closing bracket and produces pretty inscrutable  error mesages. This
% (adding extra information in one optional argument) was, in retrospect,
% a bad design decision that was made for backward compatibility and
% (originally) to minimize the changes in existing commands.
% Unfortunately we are stuck with it for at least the near future.
%
% We use the following utility to check for empty optional parameters.
% \begin{itemize}
%   \item {\tt\#1} is the parameter to test (passed by some other macro)
%   \item {\tt\#2} is what to use if {\tt\#1} is empty.
%   \item {\tt\#3} is the command being passed the optional argument
% \end{itemize}
% We use a \cs{mfp@ifempty} so \texttt{\#1} will get expanded (often we
% pass arguments as macros). After the above revamping of optional
% argument handling, we ended up needing this code only once.
%    \begin{macrocode}
\newdef\do@mtparam#1#2#3{\mfp@ifempty{#1}{#3[#2]}{#3[#1]}}%
%    \end{macrocode}
%
%
% \section{Writing to the \file{.mf} or \file{.mp} file}\label{writing}
%
% \subsection{Preserving linebreaks}\label{linebreaks}
%
% Some macros can take quite long arguments (we call them
% \cs{@listmac}\,s), especially if they are automatically generated by
% some program. While the output file need not ever be looked at, there
% can be a problem with lines too long for the \MF{} executable's line
% buffer. Plus, for debugging, we might want to examine the file \mfpic{}
% writes. We therefore try to get at least the list macros to preserve
% linebreaks on output.
%
% \DescribeMacro{\mfpicobeylines}
% We make use of the \TeX{} property that expandable commands are
% expanded inside \cs{write} commands, but unexpandable commands and
% characters are written verbatim (almost). If this were the only
% consideration, nothing would need to be done. But characters with
% catagory code 5 (end-of-line) are converted to spaces upon reading, so
% we have to change the category of the \cs{endlinechar}, or we have
% change the \cs{endlinechar} to a character in a different category.
% We do the former, because the line a macro starts on will already have
% the end-of-line character added, but its category will not yet be
% established. We need a category that \TeX{} will not \emph{ignore},
% but that nevertheless has no (or minimal) side effects if encountered in
% a \TeX{} file. We therefore make it active, but \cs{let} it equal to
% \cs{relax}. This makes the end-line-character unexpandable.
%    \begin{macrocode}
\mfp@DBlog{Direct output to Metafont/Post file.}%
\begingroup
  \catcode\mfp@ctrlM\active%
  \gdef\@activectrlM{^^M}%
  \gdef\mfpicobeylines{\catcode\mfp@ctrlM\active\let^^M\relax}%
\endgroup
%    \end{macrocode}
%
% The choice \cs{relax} seems to be actually a slightly better choice
% than \cs{endgraf} (which we used to use, and which equals the
% unexpandable primative \cs{par}) because \cs{relax} is permitted before
% the opening brace in the syntax of \meta{general text} (for token
% variable assignments, \cs{write}, \cs{message}, and the like) as well as
% being skipped in mfpic's version of \cs{@ifnextchar}.
%
% \DescribeMacro{\preservelines}
% The character assigned to \cs{endlinechar} is added to the end of all
% lines read in by \TeX. The character assigned to \cs{newlinechar}
% will produce a newline when it occurs in a \cs{write}. Our
% \cs{preservelines} ensures these are the same and makes the above
% changes in category.
%    \begin{macrocode}
\newdef\preservelines{\newlinechar\mfp@ctrlM
  \endlinechar\newlinechar \mfpicobeylines}%
%    \end{macrocode}
%
% \DescribeMacro{\unpreservelines}
% This is no longer used and may some day be removed. Grouping is
% enough to isolate effects of \cs{preservelines}. The command
% \cs{unpreservelines} simply restores the catcode of control-M to the
% control-M to the usual in formats consistent with plain \TeX. If we
% really wanted to reverse the effects of \cs{preservelines}, we'd have to
% save and restore the four items changed: the values of \cs{newlinchar}
% and \cs{endlinechar}, the category of control-M, and the definition of
% an active control-M.
%    \begin{macrocode}
\newdef\unpreservelines{\catcode\mfp@ctrlM=5 }%
%    \end{macrocode}
%
% \DescribeMacro{\mfsrc}
% \DescribeMacro{\mfcmd}
% \DescribeMacro{\mflist}
% We want these to issue \cs{preservelines} before the text is read
% (and category codes assigned). Also we often want to add a few items to
% the argument (figure macros append a semi-colon, list macros surround
% with parentheses), so we isolate the common starting code in
% \cs{@mfwrite}, and then invoke the appropriate continuation command.
% The ending code is in \cs{@mfsrc}. The \cs{begingroup} in
% \cs{@mfwrite} matches the \cs{endgroup} in \cs{@mfsrc}. The group
% isolates the changes to EOLs. We also equate \cs{@nl} to an active
% control-M so that it can be used for line breaks in cases where it is
% inconvenient to make EOLs active (in the replacement text of
% \cs{opengraphsfile} and \cs{@mfpic}, for example).
%    \begin{macrocode}
\newdef\mfsrc {\@mfwrite\@mfsrc\mfsrc}%
\newdef\mfcmd {\@mfwrite\@mfcmd}%
\newdef\mflist{\@mfwrite\@mflist}%
\newdef\@mfwrite{\begingroup
  \preservelines \let\@nl\@activectrlM}%
%    \end{macrocode}
%
% The macro \cs{@mfsrc} does the job of writing to files. The output
% stream \cs{mfp@out} is declared later. The other two commands invoke
% \cs{@mfsrc} on a slightly modified argument. The first argument to
% \cs{@mfsrc} is the command that called it (for the error message), the
% second is the code to write.
%    \begin{macrocode}
\newdef\@mfsrc#1#2{%
  \@ifmfpfileisopen{\immediate\write\mfp@out{#2}}%
   {\nooutputfileerror{#1}}\endgroup}%
\newdef\@mfcmd#1{\@mfsrc\mfcmd{#1;}}%
\newdef\@mflist#1{\@mfsrc\mflist{(#1);}}%
%    \end{macrocode}
%
% \subsection{Initializing the output file}\label{output}
%
% Category 12 characters percent, sharp and backslash signs for the
% \file{.mf} file. The command \cs{mf@d} is used to write a line of
% dashes above and below each figure to make them stand out when debugging
% the file. This might be removed in the final distribution.
%    \begin{macrocode}
\newdef\mfp@gobble#1{}%
\edef\mf@p{\@xp\mfp@gobble\string\%}%   percent (%)
\edef\mf@s{\@xp\mfp@gobble\string\#}%   sharp (#)
\edef\mf@b{\@xp\mfp@gobble\string\\}%   backslash (\)
\newdef\mf@d{--------------}%
%    \end{macrocode}
%
% Used to mark ends of things, \cs{mfp@delim} should never be expanded,
% but we give it a definition for debugging purposes:
%    \begin{macrocode}
\newdef\mfp@delim{%
  \mfp@errmsg {Misplaced \string\mfp@delim.}%
   {If you get this message but did not (mis)use the command^^J%
    \mfp@delim, please report this to the mfpic maintainer.}}%
%    \end{macrocode}
%
% The current date and time stamp will be written to the \file{.mf} file.
% We calculate it here and store the result in these macros. The commands
% \cs{normalyear} and \cs{normalmonth} are part of \ConTeXt, where they
% have been equated to the primitive commands \cs{year} and \cs{month}
% (which are then redefined).
%    \begin{macrocode}
{\mfp@ifdefined\normalmonth
    {\let\month\normalmonth\let\year\normalyear}{}%
  \xdef\mfp@today{\number\year/\ifnum\month<10 0\fi\number\month/%
    \ifnum\day<10 0\fi\number\day}%
  \count2=\time \divide\count2 by 60
  \xdef\mfp@now{\ifnum\count2<10 0\fi\number\count2:}%
  \multiply\count2 by -60 \advance\count2 \time
  \xdef\mfp@now{\mfp@now\ifnum\count2<10 0\fi\number\count2 }}%
%    \end{macrocode}
%
% These registers are allocated:
% \begin{itemize}
% \item \cs{mfp@out} Write stream for the \file{.mf} or \file{.mp} file.
% \item \cs{mfp@graph} Read stream used to test existence of files and
%       for reading datafiles.
% \item \cs{mfp@count} Number for next \env{mfpic} environment.
% \item \cs{mfp@linetype} Current line style in multi-curve data plots.
% \item \cs{mfp@n} Scratch counter, so far used only in writing data to
% the \file{.mf} file.
% \item \cs{mfp@sequence} Counter incremented with every datapoint written
% from a file to implement the feature that a list of numeric data can be
% plotted against its sequence position.
% \item \cs{mfp@toks} Temporary token register.
% \item \cs{every@tlabel} Tokens inserted at every \cs{tlabel}.
% \item \cs{mfp@verbtex} A temporary token list used by \cs{mfpverbtex}.
% \item \cs{mfp@commonverbatimtex} Tokens written at the start of every
% output file inside a \mfc{verbatimtex} group.
% \end{itemize}
%    \begin{macrocode}
\mfp@DBlog{Declarations used with data and graphs files.}%
\newwrite\mfp@out
\newread\mfp@graph
\newlet\mfp@data\mfp@graph
\newcount\mfp@count
\newcount\mfp@linetype
\newcount\mfp@n
\newcount\mfp@sequence
\newtoks\mfp@toks
\newtoks\every@tlabel
\newtoks\mfp@verbtex
\newtoks\mfp@commonverbatimtex
\every@tlabel{}%
%    \end{macrocode}
%
% We store most of the \mfc{verbatimtex} block that \mfpic{} relies on in
% the token register \cs{mfp@commonverbatimtex}. We do that because it
% relies on a couple of catcode changes and we want to be in a situation
% where we have that under control. Each line will end with an active
% ctrl-M, which is transformed by \cs{mfsrc} into a newline.
%    \begin{macrocode}
\begingroup
  \let\newtoks\relax
  \@makeother\%\@makeother\#\preservelines
  \global\mfp@commonverbatimtex=
    {\def\MFPtext#1{%
       \vbox{\def\\{\cr}\MFPcfont\everylabel
       \halign{##\hfil\cr#1\crcr}}}%
    }\endgroup
%    \end{macrocode}
%
% \DescribeMacro{\opengraphsfile}
% This is the main command to set up the output file. It also aims to
% check whether \MF{} or \MP{} has already been run on the output file,
% thereby determining whether the graphics can be included. It does this
% by checking for the existence of one of the products of these programs.
% In the case of \MF{} it looks for a \file{.tfm} file; in the case of
% \MP{} it looks for the first output graphic.
%
% The name of the output file is its only parameter, and it appends
% the extension \file{.mf} or \file{.mp} depending on the whether option
% \opt{metafont} or \opt{metapost} was chosen.
%    \begin{macrocode}
\mfp@DBlog{Macros to open and close graphs files.}%
\newdef\opengraphsfile#1{\@bsphack
%    \end{macrocode}
% A command can determine if it occurs after \cs{opengraphsfile} but
% before \cs{closegraphsfile} by testing whether \cs{mfp@filename} is defined.
%    \begin{macrocode}
  \@ifmfpfileisopen%
   {\Mfpic@warn
     {An attempt has been made to open a graph file, #1,
      \@msgbreak while another, \mfp@filename, is still open.
      \@msgbreak Closing \mfp@filename.}%
    \@closegraphsfile}%
   {}%
  \xdef\mfp@filename{#1}%
%    \end{macrocode}
% The value of \cs{mfp@count} should be the number of the first figure.
% We use the existence of that figure as a signal that there are graphics
% to be included.
%    \begin{macrocode}
  \mfp@ifmpost{%
    \openin\mfp@graph=\setfilename{\mfp@filename}{\number\mfp@count}%
    \relax
    \ifeof\mfp@graph \mfp@msg{}%
      \Mfpic@msg
        {No file \setfilename{\mfp@filename}{\number\mfp@count}.^^J}%
      \global\mfpicdrafttrue
    \else
      \global\mfpicdraftfalse
    \fi
%    \end{macrocode}
% Type out the \MP-specific portion of a reminder to process the
% output. Then on to the \MF{} case.
%    \begin{macrocode}
    \if@mfp@nowrite \else
      \immediate\openout\mfp@out=\mfp@filename.mp\relax
      \Mfpic@msg{Don't forget to process \mfp@filename.mp! %
        \@msgbreak (Apply metapost to \mfp@filename.mp.)}%
    \fi
  }{% metafont
%    \end{macrocode}
% Under the \opt{metafont} option, we check for the \file{.tfm} file.
% We do not simply try to load the font because that might trigger
% some \prog{maketfm} script which could be disastrous at this point,
% when the \file{.mf} file is in an uncertain state. We open the
% \file{.tfm} for input, and check \cs{ifeof}, as we did in the
% \MP{} graphic case.
%    \begin{macrocode}
    \openin\mfp@graph=\mfp@filename.tfm\relax
    \ifeof\mfp@graph \mfp@msg{}%
      \Mfpic@msg{No file \mfp@filename.tfm .^^J}%
      \global\let\@graphfont=\mfp@dummy
      \global\mfpicdrafttrue
%    \end{macrocode}
% If it does exist, we load the font and in either case type out the
% \MF{} specific portion of our reminder.
%    \begin{macrocode}
    \else
      \global\font\@graphfont=\mfp@filename\relax
      \global\mfpicdraftfalse
    \fi
    \if@mfp@nowrite \else
      \immediate\openout\mfp@out=\mfp@filename.mf\relax
      \Mfpic@msg{Don't forget to process \mfp@filename.mf! %
        \@msgbreak (Apply metafont to \mfp@filename.mf, %
        then gftopk to the resulting gf file.)}%
    \fi
  }%
%    \end{macrocode}
% The input stream used for testing is closed and the
% unspecific portion of the reminder is typed out, then
% the above settings of \cs{ifmfpicdraft} are overridden if the user has
% explicitly chosen the \opt{draft} or \opt{final} option. The
% \opt{nowrite} option merely disables the \cs{@mfsrc} command.
%    \begin{macrocode}
  \closein\mfp@graph
  \if@mfp@nowrite\else
    \Mfpic@msg{Then reprocess this file (\jobname).^^J}%
  \fi
  \if@mfp@draft\global\mfpicdrafttrue\fi
  \if@mfp@final\global\mfpicdraftfalse\fi
  \if@mfp@nowrite\gdef\@mfsrc##1##2{}\fi
%    \end{macrocode}
% The first two lines of the output file are comments identifying the
% file, the \mfpic{} version, the tex source file, and the date.
% Then we let \grafbase{} know the \mfpic{} version creating the file.
% After that we set the \mfc{mode}, the \mfc{mag} (both ignored by \MP),
% and arrange for \grafbase{} macros to be loaded. The current
% \grafbase{} checks the \gbc{mfpicversion}: if it is unknown, or not
% equal to the value of \gbc{grafbaseversion}, a diagnostic message is
% printed.
%    \begin{macrocode}
  \mfsrc{%
    \mf@p\space\mfp@filename.m\mfp@ifmpost{p}{f}, %
      generated by Mfpic, v\mfpfileversion\space\mfpfiledate,\@nl
    \mf@p\space from TeX source "\jobname" %
      on \mfp@today\space at \mfp@now\@nl
    numeric mfpicversion; mfpicversion:=\mfpicversion;\@nl
    if unknown mode: mode := localfont; fi\@nl
    if unknown mag: mag := \number\mag/1000; fi\@nl
    if unknown grafbase: input grafbase; fi\@nl\@nl
%    \end{macrocode}
% Then a comparison of the version of this file, stored in
% \cs{mfpicversion} with the version stored in the \grafbase{} variable
% \mfc{grafbaseversion}. This should catch mismatches the previous test
% would miss.
%    \begin{macrocode}
    if unknown grafbaseversion: grafbaseversion := 0; fi\@nl
    if grafbaseversion <> mfpicversion :\@nl
       GBmsg "Bad mfpic installation: mfpic and grafbase %
         versions do not match.";\@nl
    fi\@nl}%
%    \end{macrocode}
% For \opt{metapost} we need to load some color macros also, and write
% some setup for text labels (even if \cs{nomplabels}, because
% \cs{usemplabels could be turned on later}). \MF{} now can also handle
% the definitions in \file{dvipsnam.mp} but it seems a waste to load all
% those definitions just to get a few more grayscales (even given \MF{}
% can find that file).
%    \begin{macrocode}
  \mfp@ifmpost
   {\mfsrc{%
      if unknown Apricot: input dvipsnam.mp; fi\@nl
      verbatimtex\@nl
        \the\mfp@commonverbatimtex\@nl
        \def\noexpand\everylabel{\the\every@tlabel}\@nl
        \if@mfp@verbtex \the\mfp@verbtex\@nl \fi
      etex;\@nl}%
    \global\@mfp@verbtexfalse\mfp@verbtex{}%
%    \end{macrocode}
% Finally, we write information to the output file, and/or set switches
% based on the options as they are currently known. The \cs{usemplabels}
% was delayed until now so that the order of it and \cs{usemetapost}
% before now would not matter. The other five are issued now because they
% might require a write to the output file.
%    \begin{macrocode}
    \@ifmplabels{\usemplabels}{}%
    \if@mfp@truebbox \usetruebbox \fi
    \if@mfp@overlabels \overlaylabels \fi}{}%
  \if@mfp@clip \clipmfpic \fi
  \if@mfp@clearsym \clearsymbols \fi
  \if@shipping\else\stopshipping\fi
  \@esphack}%
%    \end{macrocode}
%
% \DescribeMacro{\closegraphsfile}
% This finishes off the output files and undefines \cs{mfp@filename}.
% We define an error message free version \cs{@closegraphsfile} for
% internal use. We unconditionally undefine \cs{mfp@filename} just in
% case.
%    \begin{macrocode}
\newdef\closegraphsfile{%
  \@ifmfpfileisopen{}{\nooutputfileerror\closegraphsfile}%
  \@closegraphsfile \global\let\mfp@filename\UndEfInEd}%
\newdef\@closegraphsfile{%
  \@ifmfpfileisopen
   {\if@mfp@nowrite \else
      \mfsrc{\@nl end.}\immediate\closeout\mfp@out
    \fi}{}}%
%    \end{macrocode}
%
% \DescribeMacro{\nooutputfileerror}
% We define a generic error message for macros that need an output file
% to write to. \cs{mfsrc} uses it, as does \cs{closegraphsfile}.
% \cs{mfpic} also uses it even though all its writes take place through
% \cs{mfsrc}. This avoids potentially hundreds of error messages.
%    \begin{macrocode}
\def\nooutputfileerror#1{%
  \mfp@errmsg {No output file has been opened.}%
   {You have tried to used a command, #1, that requires an output^^J%
    file to be opened with the \opengraphsfile command, which^^J%
    was either not issued or was not successful.}}%
%    \end{macrocode}
%
%
% \section{\Mfpic{} dimensions}\label{dimensions}
%
% A number of packages, especially figure drawing packages, allocate a
% great many dimension registers. The most familiar example is \PiCTeX{}
% which is at least partially responsible for most ``No room for a new
% \cs{dimen}'' error messages. \Mfpic{} also needs many dimension
% values, but some are set by macros that simply write the value to the
% \file{.mf} file and do not use any registers. A few are stored in
% \TeX{} registers, but most are stored using a trick with font
% dimensions.
%    \begin{macrocode}
\mfp@DBlog{Using dummy font's dimensions, to spare TeX registers.}%
%    \end{macrocode}
% While most fonts have relatively few font dimensions (twenty-two is a
% common number), it turns out that if one loads a font and immediately
% assigns a value to \cs{fontdimen}~$n$, Then \TeX{} acts as if the font
% has \cs{fontdimen}\,s 0 through $n$ available. They can be assigned
% dimension values just like \TeX{} dimension registers.
%
% Virtually all \TeX{} systems have a \file{dummy.tfm}, which contains
% no characters (it is used for syntax checking by some packages and
% classes). Since this trick will only work if we are the first to
% load the font (the \AmSTeX{} document style \file{amsppt.sty} loads
% the dummy font), we use another trick, which is to load it scaled to
% some unlikely value, which \TeX{} treats as a new font.
%    \begin{macrocode}
\font\mfp@dummy=dummy scaled 1042
\fontdimen100\mfp@dummy=0pt
%    \end{macrocode}
%
% Some versions of \file{dummy.tfm} have values already assigned to font
% dimensions 0 through 22. It would probably not hurt to use those, but
% we'll be cautious and use only font dimensions 23 and up, making 78
% available.
%
% We use an auxiliary count register to keep track of new font dimens.
%    \begin{macrocode}
\newcount\mfp@fdc
\mfp@fdc=22
%    \end{macrocode}
% \DescribeMacro{\newfdim}
% We define a macros that mimics the behavior of \cs{newdimen}, for
% allocating font dimension numbers. It increments \cs{mfp@fdc} and
% defines its argument \texttt{\#1} to expand to an assignment of the
% current \cs{fontdimen}.
%    \begin{macrocode}
\newdef\newfdim#1{%
  \global\advance\mfp@fdc 1
  \xdef#1{\fontdimen\number\mfp@fdc\mfp@dummy}%
  \wlog{\string#1=\string\fontdimen\number\mfp@fdc\mfp@dummy}}%
%    \end{macrocode}
% The definition (\cs{xdef}) is global since font dimension
% assignments are always global anyway. \TeX{} will not accept font
% dimensions in its syntax for the dimension arithmetic commands
% \cs{advance}, \cs{multiply} and \cs{divide}. In the rare cases where we
% need to do this we assign the value to a temporary register and
% calculate with it. It is, however OK to use them with a numeric factor.
%
% We allocate a couple of boxes. At the end of an \mfpic{}
% environment, \cs{@wholegraph} is loaded with the picture (possibly
% null) as it exists then. Inside the environment, when text labels are
% processed, \cs{@textbox} holds this text temporarily so it can be
% measured, moved about, etc. We also define abbreviations for the
% frequent commands that specify the dimensions of \cs{@textbox}
%    \begin{macrocode}
\mfp@DBlog{A box register for whole labeled graph, %
    and a temporary one.}%
\newbox\@wholegraph
\newbox\@textbox
\newdef\tb@ht{\ht\@textbox}% height,
\newdef\tb@dp{\dp\@textbox}% depth and
\newdef\tb@wd{\wd\@textbox}% width of the text label.
%    \end{macrocode}
%
% When labels are processed, they are accumulated in the box
% \cs{@alltlabels}. We allocate it, and four \cs{newfdim}\,s for the
% location of the four sides.
%    \begin{macrocode}
\newbox\@alltlabels
\newfdim\@tlabelstop
\newfdim\@tlabelsbot
\newfdim\@tlabelsleft
\newfdim\@tlabelsright
%    \end{macrocode}
%
% It can be argued that dimensions not needed by \TeX{} should be stored
% in the output file rather than allocating (font) dimensions. These are
% everything below from \cs{pointsize} through \cs{symbolspace},
% inclusive. This would make syncronictity between \TeX{} and \MF{} easier
% to maintain. Those that are needed by \TeX{} are then few enough to be
% regular \cs{dimen} registers, making them automatically local to each
% \env{mfpic} environment. Unfortunately, changing to such a scheme could
% break some past \mfpic{} files. It would also require recoding every
% command that now writes one of these dimensions to the output.
%
% One of these (\cs{@graphright}) is unused, except for debugging.
% We could also code around \cs{@graphwd} because it is always
% \cs{wd}\cs{@wholegraph}. ^^A Is this true? Check it out.
%    \begin{macrocode}
\mfp@DBlog{Internal dimension parameters for graph dimensions...}%
\newfdim\@graphwd
\newfdim\@graphright
\newfdim\@graphleft
\newfdim\@graphtop
\newfdim\@graphbot
\mfp@DBlog{...and dimension parameters for tlabel positioning.}%
\newfdim\tb@raise
\newfdim\tb@moveright
\newfdim\tb@totalht
%    \end{macrocode}
%
% The following are for label adjustments. The first two are used to
% implement the feature that all labels can be simultaneously shifted an
% equal amount. The last is for the feature that the label can be a
% certain distance separated from the point where it is placed.
%    \begin{macrocode}
\newfdim\tlabel@hadj
\newfdim\tlabel@vadj
\newfdim\tlabel@sep
\tlabel@hadj=0pt
\tlabel@vadj=0pt
\tlabel@sep=0pt
%    \end{macrocode}
%
% The following are default parameters for various graphics commands that
% take an optional argument for the size of something. We allocate them,
% and then initialize them.
%    \begin{macrocode}
\mfp@DBlog{User level dimension parameters, with default settings.}%
\newfdim\mfpicunit     % unit of length
\newfdim\pointsize     % diameter of circle
\newfdim\shadespace    % spacing of shade dots
\newfdim\polkadotspace % spacing of polkadots
\newfdim\hatchspace    % spacing of lines
\newfdim\headlen       % size of arrowhead (\arrow)
\newfdim\axisheadlen   % size of arrowhead (x, y axes)
\newfdim\sideheadlen   % size of arrowhead (border axes)
\newfdim\hashlen       % length of marks on axes
\newfdim\dashlen       % length of dashes (\dashed)
\newfdim\dashspace     %   space between dashes
\newfdim\dotsize       % size of dots (\dotted)
\newfdim\dotspace      %   space between dots
\newfdim\symbolspace   % space between symbols (\plot)
%
\mfpicunit=1pt
\pointsize=2pt
\shadespace=1pt
\polkadotspace=10pt
\hatchspace=3pt
\headlen=3pt
\axisheadlen=5pt
\sideheadlen=0pt
\hashlen=4pt
\dashlen=4pt
\dashspace=4pt
\dotsize=0.5pt
\dotspace=3pt
\symbolspace=5pt
%    \end{macrocode}
%
% Font dimensions are global, and so not restricted to an \env{mfpic}
% environment even when assigned inside one. This would require the
% user to restore a value every time one picture needed a different
% value from the rest. To avoid requiring this, the following macro is
% used to save all values of these dimensions at the start of a picture,
% and to restore the saved values at the end. (Some internal dimensions
% (\cs{@graph...}, for example) don't need saving since they are reset
% with each picture.)
%    \begin{macrocode}
\newdef\save@mfpicdimens{%
  \edef\restore@mfpicdimens{%
    \mfpicunit =\the\mfpicunit
    \pointsize =\the\pointsize
   \shadespace =\the\shadespace
\polkadotspace =\the\polkadotspace
   \hatchspace =\the\hatchspace
      \headlen =\the\headlen
  \axisheadlen =\the\axisheadlen
  \sideheadlen =\the\sideheadlen
      \hashlen =\the\hashlen
      \dashlen =\the\dashlen
    \dashspace =\the\dashspace
      \dotsize =\the\dotsize
     \dotspace =\the\dotspace
  \symbolspace =\the\symbolspace
  \tlabel@hadj =\the\tlabel@hadj
  \tlabel@vadj =\the\tlabel@vadj
   \tlabel@sep =\the\tlabel@sep}}%
%    \end{macrocode}
%
% \DescribeMacro{\mfpframesep}
% \DescribeMacro{\mfpframethickness}
% \DescribeMacro{\mfpicheight}
% \DescribeMacro{\mfpicwidth}
% \DescribeMacro{\mfpiccaptionskip}
% Here are the few dimension registers we do allocate. The first two are
% scratch registers, the next two govern frames, and the last two are set
% after each picture to that pictures size. A \cs{vskip} of
% \cs{mfpiccaptionskip} is placed between figure and caption by
% \cs{tcaption}.
%    \begin{macrocode}
\newdimen\mfp@scratch
\newdimen\mfp@scratchB
\newdimen\mfpframesep
\newdimen\mfpframethickness
\newdimen\mfpicheight
\newdimen\mfpicwidth
\newskip\mfpiccaptionskip
\mfpframethickness0.4pt
\mfpframesep2pt
\mfpiccaptionskip=\medskipamount
%    \end{macrocode}
%
%
% \section{Helper macros}\label{helper}
%
% \DescribeMacro{\mfpicnumber}
% We make a user-level macro for setting the number of the next graph.
% The purpose of this is so that the output file can be used as a font,
% setting the figure numbers to the ascii codes of printable characters.
% Then creating a composite figure is as easy as changing fonts:
% \marg{\cs{pic} ABABAAB}. The motivation came from a discussion on
% \texttt{comp.text.tex} started by someone who wanted to input a sequence
% of 0's and 1's and get a corresponding sequence of black and white
% squares.
%    \begin{macrocode}
\def\mfpicnumber#1{\global\mfp@count=#1\relax}%
%    \end{macrocode}
%
% \DescribeMacro{\mfpaddto}
% When placing text at intervals on an axis, we need to automatically
% calculate coordinates to feed to the \cs{tlabel} command. The
% following is a utility macro to add two real numbers. It is currently
% used only in the \cs{axislabels} command, so it needn't be globally
% defined, but it might be handy in the future.
% \begin{itemize}
% \item[] \texttt{\#1} is a \emph{macro} that expands to some number.
% \item[] \texttt{\#2} is a number to add to it.
% \end{itemize}
% The result is stored again in \texttt{\#1}, overwriting the old value.
%
% \DescribeMacro{\mfpmultiply}
% For my personal use (or for power users), this is the multiplicative
% version, with the same syntax and behavior.
%    \begin{macrocode}
\newdef\mfpaddto#1#2{\mfp@scratch=#1pt\advance\mfp@scratch#2pt
  \edef#1{\mfp@strippt\mfp@scratch}}%
\newdef\mfpmultiply#1#2{\mfp@scratch=#1pt \mfp@scratch#2\mfp@scratch
  \edef#1{\mfp@strippt\mfp@scratch}}%
\begingroup
  \@makeother P\@makeother T\lowercase{\gdef\mfp@factor#1PT{#1}}%
\endgroup
\newdef\mfp@strippt{\@xp\mfp@factor\the}%
%    \end{macrocode}
%
% A few user-level utilities.
%
% \DescribeMacro{\pointdef}
% A point defining macro, suggested by a user.
% \begin{itemize}
%   \item[] \texttt{\#1} is a symbolic name for a point, only letters.
%   \item[] \texttt{\#2} and \texttt{\#3} are the coordinates.
%   \item[] Usage: \cs{pointdef}\marg{A}\parg{2,5} makes \cs{A} expand
%           to \texttt{(2,5)}, \cs{Ax} to \texttt{2}, and \cs{Ay} to
%           \texttt{5}.
% \end{itemize}
%    \begin{macrocode}
\newdef\pointdef#1(#2,#3){%
  \@namedef{#1}{(#2,#3)}\@namedef{#1x}{#2}\@namedef{#1y}{#3}}%
%    \end{macrocode}
%
% \DescribeMacro{\pairarray}
% \DescribeMacro{\numericarray}
% The first enables the simultaneous definition of \MF{} pair variables
% \mfc{A1}, \mfc{A2}, etc, \mfc{A[n]} by writing,
% \cs{pairarray}\marg{A}\marg{\meta{list}}, the list being a list of
% $n$ ordred pairs. Numeric variables can be created similarly with the
% second command.
%    \begin{macrocode}
\newdef\pairarray#1{%
  \mfcmd{save #1}\mfsrc{textpairs (#1)}\mfp@writedata}%
\newdef\numericarray#1{\mfcmd{save #1; numeric #1; numeric #1[]}%
  \mfsrc{list (#1)}\mfp@writedata}%
%    \end{macrocode}
%
% \DescribeMacro{\lightershade}
% \DescribeMacro{\darkershade}
% Shade adjustment macros. They just multiply or divide \cs{shadespace}
% by 1.2.
%    \begin{macrocode}
\newdef\lightershade{\shadespace=1.2\shadespace}%
\newdef\darkershade{\shadespace=.833333\shadespace}%
%    \end{macrocode}
%
% \DescribeMacro{\dashlineset}
% \DescribeMacro{\dotlineset}
% The following arrange for contrastive dashed lines. \cs{dashlineset}
% just resets the default parameters that the \cs{dashed} macro uses,
% \cs{dotlineset} sets these parameters so that \cs{dashed} produces
% something almost dotted.
%    \begin{macrocode}
\newdef\dashlineset{\dashlen=4pt \dashspace=4pt}%
\newdef\dotlineset{\dashlen=1pt \dashspace=2pt}%
%    \end{macrocode}
%
% \DescribeMacro{\ifpointfill}
% With the commands \cs{pointfilltrue} or \cs{pointfillfalse} the user
% can specify points drawn with the \cs{point} command to be either
% filled in or not.
%    \begin{macrocode}
\let\ifpointfill\iftrue
\newdef\pointfilltrue{\mfp@let\ifpointfill\iftrue}%
\newdef\pointfillfalse{\mfp@let\ifpointfill\iffalse}%
%    \end{macrocode}
%
%
% \section{Macros to implement prefix commands}\label{prefix}
%
% \Mfpic{} prefix macros change the behavior of the figure macros.
% Normally we want \cs{circle}\marg{...} to draw the solid outline of a
% circle. So normally \cs{circle}\marg{...} will write a drawing command
% followed by a path expression giving the circle to draw. But
% \cs{dashed}\cs{circle}\marg{...} should write a \emph{dashing} command
% and \emph{omit} the drawing command. Thus, \emph{rendering} macros
% like \cs{dashed} need to set a switch, and figure macros like
% \cs{circle} need to test that switch.
%
% Similar considerations hold for prefix macros that transform the
% figure. The logic is that, at the \MF{} level, every figure macro
% is syntactically a path expression. Every prefix accepts a path
% expression as input and has a path as its return value, so a
% combination prefix + path expression is again a path expression.
% Prefixes may also have side effects, such as adding some ink to the
% current picture. Such prefixes are called \emph{rendering} macros.
% Rendering macros normally return the same path as their argument, but
% there are macros that modify the path. Some applying a linear
% transform, some close an open path, some return a subpath. These we call
% \emph{modification} macros.
%
% This scheme is quite simple, but unfortunately too simple. To avoid
% having to explicitly type a rendering prefix every time, we need
% the above mentioned ability to pass information to the figure macros.
% Moreover, \MF{} abhors an `isolated expression', so the first prefix
% has to write something with a different syntax, and pass the info that
% it has already done so on to later prefixes, who need to test that
% info.
%    \begin{macrocode}
\mfp@DBlog{Tests to control multiple prefix commands.}%
%    \end{macrocode}
%
% Every prefix macro needs to know if it is the first or a later one.
% They test this \cs{if} command and also set it to false. The
% figure macros, which are last in the chain, close by resetting it true.
%    \begin{macrocode}
\newif\if@startfig\@startfigtrue
%    \end{macrocode}
%
% If a prefix is a rendering prefix, it writes the rendering code
% and sets the following switch to false, letting the figure macro know
% it needn't invoke the default rendering,
% Figure macros close by resetting it true. Some modification macros don't
% touch it at all (the \cs{@modmac}\,s) others just test it
% (\cs{@closmac}\,s).
%    \begin{macrocode}
\newif\if@imrend\@imrendtrue
%    \end{macrocode}
%
% The following macro is always (and only) invoked by the first prefix
% macro. It writes the code that prevents an isolated expression. It
% stores the following path expression in the variable \gbc{curpath}. Thus
% every combination of prefixes followed by a figure macro is
% syntactically a \MF{} variable assignment command.
%    \begin{macrocode}
\newdef\store@path{\mfsrc{\@nl store (curpath)}}%
%    \end{macrocode}
%
% Every prefix and figure macro has to invoke \cs{@firststage}, since
% each is potentially the first in the sequence. If
% \cs{if@startfig} is true, it writes the storing command, sets
% \cs{@startfigfalse}, and says that rendering is needed. (The
% rendering macros immediately cancel that switch.)
%    \begin{macrocode}
\newdef\@firststage{\relax
  \if@startfig \store@path \@imrendtrue \@startfigfalse\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\@rendmac}
% Every rendering macro invokes this command. After the first-stage code
% it writes its rendering command (via \cs{mfsrc}) and passes on the info
% that rendering is no longer required of the figure macro.
%    \begin{macrocode}
\newdef\@rendmac{\@firststage \@imrendfalse \mfsrc}%
%    \end{macrocode}
%
% \DescribeMacro{\@modmac}
% It is possible we should call this something else, as only \cs{arrow}
% and \cs{reverse} use \cs{@modmac}. Other modifications cause the
% modified path to be drawn as if (modifier+figure) were a solitary figure
% macro. This would be pointless for a reversed path or a path with
% arrowhead added, as presumably the original path would already be drawn.
% Moreover, it can be argued (for \MP{} at least) that the arrowhead
% should be drawn on top of the shaft. This is the only significant effect of
% coding \cs{arrow} and \cs{reverse} as \cs{@modmac}\,s.
%
% It simply invokes the common first-stage code and writes its \MF{} code.
%    \begin{macrocode}
\newdef\@modmac{\@firststage \mfsrc}%
%    \end{macrocode}
%
% \DescribeMacro{\@closmac}
% Other modification macros were added later, and it turned out that
% they needed the same treatment as the closure macros that already
% existed. Therefore, most modification macros invoke \cs{@closmac}. The
% \emph{figure} macros proceed as follows: they invoke the \cs{@firststage}
% code, then write a rendering macro if necessary, then make
% \cs{@starfigtrue} (for the next figure), then write \MF{} code that
% defines the path. These modification macros do only the first two,
% counting on the figure macro to follow to invoke the last two. The idea
% is that {closure + figure} should act the same as if the path it defines
% were encoded as a single figure command.
%
% The \cs{@modmac} and \cs{@closmac} macros differ only when there are
% no preceeding rendering macros. In that case it is as if \cs{draw} (or
% more generally \cs{@render}) precedes the \cs{@closmac} macro. That
% drawing happens \emph{in addition to} any rendering macros that follow.
% This implicitly added \cs{draw} is not present for \cs{@modmac} macros,
% unless it is added by the following figure macro itself.
%    \begin{macrocode}
\newdef\@closmac{\@firststage \if@imrend\@xp\@render\fi \mfsrc}%
%    \end{macrocode}
%
% \DescribeMacro{\setrender}
% As mentioned above, when a figure  macro is invoked without a
% rendering prefix, it will invoke some default. That default is stored
% in the macro \cs{@render}, which can be changed for special effects.
% Initially we define it as \cs{draw} to draw solid paths, but provide a
% command for the user to change it.
%    \begin{macrocode}
\newdef\@render{\draw[]}%
\newdef\setrender#1{\mfp@def\@render{#1}}%
%    \end{macrocode}
%
% \DescribeMacro{\@figmac}
% A figure macro will invoke the common first-stage code, then check
% if rendering is needed. If so, it issues the \cs{@render} command.
% It also resets the startfig switche. Since a figure macro completes
% an assignment command in \MF, we use \cs{mfcmd}, which places a
% semicolon at the end of the code it writes. We define the first part
% (all but the writing) as a separate command because there are a few cases
% where we need to delay that writing.
%    \begin{macrocode}
\newdef\@figmacstart{%
  \@firststage \if@imrend\@xp\@render\fi \@startfigtrue}%
\newdef\@figmac{\@figmacstart\mfcmd}%
%    \end{macrocode}
%
% \DescribeMacro{\@listmac}
% The list macros take as their last argument a list of $(x,y)$ pairs.
% That list can either be typed directly into
% the \TeX{} source file (inside braces, separated by commas) or be
% present in an external datafile. Either way, the data is written
% as a list of \MF{} pairs within an enclosing pair of
% parentheses. Since these are all figure macros, \cs{@listmac} starts out
% just like \cs{@figmac}, but it writes only part of its arguments, the
% last one being handled by \cs{mfp@writedata}.
%
% \cs{mfp@writedata} looks ahead to see if the token \cs{datafile}
% follows, if it does \cs{mfp@writefile} is invoked, which gobbles
% the \cs{datafile} token and processes the filename that should follow it.
% Otherwise, \cs{mflist} is invoked to write the list in braces
% that should follow.
%
% \cs{mfp@writedata} is also used by non-figure macros such as the axis
% marks macros, plus \cs{piechart} and \cs{barchart}.
%    \begin{macrocode}
\newdef\@listmac#1{\@figmacstart\mfsrc{#1}\mfp@writedata}%
\newdef\mfp@writedata{%
  \mfp@ifnextchar\datafile{\mfp@writefile}{\mflist}}%
\newdef\mfp@writefile\datafile#1{\@processdatafile{#1}{\mfp@rwdata}}%
%    \end{macrocode}
%
% \DescribeMacro{\mftitle}
% \DescribeMacro{\tmtitle}
% These go here because they didn't seem to go anywhere else. The are
% mainly for debugging the example files. \cs{getmfp@toks} assigns the
% following group to a token register and then invokes its argument.
% \cs{mftitle} and \cs{tmtitle} use this to write the code into
% the string argument of the \grafbase{} command \gbc{mftitle}.
% \cs{mftitle} does only that, while \cs{tmtitle} also writes the argument
% to the \file{.log} file and typesets it in the document.
%
% We write the argument as a token list because that is the the easiest
% verbatim-like way to do it.
%    \begin{macrocode}
\newif\if@mfpswitch
\newdef\mftitle{\@bsphack\@mfpswitchtrue\mfp@gettoks\mf@title}%
\newdef\tmtitle{\mfp@gettoks\tm@title}%
\newdef\mfp@gettoks#1{\afterassignment#1\mfp@toks=}%
\newdef\tm@title{\@mfpswitchfalse\mf@title
  \wlog{\the\mfp@toks}{\the\mfp@toks}}%
\newdef\mf@title{\mfsrc{}%
  \immediate\write\mfp@out{mftitle "\the\mfp@toks";}%
  \if@mfpswitch\@esphack\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\noship}
% \DescribeMacro{\stopshipping}
% \DescribeMacro{\resumeshipping}
% To turn off character shipping for duration of innermost enclosing
% group (eg, \env{mfpic} environment).  As far as I know it has never been
% tested with \MP. (It hasn't been tested recently even in \MF.) The \MF{}
% code prevents the figure from being added to the font, the \TeX{} switch
% \texttt{shipping} is checked before \cs{endmfpic} attempts to add the
% (nonexistent) figure to the document.
%    \begin{macrocode}
\newdef\stopshipping{\mfp@let\if@shipping\iffalse
  \@ifmfpfileisopen{\mfcmd{save shipit;def shipit = relax enddef}}{}}%
\newdef\resumeshipping{\mfp@let\if@shipping\iftrue
  \@ifmfpfileisopen{\mfcmd{save shipit;def shipit = shipit_ enddef}}{}}%
\newlet\noship\stopshipping
\resumeshipping
%    \end{macrocode}
%
%
%  \section{Macros for getting data from files}\label{rwdata}
%
% The following command contains the common code to open a data file for
% reading. The first parameter is the filename, the second is what to do
% if it exists and is nonempty. We first try to \cs{openin} the file and
% issue an error message if that fails. Then we skip any initial blank
% lines and comments and complain if that takes us to the end of the
% file. Otherwise we execute the command specified. Afterwards, since
% each \cs{plotdata} command in a given \env{mfpic} environment
% starts with the linetype at which the previous one ended, we allow the
% value of \cs{mfp@linetype} to survive the group.  If \texttt{\#2} is
% not \cs{plotdata}, this is harmless (I hope).
%    \begin{macrocode}
\newdef\@processdatafile#1#2{%
  \openin\mfp@data=#1\relax
  \ifeof\mfp@data \nodatafileerror{#1}%
  \else
    \begingroup
      \mfp@resetwhitespace  \mfp@setcomment
      \skipBlanksandComments
      \ifeof\mfp@data \emptydatafileerror{#1}\else #2\fi
      \global\mfp@n=\mfp@linetype
    \endgroup
    \mfp@linetype=\mfp@n
  \fi
  \closein\mfp@data}%
%    \end{macrocode}
%
% \DescribeMacro{\nodatafileerror}
% \DescribeMacro{\emptydatafileerror}
% These are error messages for missing or empty data files:
%    \begin{macrocode}
\newdef\nodatafileerror#1{%
  \mfp@errmsg{No data file: #1 .}%
   {The data file you tried to plot can't be found.}}%
\newdef\emptydatafileerror#1{%
  \mfp@errmsg{Empty data file: #1 .}%
 {The file you tried to plot contains only empty lines and comments.}}%
%    \end{macrocode}
%
% When reading files it is important that white space in the files
% always have the same meaning for \TeX{}. This utility resets spaces,
% tabs and EOLs to the standard categories.
%    \begin{macrocode}
\newdef\mfp@resetwhitespace{%
  \catcode`\^^M=5 \catcode`\ =10 \catcode`\^^I=10 }%
%    \end{macrocode}
%
% \DescribeMacro{\skipcomments}
% This does what it says, skipping comments in a data file. It reads a
% line from a previously opened file (input stream \cs{mfp@data}) and
% compares it to \cs{@empty}. It calls itself when they are equal (a
% comment line). When this macro finishes, \cs{mfp@temp} contains either
% \cs{par} (blank line or EOF) or real data.
%    \begin{macrocode}
\mfp@ifdefined\@empty{}{\def\@empty{}}%
\newdef\skipcomments{\read\mfp@data to \mfp@temp
  \ifx\mfp@temp\@empty \@xp\skipcomments\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\skipBlanksandComments}
% This command first skips comments. After that \cs{mfp@temp} can contain
% \cs{par}, indicating either EOF or a blank line, or something else.
% In the first case (EOF) the macro terminates, in the second case (blank)
% it calls itself again, in the third case it also terminates, having
% presumably found real data.
%
% When this is called, a file should already be open (by
% \cs{@processdatafile}) using the handle \cs{mfp@data}.
%
% The macro \cs{@XP} causes two macros after the next token to be
% expanded, removing the two \cs{fi}\,s (and so avoiding deep nesting).
%    \begin{macrocode}
\newdef\skipBlanksandComments{\skipcomments
  \ifeof\mfp@data
  \else\ifx\mfp@temp\mfp@par \@XP\skipBlanksandComments
  \fi\fi}%
%    \end{macrocode}
%
% The following two commands, \cs{mfp@rwdata} and \cs{mfp@rwdataloop}
% perform the work of writing the file (read stream \cs{mfp@data} opened
% by \cs{@processdatafile}).
%
% The counter \cs{mfp@n} is used to keep track of how many lines of the
% data file have been written to one line of the output. The token
% \cs{sequence} in a \cs{using} specification will expand to the value of
% the counter \cs{mfp@sequence}.
%
% When this first macro is called, a non-blank line has been read to the
% macro \cs{mfp@temp}, to which we now add a space. The macro
% \cs{mfp@buffer} is what will be written to the output file as soon as it
% is long enough. We initialize it by defining it to be an open
% parenthesis followed by the result of applying \cs{parse@data} to the
% contents of \cs{mfp@temp}. Then we call \cs{mfp@rwdataloop}, which does
% the actual reading and writing.
%    \begin{macrocode}
  \def\mfp@rwdata{\mfp@n=1 \mfp@sequence=1
    \def\sequence{\number\mfp@sequence}%
    \edef\mfp@temp{\mfp@temp\space}%
    \edef\mfp@buffer{(\@xp\parse@data\mfp@temp\mfp@delim}%
    \mfp@rwdataloop}%
%    \end{macrocode}
%
% At this point, the buffer has been started with the first datum, so we
% read another line. If that is blank, we write the buffer (and the closing
% parenthesis and a semicolon) and terminate the loop. Otherwise we go
% through a loop:
% \begin{enumerate}
%   \item Increment the sequence counter,
%   \item add a comma to the buffer,
%   \item test whether the buffer is `full', and
%   \item add the datum to the buffer. If the buffer is full in step~3, it is
%       written to the output and cleared before going to step~4.
% \end{enumerate}
% \cs{mfp@rwdataloop} loops by calling itself at the end. Whenever
% \cs{mfp@temp} is empty (comment line read), (1)--(4) are skipped and
% another line read.
%    \begin{macrocode}
  \def\mfp@rwdataloop{%
    \read\mfp@data to \mfp@temp
    \ifx\mfp@temp\mfp@par
      \mfcmd{\mfp@buffer)}%
    \else
      \ifx\mfp@temp\@empty % comment line, read another
      \else
        \edef\mfp@temp{\mfp@temp\space}%
        \advance\mfp@sequence1
        \edef\mfp@buffer{\mfp@buffer\mfp@join}%
        \ifnum\mfp@n<\mfpdataperline\relax
          \advance\mfp@n1
        \else
          \mfsrc{\mfp@buffer}%
          \mfp@n=1
          \def\mfp@buffer{}%
        \fi
        \edef\mfp@buffer{\mfp@buffer
          \@xp\parse@data\mfp@temp\mfp@delim}%
      \fi
      \@xp\mfp@rwdataloop
    \fi}%
%    \end{macrocode}
%
%
% \section{Various \CMF{} Settings.}\label{MFsettings}
%
% \DescribeMacro{\drawpen}
% \DescribeMacro{\pen}
% \DescribeMacro{\penwd}
% Macros that write changes in default \grafbase{} variables now use the
% construct ``\gbc{save x; <type> x; x := <value>;}'' (via a call to
% \cs{setmfvariable}). This makes changes local if inside a given \env{mfpic}
% environment, global if outside. An exception is \gbc{penwd} which, as an
% internal variable uses `\gbc{interim}' instead (via the \grafbase{}
% command \gbc{resizedrawpen}). Both \cs{drawpen} and \cs{pen} have been
% used in the past, while \cs{penwd} is more consistent with other
% commands, so we keep all three.
%    \begin{macrocode}
\newdef\drawpen#1{\mfcmd{\@nl resizedrawpen (#1)}}%
\newlet\pen=\drawpen \newlet\penwd=\drawpen
%    \end{macrocode}
%
% \DescribeMacro{\shadewd}
% The \cs{shade} macro works in \MF{} by adding many copies of the small
% picture \gbc{shadedot} to the figure, in \MP{} the parameters
% \gbc{shadewd} and \cs{shadespace} are simply used to calculate a level
% of gray and a color fill is used.
%
% \DescribeMacro{\polkadotwd}
% However, both \MF{} and \MP{} handle polkadots the same. The only
% difference is \MF's need for fitting to a pixel grid. But that is
% handled in \grafbase.
%    \begin{macrocode}
\newdef\shadewd#1{\setmfnumeric{shadewd}{#1}}%
\newdef\polkadotwd#1{\setmfnumeric{polkadotwd}{#1}}%
%    \end{macrocode}
%
% \DescribeMacro{\hatchwd}
% The thickness of lines in the hatching fill.
%    \begin{macrocode}
\newdef\hatchwd#1{\setmfnumeric{hatchwd}{#1}%
  \setmfvariable{pen}{hatchpen}{pencircle scaled hatchwd}}%
%    \end{macrocode}
%
% \DescribeMacro{\dashpattern}
% A dash pattern consists (internal to \MF) of three arrays. The
% \grafbase{} command \gbc{dashpat} accepts a name, and a sequence of
% numbers representing the sizes of dashes and spaces, and builds these
% arrays.
%    \begin{macrocode}
\newdef\dashpattern#1#2{\mfcmd{save #1; dashpat (#1) (#2)}}%
%    \end{macrocode}
%
% \DescribeMacro{\settension}
% This sets the default tension for \cs{curve} commands, as well as for
% any command that takes an optional argument of the form
% \oarg{s\meta{tens}}. This includes \cs{function}, \cs{plrfcn},
% \cs{fcncurve}, \cs{datafile}, \cs{plotdata} and others. It also sets the
% default tension for \cs{sclosed} and \cs{bclosed}. The value should be
% at least $3/4$.
%    \begin{macrocode}
\newdef\settension#1{\setmfnumeric{default_tension}{#1}}%
%    \end{macrocode}
%
%
% \section{Settings for text label placement in
% figures}\label{labelsettings}
%
% \cs{tlabel}\,s are `justified' by placing a particular point of the
% text at the location specified. The \cs{tlabel} command accepts an
% optional argument containing two letters. There are 4 possibilities
% for the first and three for the second. It turns out to be easier to
% process these if we have a command that converts these to numbers, and
% then \cs{ifcase} can be used. There is a third part of the optional
% argument usable only in \MP{}: a number indicating degrees of rotation.
%
% \DescribeMacro{\tlabeljustify}
% The multi-part definition of \cs{tlabeljustify} is to guard
% against confusing error messages if some part of this optional argument
% is empty. The code assumes that if there are only 2, 1 or no parts, then
% later parts should be left unchanged. The rotation part is empty by
% default (rather than 0), because some commands will emit a warning if
% a nonempty rotation exists without \opt{mlabels}.
%
% The result of \cs{tlabeljustify} is that \cs{tl@vpos} is set equal to
% $-1$ if the first letter is (default) \texttt{B} (for Baseline), and
% 0--2 if it is \texttt{b} (bottom), \texttt{c} (center) or \texttt{t}
% (top). Similarly, \cs{tl@hpos} is set equal to $-1$ if the second
% letter is (default) \texttt{l} (for left), and 0 or 1 if it is
% \texttt{c} (center) or \texttt{r} (right).
%
% The rotation part is just saved in \cs{tlabel@rot}. This is now true
% even without \opt{mplabels} in case it is turned on later. It is
% ignored by \cs{tlabel} without \opt{mplabels}, but a warning is issued
% here anyway.
%    \begin{macrocode}
\newcount\tl@vpos \newcount\tl@hpos
\tl@vpos=-1 \tl@hpos=-1
\newdef\tlabel@rot{}%
%
\newdef\tlabeljustify#1{%
  \mfp@ifempty{#1}{}{\mfp@justify#1\mfp@delim}}%
\def\mfp@justify#1#2\mfp@delim{\mfp@local\mfp@vconv{#1}%
  \mfp@ifempty{#2}{}{\@mfp@justify#2\mfp@delim}}%
\newdef\@mfp@justify#1#2\mfp@delim{%
  \mfp@local\mfp@hconv{#1}\mfp@local\edef\tlabel@rot{#2}
  \@ifmplabels{}%
   {\mfp@ifempty{#2}{}%
     {\Mfpic@warn{Rotation of labels is not supported without the
        mplabels\@msgbreak option. Rotation may be ignored\@online .}}}}%
\newdef\mfp@vconv#1{%
  \if B#1\tl@vpos=-1 \else
  \if b#1\tl@vpos= 0 \else
  \if c#1\tl@vpos= 1 \else
  \if t#1\tl@vpos= 2 \else
         \tl@vpos=-1 \mfp@justifyerror
  \fi\fi\fi\fi}%
\newdef\mfp@hconv#1{%
  \if l#1\tl@hpos=-1 \else
  \if c#1\tl@hpos= 0 \else
  \if r#1\tl@hpos= 1 \else
         \tl@hpos=-1 \mfp@justifyerror
  \fi\fi\fi}%
\newdef\mfp@justifyerror{%
    \mfp@errmsg{Invalid justification parameter for text label.}%
     {The optional argument for a text label must be^^J%
      one of B, b, c or t^^J
      followed by l or r or c,^^J%
      followed by an angle (optionally).}}%
%    \end{macrocode}
%
% \DescribeMacro{\tlpathjustify}
% This acts just like \cs{tlabeljustify} from the user's point of view.
% Since it is only for users, and not used internally, it merely defines
% three macros that \cs{@@@tlpath} passes on to \cs{tlabeljustify} when no
% justification parameter is present.
%    \begin{macrocode}
\newdef\tlpathjustify#1{%
  \mfp@ifempty{#1}{}{\tlp@justify#1\mfp@delim}}%
\newdef\tlp@justify#1#2\mfp@delim{\mfp@def\tlpath@v{#1}%
  \mfp@ifempty{#2}{}{\tlp@@justify#2\mfp@delim}}%
\newdef\tlp@@justify#1#2\mfp@delim{%
  \mfp@def\tlpath@h{#1}\mfp@def\tlpath@r{#2}}%
\tlpathjustify{cc}%
%    \end{macrocode}
%
% \DescribeMacro{\tlabelsep}
% \DescribeMacro{\tlabeloffset}
% \cs{tlabelsep} takes an absolute length as its argument and sets
% parameters that determine by how much a label is separated from the
% point it is placed at. This is in case something is drawn at that point,
% such as a dot or a hash mark on an axis.
%
% \cs{tlabeloffset}, on the other hand, takes a pair of dimensions,
% representing offsets. This is mainly so that, if labels seem to be off,
% they can all be shifted with one command.
%
% Both these values are written to the \MF{} file for the sake of the
% commands that draw rectangles or ovals around labels.
%    \begin{macrocode}
\newdef\tlabelsep#1{\mfp@local\tlabel@sep=#1\relax
  \setmfnumeric{label_sep}{\the\tlabel@sep}}%
\newdef\tlabeloffset#1#2{%
  \mfp@local\tlabel@hadj=#1\relax \mfp@local\tlabel@vadj=#2\relax
  \setmfvariable{pair}{label_adjust}%
    {(\the\tlabel@hadj,\the\tlabel@vadj)}}%
%    \end{macrocode}
%
% \DescribeMacro{\everytlabel}
% Every line of a multiline label is written inside a group, so
% adjustments to baselineskip and other things are difficult or impossible.
% Therefore, \cs{everytlabel} is provided to define tokens to be inserted
% before the label code, outside these groups. It is not itself a token
% variable, so that that it can write the tokens to the \MP{} file once,
% instead of at every label.
%    \begin{macrocode}
\newdef\everytlabel{\afterassignment\@everytlabel
    \mfp@local\every@tlabel}%
\newdef\@everytlabel{%
  \mfp@ifmpost
   {\@ifmfpfileisopen
     {\mfcmd{verbatimtex\@nl
        \def\noexpand\everylabel{\the\every@tlabel} etex}}%
     {}}%
   {}}%
%    \end{macrocode}
%
%
% \section{Other settings}\label{othersettings}
%
% \DescribeMacro{\headshape}
% This sets the arrowhead shape. The parameters are: the ratio of width
% to length, the tension (see \file{grafbase.dtx}) and a boolean
% (\gbc{true} or \gbc{false}) to say whether the the head is filled, or
% only the barbs are drawn. (In retrospect, it would have been more
% consistent with other commands to have one \TeX{} parameter with commas
% separating the components.)
%    \begin{macrocode}
\newdef\headshape#1#2#3{\mfcmd{\@nl headshape (#1, #2, #3)}}%
%    \end{macrocode}
%
% \DescribeMacro{\mfpdefinecolor}
% \prog{Mfpic} supports color under \MP{} by writing all color
% definitions to the output \file{.mp} file. In order to support a
% \LaTeX-like color syntax, all the color models allowed by the color
% package correspond to a \grafbase{} function that returns a \MP{}
% color value. For example, \gbc{cmyk(.3,.3,0,.7)} returns \gbc{(0,0,.3)},
% a very dark blue. This can be set by
% \cs{mfpdefinecolor}\marg{vdblue}\marg{cmyk}\marg{.3,.3,0,.7}.
%
% \DescribeMacro{\fillcolor}
% \DescribeMacro{\drawcolor}
% \DescribeMacro{\headcolor}
% \DescribeMacro{\hatchcolor}
% \DescribeMacro{\pointcolor}
% \DescribeMacro{\tlabelcolor}
% \DescribeMacro{\backgroundcolor}
% To support the syntax
% \cs{fillcolor}\oarg{\meta{model}}\marg{\meta{parameters}}, we just
% call \cs{@mfpcolor} with the \grafbase{} color variable name
% \gbc{fillcolor}.
%    \begin{macrocode}
\newdef\mfpdefinecolor#1#2#3{\setmfcolor{#1}{#2(#3)}}%
\newdef\fillcolor{\@mfpcolor{fillcolor}}%
\newdef\drawcolor{\@mfpcolor{drawcolor}}%
\newdef\headcolor{\@mfpcolor{headcolor}}%
\newdef\hatchcolor{\@mfpcolor{hatchcolor}}%
\newdef\pointcolor{\@mfpcolor{pointcolor}}%
\newdef\tlabelcolor{\@mfpcolor{tlabelcolor}}%
\newdef\backgroundcolor{\@mfpcolor{background}}%
\newdef\@mfpcolor#1{%
  \mfp@ifnextchar[{\mfp@color{#1}}{\setmfcolor{#1}}}%
\newdef\mfp@color#1[#2]#3{\setmfcolor{#1}{#2(#3)}}%
%    \end{macrocode}
%
% When \cs{plotdata} is used to draw several graphs from one file, each
% sequence of non-blank lines corresponds to a different curve with a
% different style of rendering. The user has the option to cycle through
% different dashing patterns, different colors, or different symbols.
%
% Internally, \cs{plotdata} issues the command \cs{mfp@setstyle} (which
% can be defined to be any rendering macro), followed by a path defining
% command such as \cs{curve} or \cs{polyline}, followed by a command
% that reads the data and writes it in a suitable format. The following
% commands essentially allow the user to select the rendering macro.
% They start by resetting \cs{mfp@linetype}, the count register that keeps
% track of how many curves have been drawn, then they define
% \cs{mfp@setstyle}.
%
% \DescribeMacro{\dashedlines}
% \cs{dashedlines} uses the rendering prefix \cs{gendashed} with 6
% different dashing patterns \gbc{dashtype0} through \gbc{dashtype5}.
% These are actually selected in \MF{} through the command
% \gbc{getdashpat}. This takes care of cycling back to
% \gbc{dashtype0} when the number of available dash patterns is exceeded.
% Dashed lines is the default.
%    \begin{macrocode}
\newdef\dashedlines{\mfp@local\mfp@linetype0
  \mfp@def\mfp@setstyle{\gendashed{getdashpat\number\mfp@linetype}}}%
\dashedlines
%    \end{macrocode}
%
% \DescribeMacro{\coloredlines}
% This uses \cs{draw} with an optional color parameter set
% to \gbc{colortype0} through (by default) \gbc{colortype 7}. These are
% color variables defined by \grafbase{}. It also issues a warning if
% \MF{} is being used. As with \cs{dashedlines}, a \MP{} command
% \gbc{getcolor} selects these colors.
%    \begin{macrocode}
\newdef\coloredlines{%
  \mfp@ifmpost
   {\mfp@local\mfp@linetype0
    \mfp@def\mfp@setstyle{\draw [getcolor\number\mfp@linetype]}}%
   {\Mfpic@warn{You can't use \string\coloredlines\space in
      Metafont.\@msgbreak Using \dashedlines instead}%
    \dashedlines}}%
%    \end{macrocode}
%
% \DescribeMacro{\pointedlines}
% This makes a sort of dotted line, except the dots are actually different
% symbols. It uses the rendering macro \cs{plot} with a parameter cycling
% through 9 different symbols.
%    \begin{macrocode}
\newdef\pointedlines{\mfp@local\mfp@linetype0
  \mfp@def\mfp@setstyle{\plot{getsymbol\number\mfp@linetype}}}%
%    \end{macrocode}
%
% \DescribeMacro{\datapointsonly}
% \cs{datapointsonly} uses symbols like \cs{pointedlines}, but places
% them only at the data points from the file. It uses the rendering macro
% \cs{plotnodes} with a parameter cycling through the same 9 symbols.
%    \begin{macrocode}
\newdef\datapointsonly{\mfp@local\mfp@linetype0
  \mfp@def\mfp@setstyle{\relax
    \plotnodes{getsymbol \number\mfp@linetype}}}%
%    \end{macrocode}
%
% \DescribeMacro{\reconfigureplot}
% This command allows the user to set the dashes, colors and symbols used
% by the \cs{plotdata} command. The first argument is the plotting method
% to be changed (\texttt{dashes}, \texttt{colors}, or \texttt{symbols})
% and the second argument is a comma separated list of appropriate type
% variables for \cs{plotdata} to cycle through. For example,
% \cs{reconfigureplot}\marg{dashes} takes a list of dashing patterns
% (previously defined by the \cs{dashpattern} command) separated by
% commas. It writes a command instructing \MF{} to redefine the arrays
% \mfc{dashtype0}, \mfc{dashtype1}, etc., used with \cs{gendashed} when
% \cs{dashedlines} is in effect. The number of patterns is counted by \MF,
% which also handles the mod-ing operation now.
%
% \cs{reconfigureplot}\marg{colors} takes a list of colors (expressions or
% color names previously defined) separated by commas. It redefines
% \gbc{colortype0}, etc., used with \cs{plotdata} when \cs{coloredlines}
% is in effect.
%
% \cs{reconfigureplot}\marg{symbols} takes a list of symbols (\MF{} path
% expressions, one of the symbols available to \cs{plotsymbol}, or path
% names defined by \cs{store}) separated by commas. It redefines
% \gbc{pointtype0}, etc., used by \cs{plotdata} when \cs{pointedlines} or
% \cs{datapointsonly} is in effect.
%
% \DescribeMacro{\defaultplot}
% This restores \mfpic's predefined defaults for dash patterns, colors and
% symbols in \cs{plotdata}. The one argument is one of the words
% \texttt{dashes}, \texttt{colors}, or \texttt{symbols}, indicating which
% plotting method is to be restored.
%    \begin{macrocode}
\newdef\reconfigureplot#1{\mfsrc{setdata#1}\mfp@writedata}%
\newdef\defaultplot#1{\mfcmd{default#1}}%
%    \end{macrocode}
%
% \DescribeMacro{\mfplinetype}
% \DescribeMacro{\mfplinestyle}
% The user-level commands \cs{mfplinetype} and \cs{mfplinestyle} allow the
% user to set the starting value of \cs{mfp@linetype}. The default is to
% start at $0$. The names ``linestyle'' and ``linetype'' come from
% an analogous system of changing rendering in \prog{gnuplot}.
%    \begin{macrocode}
\newdef\mfplinetype#1{\mfp@local\mfp@linetype=#1}%
\newlet\mfplinestyle\mfplinetype
\mfplinetype{0}%
%    \end{macrocode}
%
% \prog{Mfpic} has 6 possible axes, the x- and y-axes pass through the
% origin, $(0,0)$, the four border axes are at the edges of the graph
% space, possibly offset from it by some amount. These four commands hold
% the amount of that offset in graph units, the default being 0.
%    \begin{macrocode}
\newdef\mfp@lshift{0}%
\newdef\mfp@bshift{0}%
\newdef\mfp@rshift{0}%
\newdef\mfp@tshift{0}%
%    \end{macrocode}
%
% \DescribeMacro{\axismargin}
% \DescribeMacro{\setaxismargins}
% \DescribeMacro{\setallaxismargins}
% These are the user-level command for setting the above offsets. The
% first argument to \cs{axismargin} is one of the letters l, b, r, or t to
% select the axis and the second is the offset in graph units. A positive
% offset represents an inward shift, which is why we call them
% \emph{margins}. The arguments of \cs{setaxismargins} are four offsets
% for the axes (in the above order, which is anticlockwise, starting
% with the left). \cs{setallaxismargins} takes one offset and applies it
% to all axes.
%
% The values are passed on to \MF{} in the variables \gbc{laxis},
% \gbc{baxis}, \gbc{raxis}, and \gbc{taxis}. They are also needed by the
% \cs{axislabels} command so they are saved in macros.
%    \begin{macrocode}
\newdef\axismargin#1#2{\setmfnumeric{#1axis}{#2}%
  \mfp@local\@namedef{mfp@#1shift}{#2}}%
\newdef\setaxismargins#1#2#3#4{\axismargin l{#1}\axismargin b{#2}%
    \axismargin r{#3}\axismargin t{#4}}%
\newdef\setallaxismargins#1{\setaxismargins{#1}{#1}{#1}{#1}}%
%    \end{macrocode}
%
% The following converts axis letters to a numeric, making conditionals for
% axes simpler to code (\cs{ifcase} versus the six nested \cs{if}\,s we
% see here.) Plus we get to define the error message only once. The
% first argument is the letter and the second argument is the calling
% command (for the error message).
%    \begin{macrocode}
\newcount\mfp@axisnum
\def\get@axisnum#1#2{%
  \if      x#1\relax \mfp@axisnum0
  \else\if y#1\relax \mfp@axisnum1
  \else\if l#1\relax \mfp@axisnum2
  \else\if b#1\relax \mfp@axisnum3
  \else\if r#1\relax \mfp@axisnum4
  \else\if t#1\relax \mfp@axisnum5
  \else
    \mfp@errmsg {Invalid axis letter "#1".}%
     {The command #2 requires an axis to be designated by one of^^J%
      the following letters: x, y, l, b, r, or t. If you proceed, ^^J%
      x will be assumed.}%
  \fi\fi\fi\fi\fi\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\setaxismarks}
% \DescribeMacro{\setxmarks}
% \DescribeMacro{\setymarks}
% \DescribeMacro{\setbordermarks}
% \DescribeMacro{\setallbordermarks}
% The tick marks (or hash marks) on the axes can be in three possible
% positions: centered on the axes, all on one side, or all on the other
% side. The default for the x- and y-axes is centered, for the border axes
% it is inside. For changing this we provide the \cs{setaxismarks} command,
% whose first argument is the axis letter, and whose second argument is
% one of the words \texttt{inside}, \texttt{outside}, \texttt{centered},
% \texttt{ontop}, \texttt{onbottom}, \texttt{onleft}, or \texttt{onright}.
%    \begin{macrocode}
\newdef\setaxismarks#1#2{\setmfnumeric{#1tick}{#2}}%
\newdef\setxmarks#1{\setaxismarks x{#1}}%
\newdef\setymarks#1{\setaxismarks y{#1}}%
\newdef\setbordermarks#1#2#3#4{\setaxismarks l{#1}\setaxismarks b{#2}%
  \setaxismarks r{#3}\setaxismarks t{#4}}%
\newdef\setallbordermarks#1{\setbordermarks{#1}{#1}{#1}{#1}}%
%    \end{macrocode}
%
% \DescribeMacro{\smoothdata}
% \DescribeMacro{\unsmoothdata}
% The \cs{datafile} and \cs{plotdata} commands originally just created
% polygonal paths, but users requested the ability to draw smooth ones.
% Originally only the commands below (\cs{smoothdata} and
% \cs{unsmoothdata}) were written to do this. Later, these file
% manipulation commands were given optional arguments to achieve the same
% effect, so now the commands below just set the defaults for the optional
% parameter, storing them in the macros \cs{mfp@smoothness} and
% \cs{mfp@tension}. The latter can be used to adjust the tension of the
% \MF{} path if smoothness is `s'. Default tension is now empty rather
% than 1 so we can implement a scheme to change the actual default used.
%    \begin{macrocode}
\newdef\smoothdata{\null@opt\@smoothdata}%
\newdef\@smoothdata[#1]{\mfp@def\mfp@smoothness{s}%
  \mfp@def\mfp@tension{#1}}%
\newdef\unsmoothdata{\mfp@def\mfp@smoothness{p}%
  \mfp@def\mfp@tension{}}%
\unsmoothdata% default
%    \end{macrocode}
%
% \DescribeMacro{\using}
% \DescribeMacro{\usingpairdefault}
% \DescribeMacro{\usingnumericdefault}
% These commands control how we interpret data in a file.
% The command \cs{using} is named after a keyword in \prog{gnuplot}. It
% controls which datum is plotted against which by \cs{plotdata} and
% \cs{datafile}. The default is to read the first two space separated
% words on a line as the x- and y-coordinate of a point. To allow that
% there might be more data on a line, it is also assumed that the second
% word is followed by a space and the rest of the line is read as a third
% parameter that is not used. In case there are only two words,
% \mfpic{} will always add a space on the end and then the third
% parameter will be empty.
%
% The \cs{parse@data} command reads its argument as delimited
% parameters, and the \cs{using} command tells what those delimiters are.
% For example, in the first part of
% \cs{using}\marg{\#1 \#2 \#3}\marg{(\#1,\#2)}, we are telling
% \cs{parse@data} that everything on a line up to the first space is the
% first parameter, and everything up to the second space is the second
% parameter and the rest of the line is the third parameter. In the second
% part we are telling it that what we write to the output is a pair in
% parentheses with the first two parameters separated by a comma. This
% example is the default as we see here in \cs{usingpairdefault}. This
% command can be issued by a user to return to that default. The user can
% also issue \cs{usingnumericdefault} to write the first space separated
% word as a single numeric. This is for commands like \cs{piechart}.
%
% \DescribeMacro{\mfpdataperline}
% \cs{mfpdataperline} is a user level macro that controls the maximum
% number of points that will be written to a single line in the output.
%    \begin{macrocode}
\newdef\using#1#2{\mfp@def\parse@data#1\mfp@delim{#2}}%
\newdef\usingpairdefault{\using{##1 ##2 ##3}{(##1,##2)}}%
\newdef\usingnumericdefault{\using{##1 ##2}{##1}}%
\usingpairdefault
\newdef\mfpdataperline{5}%
%    \end{macrocode}
%
% The following macros are used internally by \cs{datafile} and \cs{plotdata}.
% A comment line is read by \TeX{} as empty so we need an empty macro to
% test against, and a blank line is read as \cs{par} (not the primitive
% \cs{par}, but the literal token \cs{par}, so it tests as equal to
% \cs{mfp@par}. Early versions of \cs{plotdata} wrote a literal \MF{} path
% expression to the output file and \cs{mfp@join} created the \mfc{--}
% between points. Now we write one of the \grafbase{} list-to-path
% commands followed by a comma separated list of points, so \cs{mfp@join}
% has morphed into a comma.
%    \begin{macrocode}
\newdef\mfp@par{\par}%
\newdef\mfp@join{,}%
%    \end{macrocode}
%
% \DescribeMacro{\makepercentother}
% \DescribeMacro{\makepercentcomment}
% \DescribeMacro{\mfpdatacomment}
% The user can change the comment character for data files with
% something like \cs{mfpdatacomment}\marg{\cs{\#}}. This also changes the
% percent character to category `other'. We can also use the percent sign
% as part of the numeric data by sandwiching the \cs{using} command
% between \cs{makepercentother} and \cs{makepercentcomment}. Every file
% reading command issues \cs{mfp@setcomment} before reading. The count
% register \cs{@datacomment} hold the ASCII code of the current comment
% character, the default being the percent sign.
%    \begin{macrocode}
\newcount\@datacommentchar \@datacommentchar`\%
\newdef\makepercentother{\@makeother\%}%
\newdef\makepercentcomment{\catcode`\%=14 }%
\newdef\mfpdatacomment#1{\mfp@local\@datacommentchar`#1}%
\newdef\mfp@setcomment{\makepercentother\catcode\@datacommentchar14 }%
%    \end{macrocode}
%
% \DescribeMacro{\fdef}
% The following is for defining functions to be used in \cs{function}
% through \cs{plrregion}. The first argument is the name of the function,
% the second is its variable, the last is the \MF{} code. Obviously its
% use requires a knowledge of the \MF{} language. The function produced is
% a \mfc{vardef}, and can contain almost arbitrary \MF{} code, but must
% end with an expression. Normally it must be a numerical expression, to
% be use in \cs{function}, or a pair expression so it can be used alone in
% the last argument of \cs{parafcn}.
%
% We apply \cs{@makeother} to \texttt{\#} so it doesn't get doubled. The
% \texttt{\#} is frequent in vardefs among the \MF{} gurus.
%    \begin{macrocode}
\newdef\fdef{\begingroup\@makeother\#\preservelines\@fdef}%
\newdef\@fdef#1#2#3{\mfcmd{\@nl save #1;\@nl
  vardef #1 (expr #2) = \@nl #3\@nl enddef}\endgroup}%
%    \end{macrocode}
%
% The following is executed last inside \cs{@mfpic@graf@macs}. It is a
% hook for adding new definitions. It is initialized to empty, and add-on
% packages can add to it.
%    \begin{macrocode}
\newdef\mfp@additions{}%
%    \end{macrocode}
%
%
% \section{The main graphics macros}\label{main}
%
% In order to avoid redefining commands of other packages and in order
% to avoid having other packages redefine \mfpic{} commands, all mfpic
% commands that cannot be used outside the \env{mfpic} environment are
% defined anew with every such environment. This is accomplished by having
% the \cs{mfpic} command execute \cs{@mfpic@graf@macs}, which expands to
% all those definitions. Grouping localizes the definitions, so outside
% \env{mfpic} environments, these commands revert to being undefined, or
% to there original definitions if they had any. As might be expected it
% is quite long, over 300 lines of code at last count.
%    \begin{macrocode}
\newdef\@mfpic@graf@macs{%
%    \end{macrocode}
%
% \subsection{Plotting data from files}\label{datafiles}
%
% \DescribeMacro{\plotdata}
% Most of the \mfpic{} graphic commands take optional arguments. Most of
% them follow the scheme below: \cs{@plotdata} takes a mandatory argument
% enclosed in brackets, and does the work. \cs{plotdata} is simply defined
% to test for an optional argument and pass it or a default to
% \cs{@plotdata}. In this case, the default option is signaled by
% passing empty brackets via \cs{null@opt}.
%
% \cs{@plotdata} follows the scheme of most of the data file processing
% commands: it calls \cs{@processdatafile} with the name of the file (the
% second parameter of \cs{@plotdata}) and another command, \cs{mfp@doplots},
% which really does the work. The argument of \cs{mfp@doplots} is the
% original optional parameter of \cs{plotdata}. This optional parameter is
% the smoothness, which may be \oarg{s\meta{tension}} for a smooth path
% or \oarg{p} for a polygonal path, or empty to select whatever default
% was created by \cs{smoothdata}.
%    \begin{macrocode}
  \newdef\plotdata{\null@opt\@plotdata}%
  \newdef\@plotdata[##1]##2{\@processdatafile{##2}{\mfp@doplots{##1}}}%
%    \end{macrocode}
%
% \cs{mfp@doplots} is a self-looping macro. It issues the rendering
% prefix (in \cs{mfp@setstyle}), increments the linetype, and writes the
% path expression defined by the first set of data in the file (via
% \cs{do@datafile}, which \emph{really} does the work and which stops at a
% blank line). That part, when prefixed by \cs{@figmacstart}, functions
% as a \cs{@figmac}. When finished with one figure, \cs{@if@enddata}
% checks if there is another set of data in the file. If so,
% \cs{mfp@doplots} calls itself again.
%
% The argument is the smoothness parameter(s), which it merely passes on.
% There is no filename argument: since \cs{@processdatafile} has already
% opened the input stream \cs{mfp@data} and subsequent macros will read
% from it.
%    \begin{macrocode}
  \def\mfp@doplots##1{\mfp@setstyle
      \advance\mfp@linetype1 \@figmacstart
      \do@datafile{##1}%
      \@if@enddata{}{\mfp@doplots{##1}}}%
%    \end{macrocode}
%
% When two blank lines occur in succession, \cs{plotdata} is suppose to
% stop. \cs{@ifenddata} is called when \cs{do@datafile} ends (one blank
% line was found), it checks for another blank line (or end-of-file)
% and, if it finds one, selects the first of the two alternatives that
% follow.
%    \begin{macrocode}
  \newdef\@if@enddata{% check for another blank line
    \ifeof\mfp@data \@xp\@firstoftwo
    \else
      \skipcomments
      \ifx\mfp@temp\mfp@par \@XP\@firstoftwo
      \else \@XP\@secondoftwo
      \fi
    \fi}%
%    \end{macrocode}
%
% \DescribeMacro{\datafile}
% \cs{datafile} defines a path connecting the points in a datafile. The
% optional parameter is the smoothness, as in \cs{plotdata}. The other
% parameter is the filename. \cs{@datafile} does the figure macro stuff,
% opens the data file, and calls \cs{do@datafile} which does all the work.
%    \begin{macrocode}
  \newdef\datafile{\null@opt\@datafile}%
  \newdef\@datafile[##1]##2{\@figmacstart
    \@processdatafile{##2}{\do@datafile{##1}}}%
%    \end{macrocode}
%
% I lied. Actually all \cs{do@datafile} does is handle any empty
% optional parameter and call \cs{@do@datafile} to do the work.
%    \begin{macrocode}
  \newdef\do@datafile##1{%
    \do@mtparam{##1}{\mfp@smoothness\mfp@tension}\@do@datafile}%
%    \end{macrocode}
%
% And \cs{@do@datafile} is mainly just a wrapper, processing the optional
% parameter (passed by either \cs{plotdata} or \cs{datafile}) which
% selects what figure making code should be written. For
% \oarg{s\meta{tension}} a \gbc{curve} command is used. For \oarg{p}, a
% \gbc{polyline}. (The `\cs{mf@F}' means the curve is not closed).
%
% After that, \cs{mfp@rwdata} is called, which reads and writes the
% data.
%    \begin{macrocode}
  \newdef\@do@datafile[##1##2]{%
    \mfsrc{%
      \if s##1 \mfp@ifempty{##2}{curve }{tcurve (##2) }%
      \else polyline
      \fi (\mf@F)}\mfp@rwdata}%
%    \end{macrocode}
%
% \subsection{The prefix commands}\label{prefixcommands}
%
% \subsubsection{Storing and reusing a figure}\label{storing}
%
% \DescribeMacro{\store}
% This stores an \mfpic{} path in a \MF{} path variable. The argument is
% the variable name. It should be followed by an \mfpic{} figure macro
% (such as \cs{rect}\marg{...}). The stored path can be reused via the
% \cs{mfobj} command. This command is written as a \cs{@rendmac} even
% though it does no rendering. This is so (1)~it will turn off implicit
% rendering (any rendering must be explicitly written) and (2) it can be
% placed anywhere within the prefix area. This is new behavior with
% version 0.7. Prior to this it was required to place the path to be
% stored as a second argument. Though that argument could contain other
% prefixes in addition to the path, it was required that no other prefixes
% precede \cs{store}. Note that \cs{store} takes a second argument but
% it merely puts it back. This is so that the old syntax (with the figure
% macro in braces) will continue to work.
%    \begin{macrocode}
  \newdef\store##1##2{\@rendmac{stored (##1)}##2}%
%    \end{macrocode}
%
% \DescribeMacro{\mfobj}
% \DescribeMacro{\mpobj}
% This is the interface to use a \cs{store}-d object.
% \cs{mfobj}\marg{\meta{name}} is a figure macro, and should act pretty
% much exactly the same as if the figure macro that had been stored in the
% variable were typed in its place. Its one argument, the variable name,
% is read by \cs{@figmac}, which operates as described previously, either
% implicitly rendering the path, or allowing it to be picked up by
% preceding prefix macros.
%    \begin{macrocode}
  \newlet\mfobj\@figmac
  \newlet\mpobj\@figmac
%    \end{macrocode}
%
% \subsubsection{Subpaths}
%
% \DescribeMacro{\cutoffbefore}
% This macro take one mandatory argument which is an object stored with
% \cs{store}. It modifies the path it is prefixed to so that it starts
% at its first point of intersection with the object, cutting off any
% earlier part of the path.
%
% \DescribeMacro{\cutoffafter}
% This is similar, except the modified path ends at the last point of
% intersection between the following path and the object, cutting off
% any later part of the path.  It is internally the same as applying
% \cs{cutoffbefore} to the reversed path and reversing the result.
%
% \DescribeMacro{\trimpath}
% This trims off the specified amounts from the start and end of the
% path. The amounts are two absolute dimensions, separated by commas.
% They may be \TeX{} dimensions. If the first dimension is absent, it is
% set to \texttt{0pt}, if the second is absent, it is set equal to the
% first. (So if both are absent, nothing is trimmed.)
%    \begin{macrocode}
  \newdef\cutoffafter##1{\@closmac{cutoffafter (##1)}}%
  \newdef\cutoffbefore##1{\@closmac{cutoffbefore (##1)}}%
  \newdef\trimpath##1{\@getdimens##1,,\mfp@delim
    \@closmac{trimmedpath (\the\mfp@scratch, \the\mfp@scratchB)}}%
  \newdef\@getdimens##1,##2,##3\mfp@delim{%
    \mfp@scratch \@ifmtsub{##1}{\z@}\relax
    \mfp@scratchB\@ifmtsub{##2}{\mfp@scratch}\relax}%
%    \end{macrocode}
%
% \DescribeMacro{\partpath}
% \DescribeMacro{\subpath}
% These produce a subpath of the following path. Each takes a mandatory
% parameter containing two numbers separated by a comma. In
% \cs{partpath}, these should be between 0 and 1 and produce a fraction
% of the following path. In \cs{subpath}, these are absolute numbers between
% 0 and the number of segments in the path, and it produces the equivalent of
% \MF's \mfc{subpath} primitive.
%    \begin{macrocode}
  \newdef\partpath##1{\@closmac{partialpath (##1)}}%
  \newdef\subpath##1{\@closmac{gsubpath (##1)}}%
%    \end{macrocode}
%
% \subsubsection{Drawing a curve}\label{drawing}
%
% These are rendering macros that draw the curve in some fashion: solid,
% dashed, colored, etc.
%
% \DescribeMacro{\draw}
% \cs{draw} is the initial definition of \cs{@render}. It takes one
% optional argument, a color. In \MF{}, where color are just numerics, if
% it is ${}\ge 1$ (representing white) the path is subtracted from the
% picture, otherwise it is drawn in black.
%
%    \begin{macrocode}
  \newdef\draw{\null@opt\@draw}%
  \newdef\@draw[##1]{%
    \@rendmac{\mfp@ifempty{##1}{drawn}{colordrawn (##1)}}}%
%    \end{macrocode}
%
% \DescribeMacro{\dashed}
% \cs{dashed} (as well as \cs{dotted}) takes one optional argument,
% which should contain the length of the dashes (diameter of dots) and
% the length of the spaces between, separated by a comma. The defaults
% can be seen in the code below.
%    \begin{macrocode}
  \newdef\dashed{\simple@opt\@dashed{\the\dashlen,\the\dashspace}}%
  \newdef\@dashed##1{\@rendmac{DASHED (##1)}}%
  \newdef\dotted{\simple@opt\@dotted{\the\dotsize,\the\dotspace}}%
  \newdef\@dotted##1{\@rendmac{dotted (##1)}}%
%    \end{macrocode}
%
% \cs{gendashed} takes one mandatory argument, the name of a dash pattern
% previously defined by \cs{dashpattern}
%    \begin{macrocode}
  \newdef\gendashed##1{\@rendmac{gendashed (##1)}}%
%    \end{macrocode}
%
% \cs{plot} is like \cs{dotted}, except the dots are variously shaped
% symbols. It takes one optional argument containing the size of the
% symbol and the spacing, separated by a comma, and one mandatory
% argument, the name of the symbol. This can in principal be any
% expression of type \mfc{picture} or \mfc{path}. (In \MP, type
% \mfc{string} is also permitted). For the size parameter to work
% correctly, the symbol should be a path, and it should have 1 as it's
% natural size. \Mfpic{} provides the predefined paths
% \texttt{Triangle}, \texttt{Square}, \texttt{Circle}, \texttt{Star},
% \texttt{Diamond}, \texttt{Plus}, \texttt{Cross} and \texttt{Asterisk}.
% The first 5 have filled-in versions: \texttt{SolidTriangle}, etc.
%    \begin{macrocode}
  \newdef\plot{\simple@opt\@plot{\the\pointsize, \the\symbolspace}}%
  \newdef\@plot##1##2{\@rendmac{doplot (##2, ##1)}}%
%    \end{macrocode}
%
% Sometimes, rather than equally spaced dots or symbols, we would rather
% have a symbol at each `node' of the following path. If the path is
% created by a list macro, then usually each point in the list is a node
% (but the spline paths are exceptions). For other figures, the nodes
% can seem pretty random. For example, a \cs{circle} command without optional
% argument produces a curve with 8 equally spaced nodes, but with optional
% argument the nodes depend on how it is drawn and the size of any angle
% parameter.
%
% \cs{plotnodes} has almost the same syntax as \cs{plot}, but since it
% places the symbols only at the nodes of the path, there is no spacing
% parameter in the optional argument.
%    \begin{macrocode}
  \newdef\plotnodes{\simple@opt\@plotnodes{\the\pointsize}}%
  \newdef\@plotnodes##1##2{\@rendmac{plotnodes (##2, ##1)}}%
%    \end{macrocode}
%
% \subsubsection{Closing a curve}\label{closing}
%
% \DescribeMacro{\sclosed}
% \DescribeMacro{\bclosed}
% \DescribeMacro{\lclosed}
% \DescribeMacro{\cbclosed}
% \DescribeMacro{\qbclosed}
% \DescribeMacro{\uclosed}
% These close a path defined by whatever figure macro follows it. The
% first closes smoothly in the same manner that \cs{curve} creates a
% smooth path, the second uses an ordinary \MF{} B\'ezier. These two have
% an optional argument: the amount of tension to put in the connecting
% link. Higher tension produces a linking segment with sharper turns near
% the endpoints and a flatter path in between. This makes no sense with
% \cs{lclosed}, \cs{qbclosed} or \cs{cbclosed}. The first always draws a
% straight line and the other two requires a link explicitly determined by
% the beginning and ending segments of the path: a cubic B-spline for
% \cs{cbclosed} and a quadratic B-spline for \cs{qbclosed}. See
% \cs{closedcspline} and \cs{closedqspline} described later.
%
% Due to a misunderstanding on my part, \cs{uclosed} was defined in a more
% complicated manner than necessary, and actually produced exactly the
% same path as \cs{bclosed}. So now they are just made to be equal.
%    \begin{macrocode}
  \newdef\@closed##1##2{%
    \@closmac{##1closed\mfp@ifempty{##2}{}{t (##2)}}}%
  \newdef\bclosed{\null@opt\@bclosed}%
    \newdef\@bclosed[##1]{\@closed b{##1}}%
  \newdef\sclosed{\null@opt\@sclosed}%
    \newdef\@sclosed[##1]{\@closed s{##1}}%
  \newdef\lclosed{\@closed l{}}%
  \newdef\cbclosed{\@closed{cb}{}}%
  \newdef\qbclosed{\@closed{qb}{}}%
  \newlet\uclosed\bclosed
%    \end{macrocode}
%
% \subsubsection{Filling a closed curve}\label{filling}
%
% The next few prefix macros fill the interior of the closed path that
% follows with some sort of pattern. The path must be either already
% closed (like that produced by \cs{rect} or \cs{circle}) or explicitly
% closed with a closing prefix. A non-closed path will simply be drawn
% with a solid line.
%
% \DescribeMacro{\tess}
% \cs{tess} takes one mandatory argument, the name of a previously defined
% tile, and fills with shifted copies of the tile.
%    \begin{macrocode}
  \newdef\tess##1{\@rendmac{tess (##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\shade}
% \DescribeMacro{\polkadot}
% \cs{shade} and \cs{polkadot} take one optional parameter, the separation
% between dots, defaulting to \cs{shadespace} (resp., \cs{polkadotspace}).
% The size of the dots is set by issuing the command \cs{shadewd} (resp.,
% \cs{polkadotwd}).
%    \begin{macrocode}
  \newdef\shade{\simple@opt\@shade{\the\shadespace}}%
  \newdef\@shade##1{\@rendmac{shade (##1)}}%
  \newdef\polkadot{\simple@opt\@polkadot{\the\polkadotspace}}%
  \newdef\@polkadot##1{\@rendmac{polkadot (##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\thatch}
% \DescribeMacro{\lhatch}
% \DescribeMacro{\rhatch}
% \DescribeMacro{\xhatch}
% The hatching macros mostly take two optional parameters, the
% separation of the hatching lines (default \cs{hatchspace}) and their
% color. One slight exception is \cs{thatch}, which is called by all the
% others. Its first optional argument is the separation \emph{and} the
% angle (default $0$) of the lines, separated by a comma. The other
% hatching macros have a fixed angle. \cs{lhatch} has lines at a $-45$
% degree angle (upper left to lower right), \cs{rhatch} produces the opposite
% diagonal, and \cs{xhatch} does both sets of lines (cross hatching).
%    \begin{macrocode}
  \newdef\thatch{\simple@opt\@thatch{\the\hatchspace,0}}%
  \newdef\@thatch##1{\null@opt{\@@thatch{##1}}}%
  \newdef\@@thatch##1[##2]{\@rendmac{%
    \mfp@ifempty{##2}{thatch}{colorthatch (##2)} (##1)}}%
  \newdef\lhatch{\simple@opt\@lhatch{\the\hatchspace}}%
  \newdef\@lhatch##1{\@thatch{##1,-45}}%
  \newdef\rhatch{\simple@opt\@rhatch{\the\hatchspace}}%
  \newdef\@rhatch##1{\@thatch{##1,45}}%
  \newdef\xhatch{\simple@opt\@xhatch{\the\hatchspace}}%
  \newdef\@xhatch##1{\null@opt{\@@xhatch{##1}}}%
  \newdef\@@xhatch##1[##2]{\@rendmac{%
    \mfp@ifempty{##2}{xhatch}{colorxhatch (##2)} (##1)}}%
  \newlet\hatch=\xhatch
%    \end{macrocode}
%
% Commands that might conceivably interfere with small bits of \TeX{}
% code in labels have been renamed. Thus, instead of \cs{fill}, which is a
% \LaTeX{} text mode command, we have \cs{gfill}. We also have \cs{gclear}
% and \cs{gclip}. The `g' is for `graphic'. Later, commands that deal
% with text (labels and captions), have `t' prepended to their more
% natural name, thus \cs{tlabel} and \cs{tcaption}.
%
% \DescribeMacro{\gfill}
% \DescribeMacro{\gclear}
% \DescribeMacro{\gclip}
% \cs{gfill} take one optional argument, the color with which to fill.
% Under \MF{} the color must be a numeric (representing a level of gray)
% or one of the color functions, which are defined in \file{grafbase.mf}
% to return numeric values.
%
% \cs{gclear} will actually fill with the color \texttt{background} in \MP.
% \cs{gclip} might seem to be the inverse of \cs{gclear} (clearing the
% outside of a region), but in \MP{} the mechanism is completely
% different. One wishes \MP{} had an `inverse clip' command to use
% instead of filling with \gbc{background}. The figure macro following
% these commands must be a closed path.
%    \begin{macrocode}
  \newdef\gfill{\null@opt\@gfill}%
  \newdef\@gfill[##1]{%
    \@rendmac{\mfp@ifempty{##1}{filled}{colorfilled (##1)}}}%
  \newdef\gclear{\@rendmac{unfilled}}%
  \newdef\gclip{\@rendmac{Clip}}%
%    \end{macrocode}
%
% \subsubsection{Transforming a curve}\label{transforming}
%
% The following are transformation prefixes. They are all but one
% implemented with \cs{@closmac} for reasons covered earlier. Most have a
% mandatory argument, the parameters of the transformation. Because of the
% implementation, one can insert rendering macros between a transformation
% macro and the path being transformed, and they will apply to the
% untransformed path.
%
% If the \env{mfpic} environment has different x and y scales, the
% \cs{rotatepath} and \cs{reflectpath} compensates so that the result is
% congruent to the original. The others do not because this is what users
% seem to expect.
% \begin{itemize}
% \item \cs{reverse} and \cs{xyswappath} have no argument.
% \item \cs{rotatepath} takes  \marg{\meta{point},\meta{angle}}.
% \item \cs{shiftpath} takes  \marg{\meta{pair}}.
% \item \cs{scalepath} takes  \marg{\meta{center of scaling},\meta{factor}}.
% \item \cs{xscalepath} takes  \marg{\meta{x-center},\meta{factor}}.
% \item \cs{yscalepath} takes  \marg{\meta{y-center},\meta{factor}}.
% \item \cs{slantpath} takes  \marg{\meta{y-pivot},\meta{factor}}.
% \item \cs{xslantpath} = \cs{slantpath}.
% \item \cs{yslantpath} takes  \marg{\meta{x-pivot},\meta{factor}}.
% \item \cs{reflectpath} takes \marg{\meta{point1},\meta{point2}}, the
% endpoints of a `mirror'.
% \item \cs{transformpath} takes \marg{\meta{transformer}}, a \MF{}
%       `transformer' (see ``The \MF book'', page~212).
% \end{itemize}
%
% All of them simply write the \grafbase{} command of nearly the same
% name.
%    \begin{macrocode}
  \newdef\reverse{\@modmac{reverse}}%
  \newdef\xyswappath{\@closmac{xyswappedpath}}%
  \newdef\rotatepath##1{\@closmac{rotatedpath (##1)}}%
  \newdef\shiftpath##1{\@closmac{shiftedpath (##1)}}%
  \newdef\scalepath##1{\@closmac{scaledpath (##1)}}%
  \newdef\xscalepath##1{\@closmac{xscaledpath (##1)}}%
  \newdef\yscalepath##1{\@closmac{yscaledpath (##1)}}%
  \newdef\slantpath##1{\@closmac{xslantedpath (##1)}}%
  \newlet\xslantpath\slantpath
  \newdef\yslantpath##1{\@closmac{yslantedpath (##1)}}%
  \newdef\reflectpath##1{\@closmac{reflectedpath (##1)}}%
  \newdef\transformpath##1{\@closmac{transformedpath (##1)}}%
%    \end{macrocode}
%
% \subsubsection{Appending an arrowhead}\label{arrowhead}
%
% \DescribeMacro{\arrow}
% The four macros beginning \cs{@h} are assigned default values at the
% start and changed only if an option calls for it.
% Each option starts with a letter (The initial letters of
% `backset', `color', `length', or `rotate'), followed by a value
% to assign to the corresponding variable (defaulting to \mfc{0pt},
% \meta{empty}, \cs{the}\cs{headlen} and \gbc{0 deg}). Then \cs{arrow}
% finishes with the invokation of \cs{@arrow}.
%    \begin{macrocode}
  \def\arrow{\def\@hbackset{0}\def\@hcolour{}%
    \edef\@hlength{\the\headlen}\def\@hrotate{0}%
    \@arrow}%
%    \end{macrocode}
%
% \cs{@arrow} calls \cs{@arrowoption} if it finds an optional parameter.
% After processing the parameter, \cs{@arrowoption} calls \cs{@arrow}
% again. This loop will end when optional arguments run out. Then
% \cs{@@arrow} finishes with the actual \MF{} code.
%    \begin{macrocode}
  \newdef\@arrow{\mfp@ifnextchar[{\@arrowoption}{\@@arrow}}%
  \newdef\@@arrow{%
    \@modmac{%
      \mfp@ifempty{\@hcolour}{headpath}{colorheadpath (\@hcolour)}%
      \space(\@hlength, \@hrotate, \@hbackset)}}%
%    \end{macrocode}
%
% Since the \cs{arrow} command takes up to 4 optional arguments in any
% order, we have this utility \cs{@arrowoption} which examines an option's
% contents and assigns a value to an appropriate macro. Since rather nasty
% error messages will result if the contents are empty, we test for this
% and do nothing when there is nothing to process. \cs{@@arrowoption}
% makes the appropriated definitions, then \cs{@arrow} is iterated to
% catch another optional parameter.
%    \begin{macrocode}
  \newdef\@arrowoption[##1]{%
    \mfp@ifempty{##1}{}{\@@arrowoption##1\mfp@delim}\@arrow}%
  \newdef\@@arrowoption##1##2\mfp@delim{%
    \if l##1\relax      \mfp@ifempty{##2}{}{\def\@hlength{##2}}%
    \else\if r##1\relax \mfp@ifempty{##2}{}{\def\@hrotate{##2}}%
    \else\if b##1\relax \mfp@ifempty{##2}{}{\def\@hbackset{##2}}%
    \else\if c##1\relax \mfp@ifempty{##2}{}{\def\@hcolour{##2}}%
    \else
      \Mfpic@warn{Improper option to \string\arrow\@online .}%
    \fi\fi\fi\fi}%
%    \end{macrocode}
%
% This ends the prefix macros.
%
% \subsection{Transforming the coordinate system}\label{coordinate}
%
% \DescribeMacro{\coords}
% \DescribeMacro{\endcoords}
% The following apply transforms to the \MF{} coordinate system, and
% these can be localized with \cs{coords} $\ldots$ \cs{endcoords}. The
% transforms apply when the curve is \emph{rendered} and have no effect
% on paths merely stored with \cs{store} and \cs{patharr}. Moreover, if a
% path is created with \cs{connect}, it is transformed as a whole.
%
% \DescribeMacro{\applyT}
% These are implemented by \cs{applyT} which takes as its argument a \MF{}
% `transformer'.
%
% These commands (except \cs{turn}, kept for backward compatibility) have
% at most one argument, the parameters of the transformation. \cs{rotate}
% rotates around the origin, \cs{rotatearound} rotates around a given
% point, \cs{turn} takes the point as an optional argument.
%
% Transformations are applied in reverse of the order they appear in the
% file (i.e., the most recent first).
%    \begin{macrocode}
  \newdef\coords{\mfsrc{\@nl bcoords\@nl}}%
  \newdef\endcoords{\mfsrc{\@nl ecoords\@nl}}%
  \newdef\applyT##1{\mfsrc{\@nl hide(apply_t (##1))}}%
  \def\rotate##1{\applyT{rotated ##1}}%
  \newdef\rotatearound##1##2{%
    \applyT{rotatedaround (##1, ##2)}}%
  \newdef\turn{\simple@opt\@turn{(0,0)}}%
  \newdef\@turn##1##2{\rotatearound{##1}{##2}}%
  \newdef\reflectabout##1##2{%
    \applyT{reflectedabout (##1, ##2)}}% line ##1--##2.
  \let\mirror=\reflectabout
  \newdef\shift##1{\applyT{shifted ##1}}% pair.
  \def\scale##1{\applyT{scaled ##1}}% same scaling
  \newdef\xscale##1{\applyT{xscaled ##1}}%
  \newdef\yscale##1{\applyT{yscaled ##1}}%
  \newdef\zscale##1{\applyT{zscaled ##1}}%
  \newdef\xslant##1{\applyT{xslant ##1}}%
  \newdef\yslant##1{\applyT{yslant ##1}}%
  \newdef\zslant##1{\applyT{zslant ##1}}%
  \newdef\boost##1{\applyT{boost ##1}}%
  \newdef\xyswap{\applyT{xyswap}}%
%    \end{macrocode}
%
% \subsection{Axes and grids}\label{axes}
%
% \DescribeMacro{\axes}
% \DescribeMacro{\xaxis}
% \DescribeMacro{\yaxis}
% An axis would normally not be thought of as a figure macro, because one
% would not want to position them arbitrarily nor transform them. One
% would also not want the hassle of having always to specify the origin,
% etc. However, one would want to occasionally make them dotted or dashed
% or colored.
%
% The original \cs{axes} was therefore not a figure macro. It always drew
% both axes with solid lines. Later \cs{xaxis} and \cs{yaxis} were
% introduced, which mimicked the behavior of \cs{axes}. For backward
% compatibility, the old behavior is supported with the old commands. The
% optional argument to \cs{axes}, \cs{xaxis} and \cs{yaxis} is the length
% of the arrowhead, defaulting to \cs{the}\cs{axisheadlength}.
%    \begin{macrocode}
  \newdef\xaxis{\simple@opt\@xaxis{\the\axisheadlen}}%
  \newdef\yaxis{\simple@opt\@yaxis{\the\axisheadlen}}%
  \newdef\axes{\simple@opt\@axes{\the\axisheadlen}}%
  \newdef\@axes##1{\mfcmd{\@nl axes (##1)}}%
  \newdef\@xaxis##1{\mfcmd{\@nl xaxis (##1)}}%
  \newdef\@yaxis##1{\mfcmd{\@nl yaxis (##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\axis}
% When border axes were added, all the code was revamped, and now we
% create axes as figure macros. It also became clear there was so
% much common code that it would be better to implement the syntax
% \cs{axis}\marg{l}, etc., rather than have separate commands \cs{laxis},
% etc. for all six possible axes. Therefore, only the x- and y-axes have
% their own commands. The \cs{axis} command has one optional argument
% (the arrowhead length) and one mandatory argument, a single letter
% designating the axis to draw.
%
% The only complication is that the x- and y-axis have one default head
% length, \cs{axisheadlength} (initially \texttt{5pt}), while the side
% axes have a different default, \cs{sideheadlength} (initially \texttt{0pt}).
% Therefore we don't know which default to use until the mandatory argument
% is read. In \cs{@@axis}, we use \cs{get@axisnum} to check this
% mandatory argument and convert it to a number \cs{mfp@axisnum}, which is
% used to select the head length.
%    \begin{macrocode}
  \newdef\axis{\null@opt\@axis}%
  \newdef\@axis[##1]##2{\get@axisnum{##2}\axis
    \mfp@ifempty{##1}%
      {\edef\mfp@param{%
         \ifnum\mfp@axisnum<2 \the\axisheadlen
         \else \the\sideheadlen
         \fi}\@@axis{\mfp@param}}{\@@axis{##1}}{##2}}%
  \newdef\@@axis##1##2{\arrow[l##1]\@figmac{axisline.##2}}%
%    \end{macrocode}
%
% \DescribeMacro{\doaxes}
% \cs{doaxes} takes one optional argument, the arrowhead length, and one
% mandatory argument, all the axes to draw. These should be just letters
% with nothing separating them except optional spaces. \cs{doaxes} is
% implemented via the self-looping  macro \cs{do@axis}, which applies
% one of two commands to the letter, depending on whether the optional
% parameter was present (\cs{@axis}) or not (\cs{@@axis}).
%    \begin{macrocode}
  \newdef\doaxes{\null@opt\@doaxes}%
  \newdef\@doaxes[##1]##2{\def\mfp@axis{\@axis[##1]}%
    \do@axis##2\mfp@delim}%
  \newdef\do@axis##1{%
    \ifx\mfp@delim##1\relax\else\mfp@axis{##1}\@xp\do@axis\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\axismarks}
% \DescribeMacro{\xmarks}
% \DescribeMacro{\ymarks}
% \DescribeMacro{\lmarks}
% \DescribeMacro{\bmarks}
% \DescribeMacro{\rmarks}
% \DescribeMacro{\tmarks}
% Hash marks (or tick marks) on the axes are provided by the
% \cs{axismarks} command (\cs{marks} was the original choice, but that
% turned out to conflict with a primative of e\TeX). For brevity, therefore,
% we also have separate commands \cs{xmarks}, etc. \cs{axismarks} has two
% mandatory arguments: the letter for the axis, and a comma separated
% list of numbers giving the positions on the axis. It functions as a list
% macro (see previous discussion of types of macros) and so the list of
% numbers can be prescribed by an external file
% \cs{datafile}\marg{\meta{file}}. One must be sure to issue an
% appropriate \cs{using} command to produce a numeric list in the output.
% This is the main reason for the \cs{usingnumericdefault} command.
%
% I had a change of heart after the \cs{axis} command, and I made things
% simpler to code here by putting the optional argument of \cs{axismarks}
% after the first mandatory argument. I could justify this because I
% expect most users will use the shorter versions that don't require the
% first argument (that is, the expectation that optional arguments come
% first is still satisfied). The optional argument is the length of the
% marks. The position of the marks is controlled separately by the
% \cs{setaxismarks} command, described previously.
%    \begin{macrocode}
  \newdef\axismarks##1{\simple@opt{\@marks{##1}}{\the\hashlen}}%
  \newdef\@marks##1##2{\mfsrc{\@nl ##1marks (##2)}\mfp@writedata}%
  \newdef\xmarks{\axismarks x}%
  \newdef\ymarks{\axismarks y}%
  \newdef\lmarks{\axismarks l}%
  \newdef\bmarks{\axismarks b}%
  \newdef\rmarks{\axismarks r}%
  \newdef\tmarks{\axismarks t}%
%    \end{macrocode}
%
% \DescribeMacro{\grid}
% \DescribeMacro{\gridpoints}
% \DescribeMacro{\lattice}
% The first one is, I think, inaccurately named: the word `grid' calls
% to mind a set of lines. It functions in a similar way: allowing a
% visualization of the coordinates, but it actually produces dots. The
% dots are located at the points whose coordinates are integer multiples
% of two numbers, which are given in the single mandatory argument
% separated by commas. The optional first argument is the diameter of the
% dots this defaults to \texttt{0.5bp} (hard coded in \file{grafbase}).
% Because of the name, I have provided two aliases: \cs{gridpoints}
% (for consistency with \cs{gridlines}, below) and \cs{lattice}.
%
% \DescribeMacro{\gridlines}
% Macro \cs{gridlines} takes the same mandatory argument and draws
% horizontal and vertical lines intersecting at all the dots that
% \cs{grid} would draw. Some packages (and \ConTeXt) define a \cs{grid}
% command so we use \cs{def} here instead of \cs{newdef} or \cs{redef}.
%
% \DescribeMacro{\hgridlines}
% \DescribeMacro{\vgridlines}
% These two draw only the horizontal or vertical lines, and their
% argument is the separation (in graph units) between successive lines.
%    \begin{macrocode}
  \def\grid{\null@opt\@grid}%
  \newdef\@grid[##1]##2{%
    \mfcmd{\mfp@ifempty{##1}{grid}{vgrid (##1)} (##2)}}%
  \newlet\gridpoints=\grid \newlet\lattice=\grid
  \newdef\gridlines##1{\mfcmd{\@nl gridlines (##1)}}%
  \newdef\vgridlines##1{\mfcmd{\@nl vgridlines (##1)}}%
  \newdef\hgridlines##1{\mfcmd{\@nl hgridlines (##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\plrgrid}
% \DescribeMacro{\plrgridpoints}
% \DescribeMacro{\gridarcs}
% \DescribeMacro{\gridrays}
% \DescribeMacro{\plrpatch}
% The command \cs{plrgrid} takes one mandatory argument which contains two
% numbers separated by a comma. The first is a radius and the second an
% angle. It draws circular arcs at integer multiples of the radius, and
% radial lines at integer multiples of the angle. It fills the
% picture rectangle and is clipped to that rectangle. \cs{plrgridpoints}
% is similar but places only dots at the intersections of these arcs and
% rays. It takes an optional argument for the size of the dots, normally
% \cs{dotsize}. \cs{gridarcs} draws only the arcs, \cs{gridrays} only the
% rays. These last two take only one parameter each: the radius separating
% the arcs, and the angle separating the rays.
%
% \cs{plrpatch} draws: a circular arc at a starting
% radius, then increments that radius by a step size and draws another
% arc, etc., and finally draws an arc at the ending radius. It does a similar
% thing for radial lines and angles. It takes one mandatory argument,
% which contains 6 numbers separated by commas: starting radius, ending
% radius, step size, starting angle, ending angle, step size.
%    \begin{macrocode}
  \newdef\plrgrid##1{\mfcmd{\@nl polargrid (##1)}}%
  \newdef\plrgridpoints{\simple@opt\@plrgp{\the\dotsize}}%
  \newdef\@plrgp##1##2{\mfcmd{\@nl polargridpoints (##1, ##2)}}%
  \newdef\gridarcs##1{\mfcmd{\@nl gridarcs (##1)}}%
  \newdef\gridrays##1{\mfcmd{\@nl gridrays (##1)}}%
  \newdef\plrpatch##1{\mfcmd{\@nl polarpatch (##1)}}%
%    \end{macrocode}
%
% \subsection{Visualizing points}\label{points}
%
% \DescribeMacro{\point}
% \DescribeMacro{\plotsymbol}
% \cs{point} draws a dot or a small circle. It takes one optional
% argument, the diameter of the dot, and one mandatory argument, the ordered
% pair (or comma separated list of them) at which to draw a dot. After
% \cs{pointfillfalse}, the dots will be unfilled (i.e., small circles),
% after \cs{pointfilltrue} (the default), they will be solid. Like the
% grid macros, it is not a figure macro, but merely does its drawing and
% is not subject to any prefix macros.
%
% In order to mark points with other than circles, we have the
% \cs{plotsymbol} command, so-called because it uses the same symbols as
% the \cs{plot} command (previously discussed). There is an optional
% argument that gives the size of the symbol, a mandatory argument with
% the name of the symbol, and a second mandatory argument which
% is a comma separated list of ordered pairs for the locations.
%
% For both these commands, the default optional argument is
% \cs{the}\cs{pointsize}.
%    \begin{macrocode}
  \newdef\point{\simple@opt\@point{\the\pointsize}}%
  \newdef\@point##1{%
    \mfsrc{\@nl pointd (##1, \ifpointfill\mf@T\else\mf@F\fi)}%
        \mfp@writedata}%
  \newdef\plotsymbol{\simple@opt\@plotsymbol{\the\pointsize}}%
  \newdef\@plotsymbol##1##2{%
    \mfsrc{\@nl plotsymbol (##2, ##1)}\mfp@writedata}%
%    \end{macrocode}
%
% \DescribeMacro{\plottext}
% In \MP{}, \TeX{} labels can be used in place of the symbols in
% \cs{plotsymbol}. Moreover, multiple copies of text can be placed with
% the \cs{tlabel} command (under \opt{mplabels}), as it supports a list of
% points for the location parameter. For \MF{} we supply an alternative,
% \cs{plottext}, which loops through the list of coordinates and issues
% \cs{tlabel} commands. The text can be anything that works in \cs{tlabel}.
%
% It takes one optional argument, the justification of the text (as in the
% \cs{tlabel command}, below---see also \cs{tlabeljustify}, above),
% defaulting to \oarg{cc}. There are two mandatory arguments: the text,
% and a comma separated list of ordered pairs. For consistency with
% \cs{plotsymbol} (and because it works better), we now require the same
% syntax for the points (i.e., no braces around individual points in the
% list as are allowed in \cs{tlabel} commands).
%
% We start by handling the justification, resetting whitespace,
% and loading the text into a token register. Then we read the list of
% points with \cs{@@plottext}. Under \opt{mplabels} we process the whole
% list with a single \cs{tlabel} command. Otherwise we prepare to loop
% through the list of points. The \cs{begingroup} in \cs{@plottext} is
% ended by the command called in \cs{@@plottext}.
%    \begin{macrocode}
  \newdef\plottext{\simple@opt\@plottext{cc}}%
  \newdef\@plottext##1{%
    \begingroup
      \mfp@resetwhitespace \tlabeljustify{##1}%
      \@ifmplabels{\@makeother\#}{}%
      \mfp@gettoks\@@plottext}%
  \newdef\@@plottext##1{%
    \@ifmplabels
     {\mfp@setMPpos \def\mfp@points{##1}\@@@tlabel}%
     {\@@@plottext##1,\mfp@delim}}%
%    \end{macrocode}
% After reading the list of points and appending ending tokens, we
% loop through them. The ending condition is that the next token is
% \cs{mfp@delim}. Otherwise we read the coordinates as delimited macros,
% and call \cs{@tlabel}, feeding it the coordinates and the text to
% plot there (the \cs{begingroup} in \cs{x@plottext} matches the
% \cs{endgroup} in \cs{@tlabel}). Then we recall \cs{@@@plottext} for
% another loop. Since we have used two internal commands of \cs{tlabel}
% code, we have to remember to check this if ever we rewrite \cs{tlabel}.
%    \begin{macrocode}
  \newdef\@@@plottext{%
    \mfp@ifnextchar\mfp@delim{\@firstoftwo\endgroup}{\x@plottext}}%
  \newdef\x@plottext(##1,##2),{\begingroup
    \@tlabel{##1}{##2}{\the\mfp@toks}\@@@plottext}%
%    \end{macrocode}
%
% \subsection{Figure macros}\label{figure}
%
% \subsubsection{Common geometric objects}\label{geometric}
%
% Finally we get to the real figure macros. These are implemented as
% \MF{} paths that can be variously rendered, transformed, etc., with the
% prefix macros.
%
% The first few (\cs{rect} through \cs{makesector}) are closed paths and
% need not be prefixed with a closing macro before filling, etc.
%
% \DescribeMacro{\rect}
% This takes one mandatory argument, the two diagonally opposite
% corners of the rectangle separated by a comma, and draws the rectangle
% with horizontal and vertical sides having these as two corners. The
% direction of the path (which seldom makes a difference) is such that it
% starts at the first specified point and moves horizontally first.
%    \begin{macrocode}
  \newdef\rect##1{\@figmac{rect (##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\regpolygon}
% There are four arguments. The first is the number of sides. The second
% is the name of a variable to represent the vertices. The other
% two should be equations locating two vertices or the center and one
% vertex. If the name used is \gbc{Ver}, then the vertices will be
% \gbc{Ver1}, \gbc{Ver2}, etc., numbering anticlockwise. The center is
% \gbc{Ver0}. Case is significant. After the command, the points can be
% referred to in other \mfpic{} commands (except text label commands
% when \opt{mplabels} is not in effect).
%    \begin{macrocode}
\newdef\regpolygon##1##2##3##4{%
  \@figmac{regularpolygon(##1)(##2)(##3;##4;)}}%
%    \end{macrocode}
%
% \DescribeMacro{\circle}
% This has one optional argument containing one of the letters
% \texttt{t}, \texttt{p} (the default), \texttt{c}, or \texttt{s}. Its
% purpose is to specify what kind of data is in the single mandatory
% argument. These are a subset of the optional arguments that the \cs{arc}
% commad (below) takes, and have almost the same meaning:
% \begin{itemize}
% \item \oarg{t}, the three point form needs three points (of course).
% \item \oarg{p}, the polar form needs the center point and the radius.
%       This is the default when the optional argument is absent.
% \item \oarg{c}, the center/point form needs the center and one point on
%       the circle.
% \item \oarg{s}, the point-sweep form requires two points and the angle of
%       arc between them. The angle may be positive or negative. A
%       positive angle indicates the number of degrees anticlockwise from
%       the first point to the second. Negative means clockwise.
% \end{itemize}
%
% Supplying \cs{arc} with the same parameters, or the appropriate superset
% in the case of \oarg{p} and \oarg{c}, would produce a sub-arc of the
% circle that \cs{circle} produces. This is the reason for giving
% \cs{circle} these options: to make diagrams which show a circle and an
% arc on it. (This can also be done with an ellipse by using a
% transform on a circle and its arc.
%
% We use \cs{def} instead of \cs{newdef} or \cs{redef} because we know
% \LaTeX{} has already defined a \cs{circle} command, but plain \TeX{} has
% not. Instead of passing the default \texttt{p}, we pass a null
% argument, causing the code to compare various letters to \cs{relax}
% (always false) and then execute the default code.
%    \begin{macrocode}
  \def\circle{\null@opt\circl@}%
  \newdef\circl@[##1]##2{%
    \if      t##1\relax \@figmac{circleppp (##2)}%
    \else\if c##1\relax \@figmac{circlecp  (##2)}%
    \else\if s##1\relax \@figmac{circlepps (##2)}%
    \else               \@figmac{circle    (##2)}%
    \fi\fi\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\ellipse}
% \cs{ellipse} has one optional argument, an angle of rotation and one
% mandatory argument, containing the center, the horizontal radius (before
% rotation) and the vertical radius, separated by commas.
%    \begin{macrocode}
  \newdef\ellipse{\simple@opt\@ellipse{0}}%
  \newdef\@ellipse##1##2{\@figmac{ellipse (##2, ##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\sector}
% This is the closed curve starting at the center of a circle, out
% along a radius to the circumference of the circle, along an arc of the
% circle,  then back to the center. It has one mandatory argument
% containing the center, the radius, and the two angles, separated by
% commas.
%
% \DescribeMacro{\makesector}
% Takes a following arc and draws the sector (even if the center point
% is not known). It is really a prefix macro (closing an arc with two
% straight lines), but the combination \cs{makesector}\cs{arc} acts like a
% figure.
%    \begin{macrocode}
  \newdef\sector##1{\@figmac{sector (##1)}}%
  \newdef\makesector{\@closmac{makesector}}%
%    \end{macrocode}
%
% \DescribeMacro{\arc}
% A circular arc can be specified in several ways and we support most of
% them. \cs{arc} takes an optional argument: a letter to indicate which
% specification. It has one mandatory argument containing the data for
% that specification, separated by commas.
%
% The available letters and the corresponding required data are:
% \begin{itemize}
% \item \oarg{t}, the three point form needs three ordered pairs.
% \item \oarg{p}, the polar form needs the center point, two angles and
%       the radius.
% \item \oarg{a}, the alternative polar form needs the center, the radius
%       and two angles.
% \item \oarg{c}, the center-point-sweep form needs the center, the
%       starting point, and the angle.
% \item \oarg{s}, the point-sweep form requires the starting point, the
%       ending point and the angle.
% \end{itemize}
%
% The default optional argument is \oarg{s}. (I don't know why. It
% certainly doesn't seem the most natural. I would have picked \oarg{a}.)
% Like \cs{circle}, an empty argument is passed by default.
%    \begin{macrocode}
  \newdef\arc{\null@opt\@arc}%
  \newdef\@arc[##1]##2{%
    \if      t##1\relax \@figmac{arcppp (##2)}%
    \else\if p##1\relax \@figmac{arcplr (##2)}%
    \else\if a##1\relax \@figmac{arcalt (##2)}%
    \else\if c##1\relax \@figmac{arccps (##2)}%
    \else               \@figmac{arcpps (##2)}%
    \fi\fi\fi\fi}%
%    \end{macrocode}
%
% \DescribeMacro{\plr}
% \DescribeMacro{\midpoint}
% A little utility to convert a list of pairs into another list of
% pairs, where the given list are assumed to be polar coordinates and the
% results are their Cartesian counterparts. And one to calculate the
% midpoint, given two points separated by a comma.
%    \begin{macrocode}
  \newdef\plr##1{map (polar) (##1)}%
  \newdef\midpoint##1{(0.5[##1])}%
%    \end{macrocode}
%
% \subsubsection{List macros}\label{list}
%
% The next several figure macros are all list macros. They draw a path
% determined by a list of points. The list can be explicitly given as a
% mandatory argument containing a comma-separated list of ordered pairs,
% or it can be taken from an external datafile. This is true for
% \cs{polyline} through \cs{turtle}. These macros differ only in
% how the points determine the path. (The splines don't actually connect
% the points given, but rather use the points in a different way to
% determine a curve.) The list of points is not an argument of any of
% these. It should follow, and is picked up and written to output by the
% ending code of \cs{@listmac}. This is basic to list macros, and will not
% be repeated for each one.
%
% \DescribeMacro{\polyline}
% \DescribeMacro{\polygon}
% The most basic, a polyline or polygonal path, \cs{polyline}
% draws line segments from each point to the next. \cs{lines} is an
% alias. \cs{polygon} does the same, except it closes the path by
% connecting the last point to the first.
%
% In \cs{@polyline}, the argument is \mfc{true} or \mfc{false},
% indicating whether the path is to be closed.
%    \begin{macrocode}
  \newdef\polyline{\@polyline\mf@F}%
  \newlet\lines=\polyline
  \newdef\polygon{\@polyline\mf@T}%
  \newdef\@polyline##1{\@listmac{polyline (##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\curve}
% \DescribeMacro{\cyclic}
% \cs{curve} draws a smooth curve connecting a list of points. it arranges
% for the curve, at point $p\sb n$ to be traveling parallel to the direction
% from $p\sb {n-1}$ to $p\sb {n+1}$ (except at the first and last point).
%
% \cs{cyclic} is similar, except the curve is closed, and at the first
% point it also travels parallel to the direction from the previous point
% (the last one listed) to the next.
%
% There is an optional argument, which is the tension. This is a number
% greater than .75. The larger it is, the closer to a polyline one gets.
% The default is 1 (set in \file{grafbase}) or more generally, the value
% set by \cs{settension}.
%    \begin{macrocode}
  \newdef\curve {\null@opt{\@curve\mf@F}}%
  \newdef\cyclic{\null@opt{\@curve\mf@T}}%
  \newdef\@curve##1[##2]{%
    \@listmac{\mfp@ifempty{##2}{curve}{tcurve (##2)} (##1)}}%
%    \end{macrocode}
%
% \DescribeMacro{\fcncurve}
% A `function curve' is the graph of a function of $x$. It should always
% travel left to right. This is not guaranteed by the \cs{curve} macro,
% above, even if the x-coordinates are listed in order. \cs{fcncurve} is
% guaranteed to do this if the list of points has the x-coordinates so
% ordered.
%
% The optional argument is called tension. Internally, it is not quite the
% same as the tension argument to \cs{curve}, but it also governs how
% closely the curve stays to the corresponding polyline. If the optional
% argument is missing, this command uses $1.2$ (more precisely, it uses
% $1.2$ times the value set with \cs{settension}). The above guarantee is
% voided if the value used is less than $1$. However, most curves will
% satisfy the guarantee with some lower values.
%    \begin{macrocode}
  \newdef\fcncurve{\null@opt\@fcncurve}%
  \newdef\@fcncurve[##1]{%
    \@listmac{\mfp@ifempty{##1}{fcncurve}{functioncurve (##1)}}}%
%    \end{macrocode}
%
% \DescribeMacro{\qspline}
% \DescribeMacro{\closedqspline}
% \DescribeMacro{\cspline}
% \DescribeMacro{\closedcspline}
% These are supposed to be types of splines, about which I know only a
% little. The list or datafile that should follow each command should
% contain not the points passed through, but instead the control data.
% For quadratic B-splines the points create the path as follows: for
% successive points $p\sb i, p\sb {i+1}$ in the list, the path passes through
% the midpoint of the line segment connecting $p\sb i$ and $p\sb {i+1}$, tangent
% to that line segment.
%
% Cubic splines determine the curve as follows: for successive points
% $p\sb i, p\sb {i+1}$ in the list, the line segment connecting them is divided
% into thirds with two points $q\sb i$ and $q\sb i'$. The curve then passes
% through the midpoint of the segment from $q\sb {i-1}'$ to $q\sb i$ and tangent
% to that segment.
%
% `Control' is obtained as follows: the farther apart the points $p\sb i$
% and $p\sb {i+1}$ (quadratic) or $q\sb {i-1}'$ and $q\sb i$ (cubic) the
% less the curvature of the curve at the midpoint.
%
% The `\texttt{q}' versions produce quadratic splines, the `\texttt{c}'
% versions produce cubic splines.
%    \begin{macrocode}
  \newdef\qspline{\@listmac{openqbs}}%
  \newdef\closedqspline{\@listmac{closedqbs}}%
  \newdef\cspline{\@listmac{opencbs}}%
  \newdef\closedcspline{\@listmac{closedcbs}}%
%    \end{macrocode}
%
% \DescribeMacro{\mfbezier}
% \DescribeMacro{\closedmfbezier}
% These produce the standard \MF{} cubic B\'ezier (the connection is
% \mfc{..} unless the optional argument is used) with tension given by
% an optional argument. A mandatory argument (not shown) contains the
% list of points.
%
% \DescribeMacro{qbeziers}
% \DescribeMacro{closedqbeziers}
% These produce the equivalent of a sequence of \LaTeX{} \cs{qbezier}
% commands. The mandatory argument will be a list of points alternating
% between nodes and control points. Note that quadratic B\'eziers need
% not be smooth at the nodes unless the control points line up. Our
% plural name distinguishes it from the \LaTeX{} command.
%    \begin{macrocode}
  \newdef\mfbezier{\null@opt{\@mfbezier\mf@F}}%
  \newdef\closedmfbezier{\null@opt{\@mfbezier\mf@T}}%
  \newdef\@mfbezier##1[##2]{%
    \@listmac{\mfp@ifempty{##2}{bezier}{tbezier (##2)} (##1)}}%
  \newdef\qbeziers{\@listmac{qbezier (\mf@F)}}%
  \newdef\closedqbeziers{\@listmac{qbezier (\mf@T)}}%
%    \end{macrocode}
%
% \DescribeMacro{\turtle}
% Many years ago there was a tool for teaching programming concepts to
% young children. They could draw a figure on a screen by programming a
% `turtle' with a sequence of turns and distances. The following is
% similar. It has a mandatory argument containing a list of ordered pairs.
% The first is the coordinates of the starting point, and each of the rest
% is interpreted as a displacement from the current position, along which
% a line segment is to be drawn. The terminal point of that segment is the
% new current position
%    \begin{macrocode}
  \newdef\turtle{\@listmac{turtle}}%
%    \end{macrocode}
%
% \subsubsection{Graphing functions}\label{functions}
%
% \DescribeMacro{\function}
% \prog{Mfpic} provides the ability to plot the graph of any function that
% can be defined in \MF. This is done with the \cs{function} command, a
% figure macro which takes one optional parameter that selects
% the smoothness of the \MF{} path produced. It can be \oarg{p}, which
% draws a polyline path through selected points (much like \cs{polyline}),
% or \oarg{s\meta{tension}} which selects a smooth path (much like
% \cs{curve}\oarg{\meta{tension}}). The tension may be omitted and then
% defaults to 1 (set in \file{grafbase}). The default is \oarg{s}.
%
% There are two mandatory arguments. The second is the function, which
% must be written as a formula (strictly speaking, a \MF{} numerical
% expression) containing only one variable, \texttt{x}. The first
% mandatory argument contains three numbers separated by commas. They are,
% in order, the starting value of \texttt{x}, the ending value, and the
% step size.
%
% \DescribeMacro{\parafcn}
% \cs{parafcn} is similar, except its formula must be an ordered pair of
% formulas (strictly speaking, a \MF{} pair expression) in which
% \texttt{t} is the only variable.
%
% \DescribeMacro{\plrfcn}
% \cs{plrfcn} is similar, except its argument is a formula (a \MF{}
% numeric expression) representing the radius, in which \texttt{t} is the
% only variable, interpreted as the angle coordinate, $\theta$, in degrees.
%
% These three commands are so alike that all they do is set the name to
% be written to the output and call the common code.
%    \begin{macrocode}
  \newdef\function{\def\mfp@name{function}\mfp@fcn}%
  \newdef\parafcn{\def\mfp@name{parafcn}\mfp@fcn}%
  \newdef\plrfcn{\def\mfp@name{plrfcn}\mfp@fcn}%
  \newdef\mfp@fcn{\simple@opt\@mfp@fcn{s}}%
  \newdef\@mfp@fcn##1{\@@mfp@fcn##1\mfp@delim}%
  \newdef\@@mfp@fcn##1##2\mfp@delim##3##4{%
    \@figmac{\mfp@ifempty{##2}{}{t}\mfp@name\space
      (\if p##1\mf@F\else\mf@T\fi \mfp@ifempty{##2}{}{, ##2})
      (##3) (##4)}}%
%    \end{macrocode}
%
% \DescribeMacro{\btwnfcn}
% The region between two functions \cs{btwnfcn} is a figure macro. It is
% mostly intended for shading or other filling operations so it is already
% closed and, by default, it is not `smooth'. Its parameters are the
% same as those of \cs{function} (above), with two exceptions: the default
% optional argument is \oarg{p} and it has an additional mandatory
% argument, the other function. The resulting \MF{} path travels along one
% the graph of the first function from the starting $x$ to the ending $x$,
% thence vertically to the graph of the second function, along it (in
% reverse) to the starting $x$ and finally, vertically to the start of the
% first function's graph.
%
% \DescribeMacro{\plrregion}
% The figure macro \cs{plrregion} also produces a closed \MF{} path. It
% has the same parameters as \cs{plrfcn}, and the path produced begins at
% the origin, travels along a straight line in the direction of the
% starting angle to the beginning of the graph of the expression, along
% that graph to the ending angle and then straight back to the origin. Its
% default option is also \oarg{p}.
%    \begin{macrocode}
  \newdef\btwnfcn{\simple@opt\@btwnfcn{p}}%
  \newdef\@btwnfcn##1{\@@btwnfcn##1\mfp@delim}%
  \newdef\@@btwnfcn##1##2\mfp@delim##3##4##5{\btwn@params{##1}{##2}%
    \@figmac{\t@pref btwnfcn (\s@vals) (##3) (##4) (##5)}}%
  \newdef\btwn@params##1##2{%
    \edef\s@vals{\if s##1\mf@T\else\mf@F\fi}%
    \mfp@ifempty{##2}{\def\t@pref{}}%
     {\def\t@pref{t}\edef\s@vals{\s@vals, ##2}}}%
  \newdef\plrregion{\simple@opt\@plrregion{p}}%
  \newdef\@plrregion##1{\@@plrregion##1\mfp@delim}%
  \newdef\@@plrregion##1##2\mfp@delim##3##4{\btwn@params{##1}{##2}%
    \@figmac{((0,0)--(\t@pref plrfcn (\s@vals) (##3) (##4))%
       --cycle)}}%
%    \end{macrocode}
%
% \subsection{Some composite objects}\label{composite}
%
% \DescribeMacro{\tile}
% A tile is syntactically a \MF{} picture variable. The commands between
% \cs{tile} (or \cs{begin}\marg{tile}) and \cs{endtile} (or
% \cs{end}\marg{tile}) should be any sequence of \mfpic{} figure macros
% with possible prefix macros. They will be drawn not on the main picture
% (\gbc{currentpicture}), but on the picture given by the name in the
% \cs{tile} command's argument.
%
% The argument has five parts separated by commas, the first is the
% name, the second is the unit of length (some absolute dimension like
% \mfc{1pt}), the next two are the width and height (pure numbers, the
% actual dimensions being these numbers times the unit of length), the
% last is one of the words \mfc{true} or \mfc{false}, indicating whether
% tile should be clipped to these dimensions (true) or allowed to extend
% beyond them (false).
%    \begin{macrocode}
  \newdef\tile##1{\mfcmd{\@nl tile (##1)}}%
  \newdef\endtile{\mfsrc{endtile;\@nl}}%
%    \end{macrocode}
%
% \DescribeMacro{\patharr}
% A path array is a set of \MF{} path variables each having the same name
% followed by a different numeric suffix. This command turns off rendering
% and simply assigns these variables in order to the path expressions
% written by the figure macros between \cs{patharr} and \cs{endpatharr}.
% It works by redefining \cs{store@path}, issued by all the figure
% macros. These variables can be accessed in \mfpic{} by using the
% \cs{mfobj} command.
%
% \emph{Explicit} rendering commands will work in the sense that the
% affected path will be rendered in addition to being assigned to the
% variable. The only parameter is the common name of the variables.
%    \begin{macrocode}
  \newdef\patharr##1{\begingroup
    \mfsrc{hide(numeric ##1; path ##1[]; ##1 = 0)}%
    \def\store@path{\mfsrc{\@nl store (##1[incr ##1])}}%
    \setrender{}}%
  \newdef\endpatharr{\endgroup}%
%    \end{macrocode}
%
% \DescribeMacro{\connect}
% \DescribeMacro{\endconnect}
% These define an environment that can contain any sequence of figure
% macros. It functions as a single large \cs{@figmac}, the figure being
% the path obtained by connecting all the paths within by straight lines
% from the end of one to the beginning of the next. It is implemented via
% a path array, so the individual figures within the environment have
% implicit rendering turned off. Explicit rendering commands within the
% environment will have the expected effect.
%
% The \cs{if@mfp@latex} stuff at the end allows \cs{connect} to be used as
% a \LaTeX{} environment.
%    \begin{macrocode}
  \newdef\connect{\@figmac{begingroup; save nexus}%
    \patharr{nexus}}%
  \newdef\endconnect{\endpatharr
    \mfcmd{\@nl mkpoly (\mf@F, nexus)\@nl endgroup}%
    \if@mfp@latex \def\mfptmp@a{connect}%
      \ifx\mfptmp@a\@currenvir
        \aftergroup\@startfigtrue %\aftergroup\@imrendtrue
      \fi
    \fi}%
%    \end{macrocode}
%
% \subsection{Other graphical features}\label{otherfeatures}
%
% And now for something completely different: pie charts and bar charts
% (or bar graphs, or histograms).
%
% \DescribeMacro{\piechart}
% The \cs{piechart} command takes one optional argument containing a
% letter and an angle, and one mandatory argument containing the data. The
% letter can be `\texttt{c}' for clockwise or `\texttt{a}' for anticlockwise
% and determines the direction around the pie the different wedges will be
% drawn. The angle determines the angle of the first edge (in the given
% direction) of the first wedge. The default is \oarg{c90} which starts
% the first wedge at 12 o'clock and proceeds clockwise from there. The
% data in the mandatory argument are numbers separated by commas. The size
% of a wedge is proportional to the size of the corresponding number.
% \cs{piechart} is a list macro and can take the data from an external
% file.
%
% \DescribeMacro{\piewedge}
% Actually, nothing is drawn, it only defines a path array and a few
% other internal variables. Each individual wedge (elements of the just
% mentioned array) may be drawn using the \cs{piewedge} command, which is
% a figure macro. That command takes one optional argument that determines
% how the wedge is drawn, as described below, and one mandatory argument,
% the number of the wedge. Without the optional argument,
% \cs{piewedge}\marg{1} draws the first wedge in the position given by the
% arguments of the \cs{piechart} command.
%
% The optional arguments can be:
% \begin{itemize}
%   \item \oarg{x\meta{distance}}, the wedge is exploded, drawn
%     shifted outward from its position by \meta{distance} (in graph
%     units).
%   \item \oarg{s(\meta{dx},\meta{dy})}, the wedge is shifted from its
%     position by \meta{dx} horizontally and \meta{dy} vertically (in
%     graph units).
%   \item \oarg{m(\meta{x},\meta{y})}, the wedge is moved so that its
%     point is at coordinates \parg{\meta{x},\meta{y}}.
% \end{itemize}
%    \begin{macrocode}
  \newdef\piechart{\simple@opt\@piechart{c}}%
  \newdef\@piechart##1{\@@piechart##1\mfp@delim}%
  \newdef\@@piechart##1##2\mfp@delim##3{%
    \mfsrc{\@nl piechart(\if a##1 \else-\fi1, %
        \mfp@mtsub{##2}{90}, ##3)}\mfp@writedata}%
  \newdef\piewedge{\simple@opt\@piewedge{d}}%
  \newdef\@piewedge##1{\@@piewedge##1\mfp@delim}%
  \newdef\@@piewedge##1##2\mfp@delim##3{%
    \@figmac{(piewedge[##3]%
      \if      x##1 shifted (##2*piedirection[##3])%
      \else\if s##1 shifted (##2)%
      \else\if m##1 shifted (##2 - piecenter)%
      \else
      \fi\fi\fi)}}%
%    \end{macrocode}
%
% \DescribeMacro{\barchart}
% \DescribeMacro{\bargraph}
% \DescribeMacro{\gantt}
% \DescribeMacro{\histogram}
% The \cs{barchart} command takes one optional and two mandatory
% arguments. The last mandatory argument contains the data, separated by
% commas and these determine the length of the bars in graph units. This
% is also a list macro and instead of the list, an external file can hold
% the data.
%
% The optional argument determines the position and width of the bars and
% the first mandatory argument determines the orientation. The mandatory
% argument can be \marg{v} for vertical bars with base on the x-axis, or
% \marg{h} for horizontal bars with base on the y-axis.
% The optional argument contains three numbers separated by commas. The
% first is the coordinate of the leading edge of the first bar, the second
% is the distance (in graph coordinates) between the leading edge of one
% bar and that of the next, and the third is the fraction of that distance
% that is occupied by the bar. The default is \oarg{0,1,1}.
%
% We provide the aliases \cs{bargraph} and \cs{histogram}.
%
% \DescribeMacro{\chartbar}
% \DescribeMacro{\ganttbar}
% \DescribeMacro{\graphbar}
% \DescribeMacro{\histobar}
% The \cs{barchart} command does not actually draw anything, but defines a
% path array. The \cs{chartbar} command can then be used to draw a bar
% (one of the members of the just mentioned array). It is a figure macro
% and take the number of the bar as its mandatory argument. Aliases
% \cs{graphbar} and \cs{histobar} are provided. We avoid \cs{bar} because
% it is a math accent command.
%    \begin{macrocode}
  \newdef\barchart{\simple@opt\@barchart{0,1,1}}%
  \newdef\@barchart##1##2{%
    \mfsrc{\@nl barchart (##1, \if h##2\mf@F\else\mf@T\fi)}%
    \mfp@writedata}%
  \newlet\bargraph=\barchart
  \newlet\histogram=\barchart
  \newlet\gantt\barchart
  \newdef\chartbar##1{\@figmac{chartbar[##1]}}%
  \newlet\graphbar=\chartbar
  \newlet\histobar=\chartbar
  \newlet\ganttbar=\chartbar
%    \end{macrocode}
%
% One can add to \cs{mfp@additions} to extend \mfpic. Currently it
% is empty. This ends \cs{@mfpic@graf@macs}.
%    \begin{macrocode}
  \newdef\pinumber{3.14159}%
  \mfp@additions
}%
%    \end{macrocode}
%
%
% \section{The \env{mfpic} environment}\label{mfpicenv}
%
% \subsection{Initializations}\label{mfpicinitializations}
%
% \DescribeMacro{\mfpic}
% This command (or the \LaTeX{} environment \cs{begin}\marg{mfpic}) takes
% two optional arguments: the xscale and the yscale. When both are
% omitted, they are both set to 1, if the yscale is omitted, it is set
% equal to the xscale.
%
% There are also 4 mandatory arguments: the first two give the minimum and
% maximum extent of the x coordinates and the last two do the same for the
% y coordinates. The coordinates used in the figure commands within an
% mfpic environment are multiplied by the corresponding scales, and that
% is the multiple of \cs{mfpicunit} used in positioning, drawing, etc.
%
% The optional arguments are converted by the option handling code to
% mandatory arguments for \cs{@mfpic}, which contains the actual
% definition.
%    \begin{macrocode}
\newdef\mfpic{\simple@opt\@mfpicA{1}}%
\newdef\@mfpicA#1{\simple@opt{\@mfpic{#1}}{#1}}%
\newdef\@mfpic#1#2#3#4#5#6{%
%    \end{macrocode}
%
% We start by saving \mfpic{} extra fontdimen values. They will be
% restored by \cs{endmfpic}. This makes the values local (font dimensions
% are normally always global). Then we begin a group to localize ordinary
% \TeX{} definitions and assignments, disable writes to the output if
% \cs{opengraphsfile} hasn't occurred yet. save the current font in
% \cs{@tcurr} for restoration inside text labels and captions, set the
% switch that says we are in an \cs{mfpic} environment, disable \cs{par}
% so that blank lines have (little or) no effect, and switch to
% \cs{nullfont} so that stray characters (always an error) and spaces (not
% an error), have no effect. I wonder if \cs{@empty} is a better
% disabling definition for \cs{par} than \cs{relax}.
%    \begin{macrocode}
  \save@mfpicdimens
  \begingroup % ended near end of \endmfpic
  \@ifmfpfileisopen{}%
   {\if@mfp@nowrite\else \nooutputfileerror{\mfpic}%
      \def\@mfsrc##1##2{}%
    \fi}%
  \mfp@DBlog{Starting mfpic \number\mfp@count \@online.}%
  \font\@tcurr=\fontname\font\relax
  \let\ifin@mfpicenv\iftrue
%  \let\par\relax
  \let\par\@empty
  \nullfont
%    \end{macrocode}
%
% The graphics macros are undefined outside the \env{mfpic} environment.
% They are defined now by invoking \cs{@mfpic@graf@macs}.
%    \begin{macrocode}
  \@mfpic@graf@macs
%    \end{macrocode}
%
% Then we define two utility macros used to convert graph coordinates into
% actual dimensions relative to the lower left corner of the picture. The
% first argument is a dimension, but it is normally obtained by first
% multiplying a coordinate value by \cs{mfpicunit}. Since font dimensions
% may be involved, we assign \texttt{\#\#1} to a scratch dimension
% register first, since \TeX{} won't \cs{advance} font dimensions. We make
% the final assignment global for consistency.
%    \begin{macrocode}
  \newdef\@xconv##1{%
   {\mfp@scratch = ##1\relax
    \advance\mfp@scratch by -#3\mfpicunit
    \mfp@scratch = #1\mfp@scratch
    \global ##1 = \mfp@scratch}}%
  \newdef\@yconv##1{%
   {\mfp@scratch=##1\relax
    \advance\mfp@scratch by -#5\mfpicunit
    \mfp@scratch = #2\mfp@scratch
    \global ##1 = \mfp@scratch}}%
%    \end{macrocode}
%
% We are going to add all text labels to a box \cs{@alltlabels} and put
% that whole box on top of the graph during \cs{endmfpic}.
% We initialize the box here. The dimensions \cs{@tlabelsbot}, etc.,
% are also initialized. Each will be changed as labels are added, so a
% `non-maxdimen' value at \cs{endmfpic} means there are labels to add.
%    \begin{macrocode}
\setbox\@alltlabels\vbox{\hbox{}}%
\@tlabelsbot   \maxdimen
\@tlabelstop  -\maxdimen
\@tlabelsleft  \maxdimen
\@tlabelsright-\maxdimen
%    \end{macrocode}
%
% The graph is loaded into a box register at the end of the mfpic
% environment. The size of that box register may have to correspond to the
% arguments of the \cs{mfpic} command. Since \cs{endmfpic} doesn't receive
% these arguments we process them now.
%
% Dimensions \cs{@graphright}, etc., represent the extent of the graph
% box. We increase them when the text is added if it extends beyond the
% edges of the graph. These are all font dimensions, so they are global
% assignments.
%    \begin{macrocode}
  \@graphright=#4\mfpicunit \@xconv\@graphright
  \@graphtop=#6\mfpicunit \@yconv\@graphtop
  \@graphleft=0pt
  \@graphbot=0pt
  \@graphwd=\@graphright
%    \end{macrocode}
%
%  \subsection{Initialization code for the current
% picture}\label{current}
%
% Each \env{mfpic} environment produces a \gbc{beginmfpic...endmfpic}
% environment in the output file. Here we initialize the variables that
% correspond there to the 6 arguments and \cs{mfpicunit}, then begin the
% \MF{} environment. \gbc{beginmfpic} takes the number of the current
% figure as its only argument. For debugging purposes we write a \MF{}
% comment the contains the line number in the \TeX{} source file where the
% \cs{mfpic} command occurred. We also write a line of dashes
% (\cs{mf@d}) to make it easier to find the start of the environment. This
% will be removed in the public release.
%
% When \opt{mplabels} is in effect we need to set the font for the labels
% to the saved \cs{@tcurr} by writing some \mfc{verbatimtex} code. Since
% \opt{mplabels} can be turned on at any time, we write this whenever the
% \opt{metapost} option is in effect. It is a common misconception that
% \mfc{verbatimtex} can be used only once at the start of a \MP{} file. In
% fact it can be used any number of times. It's purpose is to be at an
% outer level, while \mfc{btex} is localized inside a box
%    \begin{macrocode}
  \mfsrc{\@nl \mf@p\mf@d\mf@d\mf@d\@nl
    unitlen := \the\mfpicunit\mf@s;\@nl
    xscale := #1; yscale := #2;\@nl
    bounds (#3, #4, #5, #6);\@nl
    \@nl
    beginmfpic(\number\mfp@count); \mf@p\space\@mfplineno.
    \mfp@ifmpost
     {\@nl verbatimtex \@nl
      \begingroup\space\font\noexpand\MFPcfont=\fontname\@tcurr\@nl
      etex;}{}}%
%    \end{macrocode}
%
% \subsection{Placing text labels}\label{textlabels}
%
% All the rest of \cs{@mfpic} defines commands that in some way or another
% produce labels. The easiest part is defining \cs{tlabel} under
% \opt{mplabels} where most of the work takes place in \file{grafbase.mp}.
% The most involved is the definition of \cs{tlabel} without
% \opt{mplabels}. All the rest (except \cs{tcaption}) add labels by
% calling \cs{tlabel}. Some of those could be simpler under \opt{mplabels}
% but then we'd need two versions of each.
%
% \DescribeMacro{\tlabel}
% This is the common code, processing optional arguments, etc. for
% \cs{tlabel}. It ultimately calls one of \cs{@tlabel} (no
% \opt{mplabels}) or \cs{@@tlabel} (\opt{mplabels}). It takes an optional
% argument describing the justification and rotation, followed by a
% location in one of two syntaxes (which adds to the complication, but we
% want to be backward compatible), followed by the text of the label
% (\TeX{} code).
%
% The location can be in the form \parg{\meta{x},\meta{y}}, but if \MP{}
% is processing labels we would like to be able to use \MP{} expressions,
% which can contain parentheses and commas. This would mess up \TeX's
% token matching for reading the two coordinates. Therefore we allow the
% whole point to be enclosed in braces. Under \opt{mplabels} the contents
% of the braces will be written to the output file without any further
% parsing. Without \opt{mplabels}, there should be either no braces, or
% inside the braces is the previously described syntax.
%
% We start with \cs{begingroup} to hide changes, then reset whitespace to
% its normal catcodes. Without \opt{mplabels} we reset \cs{tlabel@rot} to
% empty. Finally, we check for an optional parameter and run \cs{@tlabel@},
% feeding it an empty optional argument if there is none.
%    \begin{macrocode}
  \newdef\tlabel{%
    \begingroup    % ended in \@(@@)tlabel
      \mfp@resetwhitespace
      \@ifmplabels{}{\def\tlabel@rot{}}%
      \null@opt\@tlabel@}%
%    \end{macrocode}
%
% We run \cs{tlabeljustify} on the optional parameter. This keeps the
% default values of \cs{tl@vpos}, \cs{tl@hpos} and \cs{tlabel@rot} if
% the parameter is empty, otherwise it modifies them inside the current
% group.
%
% We then check for a left parenthesis and assume the
% \parg{\meta{x},\meta{y}} syntax in that case, calling \cs{@@tlabel@}
% to process it. Under \opt{mplabels} it stuffs the whole point into
% braces and call the main code \cs{@@tlabel} with that argument,
% otherwise it pulls out the two coordinates and feeds them as the first
% two arguments of the main code \cs{@tlabel}.
%    \begin{macrocode}
  \newdef\@tlabel@[##1]{\tlabeljustify{##1}%
    \mfp@ifnextchar({\@@tlabel@}{\@@tlabel@@}}%
  \newdef\@@tlabel@(##1,##2){%
    \@ifmplabels
    {\@@tlabel{(##1,##2)}}{\@tlabel{##1}{##2}}}%
%    \end{macrocode}
%
% If no parenthesis, we assume braces surround the point. Under
% \opt{mplabels} we call the main code (\cs{@@tlabel}) with that argument.
% Otherwise, we re-call the above \cs{@@tlabel@} on the contents of the
% braces, assuming (without checking) that the contents are coordinates in
% parentheses.
%    \begin{macrocode}
  \newdef\@@tlabel@@##1{%
    \@ifmplabels {\@@tlabel{##1}}{\@@tlabel@##1}}%
%    \end{macrocode}
%
% \DescribeMacro{\extraendtlabel}
% We now come to the main code under \opt{mplabels}, which should just
% arrange to write the correct commands to the output file. All labels are
% passed as \mfc{btex ... etex} structures. The definition of \cs{MFPtext}
% will have been written earlier by \cs{opengraphsfile}.
% \cs{extraendtlabel} is a hook currently only used by the \cs{tlabels}
% command to force a loop.
%    \begin{macrocode}
  \newdef\mfp@btex##1{btex \noexpand\MFPtext{##1} etex}%
  \newdef\extraendtlabel{}%
%    \end{macrocode}
%
% The command \gbc{newgblabel}, defined in \file{graphbase.mp} for placing
% labels, uses three parameters to justify the text. If we didn't have to
% support the \texttt{B} vertical placement option, there would be only
% two. All the other options involve placement \emph{relative} to the
% bounding box. But the baseline is absolute: \MP{} always puts it at
% y-coordinate 0 in the picture returned by \gbc{btex}. The first two
% parameters are numerical and the third is boolean. The
% first represents the fraction of the text that lies left of given
% point. The second is the fraction of the text below the point. If the
% third parameter is \mfc{true}, this fraction ignores the depth of the
% text (so $0$ indicates baseline placement); if it is false, the depth
% is accounted for (so $0$ indicates the very bottom of the text).
%
% By this point the letters of the optional parameter have been converted
% to integer values for \cs{tl@hpos} and \cs{tl@vpos} by
% \cs{tlabeljustify}. The following converts these integers to comma
% separated parameters as described above using \cs{ifcase}.
%
% The fourth parameter of \gbc{newgblabel} is the angle of rotation. Empty
% rotation is converted to the angle 0, otherwise it is written as is.
% All four parameters are stored in \cs{mfp@MPpos}.
%    \begin{macrocode}
  \newdef\mfp@setMPpos{%
    \edef\mfp@MPpos{%
      \ifcase\tl@hpos      .5\or 1\else 0\fi, % horizontal
      \ifcase\tl@vpos 0\or .5\or 1\else 0\fi, % vertical
      \ifnum \tl@vpos < 0 \mf@T\else\mf@F\fi, % true=Baseline
      \mfp@mtsub{\tlabel@rot}{0}}}%
%    \end{macrocode}
%
% \cs{@@tlabel} is the code called by \cs{tlabel} when \opt{mplabels} is
% in effect. The argument is a \MP{} pair expression, or comma separated
% list of them. It should be followed by the \TeX{} code for the label.
% We will load the label into a token register afterwards. First
% we restore the meaning of blank lines and then make sure any
% \texttt{\#}'s in the \TeX{} code are not doubled by changing their
% category.
%
% We load the label in a token register because writing that is (almost)
% verbatim (blank lines become \cs{par}, \texttt{\#} symbols are
% doubled if we're not careful, and control names have a space appended).
% One day maybe we'll try to obtain a true verbatim writing mode.
%    \begin{macrocode}
  \newdef\@@tlabel##1{\def\mfp@points{##1}\mfp@restorepar
    \mfp@setMPpos \@makeother\#\mfp@gettoks\@@@tlabel}%
%    \end{macrocode}
% Then the \gbc{newgblabel} command is written with the justification
% parameters, and two more: the label tokens, and the point (or list of
% points). The group (begun by \cs{tlabel}) is ended, and the
% \cs{extraendtlabel} command invoked.
%    \begin{macrocode}
  \newdef\@@@tlabel{%
    \mfcmd{\@nl
      newgblabel(\mfp@MPpos)(\mfp@btex{\the\mfp@toks})(\mfp@points)}%
    \endgroup \extraendtlabel}%
%    \end{macrocode}
%
% When \opt{mplabels} is not in effect, we use \TeX{} to position the
% label. By this point, the optional justification parameter to
% \cs{tlabel} has been converted to integer values of \cs{tl@vpos} and
% \cs{tl@hpos}, and the coordinates of the location are passed as the
% first two arguments of \cs{@tlabel}. The third argument is the \TeX{}
% code for the label.
%
% We put the label in a box (\cs{@textbox}) so we can measure and position
% it. It is a \cs{vbox} so we can have multiline labels. This is effected
% by wrapping it in a simple, left-aligned, one column \cs{halign},
% defining \cs{\bsl} to be \cs{cr}. We make this procedure a separate
% macro, since we need to do the identical thing in the \cs{tlabelpath}
% code.
%    \begin{macrocode}
  \newdef\set@textbox##1{%
    \setbox\@textbox=\vbox{\def\\{\cr}\mfp@restorepar
      \@tcurr\the\every@tlabel\halign{####\hfil\cr##1\crcr}}}%
%    \end{macrocode}
%
% We then compute its total height to simplify later code.
%    \begin{macrocode}
  \newdef\@tlabel##1##2##3{%
    \set@textbox{##3}%
    \mfp@scratch\tb@ht \advance\mfp@scratch\tb@dp
    \tb@totalht\mfp@scratch
%    \end{macrocode}
%
% The following computes whether the rightmost extent of the picture will
% be increased by the addition of the label. We convert the x-coordinate
% of the label's location to a distance from the left edge of the picture.
% We then add to that the amount of the label extending to the right of
% this location. Then we add or subtract the separation of the label
% from its location. Finally, we simply add the horizontal adjustment
% defined by the user with \cs{tlabeloffset}. The value of
% \cs{@tlabelsright} is set equal to this if it was less. We could omit
% this group: we never use \cs{@tlabelsright} except in debugging.
%
% The macro \cs{tb@wd} expands to \cs{wd}\cs{@textbox}.
%    \begin{macrocode}
    \mfp@scratch=##1\mfpicunit
    \@xconv\mfp@scratch
    \begingroup
      \ifcase\tl@hpos \advance\mfp@scratch 0.5\tb@wd % center
      \or \advance\mfp@scratch -\tlabel@sep          % right
      \else \advance\mfp@scratch \tb@wd              % left
            \advance\mfp@scratch \tlabel@sep
      \fi
      \advance\mfp@scratch \tlabel@hadj
      \ifdim \mfp@scratch>\@tlabelsright
        \@tlabelsright=\mfp@scratch
      \fi
    \endgroup
%    \end{macrocode}
%
% The following is the same as the previous calculations, but with respect
% to the leftmost extension of picture and label. Here, however, we save
% the calculated value in \cs{tb@moveright}, because it is exactly the
% amount we'll need to \cs{kern} later to position the label.
%    \begin{macrocode}
    \begingroup
      \ifcase\tl@hpos \advance\mfp@scratch -0.5\tb@wd % center
      \or \advance\mfp@scratch -\tb@wd                % right
          \advance\mfp@scratch -\tlabel@sep
      \else \advance\mfp@scratch \tlabel@sep          % left
      \fi
      \advance\mfp@scratch \tlabel@hadj
      \tb@moveright=\mfp@scratch
      \ifdim \mfp@scratch<\@tlabelsleft
        \@tlabelsleft=\mfp@scratch
      \fi
    \endgroup
%    \end{macrocode}
%
% Now we base the calculations on the vertical extent of picture and
% label. Otherwise the idea is the same, and we may increase
% \cs{@graphtop}. The macro \cs{tb@ht} means \cs{ht}\cs{@textbox} and
% \cs{tb@dp} means \cs{dp}\cs{@textbox}. Again we save the calculated
% result (in \cs{tb@raise}) for later positioning of the label.
%    \begin{macrocode}
    \mfp@scratch=##2\mfpicunit
    \@yconv\mfp@scratch
    \begingroup
      \ifcase\tl@vpos \advance\mfp@scratch \tb@totalht % bottom
        \advance\mfp@scratch \tlabel@sep
      \or \advance\mfp@scratch 0.5\tb@totalht          % center
      \or \advance\mfp@scratch -\tlabel@sep            % top
      \else \advance\mfp@scratch \tb@ht                % baseline
      \fi
      \advance\mfp@scratch \tlabel@vadj
      \tb@raise=\mfp@scratch
      \ifdim \mfp@scratch>\@tlabelstop
        \@tlabelstop=\mfp@scratch
      \fi
    \endgroup
%    \end{macrocode}
%
% Finally we compute the bottom-most extent.
%    \begin{macrocode}
    \begingroup
      \ifcase\tl@vpos \advance\mfp@scratch \tlabel@sep % bottom
      \or \advance\mfp@scratch -0.5\tb@totalht         % center
      \or \advance\mfp@scratch -\tb@totalht            % top
          \advance\mfp@scratch -\tlabel@sep
      \else \advance\mfp@scratch -\tb@dp               % baseline
      \fi
      \advance\mfp@scratch \tlabel@vadj
      \ifdim \mfp@scratch<\@tlabelsbot
        \@tlabelsbot=\mfp@scratch
      \fi
    \endgroup
%    \end{macrocode}
%
% Now we've computed the new size of \cs{@alltlabels} and we put the
% new label on top of it with the above calculated kerns.
%    \begin{macrocode}
    \global \setbox\@alltlabels=%
      \vtop{\unvbox\@alltlabels
        \vbox to 0pt{\kern-\tb@raise
          \hbox{\kern\tb@moveright\box\@textbox}\vss}}%
    \endgroup       % group begun in \tlabel
    \extraendtlabel}% End \@tlabel
%    \end{macrocode}
%
% \subsection{Surrounding the label with a path}\label{surrounding}
%
% These next macros place labels, but also define a path surrounding the
% label This allows one to clear a space for the label, create a
% background, draw a box around it, etc. They take two optional arguments.
% The first optional argument depends on the type of path being created.
% It is described below. The second one is the justification as in the
% \cs{tlabel} command. There are two mandatory arguments, the location
% (same syntax as for \cs{tlabel}) and the text. They also have
% star-forms, which create the path but doesn't place the label.
%
% All the curves are sized to just contain what I will call the
% \emph{label strip}. Imagine a rectangle that just fits around the text.
% Now extend it on all sides by the value defined with \cs{tlabelsep}.
% This rectangle is the label strip.
%
% \DescribeMacro{\tlabelrect}
% \cs{tlabelrect} creates the rectangular boundaries of the label strip by
% default. With the optional argument a rectangle with rounded corners is
% produced; the optional argument is the radius of the quarter circles used.
% These quarter circles pass through the corners of the label strip and are
% joined together with straight lines to create the rest of the rectangle.
% As a special case, the optional argument can contain the keyword
% `\texttt{roundends}' to produce a rectangle with the short sides
% replaced by a semicircle.
%
% \DescribeMacro{\tlabeloval}
% \cs{tlabeloval} produces an ellipse which, by default has the same
% aspect ratio as the label strip. It is sized to just include that label strip,
% passing through its four corners. The optional argument contains a
% numerical factor $m$ that, if greater than 1, increases the width and
% decreases the height to maintain this relationship with the label strip,
% while multiplying the width to height ratio by $m$. The default value of
% $m$ is 1.
%
% \DescribeMacro{\tlabelellipse}
% \cs{tlabelellipse} produces an ellipse, where the optional argument $a$
% is the ratio of its width to its height. The default for $a$ is 1, which
% produces a circle.
%
% \DescribeMacro{\tlabelcircle}
% To get a circle the user can \cs{tlabelellipse} without the optional
% argument, or with argument \oarg{1}. However, it makes for a more
% readable source if the command reflects the shape. \cs{tlabelcircle} is
% defined to be essentially \cs{tlabelellipse}\oarg{1}, but it first
% checks for the \texttt{*} and passes it along in front of the \oarg{1}.
%
% We implement the other three by calling \cs{tlpath} with the name of the
% curve (\texttt{rect}, \texttt{oval}, or \texttt{ellipse}) and the
% default value of the optional argument (\texttt{0}, \texttt{1}, and
% \texttt{1}, respectively) as arguments.
%    \begin{macrocode}
  \newdef\tlabelrect{\tlpath{rect}{0}}%
  \newdef\tlabeloval{\tlpath{oval}{1}}%
  \newdef\tlabelellipse{\tlpath{ellipse}{1}}%
  \newdef\tlabelcircle{%
    \mfp@ifnextchar*{\@firstoftwo{\tlabelellipse*[1]}}%
     {\tlabelellipse[1]}}%
%    \end{macrocode}
%
% We store the name of the path in \cs{mfp@name} and the default argument
% in \cs{mfp@param}, then check for a \texttt{*} and set a switch based
% on it before calling \cs{@tlpath}. The \cs{@figmacstart} must be outside
% the group so the switches it sets will survive for later commands to
% detect.
%    \begin{macrocode}
  \newdef\tlpath##1##2{\@figmacstart
    \begingroup % ended in \tlabelpath@
    \def\mfp@name{##1}\def\mfp@param{##2}%
    \mfp@ifnextchar*%
      {\@mfpswitchtrue\@firstoftwo{\@tlpath}}% gobbles the star
      {\@mfpswitchfalse\@tlpath}}%
%    \end{macrocode}
% Process first optional argument. First one has value of \cs{mfp@param}
% as default. The second one has a default justification set by the user
% with \cs{tlpathjustify} or the initial \texttt{[cc]} setting. Once these
% are processed, we check whether a parentheses follows, calling one of
% two different handlers for the location parameter(s).
%    \begin{macrocode}
  \newdef\@tlpath{\null@opt\@@tlpath}%
  \newdef\@@tlpath[##1]{%
    \edef\mfp@param{\mfp@mtsub{##1}{\mfp@param}}%
    \mfp@resetwhitespace
    \simple@opt\@@@tlpath{\tlpath@v\tlpath@h\tlpath@r}}%
  \newdef\@@@tlpath##1{\tlabeljustify{##1}%
    \mfp@setMPpos \mfp@ifnextchar({\@tlabelpath}{\@@tlabelpath}}%
%    \end{macrocode}
%
% These handlers just stuff the point into a macro and call the command
% that reads the label code. The name \cs{mfp@points} is plural (even
% though only one point is supported) because the internal command that
% places the label expects this macro. We use \cs{@firstofone} so
% that the braces will not be written to the output, but they will
% function as braces for \TeX's parameter matching.
%    \begin{macrocode}
  \newdef\@tlabelpath (##1,##2){%
    \def\mfp@points{(\@firstofone{##1},\@firstofone{##2})}%
    \@@@tlabelpath}%
  \newdef\@@tlabelpath##1{\def\mfp@points{##1}\@@@tlabelpath}%
  \newdef\@@@tlabelpath{\mfp@restorepar
    \@ifmplabels{\@makeother\#}{}\mfp@gettoks\tlabelpath@}%
%    \end{macrocode}
%
% Under \opt{mplabels} we just call on \MP{} to do everything (including
% measuring the text). Otherwise we measure the text in \TeX{} and feed
% the bounding box corners to \MF{} for making the path. Then we optionally
% place the text based on the switch previously set. All the data needed
% have already been stored in macros by previous commands in the chain.
%    \begin{macrocode}
  \newdef\tlabelpath@{%
    \@ifmplabels
     {\mfcmd{text\mfp@name x (\mfp@MPpos)\@nl(origin, % dummy parameter
        \mfp@btex{\the\mfp@toks}, \mfp@param, \mfp@points)}}%
     {\measure@textbox{\the\mfp@toks}%
      \mfcmd{text\mfp@name x (\mfp@MPpos)\@nl(\tb@ll, \tb@ur, % text bbox
        \mfp@param, \mfp@points)}}%
    \if@mfpswitch \endgroup  % *-form, no label placed
    \else    % tlabel commands contain \endgroup
      \@ifmplabels{\@@@tlabel}%
       {\@xp\@@tlabel@\mfp@points{\the\mfp@toks}}%
    \fi}%
%    \end{macrocode}
%
% Here we define the command that measures the text. It is almost a clone
% of a similar code sequence in \cs{@tlabel}, but it produces the \gbc{ll}
% and \gbc{ur} (corners of the boundingbox) that the \grafbase{} code
% needs.
%    \begin{macrocode}
  \newdef\measure@textbox##1{%
    \set@textbox{##1}%
    \edef\tb@ll{(0, -(\the\tb@dp))}%
    \edef\tb@ur{(\the\tb@wd, \the\tb@ht)}}%
%    \end{macrocode}
%
% \subsection{Placing multiple text labels}\label{multiple}
%
% \DescribeMacro{\tlabels}
% One of the more onerous things about labels in \env{mfpic} environments
% was the shear number of them. The following was intended to reduce the
% amount of typing by having to repeat only the arguments. \cs{tlabels}
% takes only one argument: any sequence of valid arguments for a \cs{tlabel}
% command, optionally separated by whitespace (but not blank lines).
%
% We begin a group, reset whitespace to normal, and call the command that
% reads the argument. That command arranges to make the main code
% self-looping by defining \cs{extraendtlabel} to call the beginning of the
% loop, then it feeds its argument to \cs{do@tlabels} followed by a
% delimiter to signal the end of the loop.
%    \begin{macrocode}
  \newdef\tlabels{%
    \begingroup % ended in \do@tlabels
      \mfp@resetwhitespace \@tlabels}%
  \newdef\@tlabels##1{\def\extraendtlabel{\do@tlabels}%
    \do@tlabels##1\mfp@delim}%
%    \end{macrocode}
%
% If \cs{do@tlabels} sees the end-of-loop delimiter it ends the group and
% gobbles the delimiter. Otherwise it calls \cs{tlabel}, which sees the
% next set of arguments, and repeats the loop.
%    \begin{macrocode}
  \newdef\do@tlabels{%
    \mfp@ifnextchar\mfp@delim{\@firstoftwo\endgroup}{\tlabel}}%
%    \end{macrocode}
%
% Labelling axes generates a lot of \cs{tlabel} commands or a single
% \cs{tlabels} command with a lot of arguments. Given that such labels
% have much in common (e.g., for the x-axis the y-coordinate and the
% justification are usually the same for all the labels) we can do still
% better at abbreviating this task.
%
% \DescribeMacro{\axislabels}
% The \cs{axislabels} command takes a mandatory argument (the axis)
% followed by an optional argument (the justification, as in the
% \cs{tlabel} command), followed by another mandatory argument, a comma
% separated list of items of the form
% \marg{\meta{label}}\meta{coordinate}. The label is placed at that
% coordinate on the given axis. This command is complicated by the fact
% that the default justification should be different for each axis (for
% example, for the y-axis it is \oarg{cr} but for the x-axis it is
% \oarg{tc}). For all of them, one of the parts is \texttt{c}, so after
% resetting whitespace we initialize them both to this and later change
% only the one that needs it.
%
% Also, one of the coordinates of a label will be given by the argument,
% while the other is the location of the axis. However, which coordinate
% is which is different for different axes. What we do is feed the
% argument to \cs{mfp@xcoord} and \cs{mfp@ycoord}. Both are initialized to
% the identity macro, but one is changed to expand to just the axis
% position.
%
% The axis position for x- and y-axis is 0. For border axes it is
% calculated by adding the border axis shift to the border coordinate.
%    \begin{macrocode}
  \newdef\axislabels##1{%
    \begingroup % ended in \do@axislabel
      \mfp@resetwhitespace \tlabeljustify{cc}%
      \let\mfp@xcoord=\@firstofone \let\mfp@ycoord=\@firstofone
      \get@axisnum{##1}\axislabels
      \ifcase\mfp@axisnum \tl@vpos=2 % x-axis -->[tc]
        \def\mfp@ycoord{0}%
      \or \tl@hpos=1  % y-axis-->[cr]
        \def\mfp@xcoord{0}
      \or \tl@hpos=1  % left  -->[cr]
        \edef\mfp@xcoord{\mfp@lshift}\mfpaddto\mfp@xcoord{#3}%
      \or \tl@vpos=2  % bottom-->[tc]
        \edef\mfp@ycoord{\mfp@bshift}\mfpaddto\mfp@ycoord{#5}%
      \or \tl@hpos=-1 % right -->[cl]
        \edef\mfp@xcoord{-\mfp@rshift}\mfpaddto\mfp@xcoord{#4}%
      \or \tl@vpos=0  % top   -->[bc]
        \edef\mfp@ycoord{-\mfp@tshift}\mfpaddto\mfp@ycoord{#6}%
      \fi
%    \end{macrocode}
%
% Now one of \cs{mfp@xcoord} or \cs{mfp@ycoord} expands to the axis
% position. We change it so that it does this while gobbling a parameter.
% And then call \cs{@axislabels}, feeding it an empty argument as the
% default optional argument.
%    \begin{macrocode}
      \ifx\@firstofone\mfp@xcoord
        \edef\mfp@ycoord####1{\mfp@ycoord}%
      \else
        \edef\mfp@xcoord####1{\mfp@xcoord}%
      \fi \null@opt\@axislabels}%
%    \end{macrocode}
%
% \cs{@axislabels} processes the contents of the optional parameter and
% calls \cs{do@axislabel} on the list in the argument. An additional item
% is added that signals the end of the loop.
%    \begin{macrocode}
  \newdef\@axislabels[##1]##2{%
    \tlabeljustify{##1}%
    \do@axislabel~ ##2,\mfp@delim}%
%    \end{macrocode}
%
% We add some code that traps the most common typos: a comma between the
% label and the coordinate, or a missing coordinate, or a doubled comma.
% It seems impossible to detect which of the first two has happened, and
% assuming the first case produces really awful results if the second is
% true. Therefore when a coordinate seems to be missing, we just lose the
% text (as we have no place to put it) and resume the loop. If the first
% case is true, the next iteration will see only the number, read one
% digit or decimal as the text and the rest as the coordinate. The output
% will be wrong, but at least \TeX{} can proceed.
%
% Above we prepended a `\verb*+~ +' so that if the coordinate is missing,
% the braces around the argument won't be lost; the space will be
% consumed in the argument processing of \cs{do@@axislabel}.
%
% The first argument should be the label, and everything from that to the
% comma is the location. In the above error cases, the second argument
% is empty
%    \begin{macrocode}
  \newdef\do@axislabel~##1,{%
    \@ifmtarg{##1}{\x@axislabel}{\do@@axislabel##1\@nil}}%
  \newdef\do@@axislabel##1##2\@nil{%
    \@ifmtarg{##2}%
     {\Mfpic@warn{Possible extra comma, missing coordinate, or
        missing\@msgbreak braces in \string\axislabels\@online.
        Skipping this label.}}%
     {\tlabel(\mfp@xcoord{##2},\mfp@ycoord{##2}){##1}}%
    \x@axislabel}%
  \newdef\x@axislabel{% check for end of list
    \mfp@ifnextchar\mfp@delim{\@firstoftwo\endgroup}{\do@axislabel~ }}%
%    \end{macrocode}
%
% \subsection{Captions}\label{captions}
%
% Captions are not added immediately by the \cs{tcaption} command. That
% command redefines \cs{@docaption} to add it, and \cs{endmfpic} executes
% \cs{@docaption}. For now, \cs{@docaption} does nothing.
%    \begin{macrocode}
  \newdef\@docaption{}%
%    \end{macrocode}
%
% \DescribeMacro{\tcaption}
% \cs{tcaption} takes an optional argument that holds two numbers,
% separated by a comma. The first number determines the maximum width of a
% one line caption. Captions larger than that multiple of the width of the
% graphic will be reset as a paragraph, whose lines have length the second
% number times the width of the graph. The defaults are \oarg{1.2,1}.
%
% \cs{@tcaption} has one mandatory argument, the caption's text. In it, the
% \cs{\bsl} command forces line breaks. This works by forcing the width to
% be greater than any reasonable setting of the maximum line width. When
% this happens, the caption is reset in a \cs{vbox} and \cs{\bsl} is
% redefined like a normal line break.
%    \begin{macrocode}
  \newdef\tcaption{\simple@opt\tcaption@{1.2, 1.0}}%
  \newdef\tcaption@##1{\@tcaption##1\mfp@delim}%
  \long\def\@tcaption##1,##2\mfp@delim##3{%
    \def\@docaption{%
      \setbox\@textbox=%
        \hbox{\def\\{\hskip\@M\p@}\mfp@restorepar
         \@tcurr##3}%
%    \end{macrocode}
%
% If the above \cs{hbox} is too wide, we re-assign \cs{@textbox} to a
% \cs{vbox} with \cs{hsize} determined by the second part of the optional
% argument, and with \cs{leftskip} and \cs{rightskip} defined according
% to the setting of \opt{centeredcaptions}.
%    \begin{macrocode}
      \@graphwd=\wd\@wholegraph
      \ifdim\tb@wd>##1\@graphwd
        \setbox\@textbox=%
        \hbox{%
          \vbox{%
            \if@mfp@latex % keep LaTeX's `\\'
            \else
              \def\\{\unskip\hbox{}\hfil\penalty-\@M\ignorespaces}%
            \fi
            \if@mfp@centcapt
              \leftskip=0pt plus 0.5fil
              \rightskip=0pt plus -0.5fil
              \parfillskip=0pt plus 1fil
            \else
              \leftskip=0pt
              \rightskip=0pt
            \fi
            \hsize=##2\@graphwd \mfp@restorepar
            \noindent\@tcurr ##3%
          }% End vbox.
        }% End hbox.
      \fi
%    \end{macrocode}
%
% Here we determine the wider of the graph or the caption, then put the
% graph and caption together by centering them in \cs{hbox}es with this
% width, stacked one atop the other with \cs{mfpiccaptionskip} (default:
% \cs{medskipamount}) in between.
%    \begin{macrocode}
      \mfp@scratch=\wd\@wholegraph
      \ifdim \mfp@scratch<\tb@wd \mfp@scratch=\tb@wd \fi
      \global\setbox\@wholegraph=%
      \vbox{\hbox to \mfp@scratch{\hss\box\@wholegraph\hss}%
        \nointerlineskip \vskip\mfpiccaptionskip
        \hbox to \mfp@scratch{\hss\box\@textbox\hss}}% End vbox.
    }% End \@docaption.
%    \ignorespaces
  }% End \@tcaption.
%  \ignorespaces
}% End of \@mfpic
%    \end{macrocode}
%
%
% \section{Placing the picture: \cs{endmfpic}}\label{endmfpic}
%
% By the time \cs{endmfpic} is reached, the \MF{} code for the figure has
% all been written to the output file. The labels have all been
% accumulated and arrangements have been made to add the caption.
%
% \DescribeMacro{\endmfpic}
% Under \opt{metapost}, write \cs{endgroup} to match beginning written
% by \cs{mfpic} Then write the \cs{grafbase} command \gbc{endmfpic},
% followed by a comment telling which figure number it is, and the line
% number in the \TeX{} source where the \cs{endmfpic} occurred.
%    \begin{macrocode}
\mfp@DBlog{Definition of closure of mfpic environment.}%
\newdef\endmfpic{%
  \mfsrc{\mfp@ifmpost{\@nl verbatimtex \endgroup\space etex;}{}\@nl
    endmfpic;\mf@p (\number\mfp@count) \space\@mfplineno.\@nl
    \mf@p\mf@d\mf@d\mf@d\@nl}%
  \ifmfpicdebug\wlog{}\wlog{Mfpic: ENTERED endmfpic.}\wlog{}\fi
%    \end{macrocode}
% The code to load and place the box is skipped if figure shipping was
% turned off.
%    \begin{macrocode}
  \if@shipping %
%    \end{macrocode}
%
% \subsection{Loading and measuring the graphic}\label{loading}
%
% Now we load the graphic. It would be at this point that we could add a
% \cs{write18} to process the figure on-the-fly. Of course that would
% require re-initializing the output file with each graphic (i.e., the
% equivalent of issuing \cs{opengraphsfile} at every \cs{mfpic} and
% \cs{closegraphsfile} at every \cs{endmfpic}.)
%    \begin{macrocode}
    \global\setbox\@wholegraph=%
    \vbox{%
%    \end{macrocode}
%
% If draft mode has been detected or set by the user, we just make a box
% of the size specified with the figure number inside it.
%    \begin{macrocode}
      \ifmfpicdraft
        \vbox to \@graphtop{\vss
          \hbox to \@graphwd{\kern2pt\tt\#\number\mfp@count\hss}%
            \kern2pt}%
      \else
%    \end{macrocode}
%
% The \opt{truebbox} option works at the \MP{} level. Without it the
% height of the EPS bounding box will actually be the calculated value
% of \cs{@graphtop} (but increased by up to \texttt{2bp} due to rounding).
% With it, the box will be its natural height. In either case, the actual
% height is what we use in the \MP{} case. For \MF{} we use the nominal
% height calculated in \cs{mfpic}.
%    \begin{macrocode}
      \mfp@ifmpost{\vbox}{\vbox to \@graphtop}%
       {\vss
%    \end{macrocode}
%
% \cs{@graphfilename} holds the name of the \MP{} output figure. (It will be
% ignored by the \opt{metafont} option.) We test if the file exists before
% doing the graphic inclusion because of the large number of confusing error
% messages many graphic inclusion packages generate otherwise. When absent
% we substitute the figure number for \cs{@setmfpicgraphic}. When present,
% and if in \LaTeXe, we arrange for the current numerical extension to be
% accepted as an EPS or MPS file by the \cs{includegraphics} command of the
% graphics package.
%    \begin{macrocode}
        \edef\@graphfilename{\setfilename{\mfp@filename}%
          {\number\mfp@count}}%
        \mfp@ifmpost
         {\openin\mfp@graph=\@graphfilename\relax
          \ifeof\mfp@graph
            \Mfpic@msg{No graph file: \@graphfilename\space.}%
            \def\@setmfpicgraphic##1{\raise2pt\hbox{\kern2pt\tt ##1}}%
            \closein\mfp@graph
          \else\if@mfp@latexe
            \@namedef{Gin@rule@.\number\mfp@count}##1{%
              {\mfp@Gtype}{.\number\mfp@count}{##1}}%
          \fi\fi}{}%
%    \end{macrocode}
%
% We put the graphic in an \cs{hbox} of the required width and close off
% the boxes.
%    \begin{macrocode}
        \mfp@ifmpost{\hbox}{\hbox to \@graphwd}%
          {\@xp\@setmfpicgraphic\@xp{\@graphfilename}\hss}% End hbox.
        \kern0pt
        }% End vbox
      \fi
    }%% End vbox (\setbox\@wholegraph)
%    \end{macrocode}
%
% We change the horizontal and vertical dimensions under \opt{metapost} in
% case \opt{truebbox} was in effect, but also because they are almost always
% rounded up to whole numbers of \texttt{bp} and therefore, even without
% \opt{truebbox} the calculated values needn't be correct.
%    \begin{macrocode}
    \mfp@ifmpost
     {\@graphright=\wd\@wholegraph
      \@graphtop=\ht\@wholegraph
      \@graphwd=\@graphright}{}%
    \ifmfpicdebug
      \wlog{Mfpic: graphleft  = \the\@graphleft}%
      \wlog{Mfpic: graphright = \the\@graphright}%
      \wlog{Mfpic: graphtop   = \the\@graphtop}%
      \wlog{Mfpic: graphbot   = \the\@graphbot}%
      \wlog{Mfpic: graphwd    = \the\wd\@wholegraph}%
      \wlog{Mfpic: graphht    = \the\ht\@wholegraph}%
      \wlog{Mfpic: graphdp    = \the\dp\@wholegraph}%
      \wlog{}%
    \fi
%    \end{macrocode}
%
% \subsection{Adding labels and caption}\label{addlabel}
%
% We now add the box \cs{@alltlabels} onto the graph box. The box should
% still have 0pt height and depth, so we can just stick it under the graph
% box. But first we have to adjust for \cs{mfpicllx} and \cs{mfpiclly}
% which can only be known after the graphics inclusion. We reset the box
% \cs{@alltlabels} so its contents are shifted by these values. We only
% need to do this if labels have have actually been added. The signal that
% this has happened is that the label dimensions are no longer
% $\pm$\cs{maxdimen}.
%    \begin{macrocode}
    \ifmfpicdebug
      \wlog{Mfpic: tlabelsleft  = \the\@tlabelsleft}%
      \wlog{Mfpic: tlabelsright = \the\@tlabelsright}%
      \wlog{Mfpic: tlabelstop   = \the\@tlabelstop}%
      \wlog{Mfpic: tlabelsbot   = \the\@tlabelsbot}%
      \wlog{}%
    \fi
    \ifdim\@tlabelsleft < \maxdimen
      \setbox\@alltlabels\vtop to 0pt{%
        \kern \mfpiclly bp
        \moveleft \mfpicllx bp \box\@alltlabels
        \vss}%
%    \end{macrocode}
% Then we adjust \cs{@tlabelsleft}, etc. for the boundingbox offset.
%    \begin{macrocode}
      \mfp@scratch\@tlabelsleft
      \advance\mfp@scratch-\mfpicllx bp
      \ifdim\mfp@scratch<\@graphleft
        \@graphleft\mfp@scratch
      \fi
      \mfp@scratch\@tlabelsright
      \advance\mfp@scratch-\mfpicllx bp
      \ifdim\mfp@scratch>\@graphright
        \@graphright\mfp@scratch
      \fi
      \mfp@scratch\@tlabelstop
      \advance\mfp@scratch-\mfpiclly bp
      \ifdim\mfp@scratch>\@graphtop
        \@graphtop\mfp@scratch
      \fi
      \mfp@scratch\@tlabelsbot
      \advance\mfp@scratch-\mfpiclly bp
      \ifdim\mfp@scratch<\@graphbot
        \@graphbot\mfp@scratch
      \fi
      \setbox\@wholegraph=\vtop{%
        \unvbox\@wholegraph\box\@alltlabels}%
    \fi
%    \end{macrocode}
%
% The method for putting labels in \cs{@alltlabels} does not add any width
% on the left, nor any height to the top or depth to the bottom of that box
% (that \TeX{} can detect), but we have saved their values and now we can
% use them. For example, if \cs{@graphleft} is negative after the above,
% then a label sticks out to the left, but \TeX{} thinks it has no width.
% Therefore put \cs{kern}\texttt{-}\cs{@graphleft} to move the graph
% rightward. The height and depth are taken care of by putting it in
% \cs{vbox} with the calculated total height and moving the graph upward
% with \cs{kern}\texttt{-}\cs{@graphbot}. The rightward extensions do get
% detected by \TeX.
%    \begin{macrocode}
    \ifmfpicdebug
      \wlog{Mfpic: tlabelsleft  = \the\@tlabelsleft}%
      \wlog{Mfpic: tlabelsright = \the\@tlabelsright}%
      \wlog{Mfpic: tlabelstop   = \the\@tlabelstop}%
      \wlog{Mfpic: tlabelsbot   = \the\@tlabelsbot}%
      \wlog{}%
    \fi
    \mfp@scratch=\@graphtop
    \advance\mfp@scratch by -\@graphbot
    \global \setbox\@wholegraph=%
    \vbox to \mfp@scratch{\vss
      \hbox{\kern-\@graphleft\box\@wholegraph}%
      \kern-\@graphbot}% End vbox.
%    \end{macrocode}
%
% Now add the caption, then set the parameters \cs{mfpicheight} and
% \cs{mfpicwidth} for user to examine. The debug info now should show
% graphwd${}={}$graphright${}-{}$graphleft,
% graphht${}={}$graphtop${}-{}$graphbot, and graphdp${}= 0$.
%    \begin{macrocode}
    \ifmfpicdebug
      \wlog{Mfpic: graphleft  = \the\@graphleft}%
      \wlog{Mfpic: graphright = \the\@graphright}%
      \wlog{Mfpic: graphtop   = \the\@graphtop}%
      \wlog{Mfpic: graphbot   = \the\@graphbot}%
      \wlog{Mfpic: graphwd    = \the\wd\@wholegraph}%
      \wlog{Mfpic: graphht    = \the\ht\@wholegraph}%
      \wlog{Mfpic: graphdp    = \the\dp\@wholegraph}%
      \wlog{}%
    \fi
    \@docaption
    \global\mfpicheight\ht\@wholegraph
    \global\mfpicwidth\wd\@wholegraph
    \ifmfpicdebug
      \wlog{Mfpic: graphleft  = \the\@graphleft}%
      \wlog{Mfpic: graphright = \the\@graphright}%
      \wlog{Mfpic: graphtop   = \the\@graphtop}%
      \wlog{Mfpic: graphbot   = \the\@graphbot}%
      \wlog{Mfpic: graphwd    = \the\wd\@wholegraph}%
      \wlog{Mfpic: graphht    = \the\ht\@wholegraph}%
      \wlog{Mfpic: graphdp    = \the\dp\@wholegraph}%
      \wlog{}%
    \fi
%    \end{macrocode}
%
% \subsection{Placing the graphic}\label{placing}
%
% Add a frame around the box \cs{@wholegraph} in draft mode (so its size
% can be seen) since there is practically nothing in it except the picture
% number
%    \begin{macrocode}
    \ifmfpicdraft
      \setbox\@wholegraph=%
        \hbox{\@mfpframed{-\mfpframethickness}{\box\@wholegraph}}%
    \fi
%    \end{macrocode}
%
% If the \cs{savepic} command occurred prior to this, then \cs{s@vemfpic}
% is defined and we save this picture in the box named in that
% \cs{savepic} command and stored in the macro \cs{s@vemfpic}. Otherwise,
% \cs{s@vemfpic} is undefined, and we place the picture (\cs{@wholegraph})
% in the document. Afterward, we undefine \cs{s@vemfpic}.
%    \begin{macrocode}
    \mfp@ifdefined\s@vemfpic
      {\global\setbox\s@vemfpic=\box\@wholegraph}%
      {\leavevmode\box\@wholegraph}%
    \global\let\s@vemfpic\UndEfInEd
%    \end{macrocode}
%
% Now we advance the figure count, end the group started by the \cs{mfpic}
% command, restore the values of extra font dimensions that were saved,
% then arrange for spaces to be ignored in case the syntax
% \cs{begin}\marg{mfpic}$\ldots$\cs{end}\marg{mfpic} was used.
%    \begin{macrocode}
    \global \advance\mfp@count1
  \fi % end of \if@shipping
  \endgroup % Begun near start of \@mfpic
  \restore@mfpicdimens
  \if@mfp@latex
    \def\mfptmp@a{mfpic}%
    \ifx\mfptmp@a\@currenvir
      \@ignoretrue% so \endmfpic and \end{mfpic} have the same effect.
    \fi
  \fi
  \ignorespaces
}%
%    \end{macrocode}
%
%
% \section{Additional features}\label{additional}
%
% \subsection{Saving a copy of the picture}\label{saving}
%
% \DescribeMacro{\newsavepic}
% One saves a picture by first allocating a save box with
% \cs{newsavepic}\marg{\cs{mypic}}, then saying
% \cs{savepic}\marg{\cs{mypic}} beforehand. The \cs{endmfpic} code
% detects that this has been done and saves the picture in \cs{mypic}.
% It can be placed with \cs{usepic}{\cs{mypic}}.
%
% \cs{newsavepic} is just a clone of \LaTeX's \cs{newsavebox}. The one
% argument is a control sequence.
%    \begin{macrocode}
\newdef\newsavepic#1{%
  \if@mfp@latex \newsavebox{#1}%
  \else
    \mfp@ifdefined{#1}%
     {\mfp@errmsg
       {Command \string #1 already defined.}%
       {You have used \newsavepic with an already defined or an^^J%
        improper control sequence. Replace #1 with another name.^^J%
        If you proceed, \newsavepic will be ignored.}}%
     {\csname newbox\endcsname#1}%
  \fi}%
\newlet\newpic=\newsavepic % compatibility
%    \end{macrocode}
%
% \DescribeMacro{\savepic}
% All \cs{savepic} really does is define \cs{s@vepic} to its argument,
% which should be a control sequence defined by \cs{newsavepic} (or
% \cs{newbox}).
%    \begin{macrocode}
\newdef\savepic#1{\relax
   \mfp@ifdefined{#1}{\gdef\s@vemfpic{#1}}%
   {\mfp@errmsg{Box \string#1 undefined.}%
    {You tried to save a picture in a box which had not been^^J%
     previously allocated. Use \newsavepic to allocate a box.}}}%
%    \end{macrocode}
%
% \DescribeMacro{\usepic}
% \cs{usepic} takes one argument, a control sequence that should have
% been previously used in a \cs{savepic} comamnd. It just places the box
% with the primitive \cs{copy} command.
%    \begin{macrocode}
\newdef\usepic#1{\leavevmode \copy#1\relax}%
%    \end{macrocode}
%
% \subsection{Putting a frame around it}\label{frame}
%
% This is essentially code I wrote years ago to have a framing command
% that had two properties not enjoyed by come example `\cs{boxit}' commands
% for plain\TeX: It should have a baseline the same as the baseline of the
% contents, and it should work as an environment, not by reading an
% argument (so verbatim material could be included).
%
% \DescribeMacro{\mfpframed}
% \DescribeMacro{\mfpframe}
% \cs{mfpframed} takes an optional argument (the separation) and a
% mandatory argument, the contents. \cs{mfpframe}$\ldots$\cs{endmfpframe}
% is an environment and \cs{mfpframe} also takes the separation as an
% optional argument.
%
% \DescribeMacro{\framed}
% \cs{framed} is a common command (\ConTeXt{} has one, a few packages also
% define it), therefore we only define it if it is not already defined.
%    \begin{macrocode}
\newdef\mfpframed{\simple@opt\@mfpframed\mfpframesep}%
\newdef\mfpframe{\simple@opt\@mfpframe\mfpframesep}%
\newdef\@mfpframed#1#2{\@mfpframe{#1}#2\endmfpframe}%
\newdef\@mfpframe#1{%
  \leavevmode\hbox\bgroup
    \mfpframesep#1\relax
    \vrule width\mfpframethickness
    \vtop\bgroup
      \vbox\bgroup
        \hrule height\mfpframethickness
        \kern\mfpframesep
        \hbox\bgroup \kern\mfpframesep \ignorespaces}%
\newdef\endmfpframe{\unskip
          \kern\mfpframesep
        \egroup % end hbox
      \egroup % end vbox
      \kern\mfpframesep
      \hrule height\mfpframethickness
    \egroup % end vtop
    \vrule width\mfpframethickness
  \egroup}% end hbox
\mfp@ifdefined\framed{}{\newlet\framed=\mfpframed}%
%    \end{macrocode}
%
% \subsection{Adding \mfc{verbatimtex} to the \file{.mp}
% file}\label{verbatimtex}
%
% \DescribeMacro{mfpverbtex}
% This is a user level utility for putting some \mfc{verbatimtex} material
% in the output file for \MP. We allow the user to do this even before
% \cs{opengraphsfile} by storing it in a token register and setting a flag
% for that command to test.
%    \begin{macrocode}
\newif\if@mfp@verbtex
\def\mfpverbtex{%
%    \end{macrocode}
%
% We start a group, make sure lines will be preserved in writing the
% material, make sure that \texttt{\#} characters will not be doubled by
% changing its category, then continue after loading the code into the
% token register \cs{mfp@verbtex}.
%    \begin{macrocode}
  \begingroup \preservelines \@makeother\#%
    \afterassignment\mfp@writetex\global\mfp@verbtex=}%
%    \end{macrocode}
%
% We end the group and then either set the switch to tell
% \cs{opengraphsfile} that the material is ready, or we write it to the
% output, between the commands \gbc{verbatimtex} and \cs{etex}.
%    \begin{macrocode}
\def\mfp@writetex{%
  \endgroup
  \@ifmfpfileisopen
   {\mfp@ifmpost
      {\mfsrc{verbatimtex}\mfsrc{\the\mfp@verbtex}\mfcmd{etex}}%
      {\noMP@error{verbatimtex}}%
    \global\@mfp@verbtexfalse\mfp@verbtex{}}%
   {\global\@mfp@verbtextrue}}%
%    \end{macrocode}
%
%
% \section{Finale}\label{finale}
%
% Set the default starting graphic number.
%    \begin{macrocode}
\global\mfp@count=1 % 1 because we now advance it in \endmfpic.
%    \end{macrocode}
%
% Create a system for adding patches in the file \file{mfppatch.tex},
% and for user defaults in a file \file{mfpic.usr}.
%    \begin{macrocode}
\newdef\MFPICinput#1{%
  \immediate\openin\mfp@graph=#1
  \ifeof\mfp@graph
    \immediate\closein\mfp@graph
  \else
    \immediate\closein\mfp@graph
    \input #1
  \fi}%
\MFPICinput{mfppatch.tex}%
%    \end{macrocode}
%
% Restore the meaning of \cs{+}, and of the \cs{newlinechar}, and execute
% the command that restores all the saved category codes.
%    \begin{macrocode}
\mfp@DBlog{Punctuation, etc., will revert to old catcodes now.}%
\let\+\mfpsaveplus
\restorenewlinechar
\MFPicpackagE%
\MFPICinput{mfpic.usr}%
%</tex>
%    \end{macrocode}
%
% Generate a (far too) simple wrapper for \LaTeX.
%    \begin{macrocode}
%<*sty>
\input mfpic.tex\relax
%</sty>
%    \end{macrocode}
%\clearpage
%\Finale
