summaryrefslogtreecommitdiff
path: root/graphics/mfpic/source/mfpic.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/mfpic/source/mfpic.dtx')
-rw-r--r--graphics/mfpic/source/mfpic.dtx6735
1 files changed, 6735 insertions, 0 deletions
diff --git a/graphics/mfpic/source/mfpic.dtx b/graphics/mfpic/source/mfpic.dtx
new file mode 100644
index 0000000000..586d051e18
--- /dev/null
+++ b/graphics/mfpic/source/mfpic.dtx
@@ -0,0 +1,6735 @@
+% \iffalse
+% File: mfpic.dtx
+% A part of mfpic 1.10 2012/12/03
+%
+% -------------------------------------------------------------------
+%
+% Copyright 2002--2012, Daniel H. Luecking
+%
+% Mfpic may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License, either version 1.3c 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.3c or later is part of all distributions of LaTeX version
+% 2008/12/01 or later.
+%
+% Mfpic has maintenance status "author-maintained". The Current Maintainer
+% is Daniel H. Luecking. There are several Base Interpreters: plain TeX, LaTeX,
+% plain Metafont and plain MetaPost.
+%
+%<*driver>
+\ProvidesFile{mfpic.dtx}
+%</driver>
+%<sty>\ProvidesPackage{mfpic}
+%<*sty>
+ [2012/12/03 v1.10. Macros for drawing with Metafont/MetaPost.]%
+%</sty>
+%<*driver>
+\documentclass{ltxdoc}
+
+\addtolength{\textwidth}{.5878pt}
+
+\def\mytt{\upshape\mdseries\ttfamily}
+\renewcommand\marg[1]{{\mytt\{#1\}}}
+\renewcommand\oarg[1]{{\mytt [#1]}}
+\renewcommand\parg[1]{{\mytt (#1)}}
+\renewcommand \arg[1]{{\mytt \##1}}
+\renewcommand\#{\char`\#\relax}
+\renewcommand{\meta}[1]{{$\langle$\rmfamily\itshape#1\/$\rangle$}}
+\newcommand{\mmarg}[1]{\marg{\meta{#1}}}
+\DeclareRobustCommand\cs[1]{{\mytt\char`\\#1}}
+\def\prog#1{{\mdseries\scshape #1}}
+\def\grafbase{\prog{grafbase}}
+\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
+\catcode`\_=12
+\renewcommand\{{\char`\{}
+\renewcommand\}{\char`\}}
+\renewcommand\|{${}\mathrel{|}{}$}
+
+\makeatletter
+\let\HD@SetMacroIndent\@gobble
+\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\usage#1{\textrm{#1}}
+\def\index@prologue{\section*{Index}\markboth{Index}{Index}%
+ Numbers refer to the page where the corresponding entry is described.
+}
+\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{5188}
+% \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 \~}
+%
+% \GetFileInfo{mfpic.dtx}
+% \maketitle
+%
+% \begin{abstract}
+% An environment, \env{mfpic}, is defined, within which commands can be
+% used for drawing pictures, especially of mathematical objects and
+% functions. These commands actually write code to an external file to 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 \mfpic{} source code. The user manual for
+% \mfpic{} is distributed as \file{mfpic-doc.pdf}, produced from
+% \file{mfpic-doc.tex}. An introductory guide to \mfpic{} is available
+% in \file{mfpguide.pdf}, produced from \file{mfpguide.tex}
+% \end{abstract}
+%
+% \StopEventually{\PrintIndex}
+% \tableofcontents
+%
+%
+%
+% \section{Introductory setup}\label{intro}
+%
+% \Mfpic{} is designed to work with plain \TeX, \LaTeX, \pdfTeX, and
+% \pdfLaTeX. I consistently use it with eplain and AMS\LaTeX{}
+% without problems. Users have reported succesfully using it with \AmSTeX.
+% It has \emph{not} been successfully used with \ConTeXt.
+%
+% \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}).
+%
+% We keep track of version numbers here. We store the version and date
+% in macros and later we write this 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>
+\ifx\mfpfileversion\UndEfInEd\else\expandafter\endinput\fi%
+{%
+ \catcode\lq\.12 \catcode\lq\/12%
+ \gdef\mfpfileversion{1.10}%
+ \gdef\mfpfiledate{2012/12/03}%
+ \gdef\mfpicversion{110}%
+}%
+% \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}
+%
+% We now get rid of unusually catcoded punctuation, space and EOL.
+% We assume that letters, numbers, `\texttt\bsl', `\texttt\{', `\texttt\}',
+% `\texttt\#' and `\texttt\%' have the usual categories. However, 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 of this code should be added in \cs{mfpic} or \cs{mfsrc}
+% command, too.
+% \begin{macrocode}
+{%
+ \catcode61\space12\relax% 61=equal sign
+ \catcode32=10\relax% 32=space
+ \catcode13=5 % 13=EOL
+ \catcode96=12 % 96=left quote
+ \catcode`\@=11
+ \gdef\MFPsavecodes{%
+ \edef\mfp@restoreNLC{\newlinechar\number\newlinechar\relax}%
+ \edef\mfp@restoreELC{\endlinechar\number\endlinechar\relax}%
+ \edef\mfp@restoreSPA{\catcode32=\number\catcode32\relax}%
+ \edef\mfp@restoreEOL{\catcode13=\number\catcode13\relax}%
+ \edef\mfp@restoreALL{\mfp@restorecode{=}\mfp@restorecode{@}%
+ \mfp@restorecode{$}\mfp@restorecode{:}\mfp@restorecode{;}%
+ \mfp@restorecode{.}\mfp@restorecode{,}\mfp@restorecode{!}%
+ \mfp@restorecode{?}\mfp@restorecode{(}\mfp@restorecode{)}%
+ \mfp@restorecode{[}\mfp@restorecode{]}\mfp@restorecode{<}%
+ \mfp@restorecode{>}\mfp@restorecode{*}\mfp@restorecode{/}%
+ \mfp@restorecode{+}\mfp@restorecode{-}\mfp@restorecode{"}%
+ \mfp@restorecode{'}\mfp@restorecode{_}\mfp@restorecode{`}%
+ \mfp@restoreEOL\mfp@restoreSPA\catcode10=\number\catcode10
+ \mfp@restoreNLC\mfp@restoreELC}}%
+ \gdef\mfp@restorecode#1{\catcode`\string#1=\number\catcode`#1\relax}%
+ \ifx\@makeother\UndEfInEd \gdef\@makeother#1{\catcode`#1=12\relax}\fi
+ \gdef\MFPsanitize{\endlinechar13 \newlinechar10
+ \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\@}%
+}%
+\MFPsavecodes\MFPsanitize
+\catcode`@11
+\chardef\mfp@ctrlJ 10 \chardef\mfp@ctrlM 13
+% \end{macrocode}
+%
+% \cs{MFPsavecodes} saves a bunch of things that must have (mostly)
+% normal settings. \cs{mfp@restoreALL} will be invoked at the end of the
+% file to restore all the values.
+%
+% \cs{MFPsanitize} sets (almost) everything to normal. It can be used to
+% redo these 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.
+%
+%
+% \subsection{Debugging and messages}\label{debug}
+%
+% \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.
+% \DescribeMacro{\ifmfpicdebug}
+% The switch \cs {ifmfpicdebug} is normally set to true if the user loads
+% \mfpic{} with the \opt{debug} option, or sets it directly with
+% \cs{mfpicdebugtrue} after loading.
+% \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}
+%
+% We need to write 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. The basic \cs{mfp@msg} defines
+% \cs{@nl} to place the \cs{newlinechar}, for multiline messages. We
+% also define \cs{@nl} in \cs{mfp@write} for new lines in writing to a
+% file. We do not define it at all at the outer level.
+% \begin{macrocode}
+\def\mfp@msg#1{%
+ {\newlinechar\mfp@ctrlJ\def\@nl{^^J}\immediate\write16{#1}}}%
+\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{\@nl Mfpic 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{mfp@lineno} is
+% for information written into the output file.
+% \begin{macrocode}
+\def\mfp@lineno{line \number\inputlineno\space in the TeX source}%
+% \end{macrocode}
+%
+%
+% \subsection{Detecting the format}\label{format}
+%
+% To detect its environment, \mfpic{} needs to test whether certain
+% commands are defined. We usually use the positive version
+% \cs{mfp@ifdefined}. The \cs{@xp} in it is used to `expand away' the rest
+% of a conditional. \cs{@XP} does this from two levels deep in a
+% conditional. Since our check uses \cs{@firstoftwo} and
+% \cs{@secondoftwo}, we cannot use it to check \emph{their} existence (but
+% we could use other means).
+%
+% \cs{mfp@ifundefined} checks its argument to see if it is defined.
+% If so, it gobbles all code up to \cs{mfp@enddef}. Otherwise that code is
+% executed. This avoids reading code prematurely (category code changes).
+%
+% We also copy \LaTeX's \cs{@ifundefined} since we have at least five
+% places where we need to supply the name without a backslash.
+% \begin{macrocode}
+\let\@xp\expandafter
+\def\@XP{\@xp\@xp\@xp}%
+\long\def\@firstoftwo#1#2{#1}%
+\long\def\@secondoftwo#1#2{#2}%
+\def\mfp@ifdefined#1{%
+ \ifx#1\UndEfInEd \@xp\@secondoftwo
+ \else\ifx#1\relax \@XP\@secondoftwo
+ \else \@XP\@firstoftwo
+ \fi\fi}%
+\mfp@ifdefined\@empty{}{\def\@empty{}}%
+\mfp@ifdefined\@gobble{}{\def\@gobble#1{}}%
+\mfp@ifdefined\@firstofone{}{\long\def\@firstofone#1{#1}}%
+\mfp@ifdefined\on@line{}%
+ {\def\on@line{ on input line \number\inputlineno}}%
+\let\mfp@enddef\@empty
+\long\def\mfp@gobbledef#1\mfp@enddef{}%
+\def\mfp@ifundefined#1{\mfp@ifdefined#1\mfp@gobbledef\@empty}%
+\mfp@ifundefined\@ifundefined
+ \def\@ifundefined#1{%
+ \@xp\ifx\csname #1\endcsname\relax \@xp\@firstoftwo
+ \else \@xp\@secondoftwo
+ \fi}%
+\mfp@enddef
+% \end{macrocode}
+%
+% The following might be useful in patching things or adding to
+% \cs{mfp@additions}.
+% \begin{macrocode}
+\mfp@ifundefined\g@addto@macro
+ \long\def\g@addto@macro#1#2{%
+ \begingroup
+ \toks@\@xp{#1#2}%
+ \xdef#1{\the\toks@}%
+ \endgroup}%
+\mfp@enddef
+\mfp@ifundefined\g@prependto@macro
+ \long\def\g@prependto@macro#1#2{%
+ \begingroup
+ \toks@{#2}\toks2\@xp{#1}%
+ \xdef#1{\the\toks@\the\toks2}%
+ \endgroup}%
+\mfp@enddef
+% \end{macrocode}
+%
+% We test for LaTeX. We assume plain\TeX{}, or something compatible,
+% except in a few places where LaTeX{} does thing differently. \Mfpic{}
+% didn't work in \ConTeXt{} the last few times I tried.
+%
+% Here we see if \cs{documentstyle} is defined, and then make sure
+% we are not in \AmSTeX{}. We used to detect \AmSTeX{} by checking
+% \cs{fmtname}. This leads to problems if some other format inputs
+% \file{amstex.tex} and redefined \cs{fmtname}. Thus we will now check
+% \cs{amstexloaded@}. Unfortunately, \file{amstex.tex} sets it equal to
+% \cs{relax}, which is much too easy to be the result of some other
+% attempt to check it. Thus, we add an additional check for
+% \cs{NoBlackBoxes}.
+% \begin{macrocode}
+\newif\ifmfp@latex \mfp@latexfalse
+\mfp@ifdefined\documentstyle
+ {\ifx \amstexloaded@\relax % amstex loaded, or a bad check for it
+ \ifx\NoBlackBoxes\UndEfInEd % amstex not loaded
+ \mfp@DBlog{LaTeX detected.}\mfp@latextrue
+ \else % most likely amstex loaded
+ \mfp@DBlog{AmS-TeX detected.}%
+ \fi
+ \else % amstex not loaded
+ \mfp@DBlog{LaTeX detected.}\mfp@latextrue
+ \fi}%
+ {\mfp@DBlog{Neither LaTeX nor AmS-TeX detected.}}%
+% \end{macrocode}
+%
+% We are in \LaTeXe{}, as opposed to \LaTeX2.09, if \cs{documentclass}
+% is defined. The \file{mfpic.sty} now assumes \LaTeXe{}. It might still
+% be possible to use \LaTeX{}2.09 with \cs{input mfpic}, but I don't
+% care enough to test it.
+% \begin{macrocode}
+\newif\ifmfp@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\ifmfp@pdf \mfp@pdffalse
+\mfp@ifdefined\pdfoutput
+ {\mfp@DBlog{PdfTeX detected...}%
+ \ifnum\pdfoutput<1 \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}
+\ifmfp@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}
+\mfp@ifdefined\@namedef{}%
+ {\def\@namedef#1{\@xp\def\csname #1\endcsname}}%
+\mfp@ifdefined\@namelet{}%
+ {\def\@namelet#1{\@xp\let\csname #1\endcsname}}%
+\mfp@ifdefined\@nameuse{}%
+ {\def\@nameuse#1{\csname #1\endcsname}}%
+\mfp@ifundefined\@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}%
+\mfp@enddef
+% \end{macrocode}
+%
+%
+% \subsection{Warning if commands are already defined}
+%
+% 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.}%
+\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}
+%
+% 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
+\def\newdef#1{\mfp@testdef#1\def#1}%
+\newdef\newlet#1{\mfp@testdef#1\let#1}%
+% \end{macrocode}
+%
+%
+% \subsection{Error messages and warnings}
+%
+% If one tries to switch on \MP{} support after the output file has been
+% set up, we issue this error message.
+% \begin{macrocode}
+\newdef\mfp@useMP@error{%
+ \mfp@errmsg {Command \mfp@b usemetapost 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}
+%
+% This one is for macros that need an output file to write to, but are
+% called before one has been opened.
+% \begin{macrocode}
+\def\mfp@nooutput@error#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}
+%
+% Some options and commands require the \opt{metapost} option be in
+% effect. We define an error message for the case where it is not in
+% effect. Rarely, we need a similar warning for the \opt{metafont}
+% option.
+% \begin{macrocode}
+\newdef\mfp@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.}}%
+\newdef\mfp@noMF@warn#1{%
+ \Mfpic@warn
+ {Metapost does not support \string#1, it will be ignored.}}%
+% \end{macrocode}
+%
+% This next is like \cs{mfp@useMP@error}, but it is not so specific.
+% It is for other options that also need to be issued before
+% \cs{opengraphsfile}.
+% \begin{macrocode}
+\def\mfp@afteropen@error#1{%
+ \mfp@errmsg{Improper use of command \string#1\on@line}%
+ {You must issue the command #1 prior to \opengraphsfile.
+ It will be ignored now.}}%
+% \end{macrocode}
+%
+% \cs{mfp@end} is defined to be an error message, but that is for
+% debugging purposes. It's actual use is to mark the end when we need to
+% process a list of tokens. The code should simply detect and remove it,
+% and it should never be expanded, so seeing the error message indicates
+% a coding error by me, or incorrect syntax by a user.
+% \begin{macrocode}
+\newdef\mfp@end{%
+ \mfp@errmsg {Unexpected token \string\mfp@end}%
+ {If you get this message but did not misuse the command^^J%
+ \mfp@end, it could mean you have unbalanced braces.}}%
+% \end{macrocode}
+%
+% The next two are error messages for missing or empty data files.
+% \begin{macrocode}
+\newdef\mfp@nofile@error#1{%
+ \mfp@errmsg{No data file: #1}%
+ {The data file you tried to plot was not found.}}%
+\newdef\mfp@nodata@error#1{%
+ \mfp@errmsg{Empty data file: #1}%
+ {The data file contained only empty lines and comments.}}%
+% \end{macrocode}
+%
+% This message is issued when the \cs{tlabeljustify} command (see
+% subsection~\ref{labelsettings}) is issued with an invalid parameter.
+% \begin{macrocode}
+\newdef\mfp@justify@error{%
+ \mfp@errmsg{Invalid justification parameter for text label}%
+ {The optional argument for an mfpic text label must be^^J%
+ one of B, b, c or t, followed by^^J%
+ one of l, r or c, optionally followed by an angle.}}%
+% \end{macrocode}
+%
+% This is the default meaning assigned to \cs{@nountil} at the
+% beginning of \cs{mfploop}. Use of \cs{mfpuntil} cancels the
+% warning, which is otherwise issued by \cs{mfpendloop}.
+% \begin{macrocode}
+\newdef\mfp@untilwarn{%
+ \Mfpic@warn{\mfp@b mfploop without \string\mfpuntil!\@nl}}%
+% \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}
+\newlet\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 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. For similar reasons, we clear the \opt{mplabels}
+% option.
+%
+% \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.
+%
+% Since \cs{mfpicllx} and \cs{mfpiclly} are globally defined by graphic
+% inclusion, we reset then to 0, in case \opt{metafont} and \opt{metapost}
+% options are mixed in one file.
+% \begin{macrocode}
+\newdef\usemetafont{\mfp@mpostfalse
+ \nomplabels
+ \def\preparemfpicgraphic##1{}%
+ \def\setmfpicgraphic##1{\mfp@graphfont\char\mfp@count}%
+ \def\getmfpicoffset##1{\gdef\mfpicllx{0}\gdef\mfpiclly{0}}}%
+% \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\mfp@ifopengraphsfile{\mfp@ifdefined\mfp@filename}%
+% \end{macrocode}
+%
+% \DescribeMacro{\mfmode}
+% For use with the \opt{metafont} option, we allow the user to set the
+% \MF{} mode. Example: \verb$\mfmode{ljfour}$
+%
+% \DescribeMacro{\mfresolution}
+% If modes are too esoteric, the user can at least set the resolution.
+% This should be a pure number representing dots per inch. Example:
+% \verb$\mfresolution{600}$
+% \begin{macrocode}
+\newdef\mfmode#1{\edef\mfp@mode{#1}%
+ \mfp@ifopengraphsfile%
+ {\mfp@afteropen@error\mfmode}%
+ {\mfp@ifmpost{\mfp@noMF@warn\mfmode}{}}}%
+\newdef\mfresolution#1{\edef\mfp@resolution{#1}%
+ \mfp@ifopengraphsfile%
+ {\mfp@afteropen@error\mfresolution}%
+ {\mfp@ifmpost{\mfp@noMF@warn\mfresolution}{}}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\setmfvariable}
+% 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.
+% \DescribeMacro{\setmpvariable}
+% For consistency, \cs{setmpvariable} is an alternative name for it. It
+% takes three arguments: the type of variable, the variable itself, and
+% its value. Example:\\
+% \indent \cs{setmfvariable}\marg{numeric}\marg{shadewd}\marg{.7pt}.\\
+% Since the \MF{} code \mfc{save}\,s the variable, there must be no
+% 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.
+%
+% Since \MP{} has three (or four) data types for color, we have to write
+% the command `\gbc{setcolor}' to the output file instead of
+% `\gbc{setvariable (color)}' so that the datatype can be determined
+% before declaring the variable. (Unlike the other data types the
+% \grafbase{} command \gbc{setcolor} is more complicated than
+% \gbc{setvariable(color)}.) For simplicity, we do this with all data
+% types. For example \cs{setmfvariable}\marg{numeric} writes
+% `\gbc{setnumeric}'. This makes spaces significant in the first argument,
+% so we strip them off the ends with \cs{mfp@sp@def} (defined in
+% section~\ref{optional}).
+%
+% We have abbreviations for the most common internal uses. For example
+% \SpecialUsageIndex{\setmfboolean}\cs{setmfboolean} is the equivalent of
+% \cs{setmfvariable} with type \mfc{boolean}. A similar statement is true
+% For \SpecialUsageIndex{\setmfnumeric}\cs{setmfnumeric},
+% \SpecialUsageIndex{\setmfpair}\cs{setmfpair}, and
+% \SpecialUsageIndex{\setmfcolor}\cs{setmfcolor}.
+%
+% \DescribeMacro{\globalsetmfvariable}
+% This is like \cs{setmfvariable}, except it doesn't perform a
+% \mfc{save} and so the variable is globally defined. Also,
+% suffixed variables are permitted (but not numeric suffixes).
+% Here, too, we have to write a different command for setting color.
+% Thus, me need to test whether the first argument is `color'. Here again,
+% spaces are significant.
+% \begin{macrocode}
+\newdef\setmfvariable#1{%
+ \mfp@sp@def\mfp@tempa{#1}\@setmfvariable\mfp@tempa}%
+\newdef\@setmfvariable#1#2#3{%
+ \mfp@ifopengraphsfile%
+ {\mfcmd{set#1 (#2) #3}}%
+ {\mfp@nooutput@error\setmfvariable}}%
+\newdef\setmfboolean{\@setmfvariable{boolean}}%
+\newdef\setmfnumeric{\@setmfvariable{numeric}}%
+\newdef\setmfpair {\@setmfvariable{pair}}%
+\newdef\setmfcolor {\@setmfvariable{color}}%
+\newdef\globalsetmfvariable#1#2#3{%
+ \mfp@sp@def\mfp@tempa{#1}%
+ \mfp@ifopengraphsfile
+ {\mfcmd{\ifx\mfp@tempa\mfp@C gsetcolor \else gsetvariable (#1) \fi
+ (#2) #3}}%
+ {\mfp@nooutput@error\globalsetmfvariable}}%
+\newlet\setmpvariable\setmfvariable
+\newlet\globalsetmpvariable\globalsetmfvariable
+% \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 synchrony, 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. The command \cs{mfp@local} tests this switch and makes the
+% following assignment global if it fails. Then we have two shortcuts for
+% the more commonly occuring cases.
+%
+% We also define here \texttt{true}, \texttt{false} and \texttt{color} as
+% macros. These are strings we need to write to the output frequently.
+% \begin{macrocode}
+\newlet\ifin@mfpicenv\iffalse
+\newdef\mfp@local{\relax\ifin@mfpicenv\else\global\fi}%
+\newdef\mfp@let{\mfp@local\let}%
+\newdef\mfp@def{\mfp@local\def}%
+\newdef\mfp@T{true}%
+\newdef\mfp@F{false}%
+\newdef\mfp@C{color}%
+% \end{macrocode}
+%
+% \DescribeMacro{\usecenteredcaptions}
+% This (\opt{centeredcaptions}) is the simplest option. Other options
+% follow a similar pattern: a user-level command \cs{usecenteredcaptions}
+% is defined for turning it on and another,
+% \DescribeMacro{\nocenteredcaptions}
+% \cs{nocenteredcaptions}, is defined for turning it off. Selection of
+% centered captions can be turned on or off at will throughout a document.
+% \begin{macrocode}
+\newdef\usecenteredcaptions{\mfp@let\ifmfp@centcapt\iftrue}%
+\newdef\nocenteredcaptions {\mfp@let\ifmfp@centcapt\iffalse}%
+\nocenteredcaptions
+% \end{macrocode}
+%
+% \DescribeMacro{\useraggedcaptions}
+% Here we define the settings for justified and ragged captions.
+% Justified captions are the default. Ragged captions are normally
+% raggedright, but are ragged on both sides if \opt{centeredcaptions} is
+% in effect.
+% \DescribeMacro{\noraggedcaptions}
+% For justified captions, lines are justified on both sides, except the
+% last is centered under \opt{centeredcaptions}.
+% \begin{macrocode}
+\newdef\useraggedcaptions{\mfp@let\mfp@capsettings\mfp@raggedcap}%
+\newdef\noraggedcaptions{\mfp@let\mfp@capsettings\mfp@justifiedcap}%
+\newdef\mfp@raggedcap{%
+ \ifmfp@latex
+ \ifmfp@centcapt \centering \else \raggedright \fi
+ \else
+ \rightskip 0pt plus 1fil\relax
+ \ifmfp@centcapt
+ \leftskip 0pt plus 1fil
+ \parfillskip 0pt plus 1fil\relax
+ \fi
+ \def\\{\unskip\hbox{}\penalty-\@M\ignorespaces}%
+ \fi}%
+\def\mfp@justifiedcap{%
+ \ifmfp@centcapt
+ \leftskip 0pt plus 0.5fil
+ \rightskip 0pt plus -0.5fil
+ \parfillskip 0pt plus 1fil\relax
+ \fi
+ \def\\{\unskip\hbox{}\hfil\penalty-\@M\ignorespaces}}%
+\noraggedcaptions
+% \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 \MF{} and
+% \TeX{} booleans to switch. In all cases, the default for the option is
+% \emph{off}, so we issue the second command after it is defined.
+%
+% Since the output file has not been opened while \mfpic{} is loading, the
+% \MF{} boolean is not set, but the \cs{opengraphsfile} code will check
+% the \TeX{} boolean and write the appropriate \MF{} code.
+% \begin{macrocode}
+\newdef\mfp@makeoption#1#2#3#4{%
+ \newdef#1{\mfp@let#4\iftrue
+ \mfp@ifopengraphsfile{\setmfboolean{#3}\mfp@T}{}}%
+ \newdef#2{\mfp@let#4\iffalse
+ \mfp@ifopengraphsfile{\setmfboolean{#3}\mfp@F}{}}%
+ #2}%
+% \end{macrocode}
+%
+% \DescribeMacro{\clipmfpic}
+% 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.
+% \DescribeMacro{\noclipmfpic}
+% The default is the old behavior: no clipping.
+% \begin{macrocode}
+\mfp@makeoption\clipmfpic\noclipmfpic{clipall}\ifmfp@clip
+% \end{macrocode}
+%
+% \DescribeMacro{\usetruebbox}
+% The \opt{truebbox} option lets \MP{} set the true bounding box (which
+% may differ from the numbers defined through \cs{mfpic}).
+% \DescribeMacro{\notruebbox}
+% The default is the old behavior, \cs{notruebbox}.
+%
+% We don't need to be too careful with the scope of these option
+% commands. 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{truebbox}\ifmfp@truebbox
+% \end{macrocode}
+%
+% \DescribeMacro{\usemplabels}
+% 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 synchronization of scope is not an issue.
+% \DescribeMacro{\nomplabels}
+% 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.
+% When writing \TeX{} code to the file we need to make sure \texttt\#
+% is not doubled. We do this by issuing \cs{mp@mksharpother} before
+% reading the argument that will be written.
+% \begin{macrocode}
+\newdef\usemplabels{\mfp@let\ifmfp@mplabels\iftrue
+ \mfp@ifopengraphsfile
+ {\mfp@ifmpost{}%
+ {\mfp@noMP@error{mplabels}\global\let\ifmfp@mplabels\iffalse}}{}}%
+\newdef\nomplabels{\mfp@let\ifmfp@mplabels\iffalse}%
+\newdef\@ifmplabels{%
+ \ifmfp@mplabels\@xp\@firstoftwo\else\@xp\@secondoftwo\fi}%
+\nomplabels
+\newdef\mp@mksharpother{\@ifmplabels{\@makeother\#}{}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\overlaylabels}
+% The option \opt{overlaylabels} instructs \MP{} to defer adding labels
+% until the end of the picture. That means they don't get clipped or
+% covered up by any drawing elements.
+% \DescribeMacro{\nooverlaylabels}
+% The default is the old behavior, \cs{nooverlaylabels}. 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{overlaylabels}\ifmfp@overlabels
+% \end{macrocode}
+%
+% \DescribeMacro{\clearsymbols}
+% The option \opt{clearsymbols} causes the symbols drawn by
+% \cs{plotsymbol} and \cs{plotnodes} to have their interiors erased before
+% being drawn.
+% \DescribeMacro{\noclearsymbols}
+% The default is the old behavior: \cs{noclearsymbols}.
+% \begin{macrocode}
+\mfp@makeoption%
+ \clearsymbols\noclearsymbols{clearsymbols}\ifmfp@clearsym
+% \end{macrocode}
+%
+% \DescribeMacro{\stopshipping}
+% This is to turn off character shipping for duration of innermost
+% enclosing \MF{} 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 \cs{ifmfp@noship} is checked before \cs{endmfpic}
+% attempts to add the (nonexistent) figure to the document.
+% \DescribeMacro{\resumeshipping}
+% The macro \cs{resumeshipping} restores character shipping.
+%
+% \DescribeMacro{\noship}
+% The macro \cs{noship} is the older name for \cs{stopshipping}. Its name
+% indicated that it was intended for use in one picture. This is not
+% actually an option (that is, there is no corresponding
+% \cs{DeclareOption} in \LaTeX), but it is coded the same.
+% \begin{macrocode}
+\mfp@makeoption\stopshipping\resumeshipping{noship}\ifmfp@noship
+\newlet\noship\stopshipping
+% \end{macrocode}
+%
+% \DescribeMacro{\mfpreadlog}
+% This sets the boolean governing the option to examine the \MF{} or
+% \MP{} log file for certain information.
+% \begin{macrocode}
+\newlet\ifmfp@readlog\iffalse
+\newdef\mfpreadlog{%
+ \mfp@ifopengraphsfile
+ {\mfp@afteropen@error\mfpreadlog}{\global\let\ifmfp@readlog\iftrue}}%
+% \end{macrocode}
+%
+%
+% \subsection{Graphic inclusion}\label{graphic}
+%
+% \DescribeMacro{\mfpicllx}
+% 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
+% \DescribeMacro{\mfpiclly}
+% bounding box coordinates of the lower left corner. Here we initialize
+% the macros that hold these coordinates.
+% \begin{macrocode}
+\newdef\mfpicllx{0}%
+\newdef\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.
+%
+% We actually define two alternative versions of \cs{@setmfpicgraphic}.
+% The normal one is as described above, and a `nofile' alternative for
+% when the graphic file somehow doesn't exist. Then we just print the
+% filename.
+% \begin{macrocode}
+\newdef\normal@setmfpgraphic#1{%
+ \preparemfpicgraphic{#1}\setmfpicgraphic{#1}\getmfpicoffset{#1}}%
+\newdef\nofile@setmfpgraphic#1{%
+ {\edef\mfp@tempa{#1}%
+ \vbox to 0pt{\vss
+ \rlap{\kern2pt \mfpdraftfont \mfp@sanitized\mfp@tempa}\kern 2pt}}}%
+\mfp@ifdefined\strip@prefix{}{\def\strip@prefix#1>{}}%
+\newdef\mfp@sanitized{\@xp\strip@prefix\meaning}%
+\newlet\@setmfpicgraphic\normal@setmfpgraphic
+\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 the output
+% file's basename (\arg1) with the picture number as the extension.
+%
+% \DescribeMacro{\setfilenametemplate}
+% The user can also tell \MP{} what kind of filename he wishes it to
+% produce. one uses \verb$\_$ in the template as a placeholder for the
+% \file{.mp} filename (the name used in \cs{opengraphsfile}) and \verb$\#$
+% for the figure number.
+% \begin{macrocode}
+\newdef\setfilename#1#2{#1.#2}%
+\newdef\setfilenametemplate#1{%
+ \begingroup
+ \def\_{\mfp@p j}%
+ \def\#{\mfp@p c}%
+ \let\@nl\relax
+ \xdef\mfp@settemplate{\@nl setoutputtemplate "#1";\@nl}%
+ \let\number\relax
+ \let\mfp@count\relax
+ \let\mfp@filename\relax
+ \def\_{\mfp@filename}%
+ \def\#{\number\mfp@count}%
+ \xdef\setfilename##1##2{#1}%
+ \endgroup
+}%
+% \end{macrocode}
+%
+% The \opt{draft}, \opt{final} and \opt{nowrite} options override
+% \mfpic's attempts to automatically detect whether the pictures should
+% be included. They also work under the \opt{metafont} option, but are
+% less important then (even unnecessary).
+%
+% \DescribeMacro{\mfpicdraft}
+% The \opt{draft} option (\cs{mfpicdraft} command) causes the pictures
+% created by \mfpic{} to be omitted.
+%
+% \DescribeMacro{\mfpicnowrite}
+% The \opt{nowrite} option (\cs{mfpicnowrite} command) turns off creation
+% of the output \file{.mp} file. It is intended to help speed things up
+% after all figures are completed, so it permits the insertion of pictures.
+%
+% \DescribeMacro{\mfpicfinal}
+% The \opt{final} option (\cs{mfpicfinal} command) can be used to
+% override a global draft option. It forces \mfpic{} to attempt to
+% insert the pictures. Under the \opt{metapost} option, missing figures
+% may cause serious slow-downs as a large number of directories may be
+% searched.
+%
+% Each of these sets the user level if-command
+% \SpecialUsageIndex{\ifmfpicdraft}\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\|final\}\{true\|false\}} are used to communicate with
+% the \cs{opengraphsfile} command, in case the user-level commands occur
+% before then.
+% \begin{macrocode}
+\newif\ifmfpicdraft
+\newlet\ifmfp@draft\iffalse
+\newlet\ifmfp@final\iffalse
+\newlet\ifmfp@nowrite\iffalse
+\newdef\mfpicdraft{%
+ \mfp@ifopengraphsfile{\global\mfpicdrafttrue}%
+ {\global\let\ifmfp@draft\iftrue}}%
+\newdef\mfpicfinal{%
+ \mfp@ifopengraphsfile{\global\mfpicdraftfalse}%
+ {\global\let\ifmfp@final\iftrue}}%
+\newdef\mfpicnowrite{%
+ \mfp@ifopengraphsfile{\mfp@afteropen@error\mfpicnowrite}%
+ {\global\let\ifmfp@nowrite\iftrue}}%
+%</tex>
+% \end{macrocode}
+%
+%
+% \subsection{\LaTeX{} options and \MP{} graphics inclusion}\label{latex}
+%
+% Code dependent on \LaTeXe. Mostly this is the option processing
+% facilities. The declaration of options is in the file
+% \file{mfpic.sty}, which will input \file{mfpic.tex}.
+% \begin{macrocode}
+%<*sty>
+\DeclareOption{draft}{\mfpicdraft}%
+\DeclareOption{final}{%
+ \mfpicfinal\PassOptionsToPackage{final}{graphics}}%
+\DeclareOption{nowrite}{\mfpicnowrite}%
+\DeclareOption{metapost}{\mfp@mposttrue}%
+\DeclareOption{metafont}{\usemetafont}%
+\DeclareOption{centeredcaptions}{\usecenteredcaptions}%
+\DeclareOption{justifiedcaptions}{\noraggedcaptions}%
+\DeclareOption{raggedcaptions}{\useraggedcaptions}%
+\DeclareOption{clip}{\clipmfpic}%
+\DeclareOption{truebbox}{\usetruebbox}%
+\DeclareOption{mplabels}{\usemplabels}%
+\DeclareOption{overlaylabels}{\overlaylabels}%
+\DeclareOption{clearsymbols}{\clearsymbols}%
+\DeclareOption{debug}{\mfpicdebugtrue}%
+\DeclareOption{mfpreadlog}{\mfp@readlogtrue}%
+\DeclareOption*{%
+ \@ifpackageloaded{graphics}%
+ {\Mfpic@warn{Unrecognized option \CurrentOption.}}%
+ {\Mfpic@msg{Passing option \CurrentOption\space to %
+ graphics package.}%
+ \PassOptionsToPackage{\CurrentOption}{graphics}}}%
+\newcommand*\mfpdraftfont{\normalfont\ttfamily}%
+% \end{macrocode}
+%
+% Now we define one of three versions of \cs{@usemetapost}. This command
+% will be issued by the user level command \cs{usemetapost}, and consists
+% of the format dependent code. The one here is, of course, for \LaTeX{}
+% and will be in \file{mfpic.sty}.
+%
+% 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. For this, we definitely
+% need to make sure the \prog{graphics} package is loaded.
+% \begin{macrocode}
+\def\@usemetapost{%
+ \mfp@ifdefined\includegraphics{}{\RequirePackage{graphics}}%
+ \let\mfp@save@parse@bb\Gread@parse@bb
+ \newdef\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 makes decisions about graphic files based on
+% the files' extensions. Since we don't want to force our users to rename
+% all the graphics output by \MP, we add code to \cs{preparemfpicgraphic}
+% 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 also use this command to substitute the above BoundingBox
+% parsing code for the \prog{graphics} package version.
+% \begin{macrocode}
+ \ifmfp@pdf \gdef\mfp@Gtype{mps}%
+ \else \gdef\mfp@Gtype{eps}%
+ \fi
+ \gdef\preparemfpicgraphic##1{%
+ \@namedef{Gin@rule@.\number\mfp@count}####1{{\mfp@Gtype}%
+ {.\number\mfp@count}{####1}}%
+ \let\Gread@parse@bb\mfp@parse@bb}%
+ \global\let\setmfpicgraphic\includegraphics
+ \gdef\getmfpicoffset##1{}}%
+% \end{macrocode}
+%
+% The \LaTeX{} wrapper ends by inputing \file{mfpic.tex}.
+% \begin{macrocode}
+\input mfpic.tex\relax
+%</sty>
+% \end{macrocode}
+%
+% \DescribeMacro{\usemetapost}
+% The user level command \cs{usemetapost} starts with a few actions common
+% to all formats, then calls \cs{@usemetapost} which is defined
+% differently for different formats.
+% \begin{macrocode}
+%<*tex>
+\newdef\usemetapost{%
+ \mfp@ifopengraphsfile{\mfp@mpostfalse\mfp@useMP@error}%
+ {\mfp@mposttrue \@usemetapost}}%
+% \end{macrocode}
+%
+% Under \LaTeX, if \file{mfpic.cfg} exists, it will be input at this
+% point. Then, we \cs{ProcessOptions}, using the star-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}
+\ifmfp@latexe
+ \InputIfFileExists{mfpic.cfg}{}{}%
+ \ProcessOptions*\relax
+% \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{\mfp@closegraphsfile}%
+% \end{macrocode}
+%
+% Now those cases outside \LaTeXe{} that we try to support.
+% \begin{macrocode}
+\else
+ \mfp@msg{}\Mfpic@msg{\mfpfiledate\space v\mfpfileversion.\@nl}%
+% \end{macrocode}
+%
+% The definition of \cs{@usemetapost} in plain \TeX{} depends on the
+% setting of \cs{ifmfp@pdf}. However both cases are so similar that we
+% define a helper macro \cs{mfp@useMP} that just needs to have the names
+% of three commands and two files fed to it.
+% \begin{macrocode}
+ \newdef\mfp@useMP#1#2#3#4#5{%
+ \mfp@ifdefined#1{}{%
+ \InputIfFileExists{#2}{}{%
+ \InputIfFileExists{#3}{}{%
+ \mfp@errmsg{Files not found: #1, #2}%
+ {One of the two named files is necessary
+ for mfpic, but neither was found.}}}}%
+ \global\let\setmfpicgraphic\mfp@includeMPS
+ \gdef\getmfpicoffset##1{\xdef\mfpicllx{#4}\xdef\mfpiclly{#5}}}%
+% \end{macrocode}
+%
+% Under \pdfTeX{}, the graphics inclusion command is \cs{convertMPtoPDF},
+% defined in \file{supp-pdf.tex}. This command parses the file's PS
+% contents to PDF code, and leaves the bounding box info in macros
+% \cs{MPllx} and \cs{MPlly}.
+% \begin{macrocode}
+ \ifmfp@pdf
+ \newdef\mfp@includeMPS#1{\convertMPtoPDF{#1}{1}{1}}%
+ \newdef\@usemetapost{%
+ \mfp@useMP\convertMPtoPDF{supp-pdf.mkii}{supp-pdf.tex}%
+ \MPllx\MPlly}%
+% \end{macrocode}
+%
+% Under plain\TeX, eplain (still need to test this after recent eplain
+% changes), \AmSTeX, or \LaTeX2.09, the graphics inclusion command is
+% \cs{epsfbox}, defined in \file{epsf.tex}. This command writes a
+% \cs{special} for \prog{dvips} (and other DVI driver programs), and
+% leaves the bounding box info in macros \cs{epsfllx} and \cs{epsflly}.
+% \begin{macrocode}
+ \else
+ \newdef\mfp@includeMPS#1{\epsfbox{#1}}%
+ \newdef\@usemetapost{%
+ \mfp@useMP\epsfbox{epsf.tex}{epsf.sty}\epsfllx\epsflly}%
+ \fi
+\fi
+% \end{macrocode}
+%
+%
+%
+% \section{Optional parameter handling}\label{optional}
+%
+% We borrow \LaTeX's \cs{@ifnextchar}. The first argument is the token
+% being checked. It doesn't have to be a character and we sometimes use
+% \cs{@ifnextchar} to check whether a certain command follows.
+% 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.
+% \begin{macrocode}
+\mfp@DBlog{Handlers for optional parameters.}%
+\mfp@ifundefined\@ifnextchar
+ \long\def\@ifnextchar#1#2#3{%
+ \let\reserved@d#1%
+ \def\reserved@a{#2}%
+ \def\reserved@b{#3}%
+ \futurelet\@let@token\@ifnch}%
+ \def\@ifnch{%
+ \ifx\@let@token\@sptoken
+ \let\reserved@c\@xifnch
+ \else
+ \ifx\@let@token\reserved@d
+ \let\reserved@c\reserved@a
+ \else
+ \let\reserved@c\reserved@b
+ \fi
+ \fi
+ \reserved@c}%
+ {%
+ \def\:{\global\let\@sptoken= }\: % makes \@sptoken a space token
+ \def\:{\@xifnch}\@xp\gdef\: {\futurelet\@let@token\@ifnch}%
+ }%
+\mfp@enddef
+% \end{macrocode}
+%
+% Here we borrow from \file{keyval.sty}. We need a command that strips
+% spaces off ends of an argument and stores the result in a macro. In
+% \file{keyval}, that is \cs{KV@@sp@def}; we copy it here with name
+% changes. Defining \cs{mfp@tempa}, and then calling it with a space as
+% argument, ensures there will be an actual space token where needed in
+% the definition of \cs{mfp@sp@def}. The first argument is the control
+% sequence to define and the second is its definition text, with possible
+% spaces to be stripped. (I'm wondering now why I didn't just use
+% \cs{zap@space} since there shouldn't be \emph{any} significant spaces.
+% Well, at least I have the code in place for a future key-value
+% interface.)
+% \begin{macrocode}
+\def\mfp@tempa#1{%
+ \def\mfp@sp@def##1##2{%
+ \futurelet\mfp@next\mfp@sp@d##2\@nil\@nil#1\@nil\relax##1}%
+ \def\mfp@sp@d{%
+ \ifx\mfp@next\@sptoken \@xp\mfp@sp@b
+ \else \@xp\mfp@sp@b\@xp#1%
+ \fi}%
+ \def\mfp@sp@b#1##1 \@nil{\mfp@sp@c##1}}%
+\mfp@tempa{ }%
+\def\mfp@sp@c#1\@nil#2\relax#3{\mfp@toks{#1}\edef#3{\the\mfp@toks}}%
+% \end{macrocode}
+%
+% The following save us some typing whenever we need to check if some
+% token follows, and then remove it if it does. That's what
+% \cs{mfp@iftoken} does, being just a generalized form of \LaTeX{}'s
+% \cs{@ifstar}. Almost all our star-form commands differ only in what
+% parameter is passed to some other command. Thus \cs{mfp@ifstar} passes
+% either \arg{2} or \arg{3} to command \arg{1}.
+%
+% The \cs{mfp@ifend} is for use in processing lists, which all end with
+% the token \cs{mfp@end}. \cs{mfp@ifendorcomma} is useful for processing
+% comma-separated lists. If \cs{mfp@end} follows, it is removed and \arg1
+% is executed. Otherwise, if a comma follows, it is removed and \arg2 is
+% executed. When neither follows, nothing is removed and \arg3 is
+% executed. Normally, this last is the main command being applied to each
+% element of the list.
+%
+% We also define \LaTeX's \cs{@ifstar} for the few cases that require it.
+% \begin{macrocode}
+\def\mfp@iftoken#1#2{\@ifnextchar#1{\@firstoftwo{#2}}}%
+\def\mfp@ifstar#1#2#3{\mfp@iftoken*{#1{#2}}{#1{#3}}}%
+\def\mfp@ifend{\mfp@iftoken\mfp@end}%
+\def\mfp@ifendorcomma#1#2#3{\mfp@ifend{#1}{\mfp@iftoken,{#2}{#3}}}%
+\mfp@ifundefined\@ifstar
+ \def\@ifstar#1{\@ifnextchar*{\@firstoftwo{#1}}}%
+\mfp@enddef
+% \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.
+% \cs{mfp@ifempty} helps check for emptyness. It uses a simple \cs{if} so
+% that \arg{1} will be expanded. I use a non-active \texttt\textasciitilde
+% (so it won't expand) to test for emptiness because, even if
+% a tilde should accidentally occur in a user's \arg1, it will most
+% likely be the usual active version which expands to something else.
+%
+% The shorthand \cs{mfp@ifexist} executes some code if \arg1 is not
+% empty, otherwise it does nothing. And \cs{mfp@emptysub} expands to
+% \arg1 if it isn't empty, otherwise \arg2.
+%
+% The \cs{@ifmtarg} macro is borrowed from \file{ifmtarg.sty}.
+% It is used when a space should count as empty, but expansion isn't
+% needed. It would be nice to have one that counts both as empty, but
+% that seems impossible (or impossibly hard).
+% \begin{macrocode}
+{%
+\catcode`Q3 \catcode`\~12
+\gdef\mfp@ifempty#1{\if~#1~\@xp\@firstoftwo\else\@xp\@secondoftwo\fi}%
+\gdef\mfp@ifexist#1{\if~#1~\@xp\@gobble\else\@xp\@firstofone\fi}%
+\gdef\mfp@emptysub#1#2{\if~#1~#2\else#1\fi}%
+\long\gdef\@ifmtarg#1{\@xifmtarg#1QQ\@secondoftwo\@firstoftwo\@nil}%
+\long\gdef\@xifmtarg#1#2Q#3#4#5\@nil{#4}%
+}%
+% \end{macrocode}
+%
+% These are the two most common methods to parse optional arguments. In
+% \cs{mfp@defaultopt}, if an optional argument is present, we use
+% \cs{mfp@ifemptyopt} to see if it is empty and substitute a default
+% (\arg{2}) if it is. Argument \arg{1} is the command to run
+% on the resulting argument after this check. It needn't be a single
+% command token, but can (and often will) be a series of commands, or a
+% command with additional arguments.
+%
+% \cs{mfp@nullopt} is a convenient abbreviation for a common case: the
+% default option is empty. We could define it in terms of
+% \cs{mfp@defaultopt}, but then we'd have the redundant step of checking
+% for an empty optional argument, only to replace it by an empty argument.
+% That might not make a significant difference, but it just feels wrong.
+%
+% Both commands turn the delimited argument, if present, into an ordinary
+% one. This extra step permits us to avoid many bracket pairs in later
+% code.
+% \begin{macrocode}
+\newdef\mfp@defaultopt#1#2{%
+ \@ifnextchar[{\mfp@ifemptyopt{#1}{#2}}{#1{#2}}}%]
+\newdef\mfp@ifemptyopt#1#2[#3]{\mfp@ifempty{#3}{#1{#2}}{#1{#3}}}%
+\newdef\mfp@nullopt#1{\@ifnextchar[{\mfp@getopt{#1}}{#1{}}}%
+\newdef\mfp@getopt#1[#2]{#1{#2}}%
+% \end{macrocode}
+%
+% Why do we bother to check for an empty optional argument? Because
+% quite a few \mfpic{} commands stuff several parameters into a
+% single optional argument. All but the last are processed as undelimited
+% arguments and the last one as delimited by the right bracket. If only
+% the last parameter is missing, TeX{} takes that as an empty argument and
+% we can proceed gracefully (substituting a default). However, if more
+% than that are missing, \TeX{} takes the closing bracket as the
+% \emph{undelimited} argument and produces pretty inscrutable error
+% mesages. This decision to add extra information in one optional argument
+% was, in retrospect, a bad one. It 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.
+%
+% Another reason is that multiple optional arguments generally mean that
+% the to specify a later one, all the previous ones need to be specified.
+% But with the above code, the user can always use an empty bracket pair
+% to indicate the default, minimizing the extra typing.
+%
+%
+%
+% \section{Writing to the \file{.mf} or \file{.mp} file}\label{writing}
+%
+%
+% \subsection{Preserving linebreaks}\label{linebreaks}
+%
+% Some macros (the ones we call list macros) can take quite long
+% arguments, 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.
+%
+% 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 of a different category. We do the former, because the line a
+% macro starts on will already have the end-of-line character added, but
+% it will not yet have been tokenized, so its category can be changed. 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 since \cs{relax} is not
+% expandable.
+% \begin{macrocode}
+\mfp@DBlog{Direct output to Metafont/Post file.}%
+{%
+ \catcode\mfp@ctrlM\active%
+ \gdef\@activectrlM{^^M}%
+ \gdef\mfp@obeylines{\catcode\mfp@ctrlM\active\let^^M\relax}%
+}%
+% \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).
+%
+% 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{mfp@keeplines} ensures these are the same and makes the above
+% changes in category. This will fail in the following case:
+% \cs{endlinechar} is not \verb$^^M$ and the data starts on the same line
+% as the command that issued \cs{mfp@keeplines}. But then the output will
+% lack only that first linebreak.
+% \begin{macrocode}
+\newdef\mfp@keeplines{\newlinechar\mfp@ctrlM
+ \endlinechar\newlinechar \mfp@obeylines}%
+% \end{macrocode}
+%
+% We want our file writes to issue \cs{mfp@keeplines} 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{mfp@write}, and then invoke the appropriate continuation command.
+%
+% \DescribeMacro{\mfsrc}
+% The macro \cs{mfsrc} is the most basic, merely writing its contents. For
+% figure macros, we ultimately call
+% \DescribeMacro{\mfcmd}
+% \cs{mfcmd}, which appends a semicolon, terminating any pending \MF{}
+% command. For macros which take a comma separated list of values as their
+% arguments, we call
+% \DescribeMacro{\mflist}
+% \cs{mflist} which surrounds the list in parentheses and appends a
+% semicolon
+%
+% The ending code is in \cs{mfp@src}. The \cs{begingroup} in
+% \cs{mfp@write} matches the \cs{endgroup} in \cs{mfp@src}. The group
+% isolates the changes to EOLs. We also define \cs{@nl} to expand 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 {\mfp@write\mfp@src\mfsrc}%
+\newdef\mfcmd {\mfp@write\mfp@cmd}%
+\newdef\mflist{\mfp@write\mfp@wlist}%
+\newdef\mfp@write{\begingroup\mfp@keeplines \let\@nl\@activectrlM}%
+% \end{macrocode}
+%
+% The macro \cs{mfp@src} does the job of writing to files. The output
+% stream \cs{mfp@out} is declared later. The other two commands invoke
+% \cs{mfp@src} on a slightly modified argument. The first argument to
+% \cs{mfp@src} is the command that called it (for the error message), the
+% second is the code to write.
+% \begin{macrocode}
+\newdef\mfp@src#1#2{%
+ \mfp@ifopengraphsfile{\immediate\write\mfp@out{#2}}%
+ {\mfp@nooutput@error{#1}}\endgroup}%
+\newdef\mfp@cmd#1{\mfp@src\mfcmd{#1;}}%
+\newdef\mfp@wlist#1{\mfp@src\mflist{(#1);}}%
+% \end{macrocode}
+%
+% If \prog{babel} is loaded with some options, certain punctuation will
+% be made active. These will then be expanded when written to the graph
+% file. \prog{Babel} provides a way to turn this off, but it would be an
+% error to run those commands if \prog{babel} is not loaded. Rather than
+% try to detect \prog{babel}, we run these commands only if they are
+% defined.
+% \begin{macrocode}
+\def\mfp@safe@activestrue{%
+ \mfp@ifdefined\@safe@activestrue\@safe@activestrue{}}%
+\def\mfp@safe@activesfalse{%
+ \mfp@ifdefined\@safe@activesfalse\@safe@activesfalse{}}%
+% \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{mfp@d} is used to write a line of
+% dashes above and below each figure to make them stand out when debugging
+% the file.
+% \begin{macrocode}
+\edef\mfp@p{\@xp\@gobble\string\%}% percent (%)
+\edef\mfp@s{\@xp\@gobble\string\#}% sharp (#)
+\edef\mfp@b{\@xp\@gobble\string\\}% backslash (\)
+\newdef\mfp@d{--------------}%
+% \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\two@digits{}%
+ {\def\two@digits#1{\ifnum#1<10 0\fi\number#1}}%
+{%
+ \mfp@ifdefined\normalmonth
+ {\let\month\normalmonth\let\year\normalyear}{}%
+ \count@\time \divide\count@ by 60
+ \xdef\mfp@now{\number\year/\two@digits\month/\two@digits\day
+ \space at \two@digits\count@:}%
+ \multiply\count@ by -60 \advance\count@\time
+ \xdef\mfp@now{\mfp@now\two@digits\count@}%
+}%
+% \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} Number indexing current line style in
+% multi-curve data plots.
+% \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{mfp@verbtex} A temporary token list used by \cs{mfpverbtex}.
+% \item \cs{ifmfp@switch} Not exactly a register, but a temporary
+% switch for passing information from one macro to another.
+% \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@sequence
+\newtoks\mfp@toks
+\newtoks\mfp@verbtex
+\newif\ifmfp@switch
+%</tex>
+% \end{macrocode}
+%
+% We store most of the \mfc{verbatimtex} block that \mfpic{} relies on in
+% the file \file{mfpicdef.tex}. This is the code that goes into that
+% file
+%
+% The \cs{mpxshipout} is to cover all three cases of the output of
+% `\texttt{mpto -tex}'. In public versions of \MP{} prior to 0.9 there was
+% no such command in that output file. In 0.9 and 0.901 that command is
+% defined at the start of the file, prior to any verbatimtex, but it is
+% buggy. This code overwrites it and fixes the bugs. In later versions a
+% good definition is used, but it appears only just before the first
+% \mfc{btex} and so will overwrite my definition. Thus all cases are
+% served.
+% \begin{macrocode}
+%<*defs>
+\gdef\mpxshipout{\afterassignment\middlempxshipout\setbox0=\hbox}%
+\gdef\middlempxshipout{\aftergroup\finishmpxshipout}%
+\gdef\finishmpxshipout{\dimen1=\ht0 \dimen2=\dp0
+ \dimen0=\dimen1 \advance\dimen0\dimen2
+ \setbox0=\hbox{\hbox{\box0
+ \ifnum\dimen0>0 \vrule width1sp height\dimen1 depth\dimen2
+ \else \vrule width1sp height1sp depth0sp\relax
+ \fi}}%
+ \ht0=0pt \dp0=0pt \shipout\hbox{\box0}}%
+\def\MFPtext#1{\vbox{\def\\{\cr}\MFPcfont\MFPeverylabel
+ \halign{##\hfil\cr#1\crcr}}}%
+% \end{macrocode}
+%
+% There are vague plans to make the output file equally usable by \MF{}
+% and \MP{}. For this to work, \file{grafbase.mf} defines
+% \mfc{verbatimtex} to gobble everything to the next colon (which we place
+% after each \mfc{etex} we write). This fails if there is a
+% \verb$\begingroup$ without matching \verb$\endgroup$ because \MF{} sees
+% this as the command \verb$\$ (meaning \mfc{relax}) followed by the \MF{}
+% primitive \mfc{begingroup}. But \MF{} doesn't allow gobbled text
+% parameters to contain unbalanced groups. Thus, we use the replacements
+% defined here, hidden from \MF{} in a \TeX{} input file.
+% \begin{macrocode}
+\let\MFPbegingroup\begingroup
+\let\MFPendgroup\endgroup
+%</defs>
+% \end{macrocode}
+%
+% Within \file{mfpic.tex} these commands can be anything unexpandable,
+% since we just want them to be written verbatim. It makes sense to give
+% them the obvious meanings.
+% \begin{macrocode}
+%<*tex>
+\let\MFPbegingroup\begingroup
+\let\MFPendgroup\endgroup
+% \end{macrocode}
+%
+% We store the first several lines that will be written to the output
+% file in a few internal macros, so that changing them will be easier.
+%
+% The first two lines of the output file are comments identifying the
+% file, the \mfpic{} version, the tex source file, and the timestamp.
+% These are stored in \cs{mfp@versioninfo}. We also let \grafbase{} know
+% the \mfpic{} version creating the file. This could catch version
+% mismatches. But since older \grafbase{} didn't test this, some
+% mismatches will be missed.
+%
+% After that (\cs{mfp@init@outfile}) we set the \mfc{mode} and the
+% \mfc{mag} if not known (both ignored by \MP), and arrange for
+% \grafbase{} macros to be loaded.
+% \begin{macrocode}
+\newdef\mfp@versioninfo{%
+ \mfp@p\space\mfp@filename.m\mfp@ifmpost{p}{f}, %
+ generated by Mfpic, v\mfpfileversion\space\mfpfiledate,\@nl
+ \mfp@p\space from TeX source "\jobname" on \mfp@now\@nl
+ numeric mfpicversion; mfpicversion := \mfpicversion;\@nl}%
+\newdef\mfp@init@outfile{%
+ 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 a mismatch caused by an old
+% \grafbase{} with a current \mfpic.
+% \begin{macrocode}
+\newdef\mfp@versioncheck{%
+ 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}
+%
+% This opens the output file and prints a reminder to the user to run
+% \MF{} or \MP{}.
+% \begin{macrocode}
+\newdef\mfp@openfile{%
+ \ifmfp@nowrite \else \mfp@msg{}%
+ \Mfpic@msg{Initializing \mfp@filename\mfp@ext.}%
+ \immediate\openout\mfp@out=\mfp@filename\mfp@ext\relax
+ \Mfpic@msg{Don't forget to process \mfp@filename\mfp@ext!}%
+ \Mfpic@msg{Apply \mfp@progname\space to \mfp@filename\mfp@ext%
+ \mfp@ifmpost{}{, then gftopk to the resulting gf file}.}%
+ \Mfpic@msg{Then reprocess this file "\jobname".\@nl}%
+ \fi}%
+% \end{macrocode}
+%
+% A little bit of \LaTeX{} for checking file existence.
+% \begin{macrocode}
+\mfp@ifundefined\IfFileExists
+ \def\IfFileExists#1{\openin\mfp@graph=#1\relax
+ \ifeof\mfp@graph \@xp\@secondoftwo
+ \else \immediate\closein\mfp@graph \@xp\@firstoftwo
+ \fi}%
+ \def\InputIfFileExists#1#2{\IfFileExists{#1}{#2\input #1\relax}}%
+\mfp@enddef
+% \end{macrocode}
+%
+% The following is the code involved in opening the output file and
+% checking for the existence of already created figures.
+% \cs{mfp@checkoutput} checks if the output file of \MP{} or \MF{} exists.
+% The first argument is the extension of that output file (\file{tfm} for
+% \MF{}, the starting value of the figure counter for \MP{}). We use the
+% existence of that output as a signal that there are graphics to be
+% included.
+%
+% Based on the file existence, we set the values of the draft switch, and
+% issue a message. Any other actions needed are passed as \arg2 (it
+% exists) and \arg3 (it doesn't). These are nonempty only under the
+% \opt{metafont} option: we load the font only if the \file{.tfm} exists,
+% otherwise we use a the \texttt{dummy} font.
+%
+% We do not try to load a nonexistent 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.
+% \begin{macrocode}
+\newdef\mfp@checkoutput#1#2#3{%
+ \IfFileExists{\setfilename\mfp@filename{#1}}%
+ {\global\mfpicdraftfalse #2}%
+ {\global\mfpicdrafttrue #3\mfp@msg{}%
+ \Mfpic@msg{No file \setfilename\mfp@filename{#1}.}%
+ }}%
+\newdef\mfp@checkMPoutput{\mfp@checkoutput{\number\mfp@count}{}{}}%
+\newdef\mfp@checkMFoutput{\mfp@checkoutput{tfm}%
+ {\global\font\mfp@graphfont\mfp@filename\relax}%
+ {\global\let\mfp@graphfont\mfp@dummy}}%
+% \end{macrocode}
+%
+% For \opt{metapost} the output file needs to load some color macros, 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 more names for grayscales (even given
+% that \MF{} can find that file).
+% \begin{macrocode}
+\newdef\mfp@MPextras{\mfp@toks\@xp{\every@tlabel}%
+ \mfsrc{%
+ if unknown Apricot: input dvipsnam.mp; fi\@nl
+ verbatimtex\@nl
+ \ifmfp@verbtex \the\mfp@verbtex\@nl \fi
+ \relax\@nl
+ \noexpand\input mfpicdef.tex\relax\@nl
+ \def\noexpand\MFPeverylabel{\the\mfp@toks}\@nl
+ etex;\@nl
+ \mfp@ifdefined\mfp@settemplate\mfp@settemplate{}%
+ }%
+ \global\mfp@verbtexfalse \global\mfp@verbtex{}%
+% \end{macrocode}
+% Finally, we process the \MP{}-specific 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.
+% \begin{macrocode}
+ \@ifmplabels\usemplabels{}%
+ \ifmfp@truebbox \usetruebbox \fi
+ \ifmfp@overlabels \overlaylabels \fi}%
+% \end{macrocode}
+%
+% There are a couple of extras that are only needed by \MF{}, the mode
+% and resolution. Unlike the `MPextras' this does not write code, but
+% rather \emph{is} code to write. It will occur inside a \cs{write}
+% command.
+% \begin{macrocode}
+\def\mfp@MFextras{%
+ \mfp@ifdefined\mfp@resolution%
+ {GBresolution := \mfp@resolution;\@nl}{}%
+ \mfp@ifdefined\mfp@mode{mode := \mfp@mode;\@nl}{}}%
+% \end{macrocode}
+%
+% All the characters likely to cause problems in a filename are rendered
+% harmless with this command. We want to allow macros so backslashes,
+% braces and spaces aren't touched.
+% \begin{macrocode}
+\def\mfp@dospecials{\do\$\do\&\do\#\do\^\do\_\do\%\do\~}%
+% \end{macrocode}
+% \DescribeMacro{\opengraphsfile}
+% This is the main command to set up the output file.
+% 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. We first nullify \TeX{}
+% special characters, then read the graphfile name, then store an
+% expanded version.
+% \begin{macrocode}
+\mfp@DBlog{Macros to open and close graphs files.}%
+\newdef\opengraphsfile{\@bsphack
+ \begingroup
+ \let\do\@makeother
+ \mfp@dospecials\@opengraphsfile}%
+\newdef\@opengraphsfile#1{%
+ \xdef\mfp@tempa{#1}%
+ \endgroup
+% \end{macrocode}
+%
+% With the graphfile name safely stored, we check if a previous one had
+% been opened and close it if so. Then we store in \cs{mfp@filename}
+% a sanitized version of the name.
+%
+% A command can determine if it occurs after \cs{opengraphsfile} but
+% before \cs{closegraphsfile} by testing whether \cs{mfp@filename} is
+% defined. We also save the name of the processing program (\MF{} or \MP)
+% and the file extension (\file{.mf} of \file{.mp}) in macros for use in
+% messages.
+% \begin{macrocode}
+ \mfp@ifopengraphsfile%
+ {\Mfpic@warn
+ {\@nl An attempt has been made to open a graph file, %
+ \mfp@sanitized\mfp@tempa\@msgbreak
+ while another, \mfp@filename, is still open. \@msgbreak
+ Closing \mfp@filename.}\mfp@closegraphsfile}%
+ {}%
+ \xdef\mfp@filename{\mfp@sanitized\mfp@tempa}%
+ \xdef\mfp@progname{meta\mfp@ifmpost{pos}{fon}t}%
+ \xdef\mfp@ext{.m\mfp@ifmpost{p}{f}}%
+% \end{macrocode}
+%
+% These commands test for the existence of the graphics (\file{.tfm} file
+% or first EPS file) and provisionally set \cs{ifmfpicdraft} based on the
+% result. Then the \file{.mf} or \file{.mp} file is opened, and the
+% automatic settings of \cs{ifmfpicdraft}, etc., are overridden if the
+% user has explicitly chosen the \opt{draft} or \opt{final} option. The
+% \opt{nowrite} option merely disables the \cs{mfp@src} command, called
+% by all the commands that write to the file.
+% \begin{macrocode}
+ \mfp@ifmpost\mfp@checkMPoutput\mfp@checkMFoutput
+ \mfp@openfile
+ \ifmfp@draft \global\mfpicdrafttrue \fi
+ \ifmfp@final \global\mfpicdraftfalse \fi
+ \ifmfp@nowrite \gdef\mfp@src##1##2{\endgroup}\fi
+% \end{macrocode}
+%
+% Now we set up the header and preamble of the output file, writing
+% version info, initializations, version checking code and extra code
+% for \MP{}, if required.
+%
+% Finally, we process options as they are currently known. These were
+% delayed until now because they might require a write to the output file.
+% Finally, we read the \prog{meta*o*t} log file, if the option to do that
+% is in effect.
+% \begin{macrocode}
+ \mfsrc{\mfp@versioninfo \mfp@ifmpost{}\mfp@MFextras
+ \mfp@init@outfile \mfp@versioncheck}%
+ \mfp@ifmpost\mfp@MPextras{}%
+ \ifmfp@clip \clipmfpic \fi
+ \ifmfp@clearsym \clearsymbols \fi
+ \ifmfp@noship \stopshipping \fi
+ \ifmfp@readlog \mfp@readlogfile \fi
+ \@esphack}%
+% \end{macrocode}
+%
+% \DescribeMacro{\closegraphsfile}
+% This command finishes off the output file and undefines \cs{mfp@filename}.
+% We define an error message free version \cs{mfp@closegraphsfile} for
+% internal use. We unconditionally undefine \cs{mfp@filename} just in
+% case.
+% \begin{macrocode}
+\newdef\closegraphsfile{%
+ \mfp@ifopengraphsfile{}{\mfp@nooutput@error\closegraphsfile}%
+ \mfp@closegraphsfile}%
+\newdef\mfp@closegraphsfile{%
+ \mfp@ifopengraphsfile
+ {\ifmfp@nowrite \else
+ \mfsrc{\@nl end.}\immediate\closeout\mfp@out
+ \fi \global\let\mfp@filename\UndEfInEd}{}}%
+% \end{macrocode}
+%
+%
+% \subsection{Information from \MF: reading its log file}
+%
+% \DescribeMacro{\assignmfvalue}\SpecialUsageIndex{\globalassignmfvalue}
+% This macro was suggested by Werner Lemberg, who also supplied working
+% code. I have made modifications, so I am to blame if it has bugs. It
+% writes code to the \file{.mf} file that causes \MF{} to write
+% information to its \file{.log} file. If the option \opt{mfpreadlog} has
+% been set, that log file will be examined for that information. The
+% result, for example, of
+% \begin{verbatim}
+% \setmfvariable{numeric}{s}{10}
+% \assignmfvalue\foo{s+2}
+% \end{verbatim}
+% is that \cs{foo} will be a macro that expands to `\texttt{12}' (during
+% the \TeX{} run following the \MF{} pass). Under \opt{mplabels} a label
+% containing \cs{foo} will only be correct in the \file{.mp} file after
+% the second \MP{} pass, and so a third \TeX{} run may be required to
+% insert the correct figure. To implement localization, the code causes
+% the internal command \cs{mfpic-\meta{N}-foo} to be defined to the value,
+% where \meta{N} is the number of the current figure. The \cs{foo} is then
+% defined to the value of that internal command. Outside any \env{mfpic}
+% environment, the internal command is \cs{mfpic--foo}. If the \file{.log}
+% file doesn't exist or doesn't yet contain the information, \cs{foo} is
+% defined to `???'.
+%
+% While \cs{mfpicvalue} is merely a signal and doesn't need a
+% definition, we give it a useful definition for debugging: its own name.
+% It could be accidentally redefined by a user, but that will be harmless;
+% the debugging is mainly for me.
+%
+% It is possible to put \cs{global} in front of \cs{assignmfvalue} and
+% its macro will be defined globally in the \TeX{} run, but I could find
+% no way to make it global in the \file{.mp} file under \opt{mplabels}.
+% Thus, I've created a \cs{globalassignmfvalue}.
+% \begin{macrocode}
+\edef\mfpicvalue{\string\mfpicvalue}%
+\newdef\mfp@cmdname{%
+ mfpic-\ifin@mfpicenv\number\mfp@count\fi-\@xp\@gobble\string}%
+\newdef\assignmfvalue{\mfp@assign\@empty}%
+\newdef\globalassignmfvalue{\mfp@assign\global}%
+\newdef\mfp@assign#1#2#3{%
+ #1\edef#2{%
+ \@ifundefined{\mfp@cmdname#2}{???}{\@nameuse{\mfp@cmdname#2}}}%
+ \@ifundefined{\mfp@cmdname#2}%
+ {\mfp@msg{}\Mfpic@msg{No value for \string#2\ifin@mfpicenv\space
+ in mfpic figure \number\mfp@count\fi.\@nl}}%
+ {}%
+ \mfsrc{%
+ \@ifmplabels{\@nl verbatimtex #1\def\string#2{#2} etex;\@nl}{}%
+ message "\string\mfpicvalue";\@nl
+ message "\mfp@cmdname#2";\@nl
+ show #3;\@nl
+ message "";}}%
+\newlet\assignmpvalue\assignmfvalue
+\newlet\globalassignmpvalue\globalassignmfvalue
+% \end{macrocode}
+%
+% The following code is what really makes \cs{assignmfvalue} work. It is
+% similar to code in the \prog{metatex} package, adapted by Werner Lemberg
+% and then modified by me. It steps through the \mfpic{} output file looking
+% for this signal: a line containing only `\verb$\mfpicvalue$'. It then
+% reads the next line, creates a macro name from it, and assigns to that
+% macro the value it reads on the next line. This is repeated to the end
+% of the file.
+% \begin{macrocode}
+\newdef\strip@gtgt>> #1\mfp@end{#1}%
+\newdef\mfp@readlogfile{%
+ \openin\mfp@data=\mfp@filename.log\relax
+ \ifeof\mfp@data \Mfpic@msg{No file \mfp@filename.log.}%
+ \else
+ {%
+ \mfp@resetwhitespace \endlinechar -1
+ \catcode`\>12
+ \def\@mfpicvalue{\mfpicvalue}%
+ \message{< Mfpic: Reading \mfp@filename.log}%
+ \mfp@readloglines
+ \message{>}%
+ }%
+ \fi \closein\mfp@data}%
+\newdef\mfp@readloglines{%
+ \read\mfp@data to \mfp@tempa
+ \ifeof\mfp@data
+ \else
+ \ifx\mfp@tempa\@mfpicvalue
+ \read\mfp@data to \mfp@tempa
+ \read\mfp@data to \mfp@tempb
+ \@XP\xdef\@nameuse\mfp@tempa{\@xp\strip@gtgt\mfp@tempb\mfp@end}%
+ \fi
+ \@xp\mfp@readloglines
+ \fi}%
+% \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@dummy0pt
+% \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@fdc22
+% \end{macrocode}
+%
+% 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 \arg{1} to expand to a reference to the
+% \cs{fontdimen} with that number. The syntax it produces is valid as
+% the left side of a dimension assignment and also as a dimension
+% that may follow a real factor and \cs{the}. For example, later we say
+% \cs{newfdim}\cs{pointsize} and give it the value \texttt{2pt}. Then
+% \verb$\the\pointsize$ prints this value and
+% \verb$\pointsize = 0.5\pointsize$ is a valid assignment.
+% \begin{macrocode}
+\newdef\newfdim#1{%
+ \global\advance\mfp@fdc1
+ \xdef#1{\fontdimen\number\mfp@fdc\mfp@dummy}%
+ \wlog{\string#1=\fontdimen\number\mfp@fdc\mfp@dummy}}%
+% \end{macrocode}
+% \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.
+%
+% 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}%
+\newdef\tb@dp{\dp\@textbox}%
+\newdef\tb@wd{\wd\@textbox}%
+% \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 three of the sides (We don't need the fourth). The box
+% \cs{@backtext} holds `background text', that is, text accumulated
+% between \cs{startbacktext} and \cs{stopbacktext}.
+% \begin{macrocode}
+\newbox\@alltlabels
+\newbox\@backtext
+\newfdim\@tlabelstop
+\newfdim\@tlabelsbot
+\newfdim\@tlabelsleft
+% \end{macrocode}
+%
+% The following fontdims record the dimensions of the box containing the
+% picture. We need to adjust them when the text labels are added to the
+% picture, because \TeX{} doesn't do it automatically. For example,
+% kerning left outside the picture will not change the picture box's
+% reference point.
+% \begin{macrocode}
+\mfp@DBlog{Internal dimension parameters for graph dimensions...}%
+\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 third is for the feature that the label can be a
+% certain distance separated from the point where it is placed. And the
+% last establishes the distance between a label and a path surrounding it.
+% \begin{macrocode}
+\newfdim\tlabel@hadj
+\newfdim\tlabel@vadj
+\newfdim\tlabel@sep
+\newfdim\tlpath@sep
+\tlabel@hadj0pt
+\tlabel@vadj0pt
+\tlabel@sep0pt
+\tlpath@sep0pt
+% \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 synchrony 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.
+%
+% The following are default parameters for various graphics commands that
+% take an optional argument for the size of something.
+% \begin{itemize}
+% \item\cs{mfpicunit}\SpecialUsageIndex{mfpicunit}, the unit of length in
+% a picture. \cs{@mfpicunit} is used internally.
+% \item\cs{pointsize}\SpecialUsageIndex{pointsize}, the diameter of a
+% \cs{point}.
+% \item\cs{shadespace}\SpecialUsageIndex{shadespace}, the spacing of dots
+% in \cs{shade}.
+% \item\cs{polkadotspace}\SpecialUsageIndex{polkadotspace}, the spacing of
+% polkadots.
+% \item\cs{hatchspace}\SpecialUsageIndex{hatchspace}, the spacing of hatch
+% lines.
+% \item\cs{headlen}\SpecialUsageIndex{headlen}, the size of arrowheads
+% (except on axes).
+% \item\cs{axisheadlen}\SpecialUsageIndex{axisheadlen}, the size of the
+% arrowhead for $x$- and $y$-axes.
+% \item\cs{sideheadlen}\SpecialUsageIndex{sideheadlen}, the size of the
+% arrowhead for border axes.
+% \item\cs{hashlen}\SpecialUsageIndex{hashlen}, the length of tic marks on
+% axes.
+% \item\cs{dashlen}\SpecialUsageIndex{dashlen}, the length of dashes in
+% \cs{dashed}.
+% \item\cs{dashspace}\SpecialUsageIndex{dashspace}, the space between such
+% dashes.
+% \item\cs{dotsize}\SpecialUsageIndex{dotsize}, the size of dots for
+% \cs{dotted}.
+% \item\cs{griddotsize}\SpecialUsageIndex{griddotsize}, the size of dots
+% for \cs{grid} and \cs{plrgridpoints}.
+% \item\cs{dotspace}\SpecialUsageIndex{dotspace}, the space between such
+% dots.
+% \item\cs{symbolspace}\SpecialUsageIndex{symbolspace}, the space between
+% symbols used in a \cs{plot} command.
+% \end{itemize}
+% We allocate them, and then initialize them.
+% \begin{macrocode}
+\mfp@DBlog{User level dimension parameters, with default settings.}%
+\newfdim\mfpicunit
+\newfdim\@mfpicunit % internal version
+\newfdim\pointsize
+\newfdim\shadespace
+\newfdim\polkadotspace
+\newfdim\hatchspace
+\newfdim\headlen
+\newfdim\axisheadlen
+\newfdim\sideheadlen
+\newfdim\hashlen
+\newfdim\dashlen
+\newfdim\dashspace
+\newfdim\dotsize
+\newfdim\griddotsize
+\newfdim\dotspace
+\newfdim\symbolspace
+\mfpicunit1pt
+\pointsize2pt
+\shadespace1pt
+\polkadotspace10pt
+\hatchspace3pt
+\headlen3pt
+\axisheadlen5pt
+\sideheadlen0pt
+\hashlen4pt
+\dashlen4pt
+\dashspace4pt
+\dotsize0.5pt
+\griddotsize0.5pt
+\dotspace3pt
+\symbolspace5pt
+% \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
+% (all the \cs{@graph...}, \cs{@tlabels...} and \cs{tb@...}) 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
+ \griddotsize \the\griddotsize
+ \dotspace \the\dotspace
+ \symbolspace \the\symbolspace
+ \tlabel@hadj \the\tlabel@hadj
+ \tlabel@vadj \the\tlabel@vadj
+ \tlabel@sep \the\tlabel@sep
+ \tlpath@sep \the\tlpath@sep}}%
+% \end{macrocode}
+%
+% Here are the few dimension registers we do allocate:
+% \SpecialUsageIndex{\mfpframesep}\cs{mfpframesep}, and
+% \SpecialUsageIndex{\mfpframethickness}\cs{mfpframethickness}
+% govern frames.
+% \SpecialUsageIndex{\mfpicheight}\cs{mfpicheight} and
+% \SpecialUsageIndex{\mfpicwidth}\cs{mfpicwidth} are set
+% after each picture to that picture's size. A \cs{vskip} of
+% \SpecialUsageIndex{\mfpiccaptionskip}\cs{mfpiccaptionskip} is placed
+% between figure and caption by \cs{tcaption}. We also allocate a
+% frequently used scratch register
+% \begin{macrocode}
+\newdimen\mfp@scratch
+\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 original purpose of this is so that the font file could have
+% characters in the positions 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
+% sequence of black and white squares. For \MP{} users it is not very
+% important.
+% \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[] \arg{1} is a \emph{macro} that expands to some number.
+% \item[] \arg{2} is a number to add to it.
+% \end{itemize}
+% The result is stored again in \arg{1}, overwriting the old value.
+%
+% \DescribeMacro{\mfpmultiply}
+% This is the multiplicative version, with the same syntax and behavior.
+% It is not used anywhere yet.
+% \begin{macrocode}
+\newdef\mfpaddto#1#2{\mfp@scratch#1pt \advance\mfp@scratch#2pt
+ \edef#1{\strip@pt\mfp@scratch}}%
+\newdef\mfpmultiply#1#2{\mfp@scratch#1pt \mfp@scratch#2\mfp@scratch
+ \edef#1{\strip@pt\mfp@scratch}}%
+\mfp@ifundefined\strip@pt
+ \begingroup
+ \lccode`\/`\p
+ \lccode`\?`\t
+ \lowercase{%
+ \endgroup
+ \def\rem@pt#1.#2/?}{#1\ifnum#2>\z@.#2\fi}%
+ \def\strip@pt{\@xp\rem@pt\the}%
+\mfp@enddef
+% \end{macrocode}
+%
+% \DescribeMacro{\pointdef}
+% A point defining macro, suggested by a user.
+% \begin{itemize}
+% \item[] \arg{1} is a symbolic name for a point, only letters.
+% \item[] \arg{2} and \arg{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){%
+ \@ifundefined{#1} {}{\Mfpic@warn{\mfp@b#1 already defined.}}%
+ \@ifundefined{#1x}{}{\Mfpic@warn{\mfp@b#1x already defined.}}%
+ \@ifundefined{#1y}{}{\Mfpic@warn{\mfp@b#1y already defined.}}%
+ \@namedef{#1}{(#2,#3)}\@namedef{#1x}{#2}\@namedef{#1y}{#3}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\setmfarray}
+% This enables the simultaneous definition of \MF{} (or \MP) variables
+% such as \mfc{A1}, \mfc{A2}, etc., by writing
+% \cs{setmfarray}\marg{\meta{type}}\marg{\meta{name}}\marg{\meta{list}},
+% the \meta{name} being any \MF{} variable without a suffix, the list being
+% a comma separated list of items of the appropriate \meta{type}.
+% For example, \cs{setmfarray}\marg{pair} would require a list of
+% pairs.
+%
+% \SpecialUsageIndex{\numericarray}
+% As with \cs{setmfvariable}, we provide a few abbreviations.
+% \cs{numericarray} is for arrays of numeric variables,
+% \SpecialUsageIndex{\pairarray} \cs{pairarray} for arrays of pair
+% variables and \SpecialUsageIndex{\colorarray}\cs{colorarray} is for
+% arrays of color variables. Finally, to set arrays globally, there is
+% \SpecialUsageIndex{\globalsetmfarray}\cs{globalsetmfarray}.
+% \begin{macrocode}
+\newdef\setmfarray#1#2{\mfsrc{setarray (#1) (#2)}\mfp@writedata}%
+\newlet\setmparray\setmfarray
+\newdef\pairarray{\setmfarray{pair}}%
+\newdef\numericarray{\setmfarray{numeric}}%
+\newdef\colorarray{\setmfarray{color}}%
+\newdef\rgbcolorarray{\setmfarray{rgbcolor}}%
+\newdef\cmykcolorarray{\setmfarray{cmykcolor}}%
+\newdef\globalsetmfarray#1#2{\mfsrc{gsetarray (#1)(#2)}\mfp@writedata}%
+\newlet\globalsetmparray\globalsetmfarray
+% \end{macrocode}
+%
+% \DescribeMacro{\lightershade}
+% Shade adjustment macros. \cs{lightershade} just multiplies
+% \cs{shadespace} by $1.2$.
+% \DescribeMacro{\darkershade}
+% While \cs{darkershade} divides by $1.2$ (actually, multiplies by
+% $1/1.2$)
+% \begin{macrocode}
+\newdef\lightershade{\shadespace1.2\shadespace}%
+\newdef\darkershade{\shadespace.83333\shadespace}%
+% \end{macrocode}
+%
+% \DescribeMacro{\dashlineset}
+% The following arrange for contrastive dashed lines. \cs{dashlineset}
+% just resets the default parameters that the \cs{dashed} macro uses,
+% \DescribeMacro{\dotlineset}
+% \cs{dotlineset} sets these parameters so that \cs{dashed} produces
+% something almost dotted.
+% \begin{macrocode}
+\newdef\dashlineset{\dashlen4pt \dashspace4pt }%
+\newdef\dotlineset{\dashlen1pt \dashspace2pt }%
+% \end{macrocode}
+%
+% \DescribeMacro{\pointfilltrue}
+% 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
+% \DescribeMacro{\pointfillfalse}
+% not.
+% \begin{macrocode}
+\let\ifpointfill\iftrue
+\newdef\pointfilltrue{\mfp@let\ifpointfill\iftrue}%
+\newdef\pointfillfalse{\mfp@let\ifpointfill\iffalse}%
+% \end{macrocode}
+%
+% \CMF{} has very flexible looping capabilities. Before version 0.8 there
+% was no \mfpic{} interface because it seemed that \cs{mfsrc} was the
+% simplest way to access this capability. Anything else would have to
+% be either a clone of \cs{mfsrc} or limit the possibilities. However, I
+% now believe it might be a good thing to have a structured way to perform
+% repetitive actions at the \MF{} level.
+%
+% As of version 0.9, \mfpic{} will allow loops outside \env{mfpic}
+% environments. It seems like a reasonable thing to be allowed to do.
+% Fortunately, the macro names are already unique.
+%
+% \DescribeMacro{\mfpfor}
+% This is the simplest: it writes the word \mfc{for} plus the contents of
+% its only mandatory argument, followed by a colon. The loop is ended by
+% \DescribeMacro{\endmfpfor}
+% \cs{endmfpfor} which merely writes the text \mfc{endfor}.
+% \begin{macrocode}
+\newdef\mfpfor#1{\begingroup\mfsrc{for #1:}}%
+\newdef\endmfpfor{\mfsrc{endfor}\endgroup}%
+% \end{macrocode}
+%
+% \DescribeMacro{\mfploop}
+% The macro \cs{mfploop} starts a loop with \mfc{forever}. The user is
+% expected to provide an escape condition with
+% \DescribeMacro{\mfpuntil}
+% \cs{mfpuntil}, which can be placed anywhere among the commands contained
+% in the \env{mfploop} environment.
+% \DescribeMacro{\endmfploop}
+% The macro \cs{endmfploop} is a clone of \cs{endmfpfor} except for the
+% warning. Grouping keeps the warning from being turned off if
+% \cs{mfpuntil} occurs in a nested loop.
+% \begin{macrocode}
+\newdef\mfploop{%
+ \begingroup\mfsrc{forever:}\let\@nountil\mfp@untilwarn}%
+\newdef\mfpuntil#1{\mfcmd{exitif #1}\let\@nountil\@empty}%
+\newdef\endmfploop{\@nountil\endmfpfor}%
+% \end{macrocode}
+%
+% \DescribeMacro{\mfpwhile}
+% This emulates a while-loop, the condition being given in the mandatory
+% argument. It has the same behavior, and writes almost the same code as
+% \cs{mfploop} with an immediate \cs{mfpuntil} using the negative of the
+% condition.
+% \DescribeMacro{\endmfpwhile}
+% The closing, \cs{endmfpwhile}, is again the same as \cs{endmfpfor}.
+% \begin{macrocode}
+\newdef\mfpwhile#1{\begingroup\mfcmd{forever: exitif not(#1)}}%
+\newlet\endmfpwhile\endmfpfor
+% \end{macrocode}
+%
+% \DescribeMacro{\plr}
+% 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. This is guaranteed to work as
+% expected only in macros with a list argument, or for a single pair.
+% \DescribeMacro{\midpoint}
+% And one to calculate the midpoint, given two points separated by a comma.
+% Can be used in graphics macros where a point is required.
+% \begin{macrocode}
+\newdef\plr#1{map (polar) (#1)}%
+\newdef\midpoint#1{(0.5[#1])}%
+% \end{macrocode}
+%
+%
+%
+% \section{Macros to implement prefix commands}\label{prefix}
+%
+% Some \mfpic{} macros, like \cs{circle} create a path. When used without
+% a prefix, they also draw the path. At the \MF{} level, every figure
+% macro is syntactically a path expression. Other macros are prefix macros
+% and operate on a figure macro that follows. 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 apply 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, a figure
+% macro needs to know if a rendering prefix has occured, so prefix macros
+% need to pass information to the figure macro (and to later prefixes).
+%
+% 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. Thus, 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}
+\mfp@DBlog{Tests to control multiple prefix commands.}%
+\newif\if@mfpstart\@mfpstarttrue
+% \end{macrocode}
+%
+% If a prefix is a rendering prefix, it writes its 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.
+% Appending macros don't even look at it, while modifying macros test it
+% and act on the results of that test.
+% \begin{macrocode}
+\newif\if@mfprend\@mfprendtrue
+% \end{macrocode}
+%
+% The following macro is always (and only) invoked by the first prefix
+% macro (or the figure macro, if there are no prefixes). 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\mfp@storepath{\mfsrc{\@nl store (curpath)}}%
+% \end{macrocode}
+%
+% Every prefix and figure macro has to invoke \cs{mfp@first}, since each
+% is potentially the first in the sequence. If \cs{@mfpstart} is true, it
+% writes the storing command, sets \cs{@mfpstartfalse}, and says that
+% rendering is needed. (The rendering macros immediately cancel that
+% switch.)
+% \begin{macrocode}
+\newdef\mfp@first{\relax
+ \if@mfpstart \mfp@storepath \@mfprendtrue \@mfpstartfalse\fi}%
+% \end{macrocode}
+%
+% Every rendering macro invokes this next 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\mfp@rendmac{\mfp@first \@mfprendfalse \mfsrc}%
+% \end{macrocode}
+%
+% The \emph{figure} macros proceed as follows: (i)~they invoke the
+% \cs{mfp@first} code, then (ii)~write a rendering macro if necessary
+% (\cs{mfp@autorend}), (iii)~then make \cs{@mfpstarttrue} (for the next
+% figure) and write \MF{} code that defines the path. The \cs{mfp@modmac}
+% macros do only the first two, then write their modification code,
+% counting on the following figure macro to do (iii). The idea is that
+% [modifier + figure] should act the same as if the path it defines were
+% encoded as a single figure command.
+% \begin{macrocode}
+\newdef\mfp@modmac{\mfp@first\mfp@autorend\mfsrc}%
+\newdef\mfp@autorend{\if@mfprend\@xp\mfp@render\fi}%
+% \end{macrocode}
+%
+% Only axis and arrow commands (plus \cs{reverse}) use \cs{mfp@addmac}.
+% As the name suggests, something is added onto an existing figure. That
+% is, it is designed to ignore the rendering state and not invoke implicit
+% rendering. If no explicit rendering occurs, the figure macro that
+% follows invokes a rendering. For arrows, this causes the arrowhead to be
+% drawn on top of the drawing of the shaft.
+%
+% It would seem \cs{reverse} doesn't fit this name, but it also needs to
+% be transparent to the rendering state so that it will work in
+% combination with arrows.
+%
+% \cs{mfp@addmac} simply invokes the common first-stage code and writes
+% its \MF{} code.
+% \begin{macrocode}
+\newdef\mfp@addmac{\mfp@first \mfsrc}%
+% \end{macrocode}
+%
+% The \cs{mfp@addmac} and \cs{mfp@modmac} macros differ when there are no
+% preceeding rendering macros. In that case it is as if \cs{draw} (or
+% more generally \cs{mfp@render}) precedes the \cs{mfp@modmac} macro. That
+% drawing happens \emph{in addition to} any rendering macros that follow.
+% This implicitly added \cs{draw} is not present for \cs{mfp@addmac}
+% macros; it is added by the following figure macro. The effect of this is
+% the \cs{mfp@addmac} macros perform their additions on top of an already
+% rendered figure.
+%
+% \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 a macro
+% and can be changed for special effects. Initially we define it as
+% \cs{draw} (with empty optional argument) to draw solid paths in the
+% default color, but we provide a command for the user to change it.
+% \begin{macrocode}
+\newdef\mfp@render{\draw[]}%
+\newdef\setrender{\mfp@def\mfp@render}%
+% \end{macrocode}
+%
+% A figure macro will invoke the common first-stage code and the rendering
+% check. It also resets the \cs{@mfpstart} switch. Because a figure macro
+% completes an assignment command in \MF, it writes its code with
+% \cs{mfcmd}, which places a semicolon at the end. 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\mfp@figmacbase{\mfp@first \mfp@autorend \@mfpstarttrue}%
+\newdef\mfp@figmac{\mfp@figmacbase\mfcmd}%
+% \end{macrocode}
+%
+% The list macros take as their last argument a list of $(x,y)$ pairs (or
+% occasionally a list of numbers). 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 within an enclosing pair of parentheses. Since these are all
+% figure macros, \cs{mfp@listmac} starts out just like \cs{mfp@figmac},
+% but it writes only part of its arguments, the last one (the data list)
+% 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\mfp@listmac#1{\mfp@figmacbase\mfsrc{#1}\mfp@writedata}%
+\newdef\mfp@writedata{\mfp@iftoken\datafile{\mfp@writefile}{\mflist}}%
+\newdef\mfp@writefile{%
+ \mfp@ifopengraphsfile
+ {\mfp@processfile{\mfp@rwdata}}{\mfp@nooutput@error\datafile}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\mftitle}
+% This is mainly for debugging the example files. \cs{mfp@title} takes
+% two arguments: the command that called it (for the error message of
+% \cs{mfp@src}), and some \TeX{} code. That code is written into the string
+% argument of the \grafbase{} command \gbc{mftitle} and ends up in the
+% \MF{} \file{.log} file and as a comment in the GF file. \cs{mftitle}
+% merely calls \cs{mfp@title}, while
+% \DescribeMacro{\tmtitle}
+% \cs{tmtitle} also writes the argument to the \TeX{} \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}
+\newdef\mftitle#1{\@bsphack\mfp@title\mftitle{#1}\@esphack}%
+\newdef\tmtitle#1{\mfp@title\tmtitle{#1}\wlog{\the\mfp@toks}{#1}}%
+\newdef\mfp@title#1#2{\mfp@toks{#2}%
+ \mfp@write\mfp@src#1{mftitle "\the\mfp@toks";}}%
+% \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 second parameter is the filename, the first 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 this group but not any enclosing
+% group.
+% \begin{macrocode}
+\newdef\mfp@processfile#1#2{%
+ \openin\mfp@data=#2\relax
+ \ifeof\mfp@data \mfp@nofile@error{#2}%
+ \else
+ \mfp@DBlog{Opening file #2 for data.}%
+ {%
+ \mfp@resetwhitespace \mfp@setcomment
+ \mfp@skipblanklines
+ \ifeof\mfp@data
+ \mfp@nodata@error{#2}%
+ \else
+ \message{< Mfpic: Reading #2}%
+ #1%
+ \message{>}%
+ \fi
+ \@xp
+ }\@xp\mfp@linetype\number\mfp@linetype\relax
+ \mfp@DBlog{Closing file #2.}%
+ \fi
+ \closein\mfp@data}%
+% \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{\mfp@restorepar
+ \endlinechar`\^^M \catcode`\^^M5 \catcode`\ 10 \catcode`\^^I10 }%
+% \end{macrocode}
+%
+% \cs{mfp@skipcomments}
+% 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, a blank line would put a \cs{par} token in \cs{mfp@data}).
+% When this macro finishes, \cs{mfp@temp} contains either \cs{par} (blank
+% line or EOF) or real data.
+% \begin{macrocode}
+\newdef\mfp@skipcomments{\read\mfp@data to \mfp@temp
+ \ifx\mfp@temp\@empty \@xp\mfp@skipcomments\fi}%
+% \end{macrocode}
+%
+% \cs{mfp@skipblanklines}
+% 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 other case (something else) it also terminates,
+% having presumably found real data.
+%
+% When this is called, a file should already be open using the handle
+% \cs{mfp@data}.
+% \begin{macrocode}
+\newdef\mfp@skipblanklines{\mfp@skipcomments
+ \ifeof\mfp@data
+ \else\ifx\mfp@temp\mfp@par \@XP\mfp@skipblanklines
+ \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{mfp@processfile}).
+%
+% The figure counter \cs{mfp@count} is reused (this should all be inside
+% a group) 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 \cs{mfp@rwdata} 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 remaining reading and all the writing.
+% \begin{macrocode}
+\newdef\mfp@nextdatum{\@xp\parse@data\mfp@temp\mfp@end}%
+\newdef\mfp@rwdata{\mfp@count1 \mfp@sequence1
+ \def\sequence{\number\mfp@sequence}%
+ \edef\mfp@temp{\mfp@temp\space}%
+ \edef\mfp@buffer{(\mfp@nextdatum}\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 have
+% read another datum and then we:
+% \begin{enumerate}
+% \item increment the sequence counter,
+% \item add a comma to the buffer,
+% \item test whether the buffer is `full', and if so, write the buffer
+% to the output and clear it, then
+% \item add the datum to the buffer.
+% \end{enumerate}
+% The buffer is `full' when \cs{mfp@count} (the number of data in the
+% buffer) exceeds \cs{mfp@dataperline}.
+%
+% \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}
+\newdef\mfp@rwdataloop{%
+ \read\mfp@data to \mfp@temp
+ \ifx\mfp@temp\mfp@par
+ \mfcmd{\mfp@buffer)}%
+ \else
+ \ifx\mfp@temp\@empty
+ \else
+ \edef\mfp@temp{\mfp@temp\space}%
+ \advance\mfp@sequence1
+ \edef\mfp@buffer{\mfp@buffer\mfp@join}%
+ \ifnum\mfp@count<\mfpdataperline\relax \advance\mfp@count1
+ \else \mfsrc{\mfp@buffer}\mfp@count1 \def\mfp@buffer{}%
+ \fi
+ \edef\mfp@buffer{\mfp@buffer\mfp@nextdatum}%
+ \fi
+ \@xp\mfp@rwdataloop
+ \fi}%
+% \end{macrocode}
+%
+% \section{Various \mfpic{} Settings.}\label{mfpsettings}
+%
+% \subsection {\CMF{} settings}\label{MFsettings}
+%
+% \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}).
+%
+% \SpecialUsageIndex{\drawpen}
+% \cs{drawpen} was the original command used to set the pen diameter
+% (prior to version 0.2.13). At some point it was replaced by
+% \SpecialUsageIndex{\pen}\cs{pen}. However \cs{penwd} seems to be more
+% consistent with other commands (e.g., \cs{shadewd}), and we keep all three.
+% \begin{macrocode}
+\newdef\pen#1{\mfcmd{\@nl resizedrawpen (#1)}}%
+\newlet\penwd\pen \newlet\drawpen\pen
+% \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 is set by \cs{hatchwd}.
+% \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 an array of lengths. The
+% \grafbase{} command \gbc{dashpat} accepts a name, and a sequence of
+% numbers representing the sizes of dashes and spaces, and builds this
+% array. It differs from \cs{numericarray} in that a little additional
+% checking is done (at the \grafbase{} level).
+% \begin{macrocode}
+\newdef\dashpattern#1{\mfsrc{save #1; dashpat (#1)}\mfp@writedata}%
+% \end{macrocode}
+%
+% \DescribeMacro{\settension}
+% This sets the default tension for any command (for example, \cs{curve})
+% that takes an optional argument that contains a tension value. This
+% includes also \cs{function}, \cs{plrfcn}, \cs{fcncurve}, \cs{datafile},
+% \cs{plotdata}. 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}
+%
+% \subsection{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{mplabels}.
+%
+% 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). Making the defaults
+% negative means they must be handled by the \cs{else} portion of any
+% \cs{ifcase}.
+%
+% The rotation part is just saved in \cs{tl@rot}. This is 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
+\newdef\mfp@tlh@l{-1}%
+\newdef\mfp@tlh@c{0}%
+\newdef\mfp@tlh@r{1}%
+\newdef\mfp@tlv@B{-1}%
+\newdef\mfp@tlv@b{0}%
+\newdef\mfp@tlv@c{1}%
+\newdef\mfp@tlv@t{2}%
+\newdef\tl@rot{}\tl@vpos-1 \tl@hpos-1
+\newdef\tlabeljustify#1{\mfp@ifexist{#1}{\mfp@justify#1\mfp@end}}%
+\newdef\mfp@justify#1#2\mfp@end{\mfp@local\mfp@vconv{#1}%
+ \mfp@ifexist{#2}{\mfp@@justify#2\mfp@end}}%
+\newdef\mfp@@justify#1#2\mfp@end{\mfp@local\mfp@hconv{#1}%
+ \mfp@local\edef\tl@rot{#2}%
+ \@ifmplabels{}%
+ {\mfp@ifexist{#2}%
+ {\Mfpic@warn{Rotation of labels is not supported without the %
+ mplabels\@msgbreak option. Rotation setting\on@line\space
+ may be ignored.}}%
+ }}%
+\newdef\mfp@vconv#1{%
+ \@ifundefined{mfp@tlv@#1}%
+ {\tl@vpos-1 \mfp@justify@error}%
+ {\tl@vpos\@nameuse{mfp@tlv@#1}\relax}}%
+\newdef\mfp@hconv#1{%
+ \@ifundefined{mfp@tlh@#1}%
+ {\tl@hpos-1 \mfp@justify@error}%
+ {\tl@hpos\@nameuse{mfp@tlh@#1}\relax}}%
+% \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 are passed to \cs{tlabeljustify} when no justification
+% parameter is present for a \cs{tlabel}-path command.
+% \begin{macrocode}
+\newdef\tlpathjustify#1{%
+ \mfp@ifexist{#1}{\tlp@justify#1\mfp@end}}%
+\newdef\tlp@justify#1#2\mfp@end{\mfp@def\tlpath@v{#1}%
+ \mfp@ifexist{#2}{\tlp@@justify#2\mfp@end}}%
+\newdef\tlp@@justify#1#2\mfp@end{%
+ \mfp@def\tlpath@h{#1}\mfp@def\tlpath@r{#2}}%
+\tlpathjustify{cc}%
+% \end{macrocode}
+%
+% \DescribeMacro{\tlpointsep}
+% This takes an absolute length as its argument and sets parameters that
+% determine by how much a tlabel 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.
+%
+% \DescribeMacro{\tlpathsep}
+% This takes an absolute length and sets parameters that determine by how
+% much a path created by one of the \cs{tlabel\meta{path}} macros is
+% separated from the label it surrounds.
+%
+% \DescribeMacro{\tlabelsep}
+% This simply issues both the above commands. This is for compatibility
+% with \mfpic{} versions 0.7 or earlier, where both these separations were
+% determined by the same parameters.
+%
+% \DescribeMacro{\tlabeloffset}
+% \cs{tlabeloffset}, on the other hand, takes two arguments: dimensions,
+% representing offsets of labels from their point of placement. 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\tlpointsep#1{\mfp@local\tlabel@sep#1\relax
+ \setmfnumeric{label_sep}{\the\tlabel@sep}}%
+\newdef\tlpathsep#1{\mfp@local\tlpath@sep#1\relax
+ \setmfnumeric{labelpath_sep}{\the\tlpath@sep}}%
+\newdef\tlabelsep#1{\tlpointsep{#1}\tlpathsep{#1}}%
+\newdef\tlabeloffset#1#2{%
+ \mfp@local\tlabel@hadj#1\relax \mfp@local\tlabel@vadj#2\relax
+ \setmfpair{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 code to be
+% inserted before the label code, outside these groups. The messing around
+% with the token register \cs{mfp@toks} is so one can put definitions in
+% the code without having to double \arg{} characters.
+%
+% The command \cs{extra@endtlabel} is called at the end of every
+% \cs{tlabel}. Normally it does nothing, but the \cs{tlabels} command
+% defines it to repeat the start of a loop.
+% \begin{macrocode}
+\newdef\everytlabel{\afterassignment\mfp@everytlabel\mfp@toks}%
+\newdef\mfp@everytlabel{\mfp@local\edef\every@tlabel{\the\mfp@toks}%
+ \mfp@ifmpost
+ {\mfp@ifopengraphsfile
+ {\mfcmd{verbatimtex\@nl
+ \def\noexpand\MFPeverylabel{\the\mfp@toks} etex}}%
+ {}}%
+ {}}%
+\newdef\every@tlabel{}%
+\newdef\extra@endtlabel{}%
+% \end{macrocode}
+%
+% Without \opt{mplabels} it is impossible to use \MP{} variables in
+% a text label placement parameter. I have occasionally found it useful
+% to have a \TeX{} version of the numeric variable \gbc{pi}.
+% \begin{macrocode}
+\newdef\pinumber{3.14159}%
+% \end{macrocode}
+%
+% \subsection{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. It would be more consistent with other
+% commands to have one \TeX{} parameter with commas separating the
+% components, but this is legacy code.
+% \begin{macrocode}
+\newdef\headshape#1#2#3{\mfcmd{\@nl headshape (#1, #2, #3)}}%
+% \end{macrocode}
+%
+% There are up to 4 optional arguments to any given \cs{arrow} command,
+% and these can take any one of 6 special indicators ({\mytt b}, {\mytt c},
+% {\mytt f}, {\mytt l}, {\mytt r} or {\mytt s}). Here we define macros
+% to handle these options. Each macro is fed a \emph{value}. For example,
+% the indicator {\mytt b} must be followed by a length, and that length is
+% the argument of \cs{mfp@arr@b}.
+% \begin{macrocode}
+\newdef\mfp@arr@b#1{\edef\mfp@hlocate{#1}}%
+\newdef\mfp@arr@c#1{\edef\mfp@hcolour{#1}}%
+\newdef\mfp@arr@l#1{\edef\mfp@hlength{#1}}%
+\newdef\mfp@arr@r#1{\edef\mfp@hrotate{#1}}%
+\newlet\mfp@arr@f\mfp@arr@b
+\newlet\mfp@arr@s\mfp@arr@l
+% \end{macrocode}
+%
+% The \cs{arc} and \cs{circle} commands take an optional argument that
+% indicates how the arc or circle is defined (and therefore the format of
+% the non-optional argument). These are passed to different \grafbase{}
+% commands whose names start with \gbc{arc} or \gbc{circle}. The commands
+% below store the rest of that name. The switch is set true by the
+% \cs{arc} command and false by \cs{circle}.
+% \begin{macrocode}
+\newdef\mfp@arc@s{pps}%
+\newdef\mfp@arc@t{ppp}%
+\newdef\mfp@arc@p{\ifmfp@switch plr\fi}%
+\newdef\mfp@arc@a{\ifmfp@switch alt\fi}%
+\newdef\mfp@arc@c{cp\ifmfp@switch s\fi}%
+\newdef\mfp@arc@r{pp (\mfp@T)}%
+\newdef\mfp@arc@q{pp (\mfp@F)}%
+% \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}.
+%
+% Several commands are provided to set certain special colors. Currently
+% we have the following commands, setting the color of the same name as
+% the command (except \cs{backgroundcolor} which sets a color named
+% \gbc{background}):
+% \cs{drawcolor}\SpecialUsageIndex{\drawcolor},\\
+% \cs{fillcolor}\SpecialUsageIndex{\fillcolor},
+% \cs{hatchcolor}\SpecialUsageIndex{\hatchcolor},
+% \cs{headcolor}\SpecialUsageIndex{\headcolor},
+% \cs{pointcolor}\SpecialUsageIndex{\pointcolor},
+% \cs{tlabelcolor}\SpecialUsageIndex{\tlabelcolor}, and\\
+% \cs{backgroundcolor}\SpecialUsageIndex{\backgroundcolor}.
+%
+% These commands support the \LaTeX-like syntax:\\
+% \indent\cs{fillcolor}\oarg{\meta{model}}\marg{\meta{parameters}}.\\
+% The code for \cs{backgroundcolor} has to be spelled out since the
+% command name has the string `\texttt{color}', but the color does not.
+% \begin{macrocode}
+\newdef\mfpdefinecolor#1#2#3{\setmfcolor{#1}{#2(#3)}}%
+\newdef\mfp@defclr#1#2#3{%
+ \setmfcolor{#1}{\mfp@ifempty{#2}{#3}{#2(#3)}}}%
+\newdef\mfp@newcolorcmd#1{%
+ \@namedef{#1\mfp@C}{\mfp@nullopt{\mfp@defclr{#1\mfp@C}}}}%
+\mfp@newcolorcmd{draw}\mfp@newcolorcmd{fill}\mfp@newcolorcmd{tlabel}%
+\mfp@newcolorcmd{hatch}\mfp@newcolorcmd{head}\mfp@newcolorcmd{point}%
+\def\backgroundcolor{\mfp@nullopt{\mfp@defclr{background}}}%
+% \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{colortype7}. 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 \mfp@b coloredlines 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}
+% The user-level command \cs{mfplinetype} allows the user to set the
+% starting value of \cs{mfp@linetype}. The default is to start at $0$.
+% \DescribeMacro{\mfplinestyle}
+% The macro \cs{mfplinestyle} is an alias for this same command. The names
+% `linestyle' and `linetype' come from an analogous system of changing
+% rendering in \prog{gnuplot}. (The reason for two names is that
+% \prog{gnuplot} documentation was not consistent in its terminology.)
+% \begin{macrocode}
+\newdef\mfplinetype#1{\mfp@local\mfp@linetype#1\relax}%
+\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}
+% The main user-level command for setting the above offsets is
+% \cs{axismargin}. Its first argument 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}.
+% \DescribeMacro{\setaxismargins}
+% The arguments of \cs{setaxismargins} are four offsets for the axes (in
+% the above order, which is anticlockwise, starting with the left).
+% \DescribeMacro{\setallaxismargins}
+% \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 six nested \cs{if}\,s).
+% Plus we get to define the error message only once. The first argument
+% of \cs{mfp@getaxis} is the letter and the third argument is the calling
+% command (for the error message). We allow the letter to be instead a word,
+% using only the first letter and discarding the rest (\arg2).
+% \begin{macrocode}
+\def\mfp@axis@x{0}%
+\def\mfp@axis@y{1}%
+\def\mfp@axis@l{2}%
+\def\mfp@axis@b{3}%
+\def\mfp@axis@r{4}%
+\def\mfp@axis@t{5}%
+\def\mfp@getaxis#1#2\mfp@end#3{%
+ \@ifundefined{mfp@axis@#1}%
+ {\mfp@errmsg {Invalid axis letter "#1"}%
+ {The command #3 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.}\def\mfp@axisnum{0}\def\mfp@axisletter{x}}%
+ {\edef\mfp@axisnum{\@nameuse{mfp@axis@#1}}\def\mfp@axisletter{#1}}%
+ \edef\mfp@defaultheadlen{%
+ \the\ifnum\mfp@axisnum>1 \sideheadlen\else \axisheadlen\fi}}%
+% \end{macrocode}
+%
+% The tick marks (or hash marks) on the axes can be in three possible
+% positions: centered on the axes, on one side, or on the other side.
+% The default for the $x$- and $y$-axes is centered, for the border axes it
+% is inside.
+% \DescribeMacro{\setaxismarks}
+% 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}.
+%
+% \DescribeMacro{\setxmarks}
+% \cs{setxmarks} takes one argument and sets the position for the $x$ axis
+% only, while
+% \DescribeMacro{\setymarks}
+% \cs{setymarks} does the same for the $y$ axis. For the border axes we
+% provide
+% \DescribeMacro{\setbordermarks}
+% \cs{setbordermarks}, which takes four arguments: the positions for the
+% left, bottom, right and top axis (in that order).
+% \DescribeMacro{\setallbordermarks}
+% The abbreviation \cs{setallbordermarks} takes one argument and sets the
+% position for all border axis marks to that.
+% \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}
+%
+% 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 `\texttt{s}'.
+%
+% \DescribeMacro{\smoothdata}
+% This takes an option tension argument. It defines \cs{mfp@smoothness} to
+% be `\texttt{s}' and \cs{mfp@tension} to be the optional argument.
+% Default tension is empty rather than 1 so we can implement a scheme to
+% change the actual default used.
+% \DescribeMacro{\unsmoothdata}
+% The macro \cs{unsmoothdata} defines \cs{mfp@smoothness} to be
+% `\texttt{p}' and \cs{mfp@tension} to be empty. The latter might not be
+% necessary.
+% \begin{macrocode}
+\newdef\mfp@smdata#1{\mfp@def\mfp@smoothness{#1}%
+ \mfp@nullopt{\mfp@def\mfp@tension}}%
+\newdef\smoothdata{\mfp@smdata{s}}%
+\newdef\unsmoothdata{\mfp@smdata{p}\@empty}%
+\unsmoothdata% default
+% \end{macrocode}
+%
+% \DescribeMacro{\using}
+% 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}.
+%
+% \DescribeMacro{\usingpairdefault}
+% The macro \cs{usingpairdefault} sets the default, which 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.
+%
+% \DescribeMacro{\usingnumericdefault}
+% For the occasional command that needs numeric data,
+% \cs{usingnumericdefault} sets \cs{using} so that the first
+% space-separated word on a line is selected and the remainder of the line
+% discarded.
+%
+% 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 word as a single
+% numeric 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@end{#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 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{\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 placing
+% \DescribeMacro{\makepercentother}
+% \cs{makepercentother} before the \cs{using} command to turn `\texttt\%'
+% into an ordinary character.
+% \DescribeMacro{\makepercentcomment}
+% \cs{makepercentcomment} returns it to its usual role as a comment. Every
+% file reading command issues \cs{mfp@setcomment} before reading. The
+% count register \cs{mfp@commentchar} holds the ASCII code of the current
+% comment character, the default being the percent sign.
+% \begin{macrocode}
+\newcount\mfp@commentchar \mfp@commentchar`\%%
+\newdef\makepercentother{\@makeother\%}%
+\newdef\makepercentcomment{\catcode`\%14 }%
+\newdef\mfpdatacomment#1{\mfp@local\mfp@commentchar`#1}%
+\newdef\mfp@setcomment{\makepercentother\catcode\mfp@commentchar14 }%
+% \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 \arg{} so it doesn't get doubled. The
+% \arg{} is frequent in vardefs among the \MF{} gurus.
+% \begin{macrocode}
+\newdef\fdef{\begingroup\@makeother\#\mfp@keeplines\mfp@fdef}%
+\newdef\mfp@fdef#1#2#3{\mfcmd{\@nl save #1;\@nl
+ vardef #1 (expr #2) = \@nl #3\@nl enddef}\endgroup}%
+% \end{macrocode}
+%
+% The following is executed right after \cs{mfp@grafmacs}. It is a hook
+% for adding new definitions inside and \env{mfpic} environment. It is
+% initialized to empty, and add-on packages can add to it.
+% \begin{macrocode}
+\newdef\mfp@additions{}%
+% \end{macrocode}
+%
+%
+%
+% \section{The user level graphics macros}
+%
+% This is the start of the definition of \cs{mfp@grafmacs}. It contains
+% the definition of every user command that has no purpose outside an
+% \env{mfpic} environment. It will be expanded inside every \env{mfpic}
+% environment, localizing all these definitions. We do this so we can
+% avoid name clashes without giving them all names beginning with \cs{mfp}.
+% \begin{macrocode}
+\newdef\mfp@grafmacs{%
+% \end{macrocode}
+%
+%
+% \subsection{Figure macros}\label{figure}
+%
+% These are the figure macros. These are implemented as \MF{} paths that
+% can be variously rendered, transformed, etc., by the prefix macros of
+% subsection~\ref{prefixcommands}.
+%
+% Most of the \mfpic{} graphic commands take optional arguments. Most of
+% them follow the scheme \cs{mfp@command} takes mandatory arguments
+% enclosed in braces, and does the work. \cs{command} is simply defined to
+% test for an optional argument (with \cs{mfp@defaultopt}) and pass it or a
+% default to \cs{mfp@command}. A typical example is \cs{ellipse} defined
+% to be \verb$\mfp@defaultopt\mfp@ellipse0$. In some cases, the default
+% option is signaled by passing an empty argument via \cs{mfp@nullopt}.
+%
+% Of the commands that have no optional argument, most simply write
+% the appropriate commands to the output file, and require no
+% \cs{mfp@} version.
+%
+% This section contains a description of the behavior of each command and
+% its syntax in use. For those that call an \cs{mfp@} version, the
+% implementation is in the next section.
+%
+%
+% \subsubsection{Common geometric objects}\label{geometric}
+%
+% The first few (\cs{rect} through \cs{sector}) 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.
+%
+% This is an example of a command that requires no further processing.
+% The \cs{mfp@figmac} command sets the appropriate switches and writes its
+% argument to the output file, followed by a semicolon.
+% \begin{macrocode}
+ \newdef\rect##1{\mfp@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{%
+ \mfp@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}, \texttt{s},
+% \texttt{r}, or \texttt{q}. 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.
+% \item \oarg{r}, the point-radius form requires two points and the
+% radius of the circle. Of the two possible circles, it produces the
+% one where the anticlockwise arc from the first point to the second
+% is not more than 180 degrees.
+% \item \oarg{q}, an alternative point-radius with the same parameters.
+% It produces the circle
+% where the anticlockwise arc from the first point to the second
+% is not less than 180 degrees.
+% \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.
+%
+% We use \cs{def} instead of \cs{newdef} because we know \LaTeX{} has
+% already defined a \cs{circle} command. We now use the same command,
+% \cs{mfp@arccircle}, for arcs and circles, setting a switch to tell it
+% which to produce.
+% \begin{macrocode}
+ \def\circle{\mfp@switchfalse\mfp@defaultopt\mfp@arccircle{p}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\ellipse}
+% \cs{ellipse} has one optional argument, an angle of rotation and one
+% mandatory argument, containing the center, the horizontal and vertical
+% radii (before rotation), separated by commas.
+% \begin{macrocode}
+ \newdef\ellipse{\mfp@defaultopt\mfp@ellipse{0}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\quarterellipse}
+% \DescribeMacro{\halfellipse}
+% \DescribeMacro{\fullellipse}
+% The next three commands simply call \grafbase{} commands of the same
+% name. They draw part or all of an ellipse inscribed in a parallelogram.
+% Each requires for its argument three points, separated by commas. For
+% \cs{quarterellipse} these points are, respectively, the midpoint of one
+% side of a parallelogram, a corner point on that side, and the midpoint
+% of the side adjacent to the first at that corner. For \cs{halfellipse}
+% they are the midpoints of three successive sides. For \cs{fullellipse}
+% they are the center and the midpoints of two adjacent sides. They are
+% all simple figmacs with no optional arguments and no star forms.
+%
+% It would be possible to give all of them the same three arguments,
+% for example those of \cs{fullellipse}, but I wanted to put the
+% endpoints of the paths into the argument list. The reason
+% \cs{quarterellipse} is passed the corner point instead of the center is
+% because of the intended use: rounding off an asymmetric corner without
+% having to compute the center of the parallelogram.
+% \begin{macrocode}
+ \newdef\quarterellipse##1{\mfp@figmac{quarterellipse (##1)}}%
+ \newdef\halfellipse##1{\mfp@figmac{halfellipse (##1)}}%
+ \newdef\fullellipse##1{\mfp@figmac{fullellipse (##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.
+% \begin{macrocode}
+ \newdef\sector##1{\mfp@figmac{sector (##1)}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\arc}
+% We have seven (actually 14) ways to specify a circular arc. \cs{arc}
+% takes an optional argument: a letter to indicate which of the 7
+% specifications. It has one mandatory argument containing the data for
+% that specification, separated by commas. It also has a star-form,
+% which produces the complementary arc. That is, instead of the arc that
+% is specified (as described below) it produces the rest of the circle
+% from the end of the specified arc to its start.
+%
+% The available letters and the corresponding required data are listed
+% below. The default optional argument is \oarg{s}.
+% \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 (in that order).
+% \item \oarg{a}, the alternative polar form needs the center, the radius
+% and two angles (in that order).
+% \item \oarg{c}, the center-point-sweep form needs the center, the
+% starting point, and the angle.
+% \item \oarg{s}, the points-sweep form requires the starting point, the
+% ending point and the angle.
+% \item \oarg{r}, the points-radius form requires the starting point, the
+% ending point and the radius of the arc. There are two circles with
+% the given radius that pass through the given points, and hence
+% four possible arcs. One arc on each circle is anticlockwise from
+% the first point to the second. Of those two arcs, only one is
+% less than $180$ degrees. That one is produced.
+% \item \oarg{q} Same as \oarg{r}, except the arc is the larger of two
+% anticlockwise arcs.
+% \end{itemize}
+% \begin{macrocode}
+ \newdef\arc{\mfp@iftoken*{\arccomplement\mfp@arc}{\mfp@arc}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\pshcircle}
+% This final circle is for us complex function theorists. It makes a
+% `pseudohyperbolic circle'. This requires a point $z$ inside the circle
+% with center $(0,0)$ and radius $1$, and a radius $R < 1$. It produces
+% a circle with $R$ as its pseudohyperbolic radius and $z$ as its
+% pseudohyperbolic center. The star form switches contexts to the upper
+% half-plane.
+% \begin{macrocode}
+ \newdef\pshcircle{\mfp@ifstar\mfp@pshcircle\mfp@F\mfp@T}%
+% \end{macrocode}
+%
+% \DescribeMacro{\hypergeodesic}
+% And this final arc is also for we complex function theorists. It makes a
+% `hyperbolic geodesic'. This requires two points $z$ and $w$ inside the
+% circle $T$ with center $(0,0)$ and radius $1$. It produces a circular arc
+% from the first point to the second on the unique circle that passes
+% through these two points and meets $T$ at right angles. The star form
+% switches contexts to the upper half-plane.
+% \begin{macrocode}
+ \newdef\hypergeodesic{\mfp@ifstar\mfp@hypergeodesic{UHP}{UD}}%
+% \end{macrocode}
+%
+%
+% \subsubsection{List macros}\label{list}
+%
+% The figure macros of this section are all list macros. They produce a
+% path from a list of ordered pairs. The list can be explicitly given as a
+% mandatory argument containing a comma-separated list of pair
+% expressions, 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 data determine the path. (Some of the splines don't connect given
+% points, but rather use the points in a different way to determine a
+% curve.) The list of pairs is not an argument of any of these. It should
+% follow, and is ultimately written to output by the ending code of
+% \cs{mfp@listmac}. This is basic to list macros, and will not be repeated
+% for each one.
+%
+% Commands in this section are grouped by the argument structure of the
+% command written to the output file. The first twelve come in pairs
+% that are distinguished by a boolean parameter, which usually determines
+% whether the path produced is closed, followed by the list.
+%
+% \DescribeMacro{\polyline}
+% The most basic, a polyline or polygonal path, \cs{polyline} draws line
+% segments from each point to the next.
+% \DescribeMacro{\lines}
+% \cs{lines} is an alias.
+%
+% \DescribeMacro{\closedpolyline}
+% The macro \cs{closedpolyline} does the same, except it produces a closed
+% path, connecting the last point to the first.
+% \DescribeMacro{polygon}
+% \cs{polygon} is an alias.
+%
+% \DescribeMacro{\computedspline}
+% The \cs{computedspline} command takes a list of points and computes the
+% controls of a cubic spline that connects the points. Adjacent segments
+% have matching first and second derivatives at the common endpoint. It is
+% limited to what is called a \emph{relaxed} spline, which has zero
+% curvature at the beginning and ending points.
+%
+% \DescribeMacro{\closedcomputedspline}
+% This is similar, but computes the unique \emph{closed} cubic spline that
+% connects a list of points.
+%
+% The next four commands also produce types of splines. The list of pairs
+% is not, however, the points passed through but rather are control points,
+% of a sort.
+%
+% \DescribeMacro{\qspline}
+% This produces quadratic 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. This causes adjacent
+% B\'ezier segments to have matching derivatives at their common
+% endpoint. Each three successive data points determines one segment of
+% the path.
+%
+% \DescribeMacro{\closedqspline}
+% The closed variant works by creating two additional segments, viewing
+% the triples $p\sb{n-1}, p\sb{n}, p\sb1$ and $p\sb{n}, p\sb1, p\sb2$ as
+% being `successive'.
+%
+% \DescribeMacro{\cspline}
+% The macro \cs{cspline} produces cubic splines. The points 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. This causes adjacent B\'ezier segments to have matching
+% first and second derivatives at their common endpoint. Each four
+% successive data points determines one segment of the path.
+%
+% \DescribeMacro{\closedcspline}
+% The closed variant works by viewing the first point as a succesor of the
+% last point, creating three additional path segments.
+%
+% \DescribeMacro{\qbeziers}
+% This produces 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, ending with the last node.
+% \DescribeMacro{\closedqbeziers}
+% The closed version ends with the control point between the last node and
+% the first. Therefore, the \cs{qbeziers} command needs an odd number of
+% points in the list, while \cs{closedqbeziers} needs an even number. If
+% this is not the case, the last point in the list is repeated, causing
+% the final segment to be a straight line (closed case) or trivial.
+%
+% 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.
+%
+% \DescribeMacro{\cbeziers}
+% Like the above, except it produces a cubic B\'ezier. It requires a
+% list of $3n+1$ points in the pattern node-control-control, ending with
+% an extra node.
+% \DescribeMacro{closedcbeziers}
+% The closed version requires only $3n$ points, taking the first for the
+% final node.
+%
+% \DescribeMacro{\fcnspline}
+% The above splines are two dimensional splines, that is, functions of
+% $t$ with pair values $(x,y)$. One dimensional splines are functions of
+% $x$ with numeric values $y$. This command produces the \emph{graph} of
+% such a function computed from a supplied list of points. It is required
+% that the $x$-values of the points are in increasing order, although it
+% will produce some sort of curve as long as adjacet $x$-values are
+% distinct. It produces the graph of a \emph{relaxed} spline, in the sense
+% that the second derivative $d^2y/dx^2$ is zero at the beginning and end.
+%
+% \DescribeMacro{\periodicfcnspline}
+% This is the same, but instead of requiring the second derivative to be
+% zero at both ends, it produces a graph such that the first and second
+% derivatives at the end match the ones at the beginning. If a copy of the
+% graph is placed with its starting point at the original graph's ending
+% point, then there is a smooth join. If the $y$-values of the
+% beginning and ending points match, a periodic graph is obtained. For
+% these last two commands the paths cannot be closed, and the boolean
+% determines the behavior at the endpoints.
+%
+% The command \cs{mfp@listi} that implements these writes the command
+% name and the argument and ends with code to write the list of pairs.
+% \begin{macrocode}
+ \newdef\lines{\mfp@listi{polyline}\mfp@F}%
+ \newdef\polygon{\mfp@listi{polyline}\mfp@T}%
+ \newdef\computedspline{\mfp@listi{dospline}\mfp@F}%
+ \newdef\closedcomputedspline{\mfp@listi{dospline}\mfp@T}%
+ \newdef\qspline{\mfp@listi{qspline}\mfp@F}%
+ \newdef\closedqspline{\mfp@listi{qspline}\mfp@T}%
+ \newdef\cspline{\mfp@listi{cspline}\mfp@F}%
+ \newdef\closedcspline{\mfp@listi{cspline}\mfp@T}%
+ \newdef\qbeziers{\mfp@listi{qbezier}\mfp@F}%
+ \newdef\closedqbeziers{\mfp@listi{qbezier}\mfp@T}%
+ \newdef\cbeziers{\mfp@listi{cbezier}\mfp@F}%
+ \newdef\closedcbeziers{\mfp@listi{cbezier}\mfp@T}%
+ \newdef\fcnspline{\mfp@listi{fcnspline}\mfp@F}%
+ \newdef\periodicfcnspline{\mfp@listi{fcnspline}\mfp@T}%
+ \newlet\closedpolyline\polygon
+ \newlet\polyline\lines
+% \end{macrocode}
+%
+% The next six macros have an optional argument called `tension', a
+% numerical value that controls how tightly the path turns at each point
+% in the list. If the optional argument is absent (or empty), the
+% \grafbase{} command that is written takes only a boolean argument
+% (closed or not closed) followed by the list of points. If the tension
+% argument is present, a different command is written that also has a tension
+% argument. The command name is almost the same, but has a `\gbc{t}'
+% prepended. The default tension is the \cs{grafbase}{} variable
+% \gbc{default_tension}, set with \cs{settension}, initialized to 1.
+% Tension of 0 is ignored (ultimately tension is divided by) and may
+% produce error messages from \MF{}.
+%
+% \DescribeMacro{\curve}
+% \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).
+%
+% \DescribeMacro{\closedcurve}
+% The closed version \cs{closedcurve} treats the
+% first point and last point the same as the rest. It has the alias
+% \DescribeMacro{\cyclic}
+% \cs{cyclic}.
+%
+% \DescribeMacro{\convexcurve}
+% This convex version produces a smooth curve that is convex in those
+% places where \cs{polyline} (with the same list of points) would produce
+% a convex shape.
+% \DescribeMacro{\closedconvexcurve}
+% It also comes in a closed version, with the alias
+% \DescribeMacro{\convexcyclic}
+% \cs{convexcyclic}.
+%
+% \DescribeMacro{\mfbezier}
+% This produces the standard \MF{} cubic B\'ezier using the \MF{} path
+% join operator (\mfc{..}) with tension given by an optional argument.
+% \DescribeMacro{\closedmfbezier}
+% The closed version connects the last point to the first in the same way.
+%
+% The command \cs{mfp@curve} examines the optional argument and writes
+% the command name (first argument, possibly modified) with the
+% appropriate arguments (the boolean or tension plus boolean).
+% \begin{macrocode}
+ \newdef\curve{\mfp@curve{curve}\mfp@F}%
+ \newdef\cyclic{\mfp@curve{curve}\mfp@T}%
+ \newdef\convexcurve{\mfp@curve{ccurve}\mfp@F}%
+ \newdef\convexcyclic{\mfp@curve{ccurve}\mfp@T}%
+ \newdef\mfbezier{\mfp@curve{bezier}\mfp@F}%
+ \newdef\closedmfbezier{\mfp@curve{bezier}\mfp@T}%
+ \newlet\closedcurve\cyclic
+ \newlet\closedconvexcurve\convexcyclic
+% \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.
+%
+% While the optional argument is called tension, it is not quite the
+% same as the tension argument to \cs{curve}, but it has a similar effect.
+% The default value is the sane as for \cs{curve}. The above guarantee is
+% voided if the value used is ${}\le1/3$.
+% \begin{macrocode}
+ \newdef\fcncurve{\mfp@nullopt\mfp@fcncurve}%
+% \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{\mfp@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
+% will be 1 (or the value set by \cs{settension}). The default optional
+% argument is \oarg{s}, a smooth curve with the default tension.
+%
+% 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 they call the same macro
+% with the name to be written as the first argument and the default
+% optional argument as the second. The latter is so that we can reuse it
+% for two other commands where the default is different.
+% \begin{macrocode}
+ \newdef\function{\mfp@fcn{function}s}%
+ \newdef\parafcn{\mfp@fcn{parafcn}s}%
+ \newdef\plrfcn{\mfp@fcn{plrfcn}s}%
+% \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 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{\btwnplrfcn}
+% We also have the polar function version, where the two function
+% arguments are as in \cs{plrfcn}. The default option is also \oarg{p}.
+% As with \cs{function}, these are implemented by calling a common
+% command with the basename of the \grafbase{} command as argument.
+%
+% \DescribeMacro{\plrregion}
+% This is like \cs{btwnplrfcn} with 0 as the first function, but it
+% is more efficient. It takes only the other function as an argument.
+% Again, the default option is \oarg{p}.
+%
+% \DescribeMacro{\belowfcn}
+% This is like \cs{btwnfcn} with 0 as the first function, but it
+% is more efficient. It takes only the other function as an argument.
+% The default option is \oarg{p}.
+% \begin{macrocode}
+ \newdef\btwnfcn{\mfp@btwn{btwnfcn}}%
+ \newdef\btwnplrfcn{\mfp@btwn{btwnplrfcn}}%
+ \newdef\belowfcn{\mfp@fcn{belowfcn}p}%
+ \newdef\plrregion{\mfp@fcn{plrregion}p}%
+% \end{macrocode}
+%
+% \DescribeMacro{\levelcurve}
+% One way to graph a function of two variables is to draw level curves.
+% The figure macro \cs{levelcurve} takes an optional smoothness
+% argument (\texttt{[s\meta{tension}]} or \texttt{[p]} with \texttt{p}
+% being the default), and two mandatory arguments. The first
+% mandatory argument is a `seed' point which is known to lie inside the
+% level curve, followed by a comma and a step size. The second is an
+% inequality between the function and the level value that is true inside
+% the level curve. Strictly speaking, the last argument can be any \MF{}
+% boolean valued expression with variables \mfc{x} and \mfc{y}. The simple
+% example,\\
+% \indent\verb$\levelcurve[p]{(0,0),0.1}{x*x + y*y < 3}$\\
+% will draw approximately the circle with radius $\sqrt3$ as a sequence of
+% line segments with length $0.1$. That will require about 109 segments.
+% Its parameters are similar enough to those of \cs{function} that we
+% can use the same interface.
+% \begin{macrocode}
+ \def\levelcurve{\mfp@fcn{levelset}p}%
+% \end{macrocode}
+%
+% We now define two macros for depicting the solution of an
+% ordinary differential equation. The first of these, \cs{DEgraph},
+% produces the graph of the solution for equations of the form
+% $$
+% \frac{dy}{dx} = f(x,y),\quad y(x\sb0) = y\sb0.
+% $$
+% The data required are the \emph{initial values} (the two numbers $x\sb0$
+% and $y\sb0$), the formula $f(x,y)$ (an explicit \MF{} numerical
+% expression with literal variables \mfc{x} and \mfc{y} as the only
+% unknowns. Since \MF{} can only handle paths connecting discrete points,
+% also required is a step size which, roughly speaking, is the distance
+% between points in graph coordinates, and the number of steps $N$ to use.
+% The \MF{} macros then calculate $N$ additional points (the first is
+% $(x\sb0,y\sb0)$) and join them together to produce the graph.
+%
+% The second macro, \cs{DEtrajectory}, draws the trajectory of a
+% two-dimentional differential equation of the form
+% $$
+% \left( \frac{dx}{dt}, \frac{dy}{dt}\right) = (f(x,y,t),g(x,y,t)\,,
+% \quad (x(0),y(0)) = (x\sb0,y\sb0)
+% $$
+% This is not, strictly speaking, a \emph{graph} since that would
+% require three dimensions to indicate the relation between $x$, $y$, and
+% $t$. Mathematicians call it a trajectory, and it only shows the
+% two-dimensional path followed by the moving object. The required data
+% are an initial point $(x\sb0,y\sb0)$, the formula for the right-hand side
+% (an explicit \MF{} pair-valued expression or a pair of numerical
+% expressions in parentheses, with literal variables \mfc{x}, \mfc{y} and
+% \mfc{t} as the only unknowns. Also required are a step size and the
+% number of steps, as in \cs{DEgraph}.
+%
+% The method used to calculate the points to connect is a modified version
+% of the four-step Runge-Kutta method. The modifications are intended to
+% avoid numerical overflow. That is, infinite blow-up in finite time. An
+% example is the simple equation
+% $$
+% \frac{dy}{dx} = y^2 \quad y(0) = 1,
+% $$
+% whose solution is $y = 1/(1-x)$. The usual definition of
+% Runge-Kutta-IV would have one process equally spaced $x$-values. If a
+% user had no idea of the character of the solution, and asked for $N$
+% $x$-values with separation $h$ to get a graph on $0\le x \le Nh$, and if
+% $Nh > 1$, then the result would be either quite different from the actual
+% solution (especially around $x=1$), or would reach a point of numerical
+% overflow.
+%
+% Thus our macros require the user to supply a parameter that will be
+% interpreted as a distance step: if $h$ is this parameter, instead of
+% finding values of $y$ at $x\sb0$, $x\sb{0+h}$, $x\sb{0+2h}$, etc., it
+% finds points $(x\sb{n},y\sb{n})$ on the graph so that the
+% two-dimensional distance from $(x\sb0,y\sb0)$ to $(x\sb1,y\sb1)$ is $h$,
+% then the distance from $(x\sb1,y\sb1)$ to $(x\sb2,y\sb2)$ is also $h$,
+% etc. The resulting graph therefore simply follow the graph of $y =
+% 1/(1-x)$ a distance roughly $Nh$ and numerical overflow is impossible
+% unless the value of $Nh$ exceeds \MF{}'s size limits. There is an
+% optional smoothness parameter as in \cs{function}.
+% \begin{macrocode}
+ \newdef\DEgraph{\mfp@fcn{odeRKIV}s}%
+ \newdef\DEtrajectory{\mfp@fcn{xyRKIV}s}%
+% \end{macrocode}
+%
+% \DescribeMacro{\brownianmotion}
+% Used by me once to ilustrate Brownian motion. The argument consists of
+% a starting point, the number of steps, and a scale factor, separated
+% by commas. It draws a polyline starting with the starting point moving
+% in a random direction a random distance, then repeating that from the
+% new point, etc., for the number of steps given. The size of each step is
+% random, but the scale factor gives the average size.
+%
+% \DescribeMacro{\browniangraph}
+% This approximates the graph of one-dimensional Brownian motion. The
+% argument consists of the number of steps and a scale factor/step size,
+% separated by commas. It draws a polyline starting at $(0,0)$, moving
+% right by the step size and up or down (randomly chosen) by a random
+% amount, then repeating that from the new point, etc., for the number of
+% steps given.
+%
+% \DescribeMacro{\randomwalk}
+% This is a two dimensional random walk. The argument consists of a
+% starting point, the number of steps, and a distance, separated by
+% commas. Like \cs{brownianmotion}, it draws a polyline starting at the
+% starting point, moving in a random direction, but for this command it
+% always moves a fixed distance.
+% \begin{macrocode}
+ \newdef\brownianmotion##1{\mfp@figmac{brownianpath (##1)}}%
+ \newdef\browniangraph##1{\mfp@figmac{browniangraph (##1)}}%
+ \newdef\randomwalk##1{\mfp@figmac{randomwalk(##1)}}%
+% \end{macrocode}
+%
+%
+% \subsection{Plotting data from files}\label{datafiles}
+%
+% \DescribeMacro{\plotdata}
+% The 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 the default. The default is \oarg{p} when
+% \mfpic{} is loaded, but can be changed with \cs{smoothdata} and restored
+% with \cs{unsmoothdata}.
+% \begin{macrocode}
+ \newdef\plotdata{\mfp@nullopt\mfp@plotdata}%
+% \end{macrocode}
+%
+% \DescribeMacro{\datafile}
+% \cs{datafile} defines a path connecting the points in a datafile. It has
+% an optional parameter for the smoothness, as in \cs{plotdata}.
+% \begin{macrocode}
+ \newdef\datafile{\mfp@nullopt\mfp@datafile}%
+% \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{mfp@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.
+%
+% \DescribeMacro{\norender}
+% Occasionally it is useful to turn off rendering (say we want to add an
+% arrowhead to a subpath of a path that is already rendered). One could
+% put \cs{store} at the start with an unused name, but as every path is
+% already stored in \gbc{curpath}, that seems redundant. So here is a
+% prefix macro with null rendering and no side effects. It is exactly
+% like \cs{mfp@rendmac}, except it does not end with \cs{mfsrc}.
+% \begin{macrocode}
+ \newdef\store##1##2{\mfp@rendmac{stored (##1)}##2}%
+ \newdef\norender{\mfp@first\@mfprendfalse}%
+% \end{macrocode}
+%
+% \DescribeMacro{\mfobj}
+% This is the interface to use a \cs{store}-d object.
+% \cs{mfobj}\marg{\meta{name}} is a figure macro, and should act exactly
+% the same as if the figure macro that had been stored in the variable
+% were typed in its place. Its one argument is the variable name.
+%
+% Instead of the variable name, the argument can contain any reasonable
+% \MF{} path expression. In this context ``reasonable'' means it should
+% contain no special \TeX{} characters that might expand upon being
+% written to the output file. In particular, the backslash and `\verb$~$'
+% should especially be avoided.
+%
+% \DescribeMacro{\mpobj}
+% The macro \cs{mpobj} is just another name for the same command.
+% \begin{macrocode}
+ \newlet\mfobj\mfp@figmac \newlet\mpobj\mfobj
+% \end{macrocode}
+%
+% \DescribeMacro{\mfpimage}
+% The command \cs{mfpimage} starts a group in which drawing commands
+% work just as usual, except they draw in a picture variable, whose name
+% is the only mandatory argument to \cs{mfpimage}.
+% \DescribeMacro{\endmfpimage}
+% The command \cs{endmfpimage} ends that group. There is an optional
+% argument to set the reference point of the created picture, the default
+% being \gbc{(0,0)}. The resulting picture can then be placed using
+% \cs{putmfpimage}.
+% \begin{macrocode}
+ \newdef\mfpimage{\mfp@defaultopt\mfp@image{(0,0)}}%
+ \newdef\endmfpimage{\mfcmd{\@nl concludeimage}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\putmfpimage}
+% This takes the name of a picture variable created with the
+% \cs{mfpimage} environment (or even with the \cs{tile} environment), and
+% places it with its reference point at the points in a list.
+% \begin{macrocode}
+ \newdef\putmfpimage##1{\mfsrc{\@nl putimage (##1)}\mfp@writedata}%
+% \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 absolute amounts from the start and end of
+% the path. The amounts can be specified as two absolute dimensions
+% separated by a comma, or a single dimension. In the second case, that
+% dimension is used at both the start and end.
+%
+% The implementation uses \cs{mfp@modi} which simply reads the argument
+% and writes it (via \cs{mfp@modmac}) as a set of parameters to the
+% appropriate \grafbase{} command. With \cs{trimpath}, however, we have to
+% parse that argument with \cs{mfp@getdimens}.
+% \begin{macrocode}
+ \newdef\cutoffafter {\mfp@modi{cutoffafter}}%
+ \newdef\cutoffbefore{\mfp@modi{cutoffbefore}}%
+ \newdef\trimpath##1{\mfp@getdimens##1,,\mfp@end
+ \mfp@modi{trimmedpath}\mfp@thedimens}%
+% \end{macrocode}
+%
+% \DescribeMacro{\partpath}
+% This produces a subpath of the following path. Its mandatory argument
+% contains two numbers separated by a comma. The numbers should be between
+% 0 and 1 and produce a fraction of the following path.
+% \DescribeMacro{\subpath}
+% The macro \cs{subpath} has a similar argument, but the numbers are
+% 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{\mfp@modi{partialpath}}%
+ \newdef\subpath{\mfp@modi{gsubpath}}%
+% \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} takes one optional argument, a color. In \MF{}, where the
+% color commands return a numeric, if it is ${}\ge 1$ (representing white)
+% the path is subtracted from the picture, otherwise it is drawn in black
+% (the default). The default in \MP{} is \gbc{drawcolor}.
+%
+% We signal the use of the default color by passing a null optional
+% argument. Because several commands handle color the same way, and all
+% are rendering macros, we have a common macro that only needs the name of
+% the \grafbase{} command.
+% \begin{macrocode}
+ \newdef\draw{\mfp@nullopt{\mfp@clroptrend{drawn}}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\doubledraw}
+% Behaves something like \cs{draw}, except it draws a double line. It
+% takes two optional arguments; the first is the distance between the
+% centers of the two lines (default \gbc{2penwd}) and the second is a
+% color.
+% \begin{macrocode}
+ \newdef\doubledraw{\mfp@defaultopt\mfp@doubledraw{2penwd}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\dashed}
+% \cs{dashed} and \cs{dotted} take one optional argument, which should
+% contain the length of the dashes (diameter of
+% \DescribeMacro{\dotted}
+% dots) and the length of the spaces between, separated by a comma.
+%
+% Several rendering macros take an optional argument which is written as
+% the first parameter of a \grafbase{} command. Thus all are handled with
+% a single macro whose arguments are the name of the command and the
+% default for the optional argument.
+% \begin{macrocode}
+ \newdef\dashed{\mfp@optrendi{DASHED}{\the\dashlen,\the\dashspace}}%
+ \newdef\dotted{\mfp@optrendi{dotted}{\the\dotsize,\the\dotspace}}%
+% \end{macrocode}
+%
+% \cs{gendashed} takes one mandatory argument, the name of a dash pattern
+% previously defined by \cs{dashpattern}. The implementing macro,
+% \cs{mfp@rendi}, is like the above, except it doesn't need to perform the
+% option processing.
+% \begin{macrocode}
+ \newdef\gendashed{\mfp@rendi{gendashed}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\zigzag}
+% This draws a zigzag, crossing from one side of the following path to
+% the other. It has one required argument containing four dimensions,
+% \meta{dim$\sb1$} through \meta{dim$\sb4$}, separated by commas. What is
+% drawn depends on whether the path is closed or open. For an open path,
+% this draws the start of the path for a distance \meta{dim$\sb1$},
+% followed by zigzags, followed by the end of the path for a distance
+% \meta{dim$\sb2$}. For a closed path the first two dimensions are
+% ignored and the zigzags follow the entire path.
+%
+% The last two dimensions define the size and slant of each `zig'. If we
+% think of the zigzags as representing a periodic wave, \meta{dim$\sb3$}
+% is the wavelength and \meta{dim$\sb4$} is the amplitude (distance from
+% the true path to the sharp points).
+%
+% \DescribeMacro{\sinewave}
+% This is similar, but the result is a smooth sinewave shaped rendering.
+%
+% \DescribeMacro{\coil}
+% This creates a coil, or corkscrew-shaped rendering. In this case
+% \meta{dim$\sb3$} is the distance from one loop to the next and
+% \meta{dim$\sb4$} is the maximum distance to each side of the path.
+% An alias,
+% \DescribeMacro{\corkscrew}
+% \cs{corkscrew}, is provided.
+%
+% Both \cs{sinewave} and \cs{corkscrew} take an optional `tension'
+% argument that affects the smoothness of the result. The default is $1$
+% and the higher the value the closer they become to a zigzag.
+% \begin{macrocode}
+ \newdef\zigzag{\mfp@rendi{zigzag}}%
+ \newdef\sinewave {\mfp@defaultopt{\mfp@wiggle{sinewave}}1}%
+ \newdef\coil{\mfp@defaultopt{\mfp@wiggle{corkscrew}}1}%
+ \newlet\corkscrew\coil
+% \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.
+%
+% The utility \cs{mfp@optrendii} is similar \cs{mfp@optrendi} except it
+% takes an additional argument, in this case, the first mandatory argument
+% of \cs{plot}.
+% \begin{macrocode}
+ \newdef\plot{%
+ \mfp@optrendii{doplot}{\the\pointsize,\the\symbolspace}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\plotnodes}
+% 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 some of 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{\mfp@optrendii{plotnodes}{\the\pointsize}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\showcontrols}
+% Mainly for debugging, this places a symbol at the precontrol and
+% postcontrol of each node, and draws a line segment from each symbol to
+% the node. The names of two symbols are given in a mandatory argument,
+% separated by commas. As a special case, if either symbol is just the
+% number `\mfc{0}', it is not drawn. There is an optional argument for
+% the size of these symbols. If the size is zero, neither symbol is drawn.
+% That is useful if one only wants to see the line segments.
+% \begin{macrocode}
+ \newdef\showcontrols{\mfp@optrendii{showcontrols}{\the\pointsize}}%
+% \end{macrocode}
+%
+%
+% \subsubsection{Closing a curve}\label{closing}
+%
+% There are several commands used to close paths (by prefixing them to
+% figure macros). The \grafbase{} commands that implement closing have a
+% common naming pattern. They all contain the string `\texttt{closed},
+% to which is added a distinguishing prefix. If the command takes a
+% tension argument, the letter `\texttt{t}' is appended. The corresponding
+% command without the `\texttt{t}' calls it with a default tension value.
+%
+% These macros all call \cs{mfp@close}, feeding it the proper prefix and
+% the tension value (empty if there is no tension option).
+%
+% \DescribeMacro{\sclosed}
+% The first, \cs{sclosed}, closes smoothly in the same manner that
+% \cs{curve} creates a smooth path.
+%
+% \DescribeMacro{\bclosed}
+% The second, \cs{bclosed}, uses an ordinary \MF{} B\'ezier. These two
+% have an optional argument: the amount of tension to put in the
+% connecting link. This makes no sense with the rest.
+%
+% \DescribeMacro{\lclosed}
+% The macro \cs{lclosed} always draws a straight line from the end of a
+% path to its start.
+%
+% \DescribeMacro{\cbclosed}
+% The macro \cs{cbclosed} computes a closure by calculating cubic B-spline
+% control points from the path data and then generating a connecting
+% spline (see \cs{cspline}).
+%
+% \DescribeMacro{\qbclosed}
+% The macro \cs{qbclosed} is similar, but quadratic B-splines are used.
+%
+% \DescribeMacro{\uclosed}
+% At one time \cs{uclosed} was defined in a more complicated manner than
+% necessary, but actually produced exactly the same path as \cs{bclosed}.
+% So now they are just made to be equal.
+% \begin{macrocode}
+ \newdef\bclosed{\mfp@nullopt{\mfp@close b}}%
+ \newdef\sclosed{\mfp@nullopt{\mfp@close s}}%
+ \newdef\lclosed{\mfp@close l{}}%
+ \newdef\cbclosed{\mfp@close{cb}{}}%
+ \newdef\qbclosed{\mfp@close{qb}{}}%
+ \newlet\uclosed\bclosed
+% \end{macrocode}
+%
+% \DescribeMacro{\makesector}
+% Takes a following arc and draws the sector (even if the center point
+% is not known). It really only works if prefixed to one of the
+% \cs{arc} commands, but it will attempt to create something even for
+% other paths. It calculates the center of the circle containing the arc
+% and connects that to the endpoints with two straight lines.
+% \begin{macrocode}
+ \newdef\makesector{\mfp@modmac{makesector}}%
+% \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 closed; if not,
+% the path will simply be drawn with a solid line.
+%
+% \DescribeMacro{\tess}
+% \cs{tess} takes one mandatory argument, the name of a previously defined
+% tile (see subsection~\ref{composite}), and fills with shifted copies of
+% the tile.
+% \begin{macrocode}
+ \newdef\tess{\mfp@rendi{tess}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\shade}
+% \cs{shade} is implemented in \MF{} by filling a region with a pattern
+% of dots, simulating gray. It take one optional parameter, the separation
+% between dots, defaulting to \cs{shadespace}. The size of the dots is
+% set by issuing the command \cs{shadewd}. In \MP{} a gray fill is
+% used but the syntax is the same. It would be better to just use
+% \cs{gfill} instead (described later).
+%
+% \DescribeMacro{\polkadot}
+% This command is actually meant to fill with a pattern of large dots.
+% It also takes the separation between dots (default \cs{polkadotspace})
+% as an optional argument. The command \cs{polkadotwd} sets the size of
+% the dots.
+% \begin{macrocode}
+ \newdef\shade{\mfp@optrendi{shade}{\the\shadespace}}%
+ \newdef\polkadot{\mfp@optrendi{polkadot}{\the\polkadotspace}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\thatch}
+% 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.
+% \DescribeMacro{\lhatch}
+% The macro \cs{lhatch} has lines at a $-45$ degree angle (upper left to
+% lower right),
+% \DescribeMacro{\rhatch}
+% \cs{rhatch} produces the opposite diagonal (angle $45$ degrees), and
+% \DescribeMacro{\xhatch}
+% \cs{xhatch} does both sets of lines (cross hatching).
+% \begin{macrocode}
+ \newdef\thatch{\mfp@defaultopt\mfp@thatch{\the\hatchspace,0}}%
+ \newdef\lhatch{\mfp@defaultopt\mfp@lhatch{\the\hatchspace}}%
+ \newdef\rhatch{\mfp@defaultopt\mfp@rhatch{\the\hatchspace}}%
+ \newdef\xhatch{\mfp@defaultopt\mfp@xhatch{\the\hatchspace}}%
+ \newlet\hatch\xhatch
+% \end{macrocode}
+%
+% \DescribeMacro{\gradient}
+% The \cs{gradient} command approximates a linear gradient fill using
+% adjacent strips of different colors. It takes one mandatory argument
+% containing three items separated by commas. The first is a
+% \mfc{vardef}-ed function that produces the colors, the second is the
+% thickness of the color strips and the third is the angle these strips
+% make with the horizontal.
+%
+% \DescribeMacro{\areagradient}
+% This allows more general shading. It produces a fill consisting of
+% differently colored ``pixels''. It also takes one mandatory argument
+% containing three items separated by commas. The first is a
+% function of two variables that produces the colors, the second is the
+% width of the pixels and the third is their height.
+%
+% \DescribeMacro{\radialgradient}
+% This allows shading in a concentric circular pattern. It produces a fill
+% consisting of differently colored circular strips. It also takes one
+% mandatory argument containing three items separated by commas. The first
+% is a function of one variable that produces the colors, the second is
+% the thickness of the circular strips, and the third is an ordered pair
+% (the center the circles).
+% \begin{macrocode}
+ \newdef\gradient{\mfp@rendi{axialgradient}}%
+ \newdef\areagradient{\mfp@rendi{areagradient}}%
+ \newdef\radialgradient{\mfp@rendi{radialgradient}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\gfill}
+% \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.
+%
+% \DescribeMacro{\gclear}
+% \cs{gclear} will actually fill with the color \texttt{background} in \MP.
+% This merely covers what originally was there.
+%
+% \DescribeMacro{\gclip}
+% \cs{gclip} clears the outside of a region, but it is a true clip
+% operation, completely different from \cs{gclear}.
+% \begin{macrocode}
+ \newdef\gfill{\mfp@nullopt{\mfp@clroptrend{filled}}}%
+ \newdef\gclear{\mfp@rendmac{unfilled}}%
+ \newdef\gclip{\mfp@rendmac{Clip}}%
+% \end{macrocode}
+%
+%
+% \subsubsection{Modifying a curve}\label{transforming}
+%
+% The following are transformation prefixes. They are all (except
+% \cs{reverse}, for reasons covered in section~\ref{prefix}) implemented
+% with \cs{mfp@modmac}. 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. This is what users seem to expect. The rest
+% do not compensate and users don't seem to mind.
+% \begin{itemize}
+% \item \cs{reverse} and \cs{xyswappath} have no argument.
+% \item \cs{reversepath} = \cs{reverse}.
+% \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, with the same arguments, via
+% \cs{mfp@modi}.\SpecialUsageIndex{\reversepath}\SpecialUsageIndex{\reverse}
+% \SpecialUsageIndex{\xyswappath}\SpecialUsageIndex{\rotatepath}
+% \SpecialUsageIndex{\shiftpath}\SpecialUsageIndex{\scalepath}
+% \SpecialUsageIndex{\xscalepath}\SpecialUsageIndex{\yscalepath}
+% \SpecialUsageIndex{\slantpath}\SpecialUsageIndex{\xslantpath}
+% \SpecialUsageIndex{\yslantpath}\SpecialUsageIndex{\reflectpath}
+% \SpecialUsageIndex{\transformpath}
+%
+% \begin{macrocode}
+ \newdef\reversepath{\mfp@addmac{reverse}}%
+ \newlet\reverse\reversepath
+ \newdef\xyswappath{\mfp@modmac{xyswappedpath}}%
+ \newdef\rotatepath{\mfp@modi{rotatedpath}}%
+ \newdef\shiftpath{\mfp@modi{shiftedpath}}%
+ \newdef\scalepath{\mfp@modi{scaledpath}}%
+ \newdef\xscalepath{\mfp@modi{xscaledpath}}%
+ \newdef\yscalepath{\mfp@modi{yscaledpath}}%
+ \newdef\xslantpath{\mfp@modi{xslantedpath}}%
+ \newlet\slantpath\xslantpath
+ \newdef\yslantpath{\mfp@modi{yslantedpath}}%
+ \newdef\reflectpath{\mfp@modi{reflectedpath}}%
+ \newdef\transformpath{\mfp@modi{transformedpath}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\parallelpath}
+% This is not an affine transformation, but is a transformation of sorts.
+% It tries to define a curve that parallels the following curve at a fixed
+% distance. The mandatory argument is the separation, in graph units. It
+% is sort of experimental and will probably fail if the path that follows
+% is too wild. Since \cs{doubledraw} shares code with \cs{parallelpath},
+% that too will probably fail in similar circumstances.
+% \begin{macrocode}
+ \newdef\parallelpath{\mfp@modi{parapath}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\randomizepath}
+% This, too, is a nonaffine transformation. It tries to define a curve
+% that remains smooth if the original is, but applies random shifts to the
+% nodes and random changes to the direction at each node.
+%
+% The only argument is mandatory and consists of a maximum shift (in graph
+% units) and a `weirdness' (a pure number) separated by a comma.
+%
+% The maximum shift can be a number, in which case it is the maximum
+% possible distance and there is no preferred direction, or it can be an
+% ordered pair, in which case it gives maximum horizontal and vertical
+% shift amounts.
+%
+% The `weirdness' is applied to path directions. If it is 0, there is no
+% change in directions of the path at nodes. If it is a positive number
+% $w$, a random angle of up to $\pm 30 w$ is added to the directions at
+% each node. Also a random scaling between $2^{-w}$ and $2^w$ is applied
+% to the control vectors. Also, if a path has a corner, the angle between
+% the two sides is randomly adjusted to be between $2^{-w}$ and $2^w$
+% times its original size.
+%
+% \DescribeMacro{\randomlines}
+% This is a simpler version whose mandatory argument contains only the
+% maximum shift parameter. It shifts the nodes and connects the results
+% with straight lines.
+% \begin{macrocode}
+ \newdef\randomizepath{\mfp@modi{randompath}}%
+ \newdef\randomlines{\mfp@modi{randomlines}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\interpolatepath}
+% This prefix macro has one mandatory argument containing a number and a path,
+% separated by a comma. The number can be any \MF{} numeric expression and
+% the path can be any \MF{} path expression. The number should normally be
+% in the range $0$ to $1$ and the path normally a variable (e.g, defined using
+% \cs{store}). It returns a path which is between the one in its argument
+% and the one that follows. If the number is $0$, the following path is
+% returned unchanged, if the number is $1$ the path in the argument is
+% returned.
+% \begin{macrocode}
+ \newdef\interpolatepath{\mfp@modi{interpolatedpath}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\arccomplement}
+% This can precede an arc and then returns its complement. It starts at
+% the last point of the following arc and ends at the beginning of that
+% arc. The sense of the resulting arc (clockwise or anticlockwise) is the
+% same as the arc it is applied to. If the following path is not an arc,
+% the result is an arc that connects the end of the path to the beginning,
+% but may bear no obvious relation to that path.
+% \begin{macrocode}
+ \newdef\arccomplement{\mfp@modmac{arccomplement}}%
+% \end{macrocode}
+%
+%
+% \subsubsection{Adding arrowheads (and tails)}\label{arrows}
+%
+% Paths can now have heads and tails and something placed in the
+% middle. Also the head, tail or the `something' can be any symbol. In
+% addition to the \cs{plotsymbol} possibilities, there is \gbc{Arrowhead},
+% which is the arrowhead of previous \mfpic{} versions, as well as
+% \gbc{Leftharpoon} and \gbc{Rightharpoon}, which are the left and right
+% halves.
+%
+% Intended for middle or tail of an arrow are \gbc{Crossbar}, \gbc{Leftbar}
+% and \gbc{Rightbar}, and for the tail there are \gbc{Lefthook} and
+% \gbc{Righthook}. \gbc{Crossbar} cuts right across the shaft
+% (perpendicular unless a rotation option is present) while \gbc{Leftbar}
+% extends to the left (from the point of view of someone facing in the
+% direction of the path. Similarly \gbc{Lefthook} curls to the left of the
+% arrow's shaft.
+%
+% All the new arrow commands take one mandatory argument, the name of the
+% symbol, followed by up to four optional arguments. Three of the optional
+% arguments are the same for all commands: these set the color, the size
+% and the amount of rotation of the symbol. Normally the symbol is
+% adjusted to `point' in the direction of the path (\gbc{Crossbar} is
+% actually perpendicular to it); with the rotation option it can be
+% adjusted.
+%
+% For example, \oarg{c red} makes the symbol red, \oarg{l 5pt} or \oarg{s
+% 5pt} scales the symbol so its nominal size or length is 5 points,
+% \oarg{r 10} rotates the symbol 10 degrees (anticlockwise) from its
+% default position.
+%
+% The other optional argument depends on the command: for heads it is an
+% amount to shift the head backward, for tails the amount to shift it
+% forward, and for things placed in the middle, it is the fraction of the
+% length of the path along which the symbol is placed.
+%
+% For example, \oarg{b 2pt} shifts a head two points backward, \oarg{f
+% 2pt} shifts a tail 2 points forward and \oarg{f .5} puts the symbol
+% right in the middle.
+%
+% The letters are mnemonics, being the initial letters of the words
+% `color', `length' or `size', `rotate', `back', and `forward' or
+% `fraction'. Actually, the letters \texttt{s} and \texttt{l} have
+% identical effects since I couldn't decide which mnemonic was more
+% natural. Oddly, \texttt{b} and \texttt{f} have identical effects also.
+% So if you accidentally use \oarg{b 2pt} for a tail, it will still be
+% shifted \emph{forward}! The reason for this is that these \mfpic{}
+% commands all correspond to \grafbase{} commands that have the same
+% argument structure. Both \texttt{b} and \texttt{f} simply cause the
+% accompanying value to be written into the fourth argument, while the
+% different commands use that argument differently. (You can shift a
+% tail backwards with a negative argument, if you really need that.)
+%
+% \DescribeMacro{\arrowhead}\SpecialUsageIndex{\arrow}
+% The \cs{arrowhead} command has a star-form which allows part of the
+% path beyond the tip of the arrowhead to be erased. The presence of a
+% star ultimately changes the \MF{} command passed on to later macros.
+% It does so by passing to \cs{mfp@arrowhead} the word `\texttt{true}' for
+% the star-form and `\texttt{false}' otherwise.
+%
+% The old \cs{arrow} command first checks for a star, and passes to
+% \cs{mfp@arrow} either an `\texttt{x}' or an empty parameter. This is
+% used to construct the \grafbase{} command name. We use \cs{def}
+% because \prog{eplain} defines one also.
+% \begin{macrocode}
+ \newdef\arrowhead{\mfp@ifstar\mfp@arrowhead\mfp@T\mfp@F}%
+ \def\arrow{\mfp@ifstar\mfp@arrow{x}{}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\arrowtail}
+% Tails are just like heads except that there is no star-form and the
+% \grafbase{} command name (second parameter of \cs{mfp@arr}) is
+% different.
+% \DescribeMacro{\arrowmid}
+% And \cs{arrowmid} is just like \cs{arrowtail} except for the command
+% name and the different default for the position optional argument.
+% \begin{macrocode}
+ \newdef\arrowtail##1{\mfp@arr 0{tailpath (##1)}}%
+ \newdef\arrowmid##1{\mfp@arr{0.5}{midpath (##1)}}%
+% \end{macrocode}
+%
+% This ends the prefix macros.
+%
+%
+% \subsection{Transforming the coordinate system}\label{coordinate}
+%
+% \DescribeMacro{\coords}
+% The following apply transforms to the \MF{} coordinate system, and
+% these can be localized with the \env{coords} environment. In plain
+% \TeX{} \cs{coords} starts the environment and
+% \DescribeMacro{\endcoords}
+% \cs{endcoords} closes it. The transforms apply when the curve is
+% \emph{rendered} and do not affect what paths are defined. Thus, for
+% example, \cs{store} will store the same path whatever the state of the
+% coordinate system. In terms of \grafbase{} commands, only \gbc{vtr} and
+% \gbc{ztr} are changed, and these are only applied when rendering.
+%
+% \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
+% no optional arguments, only mandatory arguments containing 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, defaulting to $(0,0)$.
+%
+% Transformations are applied in reverse of the order they appear in the
+% file (i.e., the most recent first). This applies even if \env{coords}
+% environments are nested, except that at \cs{endcoords} the state at
+% the matching \cs{coords} is restored.
+% \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{\mfp@defaultopt\mfp@turn{(0,0)}}%
+ \newdef\reflectabout##1##2{\applyT{reflectedabout (##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}
+%
+% 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.
+%
+% \DescribeMacro{\axes}
+% The original \cs{axes} was therefore not a figure macro. It always drew
+% both axes with solid lines.
+% \DescribeMacro{\xaxis}
+% Later \cs{xaxis} and \cs{yaxis} were introduced, which mimicked the
+% behavior of \cs{axes}. For backward
+% \DescribeMacro{\yaxis}
+% 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{axisheadlen}.
+% \begin{macrocode}
+ \newdef\xaxis{\mfp@defaultopt{\mfp@simple{xaxis}}{\the\axisheadlen}}%
+ \newdef\yaxis{\mfp@defaultopt{\mfp@simple{yaxis}}{\the\axisheadlen}}%
+ \newdef\axes{\mfp@defaultopt {\mfp@simple{axes}}{\the\axisheadlen}}%
+% \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.
+%
+% \DescribeMacro{\axisline}
+% The \cs{axisline} command is provided for users who want more control.
+% It is a figure macro that produces the corresponding line, and the user
+% can use all the flexibility of the \cs{arrowhead} command if necessary.
+% \begin{macrocode}
+ \newdef\axis{\mfp@nullopt\mfp@axis}%
+ \newdef\axisline##1{\mfp@figmac{axisline.##1}}%
+% \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{mfp@doaxis}.
+%
+% \DescribeMacro{\border}
+% The \cs{border} command is almost equivalent to \cs{doaxes}\marg{lbrt},
+% except it is a figure macro. With it, the whole picture can be filled
+% with a background color, or outlined in any available rendering.
+% \begin{macrocode}
+ \newdef\doaxes{\mfp@nullopt\mfp@doaxes}%
+ \newdef\border{\mfp@figmac{borderrect}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\axismarks}
+% 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 one of e\kern-.06em\TeX's primitives).
+% For brevity, therefore, we also have separate commands
+% \DescribeMacro{\xmarks}
+% \cs{xmarks},
+% \cs{ymarks}\SpecialUsageIndex\ymarks,
+% \cs{lmarks}\SpecialUsageIndex\lmarks,
+% \cs{bmarks}\SpecialUsageIndex\bmarks,
+% \cs{rmarks}\SpecialUsageIndex\rmarks, and
+% \cs{tmarks}\SpecialUsageIndex\tmarks.
+%
+% \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 in subsection~\ref{othersettings}.
+% \begin{macrocode}
+ \newdef\axismarks##1{\mfp@defaultopt{\mfp@marks{##1}}{\the\hashlen}}%
+ \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}
+% The command \cs{grid} is, I think, inaccurately named: the word `grid'
+% suggests a set of lines, but this actually produces dots. Its function
+% is to allow a visualization of the coordinates. 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
+% \cs{griddotsize}, initially \texttt{0.5pt}.
+%
+% Because of my concerns about the name, I have provided two aliases:
+% \cs{gridpoints}\SpecialUsageIndex{\gridpoints} (for consistency with
+% \cs{gridlines}, below) and \cs{lattice}\SpecialUsageIndex{\lattice}.
+%
+% \DescribeMacro{\gridlines}
+% Macro \cs{gridlines} has no optional argument and takes the same
+% mandatory argument as \cs{grid}. It 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}.
+%
+% \DescribeMacro{\hgridlines}
+% This draws only the horizontal lines and its argument is the separation
+% (in graph units) between successive lines.
+% \DescribeMacro{\vgridlines}
+% \cs{vgridlines} is the vertical version.
+%
+% No arguments are shown because \cs{mfp@simple} or \cs{mfp@simplei} will
+% read what it needs.
+% \begin{macrocode}
+ \def\grid{\mfp@defaultopt{\mfp@simplei{vargrid}}{\the\griddotsize}}%
+ \newlet\gridpoints\grid \newlet\lattice\grid
+ \newdef\gridlines{\mfp@simple{gridlines}}%
+ \newdef\vgridlines{\mfp@simple{vgridlines}}%
+ \newdef\hgridlines{\mfp@simple{hgridlines}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\plrgrid}
+% The command \cs{plrgrid} takes one mandatory argument which contains two
+% numbers separated by a comma. The first is a radius (in graph
+% coordinates) 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.
+%
+% \DescribeMacro{\plrgridpoints}
+% \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, default \cs{griddotsize}.
+% \DescribeMacro{\gridarcs}
+% The macro \cs{gridarcs} draws only the arcs. Its only parameter is the
+% distance between them (in graph units).
+% \DescribeMacro{\gridrays}
+% The macro \cs{gridrays} draws only the rays and its parameter is the
+% angle separating the rays.
+%
+% \DescribeMacro{\plrpatch}
+% \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, radius
+% step, starting angle, ending angle, angle step.
+% \begin{macrocode}
+ \newdef\plrgrid{\mfp@simple{polargrid}}%
+ \newdef\plrgridpoints{%
+ \mfp@defaultopt{\mfp@simplei{polargridpoints}}{\the\griddotsize}}%
+ \newdef\gridarcs{\mfp@simple{gridarcs}}%
+ \newdef\gridrays{\mfp@simple{gridrays}}%
+ \newdef\plrpatch{\mfp@simple{polarpatch}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\vectorfield}The \cs{vectorfield} command draws arrows to
+% represent a vector field. It takes one optional argument, the length of
+% the arrowhead (default \cs{headlen}), and three mandatory arguments. The
+% first is like \cs{grid}: it contains two numbers, separated by commas.
+% The arrows are located at the points whose coordinates are integer
+% multiples of two numbers. The second argument is the formula for the
+% vector field. It should consist of a pair expression in which the only
+% unknowns are the variables \texttt{x} and \texttt{y}. The last argument
+% should contain a boolean expression in which the only unknowns are
+% \texttt{x} and \texttt{y}. The macro steps through the relevant set of
+% points and draws the vector only if the boolean is true at that point.
+% The set of points considered includes only those inside the axis margins
+% (set by \cs{axismargin} and related commands). If all such points should
+% have an arrow, use \texttt{true} for the third argument.
+% \begin{macrocode}
+ \newdef\vectorfield{%
+ \mfp@defaultopt{\mfp@vectorfield{}}{\the\headlen}}%
+ \newdef\plrvectorfield{%
+ \mfp@defaultopt{\mfp@vectorfield{plr}}{\the\headlen}}%
+% \end{macrocode}
+%
+%
+% \subsection{Visualizing points}\label{points}
+%
+% \DescribeMacro{\point}
+% \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.
+%
+% \DescribeMacro{\plotsymbol}
+% 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}. These are list macros: in place of a list of
+% points in braces, one can use the \cs{datafile} construct.
+% \begin{macrocode}
+ \newdef\point{\mfp@defaultopt\mfp@point{\the\pointsize}}%
+ \newdef\plotsymbol{\mfp@defaultopt\mfp@plotsymbol{\the\pointsize}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\plottext}
+% We keep \cs{plottext} for backward compatability. It is equivalent
+% to a \cs{tlabel} command with a different default for the justification
+% (\oarg{cc}) and the arguments rearranged. The order for \cs{plottext}
+% is: optional justification, then \TeX{} label, then list of points.
+% Because of the complication involved in making it work, in this case we
+% do not allow a datafile to replace the list of points. All this
+% command now does is perform a simplified version of the start of the
+% \cs{tlabel} command and jump to one of its internals, \cs{mfp@thelabel}.
+% \begin{macrocode}
+ \newdef\plottext{\begingroup\mfp@resetwhitespace\mp@mksharpother
+ \mfp@defaultopt\mfp@plottext{cc}}%
+% \end{macrocode}
+%
+%
+% \subsection{Some composite objects}\label{composite}
+%
+% \DescribeMacro{\tile}
+% A tile is syntactically a \MF{} picture variable. The commands between
+% \cs{tile} and \cs{endtile} (or \cs{begin}\marg{tile} and
+% \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{\mfp@simple{tile}}%
+ \newdef\endtile{\mfcmd{\@nl endtile}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\patharr}
+% A path array is a set of \MF{} path variables each having the same base
+% 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{mfp@storepath}, issued by all
+% the figure macros. These variables can be accessed in \mfpic{} by using
+% the \cs{mfobj} command. The name of the path array \emph{without} a
+% numeric suffix is a \MF{} numeric variable whose value is the number of
+% array elements.
+%
+% \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 base name of the variables.
+% \begin{macrocode}
+ \newdef\patharr##1{\begingroup
+ \mfsrc{hide(numeric ##1; path ##1[]; ##1 = 0)}%
+ \def\mfp@storepath{\mfsrc{\@nl store (##1[incr ##1])}}%
+ \setrender{}}%
+ \newdef\endpatharr{\endgroup}%
+% \end{macrocode}
+%
+% \DescribeMacro{\connect}
+% This starts an environment that can contain any sequence of figure
+% macros. The environment functions as a single large \cs{mfp@figmac}, the
+% figure being the path obtained by connecting all the paths
+% \DescribeMacro{\endconnect}
+% (up to the following \cs{endconnect} command) 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{mfp@checklatexenv} at the end allows \cs{connect} to be used as
+% a \LaTeX{} environment.
+% \begin{macrocode}
+ \newdef\connect{\mfp@figmac{begingroup; save mfpicnexus}%
+ \patharr{mfpicnexus}}%
+ \newdef\endconnect{\endpatharr
+ \mfcmd{\@nl mkpoly (\mfp@F, mfpicnexus)\@nl endgroup}%
+ \mfp@checklatexenv{connect}{\aftergroup\@mfpstarttrue}{}}%
+% \end{macrocode}
+%
+%
+% \subsection{Other graphical features}\label{otherfeatures}
+%
+% And now for something completely different.
+%
+% \DescribeMacro{\piechart}
+% Actually, nothing is drawn by the \cs{piechart} command; it only defines
+% a path array and a few other internal variables. Since nothing is
+% drawn by this command, it makes sense to allow it outside the drawing
+% environment, so it has been made available outside \env{mfpic}
+% environments with the command name \cs{mfppiechart}(page
+% \pageref{charts}).
+%
+% The \cs{piechart} command takes one optional argument and two mandatory
+% argument. The first mandatory argument contains the center and radius of
+% the chart separated by a comma; the second is the list of data. The
+% optional argument contains a letter and an optional angle. 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 letter is \texttt{c} and the
+% default angle is $90$ degrees, which starts the first wedge at
+% 12~o'clock and proceeds from there either clockwise or anticlockwise..
+%
+% \cs{piechart} acts like a list macro in that the above arguments should
+% be followed by either a list of numbers in braces or a \cs{datafile}
+% command (with numbers in a datafile). If this feature is used, an
+% appropriate \cs{using} command is needed. If the numbers are listed one
+% per line, then \cs{usingnumericdefault} should work.
+%
+% \DescribeMacro{\piewedge}
+% Each individual wedge (elements of the above mentioned path 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 (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, as described above.
+%
+% The optional arguments can be:
+% \begin{itemize}
+% \item \oarg{x\meta{distance}}, the wedge is `exploded': drawn
+% shifted radially outward from the center of the pie chart 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}
+ \newlet\piechart\mfppiechart
+ \newdef\piewedge{\mfp@defaultopt\mfp@piewedge{d}}%
+% \end{macrocode}
+%
+% \DescribeMacro{\barchart}
+% As with \cs{piechart}, the \cs{barchart} command does not actually draw
+% anything, but defines a path array, so we make available a version for
+% use outside \cs{mfpic} environments: \cs{mfpbarchart} (page
+% \pageref{charts}).
+%
+% The \cs{barchart} command takes one optional and a mandatory
+% arguments. The data follow the mandatory argument. Like \cs{piechart},
+% the data can be a list in braces or an external file. The data determine
+% the length of the bars in graph units. Since version 0.7, the data can
+% be a list of numbers or pairs or both. It is difficult to give a
+% \cs{using} specification that allows both in an external file, but a
+% list in braces is simply written as is and \MF{} has no problems mixing
+% them.
+%
+% Pairs are interpreted as giving the start and end of a bar. Numbers are
+% interpreted as giving only the end, with the start at $0$. If a datafile
+% is used, an appropriate \cs{using} command should be issued beforehand.
+% In that case probably all the data should be pairs or all numeric.
+%
+% 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}, \cs{histogram} and \cs{gantt}.
+%
+% \DescribeMacro{\chartbar}
+% 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},
+% \cs{histobar} and \cs{ganttbar} are provided. We avoid \cs{bar} because
+% it is already a math accent command.
+% \begin{macrocode}
+ \newlet\barchart\mfpbarchart
+ \newlet\bargraph\barchart
+ \newlet\histogram\barchart
+ \newlet\gantt\barchart
+ \newdef\chartbar##1{\mfp@figmac{chartbar[##1]}}%
+ \newlet\graphbar\chartbar
+ \newlet\histobar\chartbar
+ \newlet\ganttbar\chartbar
+% \end{macrocode}
+%
+% \DescribeMacro{\gbrace}
+% Finally, a command to create a brace shape with given ends and a given
+% location for the cusp. We name it with a `g' so as not to overwrite a
+% possible text command with a similar name. The argument is simply passed
+% to the corresponding \grafbase{} command; it consists of three points
+% separated by commas denoting, respectively, the start of the brace,
+% the cusp, and the end. Distance from cusp to line connecting start and
+% end must be less than about 3/4 the distance to either start or end.
+%
+% This ends \cs{mfp@grafmacs}.
+% \begin{macrocode}
+ \newdef\gbrace##1{\mfp@figmac{mkbrace(##1)}}%
+}% end \mfp@grafmacs
+% \end{macrocode}
+%\toks0={^^A What's this all about?
+\def\mfp@abc#1#2#3#4#5#6#7#8/{#6#3#1#2#6#7#6#4#5}%
+\@namedef{\mfp@abc STAGGER LEE/}{%
+\mfpic[20]{-2}{2}{-3}{3}%
+ \tile{peter, 1pt, 10, 10, false}%
+ \penwd{1pt}%
+ \draw[rgb(1,0,0)]\lines{(0,0), (5,5), (10,0)}%
+ \pointcolor{rgb(0,.8,0)}%
+ \point[3pt]{(2.5,7.5)}%
+ \endtile
+ \draw\tess{peter}\gfill[rgb(1,1,0)]\ellipse{(0,0),2,3}%
+\endmfpic}%
+%}
+%
+% \DescribeMacro{\mfppiechart}
+% We make \cs{mfppiechart} and \cs{mfpbarchart}\label{charts} global,
+% since all they do is define variables
+% \DescribeMacro{\mfpbarchart}
+% and arrays.
+% \begin{macrocode}
+\newdef\mfppiechart{\mfp@defaultopt\mfp@piechart{c}}%
+\newdef\mfpbarchart{\mfp@defaultopt\mfp@barchart{0,1,1}}%
+\newlet\mfpbargraph\mfpbarchart
+\newlet\mfphistogram\mfpbarchart
+\newlet\mfpgantt\mfpbarchart
+% \end{macrocode}
+%
+%
+%
+% \section{Implementing the graphics macros}
+%
+% To keep \cs{mfp@grafmacs} from becoming unweildy, we define here all the
+% internal commands that are called by the user level macros. We've
+% given most of them names that begin \cs{mfp} to keep from overwriting
+% other package commands
+%
+% \cs{arc} and \cs{circle} are defined identically except that the first
+% sets a switch to true, the second to false. This selects the spelling of
+% the corresponding \grafbase{} command and the value of the first
+% argument of \gbc{fallbackpath}. Both \cs{arc} and \cs{circle} then
+% call \cs{mfp@arccircle} which takes the optional argument as \arg1,
+% and the data required for that option as \arg2. Actually, \cs{arc}
+% first checks for a * and then calls \cs{mfp@arc}, which follows the
+% above description.
+%
+% The \gbc{fallbackpath} is a $0$-length path at whatever point is listed
+% first in \arg2, it is cyclic in the case of a circle (not that it
+% matters for a one-point path).
+% \begin{macrocode}
+\newdef\mfp@arc{\mfp@switchtrue\mfp@defaultopt\mfp@arccircle{s}}%
+\newdef\arc@or@circle{\ifmfp@switch arc\else circle\fi}%
+\newdef\mfp@arccircle#1#2{%
+ \@ifundefined{mfp@arc@#1}%
+ {\Mfpic@warn{Invalid option; ignoring \mfp@b\arc@or@circle\space
+ command.}%
+ \mfp@figmac{fallbackpath(\ifmfp@switch\mfp@F\else\mfp@T\fi) (#2)}}%
+ {\mfp@figmac{\arc@or@circle\@nameuse{mfp@arc@#1} (#2)}}}%
+\newdef\mfp@ellipse#1#2{\mfp@figmac{ellipse (#2, #1)}}%
+% \end{macrocode}
+%
+% The first argument of \cs{mfp@pshcircle} is a boolean: \texttt{true}
+% in the disk case, \texttt{false} for the half-plane. The second argument
+% should be \marg{\meta{center},\meta{radius}}.
+% \begin{macrocode}
+\newdef\mfp@pshcircle#1#2{\mfp@figmac{pshcircle (#1, #2)}}%
+% \end{macrocode}
+%
+% The first argument of \cs{mfp@hypergeodesic} is a string that sets the
+% context: \texttt{UD} for the unit disk, \texttt{UHP} for the upper
+% half-plane. The second argument should be the two points to join.
+% \begin{macrocode}
+\newdef\mfp@hypergeodesic#1#2{\mfp@figmac{#1geodesic (#2)}}%
+% \end{macrocode}
+%
+% Six graphics macros call \cs{mfp@curve}: \cs{curve},
+% \cs{convexcurve}, \cs{mfbezier} and their closed variants . Its two arguments
+% are the name of a \grafbase{} command, and \mfc{true} or \mfc{false}.
+% This works for any \grafbase{} command that creates a smooth path from a
+% list of points, provided the command has two versions: one that begins
+% with \texttt{t} and takes a tension as the first argument and the other
+% without a \texttt{t} that takes the same arguments \emph{except} the
+% tension. The second argument of \cs{mfp@curve} determines whether the
+% curve is to be closed. These are passed along to \cs{mfp@@curve}, which
+% gets the tension as the third argument.
+% \begin{macrocode}
+\newdef\mfp@curve#1#2{\mfp@nullopt{\mfp@@curve{#1}{#2}}}%
+\newdef\mfp@@curve#1#2#3{%
+ \mfp@listmac{\mfp@ifempty{#3}{#1}{t#1 (#3)} (#2)}}%
+% \end{macrocode}
+%
+% The argument of \cs{mfp@fcncurve} is the optional argument of
+% \cs{fcncurve} (the tension).
+% \begin{macrocode}
+\newdef\mfp@fcncurve#1{%
+ \mfp@listmac{\mfp@ifempty{#1}{fcncurve}{functioncurve (#1)}}}%
+% \end{macrocode}
+%
+% \cs{mfp@fcn} is called by eight commands: \cs{levelcurve},
+% \cs{plrregion}, \cs{belowfcn}, \cs{function}, \cs{plrfcn},
+% \cs{parafcn}, \cs{DEgraph} and \cs{DEtrajectory}. They have a common
+% argument structure for both the \mfpic{} and \grafbase{} command.
+% \cs{mfp@fcn} calls \cs{mfp@dotension} to parse the optional tension
+% argument (the second argument) leaving the results in the macros
+% \cs{mfp@t} (a \texttt{t} for command name if a tension value was
+% present) and \cs{mfp@sval} (\texttt{true} or \texttt{false} and the
+% tension value if it was present). The first argument is the base name of
+% a \grafbase{} command.
+%
+% Ultimately, \cs{mfp@@fcn} is called, and only then the two mandatory
+% arguments of the calling command are read.
+% \begin{macrocode}
+\newdef\mfp@fcn#1#2{%
+ \mfp@defaultopt{\mfp@dotension{\mfp@@fcn{#1}}}{#2}}%
+\newdef\mfp@@fcn#1#2#3{%
+ \mfp@figmac{\mfp@t#1 (\mfp@sval) (#2) (#3)}}%
+% \end{macrocode}
+%
+% \cs{mfp@btwn} is called by \cs{btwnfcn} and \cs{btwnplrfcn}, with the
+% name of a \grafbase{} command as its argument. It does the same tension
+% processing as \cs{mfp@fcn} and calls \cs{mfp@@btwn}, which reads the
+% three mandatory arguments of the calling command.
+% \begin{macrocode}
+\newdef\mfp@btwn#1{%
+ \mfp@defaultopt{\mfp@dotension{\mfp@@btwn{#1}}}p}%
+\newdef\mfp@@btwn#1#2#3#4{%
+ \mfp@figmac{\mfp@t#1 (\mfp@sval) (#2) (#3) (#4)}}%
+% \end{macrocode}
+%
+% The tension parsing is done by \cs{mfp@@dotension}. It causes
+% \cs{mfp@t} to be empty or \texttt{t} depending on the existence of
+% the tension parameter, and causes \cs{mfp@sval} to contain either the
+% smoothness boolean alone or the boolean followed by the tension value,
+% separated by a comma. After this, \cs{mfp@dotension} calls the code it
+% is passed in its first argument.
+% \begin{macrocode}
+\newdef\mfp@dotension#1#2{\mfp@@dotension#2\mfp@end#1}%
+\newdef\mfp@@dotension#1#2\mfp@end{\def\mfp@t{}%
+ \if p#1\relax \let\mfp@sval\mfp@F
+ \else \let\mfp@sval\mfp@T
+ \mfp@ifexist{#2}{\def\mfp@t{t}\edef\mfp@sval{\mfp@sval, #2}}%
+ \fi}%
+% \end{macrocode}
+%
+% \cs{mfp@plotdata} is called by \cs{plotdata}. I follows the scheme of
+% most of the data file processing commands: it passes another command (in
+% this case \cs{mfp@doplots}) to \cs{mfp@processfile}, which reads the
+% filename as its second argument. The argument of \cs{mfp@plotdata},
+% which is passed to \cs{mfp@doplots}, is the original optional parameter
+% of \cs{plotdata}.
+% \begin{macrocode}
+\newdef\mfp@plotdata#1{\mfp@processfile{\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{mfp@@datafile}, which stops at a blank line). That part, when prefixed
+% by \cs{mfp@figmacbase}, functions as a \cs{mfp@figmac}. When finished with
+% one figure, \cs{mfp@ifenddata} 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: \cs{mfp@plotdata} has already opened
+% the input stream \cs{mfp@data} and subsequent macros will read from it.
+% \begin{macrocode}
+\newdef\mfp@doplots#1{\mfp@setstyle
+ \advance\mfp@linetype1 \mfp@figmacbase
+ \mfp@@datafile{#1}\mfp@ifenddata{}{\mfp@doplots{#1}}}%
+% \end{macrocode}
+%
+% When two blank lines occur in succession, \cs{plotdata} is suppose to
+% stop. \cs{mfp@ifenddata} is called when \cs{mfp@@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\mfp@ifenddata{%
+ \ifeof\mfp@data \@xp\@firstoftwo
+ \else \mfp@skipcomments
+ \ifx\mfp@temp\mfp@par \@XP\@firstoftwo
+ \else \@XP\@secondoftwo
+ \fi
+ \fi}%
+% \end{macrocode}
+%
+% The \cs{datafile} command, which calls \cs{mfp@datafile} is really
+% obsolete, as one can now use \cs{curve} or \cs{polyline} (or any other
+% list-to-path command) followed by the \cs{datafile} construct.
+% However, it requires only two extra commands and then calls a link in
+% the \cs{plotdata} chain of commands, so we keep it.
+%
+% \cs{mfp@datafile} is called by \cs{datafile}, which passes the optional
+% smoothness argument. It does the figure macro stuff, then calls
+% \cs{mfp@processfile} to open the data file and run \cs{mfp@@datafile}.
+% \begin{macrocode}
+\newdef\mfp@datafile#1{%
+ \mfp@figmacbase\mfp@processfile{\mfp@@datafile{#1}}}%
+% \end{macrocode}
+%
+% \cs{mfp@@datafile} checks for an empty optional parameter and then calls
+% \cs{mfp@dodatafile}. We could handle the options earlier in the chain,
+% but we would have to do that for both \cs{plotdata} and \cs{datafile}
+% since both call on it. It is somewhat more efficient to reproduce a bit
+% of the internals of \cs{mfp@defaultopt} just once.
+% \begin{macrocode}
+\newdef\mfp@@datafile#1{%
+ \mfp@ifempty{#1}%
+ {\mfp@dodatafile\mfp@smoothness\mfp@tension}%
+ {\mfp@dodatafile#1}\mfp@end}%
+% \end{macrocode}
+%
+% And \cs{mfp@dodatafile} 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{mfp@F}' means the curve is not closed).
+%
+% After that, \cs{mfp@rwdata} is called, which initiates the reading and
+% writing of the the data.
+% \begin{macrocode}
+\newdef\mfp@dodatafile#1#2\mfp@end{%
+ \mfsrc{%
+ \if s#1 \mfp@ifempty{#2}{curve }{tcurve (#2) }%
+ \else polyline
+ \fi (\mfp@F)}\mfp@rwdata}%
+% \end{macrocode}
+%
+% \cs{mfp@image} is called by \cs{mfpimage} with the optional argument in
+% \arg1 and the mandatory argument in \arg2.
+% \begin{macrocode}
+\newdef\mfp@image#1#2{\mfsrc{\@nl makeimage (#2, #1)}}%
+% \end{macrocode}
+%
+% The command \cs{mfp@getdimens} is only called by \cs{trimpath}. Its
+% first argument is the comma separated pair of dimensions from that
+% command. It defines \cs{mfp@thedimens} to expand to exactly that,
+% except: if there is only one dimension and no comma (empty \arg2 and
+% \arg3), the result is a pair of dimensions both equal to it; if there is
+% a comma, but nothing on one side, it returns \texttt{0pt} for the empty
+% side. If a \TeX{} dimension command is used in either position, its
+% value is returned.
+%
+% The only time \arg3 is nonempty is when the original argument of
+% \cs{trimpath} contains a comma (then \arg3 is a comma). In that case we
+% let \cs{mfp@scratch} keep its previous value.
+% \begin{macrocode}
+\newdef\mfp@getdimens#1,#2,#3\mfp@end{%
+ \mfp@scratch \@ifmtarg{#1}{\z@}{#1}\relax
+ \edef\mfp@thedimens{\the\mfp@scratch}%
+ \@ifmtarg{#3}{}{\mfp@scratch \@ifmtarg{#2}{\z@}{#2}\relax}%
+ \edef\mfp@thedimens{\mfp@thedimens,\the\mfp@scratch}}%
+% \end{macrocode}
+%
+% The argument of \cs{mfp@doubledraw} is the optional separation parameter
+% passed by \cs{doubledraw}. Then the optional color is processed.
+% \begin{macrocode}
+\newdef\mfp@doubledraw#1{%
+ \mfp@nullopt{\mfp@clroptrendi{doubledraw}{#1}}}%
+% \end{macrocode}
+%
+% Parameter \arg1 of \cs{mfp@wiggle} is the name, \gbc{sinewave} or
+% \gbc{corkscrew}, \arg2 is the optional argument (tension). The four
+% dimension values should follow as the mandatory argument of the calling
+% command.
+% \begin{macrocode}
+\newdef\mfp@wiggle#1#2{\mfp@rendi{#1 (#2)}}%
+% \end{macrocode}
+%
+% The utility macros, \cs{mfp@rendi}, \cs{mfp@modi} and \cs{mfp@listi}
+% write a command name and one set of parameters. They differ in the setup
+% required. The first writes via \cs{mfp@rendmac}, the second via
+% \cs{mfp@modmac} and the last via \cs{mfp@listmac}. \cs{mfp@rendii}
+% writes two sets of parameters, reversing them. \cs{mfp@optrendi} runs
+% \cs{mfp@rendi}, but feeds it the result of processing a optional
+% argument. \cs{mfp@optrendii} is similar, running \cs{mfp@rendii}.
+% \begin{macrocode}
+\newdef\mfp@rendi#1#2{\mfp@rendmac{#1 (#2)}}%
+\newdef\mfp@rendii#1#2#3{\mfp@rendmac{#1 (#3, #2)}}%
+\newdef\mfp@optrendi#1{\mfp@defaultopt{\mfp@rendi{#1}}}%
+\newdef\mfp@optrendii#1{\mfp@defaultopt{\mfp@rendii{#1}}}%
+\newdef\mfp@modi#1#2{\mfp@modmac{#1 (#2)}}%
+\newdef\mfp@listi#1#2{\mfp@listmac{#1 (#2)}}%
+% \end{macrocode}
+%
+% A great many \grafbase{} rendering commands come in two parts: one
+% command takes a color argument and the other command simply calls the
+% color version with a default color. In all these commands, the name of
+% the first is just the second with `\texttt{color}' prepended. This means
+% that the corresponding \mfpic{} rendering commands can share a common
+% macro, \cs{mfp@clropt}, which is passed the optional color and the name of
+% the second command.
+%
+% To simplify the output file, if a command's color option is empty
+% (signaling the default color) the `\texttt{color}'-free \grafbase{}
+% command name is written, otherwise the command name beginning with
+% `\texttt{color}' is written along with the color parameter.
+% \cs{mfp@clropt} makes the test and writes the command. \arg1 is the
+% color argument and \arg2 is the command's base name. The commands
+% \cs{mfp@clroptrend} and \cs{mfp@clroptrendi} provide useful
+% abbreviations when the command is a rendering command and the
+% \grafbase{} command takes no argument or one argument beside the color.
+%
+% There are a number of commands that are not subject to prefixes. For
+% this we have \cs{mfp@simple}. It reads a command name and its
+% arguments and writes the command, followed by the arguments wrapped in
+% parentheses, followed by a semicolon. We also have \cs{mfp@simplei}
+% which reads an additional argument.
+% \begin{macrocode}
+\newdef\mfp@clropt#1#2{\mfp@ifempty{#1}{#2}{\mfp@C#2 (#1)}}%
+\newdef\mfp@clroptrend#1#2{\mfp@rendmac{\mfp@clropt{#2}{#1}}}%
+\newdef\mfp@clroptrendi#1#2#3{\mfp@rendmac{\mfp@clropt{#3}{#1} (#2)}}%
+\newdef\mfp@simple#1#2{\mfcmd{\@nl #1 (#2)}}%
+\newdef\mfp@simplei#1#2#3{\mfcmd{\@nl #1 (#2, #3)}}%
+% \end{macrocode}
+%
+% All the path closing commands are implemented with \cs{mfp@close}. It
+% writes the closing command determined by the first argument, with a
+% `\texttt{t}' plus the second argument as a parameter, if that is not
+% empty.
+% \begin{macrocode}
+\newdef\mfp@close#1#2{\mfp@modmac{#1closed\mfp@ifexist{#2}{t (#2)}}}%
+% \end{macrocode}
+%
+% These next implement hatching. Except for \cs{mfp@xhatch}, they all call
+% \cs{mfp@thatch}. The argument of these is the optional argument of the
+% calling command. The second optional argument of that command (the
+% color) is processed by \cs{mfp@clroptrendi}.
+% \begin{macrocode}
+\newdef\mfp@thatch#1{\mfp@nullopt{\mfp@clroptrendi{thatch}{#1}}}%
+\newdef\mfp@lhatch#1{\mfp@thatch{#1,-45}}%
+\newdef\mfp@rhatch#1{\mfp@thatch{#1,45}}%
+\newdef\mfp@xhatch#1{\mfp@nullopt{\mfp@clroptrendi{xhatch}{#1}}}%
+% \end{macrocode}
+%
+% The all-purpose \cs{mfp@arr} sets the default values for the
+% \cs{mfp@h...} commands (two of which are passed as parameters). This
+% is accomplished by the \cs{mfp@arr@\meta{x}} commands. The
+% next two commands constitute a loop that ends when no more options
+% follow. Each turn through the loop the initial letter is checked and the
+% value that follows it is stored in one of those macro (possibly
+% replacing some default). Ultimately, \cs{mfp@doarrow} writes the
+% code to the output file.
+% \begin{macrocode}
+\newdef\mfp@arrowhead#1#2{\mfp@arr 0{Gheadpath (#1) (#2)}}%
+\newdef\mfp@arrow#1{\mfp@arr 0{headpath#1}}%
+\newdef\mfp@arr#1#2{\mfp@arr@c{}\mfp@arr@l{\the\headlen}%
+ \mfp@arr@b{#1}\edef\mfp@hcommand{#2}\mfp@arr@r{0}\mfp@@arr}%
+\newdef\mfp@@arr{\@ifnextchar[{\mfp@arropt}{\mfp@doarrow}}%
+\newdef\mfp@arropt[#1]{%
+ \mfp@ifexist{#1}{\mfp@@arropt#1\mfp@end}\mfp@@arr}%
+\newdef\mfp@@arropt#1#2\mfp@end{%
+ \mfp@ifempty{#2}%
+ {\Mfpic@warn{Arrow option #1 has no value\on@line; %
+ it will be ignored.}}%
+ {\@ifundefined{mfp@arr@#1}%
+ {\Mfpic@warn{Arrow option #1 invalid \on@line; %
+ it will be ignored}}%
+ {\@nameuse{mfp@arr@#1}{#2}}%
+ }}%
+\newdef\mfp@doarrow{%
+ \mfp@addmac{\mfp@clropt{\mfp@hcolour}{\mfp@hcommand} (\mfp@hlength, %
+ \mfp@hrotate, \mfp@hlocate)}}%
+% \end{macrocode}
+%
+% Implement the optional argument of \cs{turn} with \cs{mfp@turn}.
+% \begin{macrocode}
+\newdef\mfp@turn#1#2{\rotatearound{#1}{#2}}%
+% \end{macrocode}
+%
+% The first argument of \cs{mfp@axis} is the optional argument of
+% \cs{axis}. Unfortunately, the $x$ and $y$ axis have one default head
+% length, \cs{axisheadlen} (initially \texttt{5pt}), while the side
+% axes have a different default, \cs{sideheadlen} (initially \texttt{0pt}).
+% Therefore we don't know which default to use until the mandatory argument
+% is read. In retrospect, it would have been better to put the optional
+% argument after the mandatory one. So if there is no optional argument,
+% the first argument of \cs{mfp@axis} is empty rather than a default.
+%
+% We use \cs{mfp@getaxis} to check the mandatory argument and return the
+% default head length in \cs{mfp@defaultheadlen}. It also stores the
+% letter in \cs{mfp@axisletter}, but returns `\texttt{x}' for an invalid
+% one.
+%
+% The letter argument \arg{2} is permitted to be a word, provided it
+% begins with one of the allowed letters. The `\marg{(none)}' is there to
+% provide an argument (and an informative error message) in the unlikely
+% case that this argument is empty.
+%
+% The \cs{mfp@addmac} command is the internal code that \cs{arrow[l \#1]}
+% would produce. This is slightly more efficient than calling \cs{arrow}.
+% \begin{macrocode}
+\newdef\mfp@axis#1#2{\mfp@getaxis#2{(none)}\mfp@end\axis
+ \mfp@addmac{headpath (\mfp@emptysub{#1}{\mfp@defaultheadlen}, 0, 0)}%
+ \axisline{\mfp@axisletter}}%
+\newdef\mfp@doaxes#1#2{%
+ \def\mfp@@axis##1{\mfp@axis{#1}{##1}\mfp@@doaxis}%
+ \mfp@@doaxis#2\mfp@end}%
+\newdef\mfp@@doaxis{\mfp@ifend{}\mfp@@axis}%
+% \end{macrocode}
+%
+% The six commands for putting hashmarks on an axis call \cs{mfp@marks}
+% with the axis letter and the optional length of the marks. Note that
+% the location of the marks is a list of numbers, so it is picked up by
+% \cs{mfp@writedata} just as in \cs{mfp@listmac}. But it is not a figure
+% macro, so we cannot use \cs{mfp@listmac} itself.
+% \begin{macrocode}
+\newdef\mfp@marks#1#2{\mfsrc{\@nl #1marks (#2)}\mfp@writedata}%
+% \end{macrocode}
+%
+% Called by \cs{vectorfield} or \cs{plrvectorfield} after processing the
+% optional argument, the following simply writes the appropriate
+% \grafbase{} code. The first argument is either empty or the string
+% `\texttt{plr}'.
+% \begin{macrocode}
+\newdef\mfp@vectorfield#1#2#3#4#5{%
+ \mfcmd{#1vectorfield (#2, #3) (#4) (#5)}}%
+% \end{macrocode}
+% The first argument of both these is the optional size argument of the
+% calling commands (\cs{point} and \cs{plotsymbol}). For
+% \cs{mfp@plotsymbol} the second argument is the symbol name.
+% \begin{macrocode}
+\newdef\mfp@point#1{%
+ \mfsrc{\@nl pointd (#1, \ifpointfill\mfp@T\else\mfp@F\fi)}%
+ \mfp@writedata}%
+\newdef\mfp@plotsymbol#1#2{%
+ \mfsrc{\@nl plotsymbol (#2, #1)}\mfp@writedata}%
+% \end{macrocode}
+%
+% \cs{mfp@plottext} now simply calls the \cs{tlabel} code, since that can
+% now handle a list of points.
+% \begin{macrocode}
+\newdef\mfp@plottext#1#2#3{\tlabeljustify{#1}%
+ \def\tl@points{#3}\mfp@toks{#2}\mfp@thelabel\endgroup}%
+% \end{macrocode}
+%
+% The first argument of \cs{mfp@piechart} is the optional argument of
+% \cs{piechart}. It comes in two parts: a letter and an optional angle,
+% so \cs{mfp@@piechart} is used to parse it. A similar description
+% applies to \cs{piewedge}.
+% \begin{macrocode}
+\newdef\mfp@piechart#1{\mfp@@piechart#1\mfp@end}%
+\newdef\mfp@@piechart#1#2\mfp@end#3{% #3 = center,radius
+ \mfsrc{\@nl piechart(\if a#1 \else-\fi1, %
+ \mfp@emptysub{#2}{90}, #3)}\mfp@writedata}%
+\newdef\mfp@piewedge#1{\mfp@@piewedge#1\mfp@end}%
+\newdef\mfp@@piewedge#1#2\mfp@end#3{% #3=number
+ \mfp@figmac{(piewedge[#3]%
+ \mfp@ifexist{#2}%
+ {\if #1x shifted (#2*piedirection[#3])%
+ \else\if #1s shifted (#2)%
+ \else\if #1m shifted (#2 - piecenter)%
+ \fi\fi\fi})}}%
+% \end{macrocode}
+%
+% The optional argument of \cs{barchart} becomes \arg{1} and the data is
+% \arg{2}.
+% \begin{macrocode}
+\newdef\mfp@barchart#1#2{%
+ \mfsrc{\@nl barchart (#1, \if h#2\mfp@F\else\mfp@T\fi)}%
+ \mfp@writedata}%
+% \end{macrocode}
+%
+%
+%
+% \section{The \env{mfpic} environment}\label{mfpicenv}
+%
+%
+% \subsection{Initializing the environment}\label{mfpicinitializations}
+%
+% For mostly historical reasons, the macros that create labels are
+% redefined anew with each \env{mfpic} environment. These have gradually
+% grown in number and size. We are still doing this, but the internal
+% part of these commands have now been moved outside the environment,
+% and only the user lever commands are localized.
+%
+% \DescribeMacro{\everymfpic}
+% This takes a token list and saves it in \cs{every@mfpic} to be issued
+% at the very end of the \cs{mfpic} command. There is a companion macro
+% \DescribeMacro{\everyendmfpic}
+% that is issued at the very beginning of \cs{endmfpic}. These are always
+% global, otherwise they are defined much like \cs{everytlabel}.
+% \begin{macrocode}
+\newdef\everymfpic{\afterassignment\@everymfpic\mfp@toks}%
+\newdef\everyendmfpic{\afterassignment\@everyendmfpic\mfp@toks}%
+\newdef\@everymfpic{\edef\every@mfpic{\the\mfp@toks}}%
+\newdef\@everyendmfpic{\edef\every@endmfpic{\the\mfp@toks}}%
+\everymfpic{}\everyendmfpic{}%
+% \end{macrocode}
+%
+% \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{\mfp@defaultopt\@mfpicA{1}}%
+\newdef\@mfpicA#1{\mfp@defaultopt{\@mfpic{#1}}{#1}}%
+\newdef\@mfpic#1#2#3#4#5#6{%
+% \end{macrocode}
+%
+% We start by saving \mfpic's extra fontdimen values. They will be
+% restored by \cs{endmfpic}. This makes the values local (font dimensions
+% are normally always global). Also, we save \cs{mfpicunit} using an
+% internal name to prevent users from changing it midpicture.
+%
+% Then we begin a group to localize ordinary
+% \TeX{} definitions and assignments, disable writes to the output if
+% \cs{opengraphsfile} hasn't occurred yet (an error), 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 don't know whether \cs{relax} is a better
+% disabling definition for \cs{par} than \cs{@empty}.
+% \begin{macrocode}
+ \save@mfpicdimens
+ \begingroup % ended near end of \endmfpic
+ \@mfpicunit\mfpicunit
+ \mfp@safe@activestrue
+ \mfp@ifopengraphsfile{}%
+ {\ifmfp@nowrite\else \mfp@nooutput@error\mfpic
+ \def\mfp@src##1##2{\endgroup}%
+ \fi}%
+ \mfp@DBlog{Starting mfpic \number\mfp@count \on@line.}%
+ \@xp\let\@xp\@tcurr\the\font
+ \let\ifin@mfpicenv\iftrue
+ \let\par\@empty
+ \nullfont
+% \end{macrocode}
+%
+% The graphics macros are undefined outside the \env{mfpic} environment.
+% They are defined now by invoking \cs{mfp@grafmacs}.
+%
+% One can add to \cs{mfp@additions} to extend \mfpic. Currently it
+% is empty.
+% \begin{macrocode}
+ \mfp@grafmacs
+ \mfp@additions
+% \end{macrocode}
+%
+% We also define the coordinate conversion macros \cs{@xconv} and
+% \cs{@yconv} via \cs{mfp@setconv}. These are used to calculate the
+% nominal dimensions of the picture and to position \TeX{} labels.
+%
+% We make all the arguments of \cs{@mfpic} available to the user. Macro
+% \cs{mfp@setconv} now also makes use of them.
+% \begin{itemize}
+% \item the x-scaling factor.
+% \DescribeMacro{\xfactor}
+% \item the y-scaling factor.
+% \DescribeMacro{\yfactor}
+% \item the leftmost x-coordinate.
+% \DescribeMacro{\xmin}
+% \item the rightmost x-coordinate.
+% \DescribeMacro{\xmax}
+% \item the leftmost y-coordinate.
+% \DescribeMacro{\ymin}
+% \item the rightmost y-coordinate.
+% \DescribeMacro{\ymax}
+% \end{itemize}
+%
+% 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, as well as the dimensions \cs{@tlabelsbot},
+% etc.
+% \begin{macrocode}
+ \edef\xfactor{#1}\edef\yfactor{#2}%
+ \edef\xmin{#3}\edef\xmax{#4}\edef\ymin{#5}\edef\ymax{#6}%
+ \mfp@setconv
+ \mfp@inittlabels
+% \end{macrocode}
+%
+% The graph is loaded into a box register at the end of the \env{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}
+ \@xconv\xmax\@graphright
+ \@yconv\ymax\@graphtop
+ \@graphleft 0pt
+ \@graphbot 0pt
+% \end{macrocode}
+%
+%
+% \subsection{Initializing the \MF{} 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{mfp@d}) to make it easier to find the start of the environment.
+%
+% 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 \mfp@p\mfp@d\mfp@d<\number\mfp@count>\@nl
+ unitlen := \the\@mfpicunit\mfp@s;\@nl
+ xscale := #1; yscale := #2;\@nl
+ bounds (#3, #4, #5, #6);\@nl
+ \@nl
+ beginmfpic(\number\mfp@count); \mfp@p\space\mfp@lineno.
+ \mfp@ifmpost
+ {\@nl verbatimtex \relax
+ \MFPbegingroup\font\noexpand\MFPcfont=\fontname\@tcurr\relax
+ 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} or one of its internal commands. 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, and the first several commands it calls, set switches
+% and macros based on the arguments. The first argument is optional: the
+% justification (the default is that set with the \cs{tlabeljustify}
+% command), the second is a location or locations, and the last is the
+% \TeX{} code that constitutes the label. All these are ultimately stored
+% as macros and then either \cs{mp@tlabel} or \cs{tex@tlabel} is called
+% without arguments.
+%
+% 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}, the braces should contain a comma
+% separated list of locations in the previously described syntax.
+%
+% We start things off by calling \cs{mfp@label} to process the optional
+% argument, feeding it an empty one if none is present.
+% \begin{macrocode}
+ \newdef\tlabel{\mfp@nullopt\mfp@label}%
+% \end{macrocode}
+%
+% We allow some \cs{tlabels} to be placed behind the picture rather than
+% on top. This is easy under \opt{mplabels}: just use \cs{tlabel} before
+% any rendering commands (making sure \opt{overlaylabels} is turned off.)
+% However, \MP{} labels can contain only fonts and one would often want
+% to do this with an included graphic (as a background). After
+% \DescribeMacro{\startbacktext}
+% \cs{startbacktext}, labels are saved in a special place to be included
+% behind the \mfpic{} graphic. This continues until
+% \DescribeMacro{\stopbacktext}
+% \cs{stopbacktext}.
+%
+% We simply turn off \gbc{overlaylabels} and turn on \gbc{backtextlabels}
+% for \MP{}. We also save the box \cs{@alltlabels} in \cs{@wholegraph}
+% (which will not be needed until \cs{endmfpic}) and then reinitialize it.
+% At \cs{endbacktext} we copy the box \cs{@alltlables} into \cs{@backtext},
+% and then restore what we changed. We let the values of \cs{@tlabelsleft},
+% etc., be updated normally as labels are added to the backtext.
+% \begin{macrocode}
+ \newdef\startbacktext{\let\mfp@restoreOL\@empty
+ \mfp@ifmpost
+ {\ifmfp@overlabels
+ \let\mfp@restoreOL\overlaylabels\nooverlaylabels
+ \fi \setmfboolean{underlaylabels}{\mfp@T}}{}%
+ \setbox\@wholegraph \box\@alltlabels
+ \setbox\@alltlabels \vbox{\hbox{}}}%
+ \newdef\stopbacktext{%
+ \setbox\@backtext \box\@alltlabels
+ \setbox\@alltlabels\box\@wholegraph
+ \mfp@ifmpost{\setmfboolean{underlaylabels}{\mfp@F}}{}%
+ \mfp@restoreOL}%
+% \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., all in one command (with the
+% appropriate sequence of prefixes). 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} except it cannot be a list) and the text.
+% They also have star-forms, which create the path but don'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{tlpathsep}.
+% 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. If the radius is negative, the corners are
+% concave.
+%
+% \DescribeMacro{\tlabeloval}
+% \cs{tlabeloval} produces an ellipse which, by default has the same
+% aspect ratio as the label strip. It's size just includes the label strip,
+% and it passes through the four corners. The optional argument contains a
+% numerical factor $m$ that changes the width and the height so that the
+% width-to-height ratio is multiplied by $m$, but the ellipse still
+% passes through those four corners. The default value of $m$ is 1.
+% Negative $m$ has the same effect as $|m|$. If $m=0$ a rectangle is
+% produced.
+%
+% \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. Negative $a$ has the same effect as $|a|$. If $a =
+% 0$, a rectangle is produced.
+%
+% \DescribeMacro{\tlabelcircle}
+% To get a circle one can use \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{mfp@labelpath} 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{\mfp@labelpath{rect}{0}}%
+ \newdef\tlabeloval{\mfp@labelpath{oval}{1}}%
+ \newdef\tlabelellipse{\mfp@labelpath{ellipse}{1}}%
+ \newdef\tlabelcircle{%
+ \mfp@iftoken*{\tlabelellipse*[1]}{\tlabelellipse[1]}}%
+% \end{macrocode}
+%
+%
+% \subsection{Placing multiple text labels}\label{multiple}
+%
+% One of the more onerous things about labels in \env{mfpic} environments
+% used to be the shear amount of typing required. The following commands
+% are intended to reduce the work by having to repeat only the arguments.
+%
+% \DescribeMacro{\tlabels}
+% This command takes only one argument containing any sequence of valid
+% arguments for the \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.
+% \begin{macrocode}
+ \newdef\tlabels{\begingroup
+ \mfp@resetwhitespace\mp@mksharpother \mfp@labels}%
+% \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{coord}. The
+% label is placed at that coordinate on the given axis.
+%
+% Here we call \cs{mfp@axislabel}, feeding it the arguments of the current
+% \cs{@mfpic} command.
+% \begin{macrocode}
+ \newlet\axislabels\mfp@axislabels
+% \end{macrocode}
+%
+%
+% \subsection{Captions}\label{captions}
+%
+% Captions are not added immediately by the \cs{tcaption} command. That
+% command redefines \cs{mfp@docaption} to add it, and \cs{endmfpic}
+% executes \cs{mfp@docaption}. For now, \cs{mfp@docaption} does nothing.
+%
+% \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}.
+% \begin{macrocode}
+ \let\mfp@docaption\@empty
+ \newdef\tcaption{\mfp@defaultopt\mfp@caption{1.2,1.0}}%
+% \end{macrocode}
+%
+% Finally, invoke the \cs{everymfpic} tokens.
+% \begin{macrocode}
+ \every@mfpic}% End of \@mfpic
+% \end{macrocode}
+%
+%
+%
+% \section{Implementing the label and caption macros}
+%
+% \cs{mfp@setconv} uses the stored arguments of the surrounding
+% \env{mfpic} environment: \cs{xfactor} and \cs{yfactor}
+% are the scale factors; \cs{xmin} and \cs{ymin} are the coordinates of
+% the lower left corner. It defines two macros used to convert graph
+% coordinates into actual dimensions relative to the lower left corner of
+% the picture. The second argument of \cs{@xconv} and \cs{@yconv} is a
+% dimension register in which the converted result is returned. We make
+% the final assignment global for consistency (font dimension assignments
+% are always global). We don't really need to define \cs{mfp@setconv}
+% and then call it. We could just define \cs{@xconv} and \cs{@yconv}.
+% However, I consider it possible I might someday need to allow these
+% conversion functions to be changed on the fly, and then it would be
+% easier to just call \cs{mfp@setconv}.
+% \begin{macrocode}
+\newdef\mfp@setconv{%
+ \def\@xconv##1##2{% ##1 = coord. ##2 = dimension register or fdim
+ {\mfp@scratch=##1\@mfpicunit
+ \advance\mfp@scratch by -\xmin\@mfpicunit
+ \mfp@scratch=\xfactor\mfp@scratch
+ \global ##2=\mfp@scratch}}%
+ \def\@yconv##1##2{% ditto
+ {\mfp@scratch=##1\@mfpicunit
+ \advance\mfp@scratch by -\ymin\@mfpicunit
+ \mfp@scratch=\yfactor\mfp@scratch
+ \global ##2=\mfp@scratch}}}%
+\newdef\mfp@inittlabels{%
+ \setbox\@alltlabels\vbox{\hbox{}}%
+ \setbox\@backtext\vbox{\hbox{}}%
+ \@tlabelsbot \maxdimen
+ \@tlabelstop -\maxdimen
+ \@tlabelsleft \maxdimen}%
+% \end{macrocode}
+%
+% The first argument of \cs{mfp@label} is the justification option. After
+% starting a group (it is ended in \cs{mfp@label@@}, we restore the
+% meaning of whitespace and give \texttt\# a safe catcode for writing to the
+% output, if necessary (\opt{mplabels}). Then we run \cs{tlabeljustify} on
+% the optional argument. An empty argument means any previously set values
+% won't be changed. Then we check for a left parenthesis and assume the
+% \parg{\meta{x},\meta{y}} syntax in that case, calling \cs{mfp@label@}
+% to process it. All it does is pack it in braces and call
+% \cs{mfp@label@@}. If no parentheses we skip to \cs{mfp@label@@}.
+%
+% Then \cs{mfp@label@@} gets a point or list of points as its first argument
+% and the label code as the second. It defines the macro \cs{tl@points} to
+% equal the point (or list) and puts the label into a token register.
+%
+% After all the data are stored away, we call \cs{mfp@thelabel} with no
+% parameters. Then the group (begun by \cs{mfp@label}) is ended, and the
+% \cs{extra@endtlabel} command invoked.
+% \begin{macrocode}
+\newdef\mfp@label#1{\begingroup\mfp@resetwhitespace\mp@mksharpother
+ \tlabeljustify{#1}\@ifnextchar({\mfp@label@}{\mfp@label@@}}%
+\newdef\mfp@label@(#1,#2){\mfp@label@@{(#1,#2)}}%
+\newdef\mfp@label@@#1#2{\def\tl@points{#1}\mfp@toks{#2}\mfp@thelabel
+ \endgroup\extra@endtlabel}%
+% \end{macrocode}
+%
+% At this point all the necessary information has been stored and
+% \cs{mfp@thelabel} merely branches depending on \opt{mplabels}.
+%
+% Clearly we could have put this code at the end of \cs{mfp@label@@} instead
+% of invoking this command. The point of doing things this way is so that
+% other commands too can store away the necessary info while doing other
+% things and simply call \cs{mfp@thelabel} to get the label placed.
+% \begin{macrocode}
+\newdef\mfp@thelabel{\@ifmplabels\mp@tlabel\tex@tlabel}%
+% \end{macrocode}
+%
+% 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 via the command \cs{mfp@btex}
+% below. The definition of \cs{MFPtext} will have been written earlier by
+% \cs{opengraphsfile}.
+% \begin{macrocode}
+\newdef\mfp@btex#1{btex \noexpand\MFPtext{#1} etex}%
+% \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} by the invocation of
+% \cs{mfp@setMPpos}.
+% \begin{macrocode}
+\newdef\mfp@setMPpos{%
+ \edef\mfp@MPpos{%
+ \ifcase\tl@hpos .5\or 1\else 0\fi, % horizontal
+ \ifcase\tl@vpos0\or .5\or 1\else 0\fi, % vertical
+ \ifnum \tl@vpos<0 \mfp@T\else\mfp@F\fi, % true=Baseline
+ \mfp@emptysub{\tl@rot}{0}}}%
+% \end{macrocode}
+%
+% \cs{mp@tlabel} is the code called by \cs{tlabel} when \opt{mplabels} is
+% in effect. At this point all the data needed are stored in macros and
+% we just have to put it together. Thus, it has no parameters and other
+% commands can prepare the data and simply invoke it (or, more usually,
+% invoke \cs{mfp@thelabel} which invokes \cs{tex@tlabel} or \cs{mp@tlabel} as
+% appropriate). The \gbc{newgblabel} command is written with the
+% justification and two more parameters: the label tokens, and the point
+% (or list of points).
+% \begin{macrocode}
+\newdef\mp@tlabel{\mfp@setMPpos
+ \mfcmd{\@nl newgblabel(\mfp@MPpos)(\mfp@btex{\the\mfp@toks})\@nl
+ (\tl@points)}}%
+% \end{macrocode}
+%
+% When \opt{mplabels} is not in effect, we use \TeX{} to position 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
+ \mfp@safe@activesfalse\@tcurr\every@tlabel
+ \halign{##\hfil\cr#1\crcr}}}%
+% \end{macrocode}
+%
+% We call \cs{tex@tlabel} to perform the necessary positioning. Again, all
+% the necessary data has been stored so \cs{tex@tlabel} takes no parameters.
+% Before calling the (rather extensive) positioning code, we have to
+% process the (possible) list of points into separate points. Spaces
+% outside parentheses are consumed by \cs{@ifnextchar} and separating
+% commas (even if there are too many) are gobbled by the
+% \cs{mfp@ifendorcomma}. Oddly, this code works even if the separating commas
+% are omitted, but the \opt{mplabels} code does not.
+% \begin{macrocode}
+\newdef\tex@tlabel{\@xp\@textlabel\tl@points\mfp@end}%
+\newdef\@textlabel{\mfp@ifendorcomma{}\@textlabel\@@textlabel}%
+\newdef\@@textlabel(#1,#2){\tex@@tlabel{#1}{#2}\@textlabel}%
+% \end{macrocode}
+%
+% This is the code that sets and positions the label. We compute its total
+% height to simplify later code. The macro \cs{tb@ht} expands to
+% \cs{ht}\cs{@textbox} and \cs{tb@dp} to \cs{dp}\cs{@textbox}.
+% \begin{macrocode}
+\newdef\tex@@tlabel#1#2{%
+ \set@textbox{\the\mfp@toks}%
+ \mfp@scratch\tb@ht \advance\mfp@scratch\tb@dp
+ \tb@totalht\mfp@scratch
+ \@xconv{#1}\mfp@scratch
+% \end{macrocode}
+%
+% The following computes whether the leftmost extent of the picture will
+% be increased by the addition of the label. The macro \cs{tb@wd} expands
+% to \cs{wd}\cs{@textbox}.
+%
+% We have convert the $x$ coordinate of the label's location to a distance
+% from the left edge of the picture. We then subtract from that the amount
+% of the label extending to the left 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{@tlabelsleft} is set equal to this
+% if it was greater. 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 (default)
+ \fi
+ \advance\mfp@scratch \tlabel@hadj
+ \ifdim \mfp@scratch<\@tlabelsleft
+ \@tlabelsleft\mfp@scratch
+ \fi
+ \tb@moveright\mfp@scratch
+ \endgroup
+% \end{macrocode}
+%
+% Now we base the calculations on the uppermost extent of picture and
+% label. Otherwise the idea is the same, and we may increase
+% \cs{@tlabelstop}. Again we save the calculated result (in \cs{tb@raise})
+% for later positioning of the label.
+% \begin{macrocode}
+ \@yconv{#2}\mfp@scratch
+ \begingroup
+ \ifcase\tl@vpos \advance\mfp@scratch \tb@totalht
+ \advance\mfp@scratch \tlabel@sep % bottom
+ \or \advance\mfp@scratch 0.5\tb@totalht % center
+ \or \advance\mfp@scratch -\tlabel@sep % top
+ \else \advance\mfp@scratch \tb@ht % baseline (default)
+ \fi
+ \advance\mfp@scratch \tlabel@vadj
+ \ifdim \mfp@scratch>\@tlabelstop
+ \@tlabelstop\mfp@scratch
+ \fi
+ \tb@raise\mfp@scratch
+ \endgroup
+% \end{macrocode}
+%
+% Finally we compute the lowermost extent, and save it in \cs{@tlabelsbot}.
+% \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
+ \advance\mfp@scratch -\tlabel@sep % top
+ \else \advance\mfp@scratch -\tb@dp % baseline (default)
+ \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}}%
+}% End \tex@@tlabel
+% \end{macrocode}
+%
+% The argument of \cs{mfp@labels} is the ostensible argument of
+% \cs{tlabels}. Looping is accomplished by defining \cs{extra@endtlabel}
+% to repeat \cs{mfp@dolabel}.
+%
+% If \cs{mfp@dolabel} 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, places the label, and repeats the loop.
+% \begin{macrocode}
+\newdef\mfp@labels#1{\let\extra@endtlabel\mfp@dolabel
+ \mfp@dolabel#1\mfp@end}%
+\newdef\mfp@dolabel{\mfp@ifend\endgroup\tlabel}%
+% \end{macrocode}
+%
+% \cs{mfp@labelpath} stores 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{mfp@tlpath}. The
+% \cs{mfp@figmacbase} must be outside the group so the switches it sets
+% will survive for later commands to detect.
+% \begin{macrocode}
+\newdef\mfp@labelpath#1#2{\mfp@figmacbase
+ \begingroup % ended in \tlabelpath@
+ \def\mfp@name{#1}\def\mfp@param{#2}%
+ \mfp@ifstar\mfp@tlpath\mfp@switchtrue\mfp@switchfalse}%
+% \end{macrocode}
+%
+% Process the first optional argument, which has value of \cs{mfp@param}
+% as default. The second one is a justification with a default 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\mfp@tlpath#1{#1\mfp@defaultopt\mfp@@tlpath\mfp@param}%
+\newdef\mfp@@tlpath#1{\edef\mfp@param{#1}%
+ \mfp@defaultopt\mfp@tlpath@{\tlpath@v\tlpath@h\tlpath@r}}%
+\newdef\mfp@tlpath@#1{\mfp@resetwhitespace\mp@mksharpother
+ \tlabeljustify{#1}\@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{tl@points} is plural (even
+% though only one point is supported) because the internal command that
+% places the label expects this macro.
+% \begin{macrocode}
+\newdef\@tlabelpath(#1,#2){\@@tlabelpath{(#1,#2)}}%
+\newdef\@@tlabelpath#1#2{%
+ \def\tl@points{#1}\mfp@toks{#2}\tlabelpath@}%
+% \end{macrocode}
+%
+% By this point, all the elements we need are gathered. For the purposes
+% of the label we have \cs{mfp@toks} holding the label code,
+% \cs{tl@points} holding the location, and \cs{tlabeljustify} encoding
+% the adjustments. For the path, we have the type in \cs{mfp@name}, and the
+% one optional parameter parameter in \cs{mfp@param}.
+%
+% Under \opt{mplabels} we expect \MP{} to measure the text. Otherwise we
+% measure the text in \TeX{} and feed the bounding box corners to \MF{}
+% for making the path. If \cs{ifmfp@switch} is false we place the text by
+% calling \cs{mfp@thelabel}. All the data needed by \cs{mfp@thelabel} have
+% already been stored in macros by previous commands in the chain. Then we
+% complete the command by ending the group that \cs{mfp@labelpath}
+% started.
+% \begin{macrocode}
+\newdef\tlabelpath@{\@ifmplabels{}{\measure@textbox{\the\mfp@toks}}%
+ \mfp@setMPpos
+ \mfcmd{text\mfp@name x (\mfp@MPpos)\@nl
+ (\@ifmplabels{origin, \mfp@btex{\the\mfp@toks}}{\tb@ll, \tb@ur}, %
+ \mfp@param) (\tl@points)}%
+ \ifmfp@switch\else \mfp@thelabel\fi \endgroup}%
+% \end{macrocode}
+%
+% Here we define the command that measures the text. It is almost a clone
+% of a similar code sequence in \cs{tex@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}%
+ \mfp@scratch-\tb@dp
+ \edef\tb@ll{(0, \the\mfp@scratch)}%
+ \edef\tb@ur{(\the\tb@wd, \the\tb@ht)}}%
+% \end{macrocode}
+%
+% The argument of \cs{mfp@axislabels} is the axis letter.
+%
+% We start by determining the default justification. which is different
+% for each axis (for example, for the left axis it is \oarg{cr} but for
+% the bottom 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 this
+% position 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\mfp@axislabels#1{%
+ \begingroup % ended in \mfp@(@)doaxislabel
+ \mfp@resetwhitespace
+ \tl@vpos1 \tl@hpos0
+ \let\mfp@xcoord\@firstofone \let\mfp@ycoord\@firstofone
+ \mfp@getaxis#1\relax\mfp@end\axislabels
+ \ifcase\mfp@axisnum\relax
+ \tl@vpos2 \def\mfp@ycoord{0}\or
+ \tl@hpos1 \def\mfp@xcoord{0}\or
+ \tl@hpos1\edef\mfp@xcoord{\mfp@lshift}%
+ \mfpaddto\mfp@xcoord\xmin\or
+ \tl@vpos2\edef\mfp@ycoord{\mfp@bshift}%
+ \mfpaddto\mfp@ycoord\ymin\or
+ \tl@hpos-1 \edef\mfp@xcoord{-\mfp@rshift}%
+ \mfpaddto\mfp@xcoord\xmax\or
+ \tl@vpos0 \edef\mfp@ycoord{-\mfp@tshift}%
+ \mfpaddto\mfp@ycoord\ymax
+ \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 the
+% parameter, and then call \cs{mfp@@axislabels}, feeding it an empty
+% argument as the default optional argument. We also give \texttt\# a safe
+% catcode for writing to a \file{.mp} file.
+% \begin{macrocode}
+ \ifx\@firstofone\mfp@xcoord
+ \edef\mfp@ycoord##1{\mfp@ycoord}%
+ \else
+ \edef\mfp@xcoord##1{\mfp@xcoord}%
+ \fi \mp@mksharpother\mfp@nullopt\mfp@@axislabels}%
+% \end{macrocode}
+%
+% \cs{mfp@@axislabels} processes the contents of the optional parameter
+% and calls \cs{mfp@doaxislabel} on the list of labels.
+% \begin{macrocode}
+\newdef\mfp@@axislabels#1#2{%
+ \tlabeljustify{#1}\mfp@doaxislabel#2,\mfp@end}%
+% \end{macrocode}
+%
+% \cs{mfp@doaxislabel} checks for the end delimiter or a comma (the latter
+% is an error). In the first case it ends all label processing, in the
+% second it repeats itself, otherwise it continues with
+% \cs{mfp@@doaxislabel}.
+%
+% The argument of \cs{mfp@@doaxislabel} should be the label. This command
+% stores the label in \cs{mfp@toks}, then again checks for the delimiter
+% or an comma (both are errors). In the first case it ends the process; in
+% the second it goes back to \cs{mfp@doaxislabel} for another try. In both
+% cases the label is discarded as we don't know where to put it. If
+% neither the delimiter nor a comma occurs, \cs{mfp@mkaxislabel} is run.
+%
+% The argument of \cs{mfp@mkaxislabel} (everything to the next comma) is the
+% location. The command \cs{mfp@mkaxislabel} does nothing if the location
+% parameter is empty, otherwise it stores the location as a pair and calls
+% \cs{mfp@thelabel} to place the label. Finally, it repeats
+% \cs{mfp@doaxislabel} for the next iteration.
+% \begin{macrocode}
+\newdef\mfp@doaxislabel{%
+ \mfp@ifendorcomma\endgroup\mfp@doaxislabel\mfp@@doaxislabel}%
+\newdef\mfp@@doaxislabel#1{\mfp@toks{#1}%
+ \mfp@ifendorcomma\endgroup\mfp@doaxislabel\mfp@mkaxislabel}%
+\newdef\mfp@mkaxislabel#1,{%
+ \@ifmtarg{#1}{}%
+ {\edef\tl@points{(\mfp@xcoord{#1},\mfp@ycoord{#1})}\mfp@thelabel}%
+ \mfp@doaxislabel}%
+% \end{macrocode}
+%
+% \cs{mfp@caption} 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\mfp@caption#1{\begingroup\mfp@resetwhitespace
+ \mfp@@caption#1\mfp@end}%
+\long\def\mfp@@caption#1,#2\mfp@end#3{\endgroup
+ \def\mfp@docaption{%
+ \setbox\@textbox
+ \hbox{\def\\{\hskip\@M\p@\let\\\relax}\mfp@restorepar
+ \mfp@safe@activesfalse\@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. \cs{mfp@capsettings} implements the \opt{centeredcaptions}
+% and \opt{raggedcaptions} options.
+% \begin{macrocode}
+ \mfp@scratch\wd\@wholegraph
+ \ifdim\tb@wd>#1\mfp@scratch
+ \setbox\@textbox
+ \hbox{%
+ \vbox{%
+ \hsize#2\mfp@scratch \mfp@restorepar
+ \leftskip0pt \rightskip0pt\relax
+ \mfp@capsettings
+ \mfp@safe@activesfalse
+ \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}
+ \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 \mfp@docaption.
+}% End \mfp@@caption.
+% \end{macrocode}
+%
+% The following is used in \cs{endmfpic}. The first argument of
+% \cs{mfp@adjustdim} is a border dimension of the box containing all the
+% labels, the second is a comparison between that and the corresponding
+% dimension of the graph box, which is the third argument. The last is the
+% macro holding the adjustments needed when \opt{truebbox} is used. The
+% first and last line compensate for the fact that the bbox need not start
+% at $(0,0)$. The second line checks if the label box extends past the
+% graph's edge and adjusts the graph's dimension is it does.
+% \begin{macrocode}
+\def\mfp@adjustdim#1#2#3#4{%
+ \mfp@scratch#1\relax \advance\mfp@scratch-#4 bp
+ \ifdim\mfp@scratch#2#3\relax #3\mfp@scratch \fi
+ #1\mfp@scratch}%
+% \end{macrocode}
+%
+%
+%
+% \section{Placing the picture: \cs{endmfpic}}\label{endmfpic}
+%
+% \DescribeMacro{\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.
+%
+% Under \opt{metapost}, write a right brace to match the left 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{\every@endmfpic
+ \mfsrc{%
+ \mfp@ifmpost{\@nl verbatimtex \relax\MFPendgroup\space etex;}{}\@nl
+ endmfpic; \mfp@p\space(\number\mfp@count) \mfp@lineno.\@nl
+ \mfp@p\mfp@d\mfp@d\mfp@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}
+ \ifmfp@noship \else
+% \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 \@graphright{%
+ \kern2pt \mfpdraftfont\#\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}. With it, the box will be its natural height. But
+% in either case, the value will actually be increased by up to
+% \texttt{2bp} because of rounding, so the bounding box 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 filename for \cs{@setmfpicgraphic}.
+% \begin{macrocode}
+ \edef\@graphfilename{%
+ \setfilename\mfp@filename{\number\mfp@count}}%
+ \mfp@ifmpost
+ {\IfFileExists{\@graphfilename}{}%
+ {\Mfpic@msg{No graph file: \@graphfilename\space.}%
+ \let\@setmfpicgraphic\nofile@setmfpgraphic}%
+% \end{macrocode}
+%
+% We put the graphic in an \cs{hbox} of the required width and close off
+% the boxes.
+% \begin{macrocode}
+ \hbox}%
+ {\hbox to \@graphright}%
+ {\@xp\@setmfpicgraphic\@xp{\@graphfilename}\hss}%
+ \kern0pt
+ }% End vbox
+ \fi
+ }%% End \setbox\@wholegraph \vbox
+% \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}{}%
+ \ifmfpicdebug
+ \wlog{Mfpic debug: Dimensions of wholegraph before labels %
+ are added, and before truebbox adjustments:}%
+ \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 boxes \cs{@alltlabels} and \cs{@backtext} onto 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 those
+% boxes so their 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}.
+% This doesn't indicate whether it is \cs{@alltlabels} or \cs{@backtext}
+% (or both) that is nonempty, so one of the box resets may be redundant.
+% \begin{macrocode}
+ \ifmfpicdebug
+ \wlog{Mfpic debug: Dimensions of alltlabels, before %
+ truebbox adjustments:}%
+ \mfp@scratch\mfpicllx bp\relax
+ \wlog{Mfpic: mfpicllx = \the\mfp@scratch}%
+ \mfp@scratch\mfpiclly bp\relax
+ \wlog{Mfpic: mfpiclly = \the\mfp@scratch}%
+ \wlog{Mfpic: tlabelsleft = \the\@tlabelsleft}%
+ \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}%
+ \setbox\@backtext \vtop to 0pt{%
+ \kern \mfpiclly bp
+ \moveleft \mfpicllx bp \box\@backtext \vss}%
+% \end{macrocode}
+% Then we adjust \cs{@tlabelsleft}, etc. for the boundingbox offset.
+% The graph dimensions are also adjusted if the tlabel dimensions extend
+% past the edges.
+% \begin{macrocode}
+ \mfp@adjustdim\@tlabelsleft <\@graphleft \mfpicllx
+ \mfp@adjustdim\@tlabelstop >\@graphtop \mfpiclly
+ \mfp@adjustdim\@tlabelsbot <\@graphbot \mfpiclly
+ \ifmfpicdraft\else
+ \setbox\@wholegraph
+ \vtop{\offinterlineskip
+ \box\@backtext\kern-\ht\@wholegraph
+ \unvbox\@wholegraph\box\@alltlabels}%
+ \fi
+ \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 debug: Dimensions of alltlabels after %
+ truebbox adjustments:}%
+ \wlog{Mfpic: tlabelsleft = \the\@tlabelsleft}%
+ \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 debug: Dimensions of wholegraph after %
+ labels are added:}%
+ \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
+ \mfp@docaption
+ \ifmfpicdebug
+ \wlog{Mfpic debug: Values after tcaption added:}%
+ \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
+ \global\mfpicheight\ht\@wholegraph
+ \global\mfpicwidth\wd\@wholegraph
+% \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 and perhaps some tlabels.
+% \begin{macrocode}
+ \ifmfpicdraft
+ \setbox\@wholegraph
+ \hbox{\@mfpframed{-\mfpframethickness}{\box\@wholegraph}}%
+ \fi
+% \end{macrocode}
+% Now we save the graph globally, for placement after \cs{endgroup}. This
+% is so that tokens placed by \cs{everypar} will be typeset in the current
+% font (instead of \cs{nullfont}). Then we advance the figure count and
+% end the group started by the \cs{mfpic} command.
+% \begin{macrocode}
+ \global\setbox\@wholegraph\box\@wholegraph
+ \global \advance\mfp@count1
+ \fi % \ifmfp@noship
+ \endgroup % Begun near start of \@mfpic
+% \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 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}. Note: if \opt{noship} is in
+% force, it remains defined, so the next picture will be stored.
+% \begin{macrocode}
+ \ifmfp@noship \else
+ \mfp@ifdefined\s@vemfpic
+ {\global\setbox\s@vemfpic\box\@wholegraph}%
+ {\leavevmode\box\@wholegraph}%
+ \global\let\s@vemfpic\UndEfInEd
+ \fi
+% \end{macrocode}
+% Then we restore the values of extra font dimensions that were saved.
+% Just in case, we unset the switch \cs{in@mfpicenv} and then arrange for
+% spaces to be ignored in case this is a \LaTeX{} environment. (I think we
+% shouldn't ignore spaces, but I was overruled. The argument was that
+% \cs{end}\marg{mfpic} should behave like \cs{endmfpic}. I don't buy it,
+% but I will keep things the way they were since version 0.4.)
+% \begin{macrocode}
+ \restore@mfpicdimens
+ \mfp@checklatexenv{mfpic}{\@ignoretrue}{}%
+ \global\let\in@mfpicenv\iffalse
+ \ignorespaces
+}% endmfpic
+% \end{macrocode}
+%
+% The following is a little utility to run at \cs{foo} or \cs{endfoo} to
+% see if was initiated as a \LaTeX{} environment or as a plain command.
+% The first argument is the environment name, the second is what to do
+% if that is the current environment, and the third is what to do
+% otherwise. In the two cases we now use it, the third argument is
+% empty.
+% \begin{macrocode}
+\ifmfp@latex
+ \newdef\mfp@checklatexenv#1#2#3{%
+ \def\mfp@tempa{#1}\ifx\mfp@tempa\@currenvir #2\else #3\fi}%
+\else
+ \newdef\mfp@checklatexenv#1#2#3{#3}%
+\fi
+% \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}\cs{mypic}, then saying \cs{savepic}\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}
+\ifmfp@latex
+ \newlet\newsavepic\newsavebox
+\else
+ \newdef\newsavepic#1{%
+ \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.}}%
+ {\@nameuse{newbox}#1}}%
+\fi
+\newlet\newpic\newsavepic
+% \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 some 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}
+% \cs{mfpframed} takes an optional argument (the separation) and a
+% mandatory argument, the contents.
+% \DescribeMacro{\mfpframe}
+% \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{\mfp@defaultopt\@mfpframed\mfpframesep}%
+\newdef\mfpframe{\mfp@defaultopt\@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{}{\let\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 appending it to a token register and setting a
+% flag for that command to test.
+%
+% We now want \texttt\% signs to be written to the output, but also
+% want to allow the construct
+% \begin{verbatim}
+% \mfpverbtex% Comment
+% {<tex code>}\end{verbatim}
+% to function as users might expect. We therefore perform a
+% \cs{futurelet} (which should set \cs{mfp@next} equal to the opening
+% brace) but we do it solely to get \TeX's scanning mechanism past the
+% comment before we change the category of \texttt\%.
+% \begin{macrocode}
+\def\mfpverbtex{\futurelet\mfp@next\@mfpverbtex}%
+% \end{macrocode}
+%
+% We start a group, change \texttt\% and \texttt\# to `other' so they
+% can be written normally, then continue after loading the code into the
+% token register \cs{mfp@toks}.
+% \begin{macrocode}
+\def\@mfpverbtex{%
+ \begingroup
+ \@makeother\#\@makeother\%\mfp@keeplines
+ \afterassignment\mfp@writetex\global\mfp@toks}%
+% \end{macrocode}
+% We end the group and then either write it to the
+% output, between the commands \gbc{verbatimtex} and \cs{etex},
+% or append it to \cs{mfp@verbtex} and set the switch to tell
+% \cs{opengraphsfile} that there is material to write when the output file
+% is opened.
+% \begin{macrocode}
+\newif\ifmfp@verbtex
+\def\mfp@writetex{%
+ \mfp@ifopengraphsfile
+ {\mfp@ifmpost
+ {\mfcmd{verbatimtex\@nl\the\mfp@toks\@nl\mfp@p\@nl etex}}%
+ {\mfp@noMP@error\mfpverbtex}%
+ \global\mfp@verbtexfalse\global\mfp@verbtex{}}%
+ {\edef\mfp@tempa{\the\mfp@verbtex\the\mfp@toks}%
+ \global\mfp@verbtex\@xp{\mfp@tempa}%
+ \global\mfp@verbtextrue}%
+ \endgroup
+}%
+% \end{macrocode}
+%
+%
+%
+% \section{Finale}\label{finale}
+%
+% Set the default starting graphic number. We used to start at 0 and
+% increment it at the start of each picture, but now we start at 1 and
+% increment it at the end of each picture.
+% \begin{macrocode}
+\mfpicnumber{1}%
+% \end{macrocode}
+%
+% Set the font for missing or draft mode figures (for the file name or
+% figure number). This will already have been defined if \file{mfpic.sty}
+% was used, so here we can probably assume \LaTeX{} wasn't used, and
+% \cs{tt} ought to be available.
+% \begin{macrocode}
+\mfp@ifdefined\mfpdraftfont{}{\newdef\mfpdraftfont{\tt}}%
+% \end{macrocode}
+%
+% Restore the meaning of \cs{+}, and execute the command that restores all
+% the saved category codes and \cs{newlinechar}. Input user defaults in
+% the file \file{mfpic.usr}.
+% \begin{macrocode}
+\mfp@DBlog{Punctuation, etc., will revert to old catcodes now.}%
+\let\+\mfpsaveplus
+\mfp@restoreALL%
+\InputIfFileExists{mfpic.usr}{}{}%
+%</tex>
+% \end{macrocode}
+%
+%\clearpage
+%\Finale
+%\endinput