summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/feynmf/feynmf.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/feynmf/feynmf.dtx')
-rw-r--r--macros/latex/contrib/feynmf/feynmf.dtx7800
1 files changed, 7800 insertions, 0 deletions
diff --git a/macros/latex/contrib/feynmf/feynmf.dtx b/macros/latex/contrib/feynmf/feynmf.dtx
new file mode 100644
index 0000000000..e1b44f303d
--- /dev/null
+++ b/macros/latex/contrib/feynmf/feynmf.dtx
@@ -0,0 +1,7800 @@
+% \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: