% \iffalse % feynmf.dtx - Feynman diagrams with METAFONT for LaTeX(2e)
% Copyright (C) 1989, 1990, 1992-1996 by Thorsten.Ohl@Physik.TH-Darmstadt.de
% $Id: feynmf.dtx,v 1.30 1996/12/02 09:20:36 ohl Exp $
%
% Feynmf is free software; you can redistribute it and/or modify it
% under the terms of the GNU General Public License as published by 
% the Free Software Foundation; either version 2, or (at your option)
% any later version.
%
% Feynmf is distributed in the hope that it will be useful, but
% WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%
% \fi
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%% \CheckSum{924}
%% \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         \~}
%%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \MakeShortVerb{\|}
%
% \title{%
%   \FMF: \\
%   Drawing Feynman Diagrams \\
%   with \LaTeX{} and \MF\thanks{%
%      This is \texttt{\filename}, version \fileversion,
%      revision \filerevision, date \filedate.}}
%
% \author{%
%   Thorsten Ohl\thanks{e-mail:
%     {\tt Thorsten.Ohl@Physik.TH-Darmstadt.de}}\\
%   \hfil \\
%   Technische Hochschule Darmstadt \\
%   Schlo\ss gartenstr. 9 \\
%   D-64289 Darmstadt \\
%   Germany}
%
% \maketitle
% \begin{abstract}
%   \FMF{} is a \LaTeX{} package for easy drawing of professional
%   quality Feynman diagrams with \MF{} (or \MP).  \FMF{} lays out most
%   diagrams satisfactorily from the structure of the graph without
%   any need for manual intervention.  Nevertheless all the power of
%   \MF{} (or \MP) is available for obscure cases.
% \end{abstract}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section*{Copying}
%
% \FMF{} is free software; you can redistribute it and/or modify it
% under the terms of the GNU General Public License as published by 
% the Free Software Foundation; either version 2, or (at your option)
% any later version.
%
% \FMF{} is distributed in the hope that it will be useful, but
% \emph{without any warranty}; without even the implied warranty of
% \emph{merchantability} or \emph{fitness for a particular purpose}.
% See the GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \newpage
% \tableofcontents
% \newpage
% \unitlength=1mm
% \def\topfraction{0.9}
% \def\bottomfraction{0.9}
% \def\textfraction{0.1}
% \begin{fmffile}{fmfsamp1}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Introduction}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Purpose and scope}
%
% In recent years, \TeX\footnote{\TeX{} is a trademark of the American
%   Mathematical Society.}~\cite{TeX}
% and \LaTeX\footnote{\LaTeX{} might be a trademark of Addison Wesley
%   Publishing Company.}~\cite{LaTeX}
% have revolutionized the way
% we share information in theoretical physics (and other areas).  Not
% only does \TeX{} provide typographical capabilities, which transcend
% those of commercial ``wordprocessors'' substantially, \TeX{} documents
% are also completely portable.  Since implementations are available
% on essentially all computers in use in the community, documents can
% be shared without the usual restrictions of proprietary data
% formats.  This has enabled us to collaborate on papers with
% colleagues on the other side of the globe, to replace the mailing of
% hard copy preprints by electronic transmission and to submit these
% papers electronically to the publisher.
%
% This portability comes with a price, though.  \TeX{} (and \LaTeX)
% do not address the issue of graphical information, apart from the
% rudimentary (but very useful) capabilities of the \LaTeX{} |picture|
% environment and similar
% packages~\cite{LaTeX-Companion}.  As an de facto standard for the
% inclusion of more complex graphics has emerged the inclusion of
% PostScript\footnote{PostScript is a trademark of Adobe Systems
%   Inc.} 
% files.  The complete document can then
% be printed on any PostScript device.
%
% Still there are areas, where complementary approaches seem worth
% pursuing.  In particular this is the case, if the graphical
% information is highly formalized, like the case at hand.  Feynman
% diagrams are specified by their topology and the type of particles
% connecting the vertices.  Thus a given diagram can be reproduced
% from a very concise specification, if the software is able to choose
% a reasonable layout (semi-)automatically.
%
% \MF\footnote{\MF{} is a trademark of Addison Wesley Publishing
%   Company.}~\cite{MF}
% and \MP\footnote{John Hobby's \MP{} is a modified version of \MF{}
%   which generates (encapsulated) PostScript output.  \MP{} can be
%   build trivially on top of the \texttt{web2c} version of \TeX{} and
%   \MF{} for UNIX.  Ports to other systems should be
%   simple.}~\cite{MetaPost}
% appear to be the perfect tool for such a purpose, since
% \begin{enumerate}
%   \item{} \MF{} is part of any (reasonable) \TeX{} installation, thus
%     available to all potential users,
%   \item{} both have very powerful graphics primitivs, which allow high
%     quality output, and
%   \item{} both have builtin linear algebra, which allows us to choose a
%     layout automatically.
% \end{enumerate}
% Still, providing at least the basic interface in \LaTeX{} macros
% seems appropriate for boosting the acceptance among the less
% technically oriented parts of the audience. Thus
% \FMF\footnote{\FMF{} is not anybody's trademark.}~\cite{CPC,CNL}
% was conceived.
%
% \FMF{} is unique among packages for drawing Feynman diagrams in
% \emph{combining} the following features:
% \begin{itemize}
%   \item Simplicity and conciseness for common diagrams.  E.g.~the
%     scattering diagram in figure~\ref{fig:simple} can be specified
%     \emph{completely} in five lines of \LaTeX:
%     \begin{verbatim}
%       \begin{fmfgraph*}(40,30) \fmfpen{thick}
%         \fmfleft{i1,i2} \fmfright{o1,o2}
%         \fmf{fermion}{i1,v1,o1} \fmf{fermion}{i2,v2,o2}
%         \fmf{photon,label=$q$}{v1,v2} \fmfdot{v1,v2}
%       \end{fmfgraph*}
%     \end{verbatim}
%     \begin{figure}[t]
%       \begin{center}
%       \begin{fmfgraph*}(40,30) \fmfpen{thick}
%         \fmfleft{i1,i2} \fmfright{o1,o2}      
%         \fmf{fermion}{i1,v1,o1} \fmf{fermion}{i2,v2,o2}
%         \fmf{photon,label=$q$}{v1,v2} \fmfdot{v1,v2}
%       \end{fmfgraph*}
%       \end{center}
%       \caption{\label{fig:simple}Simple scattering diagram.}
%     \end{figure}
%   \item Expressiveness for complicated diagrams (see the examples
%     below).
%   \item Extensibility (e.g.~see section~\ref{sec:extensions}).
%   \item Arbitrary \TeX-labels.  This point is more important than it
%     may seem at first glance because most graphical layout systems
%     lack the power to produce complicated mathematical expressions.
%     Having matching fonts in text, equations and diagrams is also an
%     important esthetical feature.   
% \end{itemize}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Relation to similar packages}
%
% Before we start, a couple of words about some complementary packages
% on the market are in order:
% \begin{itemize}
%   \item Michael Levine's |feynman| package~\cite{levine} is
%     implemented on top of the standard \LaTeX{} |picture|
%     environment~\cite{LaTeX}.  This makes it completely portable (no
%     need for a correct \MF{} installation), but it requires manual
%     layout and the graphics output is (though very useful) less than
%     perfect.
%   \item Jos Vermaseren's |axodraw| package~\cite{axodraw} uses
%     |\special|s to access PostScript primitives for drawing
%     diagrams.  This approach is inherently not portable (the
%     ubiquity of PostScript printers makes this a minor point,
%     though) but as flexible as the present one.  Nevertheless,
%     it still requires manual layout for all diagrams.
%   \item Last, but not least, I have to mention  Thomas Leathrum's
%     |mfpic|~\cite{mfpic}, which provided the inspiration for moving
%     \FMF's user interface from \MF{} to \TeX.  It might not have
%     been unreasonable to design and implement \FMF{} as a package on
%     top of |mfpic|, but closer inspection shows that \FMF{} and
%     |mfpic| are fairly orthogonal.  |mfpic| is most useful for
%     handling simple graphical building blocks in formally
%     unconstrained contexts. \FMF{} on the other hand excels in the
%     formal context of Feynman diagrams (or any other labeled graphs
%     for that matter), which can be drawn automatically from a
%     \emph{specification}.
% \end{itemize}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Historical note}
%
% Parts of this code have a rather long history\footnote{%
%   Which is a partial explanation, if not excuse, for its slightly
%   incoherent structure.}.
% Some of the drawing primitives started in 1989 as
% |feynman.mf|, a library of \MF{} macros for drawing Feynman
% diagrams in my thesis.  The layout had to be specified completely
% by hand, which required a long edit-process-preview cycle and made
% |feynman.mf| awkward to use.
% Nevertheless, it suited my and other's neeeds and survived for five
% years without major modifications.  Early in
% 1994, I became aware of Thomas Leathrum's |mfpic|~\cite{mfpic}.
% This inspired me to shift the user interface from \MF{} to
% \LaTeX, because this allows a smoother blending of the \LaTeX{}
% |picture| environment with \FMF{} for the purpose of labeling the
% graphs.  While doing this and after
% having been taught by Tim Stelzer's and Bill Long's
% \texttt{MADGRAPH}~\cite{madgraph} that simply minimizing the length
% of the graph gives much better results than I had anticipated, I
% added the graph manipulation and layout code.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Architecture}
%
% Even though there has never been a proper design phase in the
% development of \FMF, a certain structure has emerged, which is
% depicted in figure~\ref{fig:arch}. A user who is aware of this
% architecture should be able to use \FMF{} more effectively.
%
% \begin{figure}[t]
%   \hfuzz=3cm
%   \begin{center}
%     \leavevmode
%     \includegraphics{manpics.3}
%   \end{center}
%   \caption{\label{fig:arch}%
%     Architecture of \FMF{}: the two modes of \FMF{} (immediate mode
%     and vertex mode) both interact with \LaTeX{} and \MF{} (or \MP,
%     respectively), but operate on different data types.}
% \end{figure}
%
% The most crucial aspect of the architecture is the existence of two
% distinct modes with different fundamental datatypes:
% \begin{itemize}
%   \item \emph{vertex mode,} which deals with graphs as structures
%     consisting of vertices and arcs and (almost) never deals with
%     their physical locations.
%   \item \emph{immediate mode,} which deals with \MF{} |path|s and
%     |pair|s (i.e.~coordinates) and 
%     allows complete control over the physical locations.
% \end{itemize}
% It is of course possible to mix these modes in advanced
% applications.  Commands are provided to translate vertices and arcs
% to |pair|s and |path|s and vice versa.
%
% Novice users with little experience in \MF{} programming should
% start with vertex mode to get their job done.  Later, immediate mode
% can be used to create more and more complex diagrams.  It is
% possible to create most diagrams that can actually be calculated in
% vertex mode.  Immediate mode is most useful for extending line
% \FMF{} and for drawing diagrams with fancy decorations.
%
% A word on portability: \FMF{} is implemented as a \LaTeX{} package.
% But it should be straightforward to adapt it to other \TeX{} macro
% packages because \LaTeX{} macros have been used for convenience only
% and can easily be replaced or provided in a compatibility package.
% The \LaTeX{} specific \emph{environment} construct can also easily
% be replaced by the equivalent construct in another macro package.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Conclusion}
%
% It goes without saying that \FMF{} is not perfect.  There might be
% cases where using a graphical drawing tool with a mouse can give
% more pleasing results in less time.  But in most cases, \FMF{}
% will give satisfactory results without any fine tuning.  These will
% be reproducible and independent from the computer it is running on.
%
% Early user reponses have been very encouraging.  There seems to be a
% relatively steep
% learning curve for those \LaTeX{} users that have to find out how to
% run \MF{} on their systems.  But once this purely technical obstacle
% has been
% surmounted, users have been enthusiatic as well about the quality of
% the generated graphs as about the ease of use of \FMF.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \newpage
% \section{Usage}
%
% In addition to this manual, there exists also a concise description
% of \FMF{} in a journal article~\cite{CPC}, as well as a three part
% tutorial~\cite{CNL}. 
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{\LaTeX{} package and environments}
% \label{sec:environments}
%
% Instructing \LaTeX{} to use \FMF{} is as simple as\footnote{As
%   given, this applies to \LaTeX.  But the installation file
%   \texttt{feynmf209.ins} allows to generate special versions 
%   \texttt{feynmf209.sty} and \texttt{feynmp209.sty} which are
%   compatible with the obsolete \LaTeX{} version 2.09.  These files
%   are to be used as documentstyle options
%   \begin{quote}
%     \texttt{\bslash documentstyle[...,feynmf209,...]\{...\}}
%   \end{quote}
%   or
%   \begin{quote}
%     \texttt{\bslash documentstyle[...,feynmp209,...]\{...\}}
%   \end{quote}
%   If you cannot use |epsf.sty| for including PostScript files, you
%   can either hack |feynmp209.sty| or upgrade to \LaTeX2e.
%   Please keep in mind that \FMF{} has been developed for \LaTeXe{}
%   and the \LaTeX~2.09 compatibility version will always be a
%   retrofitted hack.  I will accept bug reports for the 2.09 version,
%   but I urge everybody to move to \LaTeX2e, which is the one and
%   only supported \LaTeX{} right now.}
% \begin{quote}
%   |\usepackage{feynmf}|
% \end{quote}
% If you have \MP, then you can use it alternatively by placing
% \begin{quote}
%   |\usepackage{feynmp}|
% \end{quote}
% in your \LaTeX{} source.\footnote{%
%   \FMF{} understands an option \texttt{pre-1.03}, that is
%   of interest for veteran users:
%   \begin{quote}
%     \texttt{\bslash usepackage[pre-1.03]\{feynmf\}}
%   \end{quote}
%   or
%   \begin{quote}
%     \texttt{\bslash usepackage[pre-1.03]\{feynmp\}}
%   \end{quote}
%   The purpose of this option is to enable processing of old input
%   files (pre v1.02) that use \texttt{\bslash noexpand} in labels.
%   Since the method for processing these files can clash (in rare
%   cases) with \LaTeXe's font loading procedure, it has been disabled
%   by default.}
%
% \FMF{} has to switch interactions mode and switches to
% |\errorstopmode|, because it is impossible in \TeX{} to switch
% back. If a different default is required (for automated preprint
% processing, in particular), it can be specified as a package option:
% \begin{quote}
%   |\usepackage[errorstop]{feynmf}|\\
%   |\usepackage[scroll]{feynmf}|\\
%   |\usepackage[batch]{feynmf}|\\
%   |\usepackage[nonstop]{feynmf}|
% \end{quote}
%
% \DescribeEnv{fmffile}
% All descriptions that should go into one \MF{} file are placed
% inside a |fmffile| environment which takes the name of the \MF{}
% file as an argument:
% \begin{quote}
% \begin{flushleft}
%   |\begin{fmffile}{|\meta{\MF-file}|}|\\
%   \qquad\ldots\\
%   |\end{fmffile}|
% \end{flushleft}
% \end{quote}
% Upto 255 graphs can be placed into one \MF{} file.  Currently
% \FMF{} does \emph{not} check that the 255 graph limit per file
% is not overrun.\footnote{%
%   There is also a very primitive, but (unfortunately) popular
%   operating system, which restricts filenames to eight characters
%   with a three character extension.  On this system, only 99
%   graphs can be placed into one \MF{} file because auxiliary
%   files will not be unambiguous, if more than two digits are used.}
% Note that the filename for the \MF{} file given in the argument of
% the |fmffile| environment \emph{must not} be identical to the
% \LaTeX{} source file name, because the \MF{} |.log| would be
% overwritten and \LaTeX{} can no longer access the information in
% this |.log| file.  It should be obvious that any umber of diagrams
% can be generated by using more than one |fmffile| environment with
% different filenames.
%
% \DescribeEnv{fmfgraph}
% The |fmfgraph| environment contains the description of a single
% Feynman diagram
% which will be placed a the location of the environment.
% Arguments are the width and the height of the diagram, in units of
% |\unitlength|:
% \begin{quote}
% \begin{flushleft}
%   |\begin{fmfgraph}(|\meta{width}|,|\meta{height}|)|\\
%   \qquad\ldots\\
%   |\end{fmfgraph}|
% \end{flushleft}
% \end{quote}
% This environment does \emph{not} support labels, use |fmfgraph*| if
% your diagrams contains labels.
%
% \DescribeEnv{fmfgraph*}
% Same as |fmfgraph|, but enclosed in a |picture| environment of the
% same size and supporting \LaTeX{} labels.
% \begin{quote}
% \begin{flushleft}
%   |\begin{fmfgraph*}(|\meta{width}|,|\meta{height}|)|\\
%   \qquad\ldots\\
%   |\end{fmfgraph*}|
% \end{flushleft}
% \end{quote}
%
% \DescribeMacro{\fmfframe}
% Allows to allocate additional space around a |fmfgraph*|, since
% the labels (or the diagram itself) might overshoot:
% \begin{quote}
%   |\fmfframe(|\meta{left}|,|\meta{top}|)(|\meta{right}|,|\meta{bottom}^^A
%     |){|\meta{box}|}|
% \end{quote}
%  puts an invisible frame of the given dimensions (measured in
%  |\unitlength|) around \meta{box}.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Auxiliary files}
% \label{sec:aux-files}
%
% \FMF{} needs to share information between \MF{} and \LaTeX{}.  For
% this task several auxiliary files are needed.
% The flow of information depicted in figures~\ref{fig:flow}
% and~\ref{fig:flowp} looks much
% more complicated than it is.  The important feature is that there a
% two sets of files which can be used to distribute a document:
% \begin{enumerate}
%   \item{} Iff the recipient has a working \MF{} installation
%     (which shouldn't be a problem, except for some impoverished
%     commercial implementations), the document can be typset from the
%     \LaTeX{} source \emph{alone}, by running \LaTeX{}, \MF{}
%     and \LaTeX{} again (the latter step might have to be repeated to
%     get cross references right).
%   \item{} Another possibility (which doesn't require \MF{} on
%     the recipient's side), is to distribute the \LaTeX{} source, the
%     |tfm| and |gf| files (or |pk| files respectively) along with the
%     label files with extension |t|$n$ (where $n$ as an integer).
%     Distributing the \MF{} |log| files is a possible alternative
%     for the latter, but discouraged, because these are prone to be
%     erased accidentally.
% \end{enumerate}
%
% \begin{figure}[t]
%   \hfuzz=3cm
%   \begin{center}
%     \leavevmode
%     \includegraphics{manpics.1}
%   \end{center}
%   \caption{Interdependency of files in a \FMF{} application.
%      The arrows show which files are updated in the two \LaTeX{}
%      passes, the \MF{} pass and the final dvi translation step.}
%   \label{fig:flow}
% \end{figure}
%
% \begin{figure}[t]
%   \hfuzz=3cm
%   \begin{center}
%     \leavevmode
%     \includegraphics{manpics.2}
%   \end{center}
%   \caption{Interdependency of files in a \FMF{} application using
%      \MP: The arrows show which files are updated in the two \LaTeX{}
%      passes, the \MP{} pass and the final dvi translation step.}
%   \label{fig:flowp}
% \end{figure}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Running \MF}
% \label{sec:run-mf}
%
% Processing your document with \LaTeX{} will generate one or more
% \MF{} files, which you will have to process with \MF.  On
% UNIX\footnote{%
%   UNIX was a trademark of UNIX Systems Laboratory, but is rumored to
%   have been donored to X/Open.}
% systems, \MF{} is invoked as
% \manindex{running \MF}
% \begin{quote}
%   |mf '\mode:=|\meta{\MF-mode}|; input |\meta{\MF-file}|'|
% \end{quote}
% from the shell.  Here \meta{\MF-file} is to be replaced by the name
% of the input file (which is determined by the argument to the
% |fmffile| environment, see section~\ref{sec:environments}) and
% \meta{\MF-mode} is the proper \MF-mode for your particular printer.
% Please consult your local guide or local wizards about how to run
% \MF{} on other systems.
%
% Note that \meta{\MF-mode} \emph{must} be specified, otherwise \MF{}
% will fail or the resulting font will not be usable.\footnote{%
%   See section~\ref{sec:value-to-large} for the typical error message
%   and for additional information on printer modes.}
% You can look up the correct \MF{} mode in the file |modes.mf| that
% comes with the \MF{} distribution.  Among the more common laser
% printers are |laserjet| for HP Laserjets at 300dpi, |ljfour| for HP
% Laserjets at 600dpi, |nexthi| for NeXT laser printers at 400dpi,
% etc.
%
% A non-trivial part can be instructing \TeX{} and your favorite
% |dvi|-driver how to find the generated |tfm| and |gf| (resp.~|pk|)
% files.  This is highly system dependent and can be trivial (as in
% the standard UNIX \TeX{} installations, where no further action is
% required) or almost impossible without system priviledges (as under
% MVS).  Please consult your local guide or wizards on this point. 
% See also section~\ref{sec:out-of-date} for common problems with
% |dvi| drivers.
%
% Some recent \TeX{} implementations (e.g.~|web2c| with |kpathsea|
% version 2.6 or later) are able to generate |tfm| files on the fly.
% Using such implementations, running \LaTeX{} twice should suffice
% and \MF{} will be invoked automagically in the background.  Note
% however, that the automagically invoked tools might also install the
% ``fonts'' corresponding to the Feynman diagrams in a system
% directory, where they don't belong.  Adding the following lines to
% the |maketex.site| script will prevent this mishap in the
% te\TeX{} distribution for UNIX (which is derived from |web2c|):
% \begin{verbatim}
%   if [ -r $KPSE_DOT/$NAME.mf ]; then
%     MT_PKDESTDIR=$KPSE_DOT
%     MT_TFMDESTDIR=$KPSE_DOT
%     MT_NAMEPART=
%   fi
% \end{verbatim}
% The automagic tools will also \emph{not} notice when a diagram has
% changed.  These problems suggest that it is a generally a good idea
% to invoke \MF{} explicitely, instead of relying on the automagic
% tools.
%
% Running \MP{} is usually trivial, because not printer specific mode
% is needed:
% \manindex{running \MP}
% \begin{quote}
%   |mp |\meta{\MP-file}||
% \end{quote}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{The \texttt{feynmf} perl script}
% UNIX users will be able to take advantage of the \texttt{feynmf}
% perl script, that automates the invocation of \LaTeX{} and \MP.
% In particular it tries to guess the correct \MF-mode and
% magnification.  The latter is often different from 1 in slide
% classes.  Here is the man page of \texttt{feynmf}:
%
% ^^A LaTeX document produced by pod2latex from "feynmf.pl.pod".
% \subsubsection*{NAME}
% {\bf feynmf} --- Process {\bf LaTeX} files using {\bf FeynMF}
% 
% \subsubsection*{SYNOPSIS}
% {\bf feynmf} {\tt [}{\bf -hvqncfT}{\tt ]}
%   {\tt [}{\bf -t} {\em tfm\/} {\tt [}{\bf -t} {\em tfm\/} ...{\tt ]}{\tt ]}
%   {\tt [}{\bf -m} {\em mode\/}{\tt ]}
%   {\em file\/} {\tt [}{\em file\/} ...{\tt ]}
% 
% {\bf feynmf} {\tt [}{\bf {\tt --}help}{\tt ]}
%   {\tt [}{\bf {\tt --}version}{\tt ]} {\tt [}{\bf {\tt --}quiet}{\tt ]}
%   {\tt [}{\bf {\tt --}noexec}{\tt ]} {\tt [}{\bf {\tt --}clean}{\tt ]}
%   {\tt [}{\bf {\tt --}force}{\tt ]} {\tt [}{\bf {\tt --}notfm}{\tt ]}
%   {\tt [}{\bf {\tt --}tfm} {\em tfm\/} {\tt [}{\bf {\tt --}tfm}
%   {\em tfm\/} ...{\tt ]}{\tt ]} {\tt [}{\bf {\tt --}mode}
%   {\em mode\/}{\tt ]} {\em file\/} {\tt [}{\em file\/} ...{\tt ]}
% 
% \subsubsection*{DESCRIPTION}
% The most complicated part of using the {\bf FeynMF} style appears to be the
% proper invocation of {\bf Metafont}.  The {\bf feynmf} script provides a
% convenient front end and will automagically invoke {\bf Metafont} with the
% proper mode and magnifincation.  It will also avoid cluttering system font
% directories and offers an option to clean them.
% 
% \subsubsection*{OPTIONS}%
% \index{OPTIONS}
% 
% \begin{description}
% 
% \item[{\bf -h}, {\bf {\tt --}help}]%
% \index{-h, --help@{\bf -h}, {\bf {\tt --}help}}%
% \hfil\\
% Print a short help text.
% 
% \item[{\bf -v}, {\bf {\tt --}version}]%
% \index{-v, --version@{\bf -v}, {\bf {\tt --}version}}%
% \hfil\\
% Print the version of {\bf feynmf}.
% 
% \item[{\bf -q}, {\bf {\tt --}quiet}]%
% \index{-q, --quiet@{\bf -q}, {\bf {\tt --}quiet}}%
% \hfil\\
% Don't echo the commands being executed.
% 
% \item[{\bf -n}, {\bf {\tt --}noexec}]%
% \index{-n, --noexec@{\bf -n}, {\bf {\tt --}noexec}}%
% \hfil\\
% Don't execute {\bf LaTeX} or {\bf Metafont}.
% 
% \item[{\bf -c}, {\bf {\tt --}clean}]%
% \index{-c, --clean@{\bf -c}, {\bf {\tt --}clean}}%
% \hfil\\
% Offer to delete font files that have accidentally been placed in a
% system directory by the {\bf MakeTeXTFM} and {\bf MakeTeXPK} scripts (these
% scripts are run by {\bf tex} (and {\bf latex}) in the background).  This
% option has only been tested with recent versions of UNIX TeX.
% 
% \item[{\bf -f}, {\bf {\tt --}force}]%
% \index{-f, --force@{\bf -f}, {\bf {\tt --}force}}%
% \hfil\\
% Don't ask any questions.
% 
% \item[{\bf -T}, {\bf {\tt --}notfm}]%
% \index{-T, --notfm@{\bf -T}, {\bf {\tt --}notfm}}%
% \hfil\\
% Don't try to prepare fake {\tt .tfm} files for the first run.
% 
% \item[{\bf -t}, {\bf {\tt --}tfm} {\em tfm\/}]%
% \index{-t, --tfm tfm@{\bf -t}, {\bf {\tt --}tfm} {\em tfm\/}}%
% \hfil\\
% Don't try guess the names of the {\tt .tfm} files to fake for
% the first run and use the given {\em name\/}(s) instead.  This option
% can be useful if our incomplete parsing of the LaTeX input
% files fails.
% 
% \item[-{\bf m} {\em mode\/}, {\bf {\tt --}mode} {\em mode\/}]%
% \index{-m mode, --mode mode@-{\bf m} {\em mode\/}, {\bf {\tt --}mode} {\em mode\/}}%
% \hfil\\
% Select the METAFONT mode {\em mode\/}.  The default is guessed or
% {\tt localfont} if the guess fails.
% 
% \item[{\em file\/}]%
% \index{file@{\em file\/}}%
% \hfil\\
% Main {\bf LaTeX} input files.
% 
% \item[{\em file\/} ...]%
% \index{file ...@{\em file\/} ...}%
% \hfil\\
% Other LaTeX input files that are included by the main file.
% 
% \end{description}
% 
% \subsubsection*{AUTHOR}
% Thorsten Ohl $<$Thorsten.Ohl@Physik.TH-Darmstadt.de$>$
% 
% \subsubsection*{BUGS}
% The preparation of {\tt .tfm} files is not foolproof yet, because we can
% parse {\bf TeX} files only superficially.
% 
% This script has only been tested for recent {\bf teTeX} distributions
% of UNIX {\bf TeX}, though it will probably work with other versions of
% UNIX {\bf TeX}.  The author will be grateful for portability suggestions,
% even concerning {\bf Borg} operating systems, for the benefit of those users
% that are forced to live with DOS or Windows.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Vertex mode}
%
% These basic features of \FMF{} are (or rather ``should be'')
% available through the \LaTeX{} interface.  No knowledge of
% \MF{} is necessary.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{External vertices}
%
% \DescribeMacro{\fmfleft}
% \DescribeMacro{\fmfright}
% \DescribeMacro{\fmfbottom}
% \DescribeMacro{\fmftop}
% \DescribeMacro{\fmfsurround}
% \manindex{external vertices}
% \manindex{vertices, external}
% Positioning of
% external vertices has to done explicitely.  The technical reason is
% that they would otherwise collapse with their neighbors, but
% practical reasons also suggest to give the user full control here.
% |\fmfleft{|\meta{v1}$[$|,|\ldots$]$|}| places the
% vertices in the comma separated list \meta{v1},\ldots\ 
% equidistantly on a smooth path on the left side of the diagram.
% |\fmfright{|\meta{v1}$[$|,|\ldots$]$|}| does the same
% thing on the right.  Similarly |\fmfbottom| and |\fmftop|, while
% |\fmfsurround{|\meta{v1}$[$|,|\ldots$]$|}|
% places its arguments on smooth path
% surrounding the diagram.
%
% \def\gallerylabels{%
%   \fmfdotn{v}{4}%
%   \fmflabel{$v_1$}{v1}%
%   \fmflabel{$v_2$}{v2}%
%   \fmflabel{$v_3$}{v3}%
%   \fmflabel{$v_4$}{v4}}
% \def\gallerydemo{%
%   \fbox{\begin{fmfgraph*}(15,12)
%     \fmfpen{thick}%
%     \fmfbottomn{v}{4}\gallerylabels
%     \fmfcmd{draw (bottom_gallery);}
%   \end{fmfgraph*}}\qquad
%   \fbox{\begin{fmfgraph*}(15,12)
%     \fmfpen{thick}%
%     \fmfleftn{v}{4}\gallerylabels
%     \fmfcmd{draw (left_gallery);}
%   \end{fmfgraph*}}\qquad
%   \fbox{\begin{fmfgraph*}(15,12)
%     \fmfpen{thick}%
%     \fmfsurroundn{v}{7}\fmfdotn{v}{7}%
%     \fmflabel{$v_1$}{v1}\fmflabel{$v_2$}{v2}%
%     \fmflabel{$v_3$}{v3}\fmflabel{$v_4$}{v4}%
%     \fmflabel{$v_5$}{v5}\fmflabel{$v_6$}{v6}%
%     \fmflabel{$v_7$}{v7}%
%     \fmfcmd{draw (surround_gallery);}
%   \end{fmfgraph*}}\qquad
%   \fbox{\begin{fmfgraph*}(15,12)
%     \fmfpen{thick}%
%     \fmftopn{v}{4}\gallerylabels
%     \fmfcmd{draw (top_gallery);}
%   \end{fmfgraph*}}\qquad
%   \fbox{\begin{fmfgraph*}(15,12)
%     \fmfpen{thick}%
%     \fmfrightn{v}{4}\gallerylabels
%     \fmfcmd{draw (right_gallery);}
%   \end{fmfgraph*}}}
%
% \DescribeMacro{\fmfcurved}
% \DescribeMacro{\fmfstraight}
% \manindex{galleries}
% Per default, the \emph{galleries} on which we place the external
% vertices are curved as in figure~\ref{fig:curvedgalleries}, but
% straight galleries are also available.  The macros
% |\fmfcurved| and |\fmfstraight| switch between
% these alternatives.
%
% \begin{figure}[t]
%   \begin{center}
%     \gallerydemo
%   \end{center}
%   \caption{\label{fig:curvedgalleries}%
%     Curved galleries.}
% \end{figure}
%
% \begin{figure}[t]
%   \begin{center}
%     \fmfstraight
%     \gallerydemo
%     \fmfcurved
%   \end{center}
%   \caption{\label{fig:straightgalleries}%
%     Straight galleries.}
% \end{figure}
%
% \DescribeMacro{\fmfleftn}
% \DescribeMacro{\fmfrightn}
% \DescribeMacro{\fmfbottomn}
% \DescribeMacro{\fmftopn}
% \DescribeMacro{\fmfsurroundn}
% \manindex{external vertices}
% \manindex{vertices, external}
% The macro |\fmfleftn| is similar to |\fmfleft|, but
% |\fmfleftn{|\meta{v}\allowbreak|}{|\meta{n}|}| places the
% vertices
% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}.  Analogously for
% the macros |\fmfrightn|, |\fmfbottomn|, |\fmftopn| and
% |\fmfsurroundn|.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Arcs and internal vertices}
%
% \DeleteShortVerb{\|}
% \MakeShortVerb{\"}
%
% \def\linesample#1{%
%   \begin{fmfgraph}(30,6)
%     \fmfleft{i}
%     \fmfright{o}
%     \fmf{#1}{i,o}
%   \end{fmfgraph}}
% \begin{table}[t]
%   \hfuzz=3cm
%   \begin{center}
%   \begin{tabular}{|l|c|l|l|}\hline
%     Name               & Example                       & Parameters  & Aliases  \\\hline\hline
%     "curly"            & \linesample{curly}            & "curly_len" & "gluon"  \\\hline
%     "dbl_curly"        & \linesample{dbl_curly}        & "curly_len" & \\\hline
%     "dashes"           & \linesample{dashes}           & "dash_len"  & \\\hline
%     "dashes_arrow"     & \linesample{dashes_arrow}     & "dash_len"  & "scalar" \\\hline
%     "dbl_dashes"       & \linesample{dbl_dashes}       & "dash_len"  & \\\hline
%     "dbl_dashes_arrow" & \linesample{dbl_dashes_arrow} & "dash_len"  & \\\hline
%     "dots"             & \linesample{dots}             & "dot_len"   & \\\hline
%     "dots_arrow"       & \linesample{dots_arrow}       & "dot_len"   & "ghost"  \\\hline
%     "dbl_dots"         & \linesample{dbl_dots}         & "dot_len"   & \\\hline
%     "dbl_dots_arrow"   & \linesample{dbl_dots_arrow}   & "dot_len"   & \\\hline
%     "phantom"          & \linesample{phantom}          &             & \\\hline
%     "phantom_arrow"    & \linesample{phantom_arrow}    &             & \\\hline
%     "plain"            & \linesample{plain}            &             & "vanilla"\\\hline
%     "plain_arrow"      & \linesample{plain_arrow}      &             & "fermion",
%                                                                        "electron",
%                                                                        "quark"  \\\hline
%     "dbl_plain"        & \linesample{dbl_plain}        &             & "double" \\\hline
%     "dbl_plain_arrow"  & \linesample{dbl_plain_arrow}  &             & "double_arrow",
%                                                                        "heavy"  \\\hline
%     "wiggly"           & \linesample{wiggly}           & "wiggly_len"& "boson",
%                                                                        "photon" \\\hline
%     "dbl_wiggly"       & \linesample{dbl_wiggly}       & "wiggly_len"& \\\hline
%     "zigzag"           & \linesample{zigzag}           & "zigzag_width"& \\\hline
%     "dbl_zigzag"       & \linesample{dbl_zigzag}       & "zigzag_len"& \\\hline
%   \end{tabular}
%   \end{center}
%   \caption{Available line styles}
%   \label{tab:line-styles}
% \end{table}
%
% \begin{table}[t]
%   \begin{center}
%   \begin{tabular}{|l|p{60mm}|}\hline
%     Name         & Explanation \\\hline\hline
%     "tension"    & draw a tighter ($>1$) or more loose ($<1$) arc \\\hline
%     "left"       & draw on a halfcircle on the left \\\hline
%     "right"      & draw on a halfcircle on the right \\\hline
%     "straight"   & draw on a straight line (default) \\\hline
%     "label"      & \TeX{} text for labeling the arc \\\hline
%     "label.side" & force placement of the label on the "left" or
%                   "right" \\\hline
%     "label.dist" & place label at a distance "dist" \\\hline
%     "label.pos"  & relative position of the label
%                    (not implemented yet!) \\\hline
%     "tag"        & optional tag for disambiguating arcs\\\hline
%     "width"      & width of the line\\\hline
%     "rubout"     & scale factor for crossing out lines
%                    (doesn't work properly for doubled lines yet)\\\hline
%     "foreground" & foreground color (\MP{} only!)\\\hline
%     "background" & background color for doubled lines (\MP{} only!)\\\hline
%   \end{tabular}
%   \end{center}
%   \caption{Available line options}
%   \label{tab:line-options}
% \end{table}
%
% \DeleteShortVerb{\"}
% \MakeShortVerb{\|}
%
% \DescribeMacro{\fmf}
% \manindex{labels}
% \manindex{arcs}
% This is the the most frequently used macro in \FMF{} applications.
% \begin{quote}
%   |\fmf{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$^^A
%     |}{|\meta{v1}|,|\meta{v2}$[$|,|\ldots$]$|}|
% \end{quote}
% connects the vertices \textit{v1,v2,\ldots} with a line of style
% \meta{style}, using a set of options \meta{opt} with (optional)
% value \meta{val}.  If a vertex is not
% known yet, it is added to the diagram.  Note that the actual drawing
% is not done immediately, because the positions can only be
% calculated when \emph{all} vertices are known. The currently
% available styles are collected in table~\ref{tab:line-styles}.  Most
% names should be self explanatory
% and are not discussed further.
% The |dashes|, |dots|, |phantom| and |plain| styles can optionally be
% decorated with an arrow as shown above.  All styles, including
% |curly|, |wiggly| and |zigzag|, can be doubled.  But arrows are not
% available
% for the latter three, because esthetically pleasing results can not be
% expected.  The |phantom|
% style is special, because it
% only enters the vertices and does \emph{not} cause a line to be
% drawn.  This is extremely useful for advanced layout features, as
% explained below.
% If you need a line styles that is not listed in
% table~\ref{tab:line-styles}, see section~\ref{sec:extensions} for
% how to define your own line styles.
% 
% The supported options are collected in
% table~\ref{tab:line-options}\footnote{%
%     One particulary useful further option would be \texttt{smooth},
%     allowing for several lines joined smoothly.  Early
%     experimentation has shown however, that the results are not
%     always what one expects and that there is a lot of room for
%     abuse.}
% Note that each of the dot separated components of the options can be
% abbreviated.  For example, |l.d| is equivalent to |label.dist|.  The
% result of ambiguous matches is however undefined.
%
% Note that because the options are separated by single commata,
% commata inside arguments to options (|label| comes to mind) have to
% be doubled (similar to quotes in Fortran).\footnote{%
%   Note that, as of version 1.03, it is no longer necessary to
%   escape \TeX{} control sequences in arguments.  Old files will
%   continue to work, because \texttt{noexpand} is temporarily
%   disabled.}
%
% Arcs that return to their origin are allowed (I will refer to them
% as \emph{tadpoles}), but some options have slightly different
% semantics.  |tension| is here a inverse scale factor for the
% tadpole, whose
% default size is 2/3 of the average distance the neighboring
% vertices.  If |left| or |right| are specified, they give the direction
% (in degrees) of the preferred gap into which the tadpole is placed.
% By default, the largest gap is chosen for \emph{all} tapoles at a
% given vertex, which will therefore overlap.  This is neither a bug
% nor a feature, but a limitation.
%
% \DescribeMacro{\fmfn}
% \manindex{arcs}
% The macro |\fmfn| is similar to |\fmf|, but
% \begin{quote}
%   |\fmfn{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$^^A
%     |}{|\meta{v}|}{|\meta{n}|}|
% \end{quote}
% connects the vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}.
%
% \DescribeMacro{\fmfcyclen}
% \DescribeMacro{\fmfrcyclen}
% \manindex{arcs}
% The macro |\fmfcyclen{|\meta{style}|}{|\meta{v}|}{|\meta{n}|}|
% cyclically connects the vertices
% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. |\fmfrcyclen| operates in
% reverse order.
%
% \DescribeMacro{\fmfpen}
% Pick up a pen of the specified size.  |\fmfpen{|\meta{weight}|}|
% is used for changing the weight (i.e.~thickness) of the lines.
% Predefined sizes are |thin| and |thick|.
%
% \DeleteShortVerb{\|}
% \MakeShortVerb{\"}
%
% \begin{table}[t]
%   \begin{center}
%   \begin{tabular}{|l|p{60mm}|}\hline
%     Name                 & Explanation \\\hline\hline
%     "label"              & \TeX{} text for labeling the vertex \\\hline
%     "label.angle"        & force placement of the label at the given
%                            angle from the vertex \\\hline
%     "label.dist"         & place label at a distance "dist" \\\hline
%     "decoration.shape"   & shape of decoration \\\hline
%     "decoration.size"    & size of decoration \\\hline
%     "decoration.filled"  & fill, shade or hatch decoration \\\hline
%     "decoration.angle"   & rotate decoration \\\hline
%     "foreground"         & foreground color (\MP{} only!)\\\hline
%     "background"         & background color (\MP{} only!)\\\hline
%   \end{tabular}
%   \end{center}
%   \caption{Available vertex options}
%   \label{tab:vertex-options}
% \end{table}
%
% \DeleteShortVerb{\"}
% \MakeShortVerb{\|}
%
% \DescribeMacro{\fmfv}
% \manindex{internal vertices}
% \manindex{vertices, internal}
% \manindex{labels}
% Declare vertices with options:
% \begin{quote}
%   |\fmfv{|\meta{opt}$[$|=|\meta{val}$][$|,|\meta{opt}$[$|=|\meta{val}$]$^^A
%     |,|\ldots$]$|}{|\meta{v1}$[$|,|\ldots$]$|}|
% \end{quote}
% This is used for adding labels to a vertex and for specifying other
% decoration.  Supported options are collected in
% table~\ref{tab:vertex-options}.  Here the same abbreviation
% mechanism as above is in effect.  The available |shape|s are listed
% in various filling styles in table~\ref{tab:vertex-shapes}\footnote{%
%   If the variable \texttt{feymfwizard} is \texttt{true} (e.g.~after
%   calling the \texttt{\bslash fmfwizard} macro),
%   it is also possible to specify any \MF{} expression that evaluates
%   to a \texttt{path}.  Naturally, this has to used with great care,
%   because strange errors can be triggered by typos!}.
% The tilings |gray10|, |gray25|, |gray75| and |gray90| are available
% in addition to |gray50|.  Customized tilings can be created with
% the \MF{} function |tile_from_string|.  It should be noted however,
% that tilings are gobbling up memory at high speed and should be used
% with discretion.  The halftones\footnote{%
%   \MP{} will give true halftones (if your printer supports them),
%   while \MF{} tries to mimic them.  The dithering algorithm of the
%   latter will be improved in the future.}
% can be accessed by giving any number from 2 to 99, which will denote
% the percentage of saturation ($30\%$ and $70\%$ here)\footnote{%
%   The old numeric arguments in the range $-1\ldots1$ continue to
%   work, but are considered obsolete.}.
% Again, commata inside arguments to options have to be doubled.
%
% \end{fmffile}
% \begin{fmffile}{fmfsamp2}
%
% \DeleteShortVerb{\|}
% \MakeShortVerb{\"}
%
% \def\VertexSample#1#2{%
%   \begin{fmfgraph}(8,8)
%     \fmfforce{(.5w,.4h)}{c}
%     \fmfv{d.shape=#1,d.filled=#2}{c}
%   \end{fmfgraph}}
% \def\VertexSamples#1{%
%   \VertexSample{#1}{full} & \VertexSample{#1}{empty}
%   & \VertexSample{#1}{shaded} & \VertexSample{#1}{hatched}
%   & \VertexSample{#1}{gray50} & \VertexSample{#1}{30}
%   & \VertexSample{#1}{70}}
% \begin{table}[t]
%   \begin{center}
%     \begin{tabular}{|l|c|c|c|c|c|c|c|}\hline
%       "filled="  & "full" & "empty" & "shaded" & "hatched"
%                           & "gray50" & "30" & "70" \\\hline\hline
%       "circle"   & \VertexSamples{circle} \\\hline
%       "square"   & \VertexSamples{square} \\\hline
%       "triangle" & \VertexSamples{triangle} \\\hline
%       "diamond"  & \VertexSamples{diamond} \\\hline
%       "pentagon" & \VertexSamples{pentagon} \\\hline
%       "hexagon"  & \VertexSamples{hexagon} \\\hline
%       "triagram" & \VertexSamples{triagram} \\\hline
%       "tetragram"& \VertexSamples{tetragram} \\\hline
%       "pentagram"& \VertexSamples{pentagram} \\\hline
%       "hexagram" & \VertexSamples{hexagram} \\\hline
%     \end{tabular}
%     \vspace*{\baselineskip}\\
%     \begin{tabular}{|c|c|c|c|}\hline
%        "triacross" & "cross" & "pentacross" & "hexacross" \\\hline\hline
%        \VertexSample{triacross}{1} & \VertexSample{cross}{1}
%        & \VertexSample{pentacross}{1} & \VertexSample{hexacross}{1} \\\hline
%     \end{tabular}
%   \end{center}
%   \caption{Available vertex shapes and fill styles.}
%   \label{tab:vertex-shapes}
% \end{table}
%
% \DeleteShortVerb{\"}
% \MakeShortVerb{\|}
%
% \DescribeMacro{\fmfblob}
% \manindex{blobs}
% Draw a blob of the specified diameter at the vertices. Incidentally,
% \begin{quote}
%   |\fmfblob{|\meta{diameter}|}{|\meta{v1}$[$|,|\ldots$]$|}|
% \end{quote}
% is equivalent to
% \begin{quote}
% \begin{flushleft}
%   |\fmfv{decor.shape=circle,decor.filled=shaded,|\\
%   \qquad |decor.size=|\meta{diameter}|}{|\meta{v1}$[$|,|\ldots$]$|}|
% \end{flushleft}
% \end{quote}
%
% \DescribeMacro{\fmfdot}
% \manindex{dots}
% Draw a dot at the vertices given as arguments.
% \begin{quote}
%   |\fmfdot{|\meta{v1}$[$|,|\ldots$]$|}|
% \end{quote}
% is equivalent to
% \begin{quote}
% \begin{flushleft}
%   |\fmfv{decor.shape=circle,decor.filled=full,|\\
%   \qquad |decor.size=2thick}{|\meta{v1}$[$|,|\ldots$]$|}|
% \end{flushleft}
% \end{quote}
% \DescribeMacro{\fmfvn}
% \manindex{internal vertices}
% \manindex{vertices, internal}
% The macro |\fmfvn| is similar to |\fmfv|, but
% \begin{quote}
%   |\fmfvn{|\meta{opt}$[$|=|\meta{val}$][$|,|^^A
%     \meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v}|}{|\meta{n}|}|
% \end{quote}
% places the vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}.
%
% \DescribeMacro{\fmfdotn}
% \DescribeMacro{\fmfblobn}
% \manindex{blobs}
% \manindex{dots}
% The macros |\fmfdotn| and |\fmfblobn| are similar to the |\fmfdot|
% and |\fmfblob|, but |\fmfdotn{|\meta{v}|}{|\meta{n}|}| places the
% vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}.  Analogously for
% |\fmfblobn|.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Polygons}
%
% Complex vertices with arcs attached at the corners can be
% contructed with polygons, which share some characteristics with arcs
% and vertices.
%
% \DescribeMacro{\fmfpoly}
% \manindex{polygons}
% The macro
% \begin{quote}
%   |\fmfpoly{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$^^A
%     |,|\ldots$]$|}{|\meta{v1}|,|\meta{v2}$[$|,|\ldots$]$|}|
% \end{quote}
% places the vertices \meta{v1}, \meta{v2}, \ldots{} on the corners of
% a regular polygon.  The orientation of the polygon is fixed to be
% mathematically positive (i.e.~counter clockwise).  Note that this
% can have strange results if the orientation is opposite to the
% orientation of the vertices the corners are connected to.
% The available options are collected in
% table~\ref{tab:polygon-options}. The effects of some options are
% depicted in table~\ref{tab:polygon-shapes}.
%
% Note that is is technically \emph{impossible} to fix the size of a
% polygon.  The size can be controlled by specifying a |tension| for
% the edges, which acts like the |tension| of normal arcs.
%
% \DeleteShortVerb{\|}
% \MakeShortVerb{\"}
%
% \begin{table}[t]
%   \begin{center}
%   \begin{tabular}{|l|p{60mm}|}\hline
%     Name                 & Explanation \\\hline\hline
%     "filled"             & fill, shade or hatch interior \\\hline
%     "phantom"            & don't draw anything \\\hline
%     "empty"              & draw outline \\\hline
%     "shade"              & shade interior \\\hline
%     "hatched"            & hatch interior \\\hline
%     "full"               & fill interior \\\hline
%     "pull"               & pull edges in ($<0$) or out ($>0$) \\\hline
%     "tension"            & tension of the edges \\\hline
%     "smooth"             & draw smoth corners \\\hline
%     "label"              & \TeX{} text for labeling the polygon \\\hline
%     "label.angle"        & force placement of the label at the given
%                            angle from the vertex \\\hline
%     "label.dist"         & place label at a distance "dist" \\\hline
%     "foreground"         & foreground color (\MP{} only!)\\\hline
%     "background"         & background color (\MP{} only!)\\\hline
%   \end{tabular}
%   \end{center}
%   \caption{Available polygon options}
%   \label{tab:polygon-options}
% \end{table}
%
% \def\PolygonSample#1#2{%
%   \begin{fmfgraph}(15,15)
%     \fmfsurroundn{e}{#1}
%     \fmfpolyn{shaded,tension=#2}{z}{#1}
%     \begin{fmffor}{i}{1}{1}{#1}
%       \fmf{plain}{z[i],e[i]}
%     \end{fmffor}
%   \end{fmfgraph}}
% \def\PolygonSamples#1#2#3{%
%   \PolygonSample{#1}{#2,pull=0.75#3}
%     & \PolygonSample{#1}{#2,pull=1.0#3}
%     & \PolygonSample{#1}{#2#3}
%     & \PolygonSample{#1}{#2,pull=1.5#3}}
% \begin{table}[t]
%   \begin{center}
%     \begin{tabular}{|l|c|c|c|c|}\hline
%       "pull="    & 0.75 & 1.0 & "?" & 1.5 \\\hline\hline
%       default    & \PolygonSamples{3}{.1}{}        \\\hline
%       "smooth"   & \PolygonSamples{3}{.1}{,smooth} \\\hline
%       default    & \PolygonSamples{5}{.6}{}        \\\hline
%       "smooth"   & \PolygonSamples{5}{.6}{,smooth} \\\hline
%       default    & \PolygonSamples{7}{1.}{}        \\\hline
%       "smooth"   & \PolygonSamples{7}{1.}{,smooth} \\\hline
%     \end{tabular}
%   \end{center}
%   \caption{Some of the available polygon shapes. Note that
%     \texttt{pull=1.0} is identical to \texttt{pull=?} for straight
%     lines, but very different for \texttt{smooth} lines.}
%   \label{tab:polygon-shapes}
% \end{table}
%
% \DeleteShortVerb{\"}
% \MakeShortVerb{\|}
%
% \DescribeMacro{\fmfpolyn}
% \DescribeMacro{\fmfrpolyn}
% \manindex{polygons}
% The macro |\fmfpolyn{|\meta{style}|}{|\meta{v}|}{|\meta{n}|}|
% is similar to |\fmfpoly| but connects the vertices
% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. |\fmfrpolyn| operates in
% reverse order.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Color}
%
% If \MP{} is used for rendering the diagrams, vertices and arcs can
% be colored.  The corresponding options give a warning message under
% \MF{} and are otherwise ignored.
%
% \manindex{color}
% Two colors are available for vertices and arcs: |foreground| and
% |background|.  Both can either be specified as a linear combination
% of the predefined colors |white|, |black|, |red|, |green| and |blue|
% or as RBG triples
% |(|\meta{red}|,|\allowbreak\meta{green}|,|\allowbreak\meta{blue}|)|.
% Note that as always commata have to be doubled in option arguments.
% Therefore both |foreground=|\allowbreak|(1,,0,,1)| and
% |foreground=|\allowbreak|red+|\allowbreak|blue| are 
% valid options setting the foreground color to magenta.
% For arcs, the background color is used only for the interior of
% doubled lines.
%
% While the color feature is rarely used in papers or books, it can
% be very useful for jazzing up your transparencies.  See
% page~\pageref{rainbow} for a not very serious example.
%
% \end{fmffile}
% \begin{fmffile}{fmfsamp3}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Examples}
%
% After the main features of the vertex mode have been introduced, it
% is time for a couple of illustrative examples that are taken from
% \emph{The Real World}.
%
% \begin{examples}{40mm}
%
% As a first example, consider drawing a straightforward box diagram,
% familiar from $K$-$\bar K$, $D$-$\bar D$, and  $B$-$\bar B$ mixing.
% The commands for the labels are not shown here, they are discussed
% in section~\ref{sec:labels}
%
% Let us start the diagram and pick up a thick pen:
% \begin{verbatim}
% \begin{fmfgraph}(40,25)
%   \fmfpen{thick}
% \end{verbatim}
% The incoming and outcoming vertices are placed on the left and
% right hand side, respectively:
% \begin{verbatim}
%   \fmfleft{i1,i2}
%   \fmfright{o1,o2}
% \end{verbatim}
% Now we tell \FMF{} how the arcs are connected.
% \begin{verbatim}
%   \fmf{fermion}{i1,v1,v3,o1}
%   \fmf{fermion}{o2,v4,v2,i2}
%   \fmf{photon}{v1,v2}
%   \fmf{photon}{v3,v4}
% \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph*}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i1,i2}
%       \fmflabel{$\bar{b}$}{i1}
%       \fmflabel{$d$}{i2}
%       \fmfright{o1,o2}
%       \fmflabel{$\bar{d}$}{o1}
%       \fmflabel{$b$}{o2}
%       \fmf{fermion}{i1,v1}
%       \fmf{fermion,label=$\bar{t},,\bar{c},,\bar{u}$,
%                    l.side=right}{v1,v3}
%       \fmf{fermion}{v3,o1}
%       \fmf{fermion}{o2,v4}
%       \fmf{fermion,label=$t,,c,,u$,l.side=right}{v4,v2}
%       \fmf{fermion}{v2,i2}
%       \fmf{photon,label=$W^+$,l.side=left}{v1,v2}
%       \fmf{photon,label=$W^-$,l.side=right}{v3,v4}
%       \fmfdotn{v}{4}
%     \end{fmfgraph*}}
% \label{pg:box}
% Finally we tell \FMF{} to draw dots at the vertices and we're done.
% \begin{verbatim}
%   \fmfdotn{v}{4}
% \end{fmfgraph}
% \end{verbatim}
% \label{page:simple-examples}
% With a little effort the layout of this diagram can actually be
% improved by enlarging the inner box, see page~\pageref{pg:newbox}
% below.
%
% Here is the resonant $s$-channel contribution to $e^+e^-\to 4f$.
% (From now on, we do no longer display the
% \begin{verbatim}
%   \begin{fmfgraph}(40,25)
%     \fmfpen{thick}
%       ...
%   \end{fmfgraph}
% \end{verbatim}
% environment surrounding all pictures.)
% \begin{verbatim}
%   \fmfleftn{i}{2}
%   \fmfrightn{o}{4}
%     \fmf{fermion}{i1,v1,i2}
%   \fmf{photon}{v1,v2}
%   \fmfblob{.15w}{v2}
%     \fmf{photon}{v2,v3}
%       \fmf{fermion}{o1,v3,o2}
%     \fmf{photon}{v2,v4}
%       \fmf{fermion}{o4,v4,o3}
% \end{verbatim}
%   \marginexample{%
%       \begin{fmfgraph*}(40,25)
%         \fmfpen{thick}
%         \fmfleftn{i}{2}
%         \fmfrightn{o}{4}
%           \fmflabel{$e_-$}{i1}
%           \fmflabel{$e_+$}{i2}
%           \fmf{fermion}{i1,v1,i2}
%         \fmf{photon}{v1,v2}
%         \fmfblob{.15w}{v2}
%           \fmf{photon}{v2,v3}
%             \fmflabel{$\mu_+$}{o1}
%             \fmflabel{$\nu_\mu$}{o2}
%             \fmf{fermion}{o1,v3,o2}
%           \fmf{photon}{v2,v4}
%             \fmflabel{$\bar{c}$}{o4}
%             \fmflabel{$s$}{o3}
%             \fmf{fermion}{o4,v4,o3}
%       \end{fmfgraph*}}
%
% And the resonant $t$-channel contribution:
% \begin{verbatim}
%   \fmfleftn{i}{2}
%   \fmfrightn{o}{4}
%   \fmf{fermion}{i1,v1,v2,i2}
%     \fmf{photon}{v1,v3}
%       \fmf{fermion}{o1,v3,o2}
%     \fmf{photon}{v2,v4}
%       \fmf{fermion}{o4,v4,o3}
% \end{verbatim}
%   \marginexample{%
%       \begin{fmfgraph*}(40,25)
%         \fmfpen{thick}
%         \fmfleftn{i}{2}
%         \fmfrightn{o}{4}
%         \fmflabel{$e_-$}{i1}
%         \fmflabel{$e_+$}{i2}
%         \fmf{fermion}{i1,v1,v2,i2}
%           \fmf{photon}{v1,v3}
%             \fmflabel{$\mu_+$}{o1}
%             \fmflabel{$\nu_\mu$}{o2}
%             \fmf{fermion}{o1,v3,o2}
%           \fmf{photon}{v2,v4}
%             \fmflabel{$\bar{c}$}{o4}
%             \fmflabel{$s$}{o3}
%             \fmf{fermion}{o4,v4,o3}
%       \end{fmfgraph*}}
%
% Two point loop diagrams pose another set of problems.  We
% must have a way of specifying that one or more of the lines
% connecting the two vertices are \emph{not} connected by a straight
% line.  The options |left|, |right| and |straight| offer the
% possibility to connect two vertices by a semicircle detour, either
% on the left or on the right.  Since by default all lines contribute
% to the tension between two vertices, the |tension| option allows us
% to reduce this tension.  The next examples shows both options in
% action.  The lower fermion line is given an tension of~$1/3$ to
% make is symmetrical with the upper line with consists of three parts.
% The loop photon is using a detour on the right and does not
% contribute any tension.
% \begin{verbatim}
%   \fmfleft{i1,i2}
%   \fmfright{o1}
%   \fmf{fermion,tension=1/3}{i1,v1}
%   \fmf{plain}{v1,v2}
%   \fmf{fermion}{v2,v3}
%   \fmf{photon,right,tension=0}{v2,v3}
%   \fmf{plain}{v3,i2}
%   \fmf{photon}{v1,o1}
% \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph*}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i1,i2}
%       \fmflabel{$p^{\prime}$}{i1}
%       \fmflabel{$p$}{i2}
%       \fmfright{o1}
%       \fmf{fermion,tension=1/3}{i1,v1}
%       \fmf{plain}{v1,v2}
%       \fmf{fermion,label=$p-k$,l.side=left}{v2,v3}
%       \fmf{photon,right,tension=0,label=$k$}{v2,v3}
%       \fmf{plain}{v3,i2}
%       \fmf{photon}{v1,o1}
%     \end{fmfgraph*}}
% The optional argument to |left| and |right| can be used to deform the
% corresponding contour as in the following example.
% The default value of |left| and |right| is 1.
% \begin{verbatim}
%   \fmfleft{i} \fmfright{o}
%   \fmf{plain}{i,v1} \fmf{plain}{v2,o}
%   \fmf{dots,left=.5,tension=0.3}{v1,v2,v1}\fmffreeze
%   \fmf{plain,left}{v1,v2,v1}
%   \fmf{dashes,left=1.5}{v1,v2,v1}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(40,30)
%     \fmfpen{thick}
%     \fmfleft{i} \fmfright{o}
%     \fmf{plain}{i,v1} \fmf{plain}{v2,o}
%     \fmf{dots,left=.5,tension=0.3}{v1,v2,v1}\fmffreeze
%     \fmf{plain,left}{v1,v2,v1}
%     \fmf{dashes,left=1.5}{v1,v2,v1}
%   \end{fmfgraph}}
%
% Polygons are particulary useful for depicting non-perturbative
% contributions: 
% \begin{verbatim}
%     \fmfpen{thick}
%     \fmfleftn{l}{2}\fmfrightn{r}{2}
%     \fmfrpolyn{shaded,label=$\Gamma$}{G}{4}
%     \fmfpolyn{empty,label=$K$}{K}{4}
%     \fmf{fermion}{l1,G1}\fmf{fermion}{l2,G2}
%     \fmf{fermion}{K1,r1}\fmf{fermion}{K2,r2}
%     \fmf{fermion,left=.5,tension=.5}{G3,K3}
%     \fmf{fermion,right=.5,tension=.5}{G4,K4}
% \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph*}(40,25)
%       \fmfpen{thick}
%       \fmfleftn{l}{2}\fmfrightn{r}{2}
%       \fmfrpolyn{shaded,label=$\Gamma$}{G}{4}
%       \fmfpolyn{empty,label=$K$}{K}{4}
%       \fmf{fermion}{l1,G1}\fmf{fermion}{l2,G2}
%       \fmf{fermion}{K1,r1}\fmf{fermion}{K2,r2}
%       \fmf{fermion,left=.5,tension=.5}{G3,K3}
%       \fmf{fermion,right=.5,tension=.5}{G4,K4}
%     \end{fmfgraph*}}
%
% To conclude this first picture show, here's a self energy in
% scalar $\phi^4$-theory showing the simplicity of the tadpole
% feature:
% \begin{verbatim}
%   \fmfpen{thick}
%   \fmfleft{i}
%   \fmfright{o}
%   \fmf{plain}{i,v,v,o}
%   \fmfdot{v}
% \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i}
%       \fmfright{o}
%       \fmf{plain}{i,v,v,o}
%       \fmfdot{v}
%     \end{fmfgraph}}
% \manindex{tadpoles}
% Scalar $\phi^6$-theory needs a little manual intervention to force
% the second on the opposite side:
% \begin{verbatim}
%   \fmfpen{thick}
%   \fmfleft{i}
%   \fmfright{o}
%   \fmf{plain}{i,v,v,o}
%   \fmf{plain,left=90}{v,v}
%   \fmfdot{v}
% \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i}
%       \fmfright{o}
%       \fmf{plain}{i,v,v,o}
%       \fmf{plain,left=90}{v,v}
%       \fmfdot{v}
%     \end{fmfgraph}}
%
% \end{examples}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Labels}
% \label{sec:labels}
%
% Let us now come back to the examples on
% page~\pageref{page:simple-examples} and discuss how to add the
% labels.
%
% \DescribeMacro{\fmflabel}
% \manindex{labels}
% The macro 
% \begin{quote}
%   |\fmflabel{|\meta{label}|}{|\meta{v}|}|  
% \end{quote}
% is equivalent to
% \begin{quote}
%   |\fmfv{label=|\meta{label}|}{|\meta{v}|}|
% \end{quote}
% and adds the label
% \meta{label} to the vertex \meta{v}.  In the current implementation,
% there can be only a single label for each vertex.  Thus earlier
% calls to |\fmflabel| for the same vertex will be overwritten.
% \meta{label} will be placed with the |\put| command of the \LaTeX{}
% |picture| environment.\footnote{%
%   Note again that, as of version 1.03, it is no longer necessary to
%   escape \TeX{} control sequences in arguments.  Old files will
%   continue to work, because \texttt{noexpand} is temporarily
%   disabled.}
% Note that the |fmfgraph*| environment must be used to use labels,
% they will silently disappear in |fmfgraph|.
%
% |\fmflabel| gives the user \emph{no} control on the placement of
% the the label (use the |\fmfv| macro for a more fine-grained
% control).  The label is placed using the
% following algorithm:
% \begin{enumerate}
%   \item{} The reference point of the box containing \meta{label} is
%     placed at the distance |3thick| on the continuation of the
%     straight line connecting the center of the picture with the
%     vertex \meta{v}.
%   \item{} The reference point of the box is chosen such that the
%     contents of the box is on the outside of the vertex (with
%     respect to the center of the diagram).  It is chosen from the
%     four corners and the four midpoints of the sides.
% \end{enumerate}
%
% Therefore the four external particles in the~$B$-$\bar B$ mixing
% diagram on page~\pageref{page:simple-examples} are labelled simply
% by:
% \begin{verbatim}
%   \fmflabel{$\bar{b}$}{i1}
%   \fmflabel{$d$}{i2}
%   \fmflabel{$\bar{d}$}{o1}
%   \fmflabel{$b$}{o2}
% \end{verbatim}
%
% \begin{examples}{40mm}
% \manindex{labels}
% Here is a more systematical demonstration of the default placement
% of labels:
% \begin{verbatim}
%   \fmfsurroundn{v}{8}\fmfdotn{v}{8}
%   \fmflabel{$v_1$}{v1}
%   \fmflabel{$v_2$}{v2}
%   \fmflabel{$v_3$}{v3}
%   \fmflabel{$v_4$}{v4}
%   \fmflabel{$v_5$}{v5}
%   \fmflabel{$v_6$}{v6}
%   \fmflabel{$v_7$}{v7}
%   \fmflabel{$v_8$}{v8}
% \end{verbatim}
%   \marginexample{%
%   \begin{fmfgraph*}(40,30)
%     \fmfsurroundn{v}{8}\fmfdotn{v}{8}
%     \fmflabel{$v_1$}{v1}
%     \fmflabel{$v_2$}{v2}
%     \fmflabel{$v_3$}{v3}
%     \fmflabel{$v_4$}{v4}
%     \fmflabel{$v_5$}{v5}
%     \fmflabel{$v_6$}{v6}
%     \fmflabel{$v_7$}{v7}
%     \fmflabel{$v_8$}{v8}
%   \end{fmfgraph*}}
% And here is a demonstration of the explicit placement of
% labels\footnote{%
%   Don't be confused by the \texttt{\bslash fmfiv} command.  It is
%   described below (see section~\ref{sec:fmfiv}) and takes the same
%   arguments as the  \texttt{\bslash fmfv} command.  We use it here
%   for convenience to place multiple vertices at the same point,
%   i.e.~the center.}:
% \begin{verbatim}
%   \fmfiv{d.sh=circle,d.f=1,d.si=2thin}{c}
%   \fmfiv{l=-120,l.a=-120,l.d=.2w}{c}
%   \fmfiv{l=-60,l.a=-60,l.d=.2w}{c}
%   \fmfiv{l=0,l.a=0,l.d=.2w}{c}
%   \fmfiv{l=60,l.a=60,l.d=.2w}{c}
%   \fmfiv{l=120,l.a=120,l.d=.2w}{c}
%   \fmfiv{l=180,l.a=180,l.d=.2w}{c}
% \end{verbatim}
%   \marginexample{%
%   \begin{fmfgraph*}(40,30)
%     \fmfiv{d.sh=circle,d.f=1,d.si=2thin}{c}
%     \fmfiv{l=-120,l.a=-120,l.d=.2w}{c}
%     \fmfiv{l=-60,l.a=-60,l.d=.2w}{c}
%     \fmfiv{l=0,l.a=0,l.d=.2w}{c}
%     \fmfiv{l=60,lab.ang=60,l.d=.2w}{c}
%     \fmfiv{l=120,l.a=120,l.d=.2w}{c}
%     \fmfiv{l=180,l.a=180,l.d=.2w}{c}
%   \end{fmfgraph*}}
%
% \end{examples}
%
% There is no equivalent to |\fmflabel| for arcs.  Here options to the
% |\fmf| command have to be used.  The default placement rules put the
% label on the outside at the midpoint of a curved arc.  If the arc is
% straight, one should use the |label.side| option to push the label
% either to the |left| or to the |right|.  This |label.dist| option is
% treated analogously to same option for vertices.
%
% Therefore the four internal particles in the~$B$-$\bar B$ mixing
% diagram on page~\pageref{page:simple-examples} are labelled simply
% by adding options to the |\fmf| commands:
% \manindex{labels}
% \begin{verbatim}
%   \fmf{fermion,label=$\bar{t},,\bar{c},,\bar{u}$,
%                label.side=right}{v1,v3}
%   \fmf{fermion,label=$t,,c,,u$,label.side=right}{v4,v2}
%   \fmf{photon,label=$W^+$,label.side=left}{v1,v2}
%   \fmf{photon,label=$W^-$,label.side=right}{v3,v4}
% \end{verbatim}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Manipulating the layout}
%
% The automatic layout algorithms of \FMF{} are rather simple,
% therefore it is sometimes necessary to allow for manual intervention
% from time to time.
%
% \DescribeMacro{\fmffreeze}
% Calculate the positions of the vertices based on the arcs which are
% defined up to this point.  Usually this calculation is performed
% automatically at the end of the |fmfgraph| environment. Calling it
% explicitely is useful for later adding arcs that should not enter
% the calculation .  The layout is chosen to minimize the overall
% length of all arcs.  The length of each arc is weighted with the
% |tension| option, whose default value is 1.
% See section~\ref{sec:skeletons} for more information on
% |\fmffreeze|. 
%
% \DescribeMacro{\fmfforce}
% |\fmfforce{|\meta{pos}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% forces the position \meta{pos} of the vertices \meta{v1}\ldots,
% bypassing and overwriting the automatic layout.  In all arguments
% that are \MF{} |pair|s (i.e.~points), you can use the variable |w|
% and |h|, which are predefined to the width and the height of the
% whole
% diagram respectively.  E.g.~the center is specified as |(.5w,.5h)|
% and the lower right corner as |(w,0)|.
% The center and the four corners of the current subgraph (see the
% \texttt{fmfsubgraph} environment on page~\pageref{fmfsubgraph}) are
% available as |c|, |nw|, |ne|, |sw| and |se| (for \emph{north-west}
% etc).
%
% \DescribeMacro{\fmfshift}
% |\fmfshift{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% shifts the position of the vertices \meta{v1}\ldots{} by \meta{dist}
% from the automatic layout.  This command is only useful \emph{after}
% a |\fmffreeze| of the corresponding vertex.
%
% \DescribeMacro{\fmffixed}
% |\fmffixed{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% fixes the distance between subsequent vertices in the list
% \meta{v1}\ldots{} to \meta{dist}.
% This command should be used with care, because it is possible to
% overconstrain the layout of the graph and the error messages will be
% obscure for a novice user.
%
% \DescribeMacro{\fmffixedx}
% \DescribeMacro{\fmffixedy}
% |\fmffixedx{|\meta{dx}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% is identical to
% |\fmffixed{(|\meta{dx}|,whatever)}{|\meta{v1}\allowbreak
%   $[$|,|\ldots$]$|}|
% and |\fmffixedy{|\meta{dy}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
% is identical to
% |\fmffixed{(whatever,|\meta{dy}|)}{|\meta{v1}\allowbreak
%   $[$|,|\ldots$]$|}|.  These commands can be used to fix relative
% positions in one coordinate, while allowing movement in the other
% coordinate.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Skeletons}
% \label{sec:skeletons}
%
% The single most powerful concept for adjusting \FMF's layout
% decisions is the use of \emph{skeletons}.  By issuing a
% |\fmffreeze| after specifying a subgraph (skeleton), we can fix the
% location of the skeleton \emph{as if} the other arcs were not there.
% We can then successively add more subgraphs whose layout will be
% chosen with the skeleton remaining fixed. Similar effects can be
% achieved by giving some arcs a vanishing |tension|. 
%
% \begin{examples}{40mm}
%
% Consider the following example: suppose we want to draw a ladder
% diagram contributing to the quark form factor.  Simply linking in
% the gluons does not produce a satisfactory result:
%   \begin{verbatim}
%     \fmfleft{i1} \fmfright{o1,o2}
%     \fmf{photon}{i1,v4}
%     \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%     \fmf{gluon}{v1,v7}
%     \fmf{gluon}{v2,v6}
%     \fmf{gluon}{v3,v5}
%   \end{verbatim}
%   \marginexample{%
%    \begin{fmfgraph}(40,25)
%      \fmfpen{thick}
%      \fmfleft{i1} \fmfright{o1,o2}
%      \fmf{photon}{v4,i1}
%      \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%      \fmf{gluon}{v1,v7}
%      \fmf{gluon}{v2,v6}
%      \fmf{gluon}{v3,v5}
%    \end{fmfgraph}}
% What went wrong?  Obviously the gluons are bonding the quark lines
% too strongly.  The fix is simple: just create a skeleton excluding
% the gluons
%   \begin{verbatim}
%     \fmfleft{i1} \fmfright{o1,o2}
%     \fmf{photon}{i1,v4}
%     \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%   \end{verbatim}
%   \marginexample{
%    \begin{fmfgraph}(40,25)
%      \fmfpen{thick}
%      \fmfleft{i1} \fmfright{o1,o2}
%      \fmf{photon}{v4,i1}
%      \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%    \end{fmfgraph}}
% and add the gluons later:
%   \begin{verbatim}
%     \fmfleft{i1} \fmfright{o1,o2}
%     \fmf{photon}{i1,v4}
%     \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%     \fmffreeze
%     \fmf{gluon}{v1,v7}
%     \fmf{gluon}{v2,v6}
%     \fmf{gluon}{v3,v5}
%   \end{verbatim}
%   \marginexample{
%    \begin{fmfgraph}(40,25)
%      \fmfpen{thick}
%      \fmfleft{i1} \fmfright{o1,o2}
%      \fmf{photon}{v4,i1}
%      \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%      \fmffreeze
%      \fmf{gluon}{v1,v7}
%      \fmf{gluon}{v2,v6}
%      \fmf{gluon}{v3,v5}
%    \end{fmfgraph}}
% Alternatively, we can use a vanishing |tension|, which will
% effectively exclude the gluons from the layout decisions:
%   \begin{verbatim}
%     \fmfleft{i1} \fmfright{o1,o2}
%     \fmf{photon}{i1,v4}
%     \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%     \fmf{gluon,tension=0}{v1,v7}
%     \fmf{gluon,tension=0}{v2,v6}
%     \fmf{gluon,tension=0}{v3,v5}
%   \end{verbatim}
%   \marginexample{
%    \begin{fmfgraph}(40,25)
%      \fmfpen{thick}
%      \fmfleft{i1} \fmfright{o1,o2}
%      \fmf{photon}{v4,i1}
%      \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
%      \fmf{gluon,tension=0}{v1,v7}
%      \fmf{gluon,tension=0}{v2,v6}
%      \fmf{gluon,tension=0}{v3,v5}
%    \end{fmfgraph}}
% Which method is more intuitve is largely a matter of taste and at
% the discretion of the user.
%
% The ``crossed'' version of this diagram is best drawn using the
% |rubout| option:
%   \begin{verbatim}
%     \fmfleft{i1} \fmfright{o1,o2}
%     \fmf{photon}{i1,v3}
%     \fmf{quark}{o1,v1,v2,v3,v4,v5,o2}
%     \fmffreeze
%     \fmf{gluon}{v1,v4}
%     \fmf{gluon,rubout}{v2,v5}
%   \end{verbatim}
%   \marginexample{
%    \begin{fmfgraph}(40,25)
%      \fmfpen{thick}
%      \fmfleft{i1} \fmfright{o1,o2}
%      \fmf{photon}{i1,v3}
%      \fmf{quark}{o1,v1,v2,v3,v4,v5,o2}
%      \fmffreeze
%      \fmf{gluon}{v1,v4}
%      \fmf{gluon,rubout}{v2,v5}
%    \end{fmfgraph}}
% If |rubout| is selected, it defaults to~2, but it can be changed to
% any (reasonable) value~$>1$.  The current implementation should work
% for almost all user-defined line styles.  However, it does not work
% correctly for the predefined |double| line styles yet.
%
% Another instructive example is the following: imagine you want to
% draw a typical non-resonant contribution to~$e^+e^-\to 4f$.  The
% obvious solution doesn't look right:
%   \begin{verbatim}
%     \fmfleft{i1,i2}
%     \fmfright{o1,o2,o3,o4}
%     \fmf{fermion}{i1,v1,i2}
%     \fmf{boson}{v1,v2}
%     \fmf{fermion}{o1,v2,v3,o4}
%     \fmf{boson}{v3,v4}
%     \fmf{fermion}{o3,v4,o2}
%   \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i1,i2}
%       \fmfright{o1,o2,o3,o4}
%       \fmf{fermion}{i1,v1,i2}
%       \fmf{boson}{v1,v2}
%       \fmf{fermion}{o1,v2,v3,o4}
%       \fmf{boson}{v3,v4}
%       \fmf{fermion}{o3,v4,o2}
%     \end{fmfgraph}}
% Again, we should start with a skeleton
%   \begin{verbatim}
%     \fmfleft{i1,i2}
%     \fmfright{o1,o2,o3,o4}
%     \fmf{fermion}{i1,v1,i2}
%     \fmf{boson}{v1,v2}
%     \fmf{fermion}{o1,v2,v3,o4}
%   \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i1,i2}
%       \fmfright{o1,o2,o3,o4}
%       \fmf{fermion}{i1,v1,i2}
%       \fmf{boson}{v1,v2}
%       \fmf{fermion}{o1,v2,v3,o4}
%     \end{fmfgraph}}
% and add the second $W$ later:
%   \begin{verbatim}
%     \fmfleft{i1,i2}
%     \fmfright{o1,o2,o3,o4}
%     \fmf{fermion}{i1,v1,i2}
%     \fmf{boson}{v1,v2}
%     \fmf{fermion}{o1,v2,v3,o4}
%     \fmffreeze
%     \fmf{boson}{v3,v4}
%     \fmf{fermion}{o3,v4,o2}
%   \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i1,i2}
%       \fmfright{o1,o2,o3,o4}
%       \fmf{fermion}{i1,v1,i2}
%       \fmf{boson}{v1,v2}
%       \fmf{fermion}{o1,v2,v3,o4}
%       \fmffreeze
%       \fmf{boson}{v3,v4}
%       \fmf{fermion}{o3,v4,o2}
%     \end{fmfgraph}}
%
% Here's another example that uses stretchable arcs.  Diagrams
% of this kind are known as \emph{rainbow} diagrams.  If you're using
% \MP{} and are watching this on a color device, you'll see why.
%   \begin{verbatim}
%     \fmfpen{thick}
%     \fmfleft{i1,d1}
%     \fmfright{o1,d2}
%     \fmfn{plain}{i}{4}
%     \fmf{plain}{i4,v,o4}
%     \fmfn{plain}{o}{4}
%     \fmffreeze
%     \fmf{gluon,left,fore=red}{i1,o1}
%     \fmf{gluon,left,fore=green}{i2,o2}
%     \fmf{gluon,left,fore=blue}{i3,o3}
%     \fmfdotn{i}{3}
%     \fmfdotn{o}{3}
%     \fmfv{d.sh=circle,d.f=empty,d.si=.2w,b=(1,,0,,1),
%           l=$\Sigma$}{v}
%   \end{verbatim}
%   \marginexample{%
%     \label{rainbow}
%     \begin{fmfgraph*}(40,25)
%       \fmfpen{thick}
%       \fmfleft{i1,d1}
%       \fmfright{o1,d2}
%       \fmfn{plain}{i}{4}
%       \fmf{plain}{i4,v,o4}
%       \fmfn{plain}{o}{4}
%       \fmffreeze
%       \fmf{gluon,left,fore=red}{i1,o1}
%       \fmf{gluon,left,fore=green}{i2,o2}
%       \fmf{gluon,left,fore=blue}{i3,o3}
%       \fmfdotn{i}{3}
%       \fmfdotn{o}{3}
%       \fmfv{d.sh=circle,d.f=empty,d.si=.2w,b=(1,,0,,1),
%             l=$\Sigma$,l.d=0}{v}
%     \end{fmfgraph*}}
%
% \end{examples}
%
% Experience has shown that the method advocated in this section is
% more effective than fuzzing around with fractional |tension|
% parameters.  Using |\fmfshift| or |\fmfforce| should be
% a last resort only.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Pulling strings}
% \label{sec:strings}
%
% If you add to any arc one or more |phantom| arcs they will cause
% a tighter bonding between the vertices involved
% \begin{verbatim}
%   \fmf{fermion}{v1,v2}
%   \fmf{phantom}{v1,v2}
% \end{verbatim}
% which is equivalent to
% \begin{verbatim}
%   \fmf{fermion,tension=2}{v1,v2}
% \end{verbatim}
% The |phantom| arc has to be added \emph{before} any |\fmffreeze|
% involving these vertices, of course.
%
% \begin{examples}{40mm}
%
% Here is an example from deep inelastic scattering\footnote{%
%   Don't be confused by the \texttt{\bslash fmfi} command.  It is
%   described below (see section~\ref{sec:fmfi}) and takes the same
%   arguments as the \texttt{\bslash fmfv} command.  We use it here
%   for adding to more lines parallel to the incoming proton line.
%   They do not enter the layout decisions.}:
%   \begin{verbatim}
%     \fmfleft{ip,il}
%     \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
%     \fmf{fermion}{ip,vp,vq,oq3}
%     \fmf{fermion}{vp,oq1}
%     \fmf{fermion}{vp,oq2}
%     \fmf{photon}{vl,vq}
%     \fmf{fermion}{il,vl,ol}
%     \fmfblob{.15w}{vp}
%     \fmfdot{vq,vl}
%     \fmffreeze
%     \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
%     \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
%   \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{ip,il}
%       \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
%       \fmf{fermion}{ip,vp,vq,oq3}
%       \fmf{fermion}{vp,oq1}
%       \fmf{fermion}{vp,oq2}
%       \fmf{photon}{vl,vq}
%       \fmf{fermion}{il,vl,ol}
%       \fmfblob{.15w}{vp}
%       \fmfdot{vq,vl}
%       \fmffreeze
%       \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
%       \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
%     \end{fmfgraph}}
% As it stands, all vertices come out too far to the right, because
% the greater number of outgoing lines pulls them over.  Adding
% |\fmf{phantom}| makes the bond between the incoming vertices and the
% interactions tighter and produces a better balanced picture:
%   \begin{verbatim}
%     \fmfleft{ip,il}
%     \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
%     \fmf{fermion}{ip,vp,vq,oq3}
%     \fmf{phantom}{ip,vp}
%     \fmf{fermion}{vp,oq1}
%     \fmf{fermion}{vp,oq2}
%     \fmf{photon}{vl,vq}
%     \fmf{fermion}{il,vl,ol}
%     \fmf{phantom}{il,vl}
%     \fmfblob{.15w}{vp}
%     \fmfdot{vq,vl}
%     \fmffreeze
%     \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
%     \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
%   \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{ip,il}
%       \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
%       \fmf{fermion}{ip,vp,vq,oq3}
%       \fmf{phantom}{ip,vp}
%       \fmf{fermion}{vp,oq1}
%       \fmf{fermion}{vp,oq2}
%       \fmf{photon}{vl,vq}
%       \fmf{fermion}{il,vl,ol}
%       \fmf{phantom}{il,vl}
%       \fmfblob{.15w}{vp}
%       \fmfdot{vq,vl}
%       \fmffreeze
%       \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
%       \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
%     \end{fmfgraph}}
% Equivalently, we could add |tension| to the lines in question and we
% will get the same result:
%   \begin{verbatim}
%     \fmfleft{ip,il}
%     \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
%     \fmf{fermion,tension=2}{ip,vp}
%     \fmf{fermion}{vp,vq,oq3}
%     \fmf{fermion}{vp,oq1}
%     \fmf{fermion}{vp,oq2}
%     \fmf{photon}{vl,vq}
%     \fmf{fermion,tension=2}{il,vl}
%     \fmf{fermion}{vl,ol}
%     \fmfblob{.15w}{vp}
%     \fmfdot{vq,vl}
%     \fmffreeze
%     \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
%     \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
%   \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph}(40,25)
%       \fmfpen{thick}
%       \fmfleft{ip,il}
%       \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
%       \fmf{fermion,tension=2}{ip,vp}
%       \fmf{fermion}{vp,vq,oq3}
%       \fmf{fermion}{vp,oq1}
%       \fmf{fermion}{vp,oq2}
%       \fmf{photon}{vl,vq}
%       \fmf{fermion,tension=2}{il,vl}
%       \fmf{fermion}{vl,ol}
%       \fmfblob{.15w}{vp}
%       \fmfdot{vq,vl}
%       \fmffreeze
%       \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
%       \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
%     \end{fmfgraph}}
% \end{examples}
%
% Conversely, specifing a |tension| $<1$ will make the corresponding
% arcs more loose.
%
% \begin{examples}{40mm}
%
% Reconsider the box graph on page~\pageref{pg:box} and reduce the
% tension on the inner lines\footnote{%
%   Now that you know, I have also displayed the \texttt{label}
%   options used.}
% \begin{verbatim}
%   \fmfleft{i1,i2}
%   \fmflabel{$\bar{b}$}{i1}
%   \fmflabel{$d$}{i2}
%   \fmfright{o1,o2}
%   \fmflabel{$\bar{d}$}{o1}
%   \fmflabel{$b$}{o2}
%   \fmf{fermion}{i1,v1}
%   \fmf{fermion,tension=.5,label=$\bar{t},,\bar{c},,\bar{u}$,
%                l.side=right}{v1,v3}
%   \fmf{fermion}{v3,o1}
%   \fmf{fermion}{o2,v4}
%   \fmf{fermion,tension=.5,label=$t,,c,,u$,l.side=right}{v4,v2}
%   \fmf{fermion}{v2,i2}
%   \fmf{photon,tension=.2,label=$W^+$,l.side=left}{v1,v2}
%   \fmf{photon,tension=.2,label=$W^-$,l.side=right}{v3,v4}
%   \fmfdotn{v}{4}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph*}(40,25)
%     \fmfpen{thick}
%     \fmfleft{i1,i2}
%     \fmflabel{$\bar{b}$}{i1}
%     \fmflabel{$d$}{i2}
%     \fmfright{o1,o2}
%     \fmflabel{$\bar{d}$}{o1}
%     \fmflabel{$b$}{o2}
%     \fmf{fermion}{i1,v1}
%     \fmf{fermion,tension=.5,label=$\bar{t},,\bar{c},,\bar{u}$,
%                  l.side=right}{v1,v3}
%     \fmf{fermion}{v3,o1}
%     \fmf{fermion}{o2,v4}
%     \fmf{fermion,tension=.5,label=$t,,c,,u$,l.side=right}{v4,v2}
%     \fmf{fermion}{v2,i2}
%     \fmf{photon,tension=.2,label=$W^+$,l.side=left}{v1,v2}
%     \fmf{photon,tension=.2,label=$W^-$,l.side=right}{v3,v4}
%     \fmfdotn{v}{4}
%   \end{fmfgraph*}}
% \label{pg:newbox}
% This result is much nicer than the original.
%
% \end{examples}
% \end{fmffile}
%
% \begin{fmffile}{fmfsamp4}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Miscellaneous commands}
%
% \subsubsection{Graphs in graphs}
%
% \DescribeEnv{fmfsubgraph}
% \label{fmfsubgraph}
% \manindex{subgraphs}
% The |fmfsubgraph| environment contains a subgraph, for which the
% galleries will be placed inside the rectangle of width \meta{width}
% and height \meta{height}, with lower left corner
% at~$(\meta{x},\meta{y})$:
% \begin{quote}
% \begin{flushleft}
%   |\begin{fmfsubgraph}(|\meta{x}|,|\meta{y}|)(|^^A
%     \meta{width}|,|\meta{height}|)|\\
%   \qquad \meta{body}\\
%   |\end{fmfsubgraph}|
% \end{flushleft}
% \end{quote}
% The center and four corners are available
% as |c|, |nw|, |ne|, |sw| and |se| (for \emph{north-west} etc).
% Because of the restrictions on the overall size of the diagram in
% \MF, this environment will, mainly be useful for preparing
% transparencies with \MP.
%
% \begin{examples}{40mm}
%
% Here is a not very serious application of this feature:
% \begin{verbatim}
%   \def\subgraphsample#1{%
%     \fmfleftn{#1i}{2}%
%     \fmfrightn{#1o}{2}%
%     \fmf{plain}{#1i1,#1v1}%
%     \fmf{plain}{#1o1,#1v2}%
%     \fmf{plain}{#1o2,#1v3}%
%     \fmf{plain}{#1i2,#1v4}%
%     \fmfcyclen{plain,tension=0.3}{#1v}{4}}
%   \begin{fmfgraph}(40,30)
%     \subgraphsample{a}
%     \begin{fmfsubgraph}(.3w,.3h)(.4w,.4h)
%       \subgraphsample{b}
%     \end{fmfsubgraph}
%     \begin{fmfsubgraph}(.45w,.45h)(.1w,.1h)
%       \subgraphsample{c}
%     \end{fmfsubgraph}
%   \end{fmfgraph}
% \end{verbatim}
% \marginexample{%
%   \def\subgraphsample#1{%
%     \fmfleftn{#1i}{2}%
%     \fmfrightn{#1o}{2}%
%     \fmf{plain}{#1i1,#1v1}%
%     \fmf{plain}{#1o1,#1v2}%
%     \fmf{plain}{#1o2,#1v3}%
%     \fmf{plain}{#1i2,#1v4}%
%     \fmfcyclen{plain,tension=0.3}{#1v}{4}}
%   \begin{fmfgraph}(40,30)
%     \subgraphsample{a}
%     \begin{fmfsubgraph}(.3w,.3h)(.4w,.4h)
%       \subgraphsample{b}
%     \end{fmfsubgraph}
%     \begin{fmfsubgraph}(.45w,.45h)(.1w,.1h)
%       \subgraphsample{c}
%     \end{fmfsubgraph}
%   \end{fmfgraph}}
% More serious applications will use this feature to group together
% related diagrams and use other \MF{} drawing commands for
% graphical elements that are not available in the \LaTeX{} |picture|
% environment.
%
% \end{examples}
%
% \subsubsection{Reusing diagrams}
%
% \DescribeMacro{\fmfkeep}
% \DescribeMacro{\fmfreuse}
% After saving a pointer with |\fmfkeep{|\meta{name}|}| inside a
% |fmfgraph| or |fmfgraph*| environment, the diagram can be reused later
% by |\fmfreuse{|\meta{name}|}|.  This works across |fmffile|
% environments.
%
% Here's an example that uses centered |\parbox|es to place
% diagrams into equations.  The celebrated cancelation of quadratic
% divergencies in scalar selfenergies in supersymmetric field theories
% can be written as:
% \begin{verbatim}
% \begin{eqnarray}
%   \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{boson}
%     \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v,v,o}
%   \end{fmfgraph}} & \propto & \Lambda^2 \\
%   \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{fermion}
%     \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v1} \fmf{dashes}{v2,o}
%     \fmf{fermion,left,tension=.3}{v1,v2,v1}
%   \end{fmfgraph}} & \propto & \Lambda^2 \\
%   \parbox{20mm}{\fmfreuse{boson}} \quad + \quad
%   \parbox{20mm}{\fmfreuse{fermion}} & \propto & \ln\Lambda^2
% \end{eqnarray}
% \end{verbatim}
% The result is:
% \begin{eqnarray}
%   \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{boson}
%     \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v,v,o}
%   \end{fmfgraph}} & \propto & \Lambda^2 \\
%   \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{fermion}
%     \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v1} \fmf{dashes}{v2,o}
%     \fmf{fermion,left,tension=.3}{v1,v2,v1}
%   \end{fmfgraph}} & \propto & \Lambda^2 \\
%   \parbox{20mm}{\fmfreuse{boson}} \quad + \quad
%   \parbox{20mm}{\fmfreuse{fermion}} & \propto & \ln\Lambda^2
% \end{eqnarray}
%
% \subsubsection{Grouping}
%
% \DescribeEnv{fmfgroup}
% Make the enclosed |\fmfset| assignments local to this environment.
%
% \subsubsection{Changing parameters}
%
% \DescribeMacro{\fmfset}
% \manindex{parameters}
% This command can be used to change the parameters in
% table~\ref{tab:parameters} as follows:
% \begin{quote}
%   |\fmfset{|\meta{parameter}|}{|\meta{value}|}|
% \end{quote}
% Note that these parameters are not stored in the graph data
% structure for the individual vertices and arcs.  Instead the current
% values at the time of |\fmfdraw| are used.
%
% \DeleteShortVerb{\|}
% \MakeShortVerb{\"}
%
% \begin{table}[t]
%   \begin{center}
%     \begin{tabular}{|l|c|c|}\hline
%       Parameter      & Default         & Semantics                       \\\hline\hline
%       "thin"         &  1pt            & thin arcs                       \\\hline
%       "thick"        &  1.5"thin"      & thicker arcs                    \\\hline
%       "arrow_len"    &  4mm            & length of arrow head            \\\hline
%       "arrow_ang"    &  15             & opening angle of arrow head     \\\hline
%       "curly_len"    &  3mm            & length of one curl              \\\hline
%       "dash_len"     &  3mm            & length of one dash              \\\hline
%       "dot_len"      &  2mm            & distance of two dots            \\\hline
%       "wiggly_len"   &  4mm            & length of one wiggle            \\\hline
%       "wiggly_slope" &  60             & inclination of wiggles          \\\hline
%       "zigzag_len"   &  2mm            & length of a zig-zag period      \\\hline
%       "zigzag_width" &  2"thick"       & width of zig-zag lines          \\\hline
%       "decor_size"   &  5mm            & default size of vertex decors   \\\hline
%       "dot_size"     &  4"thick"       & diameter of dots                \\\hline
%     \end{tabular}
%   \end{center}
%   \caption{Available style parameters.}
%   \label{tab:parameters}
% \end{table}
%
% \DeleteShortVerb{\"}
% \MakeShortVerb{\|}
%
% \subsubsection{Shrinking}
%
% \DescribeEnv{fmfshrink}
% Shrink the linewidths and similar parameters in the enclosed section.
%
% \subsubsection{Debugging}
%
% \DescribeMacro{\fmftrace}
% \DescribeMacro{\fmfnotrace}
% \manindex{tracing}
% Enable and disable tracing of the layout decisions.  This is not
% necessarily printed in an intuitive format, but can be helpful for
% debugging.
%
% \DescribeMacro{\fmfdisplay}
% \DescribeMacro{\fmfstopdisplay}
% \manindex{displays, online}
% \manindex{online displays}
% Enable online displays.  |\fmfstopdisplay| will halt \MF{} everytime
% a graph is complete.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Multiple vertices and arcs}
%
% \DescribeEnv{fmffor}
% \manindex{looping}
% The environment
% \begin{quote}
% \begin{flushleft}
%   |\begin{fmffor}{|\meta{var}|}{|\meta{from}|}{|\meta{step}|}{|\meta{to}|}|\\
%   \qquad \meta{body}\\
%   |\end{fmffor}|
% \end{flushleft}
% \end{quote}
% executes \meta{body} multiple times, setting \meta{var} to
% $\meta{from}, \meta{from}+\meta{step}, \ldots, \meta{to}$.
% An application of this above \FMF{} feature is shown in
% figure~\ref{fig:euler-heisenberg}, which is generated by calling
% the \TeX{} macro
% \begin{verbatim}
%   \def\EulerHeisenberg#1{%
%      \begin{fmfgraph}(40,25)
%        \fmfpen{thick}
%        \fmfsurroundn{e}{#1}
%        \begin{fmffor}{n}{1}{1}{#1}
%          \fmf{photon}{e[n],i[n]}
%        \end{fmffor}
%        \fmfcyclen{fermion,tension=#1/8}{i}{#1}
%      \end{fmfgraph}}
% \end{verbatim}
% with the arguments 4, 6, 8, and 10, respectively.
% \def\EulerHeisenberg#1{%
%    \begin{fmfgraph}(40,25)
%      \fmfpen{thick}
%      \fmfsurroundn{e}{#1}
%      \begin{fmffor}{n}{1}{1}{#1}
%        \fmf{photon}{e[n],i[n]}
%      \end{fmffor}
%      \fmfcyclen{fermion,tension=#1/8}{i}{#1}
%    \end{fmfgraph}}
% \begin{figure}[t]
%   \begin{center}
%     \EulerHeisenberg{4} \qquad \EulerHeisenberg{6}
%   \end{center}
%   \begin{center}
%       \EulerHeisenberg{8} \qquad \EulerHeisenberg{10}
%   \end{center}
%   \caption{Higher order terms in the Euler-Heisenberg lagrangian.}
%   \label{fig:euler-heisenberg}
% \end{figure}
%
% Similarly, we can draw the diagrams from many particle physics in
% figures~\ref{fig:PP-rings} and~\ref{fig:PH-rings}:
% \begin{verbatim}
%   \def\PPRing#1{%
%     \begin{fmfgraph}(20,20)
%       \fmfsurroundn{v}{#1}
%       \fmfdotn{v}{#1}
%       \fmfcyclen{fermion,right=0.25}{v}{#1}
%       \fmfcyclen{fermion,left=0.25}{v}{#1}
%     \end{fmfgraph}}
%   \def\PHRing#1{%
%     \begin{fmfgraph}(20,20)
%       \fmfsurroundn{v}{#1}
%       \fmfdotn{v}{#1}
%       \fmfcyclen{fermion,right=0.25}{v}{#1}
%       \fmfrcyclen{fermion,right=0.25}{v}{#1}
%     \end{fmfgraph}}
% \end{verbatim}
% \def\PPRing#1{%
%   \begin{fmfgraph}(20,20)
%     \fmfsurroundn{v}{#1}
%     \fmfdotn{v}{#1}
%     \fmfcyclen{fermion,right=0.25}{v}{#1}
%     \fmfcyclen{fermion,left=0.25}{v}{#1}
%   \end{fmfgraph}}
% \def\PHRing#1{%
%   \begin{fmfgraph}(20,20)
%     \fmfsurroundn{v}{#1}
%     \fmfdotn{v}{#1}
%     \fmfcyclen{fermion,right=0.25}{v}{#1}
%     \fmfrcyclen{fermion,right=0.25}{v}{#1}
%   \end{fmfgraph}}
% \begin{figure}[t]
%   \begin{center}
%     \PPRing{3}\qquad\PPRing{4}\qquad\PPRing{5}\qquad\PPRing{6}
%   \end{center}
%   \caption{\label{fig:PP-rings}Particle-particle ring diagrams}
% \end{figure}
% \begin{figure}[t]
%   \begin{center}
%     \PHRing{3}\qquad\PHRing{4}\qquad\PHRing{5}\qquad\PHRing{6}
%   \end{center}
%   \caption{\label{fig:PH-rings}Particle-hole ring diagrams}
% \end{figure}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Immediate mode}
% \label{sec:immediate}
%
% In addition to the automatic layout of vertices, \FMF{} features an
% immediate mode, in which \FMF's drawing commands operate directly on
% \MF's |pair|s and |path|s.  You might want to consult The \MF{}
% Book~\cite{MF} or the \MP{} manual~\cite{MetaPost} for further
% information on the available |path| expressions.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Arcs}
% \label{sec:fmfi}
%
% \DescribeMacro{\fmfi}
% \manindex{arcs}
% Immediate mode's brother of |\fmf|.
% \begin{quote}
%   |\fmfi{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$^^A
%     |}{|\meta{p}|}|
% \end{quote}
% draws a line of
% style \meta{style} on path \meta{p}.  Use the |vpath| function in
% \meta{p} (\emph{after} |\fmffreeze|!) to access the \MF{} |path|
% connecting two vertices:
% |vpath|$[$\meta{tag}$]$|(|\meta{from}|,|\meta{to}|)|.  The optional
% numeric \meta{tag} can be used together with a matching |tag| option
% to |\fmf| to disambiguate arcs that connect the same vertices. 
% You have to prepend each name of a vertex in |vpath|'s arguments
% with two underscores (e.g.~|v1| becomes |__v1|).  This is necessary
% for avoiding nameclashes with some reserved words in \MF{}
% (\textit{sparks} in DEK's terminology).
% 
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Vertices}
% \label{sec:fmfiv}
%
% \DescribeMacro{\fmfiv}
% \manindex{vertices}
% Immediate mode's brother of |\fmfv|.
% \begin{quote}
%   |\fmfiv{|\meta{shape}$[$|=|\meta{val}$][$|,|\meta{opt}^^A
%     $[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v}|}|
% \end{quote}
% draws a vertex at position \meta{v}.  Note that here \meta{v} is a
% \MF{} |pair| and \emph{not} a \FMF{} vertex name.  The former's
% equivalent of the latter can be accessed (\emph{after}
% |\fmffreeze|!) with the |vloc| function: |vloc(|\meta{vertex}|)|.
% Again, you have to prepend the name of the vertex in |vloc|'s
% argument with two underscores (e.g.~|v1| becomes |__v1|).
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Declarations}
% 
% \DescribeMacro{\fmfipath}
% The argument(s) are declared \MF{} |path|s.
%
% \DescribeMacro{\fmfipair}
% The argument(s) are declared \MF{} |pair|s (coordinates).
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Assignments}
% 
% \DescribeMacro{\fmfiequ}
% Establish equality for the two arguments,
% i.e.~|\fmfiequ{lval}{rval}| translates to |lval=rval|.
%
% \DescribeMacro{\fmfiset}
% Assign the second argument to the first,
% i.e.~|\fmfiset{lval}{rval}| translates to |lval:=rval|.
%
% Specifying equality of two variables is a very different operation
% from assignment in \MF{}.  See The \MF{} Book~\cite{MF} for details
% on \MF's builtin equation solver.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Examples}
% 
% Here is a non-trivial example of immediate mode, which shows some
% useful tricks.  The non-trivial aspect of the diagram in question is
% that it has lines broken in two, denoting particles coupling to a
% condensate.
%
% \begin{examples}{40mm}
%
% We start the diagram with a skeleton (the |phantom| lines are shown
% as thin lines for clarity): 
% \begin{verbatim}
% \fmfleft{i} 
% \fmfright{o}
% \fmf{dots}{i,v1}
% \fmf{dots}{v2,o}
% \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
% \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
% \fmfdot{v1,v2}
% \fmfposition
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(40,30)
%     \fmfpen{thick}
%     \fmfleft{i} 
%     \fmfright{o}
%     \fmf{dots}{i,v1}
%     \fmf{dots}{v2,o}
%     \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
%     \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
%     \fmfposition
%     \fmfdraw
%     \fmfpen{.5thin}
%     \fmf{plain,left}{v1,v2}
%     \fmf{plain,left}{v2,v1}
%   \end{fmfgraph}}
% Add the fermions to the skeleton
% \begin{verbatim}
% \fmfipath{p[]}
% \fmfiset{p1}{vpath1(__v1,__v2)}
% \fmfiset{p2}{vpath2(__v2,__v1)}
% \fmfi{fermion}{subpath (0,length(p1)/3) of p1}
% \fmfi{fermion}{subpath (2length(p1)/3,length(p1)) of p1}
% \fmfi{fermion}{subpath (0,length(p2)/3) of p2}
% \fmfi{fermion}{subpath (2length(p2)/3,length(p2)) of p2}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(40,30)
%     \fmfpen{thick}
%     \fmfleft{i} 
%     \fmfright{o}
%     \fmf{dots}{i,v1}
%     \fmf{dots}{v2,o}
%     \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
%     \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
%     \fmfdot{v1,v2}
%     \fmfposition
%     \fmfipath{p[]}
%     \fmfiset{p1}{vpath1(__v1,__v2)}
%     \fmfiset{p2}{vpath2(__v2,__v1)}
%     \fmfi{fermion}{subpath (0,length(p1)/3) of p1}
%     \fmfi{fermion}{subpath (2length(p1)/3,length(p1)) of p1}
%     \fmfi{fermion}{subpath (0,length(p2)/3) of p2}
%     \fmfi{fermion}{subpath (2length(p2)/3,length(p2)) of p2}
%   \end{fmfgraph}}
% Add condensates and a gluon
% \begin{verbatim}
% \def\cond#1#2{%
%   \fmfiv{d.sh=cross,d.ang=#1,d.siz=5thick}{#2}}
% \cond{30}{point length(p1)/3 of p1}
% \cond{-30}{point 2length(p1)/3 of p1}
% \cond{30}{point length(p2)/3 of p2}
% \cond{-30}{point 2length(p2)/3 of p2}
% \fmfi{gluon}{point length(p1)/10 of p1
%                -- point 11length(p1)/12 of p1}
% \def\vert#1{%
%   \fmfiv{d.sh=circle,d.f=1,d.siz=2thick}{#1}}
% \vert{point length(p1)/12 of p1}
% \vert{point 11length(p1)/12 of p1}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(40,30)
%     \fmfpen{thick}
%     \fmfleft{i} 
%     \fmfright{o}
%     \fmf{dots}{i,v1}
%     \fmf{dots}{v2,o}
%     \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
%     \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
%     \fmfdot{v1,v2}
%     \fmfposition
%     \fmfipath{p[]}
%     \fmfiset{p1}{vpath1(__v1,__v2)}
%     \fmfiset{p2}{vpath2(__v2,__v1)}
%     \fmfi{fermion}{subpath (0,length(p1)/3) of p1}
%     \fmfi{fermion}{subpath (2length(p1)/3,length(p1)) of p1}
%     \fmfi{fermion}{subpath (0,length(p2)/3) of p2}
%     \fmfi{fermion}{subpath (2length(p2)/3,length(p2)) of p2}
%   \def\cond#1#2{\fmfiv{d.sh=cross,d.ang=#1,d.siz=5thick}{#2}}
%     \cond{30}{point length(p1)/3 of p1}
%     \cond{-30}{point 2length(p1)/3 of p1}
%     \cond{30}{point length(p2)/3 of p2}
%     \cond{-30}{point 2length(p2)/3 of p2}
%     \fmfi{gluon}{point length(p1)/10 of p1 -- point 11length(p1)/12 of p1}
%   \def\vert#1{\fmfiv{d.sh=circle,d.f=1,d.siz=2thick}{#1}}
%     \vert{point length(p1)/12 of p1}
%     \vert{point 11length(p1)/12 of p1}
%   \end{fmfgraph}}
%
% Here's an interesting abuse of \FMF{} (see the next section for
% |\fmfcmd|):
%   \begin{verbatim}
%   \begin{fmfgraph*}(40,40)
%     \fmfipair{o,xm,xp,ym,yp}
%     \fmfiequ{o}{(.5w,.1h)}
%     \fmfiequ{xm}{(0,.1h)}
%     \fmfiequ{xp}{(w,.1h)}
%     \fmfiequ{ym}{(.5w,0)}
%     \fmfiequ{yp}{(.5w,h)}
%     \fmfiv{l=$x$,l.a=-135,l.d=2mm}{xp}
%     \fmfiv{l=$y=x^2$,l.a=-135,l.d=2mm}{yp}
%     \fmfpen{thin}
%     \fmfcmd{draw xm--xp; draw ym--yp;}
%     \fmfpen{thick}
%     \fmfiequ{xs}{xpart(xp-o)}
%     \fmfiequ{ys}{ypart(yp-o)}
%     \fmfcmd{draw (o + (-xs,ys)) for n = -9 upto 10:
%         --(o + (xs*(n/10),ys*((n/10)**2)))
%       endfor;}
%   \end{fmfgraph*}
%   \end{verbatim}
%   \marginexample{%
%     \begin{fmfgraph*}(40,40)
%       \fmfipair{o,xm,xp,ym,yp}
%       \fmfiequ{o}{(.5w,.1h)}
%       \fmfiequ{xm}{(0,.1h)}
%       \fmfiequ{xp}{(w,.1h)}
%       \fmfiequ{ym}{(.5w,0)}
%       \fmfiequ{yp}{(.5w,h)}
%       \fmfiv{l=$x$,l.a=-135,l.d=2mm}{xp}
%       \fmfiv{l=$y=x^2$,l.a=-135,l.d=2mm}{yp}
%       \fmfpen{thin}
%       \fmfcmd{draw xm--xp; draw ym--yp;}
%       \fmfpen{thick}
%       \fmfiequ{xs}{xpart(xp-o)}
%       \fmfiequ{ys}{ypart(yp-o)}
%       \fmfcmd{draw (o + (-xs,ys)) for n = -9 upto 10:
%           --(o + (xs*(n/10),ys*((n/10)**2)))
%         endfor;}
%     \end{fmfgraph*}}
%
% \end{examples}
%
% Finally, for the curious, here is how to draw the circular gluons in
% figure~\ref{fig:gluons}:
% \begin{verbatim}
%   \fmfi{gluon}{fullcircle scaled .5w shifted (.5w,.5h)}
%   \fmfi{gluon}{reverse fullcircle scaled .5w shifted (.5w,.5h)}
% \end{verbatim}
%
% \begin{figure}[t]
%   \begin{center}
%     \begin{fmfgraph}(40,40)
%       \fmfi{gluon}{fullcircle scaled .5w shifted (.5w,.5h)}
%     \end{fmfgraph}
%     \qquad
%     \begin{fmfgraph}(40,40)
%       \fmfi{gluon}{reverse fullcircle scaled .5w shifted (.5w,.5h)}
%     \end{fmfgraph}
%   \end{center}
%   \caption{Circular gluons.}
%   \label{fig:gluons}
% \end{figure}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Raw \MF}
%
% Some more advanced features of \FMF{} are more conveniently
% accessed through raw \MF{} commands.  This can either be
% achieved by preparing a \MF{} input file or by using |\fmfcmd|
% extensively.  The latter apprach is usally more convenient.
%
% \DescribeMacro{\fmfcmd}
% The |\fmfcmd| macro writes its argument into the \MF{} input
% file generated by \FMF.  While some experience in using
% \MF{} doesn't hurt here, this approach can simplify the
% production of complex diagrams considerably.  Note that \emph{no}
% semicolon is appended, the user has to provide it explicitely.
%
% \subsubsection{Extending \FMF}
% \label{sec:extensions}
%
% \manindex{extensions}
% \manindex{defining new styles}
% \manindex{styles, defining new}
% A prominent example for using raw \MF{} is provided by the option to
% add new styles for arcs.  There is of course always one more style
% that \emph{must} be added to the default list.  But increasing this
% list without bounds will eventually slow down \FMF{} and increase
% its memory requirements.  It is therefore better to allow users to
% define their own styles.  This is done with the \MF{} macro
% |style_def|, which defines a macro that will be called to do the
% drawing and registers this macro with \FMF{} so that it can be used
% in the first argument to |\fmf|.
%
% The macro takes one argument of type |path| and is responsible for
% drawing the arc on this path. If \MP's color functionality is to be
% used, the color aware functions |cdraw|, |cfill|, |cfilldraw|,
% |ccutdraw| and |cdrawdot| should be used instead of |draw|, etc.
%
% \begin{examples}{40mm}
%
% \manindex{crossed arcs}
% After the following |style_def|, a new style |crossed| will be
% available:
% \begin{verbatim}
%   \fmfcmd{%
%     vardef cross_bar (expr p, len, ang) =
%      ((-len/2,0)--(len/2,0))
%         rotated (ang + angle direction length(p)/2 of p)
%         shifted point length(p)/2 of p
%     enddef;
%     style_def crossed expr p =
%       cdraw p;
%       ccutdraw cross_bar (p, 5mm,  45);
%       ccutdraw cross_bar (p, 5mm, -45)
%     enddef;}
% \end{verbatim}
% \fmfcmd{%
%   vardef cross_bar (expr p, len, ang) =
%    ((-len/2,0)--(len/2,0))
%       rotated (ang + angle direction length(p)/2 of p)
%       shifted point length(p)/2 of p
%   enddef;
%   style_def crossed expr p =
%     cdraw p;
%     ccutdraw cross_bar (p, 5mm,  45);
%     ccutdraw cross_bar (p, 5mm, -45)
%   enddef;}
% it can be used just like any other style:
% \begin{verbatim}
%   \fmfleft{i} 
%   \fmfright{o}
%   \fmf{plain}{i,v,o}
%   \fmf{crossed}{v,v}
%   \fmfdot{v}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(40,30)
%     \fmfpen{thick}
%     \fmfleft{i} 
%     \fmfright{o}
%     \fmf{plain}{i,v,o}
%     \fmf{crossed}{v,v}
%     \fmfdot{v}
%   \end{fmfgraph}}
% And here is an (esthetically questionable!) attempt at wiggly lines
% with arrows:
% \begin{verbatim}
%   \fmfcmd{%
%      style_def wiggly_arrow expr p =
%        cdraw (wiggly p);
%        shrink (2);
%          cfill (arrow p);
%        endshrink;
%      enddef;}
% \end{verbatim}
% \fmfcmd{%
%    style_def wiggly_arrow expr p =
%      cdraw (wiggly p);
%      shrink (2);
%        cfill (arrow p);
%      endshrink;
%    enddef;}
% \marginexample{%
%   \begin{fmfgraph}(40,10)
%     \fmfpen{thick}
%     \fmfleft{i} 
%     \fmfright{o}
%     \fmf{wiggly_arrow}{i,o}
%   \end{fmfgraph}}
% Note how the |shrink| macro (which is the \MF{} equivalent of the
% |fmfshrink| environment) is used to temporarily double the
% dimensions of the arrowhead which is constructed by the |arrow|
% macro.
%
% In particular theorists beyond the standard model are likely to need
% \emph{a lot} of different line styles.  The aficionados of majorana
% neutrinos might find the following two useful:
% \begin{verbatim}
%   \fmfcmd{%
%     style_def majorana expr p =
%       cdraw p;
%       cfill (harrow (reverse p, .5));
%       cfill (harrow (p, .5))
%     enddef;
%     style_def alt_majorana expr p =
%       cdraw p;
%       cfill (tarrow (reverse p, .55));
%       cfill (tarrow (p, .55))
%     enddef;}
% \end{verbatim}
% \fmfcmd{%
%   style_def majorana expr p =
%     cdraw p;
%     cfill (harrow (reverse p, .5));
%     cfill (harrow (p, .5))
%   enddef;
%   style_def alt_majorana expr p =
%     cdraw p;
%     cfill (tarrow (reverse p, .55));
%     cfill (tarrow (p, .55))
%   enddef;}
% \marginexample{%
%   \begin{fmfgraph}(40,30)
%     \fmfpen{thick}
%     \fmfleftn{i}{2} \fmfrightn{o}{2}
%     \fmf{majorana}{i1,v1,o1}
%     \fmf{alt_majorana}{i2,v2,o2}
%     \fmfn{boson}{v}{2}
%     \fmfdotn{v}{2}
%   \end{fmfgraph}}
% Note the use of the |harrow| and |tarrow| functions which return an
% arrowhead on the given fraction of the path, with reference points
% at the head (|harrow|) or tail (|tarrow|).  The |arrow| function
% used above is equivalent to |marrow(p,.5)|, which has the reference
% point at the center of the arrowhead.  Having the three different
% reference point available is important for supporting arcs of
% substantially differing lengths.
%
% A problem of the current implementation is that the endpoints of
% double lines don't match smoothly at vertices:
% \begin{verbatim}
%   \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
%   \fmfpolyn{shaded}{z}{4}
%   \fmf{dbl_plain_arrow}{l2,z3}
%   \fmf{dbl_plain_arrow}{l1,z4}
%   \fmf{dbl_plain_arrow}{z1,r1}
%   \fmf{dbl_plain_arrow}{z2,r2}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(40,25)
%     \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
%     \fmfpolyn{shaded}{z}{4}
%     \fmf{dbl_plain_arrow}{l2,z3}
%     \fmf{dbl_plain_arrow}{l1,z4}
%     \fmf{dbl_plain_arrow}{z1,r1}
%     \fmf{dbl_plain_arrow}{z2,r2}
%   \end{fmfgraph}}
% One way around is to add dots of the right size at the vertices
% \emph{after} the arcs have been drawn.
% \begin{verbatim}
%   \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
%   \fmfpolyn{shaded}{z}{4}
%   \fmf{dbl_plain_arrow}{l2,z3}
%   \fmf{dbl_plain_arrow}{l1,z4}
%   \fmf{dbl_plain_arrow}{z1,r1}
%   \fmf{dbl_plain_arrow}{z2,r2}
%   \fmffreeze\fmfdraw
%   \fmfvn{d.siz=2thick,d.sh=circle}{z}{4}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(40,25)
%     \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
%     \fmfpolyn{shaded}{z}{4}
%     \fmf{dbl_plain_arrow}{l2,z3}
%     \fmf{dbl_plain_arrow}{l1,z4}
%     \fmf{dbl_plain_arrow}{z1,r1}
%     \fmf{dbl_plain_arrow}{z2,r2}
%     \fmffreeze\fmfdraw
%     \fmfvn{d.siz=2thick,d.sh=circle}{z}{4}
%   \end{fmfgraph}}
% Without the |\fmffreeze\fmfdraw|, the arcs would ``know'' about the
% dots and would be shortened.
%
% A more elegant solution is to define line styles with dots at the
% head,
% \begin{verbatim}
%   \fmfcmd{vardef endpoint_dot expr p =
%     save oldpen; pen oldpen;
%     oldpen := currentpen;
%     pickup oldpen scaled 3;
%     cdrawdot p;
%     pickup oldpen;
%   enddef;}
%   \fmfcmd{style_def hd_double expr p =
%     draw_double p;
%     endpoint_dot point infinity of p;
%   enddef;}
%   \fmfcmd{style_def hd_dbl_plain_arrow expr p =
%     draw_hd_double p;
%     shrink (1.5);
%       cfill (arrow p);
%     endshrink;
%   enddef;}
% \end{verbatim}
% \fmfcmd{%
% vardef endpoint_dot expr p =
%   save oldpen; pen oldpen;
%   oldpen := currentpen;
%   pickup oldpen scaled 3;
%   cdrawdot p;
%   pickup oldpen;
% enddef;}
% \fmfcmd{%
% style_def hd_double expr p =
%   draw_double p;
%   endpoint_dot point infinity of p;
% enddef;}
% \fmfcmd{%
% style_def hd_dbl_plain_arrow expr p =
%   draw_hd_double p;
%   shrink (1.5);
%     cfill (arrow p);
%   endshrink;
% enddef;}
% tail
% \begin{verbatim}
%   \fmfcmd{style_def td_double expr p =
%     draw_double p;
%     endpoint_dot point 0 of p;
%   enddef;}
%   \fmfcmd{style_def td_dbl_plain_arrow expr p =
%     draw_td_double p;
%     shrink (1.5);
%       cfill (arrow p);
%     endshrink;
%   enddef;}
% \end{verbatim}
% \fmfcmd{%
% style_def td_double expr p =
%   draw_double p;
%   endpoint_dot point 0 of p;
% enddef;}
% \fmfcmd{%
% style_def td_dbl_plain_arrow expr p =
%   draw_td_double p;
%   shrink (1.5);
%     cfill (arrow p);
%   endshrink;
% enddef;}
% or both
% \begin{verbatim}
%   \fmfcmd{style_def htd_double expr p =
%     draw_double p;
%     endpoint_dot point 0 of p;
%     endpoint_dot point infinity of p;
%   enddef;}
%   \fmfcmd{style_def htd_dbl_plain_arrow expr p =
%     draw_htd_double p;
%     shrink (1.5);
%       cfill (arrow p);
%     endshrink;
%   enddef;}
% \end{verbatim}
% \fmfcmd{%
% style_def htd_double expr p =
%   draw_double p;
%   endpoint_dot point 0 of p;
%   endpoint_dot point infinity of p;
% enddef;}
% \fmfcmd{%
% style_def htd_dbl_plain_arrow expr p =
%   draw_htd_double p;
%   shrink (1.5);
%     cfill (arrow p);
%   endshrink;
% enddef;}
% which can be used as follows to give an equivalent result:
% \begin{verbatim}
%   \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
%   \fmfpolyn{shaded}{z}{4}
%   \fmf{hd_dbl_plain_arrow}{l2,z3}
%   \fmf{hd_dbl_plain_arrow}{l1,z4}
%   \fmf{td_dbl_plain_arrow}{z1,r1}
%   \fmf{td_dbl_plain_arrow}{z2,r2}
% \end{verbatim}
% \marginexample{%
%   \begin{fmfgraph}(50,30)
%     \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
%     \fmfpolyn{shaded}{z}{4}
%     \fmf{hd_dbl_plain_arrow}{l2,z3}
%     \fmf{hd_dbl_plain_arrow}{l1,z4}
%     \fmf{td_dbl_plain_arrow}{z1,r1}
%     \fmf{td_dbl_plain_arrow}{z2,r2}
%   \end{fmfgraph}}
% 
% \end{examples}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Common traps, trouble shooting and frequently asked
%    questions (FAQs)} 
%
% \subsubsection{\texttt{! Value is too large}}
% \label{sec:value-to-large}
% The following will be one of the most frequent errors:
% \begin{verbatim}
%   ! Value is too large (4097).
%   <recently read> ;
%
%   beginchar->...rdp:=(EXPR3);w:=hround(charwd*hppp);
%                                                     h:=...
%   l.685 ...char(64, 40*2.84526pt#, 25*2.84526pt#, 0)
%                                                     ;
%   ?
% \end{verbatim}
% It can have one of two causes:
% \begin{itemize}
%   \item{} \MF{} was invoked without specifying the |mode|.
%     This case is easily fixed by looking up the correct \MF{} mode
%     in the file |modes.mf| that comes with the \MF{} distribution.
%     This mode \emph{must} be specified on the
%     command line as |\mode:=laserjet| for HP Laserjets at 300dpi, as
%     |\mode:=ljfour| for HP Laserjets at 600dpi, as 
%     |\mode:=nexthi| for NeXT laser printers at 400dpi, etc,
%     just to name three of the more common laser printers in the
%     physics community.
%   \item{} The diagrams are too large for the printer at hand.
%     This case is actually not very likely, because even at 1200dpi
%     the diagrams can be as large as 86mm.  For the popular
%     laserprinter resolution of 300dpi, even 346mm are possible.
%     Last time I checked, the diagrams for this manual could be
%     generated for a \textit{Linotype Linotronic 300} at 2540dpi
%     (|mode:=linosuper|), but failed in the standard |proof| mode at
%     2601.72dpi.\footnote{% 
%       It would be trivial to shrink the diagrams by 1\%\ to make
%       them work in \texttt{proof} mode (accidentally, the largest
%       diagram is 40mm wide, while 4096/2601.72dpi corresponds to
%       39.99mm). However, I prefer \MF{} to give an error message if
%       the user forgot to specify the mode.  It is much more obscure
%       when \MF{} works without errors but the \texttt{dvi} driver
%       fails to find the generated bitmap file.}
%     In fact, in the current |modes.mf| file, the
%     \textit{Chelgraph IBX} at 9600dpi and the \textit{Alphatype CRS}
%     at $5333+1/3$dpi are the only typesetters that can not be used
%     to typeset this manual.\footnote{%
%       If someone wants to use \FMF{} with one of these high end
%       typesetters, I would be glad to try to help them out with
%       kludges.}
% \end{itemize}
%
% \subsubsection{Diagrams in the document are never updated}
% \label{sec:out-of-date}
% There are two known reasons why diagrams may not be updated the
% document after the source file has been changed:
% \begin{itemize}
%   \item Some |dvi| file previewers (e.g.~|xdvi(1)| under UNIX) do
%     \emph{not} reread font information if the |tfm| or |pk| files
%     have changed, even though they reread the |dvi| file if it has
%     changed.  Therefore you have to restart such previewers if you
%     have made changes in diagrams to see these changes on the screen.
%   \item Some |dvi| drivers (e.g.~|dvips(1)| under UNIX) do not work
%     with the |gf| files directly, but convert them with an external
%     program to |pk| format first.  On later occasions, the |dvi|
%     driver will then use the |pk| file which is out of date with
%     respect to the sources and the |gf| file.  The only known fix is
%     to delete the |pk| fils before running the |dvi| driver.
% \end{itemize}
%
% \subsubsection{Disgrams show up in the wrong spot}
% If you are using \FMF{} with \LaTeX's |\includeonly| feature, you
% should watch out for the following situation:
% \begin{verbatim}
% \includeonly{bar1,bar3}
% \begin{fmffile}{foograph}
% \include{bar1}
% \include{bar2}
% \include{bar3}
% \end{fmffile}
% \end{verbatim}
% where |bar1.tex| defines graph \#1, |bar2.tex| graph \#2 and
% |bar3.tex| defines graph \#3.  If you now proceeded to add graphs to
% |bar1.tex|, you will notice that a second graph is accepted, but
% instead of the new third graph, the old graph \#3 appears.  What
% happens is that \LaTeX{} stores the value of the counter for
% |fmfgraph|s in each |.aux| file so that because |bar2.tex| is not
% processed, this counter is always reset to 3 at the beginning of
% |bar3.tex|. 
%
% Even though this situation appears to be contrived, it actually
% occured in real life applications and the resulting error is very
% confusing.
%
% The only ``fix'' for this problem would be to use a private counter
% behind \LaTeX's back.  Unfortunately, it appears that this will
% violate the \emph{principle of minimal surprise} even more.  It is
% therefore usually a good idea to reprocess the complete document
% when the number of graphs has changed in an |\include|d file.  The
% other solution is to have a separate |fmfgraph| environment for each
% |\include|d file.
%
% \subsubsection{Spurious labels show up}
% If spurious labels show up in your diagrams, this is most likely
% caused by old label files (e.g.~|foo.t|\meta{n}) still lying
% around.  Just delete these files and rerun \TeX{} and \MF{} (or
% \MP{} respectively).
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Known bugs}
%
% \subsubsection{Chaotic manual}
% This is being worked on.  It should probably be rewritten from
% scratch, but I don't have enough time at the moment (this is a spare
% time activity).
%
% \subsubsection{Delayed error messages}
% This can't be fixed.  The problem is that errors can manifest
% themselves only a long time after the corresponding source line has
% been read.  Since \TeX{} doesn't allow to access the current source
% line number, there is no way to store this information along with
% the other information on the graph.
% I can only hope to have enough sanity checks in
% place some day that error messages from \MF{} won't occur.
% 
% \subsubsection{Multiple tadpoles}
% Currently, \FMF{} will not layout multiple tadpoles at a single
% vertex automatically.  This could be fixed in principle, but these
% fixes would cause other problems which are more inconvenient than
% having to lay out tadpoles manually.
%
% \subsubsection{Hard limits}
% Currently the most severe limitation lies in the size of the
% generated pictures.  The largest number \MF{} can represent
% internally is~4095.99998 and this is also the largest value any
% coordinate measured in pixels can assume.  At the most popular
% laserprinter resolution of~300 dots per inch (dpi), this corresponds
% to a horizontal and vertical extension of about~346mm, which is
% plenty and we're more likely to hit the internal limits on the
% complexity of a picture.  However, at the proof mode resolution
% of~2601.72dpi, this is reduced to slightly less than~40mm and we're
% running the risk of arithmetic overflow in internal calculations much
% earlier.
%
% There are two potential solutions of different scope and complexity:
% \begin{itemize}
%   \item{} Since John Hobby's \MP{} is now available without a
%     non-disclosure agreement from AT\&T, one solution is to replace
%     \MF{} by \MP, which doesn't suffer from the size
%     limitations.
%     This comes with a small price paid in reduced portability of the
%     generated output, but as already stated above in the case of
%     |axodraw|, the ubiquity of PostScript printers (and the free
%     GhostScript interpreter) makes this a minor point.
%   \item{} The more ambitious solutions would be \emph{virtual graphs},
%     i.e.~graphs which are larger than the current limit enforced
%     by numeric overflow at higher resolutions.  This could be
%     implemented by calculating the layout of a miniature graph and
%     afterwards distributing the full graph among several \MF{}
%     characters. 
% \end{itemize}
%
% \end{fmffile}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section*{Acknowledgements}
%
% I am most grateful to Wolfgang Kilian, who pushed \FMF's predecessor
% |feynman.mf| to its limits~\cite{Kil94}.  Discussions with him
% triggered a lot of good ideas.  Thanks also to my students and the
% people on \emph{The Net} for suggestions, portability fixes and for
% volunteering as guinea pigs.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{thebibliography}{99}
%   \bibitem{TeX} Donald E.~Knuth, \textit{The \TeX{}book},
%      Addison-Wesley, Reading MA, 1986.
%   \bibitem{LaTeX} Leslie Lamport, \textit{\LaTeX{} --- A
%     Documentation Preparation System},
%     Addison-Wesley, Reading MA, 1985.
%   \bibitem{LaTeX-Companion} Michel Goosens, Frank Mittelbach, and
%     Alexander Samarin, \textit{The \LaTeX{} Companion},
%     Addison-Wesley, Reading MA, 1994.
%   \bibitem{MF} Donald E.~Knuth, \textit{The \MF{}book},
%      Addison-Wesley, Reading MA, 1986.
%   \bibitem{MetaPost} John D.~Hobby, \textit{A User's Manual for
%     \MP}, Computer Science Report \#162, AT\&T Bell
%     Laboratories, April 1992.
%   \bibitem{CPC} Thorsten Ohl, 
%     Comp.~Phys.~Comm.~\textbf{90} (1995) 340.
%   \bibitem{CNL} Thorsten Ohl, 
%     CERN Computer Newsletter~\textbf{220} (1995) 22;
%     \textbf{221} (1995) 46; \textbf{222} (1996) 24.
%   \bibitem{levine} Micheal J.~S.~Levine,
%     Comp.~Phys.~Comm.~\textbf{58} (1990) 181.
%   \bibitem{axodraw} Jos Vermaseren,
%     Comp.~Phys.~Comm.~\textbf{83} (1994) 45.
%     \texttt{axodraw} is available from CTAN
%     (cf.~p.~\pageref{pg:CTAN}), in the  \texttt{graphics} directory.
%     ^^A Comp.~Phys.~Comm.~\textbf{??} (1995) ???.
%   \bibitem{mfpic} Thomas E.~Leathrum, \texttt{mfpic}, available from
%     CTAN (cf.~p.~\pageref{pg:CTAN}), in the \texttt{graphics}
%     directory.
%   \bibitem{madgraph} Tim Stelzer and Bill Long,
%     Comp.~Phys.~Comm.~\textbf{81} (1994) 357.
%   \bibitem{Kil94} Wolfgang Kilian, Doctoral Thesis, Technical
%     University Darmstadt, 1994.
%   \bibitem{Lambda} Alan Jeffrey, \textit{Lists in \TeX's Mouth},
%     TUGboat 199?.
% \end{thebibliography}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section*{Distribution}
% \label{sec:distribution}
%
% \FMF{} is available by anonymous internet ftp from any of the
% Comprehensive \TeX{} Archive Network (CTAN) hosts 
% \label{pg:CTAN}
% \begin{quote}
%   |ftp.shsu.edu|, |ftp.tex.ac.uk|, |ttp.dante.de|
% \end{quote}
% in the directory
% \begin{quote}
%   |macros/latex/contrib/supported/feynmf|
% \end{quote}
% It is also available from the host
% \begin{quote}
%   |crunch.ikp.physik.th-darmstadt.de|
% \end{quote}
% in the directory
% \begin{quote}
%   |pub/ohl/feynmf|
% \end{quote}
% Unsupported snapshots of my work in progress are provided as
% \begin{quote}
%   |pub/ohl/feynmf.versions/feynmf-current.tar.gz|
% \end{quote}
% There are two mailing lists
% \begin{quote}
% \begin{flushleft}
%   |feynmf-announce@crunch.ikp.physik.th-darmstadt.de|\\
%   |feynmf-bugs@crunch.ikp.physik.th-darmstadt.de|
% \end{flushleft}
% \end{quote}
% open for subscription.  The former should carry only important
% announcements, of new versions in particular.  To subscribe, send
% mail to the (electronic) mailing list manager
% \begin{quote}
%   |majordomo@crunch.ikp.physik.th-darmstadt.de|
% \end{quote}
% and \emph{not} to the lists itself.  The following commands (on a
% line in the body of the mail, not in the subject) are useful:
% \begin{quote}
% \begin{flushleft}
%   |subscribe feynmf-announce|\\
%   |unsubscribe feynmf-announce|\\
%   |help|
% \end{flushleft}
% \end{quote}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \StopEventually{\PrintIndex\PrintChanges}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \newpage
% \section{\TeX{} macros}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Startup}
%
% It's is good practice to identify this version of the document style
% option.  We do this by parsing an RCS |Id| string and storing the
% result in the conventional \TeX{} control sequences:
% \changes{v0.1}{1994/05/19}{%
%   Don't loose on {\tt RCS} strings even iff the dollar signs have
%   been removed.}
% \changes{v0.8}{1995/02/18}{\LaTeX~2.09 compatibility}
% \changes{v0.98}{1995/05/01}{%
%   Revise version control: allow for manual intervention to replace
%   the inconvenient RCS revision numbers by version numbers.}
%    \begin{macrocode}
%<*style>
\def\fileversion{v1.08}
%<!209>\NeedsTeXFormat{LaTeX2e}
{\def\RCS#1#2\endRCS{%
  \ifx$#1%
    \@RCS $#2 \endRCS
  \else
    \@RCS $*: #1#2$ \endRCS
  \fi}%
 \def\@RCS $#1: #2,v #3 #4 #5 #6 #7$ \endRCS{%
   \gdef\filename{#2}%
   \gdef\filerevision{#3}%
   \gdef\filedate{#4}%
   \gdef\filemaintainer{#6}}%
\RCS $Id: feynmf.dtx,v 1.30 1996/12/02 09:20:36 ohl Exp $ \endRCS}%
%    \end{macrocode}
%
% And now the standard procedure:
% \changes{v0.4}{1994/05/27}{%
%   \MP{} support: identification part, include
%   \texttt{graphicx} and pass options.}
%    \begin{macrocode}
%<*!209>
%<*!mp>
\ProvidesPackage{feynmf}[\filedate\space\fileversion\space
  LaTeX/Metafont Feynman Diagram Package (\filemaintainer)]
%</!mp>
%<*mp>
\ProvidesPackage{feynmp}[\filedate\space\fileversion\space
  LaTeX/MetaPost Feynman Diagram Package (\filemaintainer)]
%</mp>
%</!209>
%    \end{macrocode}
% Compatibiliy with sources written for \FMF{} \emph{before}
% version~1.03, where macros in labels had to be protected by
% |\noexpand|.  The |\fmf@noexpandoff| macro will be used of
% page~\pageref{pg:usenoexpandoff}.  The default is a no-op.
% \label{pg:defnoexpandoff}
% \changes{v1.05}{1996/05/06}{%
%   Provide option \texttt{pre-1.03} for processing old files.}
%    \begin{macrocode}
%<*!209>
\let\fmf@noexpandoff\relax
\DeclareOption{pre-1.03}{%
  \PackageWarning{feynmf}{%
    Pre v1.03 compatibility can clash with font loading}
  \def\fmf@noexpandoff{\let\noexpand\relax}}
%    \end{macrocode}
% Alow the user to override the default interaction mode
% |\errorstopmode|.  We have to change modes temorarily on
% page~\pageref{pg:useinteractionmode} below and \TeX{}
% provides no means to save the state we started in.  Therefore a
% mode differing from the default has to be requested explicitely.
% \label{pg:definteractionmode}
% \changes{v1.06}{1996/05/21}{%
%   New options \texttt{errorstop}, \texttt{scroll},
%   \texttt{nonstop} and \texttt{batch}.} 
%    \begin{macrocode}
\DeclareOption{errorstop}{\let\@interactionmode\errorstopmode}
\DeclareOption{scroll}{\let\@interactionmode\scrollmode}
\DeclareOption{nonstop}{\let\@interactionmode\nonstopmode}
\DeclareOption{batch}{\let\@interactionmode\batchmode}
\let\@interactionmode\errorstopmode
%    \end{macrocode}
% Every option we don't understand is sent down to |graphics|:
%    \begin{macrocode}
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{graphics}}
\ProcessOptions
%    \end{macrocode}
% For the sake of Portabilitical Correctness, we use \LaTeX's
% |graphics| for including PostScript, instead of the simpler |epsf|
% which comes with |dvips| and would have sufficed
% \changes{v0.99}{1995/05/02}{%
%   Switch back to \texttt{graphics} from \texttt{graphicx} to fix
%   a problem with changing interfaces in the latter.  Can't remember
%   why I used \texttt{graphicx} in the first place, \texttt{graphics}
%   works fine now.}  
%    \begin{macrocode}
%<mp>\RequirePackage{graphics}[1994/12/15]
%</!209>
%<*209>
\def\fmf@noexpandoff{\let\noexpand\relax}
%<mp>\input epsf.sty
%<mp>\let\includegraphics\epsffile
%</209>
%    \end{macrocode}
% Compatibility macros for \LaTeX~2.09.  Our definition of
% |\@inputcheck| is for supporting old and broken \LaTeX~2.09 versions
% before March 18, 1992.  Unfortunately, I couldn't get |\newread| to
% work here with \LaTeX~2.09.
% \changes{v0.99}{1995/05/02}{%
%   \texttt{\protect\bslash @inputcheck}: support for \LaTeX~2.09
%   versions before 92/03/18.}
%    \begin{macrocode}
%<*209>
\@ifundefined{@inputcheck}{\def\@inputcheck{0}}{}%
\def\InputIfFileExists#1#2#3{%
  \openin\@inputcheck#1 %
  \ifeof\@inputcheck
    \closein\@inputcheck
    #3%
  \else
    \closein\@inputcheck
    #2%
    \input{#1}%
  \fi}
\def\IfFileExists#1#2#3{%
  \openin\@inputcheck#1 %
  \ifeof\@inputcheck
    \closein\@inputcheck
    #3%
  \else
    \closein\@inputcheck
    #2%
  \fi}
%</209>
%    \end{macrocode}
%
% \begin{dubious}
%   We should |\||mdqon| at the end only if the German extensions are
%   really active, not just loaded.
% \end{dubious}
%    \begin{macrocode}
\let\mdqrestore\relax
\@ifundefined{mdqoff}{}{%
  \mdqoff
  \let\mdqrestore\mdqon}
%    \end{macrocode}
%
% \begin{macro}{\fmfcmd}
% The entrance through which our commands enter the world of
% \MF.  Note the |\ignorespaces|: we need to avoid spurious
% blanks in the output list.
% \changes{v1.03}{1996/02/17}{%
%   Token register \texttt{\protect\bslash fmfbuf@} for single level
%   evaluation.} 
% Using a trick suggested in |comp.text.tex|, we use a token register
% |\fmfbuf@| to force single level evaluation of commands which are to
% be included in \MF{} strings.
% \changes{v1.07}{1996/08/19}{%
%   Only write output if \texttt{\protect\bslash if@fmfio} is true.}
%    \begin{macrocode}
\def\fmfcmd#1{%
  \if@fmfio
    \immediate\write\@outfmf{#1}%
  \fi
  \ignorespaces}
\newif\if@fmfio
\@fmfiotrue
\newwrite\@outfmf
\newtoks\fmfbuf@
%    \end{macrocode}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Environments}
%
% \begin{macro}{\fmffile}
% This environment encloses each \MF{} input file.  The single
% argument gives the name of the file.
% \changes{v0.1}{1994/05/16}{%
%   Stupid: \texttt{\protect\bslash fileversion} can be reset by other
%   packages, store the current value in
%   \texttt{\protect\bslash fmf@fileversion} and use this one.} 
% \changes{v0.1}{1994/05/20}{%
%   Pass RCS revision in a string.}
% \changes{v0.4}{1994/05/27}{\MP{} support: write \MP{} file.}
% \changes{v0.8}{1995/01/18}{%
%   Protect against wrong arguments to
%   \texttt{\protect\bslash fmffile}.}
%    \begin{macrocode}
{\catcode`\%=11\gdef\p@rcent{%}}
\edef\fmf@revision{\filerevision}
\def\fmffile#1{%
  \def\thefmffile{#1}%
  \equaltojobname{\thefmffile}{%
    \errhelp={The argument of \fmffile MUST NOT be identical to the^^J%
              name of your main input file!  I will use fmfdefault.mf^^J%
              this time around, but you'd better fix your code now!}%
    \errmessage{Invalid arument of \string\fmffile!}%
    \def\thefmffile{fmfdefault}}{}%
%    \end{macrocode}
% The following trick has been taken from |mfpic|~\cite{mfpic}:
% proceed even if the font is not available yet, because we have to
% write the \MF{} file first.
% \changes{v0.4}{1994/05/27}{\MP{} support: don't open \texttt{tfm} file.}
% \changes{v0.98}{1995/04/30}{%
%   Save the font for the benefit of \texttt{\protect\bslash fmfkeep} and
%   \texttt{\protect\bslash fmfreuse}.}
% \changes{v1.02}{1996/01/25}{%
%   Read the \texttt{.tfm} file \emph{before} writing the \MF{} file
%   destructively.  This should allow a transparent two pass
%   processing if \texttt{MakeTeXTFM} is enabled.  Thanks to Thomas
%   Esser for the suggestion.}
%    \begin{macrocode}
%<*!mp>
  \batchmode
    \global\expandafter\font%
      \csname f@ynmf:\thefmffile\endcsname=\thefmffile
%    \end{macrocode}
% The hardcoded return to |\errorstopmode| is bad for automated preprint
% processors, but the integrated knowledge of |comp.text.tex| knows of
% no way to implement local mode changes --- short of hacking \TeX{}
% itself \ldots\par
% Therefore we use a default interaction mode which can be specified
% by the user as an option (see page~\pageref{pg:definteractionmode}).
% \label{pg:useinteractionmode}
% \changes{v1.06}{1996/05/21}{%
%   Use \texttt{\protect\bslash @interactionmode}.}
%    \begin{macrocode}
  \@interactionmode
  \expandafter\let\expandafter\f@ynmf\csname f@ynmf:\thefmffile\endcsname
%    \end{macrocode}
% Inform the user:
%    \begin{macrocode}
  \ifx\f@ynmf\nullfont
    \def\f@ynmf{Feynman graph:}%
    \IfFileExists{\thefmffile.mf}%
      {\typeout{%
        feynmf: File \thefmffile.tfm not found:^^J%
        feynmf: Process \thefmffile.mf with METAFONT and then %
                reprocess this file.}}%
      {\typeout{%
        feynmf: Files \thefmffile.mf and \thefmffile.tfm not found:^^J%
        feynmf: This job will create \thefmffile.mf, process it %
                later with METAFONT^^J%
        feynmf: and then reprocess this file.  Don't worry about a %
                harmless premature^^J%
        feynmf: MakeTeXTFM that might have failed just a moment ago!}}%
  \else
    \typeout{%
      feynmf: File \thefmffile.tfm found.^^J%
      feynmf: Nevertheless, if the picture has changed, %
              reprocess \thefmffile.mf.^^J%
      feynmf: If dimension have changed, reprocess \thefmffile.mf %
              and \jobname.tex.}%
  \fi
%</!mp>
%    \end{macrocode}
% Open the \MF{} file.  If we're running under AMS-\LaTeX, turn off
% I/O during the first pass over equation environments.
% \changes{v1.07}{1996/08/19}{%
%   Only write output if \texttt{\protect\bslash if@fmfio} is true.}
% \changes{v1.07}{1996/08/19}{%
%   Set \texttt{\protect\bslash if@fmfio} to \texttt{\protect\bslash
%   ifmeasuring@ \protect\bslash else} if the latter is set, i.e.~if
%   AMS-\LaTeX{} is loaded.} 
%    \begin{macrocode}
  \if@fmfio
    \@ifundefined{ifmeasuring@}%
      {}%
      {\def\if@fmfio{\ifmeasuring@\else}}%
%<*!mp>
    \immediate\openout\@outfmf=\thefmffile.mf\relax
    \fmfcmd{\p@rcent\space \thefmffile.mf -- do not edit, %
            generated automatically by \jobname.tex^^J%
            input feynmf^^J%
            require_RCS_revision "\fmf@revision";}%
%</!mp>
%<*mp>
    \immediate\openout\@outfmf=\thefmffile.mp\relax
    \fmfcmd{\p@rcent\space \thefmffile.mp -- do not edit, %
            generated automatically by \jobname.tex^^J%
            input feynmp^^J%
            require_RCS_revision "\fmf@revision";}%
%</mp>
  \fi
%    \end{macrocode}
% Count the graphs
%    \begin{macrocode}
  \setcounter{fmfgraph}{0}}
\let\thefmffile\relax
\newcounter{fmfgraph}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\equaltojobname}
% Here's a kludge for comparing strings to |\jobname|.  The |\meaning|
% hack is necessary, because |\jobname|'s expansion has different
% |\catcode|s
%    \begin{macrocode}
\def\equaltojobname#1#2#3{%
  \edef\@tempa{#1}%
  \edef\@tempa{\meaning\@tempa}%
  \edef\@tempb{\jobname}%
  \edef\@tempb{\meaning\@tempb}%
  \ifx\@tempa\@tempb
    #2
  \else
    #3
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endfmffile}
% And here is how we close the |fmffile| environment:
%    \begin{macrocode}
\def\endfmffile{%
  \fmfcmd{\p@rcent\space the end.^^J%
          end.^^J%
          endinput;}%
  \let\thefmffile\relax
  \if@fmfio
    \immediate\closeout\@outfmf
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fmf@graph}
% This is the bulk of the environment used for each graph
% drawn by \MF.
% \changes{v0.5}{1994/08/17}{%
%   Removed definiton of \texttt{\protect\bslash sharp}.  It's never
%   used and conflicts with the $\sharp$ symbol.}
% \changes{v1.06}{1996/05/21}{%
%   New macro \texttt{\protect\bslash dqu@te}.}
%    \begin{macrocode}
{\catcode`\#=11\gdef\sh@rp{#}%
 \catcode`\"=11\gdef\dqu@te{"}}
\def\fmf@graph#1#2{%
%    \end{macrocode}
% Make sure that a \MF{} file is open, otherwise \emph{really}
% obscure error messages are possible:
% \changes{v0.3}{1994/05/23}{%
%   Make sure that a \MF{} file is open, otherwise \emph{really}
%   obscure error messages are possible.}
%    \begin{macrocode}
  \ifx\thefmffile\relax
    \errhelp={Outside a fmffile environment, I have no clue as to where^^J%
              the METAFONT commands should go.   I will use fmfdefault.mf^^J%
              for this graph, but you'd better fix your code!}%      
    \errmessage{I detected a fmfgraph environment outside of fmffile}%
    \fmffile{fmfdefault}
  \fi
%    \end{macrocode}
% We can't use |\stepcounter| because of the |amstext| option of
% AMS-\LaTeX{} disables it sometimes.
% \changes{v0.8}{1995/01/07}{Don't use \texttt{\protect\bslash stepcounter}.}
% \changes{v0.99}{1995/05/04}{Use \texttt{\protect\bslash fmfsubgraph}.}
%    \begin{macrocode}
  \global\expandafter\advance\csname c@fmfgraph\endcsname \@ne
%    \end{macrocode}
% Start \MF{} character:\footnote{%
%   I'm flying a bit blind here, because I can't figure out why Babel
%   (unlike stand-alone \texttt{german.sty} breaks with an unprotected
%   quote here.  On all other occasions, \texttt{\protect\bslash
%   mdqoff} suffices.} 
% \changes{v1.06}{1996/05/21}{Babel compatibility.}
%    \begin{macrocode}
  \fmfcmd{beginchar(\thefmfgraph, #1*\the\unitlength\sh@rp, %
                                 #2*\the\unitlength\sh@rp, 0);^^J%
            \dqu@te feynmf: \thefmfgraph\dqu@te;}%
  \fmfcmd{LaTeX_unitlength:=\the\unitlength;}%
  \begin{fmfsubgraph}(0,0)(w,h)
    \fmfinit
    \fmfpen{thin}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fmfgraph}
% The plain version, no labels, no enclosing |picture| environment
% \changes{v0.99}{1995/05/04}{%
%   Change the name of \texttt{\protect\bslash fmfchar} and friends to
%   \texttt{\protect\bslash fmfgraph}, which should be more intuitive
%   to people with less of a \MF{} background.  Keep the old names as
%   aliases for a while.}
%    \begin{macrocode}
\def\fmfgraph(#1,#2){%
  \fmf@graph{#1}{#2}%
  \def\fmfkeep##1{\fmf@keep{#1}{#2}{##1}}%
%    \end{macrocode}
% Place the character:
% \changes{v0.4}{1994/05/27}{\MP{} support: include PostScript file.}
% \changes{v0.8}{1995/02/18}{\LaTeX~2.09 compatibility}
%    \begin{macrocode}
%<!mp>{\f@ynmf \char\value{fmfgraph}}%
%<*mp>
  \leavevmode
  \IfFileExists{\thefmffile.\thefmfgraph}%
    {\includegraphics{\thefmffile.\thefmfgraph}}%
    {\typeout{%
      feynmp: File \thefmffile.\thefmfgraph\space not found:^^J%
      feynmp: Process \thefmffile.mp with MetaPost and then %
              reprocess this file.}}%
%</mp>
  \ignorespaces}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endfmfgraph}
%    \begin{macrocode}
\def\endfmfgraph{%
    \fmffreeze
    \fmfdraw
  \end{fmfsubgraph}
  \fmfcmd{endchar;}%
  \def\fmfkeep##1{\fmf@nokeep}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fmfchar}
%   \begin{macro}{\endfmfchar}
%    \begin{macrocode}
\def\fmfchar{\@nameuse{fmfgraph}}
\def\endfmfchar{\@nameuse{endfmfgraph}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\fmfgraph*}
% The extended version, with labels and |picture| environment.
%    \begin{macrocode}
\@namedef{fmfgraph*}(#1,#2){%
  \begin{picture}(#1,#2)
    \fmf@graph{#1}{#2}%
    \def\fmfkeep##1{\fmf@keepstar{#1}{#2}{##1}}%
%    \end{macrocode}
% Process the \MF{} output for labels (if any), enforcing |%| as
% comment character.
% \changes{v0.99}{1995/05/07}{%
%   Don't include the filename in the tag for
%   \texttt{\protect\bslash grepfile}: it's a waste.}
% Not all systems use |.log| as extension of the |log|-file.  If there
% is no |.log|, but a |.lis|: use the latter.
% \changes{v0.99}{1995/05/07}{%
%   From Scott Snyder (Fermilab): allow \texttt{.lis}
%   as alternative \texttt{log}-file extension for VMS.}
% \changes{v1.07}{1996/08/19}{%
%   Call \texttt{\protect\bslash grepfile} only if
%   \texttt{\protect\bslash if@fmfio} is true.}
%    \begin{macrocode}
%<*!mp>
    \if@fmfio
      \def\thefmfext{.log}%
      \IfFileExists{\thefmffile.log}%
       {}%
       {\IfFileExists{\thefmffile.lis}%
         {\def\thefmfext{.lis}}%
         {}}%
      {\catcode`\%=14\relax
       \grepfile%
         {\thefmfgraph}%
         {\thefmffile\thefmfext}%
         {\thefmffile.t\thefmfgraph}}%
    \fi
%</!mp>
%    \end{macrocode}
% Place the character:
% \changes{v0.4}{1994/05/27}{\MP{} support: include PostScript file.}
%    \begin{macrocode}
%<!mp>\put(0,0){{\f@ynmf \char\value{fmfgraph}}}%
%<*mp>
  \IfFileExists{\thefmffile.\thefmfgraph}%
    {\put(0,0){\includegraphics{\thefmffile.\thefmfgraph}}}%
    {\typeout{%
      feynmp: File \thefmffile.\thefmfgraph\space not found:^^J%
      feynmp: Process \thefmffile.mp with MetaPost and then %
              reprocess this file.}}%
%</mp>
      \ignorespaces}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endfmfgraph*}
%    \begin{macrocode}
\@namedef{endfmfgraph*}{%
    \endfmfgraph
%    \end{macrocode}
% Enforce |%| as comment character.   Disable |\noexpand| if the
% option |pre-1.03| is in effect to allow processing of old files
% prepared before the new single level expansion had been
% implemented.  |\fmf@noexpandoff| is defined on
% page~\ref{pg:defnoexpandoff}.
% \label{pg:usenoexpandoff}
% \changes{v1.03}{1996/02/17}{%
%   Disable \texttt{\protect\bslash noexpand} to allow
%   processing of old files.}
% \changes{v1.05}{1996/05/06}{%
%   Reenable \texttt{\protect\bslash noexpand} for compatibility with
%   font loading on demand.}
% \changes{v1.07}{1996/08/19}{%
%   Include the labels file only if \texttt{\protect\bslash if@fmfio}
%   is true.} 
%    \begin{macrocode}
    \if@fmfio
      {\catcode`\%=14\relax
       \fmf@noexpandoff
        \InputIfFileExists{\thefmffile.t\thefmfgraph}{}{%
          \typeout{%
            feynmf: Label file \thefmffile.t\thefmfgraph\space not found:^^J%
%<!mp>      feynmf: Process \thefmffile.mf with METAFONT and then %
%<mp>       feynmf: Process \thefmffile.mp with MetaPost and then %
                    reprocess this file.}}}%
    \fi
  \end{picture}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fmfchar*}
%   \begin{macro}{\endfmfchar*}
%    \begin{macrocode}
\@namedef{fmfchar*}{\@nameuse{fmfgraph*}}
\@namedef{endfmfchar*}{\@nameuse{endfmfgraph*}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\fmfkeep}
% \changes{v0.98}{1995/04/30}{Implemented.}
%    \begin{macrocode}
\def\fmfkeep#1{\fmf@nokeep}
\def\fmf@nokeep{%
  \errhelp={There's nothing to \string\fmfkeep!}%
  \errmessage{feynmf: \string\fmfkeep\space outside of `fmfgraph'!}}
%    \end{macrocode}
% Here are the real implementations:
%    \begin{macrocode}
\def\fmf@keep#1#2#3{%
  \global\@namedef{fmf@k:e:#3}{\begin{fmfgraph}(#1,#2)\end{fmfgraph}}%
  \global\e@namedef{fmf@k:f:#3}{\thefmffile}%
  \global\e@namedef{fmf@k:c:#3}{\thefmfgraph}}
\def\fmf@keepstar#1#2#3{%
  \global\@namedef{fmf@k:e:#3}{\begin{fmfgraph*}(#1,#2)\end{fmfgraph*}}%
  \global\e@namedef{fmf@k:f:#3}{\thefmffile}%
  \global\e@namedef{fmf@k:c:#3}{\thefmfgraph}}
\def\e@namedef#1{\expandafter\edef\csname #1\endcsname}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fmfreuse}
% \changes{v0.98}{1995/04/30}{Implemented.}
%    \begin{macrocode}
\def\fmfreuse#1{%
  \@ifundefined{fmf@k:e:#1}%
   {\typeout{%
      feynmf: \string\fmfreuse: %
      missing \string\fmfkeep\space for `#1'!}}%
   {\edef\thefmffile{\@nameuse{fmf@k:f:#1}}%
%<*!mp>
    \expandafter\let\expandafter\f@ynmf%
      \csname f@ynmf:\thefmffile\endcsname
%</!mp>
    \@nameuse{c@fmfgraph}\@nameuse{fmf@k:c:#1}%
    \advance\@nameuse{c@fmfgraph}-1%
    \def\fmfcmd##1{}%
    \@nameuse{fmf@k:e:#1}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fmfframe}
% This is used to allocate additional space around a |fmfgraph*|, since
% the labels (or the diagram itself) might overshoot.
% |\fmfgraph(|\meta{left}|,|\meta{top}|)(|\meta{right}|,|\meta{bottom}|){|^^A
% \meta{box}|}| puts an invisible frame of the given dimensions
% (measured in |\unitlength|) around \meta{box}.
%    \begin{macrocode}
\def\fmfframe(#1,#2)(#3,#4)#5{%
  \leavevmode
  \hbox{\vbox{\vskip#2\unitlength\par
              \hbox{\hskip#1\unitlength#5\hskip#3\unitlength}\par
              \vskip#4\unitlength}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fmfpen}
% Picup a |pencircle| scaled by the argument.
%    \begin{macrocode}
\def\fmfpen#1{\fmfcmd{pickup pencircle scaled #1;}}
%    \end{macrocode}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Subgraphs}
%
% \begin{macro}{\fmfsubgraph}
%   \begin{macro}{\endfmfsubgraph}
% An environment for graphs in graphs:
% \changes{v0.99}{1995/05/04}{%
%   Implement \texttt{\protect\bslash fmfsubgraph}, as suggested by
%   Wolfgang Kilian (DESY).}
%    \begin{macrocode}
\def\fmfsubgraph(#1,#2)(#3,#4){\fmfcmd{subgraph (#1, #2, #3, #4);}}
\def\endfmfsubgraph{\fmfcmd{endsubgraph;}}
%</style>
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% Set up a subgraph:
%    \begin{macrocode}
%<*base>
def subgraph (expr x, y, wd, ht) =
  begingroup
    save c, ne, nw, sw, se;
    pair c, ne, nw, sw, se;
    sw = (x,y);
    se = sw + (wd,0);
    nw = sw + (0,ht);
    ne = sw + (wd,ht);
    c = .5[sw,ne];
enddef;
def endsubgraph =
  endgroup
enddef;
%</base>
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Grep}
% \label{sec:grep}
%
% \begin{macro}{\grepfile}
% The macro |\grepfile{|\meta{pattern}|}{|\meta{in}|}{|\meta{out}|}|
% writes all lines matching |:|\meta{pattern}|:| from file \meta{in}
% to file \meta{out} after stripping off the pattern.
% \begin{dubious}
%   Pattern matching on lines with a single leading colon fails.
% \end{dubious}
% \changes{v0.4}{1994/05/28}{%
%   Don't include the \texttt{\protect\bslash grep} macros in the
%   \MP{} version.  \texttt{\protect\bslash write} makes them
%   obsolete.} 
%    \begin{macrocode}
%<*style>
%<*!mp>
\def\grepfile#1#2#3{%
  \begingroup
%    \end{macrocode}
% Hash the pattern and open the input and output streams:
%    \begin{macrocode}
    \edef\pattern{\csname*grep*#1*\endcsname}%
    \immediate\openin\grep@infile #2\relax
    \ifeof\grep@infile
    \else
      \grep@outopenfalse
%    \end{macrocode}
% Don't add anything at the end of input lines and don't expand
% anything we've read from the file:
% \changes{v1.05}{1996/05/06}{%
%    Use \texttt{\protect\bslash @sanitize} instead of just changing
%    the \texttt{\protect\bslash catcode} of
%    ``\texttt{\protect\bslash}''.  Some styles (in particular
%    \texttt{french.sty}) play dirty tricks with ``\texttt{:}''.}
%    \begin{macrocode}
      \endlinechar=-1
      \@sanitize
%    \end{macrocode}
% But make sure that |{|, |}| and |%| continue to act as delimiters
% and comment character, respectively.  |\@sanitize| will usually have
% changed at least the |\catcode| of the latter.  We need the
% delimiters for multi-line reading and |%| for commenting out \MF's
% pregress reports.
%    \begin{macrocode}
      \catcode`\{=1 \catcode`\}=2 \catcode`\%=14 \relax
%    \end{macrocode}
% Loop over the input lines until end of file occurs.  Note that
% \TeX's |\read| will automagically continue reading until braces are
% balanced.
%    \begin{macrocode}
      \loop
        \read\grep@infile to \grep@lbuf
        \ifeof\grep@infile
          \grep@contfalse
        \else
          \grep@conttrue
%    \end{macrocode}
% Iff the input line is not empty, use |\grep@aline| to examine its
% contents and, iff the pattern matched, write a line to the output file.
%    \begin{macrocode}
          \ifx\grep@lbuf\empty
          \else
            \expandafter\grep@aline\grep@lbuf\sentinel
            \ifx\pattern\grep@tag
%    \end{macrocode}
% Delayed open (this avoids empty files):
%    \begin{macrocode}
              \ifgrep@outopen
              \else
                 \immediate\openout\grep@outfile #3\relax
                 \immediate\write\grep@outfile{\p@rcent\space #3 %
                    -- generated automatically from #2}%
                 \immediate\write\grep@outfile{\p@rcent\space
                    Think twice before editing THIS file!}%
                 \grep@outopentrue
              \fi
              \immediate\write\grep@outfile{\grep@val}%
            \fi
          \fi
        \fi
      \ifgrep@cont
      \repeat
%    \end{macrocode}
% Close the files after we're done.
% \changes{v0.1}{1994/05/16}{%
%   Stupid: \texttt{\protect\bslash closein} the input stream,
%   don't use \texttt{\protect\bslash closeout} on it.}
%    \begin{macrocode}
      \ifgrep@outopen
        \immediate\closeout\grep@outfile
      \fi
    \fi
    \immediate\closein\grep@infile
  \endgroup}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\grep@infile}
%  \begin{macro}{\grep@outfile}
% The I/O streams for the grep facility
%    \begin{macrocode}
\newread\grep@infile
\newwrite\grep@outfile
%    \end{macrocode}
%  \end{macro}
% \end{macro}
% \begin{macro}{\ifgrep@cont}
%   \begin{macro}{\ifgrep@outopen}
% and flags for the same 
%    \begin{macrocode}
\newif\ifgrep@cont
\newif\ifgrep@outopen
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\grep@aline}
% Examine one line and set the variables |\grep@tag| and |\grep@val|
% iff the line starts with a colon.  Subtle point here: |\ifx#1:| will
% \emph{not} work if |#1| starts with a |{| followed by two identical
% characters.
%    \begin{macrocode}
\def\grep@aline#1#2\sentinel{%
  \ifx:#1%
    \grep@splitlbuf#2\sentinel
  \else
    \edef\grep@tag{\csname*grep*\endcsname}%
    \def\grep@val{}%
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\grep@splitlbuf}
% Split the line buffer at the remaining colon, hashing the first part.
%    \begin{macrocode}
\def\grep@splitlbuf#1:#2\sentinel{%
  \edef\grep@tag{\csname*grep*#1*\endcsname}%
  \def\grep@val{#2}}
%</!mp>
%    \end{macrocode}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Lists}
%
% The following macros are stolen from Alan Jeffrey's
% |lambda.sty|~\cite{Lambda}.  Alan's implementation is more complete,
% this is just the subset we need to do some listprocessing in \TeX's
% mouth, e.g.~in the body of a |\write|.  Actually, you're not
% supposed to understand these macros from first reading.  It's better
% to read Alan's paper (it is available from CTAN as |lambda.tex|),
% where they are described.  From a programming point of view, Alan's
% macros are probably my favorites.  You will find a whole new
% perspective on \TeX{} there.
% \changes{v0.98}{1995/04/26}{List processing macros.}
%    \begin{macrocode}
\def\Compose#1#2#3{#1{#2{#3}}}
\def\gobblefalse\else\gobbletrue\fi#1#2{\fi#1}
\def\gobbletrue\fi#1#2{\fi#2}
\def\TeXif#1{#1\gobblefalse\else\gobbletrue\fi}
\def\Nil#1#2{#2}
\def\Cons#1#2#3#4{#3{#1}{#2}}
\def\Singleton#1{\Cons{#1}\Nil}
\def\Foldr#1#2#3{#3{\Foldr@{#1}{#2}}{#2}}
\def\Foldr@#1#2#3#4{#1{#3}{\Foldr{#1}{#2}{#4}}}
\def\Map#1{\Foldr{\Compose\Cons{#1}}\Nil}
\def\Unlistize#1{#1\Unlistize@{}}
\def\Unlistize@#1{#1\Foldr\Commaize{}}
\def\Commaize#1#2{, #1#2}
\def\Listize#1{\Listize@#1,\relax @@@}
\def\Listize@#1,#2@@@{%
   \TeXif{\ifx\relax#2}%
     {\Singleton{#1}}%
     {\Cons{#1}{\Listize@#2@@@}}}
%    \end{macrocode}
%
% Protect \MF's namespace:
% \changes{v1.03}{1996/02/17}{%
%   Replace \texttt{\protect\bslash pfx} by
%   \texttt{\protect\bslash fmfpfx} for namespace sanity.}
%    \begin{macrocode}
\def\fmfpfx@#1{__#1}
\def\fmfpfx#1{\Unlistize{\Map\fmfpfx@{\Listize{#1}}}}
%    \end{macrocode}
%
% The other \TeX{} command sequences are defined below, along with the
% \MF{} macros they are in one-to-one correspondence to.
%    \begin{macrocode}
%</style>
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{\MF{} macros}
% \label{sec:mf-code}
%
% Now we turn our attention to the \MF{}
% macros.
% \begin{dubious}
%   We should find a way (a hack) to index the
%   \MF{} macros with the |doc| option.
% \end{dubious}
% Because of name clashes, \FMF{} will not work if the |cmbase| is
% loaded.  Die with an useful error message:
% \changes{v0.5}{1994/06/13}{Don't accept the Computer Modern Base.}
%    \begin{macrocode}
%<*base>
if known cmbase:
  errhelp
    "feynmf will only work with plain Metafont, as described in the book.";
  errmessage "feynmf: CMBASE detected.  Please use the PLAIN base.";
  forever:
    errmessage "No use in trying!  You'd better eXit now ...";
    errorstopmode;
  endfor
fi
%    \end{macrocode}
%
% Make the RCS revision number available for feature testing:
% \changes{v0.1}{1994/05/20}{%
%   Handle arbitrary RCS revision strings.}
%    \begin{macrocode}
vardef parse_RCS (suffix RCS) (expr s) =
  save n, c;
  numeric n, RCS[];
  string c;
  RCS[0] := 0;
  for n = 1 upto length (s):
    c := substring (n-1,n) of s;
    exitif ((RCS[0] > 0) and (c = " "));
    if ((c = "0") or (c = "1") or (c = "2")
        or (c = "3") or (c = "4") or (c = "5")
        or (c = "6") or (c = "7") or (c = "8")
        or (c = "9")):
      if RCS[0] = 0:
        RCS[0] := 1;
        RCS[RCS[0]] := 0;
      fi
      RCS[RCS[0]] := 10 * RCS[RCS[0]] + scantokens (c);
    elseif c = ".":
      RCS[0] := RCS[0] + 1;
      RCS[RCS[0]] := 0;
    else:
    fi
  endfor
enddef;
%    \end{macrocode}
% Check that \LaTeX{} style and \MF{} macros are in sync:
%    \begin{macrocode}
vardef require_RCS_revision expr s =
  save n, TeX_rev, mf_rev;
  numeric n;
  parse_RCS (TeX_rev, s);
  parse_RCS (mf_rev, "$Revision: 1.30 $");
  for n = 1 upto min (2, TeX_rev[0], mf_rev[0]):
    if TeX_rev[n] > mf_rev[n]:
      errhelp
        "Your version of `feynmf.sty' is higher that of your `feynmf.mf'.";
      errmessage "feynmf: Metafont macros out of date";
    elseif TeX_rev[n] < mf_rev[n]:
      errhelp
        "Your version of `feynmf.mf' is higher that of your `feynmf.sty'.";
      errmessage "feynmf: LaTeX style out of date";
    fi
    exitif (TeX_rev[n] <> mf_rev[n]);
  endfor
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{\MP{} support}
%
% This \MP{} support just mimics \MF{}, but it works.
% \changes{v0.4}{1994/05/27}{Preliminary \MP{} support: mimic \MF.}
%    \begin{macrocode}
%<*mp>
vardef cullit = \ enddef;
color foreground;
foreground = black;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef beginchar (expr c, wd, ht, dp) =
  LaTeX_file := "";
  beginfig(c);
    w:=wd;
    h:=ht;
enddef;
string LaTeX_file;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef endchar =
  setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle;
  if LaTeX_file <> "":
    write EOF to LaTeX_file;
    LaTeX_file := "";
  fi
  endfig
enddef;
%    \end{macrocode}
%
% Sharped dimensions are useless with \MP.  We define them anyway
% with trivial translation, so that the \MF{} code can be used
% unchanged.
%    \begin{macrocode}
bp# := bp;
cc# := cc;
cm# := cm;
dd# := dd;
in# := in;
mm# := mm;
pc# := pc;
pt# := pt;
%    \end{macrocode}
% As I said: trivial translation.
%    \begin{macrocode}
vardef define_blacker_pixels(text t) =
  forsuffixes $=t:
    $:=$.#;
  endfor
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
picture unitpixel;
unitpixel = nullpicture;
addto unitpixel contour unitsquare;
def t_ = \ enddef;
%</mp>
%    \end{macrocode}
%
%    \begin{macrocode}
%<!mp>mode_setup;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Basics}
% \label{sec:mf-basics}
%
% Allow the user to life dangerously or not, depending on his
% preferences.
% \changes{v0.7}{1994/10/23}{\texttt{fmfwizard}: to live dangerously or not.}
%    \begin{macrocode}
boolean feynmfwizard;
feynmfwizard := false;
%</base>
%    \end{macrocode}
% \begin{macro}{\fmfwizard}
%   \begin{macro}{\fmfnowizard}
%    \begin{macrocode}
%<*style>
\def\fmfwizard{\fmfcmd{feynmfwizard := true;}}
\def\fmfnowizard{\fmfcmd{feynmfwizard := false;}}
%</style>
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% Default values of style parameters:
%    \begin{macrocode}
%<*base>
thin# := 1pt#; % dimension of the lines
thick# := 2thin#;
arrow_len# := 4mm#;
arrow_ang := 15;
curly_len# := 3mm#;
dash_len# := 3mm#; % 'photon' lines
dot_len# := 2mm#; % 'photon' lines
wiggly_len# := 4mm#; % 'photon' lines
wiggly_slope := 60;
zigzag_len# := 2mm#;
zigzag_width# := 2thick#;
decor_size# := 5mm#;
dot_size# := 2thick#;
%    \end{macrocode}
% Convert ``sharp'' units:
%    \begin{macrocode}
define_blacker_pixels (thick, thin,
  dash_len, dot_len, wiggly_len, curly_len,
  zigzag_len, zigzag_width, arrow_len, decor_size, dot_size);
%    \end{macrocode}
%
% Back by popular demand: shrinking dimensions.
% \changes{v0.5}{1994/06/13}{%
%   Back by popular demand: shrinking dimensions.}
%    \begin{macrocode}
def shrink expr s =
  begingroup
  if shrinkables <> "":
    save tmp_;
    forsuffixes $ = scantokens shrinkables:
%    \end{macrocode}
% The sharp dimension might not be known, e.g.~after
% |\fmfset{arrow_len}{6mm}|, protect against that:
% \changes{v1.06}{1995/05/29}{%
%   Make \texttt{shrink} work, even if the sharp dimension is not
%   known.}
%    \begin{macrocode}
      if known $.#:
        tmp_ := $.#;
        save $;
        $.# := s * tmp_;
        define_blacker_pixels ($);
      else:
        tmp_ := $;
        save $;
        $ := s * tmp_;
      fi
    endfor
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
def endshrink =
  endgroup
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfshrink}
%   \begin{macro}{\endfmfshrink}
% Exporting the whole enchilada to \LaTeX:
%    \begin{macrocode}
%<*style>
\def\fmfshrink#1{\fmfcmd{shrink (#1);}}
\def\endfmfshrink{\fmfcmd{endshrink;}}
%</style>
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
%    \begin {macrocode}
%<*base>
string shrinkables;
shrinkables := "";
%    \end{macrocode}
%
% This macro is used to register shrinkable dimensions.  It is not
% really robust, we have add the first enty by hand:
%    \begin {macrocode}
vardef addto_shrinkables (text l) =
  forsuffixes $ = l:
    shrinkables := shrinkables & "," & str $;
  endfor
enddef;
shrinkables := "thick,thin";
%    \end{macrocode}
%
%    \begin {macrocode}
addto_shrinkables (dash_len, dot_len);
addto_shrinkables (wiggly_len, curly_len);
addto_shrinkables (zigzag_len, zigzag_width);
addto_shrinkables (arrow_len);
addto_shrinkables (decor_size, dot_size);
%    \end{macrocode}
%
% Default to metric units, but this will be reset by |\begin{fmfgraph}|
% anyway.
%    \begin {macrocode}
LaTeX_unitlength := mm;
%    \end{macrocode}
%
% Count the number of tokens in the argument:
%    \begin {macrocode}
vardef count (text list) =
  forsuffixes $ = list: + 1 endfor
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Parsing options}
% \label{sec:getopt}
%
% Parse the string |s| into comma separated tokens |opt[]|, ignoring
% blanks before |=|'s. Double commas are passed as a single comma.
% \changes{v0.8}{1994/10/25}{%
%   Plugged the string memory leak in \texttt{getopt}: don't create
%   intermediate one character strings, \MF{} never claims them back.}
%    \begin {macrocode}
vardef getopt (suffix opt) (expr s) =
  save n, argp, escape, anchor, skip;
  numeric opt.first, opt.last, n, anchor;
  string opt[], opt[]arg;
  boolean opt[]tainted, argp, escape, skip;
  opt.first := 0;
  opt.last := 0;
  opt[opt.last] := "";
  argp := false;
  escape := false;
  anchor := 0;
  skip := true;
  for n = 1 upto length (s):
%    \end{macrocode}
% Skip blanks at the beginning of each option or argument:
%    \begin {macrocode}
    if skip and (substring (n-1, n) of s = " "):
      anchor := anchor + 1;
    else:
      skip := false;
%    \end{macrocode}
% If we see a comma which has not been escaped, check for a second
% comma and set the |escape| flags and remember to remove the second
% comma later or reset the |argp| flag, as appropriate:
%    \begin {macrocode}
      if not escape and (substring (n-1, n) of s = ","):
        if substring (n, n+1) of s = ",":
          escape := true;
          opt[opt.last]tainted := true;
%    \end{macrocode}
% Else accept the option or argument:
%    \begin {macrocode}
        else:
          if argp:
            opt[opt.last]arg := substring (anchor, n-1) of s;
          else:
            opt[opt.last] := substring (anchor, n-1) of s;
          fi
          anchor := n;
          argp := false;
          skip := true;
          opt.last := opt.last + 1;
        fi
%    \end{macrocode}
% Start as argument and ignore |=|'s until the next option:
%    \begin {macrocode}
      elseif not argp and (substring (n-1, n) of s = "="):
        opt[opt.last] := substring (anchor, n-1) of s;
        anchor := n;
        argp := true;
        skip := true;
%    \end{macrocode}
% Accept the next character (either option or argument) and reset the
% |escape| flag:
%    \begin {macrocode}
      elseif argp or (substring (n-1, n) of s <> " "):
        escape := false;
      fi
    fi
  endfor
%    \end{macrocode}
% Accept the final option or argument:
%    \begin {macrocode}
  if argp:
    opt[opt.last]arg := substring (anchor, length s) of s;
  else:
    opt[opt.last] := substring (anchor, length s) of s;
  fi
%    \end{macrocode}
% We still have to remove possible doubled commata from the arguments.
% Theoretically, we could already have done it above (that's the way
% earlier versions of \FMF{} did it), but only at the expense of
% excessive copying of strings (like |opt[n]arg:=opt[n]arg&c|).  Given
% \MF's string handling, we should avoid these \emph{at any cost},
% because the wasted string memory will \emph{never} be
% reclaimed!\footnote{Actually, \MP{} has code to compact the string
%   pool, which  makes \emph{a lot} of difference in the present case.
%   But this doesn't help us with \MF.}
% Since the more elegant former version had a serious string memory
% leak, we'd better stick to the current ugly but space efficient
% implementation.
%    \begin {macrocode}
  for n = opt.first upto opt.last:
    if known opt[n]tainted:
      if opt[n]tainted:
        opt[n]arg := untaint_string opt[n]arg;
      fi
    fi
  endfor
enddef;
%    \end{macrocode}
% Turn double commata into single commata, using as little string
% copies as possible:
%    \begin {macrocode}
vardef untaint_string suffix s =
  save n, anchor;
  numeric n, anchor;
  anchor := 0;
  for n = 1 upto length (s) - 1:
    if substring (n-1,n+1) of s = ",,":
      substring (anchor, n-1) of s &
      hide (anchor := n)
    fi
  endfor
  substring (anchor, length s) of s
enddef;
%    \end{macrocode}
%
% Split a string into |.|-separated components for matching options.
%    \begin {macrocode}
vardef split_string (suffix comp) (expr s) =
  save n, anchor;
  numeric comp.first, comp.last, n, anchor;
  string comp[];
  comp.first := 0;
  comp.last := 0;
  comp[comp.last] := "";
  anchor := 0;
  for n = 1 upto length (s):
    if substring (n-1,n) of s = ".":
      comp[comp.last] := substring (anchor, n-1) of s;
      comp.last := comp.last + 1;
      anchor := n;
    fi
  endfor
  comp[comp.last] := substring (anchor, length s) of s;
enddef;
%    \end{macrocode}
% Return |true| iff |prefix| is a prefix of |s|:
%    \begin {macrocode}
vardef match_prefix (expr prefix, s) =
  (prefix = substring (0, length prefix) of s)
enddef;
%    \end{macrocode}
% Match options similarly to |Xt| resource strings, but allowing for
% abbreviations:
% \changes{v0.7}{1994/10/23}{More general option parsing.}
%    \begin {macrocode}
vardef match_option (expr s, option) =
  save sc, optionc, n, i;
  numeric sc.first, sc.last, optionc.first, optionc.last;
  string sc[], optionc[];
  numeric n, i;
  split_string (sc, s);
  split_string (optionc, option);
  n := sc.last - sc.first;
  if n <> (optionc.last - optionc.first):
    false
  else:
    true
    for i = 0 upto n:
      and match_prefix (sc[sc.first+i],
                        optionc[optionc.first+i])
    endfor
  fi
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Manipulating \texttt{picture}s}
% \label{sec:pictures}
%
% This section is leftover from the five year old |feynman.mf| package
% and is now obsolete for \MF.  Ironically, we still need it to mimic
% our \MF{} clipping code in \MP.
%
% |save_picture (list_of_pictures)| |save|'s each member of
% |list_of_pictures| inside a group and reinitializes them as nullpictures.
%    \begin{macrocode}
def save_picture text t =
 save t; picture t; forsuffixes p=t: p:=nullpicture; endfor
enddef;
%    \end{macrocode}
%
% |begin_sketch| pushes the sketchpad stack and perform the following
% drawing commands (upto the next |end_sketch|) on the new sketchpad.
%    \begin{macrocode}
def begin_sketch =
 begingroup save_picture currentpicture;
 sketchlevel := sketchlevel+1;
enddef;
%    \end{macrocode}
%
% |end_sketch| pops the sketchpad stack.
%    \begin{macrocode}
def end_sketch =
 sketchlevel := sketchlevel-1;
 sketchpad[sketchlevel] := currentpicture;
 endgroup
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
picture sketchpad[];
sketchlevel := 1;
%    \end{macrocode}
%
% |use_sketch (transformation)| copies the transformed sketchpad into
% the current picture.
%    \begin{macrocode}
vardef use_sketch text t =
 addto currentpicture also (sketchpad[sketchlevel] t)
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Tilings}
% \label{sec:tilings}
%
% Colored drawing is available with \MP{} only:
% \changes{v0.98}{1995/04/29}{Color support.}
%    \begin{macrocode}
vardef cdraw expr p =
%<mp>  draw p withcolor foreground
%<!mp> draw p
enddef;
vardef cfill expr p =
%<mp>  fill p withcolor foreground
%<!mp> fill p
enddef;
vardef cfilldraw expr p =
%<mp>  filldraw p withcolor foreground
%<!mp> filldraw p
enddef;
%    \end{macrocode}
% |autorounding| would disturb |cutdraw|.
% \changes{v1.01}{1995/06/04}{%
%   No \texttt{autorounding} for \texttt{cutdraw}.}
%    \begin{macrocode}
vardef ccutdraw expr p =
%<mp>  cutdraw p withcolor foreground
%<!mp> interim autorounding := 0;
%<!mp> cutdraw p
enddef;
vardef cdrawdot expr p =
%<mp>  drawdot p withcolor foreground
%<!mp> drawdot p
enddef;
%    \end{macrocode}
%
% \changes{v1.01}{1995/06/11}{Implement tilings.}
% We also need some textprocessing tools.  Here's a slow and portable
% incarnation of |isdigit|:
%    \begin{macrocode}
vardef isdigit expr s =
  save n;
  (s = "0")
  for n = 1 upto 9:
    or (s = decimal n)
  endfor
enddef;
%    \end{macrocode}
% it is used in the next function, which return the interval of the
% first digits after |start| in the string |s|:
%    \begin{macrocode}
vardef digits_index (expr s, start) =
  save n, m, from, to;
  for n = start upto (length s)-1:
    if isdigit (substring (n,n+1) of s):
      from := n;
      for m = n upto length s:
        if not isdigit (substring (m,m+1) of s):
          to := m;
        fi
        exitif known to;
      endfor
    fi
    exitif known from;
  endfor
  (from, if known to: to else: infinity fi)
enddef;
%    \end{macrocode}
% The application is in this function, which takes a |suffix| and
% returns it textual representation, with all sequences of digits
% replaced by |[]|.  We need it later, because declarations like
% |picture foo1bar2;| are \emph{verboten} in \MF, they have to be
% replaced by |picture foo[]bar[];|.
%    \begin{macrocode}
vardef digits_to_brackets suffix suf =
  save s, idx;
  string s;
  pair idx;
  s = str suf;
  idx = (0,0);
  forever:
    idx := digits_index (s, xpart idx);
    exitif unknown xpart idx;
    s := substring (0,xpart idx) of s
      & "[]" & substring (ypart idx,infinity) of s;
  endfor
  s
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
tile_grain := 1in/300;
%    \end{macrocode}
%
% Declare a tile.
%    \begin{macrocode}
vardef def_tile (suffix t) (expr wd, ht) =
  if not picture tlist.t:
    picture tlist.scantokens (digits_to_brackets t);
  fi
  tlist.t := nullpicture;
  tlist.t.dx := max (floor wd, 1);
  tlist.t.dy := max (floor ht, 1);
enddef;
%    \end{macrocode}
%
% Use the tile |t| to tile a rectangle of width |wd| and height |ht|
% with lower left corner at |(x,y)|.  The upper and right boundaries
% will be rounded to multiples of the tile size.  Note that it is
% vital for our clipping tricks that \emph{no} pixel gets a weight of
% two or more!
%    \begin{macrocode}
vardef use_tile (suffix t) (expr x, y, wd, ht) =
%<*mp>
  fill unitsquare xscaled wd yscaled ht shifted (x,y)
    withcolor background;
  if str t = "shaded":
    shade_rectangle (4thin, x, y, wd, ht);
  elseif str t = "hatched":
    shade_rectangle (5thin, x, y, wd, ht);
    shade_rectangle (-5thin, x, y, wd, ht);
  else:
%</mp>
    if (picture tlist.t):
      for nx = 0 upto wd/tlist.t.dx:
        for ny = 0 upto ht/tlist.t.dy:
          addto currentpicture
            also (tlist.t shifted
                  ((x,y) + (nx*tlist.t.dx, ny*tlist.t.dy)) t_);
        endfor
      endfor
    else:
      errhelp "feynmf: your tiling has not been defined, "
            & "check spelling and reprocess!";
      errmessage "feynmf: tiling `" & str t & "' not known, "
               & "replaced by `shaded'"; 
      use_tile (shaded, x, y, wd, ht);
    fi
%<*mp>
  fi
%</mp>
enddef;
%    \end{macrocode}
% Shade a square enclosing the rectangle:
%    \begin{macrocode}
vardef shade_rectangle (expr dd, x, y, wd, ht) =
  save d, u, dx, dy, currentpen;
  pen currentpen;
  pickup pencircle scaled thin;
  d := max (floor (abs dd), 1);
  dx := max (wd, ht);
  dy := max (wd, ht);
  for u = 0 step d/dx until 1:
    if dd > 0:
      cdraw (x-d,y+u*dy-d)--(x+(1-u)*dx+d,y+dy+d);
      cdraw (x+u*dx-d,y-d)--(x+dx+d,y+(1-u)*dy+d);
    else:
      cdraw (x-d,y+u*dy+d)--(x+u*dx+d,y-d);
      cdraw (x+(1-u)*dx-d,y+dy+d)--(x+dx+d,y+(1-u)*dy-d);
    fi
  endfor
enddef;
%    \end{macrocode}
% Syntatic sugar:
%    \begin{macrocode}
def addto_tile (suffix t) =
  addto tlist.t
enddef;
%    \end{macrocode}
%
% Construct a tile from a ASCII picture:
%    \begin{macrocode}
vardef tile_from_string (suffix t) (expr str) =
  tile_grain := max (floor tile_grain, 1);
  save grain, mx, x, y, n, c, pic;
  string c;
  picture pic;
  pic := nullpicture;
  grain := tile_grain;
  mx := 0;
  x := 0;
  y := 0;
  for n := 1 upto length str:
    c := substring (n-1,n) of str;
    if c = "/":
      mx := max (mx, x);
      y := y+1;
      x := 0;
    elseif c = "*":
      addto pic also (unitpixel shifted (x,-y) t_);
      x := x+1;
    elseif c = ".":
      x := x+1;
    fi
  endfor
  def_tile (t, grain*mx, grain*(y+1));
  addto_tile (t) also (pic shifted (0,y) scaled grain t_);
  pic := nullpicture;
enddef;
%    \end{macrocode}
%
% Some standard tiles:
%    \begin{macrocode}
tile_from_string (gray10,
  "  ...  /"&
  "  .*.  /"&
  "  ...  ");
%    \end{macrocode}
%    \begin{macrocode}
tile_from_string (gray25,
  "  ..  /"&
  "  *.  ");
%    \end{macrocode}
%    \begin{macrocode}
tile_from_string (gray50,
  "  .*  /"&
  "  *.  ");
%    \end{macrocode}
%    \begin{macrocode}
tile_from_string (gray75,
  "  **  /"&
  "  .*  ");
%    \end{macrocode}
%    \begin{macrocode}
tile_from_string (gray90,
  "  ***  /"&
  "  *.*  /"&
  "  ***  ");
%    \end{macrocode}
%
% The |shaded| and |hatched| tiles are handled specially:
% \begin{itemize}
%   \item{} the tiling approach is device dependent and diagonal lines
%     will not look nice if drawn to coarsely.
%   \item{} in \MP, we need to conserve memory, because the tiling
%     approach will quickly exceed \MP's main memory.  The solution is
%     to intercept |use_tile|, as done above.
% \end{itemize}
%    \begin{macrocode}
%<*!mp>
def_tile (shaded, 4thin, 4thin);
pickup pencircle scaled thin;
begin_sketch
  save dx, dy;
  (dx,dy) = (tlist.shaded.dx,tlist.shaded.dy);
  shade_rectangle (dx, 0, 0, dx, dy);
  cullit;
  fill unitsquare xscaled dx yscaled dy;
  cull currentpicture keeping (2,infinity);
  tlist.shaded := currentpicture;
end_sketch;
%    \end{macrocode}
%
%    \begin{macrocode}
def_tile (hatched, 5thin, 5thin);
begin_sketch
  save dx, dy;
  (dx,dy) = (tlist.hatched.dx,tlist.hatched.dy);
  shade_rectangle (dx, 0, 0, dx, dy);
  shade_rectangle (-dx, 0, 0, dx, dy);
  cullit;
  fill unitsquare xscaled dx yscaled dy;
  cull currentpicture keeping (2,infinity);
  tlist.hatched := currentpicture;
end_sketch;
%</!mp>
%    \end{macrocode}
%
% Halftoning is tricky, this solution is not perfect yet.  The idea is
% to use highly nonlinear function for displacing adjacent, in order
% to avoid regular patterns in thinly populated tiles.  The random
% number solution works somehow, but hand crafted regular patterns are
% still superior.
%    \begin{macrocode}
%<*!mp>
vardef make_halftone (suffix t) (expr g, wd, ht) =
  tile_grain := max (floor tile_grain, 1);
  if (halftone_cache_g <> g)
     or (halftone_cache_grain <> tile_grain)
     or (halftone_cache_wd <> wd)
     or (halftone_cache_ht <> ht):
    halftone_cache_g := g;
    halftone_cache_grain := tile_grain;
    halftone_cache_wd := wd;
    halftone_cache_ht := ht;
    grain := tile_grain;
    def_tile (t, grain*wd, grain*ht);
    if g <= 0:
      addto_tile (t) contour unitsquare xscaled wd yscaled ht scaled grain t_;
    elseif g < 1:
      save period, offset, b, w;
      period := max (1/g, 1/(1-g));
      offset := wd - (period * ceiling (wd/period)) mod wd;
      b := 0;
      w := 0;
      randomseed := halftone_randomseed;
      for y = 0 upto ht-1:
        for x = 0 upto wd-1:
          if w > g*(b+w):
            addto_tile (t) also (unitpixel
              shifted (floor (x + y*offset + 2*uniformdeviate period)
                       mod wd, y)
              scaled grain t_);
            b := b+1;
          else:
            w := w+1;
          fi;
        endfor
      endfor
      cull tlist.t keeping (1,infinity);
    fi
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
halftone_cache_g := -1;
halftone_cache_grain := -1;
halftone_cache_wd := -1;
halftone_cache_ht := -1;
halftone_randomseed := 137;
%</!mp>
%    \end{macrocode}
% Halftoning is trivial in \MP:
%    \begin{macrocode}
%<*mp>
vardef make_halftone (suffix t) (expr g, wd, ht) =
  def_tile (t, wd, ht);
  addto tlist.t contour unitsquare
    xscaled wd yscaled ht withcolor ((1-g)*foreground + g*background)
enddef;
%</mp>
%    \end{macrocode}
%
%    \begin{macrocode}
vardef tile (suffix t) (expr p) =
  save u, x, y, max_x, min_x, max_y, min_y, xx, yy;
  -max_x = -max_y = min_x = min_y = infinity;
  for u = 0 step 0.1 until length p:
    x := xpart (point u of p);
    y := ypart (point u of p);
    max_x := max(max_x, x);   
    max_y := max(max_y, y);
    min_x := min(min_x, x);   
    min_y := min(min_y, y);   
  endfor
%<*!mp>
%    \end{macrocode}
% Give the already drawn parts a weight of 2.  Then they will survive
% along with the intersection of the tiling and the interior of the
% path |p|:
%    \begin{macrocode}
  cullit withweight 2;
  use_tile (t, min_x, min_y, max_x-min_x, max_y-min_y);
  fill p;
  cull currentpicture keeping (2,infinity)
%</!mp>
%<*mp>
  begin_sketch
    use_tile (t, min_x, min_y, max_x-min_x, max_y-min_y);
    clip currentpicture to p;
  end_sketch;
  use_sketch;
%</mp>
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef drawtile (suffix t) (expr p) =
  tile (t, p);
  cdraw p
enddef;
%    \end{macrocode}
%
% Use \MP's haltoning features (if available), because they are much
% more efficient: 
%    \begin{macrocode}
%<*!mp>
vardef use_halftone (expr g, x, y, wd, ht) =
  make_halftone (__tmp_tile__, g, 50, 50);
  use_tile (__tmp_tile__, x, y, wd, ht)
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef halftone (expr g, p) =
  make_halftone (__tmp_tile__, g, 50, 50);
  tile (__tmp_tile__, p)
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef drawhalftone (expr g, p) =
  halftone (g, p);
  cdraw p
enddef;
%</!mp>
%    \end{macrocode}
%
%    \begin{macrocode}
%<*mp>
vardef use_halftone (expr g, x, y, wd, ht) =
  fill unitsquare xscaled wd yscaled ht
    shifted (x,y) withcolor ((1-g)*foreground + g*background)
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef halftone (expr g, p) =
  fill p withcolor ((1-g)*foreground + g*background)
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef drawhalftone (expr g, p) =
  fill p withcolor ((1-g)*foreground + g*background);
  cdraw p
enddef;
%</mp>
%    \end{macrocode}
%
%    \begin{macrocode}
vardef shade expr p =
  tile (shaded, p)
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef hatch expr p =
  tile (hatched, p)
enddef;
%    \end{macrocode}
%
% Here come |filldraw|'s sisters:
%    \begin{macrocode}
vardef emptydraw expr p =
  cullit;
  unfill p;
  cullit;
  cdraw p;
enddef;
vardef shadedraw expr p =
  cullit;
  unfill p;
  cullit;
  shade p;
  cdraw p;
enddef;
vardef hatchdraw expr p =
  cullit;
  unfill p;
  cullit;
  hatch p;
  cdraw p;
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Arrows}
% \label{sec:arrows}
%
% John Hobby has a particulary nice |arrowhead| macro in plain \MP.
% Some variations on that theme adapted to our needs are here.
% \changes{v0.5}{1994/10/20}{New arrows, which look better on curved arcs.}
% Firstly centered on fraction |frac| of |p|:
% \changes{v0.99}{1995/05/04}{%
%   More general arrows \texttt{marrow}, \texttt{harrow} and
%   \texttt{tarrow} with reference
%   points in middle, at the head and at the tail, respectively.}
%    \begin{macrocode}
vardef marrow (expr p, frac) =
  save a, t, z;
  pair z;
  a = angle direction frac*length(p) of p;
  z = point frac*length(p) of p;
  (t1,whatever) = p intersectiontimes
    (halfcircle scaled 2/3arrow_len rotated (a+90) shifted z);
  (t2,whatever) = p intersectiontimes
    (halfcircle scaled 4/3arrow_len rotated (a-90) shifted z);
  arrow_head (p, t1, t2, arrow_ang)
enddef;
%    \end{macrocode}
% secondly with reference point at the tail:
%    \begin{macrocode}
vardef tarrow (expr p, frac) =
  save a, t, z;
  pair z;
  t1 = frac*length p;
  a = angle direction t1 of p;
  z = point t1 of p;
  (t2,whatever) = p intersectiontimes
    (halfcircle scaled 2arrow_len rotated (a-90) shifted z);
  arrow_head (p, t1, t2, arrow_ang)
enddef;
%    \end{macrocode}
% and finally with reference point at the head:
%    \begin{macrocode}
vardef harrow (expr p, frac) =
  save a, t, z;
  pair z;
  t2 = frac*length p;
  a = angle direction t2 of p;
  z = point t2 of p;
  (t1,whatever) = p intersectiontimes
     (halfcircle scaled 2arrow_len rotated (a+90) shifted z);
  arrow_head (p, t1, t2, arrow_ang)
enddef;
%    \end{macrocode}
% Construct an arrowhead on path |p|, ranging from |from| to |to| with
% opening angle |ang|:
% compatibility:
%    \begin{macrocode}
vardef arrow_head (expr p, from, to, ang) =
  save tip, ap, t;
  pair tip;
  path ap;
  t1 := from;
  t2 := to;
%    \end{macrocode}
% |from| and |to| may come from an |intersectiontimes|.  This
% could have failed, typically if the path is too short: protect
% against it.
% \changes{v0.6}{1994/10/21}{Fix arrows on too short arcs.}
%    \begin{macrocode}
  if t1 = -1: t1 := 0; fi
  if t2 = -1: t2 := infinity; fi
  tip = point t2 of p;
  ap = subpath (t1,t2) of p shifted -tip;
  (ap rotated ang
    forced_join reverse ap rotated -ang
    -- cycle) shifted tip
enddef;
%    \end{macrocode}
% The old, plainly centered |arrow|.  Retain it for convenience and
% compatibility:
%    \begin{macrocode}
vardef arrow expr p =
  marrow (p, .5)
enddef;
%    \end{macrocode}
% Join two paths |p| and |q| even if they don't fit exactly by
% adjusting their common point.  This is necessary in |arrow| because
% rounding errors might induce a small mismatch even if we \emph{know}
% that they should match theoretically.  This is certainly a kludge
% and should be used with care, but it works.
%    \begin{macrocode}
tertiarydef p forced_join q =
  subpath (0, length p - 1) of p
  & point (length p - 1) of p
    .. controls postcontrol (length p - 1) of p
                and precontrol infinity of p
  .. .5[point infinity of p, point 0 of q]
    .. controls postcontrol 0 of q and precontrol 1 of q
    .. point 1 of q
  & subpath (1, infinity) of q
enddef;
%    \end{macrocode}
%
% |cut_decors| expands to a subpath of |path_arg|, excluding the
% decoration at the vertices.
% \changes{v0.7}{1994/10/22}{Cut general vertex decorations.}
% \changes{v0.9}{1995/04/25}{%
%   Fix \texttt{cut\_decors} to work with tadpoles.}
%    \begin{macrocode}
vardef cut_decors (suffix from) (expr p) (suffix to) =
 subpath (if known from.decor.shape:
            xpart (p intersectiontimes
                     (from.decor.shape scaled from.decor.size
                                       shifted from.loc))
          else:
            0
          fi,
          if known to.decor.shape:
            length p 
              - xpart (reverse p intersectiontimes
                        (to.decor.shape scaled to.decor.size
                                        shifted to.loc))
          else:
             infinity
          fi) of p
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Blobs}
% \label{sec:blobs}
%
% The following functions are obsolete.  We keep them for a couple of
% releases but users should be aware that they can go away without any
% warning!
%
% The function |make_blob| is the working horse of |draw_blob|.
%    \begin{macrocode}
vardef make_blob (expr z_arg, diameter) =
 save p,currentpen; path p; pen currentpen;
 pickup pencircle scaled thick;
 p = fullcircle scaled diameter shifted z_arg;
 shadedraw p;
enddef;
%    \end{macrocode}
%
% |draw_blob (pair_arg, diameter)| draws a shaded blob of diameter
% |diameter| centered at |pair_arg|. The thickness of the border is
% controlled by the global variable |thick|.
%
% Hint: It saves time to draw blobs of the same size in sequence.
%    \begin{macrocode}
vardef draw_blob (expr z_arg, diameter) =
 if sketched_blob_diameter <> diameter: % drawn lately?
  begin_sketch make_blob (origin, diameter); end_sketch; % redo hard work!
  sketched_blob_diameter:= diameter;  % record it
 fi
 use_sketch shifted z_arg; % the easy way ...
enddef;
%    \end{macrocode}
%
% |force_new_blob| forces the redrawing of a blob of the same diameter
% (in case you only changed the shading parameters).
%    \begin{macrocode}
def force_new_blob = sketched_blob_diameter := -1; enddef;
force_new_blob;                                 % initialize it.
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Drawing}
% \label{sec:drawing}
%
% Easier than
% \begin{equation}
%   \int_0^1 dt \left\vert\frac{dx(t)}{dt}\right\vert
% \end{equation}
% with the integrand the square root of a fourth order polynomial, but
% sufficient for all practical purposes is
%    \begin{macrocode}
vardef pixlen (expr p, n) =
  for k=1 upto length(p): + segment_pixlen (subpath (k-1,k) of p, n) endfor
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef segment_pixlen (expr p, n) =
  for k=1 upto n: + abs (point k/n of p - point (k-1)/n of p) endfor
enddef;
%    \end{macrocode}
%
% |wiggly p| expands to a ``wiggled'' version of |p|. The
% slope of the wiggles is controlled by the global variable |wiggle_slope|,
% the length of the wiggles by the global variable |wiggly_len|.
% \changes{v1.08}{1996/09/01}{%
%   \texttt{wiggly}: integer number of wiggles for full path instead of
%   each segment.}
%    \begin{macrocode}
vardef wiggly expr p_arg =
 save wpp;
 numeric wpp;
 wpp = ceiling (pixlen (p_arg, 10) / wiggly_len) / length p_arg;
 for k=0 upto wpp*length(p_arg) - 1:
  point k/wpp of p_arg
       {direction k/wpp of p_arg rotated wiggly_slope} ..
  point (k+.5)/wpp of p_arg
       {direction (k+.5)/wpp of p_arg rotated - wiggly_slope} ..
 endfor
 if cycle p_arg: cycle else: point infinity of p_arg fi
enddef;
%    \end{macrocode}
%
% |curly p| expands to a ``curly'' version of |p|. The
% the length of the curls is controlled  by the global variable
% |curly_len|.
% \changes{v1.08}{1996/09/01}{%
%   \texttt{curly}: integer number of curls for full path instead of
%   each segment.}
%    \begin{macrocode}
vardef curly expr p =
 save cpp;
 numeric cpp;
 cpp := ceiling (pixlen (p, 10) / curly_len) / length p;
 if cycle p:
   for k=0 upto cpp*length(p) - 1:
     point (k+.33)/cpp of p
           {direction (k+.33)/cpp of p rotated 90} ..
     point (k-.33)/cpp of p
           {direction (k-.33)/cpp of p rotated -90} ..
   endfor
   cycle
 else:
   point 0 of p
         {direction 0 of p rotated -90} ..
   for k=1 upto cpp*length(p) - 1:
     point (k+.33)/cpp of p
           {direction (k+.33)/cpp of p rotated 90} ..
     point (k-.33)/cpp of p
           {direction (k-.33)/cpp of p rotated -90} ..
   endfor
   point infinity of p
         {direction infinity of p rotated 90}
 fi
enddef;
%    \end{macrocode}
%
% |zigzag p| expands to a ``zig-zag'' version of |p|. The
% the length of the zags is controlled  by the global variable
% |zigzag_len|.
% \changes{v0.9}{1995/04/26}{\texttt{zigzag}: new line style.}
% \changes{v1.08}{1996/09/01}{%
%   \texttt{zigzag}: integer number of zigzacs for full path instead of
%   each segment.}
%    \begin{macrocode}
vardef zigzag expr p =
 save zpp;
 numeric zpp;
 zpp = ceiling (pixlen (p, 10) / zigzag_len) / length p;
 if not cycle p:
   point 0 of p --
 fi
 for k = 0 upto zpp*length(p) - 1:
   point (k+1/3)/zpp of p shifted
     (zigzag_width
      * dir angle (direction (k+1/3)/zpp of p rotated 90)) --
   point (k+2/3)/zpp of p shifted
     (zigzag_width
      * dir angle (direction (k+2/3)/zpp of p rotated -90)) --
 endfor
 if cycle p:
   cycle
 else:
   point infinity of p
 fi
enddef;
%    \end{macrocode}
%
% An inventory of valid line styles is implemented as a hash table:
%    \begin{macrocode}
save vsty_hash;
%    \end{macrocode}
% This is a bit like |mode_def| in plain \MF{} but doesn't use an
% array of available modes: |style_def "foo"| will define a macro
% |draw_foo| drawing a line of a certain style along any given path:
%    \begin{macrocode}
def style_def suffix s =
  vsty_hash.s := 1;
  expandafter quote vardef scantokens ("draw_" & str s)
enddef;
%    \end{macrocode}
%
% Let \MF{} do the lookup: suffices
%    \begin{macrocode}
vardef vsty_exists suffix s =
  known vsty_hash.s
enddef;
%    \end{macrocode}
% an strings
%    \begin{macrocode}
vardef valid_style expr s =
  expandafter vsty_exists scantokens (s)
enddef;
%    \end{macrocode}
%
% \changes{v0.8}{1994/11/21}{Enhance and streamline the line styles.}
% |phantom| lines are simple, even with arrows.
%    \begin{macrocode}
style_def phantom expr p =
  \
enddef;
style_def phantom_arrow expr p =
  cfill (arrow p);
enddef;
%    \end{macrocode}
% |plain| lines aren't harder.
%    \begin{macrocode}
style_def plain expr p =
  cdraw p;
enddef;
style_def plain_arrow expr p =
  cdraw p;
  cfill (arrow p);
enddef;
style_def dbl_plain expr p =
  draw_double p;
enddef;
style_def dbl_plain_arrow expr p =
  draw_double_arrow p;
enddef;
%    \end{macrocode}
% Wiggly lines use |wiggly| from above
%    \begin{macrocode}
style_def wiggly expr p =
  cdraw (wiggly p);
enddef;
style_def dbl_wiggly expr p =
  draw_double (wiggly p);
enddef;
%    \end{macrocode}
% and curly lines use |curly| from above
%    \begin{macrocode}
style_def curly expr p =
  cdraw (curly p);
enddef;
style_def dbl_curly expr p =
  draw_double (curly p);
enddef;
%    \end{macrocode}
% zig-zag ditto:
%    \begin{macrocode}
style_def zigzag expr p =
  cdraw (zigzag p);
enddef;
style_def dbl_zigzag expr p =
  draw_double (zigzag p);
enddef;
%    \end{macrocode}
% |draw_dashes p| draws a dashed line on |p|
% \changes{v0.4}{1994/05/27}{%
%   Rename the line style \texttt{dashed} to \texttt{dashes}, to avoid
%   a name clash with \MP.}
% \changes{v1.08}{1996/09/01}{%
%   \texttt{dashes}, \texttt{dbl\_dashes}:
%   integer number of dashes for full path instead of each segment.}
%    \begin{macrocode}
style_def dashes expr p =
 save dpp;
 numeric dpp;
 dpp = ceiling (pixlen (p, 10) / dash_len) / length p;
 for k=0 upto dpp*length(p) - 1:
  cdraw point k/dpp of p ..
   point (k+.5)/dpp of p;
 endfor
enddef;
style_def dbl_dashes expr p =
 save dpp;
 numeric dpp;
 dpp = ceiling (pixlen (p, 10) / dash_len) / length p;
 for k=0 upto dpp*length(p) - 1:
  draw_double point k/dpp of p ..
   point (k+.5)/dpp of p;
 endfor
enddef;
%    \end{macrocode}
%  Draw arrows for doubled lines larger:
% \changes{v1.06}{1995/05/29}{%
%   Draw larger arrows for doubled lines (scale factor 1.5).}
%    \begin{macrocode}
style_def dbl_dashes_arrow expr p =
  draw_dbl_dashes p;
  shrink (1.5);
    cfill (arrow p);
  endshrink;
enddef;
style_def dashes_arrow expr p =
  draw_dashes p;
  cfill (arrow p);
enddef;
%    \end{macrocode}
%
% |draw_dots p| draws a dotted line on |path_arg|
% \changes{v0.4}{1994/05/27}{%
%   Rename the line style \texttt{dotted} to \texttt{dots}, to be
%   consistent with \texttt{dashes}.}
% \changes{v1.08}{1996/09/01}{%
%   \texttt{dots}, \texttt{dbl\_dots}:
%   integer number of dots for full path instead of each segment.}
%    \begin{macrocode}
style_def dots expr p =
 save dpp;
 numeric dpp;
 dpp = ceiling (pixlen (p, 10) / dot_len) / length p;
 for k=0 upto dpp*length(p):
   cdrawdot point k/dpp of p;
 endfor
enddef;
style_def dbl_dots expr p =
  save dpp;
  numeric dpp;
  dpp = ceiling (pixlen (p, 10) / dot_len) / length p;
  begingroup
    save oldpen;
    pen oldpen;
    oldpen := currentpen;
    pickup oldpen scaled 3; % draw a thick linn
    for k=0 upto dpp*length(p):
      cdrawdot point k/dpp of p;
    endfor
    pickup oldpen;
    cullit;
    for k=0 upto dpp*length(p):
      undrawdot point k/dpp of p;
    endfor
    cullit; % and remove the stuffing
  endgroup;
enddef;
style_def dbl_dots_arrow expr p =
  draw_dbl_dots p;
  shrink (1.5);
    cfill (arrow p);
  endshrink;
enddef;
style_def dots_arrow expr p =
  draw_dots p;
  cfill (arrow p);
enddef;
%    \end{macrocode}
%
% |draw_double p| draws a double line.
%    \begin{macrocode}
style_def double expr p =
  save oldpen;
  pen oldpen;
  oldpen := currentpen;
%    \end{macrocode}
% draw a thick linn
%    \begin{macrocode}
  pickup oldpen scaled 3;
  ccutdraw p;
%    \end{macrocode}
% and remove the stuffing
%    \begin{macrocode}
  pickup oldpen;
  cullit; undraw p; cullit;
enddef;
style_def double_arrow expr p =
  draw_double p;
  shrink (1.5);
    cfill (arrow p);
  endshrink;
enddef;
%    \end{macrocode}
%
% Old aliases:
%    \begin{macrocode}
style_def vanilla expr p = draw_plain p enddef;
style_def fermion expr p = draw_plain_arrow p enddef;
style_def quark expr p = draw_plain_arrow p enddef;
style_def electron expr p = draw_plain_arrow p enddef;
style_def photon expr p = draw_wiggly p enddef;
style_def boson expr p = draw_wiggly p enddef;
style_def gluon expr p = draw_curly p enddef;
style_def heavy expr p = draw_dbl_plain_arrow p enddef;
style_def ghost expr p = draw_dots_arrow p enddef;
style_def scalar expr p = draw_dashes_arrow p enddef;
%    \end{macrocode}
% More old aliases:
%    \begin{macrocode}
vardef fermion expr path_arg =
  cfill (arrow (path_arg));
  path_arg
enddef;
vardef photon expr path_arg =
  wiggly path_arg
enddef;
vardef gluon expr path_arg =
  curly path_arg
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Graphs of vertices}
% \label{sec:graphs}
%
% Here is the fun part of \FMF: \emph{automagic} placement of
% vertices.
%    \begin{macrocode}
%tracingmacros:=1;
%tracingonline:=1;
tracingstats:=1;
%    \end{macrocode}
%
% You can say |vtracing:=true| to see what's going on.
%    \begin{macrocode}
boolean vtracing;
vtracing := false; % true
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Data structures}
%
% \DeleteShortVerb{\|}
% \MakeShortVerb{\"}
%
% \begin{table}[t]
%   \begin{center}
%   \begin{tabular}{|l|l|l|}\hline
%     Type      & Name          & Purpose \\\hline\hline
%     "numeric" & "vlist.first" & pointer to first vertex (usually 1) \\\hline
%     "numeric" & "vlist.last"  & pointer to last vertex (starts with 0) \\\hline
%     "string"  & "vlist["$i$"]name"          & symbolic name of the vertex\\\hline
%     "pair"    & "vlist["$i$"]loc"           & position of the vertex \\\hline
%     "string"  & "vlist["$i$"]lbl"           & label \\\hline
%     "numeric" & "vlist["$i$"]lbl.ang"       & angle \\\hline
%     "numeric" & "vlist["$i$"]lbl.dist"      & distance \\\hline
%     "path"    & "vlist["$i$"]decor.shape"   & shape of decoration\\\hline
%     "numeric" & "vlist["$i$"]decor.size"    & size of decoration\\\hline
%     "numeric" & "vlist["$i$"]decor.sty"     & filling style of decoration\\\hline
%     "numeric" & "vlist["$i$"]decor.ang"     & rotation angle\\\hline
%     "numeric" & "vlist["$i$"]fore"          & foreground color\\\hline
%     "numeric" & "vlist["$i$"]back"          & background color\\\hline
%     "numeric" & "vlist["$i$"]arc.first"     & pointer to first arc \\\hline
%     "numeric" & "vlist["$i$"]arc.last"      & pointer to last arc \\\hline
%     "numeric" & "vlist["$i$"]arc["$j$"]"    & $j$th arc of the $i$th vertex \\\hline
%     "string"  & "vlist["$i$"]arc["$j$"]sty" & style of the arc\\\hline
%     "numeric" & "vlist["$i$"]arc["$j$"]tns" & tension of the arc\\\hline
%     "string"  & "vlist["$i$"]arc["$j$"]lsr" & left, straight, right\\\hline
%     "string"  & "vlist["$i$"]arc["$j$"]lbl" & label\\\hline
%     "string"  & "vlist["$i$"]arc["$j$"]lbl.side"& side of the label\\\hline
%     "numeric" & "vlist["$i$"]arc["$j$"]lbl.dist"& distance of the label\\\hline
%     "numeric" & "vlist["$i$"]arc["$j$"]tag" & tag \\\hline
%     "numeric" & "vlist["$i$"]arc["$j$"]wd"  & width of the arc\\\hline
%     "color"   & "vlist["$i$"]arc["$j$"]fore"& foreground color\\\hline
%     "color"   & "vlist["$i$"]arc["$j$"]back"& background color\\\hline
%     "numeric" & "vlist["$i$"]constr.first"  & first constraint \\\hline
%     "numeric" & "vlist["$i$"]constr.last"   & last constraint \\\hline
%     "numeric" & "vlist["$i$"]constr["$j$"]" & constraint on $j$th arc \\\hline
%     "numeric" & "vlist["$i$"]poly.first"    & \\\hline
%     "numeric" & "vlist["$i$"]poly.last"     & \\\hline
%     "numeric" & "vlist["$i$"]poly["$j$"]"   & \\\hline
%     "numeric" & "vlist["$i$"]poly["$j$"]idx"& \\\hline
%   \end{tabular}
%   \end{center}
%   \caption{Vertex data structure}
%   \label{tab:VDS}
% \end{table}
%
% \begin{table}[t]
%   \begin{center}
%   \begin{tabular}{|l|l|l|}\hline
%     Type      & Name          & Purpose \\\hline\hline
%     "numeric" & "plist.first" & pointer to first polygon (usually 1) \\\hline
%     "numeric" & "plist.last"  & pointer to last polygon (starts with 0) \\\hline
%     "numeric" & "plist["$i$"]cnt"           & number of edges\\\hline
%     "numeric" & "plist["$i$"]vtx["$j$"]"    & pointer to the $j$th vertex\\\hline
%     "numeric" & "plist["$i$"]pull"          & distortion\\\hline
%     "string"  & "plist["$i$"]cona"          & connector after\\\hline
%     "string"  & "plist["$i$"]conb"          & connector before\\\hline
%     "string"  & "plist["$i$"]sty"           & filling\\\hline
%     "string"  & "plist["$i$"]lbl"           & label\\\hline
%     "numeric" & "plist["$i$"]lbl.ang"       & direction of the label\\\hline
%     "numeric" & "plist["$i$"]lbl.dist"      & distance of the label\\\hline
%     "color"   & "plist["$i$"]fore"          & foreground color\\\hline
%     "color"   & "plist["$i$"]back"          & background color\\\hline
%   \end{tabular}
%   \end{center}
%   \caption{Polygon data structure}
%   \label{tab:PDS}
% \end{table}
%
% \DeleteShortVerb{\"}
% \MakeShortVerb{\|}
%
% The data structure for our graph is shown in
% table~\ref{tab:VDS}\footnote{%
%   \begin{dubious}
%     \texttt{boolean vlist[i]arc[j]smooth} will indicate that this
%     arc belongs to a set of arcs which are to be smoothly connected.
%     The implementation will start by going to the strt of this set,
%     define a long smooth path and finally do the drawing on the
%     various subpaths.
%   \end{dubious}}.
% \MF{} turns out to be quite powerful, providing such constructs
% in an unconventional, but flexible and concise way.  While we use
% |save vhash| to forget all previously defined vertices, we leave
% |vlist| alone, because we will know from $|vlist.last| <
% |vlist.first|$ that it's empty.  Note that we can't |vardef| this
% because then the |save| would go inside a group.
%    \begin{macrocode}
def vinit =
  save vhash;
  numeric vlist.first, vlist.last;
  vlist.first := 1;
  vlist.last := 0;
  pair vlist[]loc;
  numeric vlist[]decor.size, vlist[]decor.ang,
    vlist[]arc.first, vlist[]arc.last,
    vlist[]arc[], vlist[]arc[]lsr,
    vlist[]arc[]tns, vlist[]arc[]lbl.dist,
    vlist[]arc[]tag, vlist[]arc[]wd, vlist[]arc[]rub,
    vlist[]constr.first, vlist[]constr.last,
    vlist[]constr[], lambdax[][], lambday[][];
  string vlist[]name, vlist[]lbl, vlist[]decor.sty,
    vlist[]arc[]sty, vlist[]arc[]lbl, vlist[]arc[]lbl.side;
  numeric vlist[]lbl.ang;
  path vlist[]decor.shape;
%<*mp>
  color vlist[]fore, vlist[]back,
    vlist[]arc[]fore, vlist[]arc[]back; 
%</mp>
%    \end{macrocode}
% Data structures for polygons (cf.~table~\ref{tab:PDS}):
% \changes{v1.06}{1996/05/24}{
%   New data structure \texttt{plist} and new entries
%   \texttt{vlist[]poly}.}
%    \begin{macrocode}
  numeric plist.first, plist.last, plist[]cnt, plist[]vtx[],
   plist[]pull, plist[]lbl.ang, plist[]lbl.dist;
  string plist[]lbl, plist[]sty, plist[]cona, plist[]conb;
  plist.first := 1;
  plist.last := 0;
  numeric vlist[]poly.first, vlist[]poly.last,
    vlist[]poly[], vlist[]poly[]idx;
  pair lambdap[][];
%<mp> color plist[]fore, plist[]back;
enddef;
%</base>
%    \end{macrocode}
% \begin{macro}{\fmfinit}
% We can also ask for initialization explicitely from \TeX{} (usually
% it is called implicitely by |\begin{fmfgraph}|).  This flushes the
% vertex table. 
%    \begin{macrocode}
%<style>\def\fmfinit{\fmfcmd{vinit;}}
%    \end{macrocode}
% \end{macro}
% Useful abstractions are: first for looping over all vertices
%    \begin{macrocode}
%<*base>
def vertices =
  vlist.first upto vlist.last
enddef;
%    \end{macrocode}
% second for looping over all arcs of vertex |i|
%    \begin{macrocode}
def varcs (text i) =
  vlist[i]arc.first upto vlist[i]arc.last
enddef;
%    \end{macrocode}
% and finally for looping over all constraints of vertex |i|
%    \begin{macrocode}
def vconstr (text i) =
  vlist[i]constr.first upto vlist[i]constr.last
enddef;
%    \end{macrocode}
%    \begin{macrocode}
def polygons =
  plist.first upto plist.last
enddef;
%    \end{macrocode}
%    \begin{macrocode}
def vpoly (text i) =
  vlist[i]poly.first upto vlist[i]poly.last
enddef;
%    \end{macrocode}
% Entering vertices is simple, but note that we have to make
% |vlist[|$i$|]loc| undefined, because it might be around from an
% earlier character still.
%    \begin{macrocode}
vardef venter suffix v =
  if not vexists v:
    vlist.last := vlist.last + 1;
    vhash.v := vlist.last;
    vlist[vhash.v]name := str v;
    vlist[vhash.v]loc := (whatever,whatever);
    vlist[vhash.v]arc.first := 1;
    vlist[vhash.v]arc.last := 0;
    vlist[vhash.v]constr.first := 1;
    vlist[vhash.v]constr.last := 0;
    vlist[vhash.v]lbl := "";
    vlist[vhash.v]lbl.ang := whatever;
    vlist[vhash.v]lbl.dist := 3thick;
%<*mp>
    vlist[vhash.v]fore := (whatever, whatever, whatever);
    vlist[vhash.v]back := (whatever, whatever, whatever);
%</mp>
    vlist[vhash.v]poly.first := 1;
    vlist[vhash.v]poly.last := 0;
  fi
enddef;
%    \end{macrocode}
%
% The next three \emph{are} trivial. Existence
%    \begin{macrocode}
vardef vexists suffix v =
  if known vhash.v: true else: false fi
enddef;
%    \end{macrocode}
% index
%    \begin{macrocode}
vardef vlookup suffix v =
  if vexists v: vhash.v else: 0 fi
enddef;
%    \end{macrocode}
% and location
%    \begin{macrocode}
vardef vloc suffix v =
  vlist[vlookup v]loc
enddef;
%    \end{macrocode}
% of vertices.  We use |vhash.v| instead of |v| so that we can clear
% the whole hash table with |save vhash|.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Constructing the graph}
%
% Connect the vertices in the list |vl| with lines of style |style|,
% allocating them if necessary.
%    \begin{macrocode}
vardef vconnect (expr linesty) (text vl) =
  save from, nfrom, nto, nopt, sty;
  numeric from, nfrom, nto, nopt;
  string sty;
  getopt (opt, linesty);
  sty := opt[opt.first];
  if known opt[opt.first]arg:
    message "feynmf: line styles don't take arguments.  "
             & "Argument `" & opt[opt.first]arg & "' ignored.";
  fi
  opt.first := opt.first + 1;
  forsuffixes to = vl:
    venter to;
    nto := vlookup to;
    if known nfrom:
%    \end{macrocode}
% Later, on page~\pageref{pg:vfreeze}, it will pay back to enter the
% arc \emph{both} ways: incoming \emph{and}
% outgoing:\label{pg:vconnect}
%    \begin{macrocode}
      vlist[nfrom]arc.last := vlist[nfrom]arc.last + 1;
      vlist[nfrom]arc[vlist[nfrom]arc.last] := nto;
      vlist[nfrom]arc[vlist[nfrom]arc.last]tns := 1;
%    \end{macrocode}
% But do not enter tadpoles twice.
% \changes{v0.9}{1995/04/25}{Do not enter tadpoles twice.}
%    \begin{macrocode}
      if nfrom <> nto:
        vlist[nto]arc.last := vlist[nto]arc.last + 1;
        vlist[nto]arc[vlist[nto]arc.last] := nfrom;
        vlist[nto]arc[vlist[nto]arc.last]tns := 1;
      fi
      vlist[nfrom]arc[vlist[nfrom]arc.last]lbl := "";
      vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side := "";
      vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist := 3thick;
%    \end{macrocode}
% Handle options, starting with an option |tension|:
%    \begin{macrocode}
      for nopt = opt.first upto opt.last:
        if match_option (opt[nopt], "tension"):
          get_argument (opt[nopt], scantokens (opt[nopt]arg),
                        vlist[nfrom]arc[vlist[nfrom]arc.last]tns);
          get_argument (opt[nopt], scantokens (opt[nopt]arg),
                        vlist[nto]arc[vlist[nto]arc.last]tns);
%    \end{macrocode}
% Handle |left|, |straight| and |right|, which ask for making a
% halfcircle detour on the specified side or going straight.  If given
% an optional argument, the halfcircle is pulled in or pushed out,
% according whether it is smaller or larger than 1.
% \changes{v0.5}{1994/10/20}{Accept optional argument for detours.}
%    \begin{macrocode}
        elseif match_option (opt[nopt], "left"):
          if known opt[nopt]arg:
            vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
              := - scantokens (opt[nopt]arg);
          else:
            vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := -1;
          fi
        elseif match_option (opt[nopt], "straight"):
          vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 0;
          ignore_argument (opt[nopt], opt[nopt]arg);
        elseif match_option (opt[nopt], "right"):
          if known opt[nopt]arg:
            vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
              := scantokens (opt[nopt]arg);
          else:
            vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 1;
          fi
%    \end{macrocode}
% Labels and which side they're on:
%    \begin{macrocode}
        elseif match_option (opt[nopt], "label"):
          get_argument (opt[nopt], opt[nopt]arg,
                        vlist[nfrom]arc[vlist[nfrom]arc.last]lbl);
        elseif match_option (opt[nopt], "label.side"):
          get_argument (opt[nopt], opt[nopt]arg,
                        vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side);
        elseif match_option (opt[nopt], "label.dist"):
          get_argument (opt[nopt], scantokens (opt[nopt]arg),
                        vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist);
%    \end{macrocode}
% Numeric tags for disambiguating multiple arcs:
% \changes{v0.9}{1995/04/19}{%
%   \texttt{tag} option for \texttt{vconnect}.}
%    \begin{macrocode}
        elseif match_option (opt[nopt], "tag"):
          if known opt[nopt]arg:
            vlist[nfrom]arc[vlist[nfrom]arc.last]tag
              := scantokens (opt[nopt]arg);
          else:
            vlist[nfrom]arc[vlist[nfrom]arc.last]tag := 0;
          fi
%    \end{macrocode}
% Width and color:
% \changes{v0.98}{1995/04/29}{Width and color.}
%    \begin{macrocode}
        elseif match_option (opt[nopt], "width"):
          get_argument (opt[nopt], scantokens (opt[nopt]arg),
                        vlist[nfrom]arc[vlist[nfrom]arc.last]wd);
%<*mp>
        elseif match_option (opt[nopt], "foreground"):
          get_argument (opt[nopt], scantokens (opt[nopt]arg),
                        vlist[nfrom]arc[vlist[nfrom]arc.last]fore);
        elseif match_option (opt[nopt], "background"):
          get_argument (opt[nopt], scantokens (opt[nopt]arg),
                        vlist[nfrom]arc[vlist[nfrom]arc.last]back);
%</mp>
%<*!mp>
        elseif match_option (opt[nopt], "foreground")
           or  match_option (opt[nopt], "background"):
          message "feynmf: color available with MetaPost only!";
%</!mp>
        elseif match_option (opt[nopt], "rubout"):
          if known opt[nopt]arg:
             vlist[nfrom]arc[vlist[nfrom]arc.last]rub
               := scantokens (opt[nopt]arg);
          else:
             vlist[nfrom]arc[vlist[nfrom]arc.last]rub := 2;
          fi
%    \end{macrocode}
% Ignore bogus options:
%    \begin{macrocode}
        else:
          ignore_option (opt[nopt], opt[nopt]arg);
        fi
      endfor
      handle_line_style (vlist[nfrom]arc[vlist[nfrom]arc.last]sty, sty);
      vlist[nto]arc[vlist[nto]arc.last]lsr
        := vlist[nfrom]arc[vlist[nfrom]arc.last]lsr;
    fi
%    \end{macrocode}
% Restart the loop:
%    \begin{macrocode}
    nfrom := nto;
  endfor
enddef;
%    \end{macrocode}
% \changes{v0.9}{1995/02/20}{Started collapsing duplicate code.}
% Avoid entering invalid linestyles into the tables, because the
% delayed evaluation will make errors harder to find (line numbers
% will be wrong):
%    \begin{macrocode}
vardef handle_line_style (suffix sty) (expr name) =
  if valid_style name:
    sty := name;
  else:
    errhelp "feynmf: your linestyle is not recognizable, "
          & "check spelling and reprocess!";
    errmessage "feynmf: line style `" & name & "' not known, "
             & "replaced by `vanilla'"; 
    sty := "vanilla";
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef get_argument (expr opt, arg) (suffix variable) =
  if known arg:
    variable := arg;
  else:
    message "feynmf: option `" & opt & "' needs an argument.  Ignored.";
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef ignore_argument (expr opt, arg) =
  if known arg:
    message "feynmf: option `" & opt & "' doesn't take an argument.  "
          & "Argument `" & arg & "' ignored.";
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef ignore_option (expr opt, arg)=
  if known arg:
    message "feynmf: ignoring option " & opt & "=" & arg & ".";
  else:
    message "feynmf: ignoring option " & opt & ".";
  fi
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmf}
%   \begin{macro}{\fmfn}
% Since |vconnect| wil be the most frequent macro, we give it the
% shortest \TeX{} command sequence:
% \changes{v0.98}{1995/04/26}{%
%   Protect MF's namespace with double underscores.}
% \changes{v0.98}{1995/04/26}{\texttt{\protect\bslash fmfn}: new command.}
%    \begin{macrocode}
%<*style>
\def\fmf#1#2{%
  \fmfbuf@={#1}%
  \fmfcmd{vconnect ("\the\fmfbuf@", \fmfpfx{#2});}}
\def\fmfn#1#2#3{
  \fmfbuf@={#1}%
  \fmfcmd{vconnectn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
%</style>
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%<*base>
vardef vconnectn (expr linesty) (suffix v) (expr n) =
  vconnect (linesty, vmklist (v, n));
enddef;
%    \end{macrocode}
%
% Here's how to deconstruct a graph: |vpath| returns an arc from
% |nfrom| to |nto|, if any.  If a suffix is given, it
% has to match the |tag| of the arc.
% \changes{v0.9}{1995/04/19}{%
%   \texttt{vpath}: new function.}
% \changes{v0.9}{1995/04/20}{%
%   \texttt{vpath}: new syntax.}
%    \begin{macrocode}
vardef vpath@# (suffix from, to) =
  save nfrom, nto, origin, index, unknown_path;
  numeric nfrom, nto, origin, index;
  path unknown_path;
  if (known vloc from) and (known vloc to):
    nfrom := vlookup from;
    nto := vlookup to;
    vmatch_path (nfrom, nto, maybe_empty@#);
    if (unknown origin) or (unknown index):
      vmatch_path (nto, nfrom, maybe_empty@#);
    fi
  fi
  if (known origin) and (known index):
    vbuild_cut_arc (origin, index)
  else:
    unknown_path
  fi
enddef;
%    \end{macrocode}
% Hack: this will expand to an |unknown| value if the suffix is empty
% and to the suffix otherwise.  We use it to implement an optional
% argument.
%    \begin{macrocode}
vardef maybe_empty@# =
  save _prefix;
  _prefix=137;
  if known _prefix@#:
    whatever
  else:
    @#
  fi
enddef;
%    \end{macrocode}
% This is not a real function but a convenience macro and has the side
% effect of setting |origin| and |index| if a match is found.
%    \begin{macrocode}
vardef vmatch_path (expr nfrom, nto, t) = 
  save i;
  for i = varcs (nfrom):
    if (vlist[nfrom]arc[i] = nto) and (known vlist[nfrom]arc[i]sty):
      if unknown t:
        origin := nfrom;
        index := i;
      else:
        if known vlist[nfrom]arc[i]tag:
          if vlist[nfrom]arc[i]tag = t:
            origin := nfrom;
            index := i;
          fi
        fi
      fi
    fi
  endfor
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vcyclen (expr sty) (suffix v) (expr n) =
  for $ = 1 upto n - 1:
    vconnect (sty, v[$], v[$+1]);
  endfor
  vconnect (sty, v[n], v[1]);
enddef;
%    \end{macrocode}
% And the reverse:
%    \begin{macrocode}
vardef vrcyclen (expr sty) (suffix v) (expr n) =
  vconnect (sty, v[1], v[n]);
  for $ = n downto 2:
    vconnect (sty, v[$], v[$-1]);
  endfor
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfcyclen}
%    \begin{macrocode}
%<*style>
\def\fmfcyclen#1#2#3{%
  \fmfbuf@={#1}%
  \fmfcmd{vcyclen ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
\def\fmfrcyclen#1#2#3{%
  \fmfbuf@={#1}%
  \fmfcmd{vrcyclen ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
%</style>
%    \end{macrocode}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Constraints}
%
% \begin{macro}{\fmfforce}
%   \begin{macro}{\fmfshift}
% Explicit placement and shifting of vertices is handled in \TeX{} with
%    \begin{macrocode}
%<*style>
\def\fmfforce#1#2{\fmfcmd{vforce ((#1), \fmfpfx{#2});}}
\def\fmfshift#1#2{\fmfcmd{vshift ((#1), \fmfpfx{#2});}}
%</style>
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% Force the vertex |v| to be placed at position |z|:
%    \begin{macrocode}
%<*base>
vardef vforce (expr z) (suffix v) =
  venter v;
  vlist[vlookup v]loc := z;
enddef;
%    \end{macrocode}
%
% Shift the vertex |v| by |z|:
%    \begin{macrocode}
vardef vshift (expr z) (text vl) =
  forsuffixes $=vl:
    if vexists $:
      vlist[vlookup $]loc := vlist[vlookup $]loc + z;
    fi
  endfor
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmffixed}
%   \begin{macro}{\fmffixedx}
%     \begin{macro}{\fmffixedy}
% \changes{v0.8}{1995/01/07}{New command: \texttt{\protect\bslash fmffixed}.}
% Place the first two arguments in the distance given by the third
% argument.
% \changes{v1.04}{1996/02/20}{%
%   \texttt{\protect\bslash fmffixedx},
%   \texttt{\protect\bslash fmffixedy}: new macros.}
%    \begin{macrocode}
%<*style>
\def\fmffixed#1#2{\fmfcmd{vconstraint ((#1), \fmfpfx{#2});}}
\def\fmffixedx#1#2{\fmfcmd{vconstraint (((#1),whatever), \fmfpfx{#2});}}
\def\fmffixedy#1#2{\fmfcmd{vconstraint ((whatever,(#1)), \fmfpfx{#2});}}
%</style>
%    \end{macrocode}
%     \end{macro}
%   \end{macro}
% \end{macro}
% This amounts to adding one or more constraints into the vertex data
% structure:
%    \begin{macrocode}
%<*base>
vardef vconstraint (expr z) (text vl) =
  save nfrom, nto;
  numeric nfrom, nto;
  forsuffixes to = vl:
    venter to;
    nto := vlookup to;
    if known nfrom:
      vlist[nfrom]constr.last := vlist[nfrom]constr.last + 1;
      vlist[nto]constr.last := vlist[nto]constr.last + 1;
      vlist[nfrom]constr[vlist[nfrom]constr.last] := nto;
      vlist[nto]constr[vlist[nto]constr.last] := nfrom;
      vlist[nto]loc = vlist[nfrom]loc + z;
    fi
    nfrom := nto;
  endfor
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Polygons}
%
% Define a polygon:
% \changes{v1.06}{1996/05/24}{
%   New function \texttt{vpolygon}: allocate a polygon.}
%    \begin{macrocode}
vardef vpolygon (expr psty) (suffix v) (text vl) =
  save nopt, csty, nfrom, nfrom_, nto, i, n, j;
  numeric nopt, nfrom, nfrom_, nto, i, n, j;
  string csty;
%    \end{macrocode}
% Allocate a fresh polygon:
%    \begin{macrocode}
  n := count (vl) + 1;
  plist.last := plist.last + 1;
  plist[plist.last]cnt := n;
  plist[plist.last]lbl := "";
  plist[plist.last]lbl.ang := whatever;
  plist[plist.last]lbl.dist := 0;
%    \end{macrocode}
% Parse the options:
%    \begin{macrocode}
  csty := "phantom";
  getopt (opt, psty);
  for nopt = opt.first upto opt.last:
    if match_option (opt[nopt], "filled"):
      get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]sty);
    elseif match_option (opt[nopt], "tension"):
      if known opt[nopt]arg:
        csty := csty & ",tension=" & opt[nopt]arg;
      else:
        message "feynmf: option `tension' needs an argument.  Ignored.";
      fi
    elseif match_option (opt[nopt], "label"):
      get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]lbl);
    elseif match_option (opt[nopt], "label.angle"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg),
                               plist[plist.last]lbl.ang);
    elseif match_option (opt[nopt], "label.dist"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg),
                               plist[plist.last]lbl.dist);
    elseif match_option (opt[nopt], "pull"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg),
                               plist[plist.last]pull);
    elseif match_option (opt[nopt], "cona"):
      get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]cona);
    elseif match_option (opt[nopt], "conb"):
      get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]conb);
    elseif match_option (opt[nopt], "smooth"):
      plist[plist.last]cona := "..";
      plist[plist.last]conb := "..";
      ignore_argument (opt[nopt], opt[nopt]arg);
%<*mp>
    elseif match_option (opt[nopt], "foreground"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg),
                               plist[plist.last]fore);
    elseif match_option (opt[nopt], "background"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg),
                               plist[plist.last]back);
%</mp>
%<*!mp>
    elseif match_option (opt[nopt], "foreground")
       or  match_option (opt[nopt], "background"):
      message "feynmf: color available with MetaPost only!";
%</!mp>
    elseif match_option (opt[nopt], "phantom"):
      plist[plist.last]sty := "phantom";
    elseif match_option (opt[nopt], "empty"):
      plist[plist.last]sty := "empty";
    elseif match_option (opt[nopt], "full"):
      plist[plist.last]sty := "full";
    elseif match_option (opt[nopt], "hatched"):
      plist[plist.last]sty := "hatched";
    elseif match_option (opt[nopt], "shaded"):
      plist[plist.last]sty := "shaded";
    else:
      ignore_option (opt[nopt], opt[nopt]arg);
  fi
  endfor
  canonicalize_filling plist[plist.last]sty;
%    \end{macrocode}
% Enter the vertices:
%    \begin{macrocode}
  vconnect (csty, v, vl, v);
  i := 1;
  forsuffixes to = v, vl, v:
    nto := vlookup to;
    if known nfrom:
%    \end{macrocode}
% Enter a constraint:
% \begin{equation}
%   \vec v_{i+1} = \vec v_{i}
%             + R(2\pi/n_P) \left( \vec v_{i} - \vec v_{i-1} \right)
% \end{equation}
%    \begin{macrocode}
      if known nfrom_:
        vlist[nto]loc = vlist[nfrom]loc
          + (vlist[nfrom]loc - vlist[nfrom_]loc) rotated (360/n);
      fi
      vlist[nto]poly.last := vlist[nto]poly.last + 1;
      vlist[nto]poly[vlist[nto]poly.last] := plist.last;
      vlist[nto]poly[vlist[nto]poly.last]idx := i;
      plist[plist.last]vtx[i] := nto;
      i := i + 1;
      nfrom_ := nfrom;
    fi
    nfrom := nto;
  endfor
enddef;
%    \end{macrocode}
%
% \changes{v1.06}{1996/05/24}{
%   New function \texttt{canonicalize\_filling}: abstracted from
%   \texttt{vvertex}.}
%    \begin{macrocode}
vardef canonicalize_filling suffix f =
  if known f:
    if is_a_number (f):
      if scantokens f <= 1:
        f :=
        if scantokens f = 1:
          "full"
        elseif scantokens f > 0:
          "shaded"
        elseif scantokens f = 0:
          "empty"
        else:
          "hatched"
        fi;
      fi
    fi
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vpolygonn (expr sty) (suffix v) (expr n) =
  vpolygon (sty, v[1], for $=2 upto n-1: v[$], endfor v[n]);
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vrpolygonn (expr sty) (suffix v) (expr n) =
  vpolygon (sty, v[n], for $=n-1 downto 2: v[$], endfor v[1]);
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfpoly}
%   \begin{macro}{\fmfpolyn}
%     \begin{macro}{\fmfrpolyn}
% \changes{v1.06}{1996/05/24}{%
%   New macros \texttt{\protect\bslash fmfpoly}
%   \texttt{\protect\bslash fmfpolyn},
%   \texttt{\protect\bslash fmfrpolyn}.}
%    \begin{macrocode}
%<*style>
\def\fmfpoly#1#2{%
  \fmfbuf@={#1}%
  \fmfcmd{vpolygon ("\the\fmfbuf@", \fmfpfx{#2});}}
\def\fmfpolyn#1#2#3{%
  \fmfbuf@={#1}%
  \fmfcmd{vpolygonn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
\def\fmfrpolyn#1#2#3{%
  \fmfbuf@={#1}%
  \fmfcmd{vrpolygonn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
%    \end{macrocode}
%     \end{macro}
%   \end{macro}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Internal vertices}
%
% \begin{macro}{\fmflabel}
%    \begin{macrocode}
\def\fmflabel#1#2{%
  \fmfbuf@={#1}%
  \fmfcmd{vlabel ("\the\fmfbuf@", \fmfpfx{#2});}}
%</style>
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%<*base>
vardef vlabel (expr s) (suffix v) =
  venter v;
  vlist[vlookup v]lbl := s;
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfv}
%    \begin{macrocode}
%<*style>
\def\fmfv#1#2{%
  \fmfbuf@={#1}%
  \fmfcmd{vvertex ("\the\fmfbuf@", \fmfpfx{#2});}}
\def\fmfvn#1#2#3{%
  \fmfbuf@={#1}%
  \fmfcmd{vvertexn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
%</style>
%    \end{macrocode}
% \end{macro}
%
% \changes{v0.7}{1994/10/22}{%
%  \texttt{blob} and \texttt{dot} options obsolete, handle generalized
%  decorations (polygons).}
%    \begin{macrocode}
%<*base>
vardef vvertex (expr vtxsty) (text vl) =
  save nopt, sty, arg;
  numeric nopt, arg;
  string sty;
  getopt (opt, vtxsty);
  forsuffixes v = vl:
    venter v;
    n := vlookup v;
    for nopt = opt.first upto opt.last:
      handle_vertex_option (vlist[n], opt[nopt], opt[nopt]arg);
    endfor
  endfor
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef handle_vertex_option (suffix v) (expr opt, arg) =
  if match_option (opt, "label"):
    get_argument (opt, arg, v.lbl);
  elseif match_option (opt, "label.angle"):
    get_argument (opt, scantokens (arg), v.lbl.ang);
  elseif match_option (opt, "label.dist"):
    get_argument (opt, scantokens (arg), v.lbl.dist);
  elseif match_option (opt, "decoration.shape"):
    if known arg:
      make_decor_shape (v.decor.shape, arg);
    else:
      message "feynmf: option `decor.shape' needs an argument.  Ignored.";
    fi
%    \end{macrocode}
% \MP{} has |filled| reserved, use |sty| instead.
%    \begin{macrocode}
  elseif match_option (opt, "decoration.filled"):
    get_argument (opt, arg, v.decor.sty);
%    \end{macrocode}
% Continue to support the old numeric argument:
%    \begin{macrocode}
    canonicalize_filling v.decor.sty;
  elseif match_option (opt, "decoration.size"):
    get_argument (opt, scantokens (arg), v.decor.size);
  elseif match_option (opt, "decoration.angle"):
    get_argument (opt, scantokens (arg), v.decor.ang);
%<*mp>
  elseif match_option (opt, "foreground"):
    get_argument (opt, scantokens (arg), v.fore);
  elseif match_option (opt, "background"):
    get_argument (opt, scantokens (arg), v.back);
%</mp>
%<*!mp>
  elseif match_option (opt, "foreground")
     or  match_option (opt, "background"):
    message "feynmf: color available with MetaPost only!";
%</!mp>
%    \end{macrocode}
% Ignore bogus options:
%    \begin{macrocode}
  else:
    ignore_option (opt, arg);
  fi
enddef;
%    \end{macrocode}
% Maybe we should replace this long switch by a hashing scheme:
%    \begin{macrocode}
vardef make_decor_shape (suffix p) (expr n) =
  if match_prefix (n, "circle"): p := fullcircle;
  elseif match_prefix (n, "square"):
    p := unitsquare shifted -(.5,.5);
  elseif match_prefix (n, "cross"): p := polycross 4;
  elseif match_prefix (n, "triangle"): p := polygon 3;
  elseif match_prefix (n, "triagon"): p := polygon 3;
  elseif match_prefix (n, "diamond"): p := polygon 4;
  elseif match_prefix (n, "tetragon"): p := polygon 4;
  elseif match_prefix (n, "pentagon"): p := polygon 5;
  elseif match_prefix (n, "hexagon"): p := polygon 6;
  elseif match_prefix (n, "triagram"): p := polygram 3;
  elseif match_prefix (n, "tetragram"): p := polygram 4;
  elseif match_prefix (n, "pentagram"): p := polygram 5;
  elseif match_prefix (n, "hexagram"): p := polygram 6;
  elseif match_prefix (n, "triacross"): p := polycross 3;
  elseif match_prefix (n, "tetracross"): p := polycross 4;
  elseif match_prefix (n, "pentacross"): p := polycross 5;
  elseif match_prefix (n, "hexacross"): p := polycross 6;
  else:
    if feynmfwizard:
      p := scantokens(n);
    else:
      message "feynmf: invalid argument `" & n
            & "' to option `decor.shape'.  Ignored.";
    fi
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef is_a_number expr s =
  save n;
  if known s:
    (true
     for n = 1 upto length s:
       and ((substring (n-1,n) of s = ".")
            or (substring (n-1,n) of s = "-")
            or isdigit substring (n-1,n) of s)
      endfor)
  else:
    false
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vvertexn (expr vtxsty) (suffix v) (expr n) =
  vvertex (vtxsty, vmklist (v, n));
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfblob}
%   \begin{macro}{\fmfdot}
% We can decorate vertices with ``blobs'' and dots from \TeX{} with
% the command sequences:
%    \begin{macrocode}
%<style>\def\fmfblob#1#2{\fmfcmd{vblob ((#1), \fmfpfx{#2});}}
%<style>\def\fmfdot#1{\fmfcmd{vdot (\fmfpfx{#1});}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% The vertices in the list |vl| will be drawn with a blob of diameter
% |bd|:
%    \begin{macrocode}
%<*base>
vardef vblob (expr bd) (text vl)=
  forsuffixes $=vl:
    if not vexists $: venter $; fi
    vlist[vlookup $]decor.shape := fullcircle;
    vlist[vlookup $]decor.size := bd;
    vlist[vlookup $]decor.sty := "shaded";
 endfor
enddef;
%    \end{macrocode}
%
% The vertices in the list |vl| will be drawn with a dot.
%    \begin{macrocode}
vardef vdot (text vl)=
  forsuffixes $=vl:
    if not vexists $: venter $; fi
    vlist[vlookup $]decor.shape := fullcircle;
    vlist[vlookup $]decor.size := dot_size;
    vlist[vlookup $]decor.sty := "full";
 endfor
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vdotn (suffix v) (expr n) =
  vdot (vmklist (v, n));
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vblobn (suffix v) (expr n) =
  vblob (vmklist (v, n));
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfdotn}
% Place |#2| blobs or dots at $|v|_1,\ldots,|v|_{|#1|}$.
%    \begin{macrocode}
%<style>\def\fmfblobn#1#2{\fmfcmd{vblobn (\fmfpfx{#1}, #2);}}
%<style>\def\fmfdotn#1#2{\fmfcmd{vdotn (\fmfpfx{#1}, #2);}}
%    \end{macrocode}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{External vertices}
%
% \begin{macro}{\fmfleft}
%   \begin{macro}{\fmfright}
%     \begin{macro}{\fmfbottom}
%       \begin{macro}{\fmftop}
%         \begin{macro}{\fmfsurround}
% External vertices are positioned thusly in \TeX{}:
% \changes{v0.8}{1994/10/27}{%
%   Make \texttt{\protect\bslash fmfincoming} and
%   \texttt{\protect\bslash fmfoutgoing} obsolescent.
%   Provide \texttt{\protect\bslash fmfleft},
%   \texttt{\protect\bslash fmfright},
%   \texttt{\protect\bslash fmfbottom}
%   and \texttt{\protect\bslash fmftop} instead.}
% \changes{v0.8}{1994/12/29}{Fix typos in
%   \texttt{\protect\bslash fmfbottom}
%   and \texttt{\protect\bslash fmftop}.}
%    \begin{macrocode}
%<*style>
\def\fmfleft#1{\fmfcmd{vleft (\fmfpfx{#1});}}
\def\fmfright#1{\fmfcmd{vright (\fmfpfx{#1});}}
\def\fmfbottom#1{\fmfcmd{vbottom (\fmfpfx{#1});}}
\def\fmftop#1{\fmfcmd{vtop (\fmfpfx{#1});}}
\let\fmfincoming\fmfleft
\let\fmfoutgoing\fmfright
\def\fmfsurround#1{\fmfcmd{vsurround (\fmfpfx{#1});}}
%</style>
%    \end{macrocode}
%         \end{macro}
%       \end{macro}
%     \end{macro}
%   \end{macro}
% \end{macro}
% Here are the ``galleries'' we're hooking our external vertices on
% (see figure~\ref{fig:curvedgalleries}):
% \changes{v0.99}{1995/05/04}{%
%   Adjust galleries to subgraphs.}
%    \begin{macrocode}
%<*base>
vardef curved_left_gallery = .9[se,sw] .. .5[sw,nw] .. .1[nw,ne] enddef;
vardef curved_right_gallery = .9[sw,se] .. .5[se,ne] .. .1[ne,nw] enddef;
vardef curved_bottom_gallery = .9[nw,sw] .. .5[sw,se] .. .1[se,ne] enddef;
vardef curved_top_gallery = .9[sw,nw] .. .5[nw,ne] .. .1[ne,se] enddef;
vardef curved_surround_gallery =
  superellipse (.5[se,ne], .5[ne,nw], .5[nw,sw], .5[sw,se], .75)
enddef;
%    \end{macrocode}
% Here are their straight brothers (see
% figure~\ref{fig:straightgalleries}): 
%    \begin{macrocode}
vardef straight_left_gallery = sw -- nw enddef;
vardef straight_right_gallery = se -- ne enddef;
vardef straight_bottom_gallery = sw -- se enddef;
vardef straight_top_gallery = nw -- ne enddef;
vardef straight_surround_gallery =
   .5[se,ne] -- ne -- .5[ne,nw] -- nw
     -- .5[nw,sw] -- sw -- .5[sw,se] -- se -- cycle
enddef;
%    \end{macrocode}
% And here's how to switch:
%    \begin{macrocode}
vardef curved_galleries =
  vardef left_gallery = curved_left_gallery enddef;
  vardef right_gallery = curved_right_gallery enddef;
  vardef bottom_gallery = curved_bottom_gallery enddef;
  vardef top_gallery = curved_top_gallery enddef;
  vardef surround_gallery = curved_surround_gallery enddef;
enddef;
vardef straight_galleries =
  vardef left_gallery = straight_left_gallery enddef;
  vardef right_gallery = straight_right_gallery enddef;
  vardef bottom_gallery = straight_bottom_gallery enddef;
  vardef top_gallery = straight_top_gallery enddef;
  vardef surround_gallery = straight_surround_gallery enddef;
enddef;
%    \end{macrocode}
% The \MF{} code which does the hard work for the above
% \TeX{} macros
%    \begin{macrocode}
vardef vleft (text vl) = vdistribute (left_gallery, vl) enddef;
vardef vright (text vl) = vdistribute (right_gallery, vl) enddef;
vardef vbottom (text vl) = vdistribute (bottom_gallery, vl) enddef;
vardef vtop (text vl) = vdistribute (top_gallery, vl) enddef;
vardef vsurround (text vl) = vdistribute (surround_gallery, vl) enddef;
%    \end{macrocode}
%
% Curved galleries are the default
%    \begin{macrocode}
curved_galleries;
%</base>
%    \end{macrocode}
% \begin{macro}{\fmfcurved}
%   \begin{macro}{\fmfstraight}
% but here's how to switch:
% \changes{v0.98}{1995/04/29}{shortened galleries switch.}
%    \begin{macrocode}
%<*style>
\def\fmfcurved{\fmfcmd{curved_galleries;}}
\def\fmfstraight{\fmfcmd{straight_galleries;}}
\let\fmfcurvedgalleries\fmfcurved
\let\fmfstraightgalleries\fmfstraight
%</style>
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% Distribute the vertices in the list |vl| evenly along the path |p|:
%    \begin{macrocode}
%<*base>
vardef vdistribute (expr p) (text vl) =
  save numv, len, off;
  numeric numv, len, off;
  numv = count (vl);
%    \end{macrocode}
% If the path is cyclic, place the first vertex twice:
%    \begin{macrocode}
  if cycle p: numv := numv + 1; fi
  len := length (p);
  if numv = 1:
    vforce (point len/2 of p, vl);
  else:
    off := 0;
    forsuffixes $ = vl:
      vforce (point off of p, $);
      off := off + len/(numv-1);
    endfor
  fi
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfleftn}
%   \begin{macro}{\fmfrightn}
%     \begin{macro}{\fmfbottomn}
%       \begin{macro}{\fmftopn}
%         \begin{macro}{\fmfsurroundn}
% A short cut:
%    \begin{macrocode}
%<*style>
\def\fmfleftn#1#2{\fmfcmd{vleftn (\fmfpfx{#1}, #2);}}
\def\fmfrightn#1#2{\fmfcmd{vrightn (\fmfpfx{#1}, #2);}}
\def\fmfbottomn#1#2{\fmfcmd{vbottomn (\fmfpfx{#1}, #2);}}
\def\fmftopn#1#2{\fmfcmd{vtopn (\fmfpfx{#1}, #2);}}
\let\fmfincomingn\fmfleftn
\let\fmfoutgoingn\fmfrightn
\def\fmfsurroundn#1#2{\fmfcmd{vsurroundn (\fmfpfx{#1}, #2);}}
%</style>
%    \end{macrocode}
%         \end{macro}
%       \end{macro}
%     \end{macro}
%   \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%<*base>
def vmklist (suffix v) (expr n) =
  for $ = 1 upto n-1: v[$], endfor v[n]
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vleftn (suffix v) (expr n) =
  vleft (vmklist (v, n));
enddef;
vardef vrightn (suffix v) (expr n) =
  vright (vmklist (v, n));
enddef;
vardef vbottomn (suffix v) (expr n) =
  vbottom (vmklist (v, n));
enddef;
vardef vtopn (suffix v) (expr n) =
  vtop (vmklist (v, n));
enddef;
vardef vsurroundn (suffix v) (expr n) =
  vsurround (vmklist (v, n));
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmffor}
%   \begin{macro}{\endfmffor}
%    \begin{macrocode}
%<*style>
\def\fmffor#1#2#3#4{\fmfcmd{for #1 = #2 step #3 until #4:}}
\def\endfmffor{\fmfcmd{endfor}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\fmfgroup}
%   \begin{macro}{\endfmfgroup}
% Syntactic sugar:
% \changes{v0.98}{1995/04/29}{\texttt{fmfgroup}: new environment.}
%    \begin{macrocode}
\def\fmfgroup{\fmfcmd{begingroup}}
\def\endfmfgroup{\fmfcmd{endgroup;}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\fmfset}
% \changes{v0.98}{1995/04/29}{%
%   \texttt{\protect\bslash fmfset}: new command.}
%    \begin{macrocode}
\def\fmfset#1#2{\fmfcmd{save #1; #1:=#2;}}
%</style>
%    \end{macrocode}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Choosing a layout for the graph}
%
% The procedure |vfreeze| is called near the end and
% chooses ``optimal'' vertex positions by minimizing the sum of the
% weighted lengths of the arcs.  Since the quantity to be optimized is
% quadratic in the vertices
% \begin{equation}
%   L = \frac{1}{2} \sum_i \sum_{j\in\alpha(i)}
%         t_{ij} (\vec v_i - \vec v_j)^2\,,
% \end{equation}
% where~$\alpha(i)$ denotes the set of vertices connectes with the
% vertex~$i$, we just have to solve a system of linear equations.
% Adding Lagrange multipliers~$\lambda_{ij}$ for the constraints that
% have been specified
% \begin{equation}
%   \Lambda = \sum_i \sum_{j\in\gamma(i) \atop j>i}
%         \vec\lambda_{ij}\cdot(\vec v_i - \vec v_j - \vec d_{ij})\,,
% \end{equation}
% where~$\gamma(i)$ denotes the set of vertices which have a fixed
% distance to the vertex~$i$, the set of linear equations is given by
% \begin{eqnarray}
%   0 & = & \frac{\partial}{\partial \vec v_i} (L+\Lambda)
%            = \sum_{j\in\alpha(i)} t_{ij} (\vec v_i - \vec v_j)
%              + \sum_{j\in\gamma(i) \atop j>i} \vec\lambda_{ij}
%              - \sum_{j\in\gamma(i) \atop j<i} \vec\lambda_{ji} \\
%   0 & = & \vec v_i - \vec v_j - \vec d_{ij}\;\; \mid  j \in \gamma(i)\,.
% \end{eqnarray}
% The implementation is simple: loop over all vertices in |vlist[]|
%    \begin{macrocode}
%<*base>
vardef vfreeze =
  for i = vertices:
%    \end{macrocode}
% and iff the position of the vertex has not been fixed yet, add
% another equation.  Note that each arc enters twice (incoming
% \emph{and} outgoing) in this procedure.  Thus it is easiest to store
% them \emph{both} ways in the |vlist| structure
% (cf.~page~\pageref{pg:vconnect})\label{pg:vfreeze}.
%    \begin{macrocode}
    if unknown vlist[i]loc:
      origin = origin
      for j = varcs (i):
        + vlist[i]arc[j]tns * (vlist[i]loc - vlist[vlist[i]arc[j]]loc)
      endfor
      for j = vconstr (i):
        if i < vlist[i]constr[j]:
          + lambda (i, vlist[i]constr[j])
        elseif i > vlist[i]constr[j]:
          - lambda (vlist[i]constr[j], i)
        fi
      endfor
      for j = vpoly (i):
        + lambdapoly (vlist[i]poly[j], plist[vlist[i]poly[j]]cnt,
                      vlist[i]poly[j]idx)
      endfor;
    fi
  endfor
%    \end{macrocode}
% Inquiring minds might want to see the result in numbers:
%    \begin{macrocode}
  if vtracing: vdump; fi
enddef;
%    \end{macrocode}
% Separate Langrange multipliers for~$x$ and~$y$:
% \changes{v1.04}{1996/02/20}{%
%   Have separate Langrange multipliers for~$x$ and~$y$.}
%    \begin{macrocode}
vardef lambda (expr i, j) =
  (if known (xpart(vlist[i]loc - vlist[j]loc)):
     lambdax[i][j]
   else:
     0
   fi,
   if known (ypart(vlist[i]loc - vlist[j]loc)):
     lambday[i][j]
   else:
     0
   fi)
enddef;
%    \end{macrocode}
%
% The Lagrange multiplier for a polynomial~$P$
% \begin{equation}
%   \Lambda_P = \sum_{i=2}^{n_P} \vec\lambda_{P,i}
%     \left( \vec v_{i+1} - \vec v_i
%             + R(2\pi/n_P) \left( \vec v_{i-1} - \vec v_i \right)
%     \right)
% \end{equation}
% can be reshuffled trivially
% \begin{eqnarray}
%   \Lambda_P & = &
%     \vec\lambda_{n-1} \vec v_{n}
%     - \vec\lambda_1 \vec v_2
%     + \vec\lambda_2 R(2\pi/n_P) \vec v_1
%     - \vec\lambda_n R(2\pi/n_P) \vec v_{n-1} \\
%     & & \mbox{} + \sum_{i=2}^{n_P}
%         \left( \vec\lambda_{i-1} + \vec\lambda_{i+1} R(2\pi/n_P)
%                - \vec\lambda_i (1 + R(2\pi/n_P)) \right) \vec v_i
%         \nonumber
% \end{eqnarray}
% \changes{v1.06}{1996/05/24}{
%   New function \texttt{lambdapoly}: Lagrange multipliers for
%   polygons.}
%    \begin{macrocode}
vardef lambdapoly (expr p, n, i) =
  origin
  if i = 1:
    + lambdap[p][2] rotated (-360/n)
  elseif i = 2:
    - lambdap[p][1]
  fi
  if i = n - 1:
    - lambdap[p][n] rotated (-360/n)
  elseif i = n:
    + lambdap[p][n-1]
  fi
  if (i > 1) and (i < n):
    + lambdap[p][i-1] + lambdap[p][i+1] rotated (-360/n)
    - lambdap[p][i] - lambdap[p][i] rotated (-360/n)
  fi
enddef;
%</base>
%    \end{macrocode}
% \begin{macro}{\fmffreeze}
% Again, we can ask for positioning and drawing explicitely from \TeX{}
% (usually called implicitely by |\end{fmfgraph}|).  This is useful for
% subsequent fine tuning.
% \changes{v0.9}{1995/04/27}{%
%   \texttt{\protect\bslash fmffreeze}
%    is new name of \texttt{\protect\bslash fmfposition}.}
%    \begin{macrocode}
%<style>\def\fmffreeze{\fmfcmd{vfreeze;}}
%<style>\let\fmfposition\fmffreeze
%    \end{macrocode}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Immediate mode commands}
%
% This could share some code with |vconnect|, but it doesn't seem
% worth the extra effort just now.
% \changes{v0.9}{1995/02/19}{%
%   Started implementing immediate mode commands.} 
%    \begin{macrocode}
%<*base>
vardef idraw (expr linesty, p) =
  save nopt, sty, lbl, wd, rub;
  numeric nopt, lbl.dist, wd, rub;
%<*mp>
  save  fore, back;
  color fore, back;
%</mp>
  string sty, lbl, lbl.side;
  getopt (opt, linesty);
  sty := opt[opt.first];
  if known opt[opt.first]arg:
    message "feynmf: line styles don't take arguments.  "
             & "Argument `" & opt[opt.first]arg & "' ignored.";
  fi
  opt.first := opt.first + 1;
  lbl := "";
  lbl.side := "";
  lbl.dist := 3thick;
  for nopt = opt.first upto opt.last:
    if match_option (opt[nopt], "label"):
      get_argument (opt[nopt], opt[nopt]arg, lbl);
    elseif match_option (opt[nopt], "label.side"):
      get_argument (opt[nopt], opt[nopt]arg, lbl.side);
    elseif match_option (opt[nopt], "label.dist"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg), lbl.dist);
    elseif match_option (opt[nopt], "width"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg), wd);
%<*mp>
    elseif match_option (opt[nopt], "foreground"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg), fore);
    elseif match_option (opt[nopt], "background"):
      get_argument (opt[nopt], scantokens (opt[nopt]arg), back);
%</mp>
%<*!mp>
    elseif match_option (opt[nopt], "foreground")
       or  match_option (opt[nopt], "background"):
      message "feynmf: color available with MetaPost only!";
%</!mp>
    elseif match_option (opt[nopt], "rubout"):
      if known opt[nopt]arg:
         rub := scantokens (opt[nopt]arg);
      else:
         rub := 2;
      fi
    else:
      ignore_option (opt[nopt], opt[nopt]arg);
    fi
  endfor
  handle_line_style (sty, sty);
  begingroup
%<*mp>
    if known fore:
      save foreground;
      color foreground;
      foreground = fore;
    fi
    if known back:
      save background;
      color background;
      foreground = back;
    fi
%</mp>
    vdraw_arc_rubout (rub, sty, wd, p, lbl);
  endgroup;
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef ivertex (expr vtxsty, pos) =
  save nopt, v;
  numeric nopt, v.lbl.ang, v.lbl.dist,
    v.decor.size, v.decor.ang;
  pair v.loc;
  string v.lbl, v.decor.sty;
  path v.decor.shape;
  v.loc := pos;
  v.lbl := "";
  v.lbl.ang := whatever;
  v.lbl.dist := 3thick;
  v.decor.size := decor_size;
  getopt (opt, vtxsty);
  for nopt = opt.first upto opt.last:
    handle_vertex_option (v, opt[nopt], opt[nopt]arg);
  endfor
  vdraw_label (v.loc, v.lbl);
  vdraw_vertex v;
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfi}
%   \begin{macro}{\fmfiv}
%     \begin{macro}{\fmfipath}
%       \begin{macro}{\fmfipair}
%         \begin{macro}{\fmfiset}
%           \begin{macro}{\fmfiequ}
%    \begin{macrocode}
%<*style>
\def\fmfi#1#2{%
  \fmfbuf@={#1}%
  \fmfcmd{idraw ("\the\fmfbuf@", #2);}}
\def\fmfiv#1#2{%
  \fmfbuf@={#1}%
  \fmfcmd{ivertex ("\the\fmfbuf@", #2);}}
\def\fmfipath#1{\fmfcmd{path #1;}}
\def\fmfipair#1{\fmfcmd{pair #1;}}
\def\fmfiset#1#2{\fmfcmd{#1:=#2;}}
\def\fmfiequ#1#2{\fmfcmd{#1=#2;}}
%</style>
%    \end{macrocode}
%           \end{macro}
%         \end{macro}
%       \end{macro}
%     \end{macro}
%   \end{macro}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Drawing the graph}
%
% \begin{macro}{\fmfdraw}
%    \begin{macrocode}
%<style>\def\fmfdraw{\fmfcmd{vdraw;}}
%    \end{macrocode}
% \end{macro}
%
% And here's the actual \MF{} implementation of |vdraw|:
%    \begin{macrocode}
%<*base>
vardef vdraw =
%    \end{macrocode}
% Check for typos:
%    \begin{macrocode}
  if not feynmfwizard:
    vcheck_typos;
  fi
%    \end{macrocode}
% Check that all vertices are known before attempting to draw the
% diagram.
%    \begin{macrocode}
  for i = vertices:
    if not known vlist[i]loc:
      errhelp "Your graph specification was not complete (probably a "
            & "lone vertex).            Check logic and reprocess!";
      errmessage "feynmf: vertex `" & vlist[i]name & "' not determined, "
               & "replaced by `(0,0)'."; 
      vlist[i]loc := origin;
    fi
    if unknown vlist[i]decor.size:
      vlist[i]decor.size = decor_size;
    fi
  endfor
%    \end{macrocode}
% Now do the actual drawing, looping over vertices and arcs.  Draw all
% arcs without the |rubout| option
% before any vertex so we can be a bit more sloppy with drawing
% the endpoints of arcs at decorated vertices.
%    \begin{macrocode}
  for i = vertices:
    for j = varcs (i):
      if known vlist[i]arc[j]sty:
        if vlist[i]arc[j]sty <> "":
          if unknown vlist[i]arc[j]rub:
%    \end{macrocode}
% \changes{v0.5}{1994/10/20}{Implement optional argument for detours.}
%    \begin{macrocode}
            begingroup
%<*mp>
              if known vlist[i]arc[j]fore:
                save foreground; color foreground;
                foreground = vlist[i]arc[j]fore;
              fi
              if known vlist[i]arc[j]back:
                save background; color background;
                background = vlist[i]arc[j]back;
              fi
%</mp>
              vdraw_arc (vlist[i]arc[j]sty, vlist[i]arc[j]wd,
                         vbuild_cut_arc (i, j), vlist[i]arc[j]lbl);
%    \end{macrocode}
% \changes{v0.6}{1995/05/29}{Draw each vertex only once.}
%    \begin{macrocode}
              vlist[i]arc[j]sty := "";
            endgroup;
          fi
        fi
      fi
    endfor;
  endfor
  for i = polygons:
    vdraw_label (pcenter plist[i], plist[i]lbl);
    vdraw_polygon plist[i];
  endfor
  for i = vertices:
    vdraw_label (vlist[i]loc, vlist[i]lbl);
    vdraw_vertex vlist[i];
  endfor
%    \end{macrocode}
% Make a second pass over the arcs, now drawing those with a |rubout|
% option.
%    \begin{macrocode}
  for i = vertices:
    for j = varcs (i):
      if known vlist[i]arc[j]sty:
        if vlist[i]arc[j]sty <> "":
          if known vlist[i]arc[j]rub:
            begingroup
%<*mp>
              if known vlist[i]arc[j]fore:
                save foreground; color foreground;
                foreground = vlist[i]arc[j]fore;
              fi
              if known vlist[i]arc[j]back:
                save background; color background;
                background = vlist[i]arc[j]back;
              fi
%</mp>
              vdraw_arc_rubout (vlist[i]arc[j]rub,
                                vlist[i]arc[j]sty,
                                vlist[i]arc[j]wd,
                                vbuild_cut_arc (i, j),
                                vlist[i]arc[j]lbl);
              vlist[i]arc[j]sty := "";
            endgroup;
          fi
        fi
      fi
    endfor;
  endfor
enddef;
%    \end{macrocode}
%
% Check for the most common typos in vertex names:
% \changes{v1.06}{1996/05/08}{%
%   New macro \texttt{vcheck\_typo}, checking for common errors.}
%    \begin{macrocode}
vardef vcheck_typos =
  save j, err;
  boolean wrn;
  wrn := false;
  for i = vertices:
    save connections;
    connections = vlist[i]arc.last - vlist[i]arc.first + 1;
%    \end{macrocode}
% This vertex has neither been connected nor fixed at a particular
% position.  Issue a warning message.
%    \begin{macrocode}
    if connections < 1:
      if unknown vlist[i]loc:
        message "feynmf: warning: disconnected and unspecified vertex `"
              & substring (2,infinity) of vlist[i]name
              & "'.";
        wrn := true;
      fi
    elseif connections = 1:
      j := vlist[i]arc[vlist[i]arc.last];
%    \end{macrocode}
% A vertex has only been connected with one other vertex and has not
% been fixed as an external vertex. Issue a warning message, but only
% once per connection.
%    \begin{macrocode}
      if j < i:
        if vlist[i]loc = vlist[j]loc:
          message "feynmf: warning: dangling vertex `"
                & substring (2,infinity) of vlist[i]name
                & "' colliding with `"
                & substring (2,infinity) of vlist[j]name
                & "'.";
        wrn := true;
        fi
      fi
    fi
  endfor
  if wrn:
    message "feynmf: Have you seen the warning messages above?";
    message "        They are usually caused by misspelling a vertex'";
    message "        name and can trigger errors further below!";
    message "        Fix the typos and run LaTeX and Metafont again.";
  fi
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Drawing arcs}
%
% Construct an arc from |from| to |to|.  The arc will be straight if
% $|lsr| = 0$, a left (approximate) halfcircle if $|lsr| = -1$ and a
% right halfcircle if $|lsr| = 1$.  Othe values of |lsr| will give
% obvious interpolations.  We optimize the most frequent straight
% line case. 
% \changes{v0.6}{1994/10/22}{%
%   Don't use \texttt{interpath} and halfcircles for detours anymore.
%   Simple paths constructed from three points are better (and
%   simpler).}
%    \begin{macrocode}
vardef vbuild_arc (expr lsr, from, to) =
  if unknown lsr:
    from -- to
  else:
    if lsr = 0:
      from -- to
    else:
      from
        .. (1-lsr)/2 *(to rotatedabout (.5[from,to], 90))
           + (1+lsr)/2 * (to rotatedabout (.5[from,to], -90))
        .. to
    fi
  fi
enddef;
%    \end{macrocode}
% \changes{v0.9}{1995/04/19}{%
%   \texttt{vbuild\_cut\_arc}: new function.}
%    \begin{macrocode}
vardef vbuild_cut_arc (expr origin, index) =
  cut_decors (vlist[origin],
              if vlist[origin]arc[index] <> origin:
                vbuild_arc (vlist[origin]arc[index]lsr,
                            vlist[origin]loc,
                            vlist[vlist[origin]arc[index]]loc)
              else:
                vbuild_tadpole (origin, index)
              fi,
              vlist[vlist[origin]arc[index]])
enddef;
%    \end{macrocode}
%
% \changes{v0.9}{1995/04/25}{%
%   \texttt{vbuild\_tadpole}: new function.}
%    \begin{macrocode}
vardef vbuild_tadpole (expr origin, index) =
  save j, n, nn, nnn, aidx, aang, agap, bgap, ngap, distsum;
  n := 0;
  distsum := 0;
  for j = varcs (origin):
    if vlist[origin]arc[j] <> origin:
%    \end{macrocode}
% This uses the fact that |lsr| has been defined both ways:
%    \begin{macrocode}
      ang := angle direction 0 of
        vbuild_arc (vlist[origin]arc[j]lsr,
                    vlist[origin]loc,
                    vlist[vlist[origin]arc[j]]loc);
      n := n + 1;
      distsum := distsum
        + abs (vlist[vlist[origin]arc[j]]loc - vlist[origin]loc);
%    \end{macrocode}
% A sentinel:
%    \begin{macrocode}
      aang[n] := 360;
      for nn = 1 upto n:
        if ang < aang[nn]:
          for nnn = n - 1 downto nn:
            aang[nnn+1] := aang[nnn];
            aidx[nnn+1] := aidx[nnn];
          endfor
          aang[nn] := ang;
          aidx[nn] := n;
        fi
        exitif known aidx[n];
      endfor
    fi
  endfor
  aidx[n+1] := aidx[1];
  aang[n+1] := aang[1] + 360;
  for nn = 1 upto n:
    agap[nn] = aang[nn+1] - aang[nn];
  endfor
  if known vlist[origin]arc[index]lsr:
%    \end{macrocode}
% Select specified gap:
%    \begin{macrocode}
    ngap := n;
    for nn = 1 upto n:
      if (aang[nn] < vlist[origin]arc[index]lsr)
         and (vlist[origin]arc[index]lsr < aang[nn+1]):
        ngap := nn;
      fi
    endfor
  else:
%    \end{macrocode}
% Select the largest gap:
%    \begin{macrocode}
    bgap := 0;
    for nn = 1 upto n:
      if agap[nn] > bgap:
        bgap :=  agap[nn];
        ngap := nn;
      fi
    endfor
  fi
  if vtracing: adump (n + 1); fi
  vlist[origin]loc{dir(aang[ngap]+agap[ngap]/4)}
    ... vlist[origin]loc + 2/3 * distsum/n
                            / vlist[origin]arc[index]tns
                            * dir(aang[ngap]+agap[ngap]/2)
    ... {-dir(aang[ngap+1]-agap[ngap]/4)}vlist[origin]loc
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef adump expr n =
  save i;
  for i = 1 upto n:
    message "aidx[" & decimal_ (i) & "]=" & decimal_ (aidx[i])
            & ", aang[" & decimal_ (i) & "]=" & decimal_ (aang[i])
            & ", agap[" & decimal_ (i) & "]=" & decimal_ (agap[i]);
  endfor
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vdraw_arc (expr sty, wd, arc) (suffix lbl) =
  if known wd:
    save currentpen;
    pen currentpen;
    pickup pencircle scaled wd;
  fi
  scantokens ("draw_" & sty) (arc);
  vdraw_arc_label (arc, lbl);
enddef;
%    \end{macrocode}
% Dirty trick: temporarily redefine the |draw| macro.
% \changes{v1.06}{1996/05/25}{Handle the \texttt{rubout} option.}
%    \begin{macrocode}
let plain_draw = draw;
vardef vdraw_arc_rubout (expr rub, sty, wd, arc) (suffix lbl) =
  if known rub:
    begingroup
      def draw expr p =
        save oldpen; pen oldpen;
        oldpen := currentpen;
        save currentpen; pen currentpen;
        pickup oldpen scaled rub;
        erase plain_draw (subpath (.1,.9)*length(p) of p)
      enddef;
      vdraw_arc (sty, wd, arc, lbl);
      let draw = plain_draw;
    endgroup;
  fi
  vdraw_arc (sty, wd, arc, lbl);
enddef;
%    \end{macrocode}
%
% Construct the path of a polygon according to |p.cona|, |p.conb| and
% |p.pull|.
% \changes{v1.06}{1996/05/24}{
%   New function \texttt{vbuild\_polygon}: construct polygon path.}
%    \begin{macrocode}
vardef vbuild_polygon suffix p =
  if known p.pull:
%    \end{macrocode}
% Connect the vertices with intermediate points:
%    \begin{macrocode}
    save c; pair c;
    c := pcenter p;
    for i = 1 upto (p.cnt - 1):
      vbuild_polygon_section (p, i, i+1)
    endfor
    vbuild_polygon_section (p, p.cnt, 1)
  else:
%    \end{macrocode}
% Just connect the vertices:
%    \begin{macrocode}
    for i = 1 upto p.cnt:
      vlist[p.vtx[i]]loc
        if known p.cona: scantokens (p.cona) else: -- fi
    endfor
  fi
  cycle
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
def vbuild_polygon_section (suffix p) (expr from, to) =
  vlist[p.vtx[from]]loc
    if known p.cona: scantokens (p.cona) else: -- fi
  p.pull[c,.5[vlist[p.vtx[from]]loc,vlist[p.vtx[to]]loc]]
    if known p.conb: scantokens (p.conb) else: -- fi
enddef;
%    \end{macrocode}
% Calculate the center of gravity of a polygon:
%    \begin{macrocode}
vardef pcenter suffix p =
 (origin for i = 1 upto p.cnt:
           + vlist[p.vtx[i]]loc
         endfor) / p.cnt
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Drawing labels}
%
%    \begin{macrocode}
vardef vdraw_arc_label (expr arc) (suffix lbl) =
  if lbl <> "":
    save _a, _z, _zz, _r;
    numeric _a;
    pair _z, _zz, _r;
    _z := point .5 length (arc) of arc;
    if lbl.dist = 0:
      LaTeX_text (_z, whatever, lbl);
    else:
      _r := direction .5 length (arc) of arc rotated - 90;
      if lbl.side = "left":
        _a := angle (-_r);
      elseif lbl.side = "right":
        _a := angle (_r);
      else:
%    \end{macrocode}
% Normalize to avoid overflow in |dotprod|:
% \changes{v0.8}{1995/02/18}{%
%   \texttt{vdraw\_arc\_label}: Protect against divide by zero.}
%    \begin{macrocode}
        _zz = _z - .5[point 0 of arc, point infinity of arc];
        if ((_zz if length (_zz) >  0: / length (_zz) fi)
            dotprod _r) >= 0:
          _a := angle (_r);
        else:
          _a := angle (-_r);
        fi
      fi
      LaTeX_text (_z + lbl.dist * dir _a, _a, lbl);
    fi
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef vdraw_label (expr loc) (suffix lbl) =
  if lbl <> "":
    save a;
    numeric a;
    if lbl.dist = 0:
      LaTeX_text (loc, whatever, lbl);
    else:
      if unknown lbl.ang:
        if loc = (.5w,.5h):
          a := 0;
        else:
          a := angle (loc - (.5w,.5h));
        fi
      else:
        a := lbl.ang;
      fi
      LaTeX_text (loc + lbl.dist * dir a, a, lbl);
    fi
  fi
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Drawing vertices}
%
%    \begin{macrocode}
vardef vdraw_vertex suffix v =
  if known v.decor.shape:
%<*mp>
    if known v.fore:
      save foreground;
      color foreground;
      foreground = v.fore;
    fi
    if known v.back:
      save background;
      color background;
      background = v.back;
    fi
%</mp>
    if known v.decor.sty:
      if v.decor.sty = "empty":
        emptydraw (
      elseif v.decor.sty = "full":
        cfilldraw (
      elseif is_a_number v.decor.sty:
        drawhalftone (1 - scantokens v.decor.sty / 100,
      else:
        drawtile (scantokens v.decor.sty,
      fi
    else:
      cfilldraw (
    fi
        v.decor.shape
          if known v.decor.ang: rotated v.decor.ang fi
          scaled v.decor.size shifted v.loc);
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef polygon expr n =
  if n > 2:
    for i = 1 upto n:
      (.5up rotated (360i/n)) --
    endfor
    cycle
  else:
    fullcircle
  fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef polygram expr n =
  if n > 2:
    for i = 1 upto n:
      (.5up rotated (360i/n)) --
      (.2up rotated (360(i+.5)/n)) --
    endfor
    cycle
  else:
    fullcircle
  fi
enddef;
%    \end{macrocode}
%
% \changes{v1.01}{1995/06/04}{%
%   \texttt{polycross} for vertices with crosses.}
%    \begin{macrocode}
vardef polycross expr n =
  save i;
  for i = 1 upto n:
    origin -- .5 dir (360(i-.5)/n) --
  endfor
  cycle
enddef;
%    \end{macrocode}
%
% Draw the path of a polygon and fill it according to |p.sty|.
% \changes{v1.06}{1996/05/24}{
%   New function \texttt{vdraw\_polygon}: draw and fill polygon.}
%    \begin{macrocode}
vardef vdraw_polygon suffix p =
%<*mp>
  if known p.fore:
    save foreground;
    color foreground;
    foreground = p.fore;
  fi
  if known p.back:
    save background;
    color background;
    background = p.back;
  fi
%</mp>
  if known p.sty:
    if p.sty = "phantom":
    elseif p.sty = "empty":
      emptydraw (vbuild_polygon p);
    elseif p.sty = "full":
      cfilldraw (vbuild_polygon p);
    elseif is_a_number p.sty:
      drawhalftone (1 - scantokens p.sty / 100, vbuild_polygon p);
    else:
      drawtile (scantokens p.sty, vbuild_polygon p);
    fi
  else:
    cdraw (vbuild_polygon p);
  fi
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Talking to \LaTeX}
%
% Unfortunately, enclosing the |message| in a |batchmode|
% |errorstopmode| pair doesn't work.  The label information isn't
% written to the terminal, but an empty line is anyway.
% \changes{v0.4}{1994/05/28}{%
%   \MP: \texttt{write} the label files directly.}
% \changes{v0.99}{1995/05/07}{%
%   Don't include the filename in the tag for
%   \texttt{\protect\bslash grepfile}: it's a waste.}
% The good news is that we don't have to worry about too long lines,
% because |message| will break them automagically and |\read| will
% splice them together again until braces are balanced.
%    \begin{macrocode}
vardef LaTeX expr text =
%<*!mp>
  message (":" & decimal charcode & ":" & text & "%")
%</!mp>
%<*mp>
  if LaTeX_file = "":
    LaTeX_file := jobname & ".t" & decimal charcode;
    write ("% " & LaTeX_file & " -- generated from " & jobname & ".mp")
      to LaTeX_file;
  fi
  write (text & "%") to LaTeX_file
%</mp>
enddef;
vardef LaTeX_text (expr z, a, txt) =
  LaTeX "\fmfL(" & (decimal (xpart z/LaTeX_unitlength)) & ","
      & (decimal (ypart z/LaTeX_unitlength)) & ","
      & (voctant a) & "){" & txt & "}";
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfL}
% This is an internal macro for squeezing more text into \MF's
% 80 character wide output.
%    \begin{macrocode}
%<style>\def\fmfL(#1,#2,#3)#4{\put(#1,#2){\makebox(0,0)[#3]{#4}}}
%    \end{macrocode}
% \end{macro}
%
% This will only be used with $\vert|a|\vert\le180$:
%    \begin{macrocode}
%<*base>
vardef voctant expr a =
  if known a:
    voctant_list[floor (a/45 + .5)]
  else:
    "c"
  fi
enddef;
string voctant_list[];
voctant_list[-4] := "r";
voctant_list[-3] := "rt";
voctant_list[-2] := "t";
voctant_list[-1] := "lt";
voctant_list[0] := "l";
voctant_list[1] := "lb";
voctant_list[2] := "b";
voctant_list[3] := "rb";
voctant_list[4] := "r";
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsubsection{Tracing}
%
%    \begin{macrocode}
vardef vdump =
  message ">>>>> Vertices and arcs for diagram #" & decimal charcode
        & " of " & jobname & ".mf:";
  for i = vertices:
    message "> " & vlist[i]name & "=" & decimal_pair (vlist[i]loc)
          & ": #lines="
          & decimal (vlist[i]arc.last - vlist[i]arc.first + 1)
          if vlist[i]lbl <> "":
            & ", lbl=" & vlist[i]lbl
            & ", l.angle=" & decimal_ (vlist[i]lbl.ang)
            & ", l.dist=" & decimal_ (vlist[i]lbl.dist)
          fi
          & ".";
  endfor
  for i = vertices:
    for j = varcs (i):
      if known vlist[i]arc[j]sty:
        message "> " & vlist[i]name & "*" & vlist[vlist[i]arc[j]]name
                & ": " & vlist[i]arc[j]sty
                & ", tns=" & decimal_ (vlist[i]arc[j]tns)
                & ", lsr=" & decimal_ (vlist[i]arc[j]lsr)
                & ", wd=" & decimal_ (vlist[i]arc[j]wd)
                & ", rub=" & decimal_ (vlist[i]arc[j]rub)
                if vlist[i]arc[j]lbl <> "":
                  & ", lbl=" & vlist[i]arc[j]lbl
                  & ", l.side=" & vlist[i]arc[j]lbl.side
                  & ", l.dist=" & decimal_ (vlist[i]arc[j]lbl.dist)
                fi
                & ".";
      fi
    endfor
    for j = vconstr (i):
      if i < vlist[i]constr[j]:
%    \end{macrocode}
% We don't keep an explicit record of the fixed distances, but they're
% easy to recover:
%    \begin{macrocode}
        save z;
        pair z;
        z = vlist[vlist[i]constr[j]]loc - vlist[i]loc;
        message "> " & vlist[i]name & "&"
                & vlist[vlist[i]constr[j]]name
                & ": " & decimal_pair (z);
      fi
    endfor;
  endfor
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef decimal_ (text n) =
  if known n: decimal n else: "?" fi
enddef;
%    \end{macrocode}
%
%    \begin{macrocode}
vardef decimal_pair (text z) =
  "(" & decimal_ (xpart z) & "," & decimal_ (ypart z) & ")"
enddef;
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Online displays}
%
% This is a bit smarter about pictures of varying sizes and some
% overshooting than |showit|.  You can still get burned, though,
% because \MF{} might not be able to enlarge the screen sufficiently.
% \changes{v0.8}{1994/10/25}{Online display support.}
%    \begin{macrocode}
def show_diagram_ expr frame =
  if (screen_cols < w + 2 xpart frame) or (screen_rows < h + 2 ypart frame):
    screen_cols := w + 2 xpart frame;
    screen_rows := h + 2 ypart frame;
    openwindow currentwindow
      from origin to (screen_rows, screen_cols)
      at (- xpart frame, h + ypart frame);
  fi
  showit_;
  if showstopping > 0:
    stop "This is diagram #" & decimal charcode
       & ".  Hit return to continue...";
  fi
enddef;
%    \end{macrocode}
% Self-modifying code is \emph{fun}: make sure to clear the window the
% second time around.
%    \begin{macrocode}
def show_diagram =
  def show_diagram =
    display blankpicture inwindow currentwindow;
    show_diagram_
  enddef;
  show_diagram_
enddef;
%    \end{macrocode}
% |show_all_diagrams| turns on the above online display mechanism.
% Creative use of |extra_endchar| allows us to do this from the
% command line (|showstopping| is used here to slow down the slide
% show).
% \begin{verbatim}
% mf '\mode:=localmode;
%     showstopping:=1;
%     extra_endchar:="show_all_diagrams(100,100);";
%     input foo.mf'
% \end{verbatim}
%    \begin{macrocode}
def show_all_diagrams expr frame =
  def showit = show_diagram frame enddef;
  displaying:=1;
enddef;
%</base>
%    \end{macrocode}
%
% \begin{macro}{\fmfdisplay}
%   \begin{macro}{\fmfstopdisplay}
% Make the display accessible from \TeX{} too.
%    \begin{macrocode}
%<*style>
\def\fmfdisplay{\fmfcmd{show_all_diagrams (100,100);}}
\def\fmfstopdisplay{\fmfcmd{showstopping:=1;}\fmfdisplay}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\fmftrace}
%   \begin{macro}{\fmfnotrace}
% Make the display accessible from \TeX{} too.
%    \begin{macrocode}
\def\fmftrace{\fmfcmd{vtracing:=true;}}
\def\fmfnotrace{\fmfcmd{vtracing:=false;}}
%</style>
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% Now we're done with the \MF{} macros
%    \begin{macrocode}
%<*base>
endinput;
%</base>
%    \end{macrocode}
% and the \TeX{} macros too:
%    \begin{macrocode}
%<*style>
\mdqrestore
%</style>
%    \end{macrocode}
%
% \Finale
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \appendix
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Driver file}
%
%    \begin{macrocode}
%<*driver>
%<*!209>
\documentclass[a4paper]{article}
\usepackage{doc}
%    \end{macrocode}
% The \MF{} and \MP{} logos come out much nicer if you have |mflogo|
% installed:
%    \begin{macrocode}
\IfFileExists{mflogo.sty}%
  {\usepackage{mflogo}%
   \def\FMF{\texttt{feyn}\textlogo{MF}}}%
  {\def\MF{\textsf{META}\-\textsf{FONT}}%
   \def\MP{\textsf{META}\-\textsf{POST}}%
   \def\FMF{\texttt{feyn}\textsf{MF}}}
%    \end{macrocode}
% Here is the place to declare your own PostScript aware |dvi| driver
% option:
% \changes{v1.01}{1995/07/05}{%
%    Don't force \texttt{dvips} as \texttt{dvi} driver.}
%    \begin{macrocode}
\usepackage{graphics}[1994/12/15]
%<mp>\usepackage{feynmp}
%<!mp>\usepackage{feynmf}
%</!209>
%    \end{macrocode}
% Here's the \LaTeX~2.09 compatibility stuff:
%    \begin{macrocode}
%<*209>
%<mp>\documentstyle[doc,feynmp209]{article}
%<!mp>\documentstyle[doc,feynmf209,epsf]{article}
%<!mp>\let\includegraphics\epsffile
\def\textit#1{{\it#1\/}}
\def\textbf#1{{\bf#1}}
\def\textsf#1{{\sf#1}}
\def\texttt#1{{\tt#1}}
\def\emph#1{{\em#1\/}}
\let\bfseries\bf
\def\LaTeXe{\LaTeX$2_\epsilon$}
\def\MF{\textsf{META}\-\textsf{FONT}}
\def\MP{\textsf{META}\-\textsf{POST}}
\def\FMF{\texttt{feyn}\textsf{MF}}
%</209>
%    \end{macrocode}
% The rest is common:
%    \begin{macrocode}
\font\manfnt=manfnt
\def\dangerousbend/{{\manfnt\char"7F}}
\def\dubious{\begin{itemize}\item[\dangerousbend/]}
\def\enddubious{\end{itemize}}
\def\examples#1{%
  \begin{list}{}%
   {\setlength{\leftmargin}{#1}%
    \addtolength{\leftmargin}{\marginparsep}%
    \addtolength{\leftmargin}{-\marginparwidth}%
    \setlength{\rightmargin}{0mm}%
    \setlength{\itemindent}{\parindent}%
    \setlength{\listparindent}{\parindent}}%
    \item}
\def\endexamples{\end{list}}
\def\marginexample#1{\marginpar{\hbox to\marginparwidth{#1\hss}}}
\parindent0pt
\def\manindex#1{\SortIndex{#1}{#1}}
%<manual>\OnlyDescription
\EnableCrossrefs
\RecordChanges
\CodelineIndex
\DoNotIndex{\def,\gdef,\long,\let,\begin,\end,\if,\ifx,\else,\fi}
\DoNotIndex{\immediate,\write,\newwrite,\openout,\closeout,\typeout}
\DoNotIndex{\font,\nullfont,\jobname,\documentclass}
\DoNotIndex{\batchmode,\errorstopmode,\char,\catcode,\ }
\DoNotIndex{\CodelineIndex,\DocInput,\DoNotIndex,\EnableCrossrefs}
\DoNotIndex{\filedate,\filename,\fileversion,\logo,\manfnt}
\DoNotIndex{\NeedsTeXFormat,\ProvidesPackage,\RecordChanges,\space}
\DoNotIndex{\usepackage,\wlog,\@gobble,\@ifundefined,\@namedef,\@spaces}
\DoNotIndex{\begingroup,\csname,\edef,\endcsname,\expandafter,\hbox}
\DoNotIndex{\hskip,\ifeof,\ignorespaces,\item,\leavevmode,\loop,\makebox}
\DoNotIndex{\newcounter,\newif,\newread,\openin,\par,\parindent,\put}
\DoNotIndex{\read,\relax,\repeat,\setcounter,\stepcounter,\the}
\DoNotIndex{\value,\vbox,\vskip}
\DoNotIndex{\@tempa,\@tempb,\advance,\bf,\bfseries,\closein}
\DoNotIndex{\CurrentOption,\DeclareOption,\documentstyle,\em,\emph}
\DoNotIndex{\endgroup,\epsilon,\global,\hfuzz,\input,\it,\LaTeX,\LaTeXe}
\DoNotIndex{\macrocode,\meaning,\OnlyDescription,\PassOptionsToPackage}
\DoNotIndex{\ProcessOptions,\RequirePackage,\sf,\string,\textbf,\textit}
\DoNotIndex{\textsf,\texttt,\tt,\unitlength}
%    \end{macrocode}
% Cut the linebreaking some slack for macrocode which might conatin
% long lines (it doesn't really hurt if they stick out a bit).
%    \begin{macrocode}
\let\origmacrocode\macrocode
\def\macrocode{\hfuzz 5em\origmacrocode}
\begin{document}
  \DocInput{feynmf.dtx}
\end{document}
%</driver>
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\endinput
Local Variables:
mode:LaTeX
fill-prefix:"% "
indent-tabs-mode:nil
change-log-default-name:"TODO"
page-delimiter:"^% %%%%%%%%%*\n"
End:
