% \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). % ; % % 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} %\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> \ProvidesPackage{feynmp}[\filedate\space\fileversion\space LaTeX/MetaPost Feynman Diagram Package (\filemaintainer)] % % % \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} %\RequirePackage{graphics}[1994/12/15] % %<*209> \def\fmf@noexpandoff{\let\noexpand\relax} %\input epsf.sty %\let\includegraphics\epsffile % % \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} % % \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 % % \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> \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";}% % \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} %{\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.}}% % \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 % % \end{macrocode} % Place the character: % \changes{v0.4}{1994/05/27}{\MP{} support: include PostScript file.} % \begin{macrocode} %\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.}}% % \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% % feynmf: Process \thefmffile.mf with METAFONT and then % % 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 % \@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;}} % % \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; % % \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}} % % \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} % % \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; % % \end{macrocode} % % \begin{macrocode} %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; % % \end{macrocode} % \begin{macro}{\fmfwizard} % \begin{macro}{\fmfnowizard} % \begin{macrocode} %<*style> \def\fmfwizard{\fmfcmd{feynmfwizard := true;}} \def\fmfnowizard{\fmfcmd{feynmfwizard := false;}} % % \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; % % \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;}} % % \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 = % draw p withcolor foreground % draw p enddef; vardef cfill expr p = % fill p withcolor foreground % fill p enddef; vardef cfilldraw expr p = % filldraw p withcolor foreground % 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 = % cutdraw p withcolor foreground % interim autorounding := 0; % cutdraw p enddef; vardef cdrawdot expr p = % drawdot p withcolor foreground % 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: % 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 % 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; % % \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; % % \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; % % \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> 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; % 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; % % \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; % % \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; % % \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[][]; % color plist[]fore, plist[]back; enddef; % % \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} % % \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; % % \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);}} % % \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});}} % % \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; % % \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});}} % % \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> elseif match_option (opt[nopt], "foreground") or match_option (opt[nopt], "background"): message "feynmf: color available with MetaPost only!"; % 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; % % \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});}} % % \end{macrocode} % \end{macro} % % \begin{macrocode} %<*base> vardef vlabel (expr s) (suffix v) = venter v; vlist[vlookup v]lbl := s; enddef; % % \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);}} % % \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> elseif match_option (opt, "foreground") or match_option (opt, "background"): message "feynmf: color available with MetaPost only!"; % % \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; % % \end{macrocode} % % \begin{macro}{\fmfblob} % \begin{macro}{\fmfdot} % We can decorate vertices with ``blobs'' and dots from \TeX{} with % the command sequences: % \begin{macrocode} % % \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; % % \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 % % \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; % % \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);}} % % \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; % % \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;}} % % \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 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; % % \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} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsection{Drawing the graph} % % \begin{macro}{\fmfdraw} % \begin{macrocode} % % \end{macrocode} % \end{macro} % \end{macro} % % Now we're done with the \MF{} macros % \begin{macrocode} %<*base> endinput; % % \end{macrocode} % and the \TeX{} macros too: % \begin{macrocode} %<*style> \mdqrestore % % \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] %\usepackage{feynmp} %\usepackage{feynmf} % % \end{macrocode} % Here's the \LaTeX~2.09 compatibility stuff: % \begin{macrocode} %<*209> %\documentstyle[doc,feynmp209]{article} %\documentstyle[doc,feynmf209,epsf]{article} %\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}} % % \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}} %\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} % % \end{macrocode} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput Local Variables: mode:LaTeX fill-prefix:"% " indent-tabs-mode:nil change-log-default-name:"TODO" page-delimiter:"^% %%%%%%%%%*\n" End: