summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/feynmf
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/feynmf
Initial commit
Diffstat (limited to 'macros/latex/contrib/feynmf')
-rw-r--r--macros/latex/contrib/feynmf/Announce31
-rw-r--r--macros/latex/contrib/feynmf/COPYING339
-rw-r--r--macros/latex/contrib/feynmf/Feynman.Diagrams2
-rw-r--r--macros/latex/contrib/feynmf/Makefile303
-rw-r--r--macros/latex/contrib/feynmf/README200
-rw-r--r--macros/latex/contrib/feynmf/Tutorial21
-rw-r--r--macros/latex/contrib/feynmf/feynmf.dtx7800
-rw-r--r--macros/latex/contrib/feynmf/feynmf.ins95
-rw-r--r--macros/latex/contrib/feynmf/feynmf.pl457
-rw-r--r--macros/latex/contrib/feynmf/feynmf209.ins86
-rw-r--r--macros/latex/contrib/feynmf/fmfman.pdfbin0 -> 520160 bytes
-rw-r--r--macros/latex/contrib/feynmf/manpics.1377
-rw-r--r--macros/latex/contrib/feynmf/manpics.2358
-rw-r--r--macros/latex/contrib/feynmf/manpics.3190
-rw-r--r--macros/latex/contrib/feynmf/manpics.mp331
-rw-r--r--macros/latex/contrib/feynmf/template.tex24
16 files changed, 10614 insertions, 0 deletions
diff --git a/macros/latex/contrib/feynmf/Announce b/macros/latex/contrib/feynmf/Announce
new file mode 100644
index 0000000000..a824773362
--- /dev/null
+++ b/macros/latex/contrib/feynmf/Announce
@@ -0,0 +1,31 @@
+To: ctan-ann@shsu.edu,
+ feynmf-announce@crunch.ikp.physik.th-darmstadt.de
+Subject: [LaTeX/Metafont] Feynman diagrams: FeynMF v1.08 released
+
+This announces version 1.08 of feynmf, a combined LaTeX and Metafont
+(or Metapost) package for easy drawing of professional quality Feynman
+(and maybe other) diagrams.
+
+Version 1.08 is mainly a bug fix release and offers a driver script as
+the only new feature. The driver script is still experimental and I
+will be grateful for portability suggestions (it has been developed with
+teTeX under Linux).
+
+This software will show up through the magic of mirroring at the CTAN
+host near you.
+
+Enjoy,
+-Thorsten
+
+NEWS for Version 1.08
+
+ * Improved very short gluon and photon propagators by relaxing
+ overly aggressive rounding.
+
+ * New (still experimental) `feynmf' script automating the
+ invocation of Metafont (requires perl(1)).
+
+/// Thorsten Ohl, TH Darmstadt, Schlossgartenstr. 9, D-64289 Darmstadt, Germany
+//////////////// net: ohl@crunch.ikp.physik.th-darmstadt.de, ohl@gnu.ai.mit.edu
+/// voice: +49-6151-16-3116, secretary: +49-6151-16-2072, fax: +49-6151-16-2421
+
diff --git a/macros/latex/contrib/feynmf/COPYING b/macros/latex/contrib/feynmf/COPYING
new file mode 100644
index 0000000000..e77696ae8d
--- /dev/null
+++ b/macros/latex/contrib/feynmf/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/macros/latex/contrib/feynmf/Feynman.Diagrams b/macros/latex/contrib/feynmf/Feynman.Diagrams
new file mode 100644
index 0000000000..4292cb9cf5
--- /dev/null
+++ b/macros/latex/contrib/feynmf/Feynman.Diagrams
@@ -0,0 +1,2 @@
+This file is only needed to make 'quote site index feynman' work ...
+Have a look at the README file in this directory.
diff --git a/macros/latex/contrib/feynmf/Makefile b/macros/latex/contrib/feynmf/Makefile
new file mode 100644
index 0000000000..800e811006
--- /dev/null
+++ b/macros/latex/contrib/feynmf/Makefile
@@ -0,0 +1,303 @@
+# Makefile -- install feynmf.
+# Copyright (C) 1994,1995 Thorsten.Ohl@Physik.TH-Darmstadt.de
+#
+# 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.
+#
+# $Id: Makefile,v 1.27 1996/12/02 09:20:35 ohl Exp $
+#
+########################################################################
+
+VERSION = 1
+RELEASE = 08
+STATUS =
+
+########################################################################
+
+# Directories
+prefix = $(HOME)
+bindir = $(prefix)/bin
+mandir = $(prefix)/man/man1
+texdir = $(prefix)/tex/inputs
+mfdir = $(prefix)/mf/inputs
+docdir = $(texdir)/doc
+
+# Commands
+INSTALL = install -c -m 755
+INSTALL_DATA = install -c -m 644
+# INSTALL = cp
+# INSTALL_DATA = cp
+
+# This has to be the new LaTeX
+LATEX = latex
+# This should be the old LaTeX
+LATEX209 = tex '&latex209'
+# This must not have the cmbase preloaded:
+MF = mf
+MP = mp
+MAKEINDEX = makeindex
+
+# Your local printer mode
+MFMODE = laserjet
+
+########################################################################
+# No user serviceable parts below:
+########################################################################
+
+RESOLVE_XREF = \
+ $(LATEX) $*.drv && \
+ while grep 'Rerun to get cross-references right\.' $*.log; \
+ do \
+ $(LATEX) $*.drv; \
+ done
+
+RESOLVE_XREF209 = \
+ $(LATEX209) $*.drv && \
+ while grep 'Rerun to get cross-references right\.' $*.log; \
+ do \
+ $(LATEX209) $*.drv; \
+ done
+
+RUN_METAFONT = \
+ $(MF) '\mode:=$(MFMODE); input fmfsamp1'; \
+ $(MF) '\mode:=$(MFMODE); input fmfsamp2'; \
+ $(MF) '\mode:=$(MFMODE); input fmfsamp3'; \
+ $(MF) '\mode:=$(MFMODE); input fmfsamp4'
+
+RUN_METAPOST = \
+ $(MP) fmfsamp1; \
+ $(MP) fmfsamp2; \
+ $(MP) fmfsamp3; \
+ $(MP) fmfsamp4;
+
+RUN_MAKEINDEX = \
+ $(MAKEINDEX) -s gind.ist -o $*.ind $*.idx && \
+ $(MAKEINDEX) -s gglo.ist -o $*.gls $*.glo
+
+MANPICS = manpics.1 manpics.2 manpics.3
+
+all: feynmf.sty feynmf.mf feynmf.drv \
+ feynmp.sty feynmp.mp feynmp.drv $(MANPICS) \
+ feynmf.1
+
+all209: feynmf209.sty feynmf.mf feynmf209.drv \
+ feynmp209.sty feynmp.mp feynmp209.drv $(MANPICS)
+
+man: fmfman.dvi
+
+man209: fmfman209.dvi
+
+quick-man:
+ $(MAKE) man RUN_MAKEINDEX=: RESOLVE_XREF=:
+
+dvi: feynmf.dvi
+
+dvi209: feynmf209.dvi
+
+quick-dvi:
+ $(MAKE) dvi RUN_MAKEINDEX=: RESOLVE_XREF=:
+
+bigtest: feynmf.dvi feynmp.dvi fmfman.dvi fmfmanps.dvi manual.ps
+
+bigtest209: feynmf209.dvi feynmp209.dvi fmfman209.dvi \
+ fmfman209ps.dvi manual209.ps
+
+install: all
+ $(INSTALL_DATA) feynmf.mf $(mfdir)
+ $(INSTALL_DATA) feynmp.mp $(mfdir)
+ $(INSTALL_DATA) feynmf.sty $(texdir)
+ $(INSTALL_DATA) feynmp.sty $(texdir)
+ $(INSTALL_DATA) feynmf.1 $(mandir)
+ $(INSTALL) feynmf.pl $(bindir)/feynmf
+
+install.doc: all
+ $(INSTALL_DATA) feynmf.dtx $(docdir)
+ $(INSTALL_DATA) feynmf.drv $(docdir)
+ $(INSTALL_DATA) fmfman.drv $(docdir)
+ $(INSTALL_DATA) $(MANPICS) $(docdir)
+
+uninstall:
+ rm -f $(mfdir)/feynmf.mf
+ rm -f $(mfdir)/feynmp.mp
+ rm -f $(texdir)/feynmf.sty
+ rm -f $(texdir)/feynmp.sty
+ rm -f $(bindir)/feynmf
+ rm -f $(mandir)/feynmf.1
+
+uninstall.doc:
+ rm -f $(docdir)/feynmf.dtx
+ rm -f $(docdir)/feynmf.drv
+ rm -f $(docdir)/fmfman.drv
+
+feynmf.sty: feynmf.dtx feynmf.ins
+ $(LATEX) feynmf.ins
+
+feynmf209.sty: feynmf.dtx feynmf209.ins
+ $(LATEX209) feynmf209.ins
+
+feynmf.mf feynmf.drv feynmp.sty feynmp.mp feynmp.drv \
+ fmfman.drv fmfmanps.drv: feynmf.sty
+
+feynmf209.drv feynmp209.sty feynmp209.drv \
+ fmfman209.drv fmfman209ps.drv: feynmf209.sty
+
+feynmf.dvi: feynmf.dtx feynmf.drv feynmf.sty feynmf.mf $(MANPICS)
+ -$(LATEX) $*.drv
+ $(RUN_METAFONT)
+ -$(LATEX) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF)
+
+feynmf209.dvi: feynmf.dtx feynmf209.drv feynmf209.sty feynmf.mf $(MANPICS)
+ -$(LATEX209) $*.drv
+ $(RUN_METAFONT)
+ -$(LATEX209) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF209)
+
+feynmp.dvi: feynmf.dtx feynmp.drv feynmp.sty feynmp.mp $(MANPICS)
+ -$(LATEX) $*.drv
+ $(RUN_METAPOST)
+ -$(LATEX) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF)
+
+feynmp209.dvi: feynmf.dtx feynmp209.drv feynmp209.sty feynmp.mp $(MANPICS)
+ -$(LATEX209) $*.drv
+ $(RUN_METAPOST)
+ -$(LATEX209) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF209)
+
+fmfman.dvi: feynmf.dtx fmfman.drv feynmf.sty feynmf.mf $(MANPICS)
+ -$(LATEX) $*.drv
+ $(RUN_METAFONT)
+ -$(LATEX) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF)
+
+fmfman209.dvi: feynmf.dtx fmfman209.drv feynmf209.sty feynmf.mf $(MANPICS)
+ -$(LATEX209) $*.drv
+ $(RUN_METAFONT)
+ -$(LATEX209) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF209)
+
+fmfmanps.dvi: feynmf.dtx fmfmanps.drv feynmp.sty feynmp.mp $(MANPICS)
+ -$(LATEX) $*.drv
+ $(RUN_METAPOST)
+ -$(LATEX) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF)
+
+fmfman209ps.dvi: feynmf.dtx fmfman209ps.drv feynmp209.sty feynmp.mp $(MANPICS)
+ -$(LATEX209) $*.drv
+ $(RUN_METAPOST)
+ -$(LATEX209) $*.drv
+ $(RUN_MAKEINDEX)
+ $(RESOLVE_XREF209)
+
+manual.ps.gz: manual.ps
+ gzip < $< > $@
+
+manual.ps: fmfmanps.dvi $(MANPICS)
+ dvips -o $@ $<
+
+manual209.ps: fmfman209ps.dvi $(MANPICS)
+ dvips -o $@ $<
+
+manpics.1: manpics.mp
+ -mp $<
+
+manpics.2 manpics.3: manpics.1
+
+feynmf.1: feynmf.pl
+ pod2man --section 1 \
+ --release "FeynMF Version $(VERSION).$(RELEASE)$(STATUS)" \
+ --center "Contributed LaTeX Utilities" $< > $@
+
+clean:
+ rm -f fmfsamp?.* \
+ *.tfm *.*gf *.*pk \
+ *.log *.t[1-9] *.t[1-9][0-9] *.t[12][0-9][0-9] \
+ *.dvi *.aux *.toc *.ilg *.glo *.gls *.idx *.ind \
+ *.ps *.mpx '#*#' *~ .*~
+
+realclean: clean
+ rm -f feynmf.mf feynmf.sty feynmf.drv feynmp.* fmfman* \
+ feynmf209.sty feynmf209.drv feynmp209.*
+
+distclean: realclean
+
+########################################################################
+# Maintenance:
+
+DISTFILES = /usr/local/etc/COPYING README Makefile feynmf.dtx \
+ feynmf.ins feynmf209.ins manpics.mp $(MANPICS) \
+ feynmf.pl template.tex
+
+distdir = feynmf-$(VERSION).$(RELEASE)$(STATUS)
+CVSTAG = FEYNMF_$(VERSION)_$(RELEASE)$(STATUS)
+TEXTAG = v$(VERSION).$(RELEASE)
+M =
+
+fileversion:
+ perl -pe \
+ 's/^\\def\\fileversion\{.*\}/\\def\\fileversion{$(TEXTAG)}/;' \
+ feynmf.dtx > feynmf.vtmp
+ if cmp -s feynmf.dtx feynmf.vtmp; then \
+ rm -f feynmf.vtmp; \
+ else \
+ mv feynmf.vtmp feynmf.dtx; \
+ fi
+
+commit: fileversion
+ @if test -n "$(M)"; then \
+ echo "cvs commit -m '$(M)'"; cvs commit -m '$(M)'; \
+ echo "cvs tag $(CVSTAG)"; cvs tag $(CVSTAG); \
+ echo "cvs tag -b $(CVSTAG)_"; cvs tag -b $(CVSTAG)_; \
+ else \
+ echo "usage: make commit M='<message>'" 1>&2; \
+ fi
+
+dist: $(distdir).tar.gz
+snap: feynmf-current.tar.gz
+
+$(distdir).tar.gz:
+ rm -fr $(distdir) $(distdir).tmp
+ cvs export -r $(CVSTAG) -d $(distdir).tmp feynmf
+ mkdir $(distdir)
+ (cd ./$(distdir).tmp && \
+ make $(DISTFILES) && \
+ cp $(DISTFILES) ../$(distdir))
+ tar cf - $(distdir) | gzip > $@
+ rm -fr $(distdir) $(distdir).tmp
+
+feynmf-current.tar.gz: $(DISTFILES) fileversion
+ rm -fr feynmf-current
+ mkdir feynmf-current
+ touch feynmf-current/1_THIS_IS_A_SNAPSHOT_OF_
+ touch feynmf-current/2_WORK_IN_PROGRESS_AND__
+ touch feynmf-current/3_NOT_YET_RELEASED_CODE_
+ cp $(DISTFILES) feynmf-current
+# perl -pe \
+# 's/\[\\filedate/[(UNRELEASED and UNSUPPORTED snapshot)/;' \
+ feynmf.dtx > feynmf-current/feynmf.dtx
+ tar cf - feynmf-current | gzip > $@
+ rm -fr feynmf-current
+
+########################################################################
+# Local Variables:
+# mode:text
+# End:
diff --git a/macros/latex/contrib/feynmf/README b/macros/latex/contrib/feynmf/README
new file mode 100644
index 0000000000..611dbfad52
--- /dev/null
+++ b/macros/latex/contrib/feynmf/README
@@ -0,0 +1,200 @@
+# $Id: README,v 1.30 1996/12/02 01:38:45 ohl Exp $
+########################################################################
+
+ This is feynmf, a combined LaTeX/Metafont package for easy drawing
+ of professional quality Feynman diagrams. feynmf lays out most
+ diagrams satisfactorily from the structure of the graph without
+ any need for manual intervention. Nevertheless all the power of
+ Metafont is available for more obscure cases. See the
+ documentation for appetizers, examples and more details.
+
+ A preformatted manual (`manual.ps.gz') is provided to wet your
+ appetite with numerous examples.
+
+ Anyway, you are invited to share, use, abuse, and improve it, see
+ the file COPYING for details.
+
+ Enjoy,
+ -Thorsten
+
+########################################################################
+
+ Installation:
+
+ You need a recent LaTeX (LaTeX2e, as of December 1994 is
+ sufficient) to use feynmf, docstrip.tex to install it and doc.sty
+ to typeset the documentation. If it is not already on your system,
+ you can get all this (and much more) from your nearest CTAN host.
+
+ To install, either use the Makefile or use the installation file
+ feynmf.ins:
+
+ $ latex feynmf.ins
+
+ then you can typeset the documentation by
+
+ $ latex fmfman.drv
+ $ mf '\mode:=laserjet; input fmfsamp1'
+ $ mf '\mode:=laserjet; input fmfsamp2'
+ $ mf '\mode:=laserjet; input fmfsamp3'
+ $ mf '\mode:=laserjet; input fmfsamp4'
+ $ latex fmfman.drv
+ $ makeindex -s gind.ist -o fmfman.ind fmfman.idx
+ $ makeindex -s gglo.ist -o fmfman.gls fmfman.glo
+ $ latex fmfman.drv
+
+ or by using the Makefile (`make man'). That's it.
+
+ There is also a simple example `template.tex' that you can use as
+ a template for your own creations. To typeset, either use the
+ feynmf script
+
+ $ feynmf template
+
+ or run Metafont manually
+
+ $ latex template
+ $ mf '\mode:=localfont; input fmftempl'
+ $ latex template
+
+ Finally, there is another installation file for LaTeX 2.09 compatible
+ versions: feynmf209.ins. This file has to be processed _in addition_
+ to feynmf.ins!
+
+########################################################################
+
+WARNING:
+
+ If LaTeX fails with `Unknown graphics extension: 3', you have a
+ slightly out-of-date graphics.sty file (LaTeX will have issued a
+ warning in this case). There has been a change to the user
+ interface, which makes it very hard to support both versions.
+ Sorry. I have chosen to support the current one, which will
+ hopefully be stable.
+
+ You can work around this by either getting a more recent graphics
+ package from CTAN (macros/latex/packages/graphics) or by using
+ epsf.sty instead (`\let\includegraphics\epsffile\input epsf.sty').
+ [You can also ignore it and get the preformatted manual. But you
+ will not be able to use the MetaPost version in this case.]
+
+########################################################################
+
+ Comments, bug reports and improvements are welcome at:
+
+ Thorsten.Ohl@Physik.TH-Darmstadt.de
+ (aka: ohl@crunch.ikp.physik.th-darmstadt.de)
+
+ New versions can be found in:
+
+ crunch.ikp.physik.th-darmstadt.de:/pub/ohl/feynmf
+
+ or at CTAN:
+
+ {ftp.shsu.edu,ftp.tex.ac.uk,ftp.dante.de}:
+ ... macros/latex/contrib/supported/feynmf
+
+ There are two mailing lists
+
+ feynmf-announce@crunch.ikp.physik.th-darmstadt.de
+ feynmf-bugs@crunch.ikp.physik.th-darmstadt.de
+
+ both are open for subscription. The former should be very low
+ volume and carry only important announcements. The latter can
+ serve as a more general discussion forum.
+
+ To subscribe, send mail to
+
+ majordomo@crunch.ikp.physik.th-darmstadt.de
+
+ and NOT to the lists itself. The following commands (on a line in
+ the body of the mail, not in the subject) are useful: `subscribe
+ feynmf-announce', `unsubscribe feynmf-bugs', `help', etc.
+
+########################################################################
+
+NEWS for Version 1.08
+
+ * Improved very short gluon and photon propagators by relaxing
+ overly aggressive rounding.
+
+ * New (still experimental) `feynmf' script automating the
+ invocation of Metafont (requires perl(1)).
+
+NEWS for Version 1.07
+
+ * Switch off I/O during the first pass in AMS-LaTeX equation
+ environments. This avoids a nasty race condition (thanks to Axel
+ Thimm for reporting this bug). A beneficial side effect is that
+ it saves us 50% processing time in these cases.
+
+NEWS for Version 1.06
+
+ * New abstraction: polygons. Useful for complex vertices in
+ non-perturbative diagrams.
+
+ * New commands: \fmfpoly, \fmfpolyn and \fmfrpolyn, implementing
+ polygons.
+
+ * New option `rubout' for crossing propagators.
+
+ * Some common typos are detected are appropriate warning messages
+ are issued.
+
+ * New options `errorstop', `scroll', `nonstop' and `batch' for
+ specifying the desired interactionmode.
+
+ * Work around an obscure babel/german/feynmf three way
+ destructive interference.
+
+NEWS for Version 1.05
+
+ * FeynMF now coexists with french.sty and other packages that
+ change the \catcode of ``:''.
+
+ * Fixed a bug introduced in version 1.03, which could cause
+ problems with font loading. Unfortunately, the fix has to give up
+ some compatibility with earlier versions. Sources for version
+ 1.02 and earlier which used \noexpand in labels have to upgraded
+ or the option `pre-1.03' has to be used. Sorry.
+
+NEWS for Version 1.04
+
+ * Finally, \fmffixed{(dx,whatever)}{v1,v2} and
+ \fmffixed{(whatever,dy)}{v1,v2} do what you would expect them
+ to. \fmffixedx and \fmffixedy are new synonyms for those.
+
+NEWS for Version 1.03
+
+ * It is no longer necessary to protect TeX command sequences with
+ \noexpand. Old files using \noexpand will continue to work.
+
+NEWS for Version 1.02
+
+ * Read the .tfm file before writing the .mf file destructively.
+ This should allow a transparent two pass processing if MakeTeXTFM
+ is enabled. Thanks to Thomas Esser <te@informatik.uni-hannover.de>
+ for the suggestion.
+
+NEWS for Version 1.01
+
+ * new decoration shapes for vertices by popular demand: `cross'
+ (also `triacross', `pentacross' and `hexacross').
+
+ * fixed a rounding bug in cut-off ends (noticeable as a spurious
+ thin diagonal line at the left end of double lines).
+
+ * The maximum size for shaded and hatched areas has been doubled
+ by removing an obsolete speedup hack that was not used anymore.
+
+ * In an unrelated move, shading and hatching has been
+ reimplemented in a much more general fashion. Now arbitray
+ tilings can be specified as argument to `decoration.filled='. The
+ old style numerical arguments continue to work, but should be
+ replaced by `empty', `full', `shaded', and `hatched' in new
+ documents.
+
+########################################################################
+# Local Variables:
+# mode:indented-text
+# End:
diff --git a/macros/latex/contrib/feynmf/Tutorial b/macros/latex/contrib/feynmf/Tutorial
new file mode 100644
index 0000000000..1edeb88cf5
--- /dev/null
+++ b/macros/latex/contrib/feynmf/Tutorial
@@ -0,0 +1,21 @@
+All three parts of a tuturial on FeynMF are now available from CERN,
+both as PostScript and HTML files:
+
+PostScript:
+***********
+
+ ftp://asisftp.cern.ch/cnl/220/textproc.ps.gz [Part 1]
+ ftp://asisftp.cern.ch/cnl/221/textproc.ps.gz [Part 2]
+ ftp://asisftp.cern.ch/cnl/222/textproc.ps.gz [Part 3]
+
+
+HTML:
+*****
+
+ http://wwwcn1.cern.ch/cnls/220/node57.html [Part 1]
+ http://wwwcn1.cern.ch/cnls/221/node63.html [Part 2]
+ http://wwwcn1.cern.ch/cnls/222/node38.html [Part 3]
+
+A paper has been printed by Computer Physics Communications:
+
+ T. Ohl, Comp. Phys. Comm. 90 (1995) 340-354
diff --git a/macros/latex/contrib/feynmf/feynmf.dtx b/macros/latex/contrib/feynmf/feynmf.dtx
new file mode 100644
index 0000000000..e1b44f303d
--- /dev/null
+++ b/macros/latex/contrib/feynmf/feynmf.dtx
@@ -0,0 +1,7800 @@
+% \iffalse % feynmf.dtx - Feynman diagrams with METAFONT for LaTeX(2e)
+% Copyright (C) 1989, 1990, 1992-1996 by Thorsten.Ohl@Physik.TH-Darmstadt.de
+% $Id: feynmf.dtx,v 1.30 1996/12/02 09:20:36 ohl Exp $
+%
+% Feynmf is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 2, or (at your option)
+% any later version.
+%
+% Feynmf is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%
+% \fi
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%% \CheckSum{924}
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \MakeShortVerb{\|}
+%
+% \title{%
+% \FMF: \\
+% Drawing Feynman Diagrams \\
+% with \LaTeX{} and \MF\thanks{%
+% This is \texttt{\filename}, version \fileversion,
+% revision \filerevision, date \filedate.}}
+%
+% \author{%
+% Thorsten Ohl\thanks{e-mail:
+% {\tt Thorsten.Ohl@Physik.TH-Darmstadt.de}}\\
+% \hfil \\
+% Technische Hochschule Darmstadt \\
+% Schlo\ss gartenstr. 9 \\
+% D-64289 Darmstadt \\
+% Germany}
+%
+% \maketitle
+% \begin{abstract}
+% \FMF{} is a \LaTeX{} package for easy drawing of professional
+% quality Feynman diagrams with \MF{} (or \MP). \FMF{} lays out most
+% diagrams satisfactorily from the structure of the graph without
+% any need for manual intervention. Nevertheless all the power of
+% \MF{} (or \MP) is available for obscure cases.
+% \end{abstract}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section*{Copying}
+%
+% \FMF{} is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 2, or (at your option)
+% any later version.
+%
+% \FMF{} is distributed in the hope that it will be useful, but
+% \emph{without any warranty}; without even the implied warranty of
+% \emph{merchantability} or \emph{fitness for a particular purpose}.
+% See the GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \newpage
+% \tableofcontents
+% \newpage
+% \unitlength=1mm
+% \def\topfraction{0.9}
+% \def\bottomfraction{0.9}
+% \def\textfraction{0.1}
+% \begin{fmffile}{fmfsamp1}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{Introduction}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Purpose and scope}
+%
+% In recent years, \TeX\footnote{\TeX{} is a trademark of the American
+% Mathematical Society.}~\cite{TeX}
+% and \LaTeX\footnote{\LaTeX{} might be a trademark of Addison Wesley
+% Publishing Company.}~\cite{LaTeX}
+% have revolutionized the way
+% we share information in theoretical physics (and other areas). Not
+% only does \TeX{} provide typographical capabilities, which transcend
+% those of commercial ``wordprocessors'' substantially, \TeX{} documents
+% are also completely portable. Since implementations are available
+% on essentially all computers in use in the community, documents can
+% be shared without the usual restrictions of proprietary data
+% formats. This has enabled us to collaborate on papers with
+% colleagues on the other side of the globe, to replace the mailing of
+% hard copy preprints by electronic transmission and to submit these
+% papers electronically to the publisher.
+%
+% This portability comes with a price, though. \TeX{} (and \LaTeX)
+% do not address the issue of graphical information, apart from the
+% rudimentary (but very useful) capabilities of the \LaTeX{} |picture|
+% environment and similar
+% packages~\cite{LaTeX-Companion}. As an de facto standard for the
+% inclusion of more complex graphics has emerged the inclusion of
+% PostScript\footnote{PostScript is a trademark of Adobe Systems
+% Inc.}
+% files. The complete document can then
+% be printed on any PostScript device.
+%
+% Still there are areas, where complementary approaches seem worth
+% pursuing. In particular this is the case, if the graphical
+% information is highly formalized, like the case at hand. Feynman
+% diagrams are specified by their topology and the type of particles
+% connecting the vertices. Thus a given diagram can be reproduced
+% from a very concise specification, if the software is able to choose
+% a reasonable layout (semi-)automatically.
+%
+% \MF\footnote{\MF{} is a trademark of Addison Wesley Publishing
+% Company.}~\cite{MF}
+% and \MP\footnote{John Hobby's \MP{} is a modified version of \MF{}
+% which generates (encapsulated) PostScript output. \MP{} can be
+% build trivially on top of the \texttt{web2c} version of \TeX{} and
+% \MF{} for UNIX. Ports to other systems should be
+% simple.}~\cite{MetaPost}
+% appear to be the perfect tool for such a purpose, since
+% \begin{enumerate}
+% \item{} \MF{} is part of any (reasonable) \TeX{} installation, thus
+% available to all potential users,
+% \item{} both have very powerful graphics primitivs, which allow high
+% quality output, and
+% \item{} both have builtin linear algebra, which allows us to choose a
+% layout automatically.
+% \end{enumerate}
+% Still, providing at least the basic interface in \LaTeX{} macros
+% seems appropriate for boosting the acceptance among the less
+% technically oriented parts of the audience. Thus
+% \FMF\footnote{\FMF{} is not anybody's trademark.}~\cite{CPC,CNL}
+% was conceived.
+%
+% \FMF{} is unique among packages for drawing Feynman diagrams in
+% \emph{combining} the following features:
+% \begin{itemize}
+% \item Simplicity and conciseness for common diagrams. E.g.~the
+% scattering diagram in figure~\ref{fig:simple} can be specified
+% \emph{completely} in five lines of \LaTeX:
+% \begin{verbatim}
+% \begin{fmfgraph*}(40,30) \fmfpen{thick}
+% \fmfleft{i1,i2} \fmfright{o1,o2}
+% \fmf{fermion}{i1,v1,o1} \fmf{fermion}{i2,v2,o2}
+% \fmf{photon,label=$q$}{v1,v2} \fmfdot{v1,v2}
+% \end{fmfgraph*}
+% \end{verbatim}
+% \begin{figure}[t]
+% \begin{center}
+% \begin{fmfgraph*}(40,30) \fmfpen{thick}
+% \fmfleft{i1,i2} \fmfright{o1,o2}
+% \fmf{fermion}{i1,v1,o1} \fmf{fermion}{i2,v2,o2}
+% \fmf{photon,label=$q$}{v1,v2} \fmfdot{v1,v2}
+% \end{fmfgraph*}
+% \end{center}
+% \caption{\label{fig:simple}Simple scattering diagram.}
+% \end{figure}
+% \item Expressiveness for complicated diagrams (see the examples
+% below).
+% \item Extensibility (e.g.~see section~\ref{sec:extensions}).
+% \item Arbitrary \TeX-labels. This point is more important than it
+% may seem at first glance because most graphical layout systems
+% lack the power to produce complicated mathematical expressions.
+% Having matching fonts in text, equations and diagrams is also an
+% important esthetical feature.
+% \end{itemize}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Relation to similar packages}
+%
+% Before we start, a couple of words about some complementary packages
+% on the market are in order:
+% \begin{itemize}
+% \item Michael Levine's |feynman| package~\cite{levine} is
+% implemented on top of the standard \LaTeX{} |picture|
+% environment~\cite{LaTeX}. This makes it completely portable (no
+% need for a correct \MF{} installation), but it requires manual
+% layout and the graphics output is (though very useful) less than
+% perfect.
+% \item Jos Vermaseren's |axodraw| package~\cite{axodraw} uses
+% |\special|s to access PostScript primitives for drawing
+% diagrams. This approach is inherently not portable (the
+% ubiquity of PostScript printers makes this a minor point,
+% though) but as flexible as the present one. Nevertheless,
+% it still requires manual layout for all diagrams.
+% \item Last, but not least, I have to mention Thomas Leathrum's
+% |mfpic|~\cite{mfpic}, which provided the inspiration for moving
+% \FMF's user interface from \MF{} to \TeX. It might not have
+% been unreasonable to design and implement \FMF{} as a package on
+% top of |mfpic|, but closer inspection shows that \FMF{} and
+% |mfpic| are fairly orthogonal. |mfpic| is most useful for
+% handling simple graphical building blocks in formally
+% unconstrained contexts. \FMF{} on the other hand excels in the
+% formal context of Feynman diagrams (or any other labeled graphs
+% for that matter), which can be drawn automatically from a
+% \emph{specification}.
+% \end{itemize}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Historical note}
+%
+% Parts of this code have a rather long history\footnote{%
+% Which is a partial explanation, if not excuse, for its slightly
+% incoherent structure.}.
+% Some of the drawing primitives started in 1989 as
+% |feynman.mf|, a library of \MF{} macros for drawing Feynman
+% diagrams in my thesis. The layout had to be specified completely
+% by hand, which required a long edit-process-preview cycle and made
+% |feynman.mf| awkward to use.
+% Nevertheless, it suited my and other's neeeds and survived for five
+% years without major modifications. Early in
+% 1994, I became aware of Thomas Leathrum's |mfpic|~\cite{mfpic}.
+% This inspired me to shift the user interface from \MF{} to
+% \LaTeX, because this allows a smoother blending of the \LaTeX{}
+% |picture| environment with \FMF{} for the purpose of labeling the
+% graphs. While doing this and after
+% having been taught by Tim Stelzer's and Bill Long's
+% \texttt{MADGRAPH}~\cite{madgraph} that simply minimizing the length
+% of the graph gives much better results than I had anticipated, I
+% added the graph manipulation and layout code.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Architecture}
+%
+% Even though there has never been a proper design phase in the
+% development of \FMF, a certain structure has emerged, which is
+% depicted in figure~\ref{fig:arch}. A user who is aware of this
+% architecture should be able to use \FMF{} more effectively.
+%
+% \begin{figure}[t]
+% \hfuzz=3cm
+% \begin{center}
+% \leavevmode
+% \includegraphics{manpics.3}
+% \end{center}
+% \caption{\label{fig:arch}%
+% Architecture of \FMF{}: the two modes of \FMF{} (immediate mode
+% and vertex mode) both interact with \LaTeX{} and \MF{} (or \MP,
+% respectively), but operate on different data types.}
+% \end{figure}
+%
+% The most crucial aspect of the architecture is the existence of two
+% distinct modes with different fundamental datatypes:
+% \begin{itemize}
+% \item \emph{vertex mode,} which deals with graphs as structures
+% consisting of vertices and arcs and (almost) never deals with
+% their physical locations.
+% \item \emph{immediate mode,} which deals with \MF{} |path|s and
+% |pair|s (i.e.~coordinates) and
+% allows complete control over the physical locations.
+% \end{itemize}
+% It is of course possible to mix these modes in advanced
+% applications. Commands are provided to translate vertices and arcs
+% to |pair|s and |path|s and vice versa.
+%
+% Novice users with little experience in \MF{} programming should
+% start with vertex mode to get their job done. Later, immediate mode
+% can be used to create more and more complex diagrams. It is
+% possible to create most diagrams that can actually be calculated in
+% vertex mode. Immediate mode is most useful for extending line
+% \FMF{} and for drawing diagrams with fancy decorations.
+%
+% A word on portability: \FMF{} is implemented as a \LaTeX{} package.
+% But it should be straightforward to adapt it to other \TeX{} macro
+% packages because \LaTeX{} macros have been used for convenience only
+% and can easily be replaced or provided in a compatibility package.
+% The \LaTeX{} specific \emph{environment} construct can also easily
+% be replaced by the equivalent construct in another macro package.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Conclusion}
+%
+% It goes without saying that \FMF{} is not perfect. There might be
+% cases where using a graphical drawing tool with a mouse can give
+% more pleasing results in less time. But in most cases, \FMF{}
+% will give satisfactory results without any fine tuning. These will
+% be reproducible and independent from the computer it is running on.
+%
+% Early user reponses have been very encouraging. There seems to be a
+% relatively steep
+% learning curve for those \LaTeX{} users that have to find out how to
+% run \MF{} on their systems. But once this purely technical obstacle
+% has been
+% surmounted, users have been enthusiatic as well about the quality of
+% the generated graphs as about the ease of use of \FMF.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \newpage
+% \section{Usage}
+%
+% In addition to this manual, there exists also a concise description
+% of \FMF{} in a journal article~\cite{CPC}, as well as a three part
+% tutorial~\cite{CNL}.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{\LaTeX{} package and environments}
+% \label{sec:environments}
+%
+% Instructing \LaTeX{} to use \FMF{} is as simple as\footnote{As
+% given, this applies to \LaTeX. But the installation file
+% \texttt{feynmf209.ins} allows to generate special versions
+% \texttt{feynmf209.sty} and \texttt{feynmp209.sty} which are
+% compatible with the obsolete \LaTeX{} version 2.09. These files
+% are to be used as documentstyle options
+% \begin{quote}
+% \texttt{\bslash documentstyle[...,feynmf209,...]\{...\}}
+% \end{quote}
+% or
+% \begin{quote}
+% \texttt{\bslash documentstyle[...,feynmp209,...]\{...\}}
+% \end{quote}
+% If you cannot use |epsf.sty| for including PostScript files, you
+% can either hack |feynmp209.sty| or upgrade to \LaTeX2e.
+% Please keep in mind that \FMF{} has been developed for \LaTeXe{}
+% and the \LaTeX~2.09 compatibility version will always be a
+% retrofitted hack. I will accept bug reports for the 2.09 version,
+% but I urge everybody to move to \LaTeX2e, which is the one and
+% only supported \LaTeX{} right now.}
+% \begin{quote}
+% |\usepackage{feynmf}|
+% \end{quote}
+% If you have \MP, then you can use it alternatively by placing
+% \begin{quote}
+% |\usepackage{feynmp}|
+% \end{quote}
+% in your \LaTeX{} source.\footnote{%
+% \FMF{} understands an option \texttt{pre-1.03}, that is
+% of interest for veteran users:
+% \begin{quote}
+% \texttt{\bslash usepackage[pre-1.03]\{feynmf\}}
+% \end{quote}
+% or
+% \begin{quote}
+% \texttt{\bslash usepackage[pre-1.03]\{feynmp\}}
+% \end{quote}
+% The purpose of this option is to enable processing of old input
+% files (pre v1.02) that use \texttt{\bslash noexpand} in labels.
+% Since the method for processing these files can clash (in rare
+% cases) with \LaTeXe's font loading procedure, it has been disabled
+% by default.}
+%
+% \FMF{} has to switch interactions mode and switches to
+% |\errorstopmode|, because it is impossible in \TeX{} to switch
+% back. If a different default is required (for automated preprint
+% processing, in particular), it can be specified as a package option:
+% \begin{quote}
+% |\usepackage[errorstop]{feynmf}|\\
+% |\usepackage[scroll]{feynmf}|\\
+% |\usepackage[batch]{feynmf}|\\
+% |\usepackage[nonstop]{feynmf}|
+% \end{quote}
+%
+% \DescribeEnv{fmffile}
+% All descriptions that should go into one \MF{} file are placed
+% inside a |fmffile| environment which takes the name of the \MF{}
+% file as an argument:
+% \begin{quote}
+% \begin{flushleft}
+% |\begin{fmffile}{|\meta{\MF-file}|}|\\
+% \qquad\ldots\\
+% |\end{fmffile}|
+% \end{flushleft}
+% \end{quote}
+% Upto 255 graphs can be placed into one \MF{} file. Currently
+% \FMF{} does \emph{not} check that the 255 graph limit per file
+% is not overrun.\footnote{%
+% There is also a very primitive, but (unfortunately) popular
+% operating system, which restricts filenames to eight characters
+% with a three character extension. On this system, only 99
+% graphs can be placed into one \MF{} file because auxiliary
+% files will not be unambiguous, if more than two digits are used.}
+% Note that the filename for the \MF{} file given in the argument of
+% the |fmffile| environment \emph{must not} be identical to the
+% \LaTeX{} source file name, because the \MF{} |.log| would be
+% overwritten and \LaTeX{} can no longer access the information in
+% this |.log| file. It should be obvious that any umber of diagrams
+% can be generated by using more than one |fmffile| environment with
+% different filenames.
+%
+% \DescribeEnv{fmfgraph}
+% The |fmfgraph| environment contains the description of a single
+% Feynman diagram
+% which will be placed a the location of the environment.
+% Arguments are the width and the height of the diagram, in units of
+% |\unitlength|:
+% \begin{quote}
+% \begin{flushleft}
+% |\begin{fmfgraph}(|\meta{width}|,|\meta{height}|)|\\
+% \qquad\ldots\\
+% |\end{fmfgraph}|
+% \end{flushleft}
+% \end{quote}
+% This environment does \emph{not} support labels, use |fmfgraph*| if
+% your diagrams contains labels.
+%
+% \DescribeEnv{fmfgraph*}
+% Same as |fmfgraph|, but enclosed in a |picture| environment of the
+% same size and supporting \LaTeX{} labels.
+% \begin{quote}
+% \begin{flushleft}
+% |\begin{fmfgraph*}(|\meta{width}|,|\meta{height}|)|\\
+% \qquad\ldots\\
+% |\end{fmfgraph*}|
+% \end{flushleft}
+% \end{quote}
+%
+% \DescribeMacro{\fmfframe}
+% Allows to allocate additional space around a |fmfgraph*|, since
+% the labels (or the diagram itself) might overshoot:
+% \begin{quote}
+% |\fmfframe(|\meta{left}|,|\meta{top}|)(|\meta{right}|,|\meta{bottom}^^A
+% |){|\meta{box}|}|
+% \end{quote}
+% puts an invisible frame of the given dimensions (measured in
+% |\unitlength|) around \meta{box}.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Auxiliary files}
+% \label{sec:aux-files}
+%
+% \FMF{} needs to share information between \MF{} and \LaTeX{}. For
+% this task several auxiliary files are needed.
+% The flow of information depicted in figures~\ref{fig:flow}
+% and~\ref{fig:flowp} looks much
+% more complicated than it is. The important feature is that there a
+% two sets of files which can be used to distribute a document:
+% \begin{enumerate}
+% \item{} Iff the recipient has a working \MF{} installation
+% (which shouldn't be a problem, except for some impoverished
+% commercial implementations), the document can be typset from the
+% \LaTeX{} source \emph{alone}, by running \LaTeX{}, \MF{}
+% and \LaTeX{} again (the latter step might have to be repeated to
+% get cross references right).
+% \item{} Another possibility (which doesn't require \MF{} on
+% the recipient's side), is to distribute the \LaTeX{} source, the
+% |tfm| and |gf| files (or |pk| files respectively) along with the
+% label files with extension |t|$n$ (where $n$ as an integer).
+% Distributing the \MF{} |log| files is a possible alternative
+% for the latter, but discouraged, because these are prone to be
+% erased accidentally.
+% \end{enumerate}
+%
+% \begin{figure}[t]
+% \hfuzz=3cm
+% \begin{center}
+% \leavevmode
+% \includegraphics{manpics.1}
+% \end{center}
+% \caption{Interdependency of files in a \FMF{} application.
+% The arrows show which files are updated in the two \LaTeX{}
+% passes, the \MF{} pass and the final dvi translation step.}
+% \label{fig:flow}
+% \end{figure}
+%
+% \begin{figure}[t]
+% \hfuzz=3cm
+% \begin{center}
+% \leavevmode
+% \includegraphics{manpics.2}
+% \end{center}
+% \caption{Interdependency of files in a \FMF{} application using
+% \MP: The arrows show which files are updated in the two \LaTeX{}
+% passes, the \MP{} pass and the final dvi translation step.}
+% \label{fig:flowp}
+% \end{figure}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Running \MF}
+% \label{sec:run-mf}
+%
+% Processing your document with \LaTeX{} will generate one or more
+% \MF{} files, which you will have to process with \MF. On
+% UNIX\footnote{%
+% UNIX was a trademark of UNIX Systems Laboratory, but is rumored to
+% have been donored to X/Open.}
+% systems, \MF{} is invoked as
+% \manindex{running \MF}
+% \begin{quote}
+% |mf '\mode:=|\meta{\MF-mode}|; input |\meta{\MF-file}|'|
+% \end{quote}
+% from the shell. Here \meta{\MF-file} is to be replaced by the name
+% of the input file (which is determined by the argument to the
+% |fmffile| environment, see section~\ref{sec:environments}) and
+% \meta{\MF-mode} is the proper \MF-mode for your particular printer.
+% Please consult your local guide or local wizards about how to run
+% \MF{} on other systems.
+%
+% Note that \meta{\MF-mode} \emph{must} be specified, otherwise \MF{}
+% will fail or the resulting font will not be usable.\footnote{%
+% See section~\ref{sec:value-to-large} for the typical error message
+% and for additional information on printer modes.}
+% You can look up the correct \MF{} mode in the file |modes.mf| that
+% comes with the \MF{} distribution. Among the more common laser
+% printers are |laserjet| for HP Laserjets at 300dpi, |ljfour| for HP
+% Laserjets at 600dpi, |nexthi| for NeXT laser printers at 400dpi,
+% etc.
+%
+% A non-trivial part can be instructing \TeX{} and your favorite
+% |dvi|-driver how to find the generated |tfm| and |gf| (resp.~|pk|)
+% files. This is highly system dependent and can be trivial (as in
+% the standard UNIX \TeX{} installations, where no further action is
+% required) or almost impossible without system priviledges (as under
+% MVS). Please consult your local guide or wizards on this point.
+% See also section~\ref{sec:out-of-date} for common problems with
+% |dvi| drivers.
+%
+% Some recent \TeX{} implementations (e.g.~|web2c| with |kpathsea|
+% version 2.6 or later) are able to generate |tfm| files on the fly.
+% Using such implementations, running \LaTeX{} twice should suffice
+% and \MF{} will be invoked automagically in the background. Note
+% however, that the automagically invoked tools might also install the
+% ``fonts'' corresponding to the Feynman diagrams in a system
+% directory, where they don't belong. Adding the following lines to
+% the |maketex.site| script will prevent this mishap in the
+% te\TeX{} distribution for UNIX (which is derived from |web2c|):
+% \begin{verbatim}
+% if [ -r $KPSE_DOT/$NAME.mf ]; then
+% MT_PKDESTDIR=$KPSE_DOT
+% MT_TFMDESTDIR=$KPSE_DOT
+% MT_NAMEPART=
+% fi
+% \end{verbatim}
+% The automagic tools will also \emph{not} notice when a diagram has
+% changed. These problems suggest that it is a generally a good idea
+% to invoke \MF{} explicitely, instead of relying on the automagic
+% tools.
+%
+% Running \MP{} is usually trivial, because not printer specific mode
+% is needed:
+% \manindex{running \MP}
+% \begin{quote}
+% |mp |\meta{\MP-file}||
+% \end{quote}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{The \texttt{feynmf} perl script}
+% UNIX users will be able to take advantage of the \texttt{feynmf}
+% perl script, that automates the invocation of \LaTeX{} and \MP.
+% In particular it tries to guess the correct \MF-mode and
+% magnification. The latter is often different from 1 in slide
+% classes. Here is the man page of \texttt{feynmf}:
+%
+% ^^A LaTeX document produced by pod2latex from "feynmf.pl.pod".
+% \subsubsection*{NAME}
+% {\bf feynmf} --- Process {\bf LaTeX} files using {\bf FeynMF}
+%
+% \subsubsection*{SYNOPSIS}
+% {\bf feynmf} {\tt [}{\bf -hvqncfT}{\tt ]}
+% {\tt [}{\bf -t} {\em tfm\/} {\tt [}{\bf -t} {\em tfm\/} ...{\tt ]}{\tt ]}
+% {\tt [}{\bf -m} {\em mode\/}{\tt ]}
+% {\em file\/} {\tt [}{\em file\/} ...{\tt ]}
+%
+% {\bf feynmf} {\tt [}{\bf {\tt --}help}{\tt ]}
+% {\tt [}{\bf {\tt --}version}{\tt ]} {\tt [}{\bf {\tt --}quiet}{\tt ]}
+% {\tt [}{\bf {\tt --}noexec}{\tt ]} {\tt [}{\bf {\tt --}clean}{\tt ]}
+% {\tt [}{\bf {\tt --}force}{\tt ]} {\tt [}{\bf {\tt --}notfm}{\tt ]}
+% {\tt [}{\bf {\tt --}tfm} {\em tfm\/} {\tt [}{\bf {\tt --}tfm}
+% {\em tfm\/} ...{\tt ]}{\tt ]} {\tt [}{\bf {\tt --}mode}
+% {\em mode\/}{\tt ]} {\em file\/} {\tt [}{\em file\/} ...{\tt ]}
+%
+% \subsubsection*{DESCRIPTION}
+% The most complicated part of using the {\bf FeynMF} style appears to be the
+% proper invocation of {\bf Metafont}. The {\bf feynmf} script provides a
+% convenient front end and will automagically invoke {\bf Metafont} with the
+% proper mode and magnifincation. It will also avoid cluttering system font
+% directories and offers an option to clean them.
+%
+% \subsubsection*{OPTIONS}%
+% \index{OPTIONS}
+%
+% \begin{description}
+%
+% \item[{\bf -h}, {\bf {\tt --}help}]%
+% \index{-h, --help@{\bf -h}, {\bf {\tt --}help}}%
+% \hfil\\
+% Print a short help text.
+%
+% \item[{\bf -v}, {\bf {\tt --}version}]%
+% \index{-v, --version@{\bf -v}, {\bf {\tt --}version}}%
+% \hfil\\
+% Print the version of {\bf feynmf}.
+%
+% \item[{\bf -q}, {\bf {\tt --}quiet}]%
+% \index{-q, --quiet@{\bf -q}, {\bf {\tt --}quiet}}%
+% \hfil\\
+% Don't echo the commands being executed.
+%
+% \item[{\bf -n}, {\bf {\tt --}noexec}]%
+% \index{-n, --noexec@{\bf -n}, {\bf {\tt --}noexec}}%
+% \hfil\\
+% Don't execute {\bf LaTeX} or {\bf Metafont}.
+%
+% \item[{\bf -c}, {\bf {\tt --}clean}]%
+% \index{-c, --clean@{\bf -c}, {\bf {\tt --}clean}}%
+% \hfil\\
+% Offer to delete font files that have accidentally been placed in a
+% system directory by the {\bf MakeTeXTFM} and {\bf MakeTeXPK} scripts (these
+% scripts are run by {\bf tex} (and {\bf latex}) in the background). This
+% option has only been tested with recent versions of UNIX TeX.
+%
+% \item[{\bf -f}, {\bf {\tt --}force}]%
+% \index{-f, --force@{\bf -f}, {\bf {\tt --}force}}%
+% \hfil\\
+% Don't ask any questions.
+%
+% \item[{\bf -T}, {\bf {\tt --}notfm}]%
+% \index{-T, --notfm@{\bf -T}, {\bf {\tt --}notfm}}%
+% \hfil\\
+% Don't try to prepare fake {\tt .tfm} files for the first run.
+%
+% \item[{\bf -t}, {\bf {\tt --}tfm} {\em tfm\/}]%
+% \index{-t, --tfm tfm@{\bf -t}, {\bf {\tt --}tfm} {\em tfm\/}}%
+% \hfil\\
+% Don't try guess the names of the {\tt .tfm} files to fake for
+% the first run and use the given {\em name\/}(s) instead. This option
+% can be useful if our incomplete parsing of the LaTeX input
+% files fails.
+%
+% \item[-{\bf m} {\em mode\/}, {\bf {\tt --}mode} {\em mode\/}]%
+% \index{-m mode, --mode mode@-{\bf m} {\em mode\/}, {\bf {\tt --}mode} {\em mode\/}}%
+% \hfil\\
+% Select the METAFONT mode {\em mode\/}. The default is guessed or
+% {\tt localfont} if the guess fails.
+%
+% \item[{\em file\/}]%
+% \index{file@{\em file\/}}%
+% \hfil\\
+% Main {\bf LaTeX} input files.
+%
+% \item[{\em file\/} ...]%
+% \index{file ...@{\em file\/} ...}%
+% \hfil\\
+% Other LaTeX input files that are included by the main file.
+%
+% \end{description}
+%
+% \subsubsection*{AUTHOR}
+% Thorsten Ohl $<$Thorsten.Ohl@Physik.TH-Darmstadt.de$>$
+%
+% \subsubsection*{BUGS}
+% The preparation of {\tt .tfm} files is not foolproof yet, because we can
+% parse {\bf TeX} files only superficially.
+%
+% This script has only been tested for recent {\bf teTeX} distributions
+% of UNIX {\bf TeX}, though it will probably work with other versions of
+% UNIX {\bf TeX}. The author will be grateful for portability suggestions,
+% even concerning {\bf Borg} operating systems, for the benefit of those users
+% that are forced to live with DOS or Windows.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Vertex mode}
+%
+% These basic features of \FMF{} are (or rather ``should be'')
+% available through the \LaTeX{} interface. No knowledge of
+% \MF{} is necessary.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{External vertices}
+%
+% \DescribeMacro{\fmfleft}
+% \DescribeMacro{\fmfright}
+% \DescribeMacro{\fmfbottom}
+% \DescribeMacro{\fmftop}
+% \DescribeMacro{\fmfsurround}
+% \manindex{external vertices}
+% \manindex{vertices, external}
+% Positioning of
+% external vertices has to done explicitely. The technical reason is
+% that they would otherwise collapse with their neighbors, but
+% practical reasons also suggest to give the user full control here.
+% |\fmfleft{|\meta{v1}$[$|,|\ldots$]$|}| places the
+% vertices in the comma separated list \meta{v1},\ldots\
+% equidistantly on a smooth path on the left side of the diagram.
+% |\fmfright{|\meta{v1}$[$|,|\ldots$]$|}| does the same
+% thing on the right. Similarly |\fmfbottom| and |\fmftop|, while
+% |\fmfsurround{|\meta{v1}$[$|,|\ldots$]$|}|
+% places its arguments on smooth path
+% surrounding the diagram.
+%
+% \def\gallerylabels{%
+% \fmfdotn{v}{4}%
+% \fmflabel{$v_1$}{v1}%
+% \fmflabel{$v_2$}{v2}%
+% \fmflabel{$v_3$}{v3}%
+% \fmflabel{$v_4$}{v4}}
+% \def\gallerydemo{%
+% \fbox{\begin{fmfgraph*}(15,12)
+% \fmfpen{thick}%
+% \fmfbottomn{v}{4}\gallerylabels
+% \fmfcmd{draw (bottom_gallery);}
+% \end{fmfgraph*}}\qquad
+% \fbox{\begin{fmfgraph*}(15,12)
+% \fmfpen{thick}%
+% \fmfleftn{v}{4}\gallerylabels
+% \fmfcmd{draw (left_gallery);}
+% \end{fmfgraph*}}\qquad
+% \fbox{\begin{fmfgraph*}(15,12)
+% \fmfpen{thick}%
+% \fmfsurroundn{v}{7}\fmfdotn{v}{7}%
+% \fmflabel{$v_1$}{v1}\fmflabel{$v_2$}{v2}%
+% \fmflabel{$v_3$}{v3}\fmflabel{$v_4$}{v4}%
+% \fmflabel{$v_5$}{v5}\fmflabel{$v_6$}{v6}%
+% \fmflabel{$v_7$}{v7}%
+% \fmfcmd{draw (surround_gallery);}
+% \end{fmfgraph*}}\qquad
+% \fbox{\begin{fmfgraph*}(15,12)
+% \fmfpen{thick}%
+% \fmftopn{v}{4}\gallerylabels
+% \fmfcmd{draw (top_gallery);}
+% \end{fmfgraph*}}\qquad
+% \fbox{\begin{fmfgraph*}(15,12)
+% \fmfpen{thick}%
+% \fmfrightn{v}{4}\gallerylabels
+% \fmfcmd{draw (right_gallery);}
+% \end{fmfgraph*}}}
+%
+% \DescribeMacro{\fmfcurved}
+% \DescribeMacro{\fmfstraight}
+% \manindex{galleries}
+% Per default, the \emph{galleries} on which we place the external
+% vertices are curved as in figure~\ref{fig:curvedgalleries}, but
+% straight galleries are also available. The macros
+% |\fmfcurved| and |\fmfstraight| switch between
+% these alternatives.
+%
+% \begin{figure}[t]
+% \begin{center}
+% \gallerydemo
+% \end{center}
+% \caption{\label{fig:curvedgalleries}%
+% Curved galleries.}
+% \end{figure}
+%
+% \begin{figure}[t]
+% \begin{center}
+% \fmfstraight
+% \gallerydemo
+% \fmfcurved
+% \end{center}
+% \caption{\label{fig:straightgalleries}%
+% Straight galleries.}
+% \end{figure}
+%
+% \DescribeMacro{\fmfleftn}
+% \DescribeMacro{\fmfrightn}
+% \DescribeMacro{\fmfbottomn}
+% \DescribeMacro{\fmftopn}
+% \DescribeMacro{\fmfsurroundn}
+% \manindex{external vertices}
+% \manindex{vertices, external}
+% The macro |\fmfleftn| is similar to |\fmfleft|, but
+% |\fmfleftn{|\meta{v}\allowbreak|}{|\meta{n}|}| places the
+% vertices
+% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. Analogously for
+% the macros |\fmfrightn|, |\fmfbottomn|, |\fmftopn| and
+% |\fmfsurroundn|.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Arcs and internal vertices}
+%
+% \DeleteShortVerb{\|}
+% \MakeShortVerb{\"}
+%
+% \def\linesample#1{%
+% \begin{fmfgraph}(30,6)
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{#1}{i,o}
+% \end{fmfgraph}}
+% \begin{table}[t]
+% \hfuzz=3cm
+% \begin{center}
+% \begin{tabular}{|l|c|l|l|}\hline
+% Name & Example & Parameters & Aliases \\\hline\hline
+% "curly" & \linesample{curly} & "curly_len" & "gluon" \\\hline
+% "dbl_curly" & \linesample{dbl_curly} & "curly_len" & \\\hline
+% "dashes" & \linesample{dashes} & "dash_len" & \\\hline
+% "dashes_arrow" & \linesample{dashes_arrow} & "dash_len" & "scalar" \\\hline
+% "dbl_dashes" & \linesample{dbl_dashes} & "dash_len" & \\\hline
+% "dbl_dashes_arrow" & \linesample{dbl_dashes_arrow} & "dash_len" & \\\hline
+% "dots" & \linesample{dots} & "dot_len" & \\\hline
+% "dots_arrow" & \linesample{dots_arrow} & "dot_len" & "ghost" \\\hline
+% "dbl_dots" & \linesample{dbl_dots} & "dot_len" & \\\hline
+% "dbl_dots_arrow" & \linesample{dbl_dots_arrow} & "dot_len" & \\\hline
+% "phantom" & \linesample{phantom} & & \\\hline
+% "phantom_arrow" & \linesample{phantom_arrow} & & \\\hline
+% "plain" & \linesample{plain} & & "vanilla"\\\hline
+% "plain_arrow" & \linesample{plain_arrow} & & "fermion",
+% "electron",
+% "quark" \\\hline
+% "dbl_plain" & \linesample{dbl_plain} & & "double" \\\hline
+% "dbl_plain_arrow" & \linesample{dbl_plain_arrow} & & "double_arrow",
+% "heavy" \\\hline
+% "wiggly" & \linesample{wiggly} & "wiggly_len"& "boson",
+% "photon" \\\hline
+% "dbl_wiggly" & \linesample{dbl_wiggly} & "wiggly_len"& \\\hline
+% "zigzag" & \linesample{zigzag} & "zigzag_width"& \\\hline
+% "dbl_zigzag" & \linesample{dbl_zigzag} & "zigzag_len"& \\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Available line styles}
+% \label{tab:line-styles}
+% \end{table}
+%
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|p{60mm}|}\hline
+% Name & Explanation \\\hline\hline
+% "tension" & draw a tighter ($>1$) or more loose ($<1$) arc \\\hline
+% "left" & draw on a halfcircle on the left \\\hline
+% "right" & draw on a halfcircle on the right \\\hline
+% "straight" & draw on a straight line (default) \\\hline
+% "label" & \TeX{} text for labeling the arc \\\hline
+% "label.side" & force placement of the label on the "left" or
+% "right" \\\hline
+% "label.dist" & place label at a distance "dist" \\\hline
+% "label.pos" & relative position of the label
+% (not implemented yet!) \\\hline
+% "tag" & optional tag for disambiguating arcs\\\hline
+% "width" & width of the line\\\hline
+% "rubout" & scale factor for crossing out lines
+% (doesn't work properly for doubled lines yet)\\\hline
+% "foreground" & foreground color (\MP{} only!)\\\hline
+% "background" & background color for doubled lines (\MP{} only!)\\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Available line options}
+% \label{tab:line-options}
+% \end{table}
+%
+% \DeleteShortVerb{\"}
+% \MakeShortVerb{\|}
+%
+% \DescribeMacro{\fmf}
+% \manindex{labels}
+% \manindex{arcs}
+% This is the the most frequently used macro in \FMF{} applications.
+% \begin{quote}
+% |\fmf{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$^^A
+% |}{|\meta{v1}|,|\meta{v2}$[$|,|\ldots$]$|}|
+% \end{quote}
+% connects the vertices \textit{v1,v2,\ldots} with a line of style
+% \meta{style}, using a set of options \meta{opt} with (optional)
+% value \meta{val}. If a vertex is not
+% known yet, it is added to the diagram. Note that the actual drawing
+% is not done immediately, because the positions can only be
+% calculated when \emph{all} vertices are known. The currently
+% available styles are collected in table~\ref{tab:line-styles}. Most
+% names should be self explanatory
+% and are not discussed further.
+% The |dashes|, |dots|, |phantom| and |plain| styles can optionally be
+% decorated with an arrow as shown above. All styles, including
+% |curly|, |wiggly| and |zigzag|, can be doubled. But arrows are not
+% available
+% for the latter three, because esthetically pleasing results can not be
+% expected. The |phantom|
+% style is special, because it
+% only enters the vertices and does \emph{not} cause a line to be
+% drawn. This is extremely useful for advanced layout features, as
+% explained below.
+% If you need a line styles that is not listed in
+% table~\ref{tab:line-styles}, see section~\ref{sec:extensions} for
+% how to define your own line styles.
+%
+% The supported options are collected in
+% table~\ref{tab:line-options}\footnote{%
+% One particulary useful further option would be \texttt{smooth},
+% allowing for several lines joined smoothly. Early
+% experimentation has shown however, that the results are not
+% always what one expects and that there is a lot of room for
+% abuse.}
+% Note that each of the dot separated components of the options can be
+% abbreviated. For example, |l.d| is equivalent to |label.dist|. The
+% result of ambiguous matches is however undefined.
+%
+% Note that because the options are separated by single commata,
+% commata inside arguments to options (|label| comes to mind) have to
+% be doubled (similar to quotes in Fortran).\footnote{%
+% Note that, as of version 1.03, it is no longer necessary to
+% escape \TeX{} control sequences in arguments. Old files will
+% continue to work, because \texttt{noexpand} is temporarily
+% disabled.}
+%
+% Arcs that return to their origin are allowed (I will refer to them
+% as \emph{tadpoles}), but some options have slightly different
+% semantics. |tension| is here a inverse scale factor for the
+% tadpole, whose
+% default size is 2/3 of the average distance the neighboring
+% vertices. If |left| or |right| are specified, they give the direction
+% (in degrees) of the preferred gap into which the tadpole is placed.
+% By default, the largest gap is chosen for \emph{all} tapoles at a
+% given vertex, which will therefore overlap. This is neither a bug
+% nor a feature, but a limitation.
+%
+% \DescribeMacro{\fmfn}
+% \manindex{arcs}
+% The macro |\fmfn| is similar to |\fmf|, but
+% \begin{quote}
+% |\fmfn{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$^^A
+% |}{|\meta{v}|}{|\meta{n}|}|
+% \end{quote}
+% connects the vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}.
+%
+% \DescribeMacro{\fmfcyclen}
+% \DescribeMacro{\fmfrcyclen}
+% \manindex{arcs}
+% The macro |\fmfcyclen{|\meta{style}|}{|\meta{v}|}{|\meta{n}|}|
+% cyclically connects the vertices
+% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. |\fmfrcyclen| operates in
+% reverse order.
+%
+% \DescribeMacro{\fmfpen}
+% Pick up a pen of the specified size. |\fmfpen{|\meta{weight}|}|
+% is used for changing the weight (i.e.~thickness) of the lines.
+% Predefined sizes are |thin| and |thick|.
+%
+% \DeleteShortVerb{\|}
+% \MakeShortVerb{\"}
+%
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|p{60mm}|}\hline
+% Name & Explanation \\\hline\hline
+% "label" & \TeX{} text for labeling the vertex \\\hline
+% "label.angle" & force placement of the label at the given
+% angle from the vertex \\\hline
+% "label.dist" & place label at a distance "dist" \\\hline
+% "decoration.shape" & shape of decoration \\\hline
+% "decoration.size" & size of decoration \\\hline
+% "decoration.filled" & fill, shade or hatch decoration \\\hline
+% "decoration.angle" & rotate decoration \\\hline
+% "foreground" & foreground color (\MP{} only!)\\\hline
+% "background" & background color (\MP{} only!)\\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Available vertex options}
+% \label{tab:vertex-options}
+% \end{table}
+%
+% \DeleteShortVerb{\"}
+% \MakeShortVerb{\|}
+%
+% \DescribeMacro{\fmfv}
+% \manindex{internal vertices}
+% \manindex{vertices, internal}
+% \manindex{labels}
+% Declare vertices with options:
+% \begin{quote}
+% |\fmfv{|\meta{opt}$[$|=|\meta{val}$][$|,|\meta{opt}$[$|=|\meta{val}$]$^^A
+% |,|\ldots$]$|}{|\meta{v1}$[$|,|\ldots$]$|}|
+% \end{quote}
+% This is used for adding labels to a vertex and for specifying other
+% decoration. Supported options are collected in
+% table~\ref{tab:vertex-options}. Here the same abbreviation
+% mechanism as above is in effect. The available |shape|s are listed
+% in various filling styles in table~\ref{tab:vertex-shapes}\footnote{%
+% If the variable \texttt{feymfwizard} is \texttt{true} (e.g.~after
+% calling the \texttt{\bslash fmfwizard} macro),
+% it is also possible to specify any \MF{} expression that evaluates
+% to a \texttt{path}. Naturally, this has to used with great care,
+% because strange errors can be triggered by typos!}.
+% The tilings |gray10|, |gray25|, |gray75| and |gray90| are available
+% in addition to |gray50|. Customized tilings can be created with
+% the \MF{} function |tile_from_string|. It should be noted however,
+% that tilings are gobbling up memory at high speed and should be used
+% with discretion. The halftones\footnote{%
+% \MP{} will give true halftones (if your printer supports them),
+% while \MF{} tries to mimic them. The dithering algorithm of the
+% latter will be improved in the future.}
+% can be accessed by giving any number from 2 to 99, which will denote
+% the percentage of saturation ($30\%$ and $70\%$ here)\footnote{%
+% The old numeric arguments in the range $-1\ldots1$ continue to
+% work, but are considered obsolete.}.
+% Again, commata inside arguments to options have to be doubled.
+%
+% \end{fmffile}
+% \begin{fmffile}{fmfsamp2}
+%
+% \DeleteShortVerb{\|}
+% \MakeShortVerb{\"}
+%
+% \def\VertexSample#1#2{%
+% \begin{fmfgraph}(8,8)
+% \fmfforce{(.5w,.4h)}{c}
+% \fmfv{d.shape=#1,d.filled=#2}{c}
+% \end{fmfgraph}}
+% \def\VertexSamples#1{%
+% \VertexSample{#1}{full} & \VertexSample{#1}{empty}
+% & \VertexSample{#1}{shaded} & \VertexSample{#1}{hatched}
+% & \VertexSample{#1}{gray50} & \VertexSample{#1}{30}
+% & \VertexSample{#1}{70}}
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|c|c|c|c|c|c|c|}\hline
+% "filled=" & "full" & "empty" & "shaded" & "hatched"
+% & "gray50" & "30" & "70" \\\hline\hline
+% "circle" & \VertexSamples{circle} \\\hline
+% "square" & \VertexSamples{square} \\\hline
+% "triangle" & \VertexSamples{triangle} \\\hline
+% "diamond" & \VertexSamples{diamond} \\\hline
+% "pentagon" & \VertexSamples{pentagon} \\\hline
+% "hexagon" & \VertexSamples{hexagon} \\\hline
+% "triagram" & \VertexSamples{triagram} \\\hline
+% "tetragram"& \VertexSamples{tetragram} \\\hline
+% "pentagram"& \VertexSamples{pentagram} \\\hline
+% "hexagram" & \VertexSamples{hexagram} \\\hline
+% \end{tabular}
+% \vspace*{\baselineskip}\\
+% \begin{tabular}{|c|c|c|c|}\hline
+% "triacross" & "cross" & "pentacross" & "hexacross" \\\hline\hline
+% \VertexSample{triacross}{1} & \VertexSample{cross}{1}
+% & \VertexSample{pentacross}{1} & \VertexSample{hexacross}{1} \\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Available vertex shapes and fill styles.}
+% \label{tab:vertex-shapes}
+% \end{table}
+%
+% \DeleteShortVerb{\"}
+% \MakeShortVerb{\|}
+%
+% \DescribeMacro{\fmfblob}
+% \manindex{blobs}
+% Draw a blob of the specified diameter at the vertices. Incidentally,
+% \begin{quote}
+% |\fmfblob{|\meta{diameter}|}{|\meta{v1}$[$|,|\ldots$]$|}|
+% \end{quote}
+% is equivalent to
+% \begin{quote}
+% \begin{flushleft}
+% |\fmfv{decor.shape=circle,decor.filled=shaded,|\\
+% \qquad |decor.size=|\meta{diameter}|}{|\meta{v1}$[$|,|\ldots$]$|}|
+% \end{flushleft}
+% \end{quote}
+%
+% \DescribeMacro{\fmfdot}
+% \manindex{dots}
+% Draw a dot at the vertices given as arguments.
+% \begin{quote}
+% |\fmfdot{|\meta{v1}$[$|,|\ldots$]$|}|
+% \end{quote}
+% is equivalent to
+% \begin{quote}
+% \begin{flushleft}
+% |\fmfv{decor.shape=circle,decor.filled=full,|\\
+% \qquad |decor.size=2thick}{|\meta{v1}$[$|,|\ldots$]$|}|
+% \end{flushleft}
+% \end{quote}
+% \DescribeMacro{\fmfvn}
+% \manindex{internal vertices}
+% \manindex{vertices, internal}
+% The macro |\fmfvn| is similar to |\fmfv|, but
+% \begin{quote}
+% |\fmfvn{|\meta{opt}$[$|=|\meta{val}$][$|,|^^A
+% \meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v}|}{|\meta{n}|}|
+% \end{quote}
+% places the vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}.
+%
+% \DescribeMacro{\fmfdotn}
+% \DescribeMacro{\fmfblobn}
+% \manindex{blobs}
+% \manindex{dots}
+% The macros |\fmfdotn| and |\fmfblobn| are similar to the |\fmfdot|
+% and |\fmfblob|, but |\fmfdotn{|\meta{v}|}{|\meta{n}|}| places the
+% vertices \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. Analogously for
+% |\fmfblobn|.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Polygons}
+%
+% Complex vertices with arcs attached at the corners can be
+% contructed with polygons, which share some characteristics with arcs
+% and vertices.
+%
+% \DescribeMacro{\fmfpoly}
+% \manindex{polygons}
+% The macro
+% \begin{quote}
+% |\fmfpoly{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$^^A
+% |,|\ldots$]$|}{|\meta{v1}|,|\meta{v2}$[$|,|\ldots$]$|}|
+% \end{quote}
+% places the vertices \meta{v1}, \meta{v2}, \ldots{} on the corners of
+% a regular polygon. The orientation of the polygon is fixed to be
+% mathematically positive (i.e.~counter clockwise). Note that this
+% can have strange results if the orientation is opposite to the
+% orientation of the vertices the corners are connected to.
+% The available options are collected in
+% table~\ref{tab:polygon-options}. The effects of some options are
+% depicted in table~\ref{tab:polygon-shapes}.
+%
+% Note that is is technically \emph{impossible} to fix the size of a
+% polygon. The size can be controlled by specifying a |tension| for
+% the edges, which acts like the |tension| of normal arcs.
+%
+% \DeleteShortVerb{\|}
+% \MakeShortVerb{\"}
+%
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|p{60mm}|}\hline
+% Name & Explanation \\\hline\hline
+% "filled" & fill, shade or hatch interior \\\hline
+% "phantom" & don't draw anything \\\hline
+% "empty" & draw outline \\\hline
+% "shade" & shade interior \\\hline
+% "hatched" & hatch interior \\\hline
+% "full" & fill interior \\\hline
+% "pull" & pull edges in ($<0$) or out ($>0$) \\\hline
+% "tension" & tension of the edges \\\hline
+% "smooth" & draw smoth corners \\\hline
+% "label" & \TeX{} text for labeling the polygon \\\hline
+% "label.angle" & force placement of the label at the given
+% angle from the vertex \\\hline
+% "label.dist" & place label at a distance "dist" \\\hline
+% "foreground" & foreground color (\MP{} only!)\\\hline
+% "background" & background color (\MP{} only!)\\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Available polygon options}
+% \label{tab:polygon-options}
+% \end{table}
+%
+% \def\PolygonSample#1#2{%
+% \begin{fmfgraph}(15,15)
+% \fmfsurroundn{e}{#1}
+% \fmfpolyn{shaded,tension=#2}{z}{#1}
+% \begin{fmffor}{i}{1}{1}{#1}
+% \fmf{plain}{z[i],e[i]}
+% \end{fmffor}
+% \end{fmfgraph}}
+% \def\PolygonSamples#1#2#3{%
+% \PolygonSample{#1}{#2,pull=0.75#3}
+% & \PolygonSample{#1}{#2,pull=1.0#3}
+% & \PolygonSample{#1}{#2#3}
+% & \PolygonSample{#1}{#2,pull=1.5#3}}
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|c|c|c|c|}\hline
+% "pull=" & 0.75 & 1.0 & "?" & 1.5 \\\hline\hline
+% default & \PolygonSamples{3}{.1}{} \\\hline
+% "smooth" & \PolygonSamples{3}{.1}{,smooth} \\\hline
+% default & \PolygonSamples{5}{.6}{} \\\hline
+% "smooth" & \PolygonSamples{5}{.6}{,smooth} \\\hline
+% default & \PolygonSamples{7}{1.}{} \\\hline
+% "smooth" & \PolygonSamples{7}{1.}{,smooth} \\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Some of the available polygon shapes. Note that
+% \texttt{pull=1.0} is identical to \texttt{pull=?} for straight
+% lines, but very different for \texttt{smooth} lines.}
+% \label{tab:polygon-shapes}
+% \end{table}
+%
+% \DeleteShortVerb{\"}
+% \MakeShortVerb{\|}
+%
+% \DescribeMacro{\fmfpolyn}
+% \DescribeMacro{\fmfrpolyn}
+% \manindex{polygons}
+% The macro |\fmfpolyn{|\meta{style}|}{|\meta{v}|}{|\meta{n}|}|
+% is similar to |\fmfpoly| but connects the vertices
+% \meta{v$[$1$]$}\ldots\meta{v$[$n$]$}. |\fmfrpolyn| operates in
+% reverse order.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Color}
+%
+% If \MP{} is used for rendering the diagrams, vertices and arcs can
+% be colored. The corresponding options give a warning message under
+% \MF{} and are otherwise ignored.
+%
+% \manindex{color}
+% Two colors are available for vertices and arcs: |foreground| and
+% |background|. Both can either be specified as a linear combination
+% of the predefined colors |white|, |black|, |red|, |green| and |blue|
+% or as RBG triples
+% |(|\meta{red}|,|\allowbreak\meta{green}|,|\allowbreak\meta{blue}|)|.
+% Note that as always commata have to be doubled in option arguments.
+% Therefore both |foreground=|\allowbreak|(1,,0,,1)| and
+% |foreground=|\allowbreak|red+|\allowbreak|blue| are
+% valid options setting the foreground color to magenta.
+% For arcs, the background color is used only for the interior of
+% doubled lines.
+%
+% While the color feature is rarely used in papers or books, it can
+% be very useful for jazzing up your transparencies. See
+% page~\pageref{rainbow} for a not very serious example.
+%
+% \end{fmffile}
+% \begin{fmffile}{fmfsamp3}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Examples}
+%
+% After the main features of the vertex mode have been introduced, it
+% is time for a couple of illustrative examples that are taken from
+% \emph{The Real World}.
+%
+% \begin{examples}{40mm}
+%
+% As a first example, consider drawing a straightforward box diagram,
+% familiar from $K$-$\bar K$, $D$-$\bar D$, and $B$-$\bar B$ mixing.
+% The commands for the labels are not shown here, they are discussed
+% in section~\ref{sec:labels}
+%
+% Let us start the diagram and pick up a thick pen:
+% \begin{verbatim}
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \end{verbatim}
+% The incoming and outcoming vertices are placed on the left and
+% right hand side, respectively:
+% \begin{verbatim}
+% \fmfleft{i1,i2}
+% \fmfright{o1,o2}
+% \end{verbatim}
+% Now we tell \FMF{} how the arcs are connected.
+% \begin{verbatim}
+% \fmf{fermion}{i1,v1,v3,o1}
+% \fmf{fermion}{o2,v4,v2,i2}
+% \fmf{photon}{v1,v2}
+% \fmf{photon}{v3,v4}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1,i2}
+% \fmflabel{$\bar{b}$}{i1}
+% \fmflabel{$d$}{i2}
+% \fmfright{o1,o2}
+% \fmflabel{$\bar{d}$}{o1}
+% \fmflabel{$b$}{o2}
+% \fmf{fermion}{i1,v1}
+% \fmf{fermion,label=$\bar{t},,\bar{c},,\bar{u}$,
+% l.side=right}{v1,v3}
+% \fmf{fermion}{v3,o1}
+% \fmf{fermion}{o2,v4}
+% \fmf{fermion,label=$t,,c,,u$,l.side=right}{v4,v2}
+% \fmf{fermion}{v2,i2}
+% \fmf{photon,label=$W^+$,l.side=left}{v1,v2}
+% \fmf{photon,label=$W^-$,l.side=right}{v3,v4}
+% \fmfdotn{v}{4}
+% \end{fmfgraph*}}
+% \label{pg:box}
+% Finally we tell \FMF{} to draw dots at the vertices and we're done.
+% \begin{verbatim}
+% \fmfdotn{v}{4}
+% \end{fmfgraph}
+% \end{verbatim}
+% \label{page:simple-examples}
+% With a little effort the layout of this diagram can actually be
+% improved by enlarging the inner box, see page~\pageref{pg:newbox}
+% below.
+%
+% Here is the resonant $s$-channel contribution to $e^+e^-\to 4f$.
+% (From now on, we do no longer display the
+% \begin{verbatim}
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% ...
+% \end{fmfgraph}
+% \end{verbatim}
+% environment surrounding all pictures.)
+% \begin{verbatim}
+% \fmfleftn{i}{2}
+% \fmfrightn{o}{4}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{photon}{v1,v2}
+% \fmfblob{.15w}{v2}
+% \fmf{photon}{v2,v3}
+% \fmf{fermion}{o1,v3,o2}
+% \fmf{photon}{v2,v4}
+% \fmf{fermion}{o4,v4,o3}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,25)
+% \fmfpen{thick}
+% \fmfleftn{i}{2}
+% \fmfrightn{o}{4}
+% \fmflabel{$e_-$}{i1}
+% \fmflabel{$e_+$}{i2}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{photon}{v1,v2}
+% \fmfblob{.15w}{v2}
+% \fmf{photon}{v2,v3}
+% \fmflabel{$\mu_+$}{o1}
+% \fmflabel{$\nu_\mu$}{o2}
+% \fmf{fermion}{o1,v3,o2}
+% \fmf{photon}{v2,v4}
+% \fmflabel{$\bar{c}$}{o4}
+% \fmflabel{$s$}{o3}
+% \fmf{fermion}{o4,v4,o3}
+% \end{fmfgraph*}}
+%
+% And the resonant $t$-channel contribution:
+% \begin{verbatim}
+% \fmfleftn{i}{2}
+% \fmfrightn{o}{4}
+% \fmf{fermion}{i1,v1,v2,i2}
+% \fmf{photon}{v1,v3}
+% \fmf{fermion}{o1,v3,o2}
+% \fmf{photon}{v2,v4}
+% \fmf{fermion}{o4,v4,o3}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,25)
+% \fmfpen{thick}
+% \fmfleftn{i}{2}
+% \fmfrightn{o}{4}
+% \fmflabel{$e_-$}{i1}
+% \fmflabel{$e_+$}{i2}
+% \fmf{fermion}{i1,v1,v2,i2}
+% \fmf{photon}{v1,v3}
+% \fmflabel{$\mu_+$}{o1}
+% \fmflabel{$\nu_\mu$}{o2}
+% \fmf{fermion}{o1,v3,o2}
+% \fmf{photon}{v2,v4}
+% \fmflabel{$\bar{c}$}{o4}
+% \fmflabel{$s$}{o3}
+% \fmf{fermion}{o4,v4,o3}
+% \end{fmfgraph*}}
+%
+% Two point loop diagrams pose another set of problems. We
+% must have a way of specifying that one or more of the lines
+% connecting the two vertices are \emph{not} connected by a straight
+% line. The options |left|, |right| and |straight| offer the
+% possibility to connect two vertices by a semicircle detour, either
+% on the left or on the right. Since by default all lines contribute
+% to the tension between two vertices, the |tension| option allows us
+% to reduce this tension. The next examples shows both options in
+% action. The lower fermion line is given an tension of~$1/3$ to
+% make is symmetrical with the upper line with consists of three parts.
+% The loop photon is using a detour on the right and does not
+% contribute any tension.
+% \begin{verbatim}
+% \fmfleft{i1,i2}
+% \fmfright{o1}
+% \fmf{fermion,tension=1/3}{i1,v1}
+% \fmf{plain}{v1,v2}
+% \fmf{fermion}{v2,v3}
+% \fmf{photon,right,tension=0}{v2,v3}
+% \fmf{plain}{v3,i2}
+% \fmf{photon}{v1,o1}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1,i2}
+% \fmflabel{$p^{\prime}$}{i1}
+% \fmflabel{$p$}{i2}
+% \fmfright{o1}
+% \fmf{fermion,tension=1/3}{i1,v1}
+% \fmf{plain}{v1,v2}
+% \fmf{fermion,label=$p-k$,l.side=left}{v2,v3}
+% \fmf{photon,right,tension=0,label=$k$}{v2,v3}
+% \fmf{plain}{v3,i2}
+% \fmf{photon}{v1,o1}
+% \end{fmfgraph*}}
+% The optional argument to |left| and |right| can be used to deform the
+% corresponding contour as in the following example.
+% The default value of |left| and |right| is 1.
+% \begin{verbatim}
+% \fmfleft{i} \fmfright{o}
+% \fmf{plain}{i,v1} \fmf{plain}{v2,o}
+% \fmf{dots,left=.5,tension=0.3}{v1,v2,v1}\fmffreeze
+% \fmf{plain,left}{v1,v2,v1}
+% \fmf{dashes,left=1.5}{v1,v2,v1}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,30)
+% \fmfpen{thick}
+% \fmfleft{i} \fmfright{o}
+% \fmf{plain}{i,v1} \fmf{plain}{v2,o}
+% \fmf{dots,left=.5,tension=0.3}{v1,v2,v1}\fmffreeze
+% \fmf{plain,left}{v1,v2,v1}
+% \fmf{dashes,left=1.5}{v1,v2,v1}
+% \end{fmfgraph}}
+%
+% Polygons are particulary useful for depicting non-perturbative
+% contributions:
+% \begin{verbatim}
+% \fmfpen{thick}
+% \fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfrpolyn{shaded,label=$\Gamma$}{G}{4}
+% \fmfpolyn{empty,label=$K$}{K}{4}
+% \fmf{fermion}{l1,G1}\fmf{fermion}{l2,G2}
+% \fmf{fermion}{K1,r1}\fmf{fermion}{K2,r2}
+% \fmf{fermion,left=.5,tension=.5}{G3,K3}
+% \fmf{fermion,right=.5,tension=.5}{G4,K4}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,25)
+% \fmfpen{thick}
+% \fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfrpolyn{shaded,label=$\Gamma$}{G}{4}
+% \fmfpolyn{empty,label=$K$}{K}{4}
+% \fmf{fermion}{l1,G1}\fmf{fermion}{l2,G2}
+% \fmf{fermion}{K1,r1}\fmf{fermion}{K2,r2}
+% \fmf{fermion,left=.5,tension=.5}{G3,K3}
+% \fmf{fermion,right=.5,tension=.5}{G4,K4}
+% \end{fmfgraph*}}
+%
+% To conclude this first picture show, here's a self energy in
+% scalar $\phi^4$-theory showing the simplicity of the tadpole
+% feature:
+% \begin{verbatim}
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{plain}{i,v,v,o}
+% \fmfdot{v}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{plain}{i,v,v,o}
+% \fmfdot{v}
+% \end{fmfgraph}}
+% \manindex{tadpoles}
+% Scalar $\phi^6$-theory needs a little manual intervention to force
+% the second on the opposite side:
+% \begin{verbatim}
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{plain}{i,v,v,o}
+% \fmf{plain,left=90}{v,v}
+% \fmfdot{v}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{plain}{i,v,v,o}
+% \fmf{plain,left=90}{v,v}
+% \fmfdot{v}
+% \end{fmfgraph}}
+%
+% \end{examples}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Labels}
+% \label{sec:labels}
+%
+% Let us now come back to the examples on
+% page~\pageref{page:simple-examples} and discuss how to add the
+% labels.
+%
+% \DescribeMacro{\fmflabel}
+% \manindex{labels}
+% The macro
+% \begin{quote}
+% |\fmflabel{|\meta{label}|}{|\meta{v}|}|
+% \end{quote}
+% is equivalent to
+% \begin{quote}
+% |\fmfv{label=|\meta{label}|}{|\meta{v}|}|
+% \end{quote}
+% and adds the label
+% \meta{label} to the vertex \meta{v}. In the current implementation,
+% there can be only a single label for each vertex. Thus earlier
+% calls to |\fmflabel| for the same vertex will be overwritten.
+% \meta{label} will be placed with the |\put| command of the \LaTeX{}
+% |picture| environment.\footnote{%
+% Note again that, as of version 1.03, it is no longer necessary to
+% escape \TeX{} control sequences in arguments. Old files will
+% continue to work, because \texttt{noexpand} is temporarily
+% disabled.}
+% Note that the |fmfgraph*| environment must be used to use labels,
+% they will silently disappear in |fmfgraph|.
+%
+% |\fmflabel| gives the user \emph{no} control on the placement of
+% the the label (use the |\fmfv| macro for a more fine-grained
+% control). The label is placed using the
+% following algorithm:
+% \begin{enumerate}
+% \item{} The reference point of the box containing \meta{label} is
+% placed at the distance |3thick| on the continuation of the
+% straight line connecting the center of the picture with the
+% vertex \meta{v}.
+% \item{} The reference point of the box is chosen such that the
+% contents of the box is on the outside of the vertex (with
+% respect to the center of the diagram). It is chosen from the
+% four corners and the four midpoints of the sides.
+% \end{enumerate}
+%
+% Therefore the four external particles in the~$B$-$\bar B$ mixing
+% diagram on page~\pageref{page:simple-examples} are labelled simply
+% by:
+% \begin{verbatim}
+% \fmflabel{$\bar{b}$}{i1}
+% \fmflabel{$d$}{i2}
+% \fmflabel{$\bar{d}$}{o1}
+% \fmflabel{$b$}{o2}
+% \end{verbatim}
+%
+% \begin{examples}{40mm}
+% \manindex{labels}
+% Here is a more systematical demonstration of the default placement
+% of labels:
+% \begin{verbatim}
+% \fmfsurroundn{v}{8}\fmfdotn{v}{8}
+% \fmflabel{$v_1$}{v1}
+% \fmflabel{$v_2$}{v2}
+% \fmflabel{$v_3$}{v3}
+% \fmflabel{$v_4$}{v4}
+% \fmflabel{$v_5$}{v5}
+% \fmflabel{$v_6$}{v6}
+% \fmflabel{$v_7$}{v7}
+% \fmflabel{$v_8$}{v8}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,30)
+% \fmfsurroundn{v}{8}\fmfdotn{v}{8}
+% \fmflabel{$v_1$}{v1}
+% \fmflabel{$v_2$}{v2}
+% \fmflabel{$v_3$}{v3}
+% \fmflabel{$v_4$}{v4}
+% \fmflabel{$v_5$}{v5}
+% \fmflabel{$v_6$}{v6}
+% \fmflabel{$v_7$}{v7}
+% \fmflabel{$v_8$}{v8}
+% \end{fmfgraph*}}
+% And here is a demonstration of the explicit placement of
+% labels\footnote{%
+% Don't be confused by the \texttt{\bslash fmfiv} command. It is
+% described below (see section~\ref{sec:fmfiv}) and takes the same
+% arguments as the \texttt{\bslash fmfv} command. We use it here
+% for convenience to place multiple vertices at the same point,
+% i.e.~the center.}:
+% \begin{verbatim}
+% \fmfiv{d.sh=circle,d.f=1,d.si=2thin}{c}
+% \fmfiv{l=-120,l.a=-120,l.d=.2w}{c}
+% \fmfiv{l=-60,l.a=-60,l.d=.2w}{c}
+% \fmfiv{l=0,l.a=0,l.d=.2w}{c}
+% \fmfiv{l=60,l.a=60,l.d=.2w}{c}
+% \fmfiv{l=120,l.a=120,l.d=.2w}{c}
+% \fmfiv{l=180,l.a=180,l.d=.2w}{c}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,30)
+% \fmfiv{d.sh=circle,d.f=1,d.si=2thin}{c}
+% \fmfiv{l=-120,l.a=-120,l.d=.2w}{c}
+% \fmfiv{l=-60,l.a=-60,l.d=.2w}{c}
+% \fmfiv{l=0,l.a=0,l.d=.2w}{c}
+% \fmfiv{l=60,lab.ang=60,l.d=.2w}{c}
+% \fmfiv{l=120,l.a=120,l.d=.2w}{c}
+% \fmfiv{l=180,l.a=180,l.d=.2w}{c}
+% \end{fmfgraph*}}
+%
+% \end{examples}
+%
+% There is no equivalent to |\fmflabel| for arcs. Here options to the
+% |\fmf| command have to be used. The default placement rules put the
+% label on the outside at the midpoint of a curved arc. If the arc is
+% straight, one should use the |label.side| option to push the label
+% either to the |left| or to the |right|. This |label.dist| option is
+% treated analogously to same option for vertices.
+%
+% Therefore the four internal particles in the~$B$-$\bar B$ mixing
+% diagram on page~\pageref{page:simple-examples} are labelled simply
+% by adding options to the |\fmf| commands:
+% \manindex{labels}
+% \begin{verbatim}
+% \fmf{fermion,label=$\bar{t},,\bar{c},,\bar{u}$,
+% label.side=right}{v1,v3}
+% \fmf{fermion,label=$t,,c,,u$,label.side=right}{v4,v2}
+% \fmf{photon,label=$W^+$,label.side=left}{v1,v2}
+% \fmf{photon,label=$W^-$,label.side=right}{v3,v4}
+% \end{verbatim}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Manipulating the layout}
+%
+% The automatic layout algorithms of \FMF{} are rather simple,
+% therefore it is sometimes necessary to allow for manual intervention
+% from time to time.
+%
+% \DescribeMacro{\fmffreeze}
+% Calculate the positions of the vertices based on the arcs which are
+% defined up to this point. Usually this calculation is performed
+% automatically at the end of the |fmfgraph| environment. Calling it
+% explicitely is useful for later adding arcs that should not enter
+% the calculation . The layout is chosen to minimize the overall
+% length of all arcs. The length of each arc is weighted with the
+% |tension| option, whose default value is 1.
+% See section~\ref{sec:skeletons} for more information on
+% |\fmffreeze|.
+%
+% \DescribeMacro{\fmfforce}
+% |\fmfforce{|\meta{pos}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
+% forces the position \meta{pos} of the vertices \meta{v1}\ldots,
+% bypassing and overwriting the automatic layout. In all arguments
+% that are \MF{} |pair|s (i.e.~points), you can use the variable |w|
+% and |h|, which are predefined to the width and the height of the
+% whole
+% diagram respectively. E.g.~the center is specified as |(.5w,.5h)|
+% and the lower right corner as |(w,0)|.
+% The center and the four corners of the current subgraph (see the
+% \texttt{fmfsubgraph} environment on page~\pageref{fmfsubgraph}) are
+% available as |c|, |nw|, |ne|, |sw| and |se| (for \emph{north-west}
+% etc).
+%
+% \DescribeMacro{\fmfshift}
+% |\fmfshift{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
+% shifts the position of the vertices \meta{v1}\ldots{} by \meta{dist}
+% from the automatic layout. This command is only useful \emph{after}
+% a |\fmffreeze| of the corresponding vertex.
+%
+% \DescribeMacro{\fmffixed}
+% |\fmffixed{|\meta{dist}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
+% fixes the distance between subsequent vertices in the list
+% \meta{v1}\ldots{} to \meta{dist}.
+% This command should be used with care, because it is possible to
+% overconstrain the layout of the graph and the error messages will be
+% obscure for a novice user.
+%
+% \DescribeMacro{\fmffixedx}
+% \DescribeMacro{\fmffixedy}
+% |\fmffixedx{|\meta{dx}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
+% is identical to
+% |\fmffixed{(|\meta{dx}|,whatever)}{|\meta{v1}\allowbreak
+% $[$|,|\ldots$]$|}|
+% and |\fmffixedy{|\meta{dy}|}{|\meta{v1}\allowbreak$[$|,|\ldots$]$|}|
+% is identical to
+% |\fmffixed{(whatever,|\meta{dy}|)}{|\meta{v1}\allowbreak
+% $[$|,|\ldots$]$|}|. These commands can be used to fix relative
+% positions in one coordinate, while allowing movement in the other
+% coordinate.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Skeletons}
+% \label{sec:skeletons}
+%
+% The single most powerful concept for adjusting \FMF's layout
+% decisions is the use of \emph{skeletons}. By issuing a
+% |\fmffreeze| after specifying a subgraph (skeleton), we can fix the
+% location of the skeleton \emph{as if} the other arcs were not there.
+% We can then successively add more subgraphs whose layout will be
+% chosen with the skeleton remaining fixed. Similar effects can be
+% achieved by giving some arcs a vanishing |tension|.
+%
+% \begin{examples}{40mm}
+%
+% Consider the following example: suppose we want to draw a ladder
+% diagram contributing to the quark form factor. Simply linking in
+% the gluons does not produce a satisfactory result:
+% \begin{verbatim}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{i1,v4}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \fmf{gluon}{v1,v7}
+% \fmf{gluon}{v2,v6}
+% \fmf{gluon}{v3,v5}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{v4,i1}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \fmf{gluon}{v1,v7}
+% \fmf{gluon}{v2,v6}
+% \fmf{gluon}{v3,v5}
+% \end{fmfgraph}}
+% What went wrong? Obviously the gluons are bonding the quark lines
+% too strongly. The fix is simple: just create a skeleton excluding
+% the gluons
+% \begin{verbatim}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{i1,v4}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \end{verbatim}
+% \marginexample{
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{v4,i1}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \end{fmfgraph}}
+% and add the gluons later:
+% \begin{verbatim}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{i1,v4}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \fmffreeze
+% \fmf{gluon}{v1,v7}
+% \fmf{gluon}{v2,v6}
+% \fmf{gluon}{v3,v5}
+% \end{verbatim}
+% \marginexample{
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{v4,i1}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \fmffreeze
+% \fmf{gluon}{v1,v7}
+% \fmf{gluon}{v2,v6}
+% \fmf{gluon}{v3,v5}
+% \end{fmfgraph}}
+% Alternatively, we can use a vanishing |tension|, which will
+% effectively exclude the gluons from the layout decisions:
+% \begin{verbatim}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{i1,v4}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \fmf{gluon,tension=0}{v1,v7}
+% \fmf{gluon,tension=0}{v2,v6}
+% \fmf{gluon,tension=0}{v3,v5}
+% \end{verbatim}
+% \marginexample{
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{v4,i1}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,v6,v7,o2}
+% \fmf{gluon,tension=0}{v1,v7}
+% \fmf{gluon,tension=0}{v2,v6}
+% \fmf{gluon,tension=0}{v3,v5}
+% \end{fmfgraph}}
+% Which method is more intuitve is largely a matter of taste and at
+% the discretion of the user.
+%
+% The ``crossed'' version of this diagram is best drawn using the
+% |rubout| option:
+% \begin{verbatim}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{i1,v3}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,o2}
+% \fmffreeze
+% \fmf{gluon}{v1,v4}
+% \fmf{gluon,rubout}{v2,v5}
+% \end{verbatim}
+% \marginexample{
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1} \fmfright{o1,o2}
+% \fmf{photon}{i1,v3}
+% \fmf{quark}{o1,v1,v2,v3,v4,v5,o2}
+% \fmffreeze
+% \fmf{gluon}{v1,v4}
+% \fmf{gluon,rubout}{v2,v5}
+% \end{fmfgraph}}
+% If |rubout| is selected, it defaults to~2, but it can be changed to
+% any (reasonable) value~$>1$. The current implementation should work
+% for almost all user-defined line styles. However, it does not work
+% correctly for the predefined |double| line styles yet.
+%
+% Another instructive example is the following: imagine you want to
+% draw a typical non-resonant contribution to~$e^+e^-\to 4f$. The
+% obvious solution doesn't look right:
+% \begin{verbatim}
+% \fmfleft{i1,i2}
+% \fmfright{o1,o2,o3,o4}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{boson}{v1,v2}
+% \fmf{fermion}{o1,v2,v3,o4}
+% \fmf{boson}{v3,v4}
+% \fmf{fermion}{o3,v4,o2}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1,i2}
+% \fmfright{o1,o2,o3,o4}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{boson}{v1,v2}
+% \fmf{fermion}{o1,v2,v3,o4}
+% \fmf{boson}{v3,v4}
+% \fmf{fermion}{o3,v4,o2}
+% \end{fmfgraph}}
+% Again, we should start with a skeleton
+% \begin{verbatim}
+% \fmfleft{i1,i2}
+% \fmfright{o1,o2,o3,o4}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{boson}{v1,v2}
+% \fmf{fermion}{o1,v2,v3,o4}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1,i2}
+% \fmfright{o1,o2,o3,o4}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{boson}{v1,v2}
+% \fmf{fermion}{o1,v2,v3,o4}
+% \end{fmfgraph}}
+% and add the second $W$ later:
+% \begin{verbatim}
+% \fmfleft{i1,i2}
+% \fmfright{o1,o2,o3,o4}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{boson}{v1,v2}
+% \fmf{fermion}{o1,v2,v3,o4}
+% \fmffreeze
+% \fmf{boson}{v3,v4}
+% \fmf{fermion}{o3,v4,o2}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1,i2}
+% \fmfright{o1,o2,o3,o4}
+% \fmf{fermion}{i1,v1,i2}
+% \fmf{boson}{v1,v2}
+% \fmf{fermion}{o1,v2,v3,o4}
+% \fmffreeze
+% \fmf{boson}{v3,v4}
+% \fmf{fermion}{o3,v4,o2}
+% \end{fmfgraph}}
+%
+% Here's another example that uses stretchable arcs. Diagrams
+% of this kind are known as \emph{rainbow} diagrams. If you're using
+% \MP{} and are watching this on a color device, you'll see why.
+% \begin{verbatim}
+% \fmfpen{thick}
+% \fmfleft{i1,d1}
+% \fmfright{o1,d2}
+% \fmfn{plain}{i}{4}
+% \fmf{plain}{i4,v,o4}
+% \fmfn{plain}{o}{4}
+% \fmffreeze
+% \fmf{gluon,left,fore=red}{i1,o1}
+% \fmf{gluon,left,fore=green}{i2,o2}
+% \fmf{gluon,left,fore=blue}{i3,o3}
+% \fmfdotn{i}{3}
+% \fmfdotn{o}{3}
+% \fmfv{d.sh=circle,d.f=empty,d.si=.2w,b=(1,,0,,1),
+% l=$\Sigma$}{v}
+% \end{verbatim}
+% \marginexample{%
+% \label{rainbow}
+% \begin{fmfgraph*}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1,d1}
+% \fmfright{o1,d2}
+% \fmfn{plain}{i}{4}
+% \fmf{plain}{i4,v,o4}
+% \fmfn{plain}{o}{4}
+% \fmffreeze
+% \fmf{gluon,left,fore=red}{i1,o1}
+% \fmf{gluon,left,fore=green}{i2,o2}
+% \fmf{gluon,left,fore=blue}{i3,o3}
+% \fmfdotn{i}{3}
+% \fmfdotn{o}{3}
+% \fmfv{d.sh=circle,d.f=empty,d.si=.2w,b=(1,,0,,1),
+% l=$\Sigma$,l.d=0}{v}
+% \end{fmfgraph*}}
+%
+% \end{examples}
+%
+% Experience has shown that the method advocated in this section is
+% more effective than fuzzing around with fractional |tension|
+% parameters. Using |\fmfshift| or |\fmfforce| should be
+% a last resort only.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Pulling strings}
+% \label{sec:strings}
+%
+% If you add to any arc one or more |phantom| arcs they will cause
+% a tighter bonding between the vertices involved
+% \begin{verbatim}
+% \fmf{fermion}{v1,v2}
+% \fmf{phantom}{v1,v2}
+% \end{verbatim}
+% which is equivalent to
+% \begin{verbatim}
+% \fmf{fermion,tension=2}{v1,v2}
+% \end{verbatim}
+% The |phantom| arc has to be added \emph{before} any |\fmffreeze|
+% involving these vertices, of course.
+%
+% \begin{examples}{40mm}
+%
+% Here is an example from deep inelastic scattering\footnote{%
+% Don't be confused by the \texttt{\bslash fmfi} command. It is
+% described below (see section~\ref{sec:fmfi}) and takes the same
+% arguments as the \texttt{\bslash fmfv} command. We use it here
+% for adding to more lines parallel to the incoming proton line.
+% They do not enter the layout decisions.}:
+% \begin{verbatim}
+% \fmfleft{ip,il}
+% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
+% \fmf{fermion}{ip,vp,vq,oq3}
+% \fmf{fermion}{vp,oq1}
+% \fmf{fermion}{vp,oq2}
+% \fmf{photon}{vl,vq}
+% \fmf{fermion}{il,vl,ol}
+% \fmfblob{.15w}{vp}
+% \fmfdot{vq,vl}
+% \fmffreeze
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{ip,il}
+% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
+% \fmf{fermion}{ip,vp,vq,oq3}
+% \fmf{fermion}{vp,oq1}
+% \fmf{fermion}{vp,oq2}
+% \fmf{photon}{vl,vq}
+% \fmf{fermion}{il,vl,ol}
+% \fmfblob{.15w}{vp}
+% \fmfdot{vq,vl}
+% \fmffreeze
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
+% \end{fmfgraph}}
+% As it stands, all vertices come out too far to the right, because
+% the greater number of outgoing lines pulls them over. Adding
+% |\fmf{phantom}| makes the bond between the incoming vertices and the
+% interactions tighter and produces a better balanced picture:
+% \begin{verbatim}
+% \fmfleft{ip,il}
+% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
+% \fmf{fermion}{ip,vp,vq,oq3}
+% \fmf{phantom}{ip,vp}
+% \fmf{fermion}{vp,oq1}
+% \fmf{fermion}{vp,oq2}
+% \fmf{photon}{vl,vq}
+% \fmf{fermion}{il,vl,ol}
+% \fmf{phantom}{il,vl}
+% \fmfblob{.15w}{vp}
+% \fmfdot{vq,vl}
+% \fmffreeze
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{ip,il}
+% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
+% \fmf{fermion}{ip,vp,vq,oq3}
+% \fmf{phantom}{ip,vp}
+% \fmf{fermion}{vp,oq1}
+% \fmf{fermion}{vp,oq2}
+% \fmf{photon}{vl,vq}
+% \fmf{fermion}{il,vl,ol}
+% \fmf{phantom}{il,vl}
+% \fmfblob{.15w}{vp}
+% \fmfdot{vq,vl}
+% \fmffreeze
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
+% \end{fmfgraph}}
+% Equivalently, we could add |tension| to the lines in question and we
+% will get the same result:
+% \begin{verbatim}
+% \fmfleft{ip,il}
+% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
+% \fmf{fermion,tension=2}{ip,vp}
+% \fmf{fermion}{vp,vq,oq3}
+% \fmf{fermion}{vp,oq1}
+% \fmf{fermion}{vp,oq2}
+% \fmf{photon}{vl,vq}
+% \fmf{fermion,tension=2}{il,vl}
+% \fmf{fermion}{vl,ol}
+% \fmfblob{.15w}{vp}
+% \fmfdot{vq,vl}
+% \fmffreeze
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfleft{ip,il}
+% \fmfright{oq1,oq2,d1,oq3,d2,d3,ol}
+% \fmf{fermion,tension=2}{ip,vp}
+% \fmf{fermion}{vp,vq,oq3}
+% \fmf{fermion}{vp,oq1}
+% \fmf{fermion}{vp,oq2}
+% \fmf{photon}{vl,vq}
+% \fmf{fermion,tension=2}{il,vl}
+% \fmf{fermion}{vl,ol}
+% \fmfblob{.15w}{vp}
+% \fmfdot{vq,vl}
+% \fmffreeze
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(0,2))}
+% \fmfi{plain}{vpath (__ip,__vp) shifted (thick*(1,-2))}
+% \end{fmfgraph}}
+% \end{examples}
+%
+% Conversely, specifing a |tension| $<1$ will make the corresponding
+% arcs more loose.
+%
+% \begin{examples}{40mm}
+%
+% Reconsider the box graph on page~\pageref{pg:box} and reduce the
+% tension on the inner lines\footnote{%
+% Now that you know, I have also displayed the \texttt{label}
+% options used.}
+% \begin{verbatim}
+% \fmfleft{i1,i2}
+% \fmflabel{$\bar{b}$}{i1}
+% \fmflabel{$d$}{i2}
+% \fmfright{o1,o2}
+% \fmflabel{$\bar{d}$}{o1}
+% \fmflabel{$b$}{o2}
+% \fmf{fermion}{i1,v1}
+% \fmf{fermion,tension=.5,label=$\bar{t},,\bar{c},,\bar{u}$,
+% l.side=right}{v1,v3}
+% \fmf{fermion}{v3,o1}
+% \fmf{fermion}{o2,v4}
+% \fmf{fermion,tension=.5,label=$t,,c,,u$,l.side=right}{v4,v2}
+% \fmf{fermion}{v2,i2}
+% \fmf{photon,tension=.2,label=$W^+$,l.side=left}{v1,v2}
+% \fmf{photon,tension=.2,label=$W^-$,l.side=right}{v3,v4}
+% \fmfdotn{v}{4}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,25)
+% \fmfpen{thick}
+% \fmfleft{i1,i2}
+% \fmflabel{$\bar{b}$}{i1}
+% \fmflabel{$d$}{i2}
+% \fmfright{o1,o2}
+% \fmflabel{$\bar{d}$}{o1}
+% \fmflabel{$b$}{o2}
+% \fmf{fermion}{i1,v1}
+% \fmf{fermion,tension=.5,label=$\bar{t},,\bar{c},,\bar{u}$,
+% l.side=right}{v1,v3}
+% \fmf{fermion}{v3,o1}
+% \fmf{fermion}{o2,v4}
+% \fmf{fermion,tension=.5,label=$t,,c,,u$,l.side=right}{v4,v2}
+% \fmf{fermion}{v2,i2}
+% \fmf{photon,tension=.2,label=$W^+$,l.side=left}{v1,v2}
+% \fmf{photon,tension=.2,label=$W^-$,l.side=right}{v3,v4}
+% \fmfdotn{v}{4}
+% \end{fmfgraph*}}
+% \label{pg:newbox}
+% This result is much nicer than the original.
+%
+% \end{examples}
+% \end{fmffile}
+%
+% \begin{fmffile}{fmfsamp4}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Miscellaneous commands}
+%
+% \subsubsection{Graphs in graphs}
+%
+% \DescribeEnv{fmfsubgraph}
+% \label{fmfsubgraph}
+% \manindex{subgraphs}
+% The |fmfsubgraph| environment contains a subgraph, for which the
+% galleries will be placed inside the rectangle of width \meta{width}
+% and height \meta{height}, with lower left corner
+% at~$(\meta{x},\meta{y})$:
+% \begin{quote}
+% \begin{flushleft}
+% |\begin{fmfsubgraph}(|\meta{x}|,|\meta{y}|)(|^^A
+% \meta{width}|,|\meta{height}|)|\\
+% \qquad \meta{body}\\
+% |\end{fmfsubgraph}|
+% \end{flushleft}
+% \end{quote}
+% The center and four corners are available
+% as |c|, |nw|, |ne|, |sw| and |se| (for \emph{north-west} etc).
+% Because of the restrictions on the overall size of the diagram in
+% \MF, this environment will, mainly be useful for preparing
+% transparencies with \MP.
+%
+% \begin{examples}{40mm}
+%
+% Here is a not very serious application of this feature:
+% \begin{verbatim}
+% \def\subgraphsample#1{%
+% \fmfleftn{#1i}{2}%
+% \fmfrightn{#1o}{2}%
+% \fmf{plain}{#1i1,#1v1}%
+% \fmf{plain}{#1o1,#1v2}%
+% \fmf{plain}{#1o2,#1v3}%
+% \fmf{plain}{#1i2,#1v4}%
+% \fmfcyclen{plain,tension=0.3}{#1v}{4}}
+% \begin{fmfgraph}(40,30)
+% \subgraphsample{a}
+% \begin{fmfsubgraph}(.3w,.3h)(.4w,.4h)
+% \subgraphsample{b}
+% \end{fmfsubgraph}
+% \begin{fmfsubgraph}(.45w,.45h)(.1w,.1h)
+% \subgraphsample{c}
+% \end{fmfsubgraph}
+% \end{fmfgraph}
+% \end{verbatim}
+% \marginexample{%
+% \def\subgraphsample#1{%
+% \fmfleftn{#1i}{2}%
+% \fmfrightn{#1o}{2}%
+% \fmf{plain}{#1i1,#1v1}%
+% \fmf{plain}{#1o1,#1v2}%
+% \fmf{plain}{#1o2,#1v3}%
+% \fmf{plain}{#1i2,#1v4}%
+% \fmfcyclen{plain,tension=0.3}{#1v}{4}}
+% \begin{fmfgraph}(40,30)
+% \subgraphsample{a}
+% \begin{fmfsubgraph}(.3w,.3h)(.4w,.4h)
+% \subgraphsample{b}
+% \end{fmfsubgraph}
+% \begin{fmfsubgraph}(.45w,.45h)(.1w,.1h)
+% \subgraphsample{c}
+% \end{fmfsubgraph}
+% \end{fmfgraph}}
+% More serious applications will use this feature to group together
+% related diagrams and use other \MF{} drawing commands for
+% graphical elements that are not available in the \LaTeX{} |picture|
+% environment.
+%
+% \end{examples}
+%
+% \subsubsection{Reusing diagrams}
+%
+% \DescribeMacro{\fmfkeep}
+% \DescribeMacro{\fmfreuse}
+% After saving a pointer with |\fmfkeep{|\meta{name}|}| inside a
+% |fmfgraph| or |fmfgraph*| environment, the diagram can be reused later
+% by |\fmfreuse{|\meta{name}|}|. This works across |fmffile|
+% environments.
+%
+% Here's an example that uses centered |\parbox|es to place
+% diagrams into equations. The celebrated cancelation of quadratic
+% divergencies in scalar selfenergies in supersymmetric field theories
+% can be written as:
+% \begin{verbatim}
+% \begin{eqnarray}
+% \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{boson}
+% \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v,v,o}
+% \end{fmfgraph}} & \propto & \Lambda^2 \\
+% \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{fermion}
+% \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v1} \fmf{dashes}{v2,o}
+% \fmf{fermion,left,tension=.3}{v1,v2,v1}
+% \end{fmfgraph}} & \propto & \Lambda^2 \\
+% \parbox{20mm}{\fmfreuse{boson}} \quad + \quad
+% \parbox{20mm}{\fmfreuse{fermion}} & \propto & \ln\Lambda^2
+% \end{eqnarray}
+% \end{verbatim}
+% The result is:
+% \begin{eqnarray}
+% \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{boson}
+% \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v,v,o}
+% \end{fmfgraph}} & \propto & \Lambda^2 \\
+% \parbox{20mm}{\begin{fmfgraph}(20,15)\fmfkeep{fermion}
+% \fmfleft{i} \fmfright{o} \fmf{dashes}{i,v1} \fmf{dashes}{v2,o}
+% \fmf{fermion,left,tension=.3}{v1,v2,v1}
+% \end{fmfgraph}} & \propto & \Lambda^2 \\
+% \parbox{20mm}{\fmfreuse{boson}} \quad + \quad
+% \parbox{20mm}{\fmfreuse{fermion}} & \propto & \ln\Lambda^2
+% \end{eqnarray}
+%
+% \subsubsection{Grouping}
+%
+% \DescribeEnv{fmfgroup}
+% Make the enclosed |\fmfset| assignments local to this environment.
+%
+% \subsubsection{Changing parameters}
+%
+% \DescribeMacro{\fmfset}
+% \manindex{parameters}
+% This command can be used to change the parameters in
+% table~\ref{tab:parameters} as follows:
+% \begin{quote}
+% |\fmfset{|\meta{parameter}|}{|\meta{value}|}|
+% \end{quote}
+% Note that these parameters are not stored in the graph data
+% structure for the individual vertices and arcs. Instead the current
+% values at the time of |\fmfdraw| are used.
+%
+% \DeleteShortVerb{\|}
+% \MakeShortVerb{\"}
+%
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|c|c|}\hline
+% Parameter & Default & Semantics \\\hline\hline
+% "thin" & 1pt & thin arcs \\\hline
+% "thick" & 1.5"thin" & thicker arcs \\\hline
+% "arrow_len" & 4mm & length of arrow head \\\hline
+% "arrow_ang" & 15 & opening angle of arrow head \\\hline
+% "curly_len" & 3mm & length of one curl \\\hline
+% "dash_len" & 3mm & length of one dash \\\hline
+% "dot_len" & 2mm & distance of two dots \\\hline
+% "wiggly_len" & 4mm & length of one wiggle \\\hline
+% "wiggly_slope" & 60 & inclination of wiggles \\\hline
+% "zigzag_len" & 2mm & length of a zig-zag period \\\hline
+% "zigzag_width" & 2"thick" & width of zig-zag lines \\\hline
+% "decor_size" & 5mm & default size of vertex decors \\\hline
+% "dot_size" & 4"thick" & diameter of dots \\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Available style parameters.}
+% \label{tab:parameters}
+% \end{table}
+%
+% \DeleteShortVerb{\"}
+% \MakeShortVerb{\|}
+%
+% \subsubsection{Shrinking}
+%
+% \DescribeEnv{fmfshrink}
+% Shrink the linewidths and similar parameters in the enclosed section.
+%
+% \subsubsection{Debugging}
+%
+% \DescribeMacro{\fmftrace}
+% \DescribeMacro{\fmfnotrace}
+% \manindex{tracing}
+% Enable and disable tracing of the layout decisions. This is not
+% necessarily printed in an intuitive format, but can be helpful for
+% debugging.
+%
+% \DescribeMacro{\fmfdisplay}
+% \DescribeMacro{\fmfstopdisplay}
+% \manindex{displays, online}
+% \manindex{online displays}
+% Enable online displays. |\fmfstopdisplay| will halt \MF{} everytime
+% a graph is complete.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Multiple vertices and arcs}
+%
+% \DescribeEnv{fmffor}
+% \manindex{looping}
+% The environment
+% \begin{quote}
+% \begin{flushleft}
+% |\begin{fmffor}{|\meta{var}|}{|\meta{from}|}{|\meta{step}|}{|\meta{to}|}|\\
+% \qquad \meta{body}\\
+% |\end{fmffor}|
+% \end{flushleft}
+% \end{quote}
+% executes \meta{body} multiple times, setting \meta{var} to
+% $\meta{from}, \meta{from}+\meta{step}, \ldots, \meta{to}$.
+% An application of this above \FMF{} feature is shown in
+% figure~\ref{fig:euler-heisenberg}, which is generated by calling
+% the \TeX{} macro
+% \begin{verbatim}
+% \def\EulerHeisenberg#1{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfsurroundn{e}{#1}
+% \begin{fmffor}{n}{1}{1}{#1}
+% \fmf{photon}{e[n],i[n]}
+% \end{fmffor}
+% \fmfcyclen{fermion,tension=#1/8}{i}{#1}
+% \end{fmfgraph}}
+% \end{verbatim}
+% with the arguments 4, 6, 8, and 10, respectively.
+% \def\EulerHeisenberg#1{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}
+% \fmfsurroundn{e}{#1}
+% \begin{fmffor}{n}{1}{1}{#1}
+% \fmf{photon}{e[n],i[n]}
+% \end{fmffor}
+% \fmfcyclen{fermion,tension=#1/8}{i}{#1}
+% \end{fmfgraph}}
+% \begin{figure}[t]
+% \begin{center}
+% \EulerHeisenberg{4} \qquad \EulerHeisenberg{6}
+% \end{center}
+% \begin{center}
+% \EulerHeisenberg{8} \qquad \EulerHeisenberg{10}
+% \end{center}
+% \caption{Higher order terms in the Euler-Heisenberg lagrangian.}
+% \label{fig:euler-heisenberg}
+% \end{figure}
+%
+% Similarly, we can draw the diagrams from many particle physics in
+% figures~\ref{fig:PP-rings} and~\ref{fig:PH-rings}:
+% \begin{verbatim}
+% \def\PPRing#1{%
+% \begin{fmfgraph}(20,20)
+% \fmfsurroundn{v}{#1}
+% \fmfdotn{v}{#1}
+% \fmfcyclen{fermion,right=0.25}{v}{#1}
+% \fmfcyclen{fermion,left=0.25}{v}{#1}
+% \end{fmfgraph}}
+% \def\PHRing#1{%
+% \begin{fmfgraph}(20,20)
+% \fmfsurroundn{v}{#1}
+% \fmfdotn{v}{#1}
+% \fmfcyclen{fermion,right=0.25}{v}{#1}
+% \fmfrcyclen{fermion,right=0.25}{v}{#1}
+% \end{fmfgraph}}
+% \end{verbatim}
+% \def\PPRing#1{%
+% \begin{fmfgraph}(20,20)
+% \fmfsurroundn{v}{#1}
+% \fmfdotn{v}{#1}
+% \fmfcyclen{fermion,right=0.25}{v}{#1}
+% \fmfcyclen{fermion,left=0.25}{v}{#1}
+% \end{fmfgraph}}
+% \def\PHRing#1{%
+% \begin{fmfgraph}(20,20)
+% \fmfsurroundn{v}{#1}
+% \fmfdotn{v}{#1}
+% \fmfcyclen{fermion,right=0.25}{v}{#1}
+% \fmfrcyclen{fermion,right=0.25}{v}{#1}
+% \end{fmfgraph}}
+% \begin{figure}[t]
+% \begin{center}
+% \PPRing{3}\qquad\PPRing{4}\qquad\PPRing{5}\qquad\PPRing{6}
+% \end{center}
+% \caption{\label{fig:PP-rings}Particle-particle ring diagrams}
+% \end{figure}
+% \begin{figure}[t]
+% \begin{center}
+% \PHRing{3}\qquad\PHRing{4}\qquad\PHRing{5}\qquad\PHRing{6}
+% \end{center}
+% \caption{\label{fig:PH-rings}Particle-hole ring diagrams}
+% \end{figure}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Immediate mode}
+% \label{sec:immediate}
+%
+% In addition to the automatic layout of vertices, \FMF{} features an
+% immediate mode, in which \FMF's drawing commands operate directly on
+% \MF's |pair|s and |path|s. You might want to consult The \MF{}
+% Book~\cite{MF} or the \MP{} manual~\cite{MetaPost} for further
+% information on the available |path| expressions.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Arcs}
+% \label{sec:fmfi}
+%
+% \DescribeMacro{\fmfi}
+% \manindex{arcs}
+% Immediate mode's brother of |\fmf|.
+% \begin{quote}
+% |\fmfi{|\meta{style}$[$|,|\meta{opt}$[$|=|\meta{val}$]$|,|\ldots$]$^^A
+% |}{|\meta{p}|}|
+% \end{quote}
+% draws a line of
+% style \meta{style} on path \meta{p}. Use the |vpath| function in
+% \meta{p} (\emph{after} |\fmffreeze|!) to access the \MF{} |path|
+% connecting two vertices:
+% |vpath|$[$\meta{tag}$]$|(|\meta{from}|,|\meta{to}|)|. The optional
+% numeric \meta{tag} can be used together with a matching |tag| option
+% to |\fmf| to disambiguate arcs that connect the same vertices.
+% You have to prepend each name of a vertex in |vpath|'s arguments
+% with two underscores (e.g.~|v1| becomes |__v1|). This is necessary
+% for avoiding nameclashes with some reserved words in \MF{}
+% (\textit{sparks} in DEK's terminology).
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Vertices}
+% \label{sec:fmfiv}
+%
+% \DescribeMacro{\fmfiv}
+% \manindex{vertices}
+% Immediate mode's brother of |\fmfv|.
+% \begin{quote}
+% |\fmfiv{|\meta{shape}$[$|=|\meta{val}$][$|,|\meta{opt}^^A
+% $[$|=|\meta{val}$]$|,|\ldots$]$|}{|\meta{v}|}|
+% \end{quote}
+% draws a vertex at position \meta{v}. Note that here \meta{v} is a
+% \MF{} |pair| and \emph{not} a \FMF{} vertex name. The former's
+% equivalent of the latter can be accessed (\emph{after}
+% |\fmffreeze|!) with the |vloc| function: |vloc(|\meta{vertex}|)|.
+% Again, you have to prepend the name of the vertex in |vloc|'s
+% argument with two underscores (e.g.~|v1| becomes |__v1|).
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Declarations}
+%
+% \DescribeMacro{\fmfipath}
+% The argument(s) are declared \MF{} |path|s.
+%
+% \DescribeMacro{\fmfipair}
+% The argument(s) are declared \MF{} |pair|s (coordinates).
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Assignments}
+%
+% \DescribeMacro{\fmfiequ}
+% Establish equality for the two arguments,
+% i.e.~|\fmfiequ{lval}{rval}| translates to |lval=rval|.
+%
+% \DescribeMacro{\fmfiset}
+% Assign the second argument to the first,
+% i.e.~|\fmfiset{lval}{rval}| translates to |lval:=rval|.
+%
+% Specifying equality of two variables is a very different operation
+% from assignment in \MF{}. See The \MF{} Book~\cite{MF} for details
+% on \MF's builtin equation solver.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Examples}
+%
+% Here is a non-trivial example of immediate mode, which shows some
+% useful tricks. The non-trivial aspect of the diagram in question is
+% that it has lines broken in two, denoting particles coupling to a
+% condensate.
+%
+% \begin{examples}{40mm}
+%
+% We start the diagram with a skeleton (the |phantom| lines are shown
+% as thin lines for clarity):
+% \begin{verbatim}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{dots}{i,v1}
+% \fmf{dots}{v2,o}
+% \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
+% \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
+% \fmfdot{v1,v2}
+% \fmfposition
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,30)
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{dots}{i,v1}
+% \fmf{dots}{v2,o}
+% \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
+% \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
+% \fmfposition
+% \fmfdraw
+% \fmfpen{.5thin}
+% \fmf{plain,left}{v1,v2}
+% \fmf{plain,left}{v2,v1}
+% \end{fmfgraph}}
+% Add the fermions to the skeleton
+% \begin{verbatim}
+% \fmfipath{p[]}
+% \fmfiset{p1}{vpath1(__v1,__v2)}
+% \fmfiset{p2}{vpath2(__v2,__v1)}
+% \fmfi{fermion}{subpath (0,length(p1)/3) of p1}
+% \fmfi{fermion}{subpath (2length(p1)/3,length(p1)) of p1}
+% \fmfi{fermion}{subpath (0,length(p2)/3) of p2}
+% \fmfi{fermion}{subpath (2length(p2)/3,length(p2)) of p2}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,30)
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{dots}{i,v1}
+% \fmf{dots}{v2,o}
+% \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
+% \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
+% \fmfdot{v1,v2}
+% \fmfposition
+% \fmfipath{p[]}
+% \fmfiset{p1}{vpath1(__v1,__v2)}
+% \fmfiset{p2}{vpath2(__v2,__v1)}
+% \fmfi{fermion}{subpath (0,length(p1)/3) of p1}
+% \fmfi{fermion}{subpath (2length(p1)/3,length(p1)) of p1}
+% \fmfi{fermion}{subpath (0,length(p2)/3) of p2}
+% \fmfi{fermion}{subpath (2length(p2)/3,length(p2)) of p2}
+% \end{fmfgraph}}
+% Add condensates and a gluon
+% \begin{verbatim}
+% \def\cond#1#2{%
+% \fmfiv{d.sh=cross,d.ang=#1,d.siz=5thick}{#2}}
+% \cond{30}{point length(p1)/3 of p1}
+% \cond{-30}{point 2length(p1)/3 of p1}
+% \cond{30}{point length(p2)/3 of p2}
+% \cond{-30}{point 2length(p2)/3 of p2}
+% \fmfi{gluon}{point length(p1)/10 of p1
+% -- point 11length(p1)/12 of p1}
+% \def\vert#1{%
+% \fmfiv{d.sh=circle,d.f=1,d.siz=2thick}{#1}}
+% \vert{point length(p1)/12 of p1}
+% \vert{point 11length(p1)/12 of p1}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,30)
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{dots}{i,v1}
+% \fmf{dots}{v2,o}
+% \fmf{phantom,left,tension=0.2,tag=1}{v1,v2}
+% \fmf{phantom,left,tension=0.2,tag=2}{v2,v1}
+% \fmfdot{v1,v2}
+% \fmfposition
+% \fmfipath{p[]}
+% \fmfiset{p1}{vpath1(__v1,__v2)}
+% \fmfiset{p2}{vpath2(__v2,__v1)}
+% \fmfi{fermion}{subpath (0,length(p1)/3) of p1}
+% \fmfi{fermion}{subpath (2length(p1)/3,length(p1)) of p1}
+% \fmfi{fermion}{subpath (0,length(p2)/3) of p2}
+% \fmfi{fermion}{subpath (2length(p2)/3,length(p2)) of p2}
+% \def\cond#1#2{\fmfiv{d.sh=cross,d.ang=#1,d.siz=5thick}{#2}}
+% \cond{30}{point length(p1)/3 of p1}
+% \cond{-30}{point 2length(p1)/3 of p1}
+% \cond{30}{point length(p2)/3 of p2}
+% \cond{-30}{point 2length(p2)/3 of p2}
+% \fmfi{gluon}{point length(p1)/10 of p1 -- point 11length(p1)/12 of p1}
+% \def\vert#1{\fmfiv{d.sh=circle,d.f=1,d.siz=2thick}{#1}}
+% \vert{point length(p1)/12 of p1}
+% \vert{point 11length(p1)/12 of p1}
+% \end{fmfgraph}}
+%
+% Here's an interesting abuse of \FMF{} (see the next section for
+% |\fmfcmd|):
+% \begin{verbatim}
+% \begin{fmfgraph*}(40,40)
+% \fmfipair{o,xm,xp,ym,yp}
+% \fmfiequ{o}{(.5w,.1h)}
+% \fmfiequ{xm}{(0,.1h)}
+% \fmfiequ{xp}{(w,.1h)}
+% \fmfiequ{ym}{(.5w,0)}
+% \fmfiequ{yp}{(.5w,h)}
+% \fmfiv{l=$x$,l.a=-135,l.d=2mm}{xp}
+% \fmfiv{l=$y=x^2$,l.a=-135,l.d=2mm}{yp}
+% \fmfpen{thin}
+% \fmfcmd{draw xm--xp; draw ym--yp;}
+% \fmfpen{thick}
+% \fmfiequ{xs}{xpart(xp-o)}
+% \fmfiequ{ys}{ypart(yp-o)}
+% \fmfcmd{draw (o + (-xs,ys)) for n = -9 upto 10:
+% --(o + (xs*(n/10),ys*((n/10)**2)))
+% endfor;}
+% \end{fmfgraph*}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph*}(40,40)
+% \fmfipair{o,xm,xp,ym,yp}
+% \fmfiequ{o}{(.5w,.1h)}
+% \fmfiequ{xm}{(0,.1h)}
+% \fmfiequ{xp}{(w,.1h)}
+% \fmfiequ{ym}{(.5w,0)}
+% \fmfiequ{yp}{(.5w,h)}
+% \fmfiv{l=$x$,l.a=-135,l.d=2mm}{xp}
+% \fmfiv{l=$y=x^2$,l.a=-135,l.d=2mm}{yp}
+% \fmfpen{thin}
+% \fmfcmd{draw xm--xp; draw ym--yp;}
+% \fmfpen{thick}
+% \fmfiequ{xs}{xpart(xp-o)}
+% \fmfiequ{ys}{ypart(yp-o)}
+% \fmfcmd{draw (o + (-xs,ys)) for n = -9 upto 10:
+% --(o + (xs*(n/10),ys*((n/10)**2)))
+% endfor;}
+% \end{fmfgraph*}}
+%
+% \end{examples}
+%
+% Finally, for the curious, here is how to draw the circular gluons in
+% figure~\ref{fig:gluons}:
+% \begin{verbatim}
+% \fmfi{gluon}{fullcircle scaled .5w shifted (.5w,.5h)}
+% \fmfi{gluon}{reverse fullcircle scaled .5w shifted (.5w,.5h)}
+% \end{verbatim}
+%
+% \begin{figure}[t]
+% \begin{center}
+% \begin{fmfgraph}(40,40)
+% \fmfi{gluon}{fullcircle scaled .5w shifted (.5w,.5h)}
+% \end{fmfgraph}
+% \qquad
+% \begin{fmfgraph}(40,40)
+% \fmfi{gluon}{reverse fullcircle scaled .5w shifted (.5w,.5h)}
+% \end{fmfgraph}
+% \end{center}
+% \caption{Circular gluons.}
+% \label{fig:gluons}
+% \end{figure}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Raw \MF}
+%
+% Some more advanced features of \FMF{} are more conveniently
+% accessed through raw \MF{} commands. This can either be
+% achieved by preparing a \MF{} input file or by using |\fmfcmd|
+% extensively. The latter apprach is usally more convenient.
+%
+% \DescribeMacro{\fmfcmd}
+% The |\fmfcmd| macro writes its argument into the \MF{} input
+% file generated by \FMF. While some experience in using
+% \MF{} doesn't hurt here, this approach can simplify the
+% production of complex diagrams considerably. Note that \emph{no}
+% semicolon is appended, the user has to provide it explicitely.
+%
+% \subsubsection{Extending \FMF}
+% \label{sec:extensions}
+%
+% \manindex{extensions}
+% \manindex{defining new styles}
+% \manindex{styles, defining new}
+% A prominent example for using raw \MF{} is provided by the option to
+% add new styles for arcs. There is of course always one more style
+% that \emph{must} be added to the default list. But increasing this
+% list without bounds will eventually slow down \FMF{} and increase
+% its memory requirements. It is therefore better to allow users to
+% define their own styles. This is done with the \MF{} macro
+% |style_def|, which defines a macro that will be called to do the
+% drawing and registers this macro with \FMF{} so that it can be used
+% in the first argument to |\fmf|.
+%
+% The macro takes one argument of type |path| and is responsible for
+% drawing the arc on this path. If \MP's color functionality is to be
+% used, the color aware functions |cdraw|, |cfill|, |cfilldraw|,
+% |ccutdraw| and |cdrawdot| should be used instead of |draw|, etc.
+%
+% \begin{examples}{40mm}
+%
+% \manindex{crossed arcs}
+% After the following |style_def|, a new style |crossed| will be
+% available:
+% \begin{verbatim}
+% \fmfcmd{%
+% vardef cross_bar (expr p, len, ang) =
+% ((-len/2,0)--(len/2,0))
+% rotated (ang + angle direction length(p)/2 of p)
+% shifted point length(p)/2 of p
+% enddef;
+% style_def crossed expr p =
+% cdraw p;
+% ccutdraw cross_bar (p, 5mm, 45);
+% ccutdraw cross_bar (p, 5mm, -45)
+% enddef;}
+% \end{verbatim}
+% \fmfcmd{%
+% vardef cross_bar (expr p, len, ang) =
+% ((-len/2,0)--(len/2,0))
+% rotated (ang + angle direction length(p)/2 of p)
+% shifted point length(p)/2 of p
+% enddef;
+% style_def crossed expr p =
+% cdraw p;
+% ccutdraw cross_bar (p, 5mm, 45);
+% ccutdraw cross_bar (p, 5mm, -45)
+% enddef;}
+% it can be used just like any other style:
+% \begin{verbatim}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{plain}{i,v,o}
+% \fmf{crossed}{v,v}
+% \fmfdot{v}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,30)
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{plain}{i,v,o}
+% \fmf{crossed}{v,v}
+% \fmfdot{v}
+% \end{fmfgraph}}
+% And here is an (esthetically questionable!) attempt at wiggly lines
+% with arrows:
+% \begin{verbatim}
+% \fmfcmd{%
+% style_def wiggly_arrow expr p =
+% cdraw (wiggly p);
+% shrink (2);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% \end{verbatim}
+% \fmfcmd{%
+% style_def wiggly_arrow expr p =
+% cdraw (wiggly p);
+% shrink (2);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% \marginexample{%
+% \begin{fmfgraph}(40,10)
+% \fmfpen{thick}
+% \fmfleft{i}
+% \fmfright{o}
+% \fmf{wiggly_arrow}{i,o}
+% \end{fmfgraph}}
+% Note how the |shrink| macro (which is the \MF{} equivalent of the
+% |fmfshrink| environment) is used to temporarily double the
+% dimensions of the arrowhead which is constructed by the |arrow|
+% macro.
+%
+% In particular theorists beyond the standard model are likely to need
+% \emph{a lot} of different line styles. The aficionados of majorana
+% neutrinos might find the following two useful:
+% \begin{verbatim}
+% \fmfcmd{%
+% style_def majorana expr p =
+% cdraw p;
+% cfill (harrow (reverse p, .5));
+% cfill (harrow (p, .5))
+% enddef;
+% style_def alt_majorana expr p =
+% cdraw p;
+% cfill (tarrow (reverse p, .55));
+% cfill (tarrow (p, .55))
+% enddef;}
+% \end{verbatim}
+% \fmfcmd{%
+% style_def majorana expr p =
+% cdraw p;
+% cfill (harrow (reverse p, .5));
+% cfill (harrow (p, .5))
+% enddef;
+% style_def alt_majorana expr p =
+% cdraw p;
+% cfill (tarrow (reverse p, .55));
+% cfill (tarrow (p, .55))
+% enddef;}
+% \marginexample{%
+% \begin{fmfgraph}(40,30)
+% \fmfpen{thick}
+% \fmfleftn{i}{2} \fmfrightn{o}{2}
+% \fmf{majorana}{i1,v1,o1}
+% \fmf{alt_majorana}{i2,v2,o2}
+% \fmfn{boson}{v}{2}
+% \fmfdotn{v}{2}
+% \end{fmfgraph}}
+% Note the use of the |harrow| and |tarrow| functions which return an
+% arrowhead on the given fraction of the path, with reference points
+% at the head (|harrow|) or tail (|tarrow|). The |arrow| function
+% used above is equivalent to |marrow(p,.5)|, which has the reference
+% point at the center of the arrowhead. Having the three different
+% reference point available is important for supporting arcs of
+% substantially differing lengths.
+%
+% A problem of the current implementation is that the endpoints of
+% double lines don't match smoothly at vertices:
+% \begin{verbatim}
+% \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfpolyn{shaded}{z}{4}
+% \fmf{dbl_plain_arrow}{l2,z3}
+% \fmf{dbl_plain_arrow}{l1,z4}
+% \fmf{dbl_plain_arrow}{z1,r1}
+% \fmf{dbl_plain_arrow}{z2,r2}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfpolyn{shaded}{z}{4}
+% \fmf{dbl_plain_arrow}{l2,z3}
+% \fmf{dbl_plain_arrow}{l1,z4}
+% \fmf{dbl_plain_arrow}{z1,r1}
+% \fmf{dbl_plain_arrow}{z2,r2}
+% \end{fmfgraph}}
+% One way around is to add dots of the right size at the vertices
+% \emph{after} the arcs have been drawn.
+% \begin{verbatim}
+% \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfpolyn{shaded}{z}{4}
+% \fmf{dbl_plain_arrow}{l2,z3}
+% \fmf{dbl_plain_arrow}{l1,z4}
+% \fmf{dbl_plain_arrow}{z1,r1}
+% \fmf{dbl_plain_arrow}{z2,r2}
+% \fmffreeze\fmfdraw
+% \fmfvn{d.siz=2thick,d.sh=circle}{z}{4}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(40,25)
+% \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfpolyn{shaded}{z}{4}
+% \fmf{dbl_plain_arrow}{l2,z3}
+% \fmf{dbl_plain_arrow}{l1,z4}
+% \fmf{dbl_plain_arrow}{z1,r1}
+% \fmf{dbl_plain_arrow}{z2,r2}
+% \fmffreeze\fmfdraw
+% \fmfvn{d.siz=2thick,d.sh=circle}{z}{4}
+% \end{fmfgraph}}
+% Without the |\fmffreeze\fmfdraw|, the arcs would ``know'' about the
+% dots and would be shortened.
+%
+% A more elegant solution is to define line styles with dots at the
+% head,
+% \begin{verbatim}
+% \fmfcmd{vardef endpoint_dot expr p =
+% save oldpen; pen oldpen;
+% oldpen := currentpen;
+% pickup oldpen scaled 3;
+% cdrawdot p;
+% pickup oldpen;
+% enddef;}
+% \fmfcmd{style_def hd_double expr p =
+% draw_double p;
+% endpoint_dot point infinity of p;
+% enddef;}
+% \fmfcmd{style_def hd_dbl_plain_arrow expr p =
+% draw_hd_double p;
+% shrink (1.5);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% \end{verbatim}
+% \fmfcmd{%
+% vardef endpoint_dot expr p =
+% save oldpen; pen oldpen;
+% oldpen := currentpen;
+% pickup oldpen scaled 3;
+% cdrawdot p;
+% pickup oldpen;
+% enddef;}
+% \fmfcmd{%
+% style_def hd_double expr p =
+% draw_double p;
+% endpoint_dot point infinity of p;
+% enddef;}
+% \fmfcmd{%
+% style_def hd_dbl_plain_arrow expr p =
+% draw_hd_double p;
+% shrink (1.5);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% tail
+% \begin{verbatim}
+% \fmfcmd{style_def td_double expr p =
+% draw_double p;
+% endpoint_dot point 0 of p;
+% enddef;}
+% \fmfcmd{style_def td_dbl_plain_arrow expr p =
+% draw_td_double p;
+% shrink (1.5);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% \end{verbatim}
+% \fmfcmd{%
+% style_def td_double expr p =
+% draw_double p;
+% endpoint_dot point 0 of p;
+% enddef;}
+% \fmfcmd{%
+% style_def td_dbl_plain_arrow expr p =
+% draw_td_double p;
+% shrink (1.5);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% or both
+% \begin{verbatim}
+% \fmfcmd{style_def htd_double expr p =
+% draw_double p;
+% endpoint_dot point 0 of p;
+% endpoint_dot point infinity of p;
+% enddef;}
+% \fmfcmd{style_def htd_dbl_plain_arrow expr p =
+% draw_htd_double p;
+% shrink (1.5);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% \end{verbatim}
+% \fmfcmd{%
+% style_def htd_double expr p =
+% draw_double p;
+% endpoint_dot point 0 of p;
+% endpoint_dot point infinity of p;
+% enddef;}
+% \fmfcmd{%
+% style_def htd_dbl_plain_arrow expr p =
+% draw_htd_double p;
+% shrink (1.5);
+% cfill (arrow p);
+% endshrink;
+% enddef;}
+% which can be used as follows to give an equivalent result:
+% \begin{verbatim}
+% \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfpolyn{shaded}{z}{4}
+% \fmf{hd_dbl_plain_arrow}{l2,z3}
+% \fmf{hd_dbl_plain_arrow}{l1,z4}
+% \fmf{td_dbl_plain_arrow}{z1,r1}
+% \fmf{td_dbl_plain_arrow}{z2,r2}
+% \end{verbatim}
+% \marginexample{%
+% \begin{fmfgraph}(50,30)
+% \fmfpen{thick}\fmfleftn{l}{2}\fmfrightn{r}{2}
+% \fmfpolyn{shaded}{z}{4}
+% \fmf{hd_dbl_plain_arrow}{l2,z3}
+% \fmf{hd_dbl_plain_arrow}{l1,z4}
+% \fmf{td_dbl_plain_arrow}{z1,r1}
+% \fmf{td_dbl_plain_arrow}{z2,r2}
+% \end{fmfgraph}}
+%
+% \end{examples}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Common traps, trouble shooting and frequently asked
+% questions (FAQs)}
+%
+% \subsubsection{\texttt{! Value is too large}}
+% \label{sec:value-to-large}
+% The following will be one of the most frequent errors:
+% \begin{verbatim}
+% ! Value is too large (4097).
+% <recently read> ;
+%
+% beginchar->...rdp:=(EXPR3);w:=hround(charwd*hppp);
+% h:=...
+% l.685 ...char(64, 40*2.84526pt#, 25*2.84526pt#, 0)
+% ;
+% ?
+% \end{verbatim}
+% It can have one of two causes:
+% \begin{itemize}
+% \item{} \MF{} was invoked without specifying the |mode|.
+% This case is easily fixed by looking up the correct \MF{} mode
+% in the file |modes.mf| that comes with the \MF{} distribution.
+% This mode \emph{must} be specified on the
+% command line as |\mode:=laserjet| for HP Laserjets at 300dpi, as
+% |\mode:=ljfour| for HP Laserjets at 600dpi, as
+% |\mode:=nexthi| for NeXT laser printers at 400dpi, etc,
+% just to name three of the more common laser printers in the
+% physics community.
+% \item{} The diagrams are too large for the printer at hand.
+% This case is actually not very likely, because even at 1200dpi
+% the diagrams can be as large as 86mm. For the popular
+% laserprinter resolution of 300dpi, even 346mm are possible.
+% Last time I checked, the diagrams for this manual could be
+% generated for a \textit{Linotype Linotronic 300} at 2540dpi
+% (|mode:=linosuper|), but failed in the standard |proof| mode at
+% 2601.72dpi.\footnote{%
+% It would be trivial to shrink the diagrams by 1\%\ to make
+% them work in \texttt{proof} mode (accidentally, the largest
+% diagram is 40mm wide, while 4096/2601.72dpi corresponds to
+% 39.99mm). However, I prefer \MF{} to give an error message if
+% the user forgot to specify the mode. It is much more obscure
+% when \MF{} works without errors but the \texttt{dvi} driver
+% fails to find the generated bitmap file.}
+% In fact, in the current |modes.mf| file, the
+% \textit{Chelgraph IBX} at 9600dpi and the \textit{Alphatype CRS}
+% at $5333+1/3$dpi are the only typesetters that can not be used
+% to typeset this manual.\footnote{%
+% If someone wants to use \FMF{} with one of these high end
+% typesetters, I would be glad to try to help them out with
+% kludges.}
+% \end{itemize}
+%
+% \subsubsection{Diagrams in the document are never updated}
+% \label{sec:out-of-date}
+% There are two known reasons why diagrams may not be updated the
+% document after the source file has been changed:
+% \begin{itemize}
+% \item Some |dvi| file previewers (e.g.~|xdvi(1)| under UNIX) do
+% \emph{not} reread font information if the |tfm| or |pk| files
+% have changed, even though they reread the |dvi| file if it has
+% changed. Therefore you have to restart such previewers if you
+% have made changes in diagrams to see these changes on the screen.
+% \item Some |dvi| drivers (e.g.~|dvips(1)| under UNIX) do not work
+% with the |gf| files directly, but convert them with an external
+% program to |pk| format first. On later occasions, the |dvi|
+% driver will then use the |pk| file which is out of date with
+% respect to the sources and the |gf| file. The only known fix is
+% to delete the |pk| fils before running the |dvi| driver.
+% \end{itemize}
+%
+% \subsubsection{Disgrams show up in the wrong spot}
+% If you are using \FMF{} with \LaTeX's |\includeonly| feature, you
+% should watch out for the following situation:
+% \begin{verbatim}
+% \includeonly{bar1,bar3}
+% \begin{fmffile}{foograph}
+% \include{bar1}
+% \include{bar2}
+% \include{bar3}
+% \end{fmffile}
+% \end{verbatim}
+% where |bar1.tex| defines graph \#1, |bar2.tex| graph \#2 and
+% |bar3.tex| defines graph \#3. If you now proceeded to add graphs to
+% |bar1.tex|, you will notice that a second graph is accepted, but
+% instead of the new third graph, the old graph \#3 appears. What
+% happens is that \LaTeX{} stores the value of the counter for
+% |fmfgraph|s in each |.aux| file so that because |bar2.tex| is not
+% processed, this counter is always reset to 3 at the beginning of
+% |bar3.tex|.
+%
+% Even though this situation appears to be contrived, it actually
+% occured in real life applications and the resulting error is very
+% confusing.
+%
+% The only ``fix'' for this problem would be to use a private counter
+% behind \LaTeX's back. Unfortunately, it appears that this will
+% violate the \emph{principle of minimal surprise} even more. It is
+% therefore usually a good idea to reprocess the complete document
+% when the number of graphs has changed in an |\include|d file. The
+% other solution is to have a separate |fmfgraph| environment for each
+% |\include|d file.
+%
+% \subsubsection{Spurious labels show up}
+% If spurious labels show up in your diagrams, this is most likely
+% caused by old label files (e.g.~|foo.t|\meta{n}) still lying
+% around. Just delete these files and rerun \TeX{} and \MF{} (or
+% \MP{} respectively).
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Known bugs}
+%
+% \subsubsection{Chaotic manual}
+% This is being worked on. It should probably be rewritten from
+% scratch, but I don't have enough time at the moment (this is a spare
+% time activity).
+%
+% \subsubsection{Delayed error messages}
+% This can't be fixed. The problem is that errors can manifest
+% themselves only a long time after the corresponding source line has
+% been read. Since \TeX{} doesn't allow to access the current source
+% line number, there is no way to store this information along with
+% the other information on the graph.
+% I can only hope to have enough sanity checks in
+% place some day that error messages from \MF{} won't occur.
+%
+% \subsubsection{Multiple tadpoles}
+% Currently, \FMF{} will not layout multiple tadpoles at a single
+% vertex automatically. This could be fixed in principle, but these
+% fixes would cause other problems which are more inconvenient than
+% having to lay out tadpoles manually.
+%
+% \subsubsection{Hard limits}
+% Currently the most severe limitation lies in the size of the
+% generated pictures. The largest number \MF{} can represent
+% internally is~4095.99998 and this is also the largest value any
+% coordinate measured in pixels can assume. At the most popular
+% laserprinter resolution of~300 dots per inch (dpi), this corresponds
+% to a horizontal and vertical extension of about~346mm, which is
+% plenty and we're more likely to hit the internal limits on the
+% complexity of a picture. However, at the proof mode resolution
+% of~2601.72dpi, this is reduced to slightly less than~40mm and we're
+% running the risk of arithmetic overflow in internal calculations much
+% earlier.
+%
+% There are two potential solutions of different scope and complexity:
+% \begin{itemize}
+% \item{} Since John Hobby's \MP{} is now available without a
+% non-disclosure agreement from AT\&T, one solution is to replace
+% \MF{} by \MP, which doesn't suffer from the size
+% limitations.
+% This comes with a small price paid in reduced portability of the
+% generated output, but as already stated above in the case of
+% |axodraw|, the ubiquity of PostScript printers (and the free
+% GhostScript interpreter) makes this a minor point.
+% \item{} The more ambitious solutions would be \emph{virtual graphs},
+% i.e.~graphs which are larger than the current limit enforced
+% by numeric overflow at higher resolutions. This could be
+% implemented by calculating the layout of a miniature graph and
+% afterwards distributing the full graph among several \MF{}
+% characters.
+% \end{itemize}
+%
+% \end{fmffile}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section*{Acknowledgements}
+%
+% I am most grateful to Wolfgang Kilian, who pushed \FMF's predecessor
+% |feynman.mf| to its limits~\cite{Kil94}. Discussions with him
+% triggered a lot of good ideas. Thanks also to my students and the
+% people on \emph{The Net} for suggestions, portability fixes and for
+% volunteering as guinea pigs.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \begin{thebibliography}{99}
+% \bibitem{TeX} Donald E.~Knuth, \textit{The \TeX{}book},
+% Addison-Wesley, Reading MA, 1986.
+% \bibitem{LaTeX} Leslie Lamport, \textit{\LaTeX{} --- A
+% Documentation Preparation System},
+% Addison-Wesley, Reading MA, 1985.
+% \bibitem{LaTeX-Companion} Michel Goosens, Frank Mittelbach, and
+% Alexander Samarin, \textit{The \LaTeX{} Companion},
+% Addison-Wesley, Reading MA, 1994.
+% \bibitem{MF} Donald E.~Knuth, \textit{The \MF{}book},
+% Addison-Wesley, Reading MA, 1986.
+% \bibitem{MetaPost} John D.~Hobby, \textit{A User's Manual for
+% \MP}, Computer Science Report \#162, AT\&T Bell
+% Laboratories, April 1992.
+% \bibitem{CPC} Thorsten Ohl,
+% Comp.~Phys.~Comm.~\textbf{90} (1995) 340.
+% \bibitem{CNL} Thorsten Ohl,
+% CERN Computer Newsletter~\textbf{220} (1995) 22;
+% \textbf{221} (1995) 46; \textbf{222} (1996) 24.
+% \bibitem{levine} Micheal J.~S.~Levine,
+% Comp.~Phys.~Comm.~\textbf{58} (1990) 181.
+% \bibitem{axodraw} Jos Vermaseren,
+% Comp.~Phys.~Comm.~\textbf{83} (1994) 45.
+% \texttt{axodraw} is available from CTAN
+% (cf.~p.~\pageref{pg:CTAN}), in the \texttt{graphics} directory.
+% ^^A Comp.~Phys.~Comm.~\textbf{??} (1995) ???.
+% \bibitem{mfpic} Thomas E.~Leathrum, \texttt{mfpic}, available from
+% CTAN (cf.~p.~\pageref{pg:CTAN}), in the \texttt{graphics}
+% directory.
+% \bibitem{madgraph} Tim Stelzer and Bill Long,
+% Comp.~Phys.~Comm.~\textbf{81} (1994) 357.
+% \bibitem{Kil94} Wolfgang Kilian, Doctoral Thesis, Technical
+% University Darmstadt, 1994.
+% \bibitem{Lambda} Alan Jeffrey, \textit{Lists in \TeX's Mouth},
+% TUGboat 199?.
+% \end{thebibliography}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section*{Distribution}
+% \label{sec:distribution}
+%
+% \FMF{} is available by anonymous internet ftp from any of the
+% Comprehensive \TeX{} Archive Network (CTAN) hosts
+% \label{pg:CTAN}
+% \begin{quote}
+% |ftp.shsu.edu|, |ftp.tex.ac.uk|, |ttp.dante.de|
+% \end{quote}
+% in the directory
+% \begin{quote}
+% |macros/latex/contrib/supported/feynmf|
+% \end{quote}
+% It is also available from the host
+% \begin{quote}
+% |crunch.ikp.physik.th-darmstadt.de|
+% \end{quote}
+% in the directory
+% \begin{quote}
+% |pub/ohl/feynmf|
+% \end{quote}
+% Unsupported snapshots of my work in progress are provided as
+% \begin{quote}
+% |pub/ohl/feynmf.versions/feynmf-current.tar.gz|
+% \end{quote}
+% There are two mailing lists
+% \begin{quote}
+% \begin{flushleft}
+% |feynmf-announce@crunch.ikp.physik.th-darmstadt.de|\\
+% |feynmf-bugs@crunch.ikp.physik.th-darmstadt.de|
+% \end{flushleft}
+% \end{quote}
+% open for subscription. The former should carry only important
+% announcements, of new versions in particular. To subscribe, send
+% mail to the (electronic) mailing list manager
+% \begin{quote}
+% |majordomo@crunch.ikp.physik.th-darmstadt.de|
+% \end{quote}
+% and \emph{not} to the lists itself. The following commands (on a
+% line in the body of the mail, not in the subject) are useful:
+% \begin{quote}
+% \begin{flushleft}
+% |subscribe feynmf-announce|\\
+% |unsubscribe feynmf-announce|\\
+% |help|
+% \end{flushleft}
+% \end{quote}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \StopEventually{\PrintIndex\PrintChanges}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \newpage
+% \section{\TeX{} macros}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Startup}
+%
+% It's is good practice to identify this version of the document style
+% option. We do this by parsing an RCS |Id| string and storing the
+% result in the conventional \TeX{} control sequences:
+% \changes{v0.1}{1994/05/19}{%
+% Don't loose on {\tt RCS} strings even iff the dollar signs have
+% been removed.}
+% \changes{v0.8}{1995/02/18}{\LaTeX~2.09 compatibility}
+% \changes{v0.98}{1995/05/01}{%
+% Revise version control: allow for manual intervention to replace
+% the inconvenient RCS revision numbers by version numbers.}
+% \begin{macrocode}
+%<*style>
+\def\fileversion{v1.08}
+%<!209>\NeedsTeXFormat{LaTeX2e}
+{\def\RCS#1#2\endRCS{%
+ \ifx$#1%
+ \@RCS $#2 \endRCS
+ \else
+ \@RCS $*: #1#2$ \endRCS
+ \fi}%
+ \def\@RCS $#1: #2,v #3 #4 #5 #6 #7$ \endRCS{%
+ \gdef\filename{#2}%
+ \gdef\filerevision{#3}%
+ \gdef\filedate{#4}%
+ \gdef\filemaintainer{#6}}%
+\RCS $Id: feynmf.dtx,v 1.30 1996/12/02 09:20:36 ohl Exp $ \endRCS}%
+% \end{macrocode}
+%
+% And now the standard procedure:
+% \changes{v0.4}{1994/05/27}{%
+% \MP{} support: identification part, include
+% \texttt{graphicx} and pass options.}
+% \begin{macrocode}
+%<*!209>
+%<*!mp>
+\ProvidesPackage{feynmf}[\filedate\space\fileversion\space
+ LaTeX/Metafont Feynman Diagram Package (\filemaintainer)]
+%</!mp>
+%<*mp>
+\ProvidesPackage{feynmp}[\filedate\space\fileversion\space
+ LaTeX/MetaPost Feynman Diagram Package (\filemaintainer)]
+%</mp>
+%</!209>
+% \end{macrocode}
+% Compatibiliy with sources written for \FMF{} \emph{before}
+% version~1.03, where macros in labels had to be protected by
+% |\noexpand|. The |\fmf@noexpandoff| macro will be used of
+% page~\pageref{pg:usenoexpandoff}. The default is a no-op.
+% \label{pg:defnoexpandoff}
+% \changes{v1.05}{1996/05/06}{%
+% Provide option \texttt{pre-1.03} for processing old files.}
+% \begin{macrocode}
+%<*!209>
+\let\fmf@noexpandoff\relax
+\DeclareOption{pre-1.03}{%
+ \PackageWarning{feynmf}{%
+ Pre v1.03 compatibility can clash with font loading}
+ \def\fmf@noexpandoff{\let\noexpand\relax}}
+% \end{macrocode}
+% Alow the user to override the default interaction mode
+% |\errorstopmode|. We have to change modes temorarily on
+% page~\pageref{pg:useinteractionmode} below and \TeX{}
+% provides no means to save the state we started in. Therefore a
+% mode differing from the default has to be requested explicitely.
+% \label{pg:definteractionmode}
+% \changes{v1.06}{1996/05/21}{%
+% New options \texttt{errorstop}, \texttt{scroll},
+% \texttt{nonstop} and \texttt{batch}.}
+% \begin{macrocode}
+\DeclareOption{errorstop}{\let\@interactionmode\errorstopmode}
+\DeclareOption{scroll}{\let\@interactionmode\scrollmode}
+\DeclareOption{nonstop}{\let\@interactionmode\nonstopmode}
+\DeclareOption{batch}{\let\@interactionmode\batchmode}
+\let\@interactionmode\errorstopmode
+% \end{macrocode}
+% Every option we don't understand is sent down to |graphics|:
+% \begin{macrocode}
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{graphics}}
+\ProcessOptions
+% \end{macrocode}
+% For the sake of Portabilitical Correctness, we use \LaTeX's
+% |graphics| for including PostScript, instead of the simpler |epsf|
+% which comes with |dvips| and would have sufficed
+% \changes{v0.99}{1995/05/02}{%
+% Switch back to \texttt{graphics} from \texttt{graphicx} to fix
+% a problem with changing interfaces in the latter. Can't remember
+% why I used \texttt{graphicx} in the first place, \texttt{graphics}
+% works fine now.}
+% \begin{macrocode}
+%<mp>\RequirePackage{graphics}[1994/12/15]
+%</!209>
+%<*209>
+\def\fmf@noexpandoff{\let\noexpand\relax}
+%<mp>\input epsf.sty
+%<mp>\let\includegraphics\epsffile
+%</209>
+% \end{macrocode}
+% Compatibility macros for \LaTeX~2.09. Our definition of
+% |\@inputcheck| is for supporting old and broken \LaTeX~2.09 versions
+% before March 18, 1992. Unfortunately, I couldn't get |\newread| to
+% work here with \LaTeX~2.09.
+% \changes{v0.99}{1995/05/02}{%
+% \texttt{\protect\bslash @inputcheck}: support for \LaTeX~2.09
+% versions before 92/03/18.}
+% \begin{macrocode}
+%<*209>
+\@ifundefined{@inputcheck}{\def\@inputcheck{0}}{}%
+\def\InputIfFileExists#1#2#3{%
+ \openin\@inputcheck#1 %
+ \ifeof\@inputcheck
+ \closein\@inputcheck
+ #3%
+ \else
+ \closein\@inputcheck
+ #2%
+ \input{#1}%
+ \fi}
+\def\IfFileExists#1#2#3{%
+ \openin\@inputcheck#1 %
+ \ifeof\@inputcheck
+ \closein\@inputcheck
+ #3%
+ \else
+ \closein\@inputcheck
+ #2%
+ \fi}
+%</209>
+% \end{macrocode}
+%
+% \begin{dubious}
+% We should |\||mdqon| at the end only if the German extensions are
+% really active, not just loaded.
+% \end{dubious}
+% \begin{macrocode}
+\let\mdqrestore\relax
+\@ifundefined{mdqoff}{}{%
+ \mdqoff
+ \let\mdqrestore\mdqon}
+% \end{macrocode}
+%
+% \begin{macro}{\fmfcmd}
+% The entrance through which our commands enter the world of
+% \MF. Note the |\ignorespaces|: we need to avoid spurious
+% blanks in the output list.
+% \changes{v1.03}{1996/02/17}{%
+% Token register \texttt{\protect\bslash fmfbuf@} for single level
+% evaluation.}
+% Using a trick suggested in |comp.text.tex|, we use a token register
+% |\fmfbuf@| to force single level evaluation of commands which are to
+% be included in \MF{} strings.
+% \changes{v1.07}{1996/08/19}{%
+% Only write output if \texttt{\protect\bslash if@fmfio} is true.}
+% \begin{macrocode}
+\def\fmfcmd#1{%
+ \if@fmfio
+ \immediate\write\@outfmf{#1}%
+ \fi
+ \ignorespaces}
+\newif\if@fmfio
+\@fmfiotrue
+\newwrite\@outfmf
+\newtoks\fmfbuf@
+% \end{macrocode}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Environments}
+%
+% \begin{macro}{\fmffile}
+% This environment encloses each \MF{} input file. The single
+% argument gives the name of the file.
+% \changes{v0.1}{1994/05/16}{%
+% Stupid: \texttt{\protect\bslash fileversion} can be reset by other
+% packages, store the current value in
+% \texttt{\protect\bslash fmf@fileversion} and use this one.}
+% \changes{v0.1}{1994/05/20}{%
+% Pass RCS revision in a string.}
+% \changes{v0.4}{1994/05/27}{\MP{} support: write \MP{} file.}
+% \changes{v0.8}{1995/01/18}{%
+% Protect against wrong arguments to
+% \texttt{\protect\bslash fmffile}.}
+% \begin{macrocode}
+{\catcode`\%=11\gdef\p@rcent{%}}
+\edef\fmf@revision{\filerevision}
+\def\fmffile#1{%
+ \def\thefmffile{#1}%
+ \equaltojobname{\thefmffile}{%
+ \errhelp={The argument of \fmffile MUST NOT be identical to the^^J%
+ name of your main input file! I will use fmfdefault.mf^^J%
+ this time around, but you'd better fix your code now!}%
+ \errmessage{Invalid arument of \string\fmffile!}%
+ \def\thefmffile{fmfdefault}}{}%
+% \end{macrocode}
+% The following trick has been taken from |mfpic|~\cite{mfpic}:
+% proceed even if the font is not available yet, because we have to
+% write the \MF{} file first.
+% \changes{v0.4}{1994/05/27}{\MP{} support: don't open \texttt{tfm} file.}
+% \changes{v0.98}{1995/04/30}{%
+% Save the font for the benefit of \texttt{\protect\bslash fmfkeep} and
+% \texttt{\protect\bslash fmfreuse}.}
+% \changes{v1.02}{1996/01/25}{%
+% Read the \texttt{.tfm} file \emph{before} writing the \MF{} file
+% destructively. This should allow a transparent two pass
+% processing if \texttt{MakeTeXTFM} is enabled. Thanks to Thomas
+% Esser for the suggestion.}
+% \begin{macrocode}
+%<*!mp>
+ \batchmode
+ \global\expandafter\font%
+ \csname f@ynmf:\thefmffile\endcsname=\thefmffile
+% \end{macrocode}
+% The hardcoded return to |\errorstopmode| is bad for automated preprint
+% processors, but the integrated knowledge of |comp.text.tex| knows of
+% no way to implement local mode changes --- short of hacking \TeX{}
+% itself \ldots\par
+% Therefore we use a default interaction mode which can be specified
+% by the user as an option (see page~\pageref{pg:definteractionmode}).
+% \label{pg:useinteractionmode}
+% \changes{v1.06}{1996/05/21}{%
+% Use \texttt{\protect\bslash @interactionmode}.}
+% \begin{macrocode}
+ \@interactionmode
+ \expandafter\let\expandafter\f@ynmf\csname f@ynmf:\thefmffile\endcsname
+% \end{macrocode}
+% Inform the user:
+% \begin{macrocode}
+ \ifx\f@ynmf\nullfont
+ \def\f@ynmf{Feynman graph:}%
+ \IfFileExists{\thefmffile.mf}%
+ {\typeout{%
+ feynmf: File \thefmffile.tfm not found:^^J%
+ feynmf: Process \thefmffile.mf with METAFONT and then %
+ reprocess this file.}}%
+ {\typeout{%
+ feynmf: Files \thefmffile.mf and \thefmffile.tfm not found:^^J%
+ feynmf: This job will create \thefmffile.mf, process it %
+ later with METAFONT^^J%
+ feynmf: and then reprocess this file. Don't worry about a %
+ harmless premature^^J%
+ feynmf: MakeTeXTFM that might have failed just a moment ago!}}%
+ \else
+ \typeout{%
+ feynmf: File \thefmffile.tfm found.^^J%
+ feynmf: Nevertheless, if the picture has changed, %
+ reprocess \thefmffile.mf.^^J%
+ feynmf: If dimension have changed, reprocess \thefmffile.mf %
+ and \jobname.tex.}%
+ \fi
+%</!mp>
+% \end{macrocode}
+% Open the \MF{} file. If we're running under AMS-\LaTeX, turn off
+% I/O during the first pass over equation environments.
+% \changes{v1.07}{1996/08/19}{%
+% Only write output if \texttt{\protect\bslash if@fmfio} is true.}
+% \changes{v1.07}{1996/08/19}{%
+% Set \texttt{\protect\bslash if@fmfio} to \texttt{\protect\bslash
+% ifmeasuring@ \protect\bslash else} if the latter is set, i.e.~if
+% AMS-\LaTeX{} is loaded.}
+% \begin{macrocode}
+ \if@fmfio
+ \@ifundefined{ifmeasuring@}%
+ {}%
+ {\def\if@fmfio{\ifmeasuring@\else}}%
+%<*!mp>
+ \immediate\openout\@outfmf=\thefmffile.mf\relax
+ \fmfcmd{\p@rcent\space \thefmffile.mf -- do not edit, %
+ generated automatically by \jobname.tex^^J%
+ input feynmf^^J%
+ require_RCS_revision "\fmf@revision";}%
+%</!mp>
+%<*mp>
+ \immediate\openout\@outfmf=\thefmffile.mp\relax
+ \fmfcmd{\p@rcent\space \thefmffile.mp -- do not edit, %
+ generated automatically by \jobname.tex^^J%
+ input feynmp^^J%
+ require_RCS_revision "\fmf@revision";}%
+%</mp>
+ \fi
+% \end{macrocode}
+% Count the graphs
+% \begin{macrocode}
+ \setcounter{fmfgraph}{0}}
+\let\thefmffile\relax
+\newcounter{fmfgraph}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\equaltojobname}
+% Here's a kludge for comparing strings to |\jobname|. The |\meaning|
+% hack is necessary, because |\jobname|'s expansion has different
+% |\catcode|s
+% \begin{macrocode}
+\def\equaltojobname#1#2#3{%
+ \edef\@tempa{#1}%
+ \edef\@tempa{\meaning\@tempa}%
+ \edef\@tempb{\jobname}%
+ \edef\@tempb{\meaning\@tempb}%
+ \ifx\@tempa\@tempb
+ #2
+ \else
+ #3
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\endfmffile}
+% And here is how we close the |fmffile| environment:
+% \begin{macrocode}
+\def\endfmffile{%
+ \fmfcmd{\p@rcent\space the end.^^J%
+ end.^^J%
+ endinput;}%
+ \let\thefmffile\relax
+ \if@fmfio
+ \immediate\closeout\@outfmf
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fmf@graph}
+% This is the bulk of the environment used for each graph
+% drawn by \MF.
+% \changes{v0.5}{1994/08/17}{%
+% Removed definiton of \texttt{\protect\bslash sharp}. It's never
+% used and conflicts with the $\sharp$ symbol.}
+% \changes{v1.06}{1996/05/21}{%
+% New macro \texttt{\protect\bslash dqu@te}.}
+% \begin{macrocode}
+{\catcode`\#=11\gdef\sh@rp{#}%
+ \catcode`\"=11\gdef\dqu@te{"}}
+\def\fmf@graph#1#2{%
+% \end{macrocode}
+% Make sure that a \MF{} file is open, otherwise \emph{really}
+% obscure error messages are possible:
+% \changes{v0.3}{1994/05/23}{%
+% Make sure that a \MF{} file is open, otherwise \emph{really}
+% obscure error messages are possible.}
+% \begin{macrocode}
+ \ifx\thefmffile\relax
+ \errhelp={Outside a fmffile environment, I have no clue as to where^^J%
+ the METAFONT commands should go. I will use fmfdefault.mf^^J%
+ for this graph, but you'd better fix your code!}%
+ \errmessage{I detected a fmfgraph environment outside of fmffile}%
+ \fmffile{fmfdefault}
+ \fi
+% \end{macrocode}
+% We can't use |\stepcounter| because of the |amstext| option of
+% AMS-\LaTeX{} disables it sometimes.
+% \changes{v0.8}{1995/01/07}{Don't use \texttt{\protect\bslash stepcounter}.}
+% \changes{v0.99}{1995/05/04}{Use \texttt{\protect\bslash fmfsubgraph}.}
+% \begin{macrocode}
+ \global\expandafter\advance\csname c@fmfgraph\endcsname \@ne
+% \end{macrocode}
+% Start \MF{} character:\footnote{%
+% I'm flying a bit blind here, because I can't figure out why Babel
+% (unlike stand-alone \texttt{german.sty} breaks with an unprotected
+% quote here. On all other occasions, \texttt{\protect\bslash
+% mdqoff} suffices.}
+% \changes{v1.06}{1996/05/21}{Babel compatibility.}
+% \begin{macrocode}
+ \fmfcmd{beginchar(\thefmfgraph, #1*\the\unitlength\sh@rp, %
+ #2*\the\unitlength\sh@rp, 0);^^J%
+ \dqu@te feynmf: \thefmfgraph\dqu@te;}%
+ \fmfcmd{LaTeX_unitlength:=\the\unitlength;}%
+ \begin{fmfsubgraph}(0,0)(w,h)
+ \fmfinit
+ \fmfpen{thin}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fmfgraph}
+% The plain version, no labels, no enclosing |picture| environment
+% \changes{v0.99}{1995/05/04}{%
+% Change the name of \texttt{\protect\bslash fmfchar} and friends to
+% \texttt{\protect\bslash fmfgraph}, which should be more intuitive
+% to people with less of a \MF{} background. Keep the old names as
+% aliases for a while.}
+% \begin{macrocode}
+\def\fmfgraph(#1,#2){%
+ \fmf@graph{#1}{#2}%
+ \def\fmfkeep##1{\fmf@keep{#1}{#2}{##1}}%
+% \end{macrocode}
+% Place the character:
+% \changes{v0.4}{1994/05/27}{\MP{} support: include PostScript file.}
+% \changes{v0.8}{1995/02/18}{\LaTeX~2.09 compatibility}
+% \begin{macrocode}
+%<!mp>{\f@ynmf \char\value{fmfgraph}}%
+%<*mp>
+ \leavevmode
+ \IfFileExists{\thefmffile.\thefmfgraph}%
+ {\includegraphics{\thefmffile.\thefmfgraph}}%
+ {\typeout{%
+ feynmp: File \thefmffile.\thefmfgraph\space not found:^^J%
+ feynmp: Process \thefmffile.mp with MetaPost and then %
+ reprocess this file.}}%
+%</mp>
+ \ignorespaces}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\endfmfgraph}
+% \begin{macrocode}
+\def\endfmfgraph{%
+ \fmffreeze
+ \fmfdraw
+ \end{fmfsubgraph}
+ \fmfcmd{endchar;}%
+ \def\fmfkeep##1{\fmf@nokeep}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fmfchar}
+% \begin{macro}{\endfmfchar}
+% \begin{macrocode}
+\def\fmfchar{\@nameuse{fmfgraph}}
+\def\endfmfchar{\@nameuse{endfmfgraph}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fmfgraph*}
+% The extended version, with labels and |picture| environment.
+% \begin{macrocode}
+\@namedef{fmfgraph*}(#1,#2){%
+ \begin{picture}(#1,#2)
+ \fmf@graph{#1}{#2}%
+ \def\fmfkeep##1{\fmf@keepstar{#1}{#2}{##1}}%
+% \end{macrocode}
+% Process the \MF{} output for labels (if any), enforcing |%| as
+% comment character.
+% \changes{v0.99}{1995/05/07}{%
+% Don't include the filename in the tag for
+% \texttt{\protect\bslash grepfile}: it's a waste.}
+% Not all systems use |.log| as extension of the |log|-file. If there
+% is no |.log|, but a |.lis|: use the latter.
+% \changes{v0.99}{1995/05/07}{%
+% From Scott Snyder (Fermilab): allow \texttt{.lis}
+% as alternative \texttt{log}-file extension for VMS.}
+% \changes{v1.07}{1996/08/19}{%
+% Call \texttt{\protect\bslash grepfile} only if
+% \texttt{\protect\bslash if@fmfio} is true.}
+% \begin{macrocode}
+%<*!mp>
+ \if@fmfio
+ \def\thefmfext{.log}%
+ \IfFileExists{\thefmffile.log}%
+ {}%
+ {\IfFileExists{\thefmffile.lis}%
+ {\def\thefmfext{.lis}}%
+ {}}%
+ {\catcode`\%=14\relax
+ \grepfile%
+ {\thefmfgraph}%
+ {\thefmffile\thefmfext}%
+ {\thefmffile.t\thefmfgraph}}%
+ \fi
+%</!mp>
+% \end{macrocode}
+% Place the character:
+% \changes{v0.4}{1994/05/27}{\MP{} support: include PostScript file.}
+% \begin{macrocode}
+%<!mp>\put(0,0){{\f@ynmf \char\value{fmfgraph}}}%
+%<*mp>
+ \IfFileExists{\thefmffile.\thefmfgraph}%
+ {\put(0,0){\includegraphics{\thefmffile.\thefmfgraph}}}%
+ {\typeout{%
+ feynmp: File \thefmffile.\thefmfgraph\space not found:^^J%
+ feynmp: Process \thefmffile.mp with MetaPost and then %
+ reprocess this file.}}%
+%</mp>
+ \ignorespaces}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\endfmfgraph*}
+% \begin{macrocode}
+\@namedef{endfmfgraph*}{%
+ \endfmfgraph
+% \end{macrocode}
+% Enforce |%| as comment character. Disable |\noexpand| if the
+% option |pre-1.03| is in effect to allow processing of old files
+% prepared before the new single level expansion had been
+% implemented. |\fmf@noexpandoff| is defined on
+% page~\ref{pg:defnoexpandoff}.
+% \label{pg:usenoexpandoff}
+% \changes{v1.03}{1996/02/17}{%
+% Disable \texttt{\protect\bslash noexpand} to allow
+% processing of old files.}
+% \changes{v1.05}{1996/05/06}{%
+% Reenable \texttt{\protect\bslash noexpand} for compatibility with
+% font loading on demand.}
+% \changes{v1.07}{1996/08/19}{%
+% Include the labels file only if \texttt{\protect\bslash if@fmfio}
+% is true.}
+% \begin{macrocode}
+ \if@fmfio
+ {\catcode`\%=14\relax
+ \fmf@noexpandoff
+ \InputIfFileExists{\thefmffile.t\thefmfgraph}{}{%
+ \typeout{%
+ feynmf: Label file \thefmffile.t\thefmfgraph\space not found:^^J%
+%<!mp> feynmf: Process \thefmffile.mf with METAFONT and then %
+%<mp> feynmf: Process \thefmffile.mp with MetaPost and then %
+ reprocess this file.}}}%
+ \fi
+ \end{picture}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fmfchar*}
+% \begin{macro}{\endfmfchar*}
+% \begin{macrocode}
+\@namedef{fmfchar*}{\@nameuse{fmfgraph*}}
+\@namedef{endfmfchar*}{\@nameuse{endfmfgraph*}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fmfkeep}
+% \changes{v0.98}{1995/04/30}{Implemented.}
+% \begin{macrocode}
+\def\fmfkeep#1{\fmf@nokeep}
+\def\fmf@nokeep{%
+ \errhelp={There's nothing to \string\fmfkeep!}%
+ \errmessage{feynmf: \string\fmfkeep\space outside of `fmfgraph'!}}
+% \end{macrocode}
+% Here are the real implementations:
+% \begin{macrocode}
+\def\fmf@keep#1#2#3{%
+ \global\@namedef{fmf@k:e:#3}{\begin{fmfgraph}(#1,#2)\end{fmfgraph}}%
+ \global\e@namedef{fmf@k:f:#3}{\thefmffile}%
+ \global\e@namedef{fmf@k:c:#3}{\thefmfgraph}}
+\def\fmf@keepstar#1#2#3{%
+ \global\@namedef{fmf@k:e:#3}{\begin{fmfgraph*}(#1,#2)\end{fmfgraph*}}%
+ \global\e@namedef{fmf@k:f:#3}{\thefmffile}%
+ \global\e@namedef{fmf@k:c:#3}{\thefmfgraph}}
+\def\e@namedef#1{\expandafter\edef\csname #1\endcsname}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fmfreuse}
+% \changes{v0.98}{1995/04/30}{Implemented.}
+% \begin{macrocode}
+\def\fmfreuse#1{%
+ \@ifundefined{fmf@k:e:#1}%
+ {\typeout{%
+ feynmf: \string\fmfreuse: %
+ missing \string\fmfkeep\space for `#1'!}}%
+ {\edef\thefmffile{\@nameuse{fmf@k:f:#1}}%
+%<*!mp>
+ \expandafter\let\expandafter\f@ynmf%
+ \csname f@ynmf:\thefmffile\endcsname
+%</!mp>
+ \@nameuse{c@fmfgraph}\@nameuse{fmf@k:c:#1}%
+ \advance\@nameuse{c@fmfgraph}-1%
+ \def\fmfcmd##1{}%
+ \@nameuse{fmf@k:e:#1}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fmfframe}
+% This is used to allocate additional space around a |fmfgraph*|, since
+% the labels (or the diagram itself) might overshoot.
+% |\fmfgraph(|\meta{left}|,|\meta{top}|)(|\meta{right}|,|\meta{bottom}|){|^^A
+% \meta{box}|}| puts an invisible frame of the given dimensions
+% (measured in |\unitlength|) around \meta{box}.
+% \begin{macrocode}
+\def\fmfframe(#1,#2)(#3,#4)#5{%
+ \leavevmode
+ \hbox{\vbox{\vskip#2\unitlength\par
+ \hbox{\hskip#1\unitlength#5\hskip#3\unitlength}\par
+ \vskip#4\unitlength}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fmfpen}
+% Picup a |pencircle| scaled by the argument.
+% \begin{macrocode}
+\def\fmfpen#1{\fmfcmd{pickup pencircle scaled #1;}}
+% \end{macrocode}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Subgraphs}
+%
+% \begin{macro}{\fmfsubgraph}
+% \begin{macro}{\endfmfsubgraph}
+% An environment for graphs in graphs:
+% \changes{v0.99}{1995/05/04}{%
+% Implement \texttt{\protect\bslash fmfsubgraph}, as suggested by
+% Wolfgang Kilian (DESY).}
+% \begin{macrocode}
+\def\fmfsubgraph(#1,#2)(#3,#4){\fmfcmd{subgraph (#1, #2, #3, #4);}}
+\def\endfmfsubgraph{\fmfcmd{endsubgraph;}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Set up a subgraph:
+% \begin{macrocode}
+%<*base>
+def subgraph (expr x, y, wd, ht) =
+ begingroup
+ save c, ne, nw, sw, se;
+ pair c, ne, nw, sw, se;
+ sw = (x,y);
+ se = sw + (wd,0);
+ nw = sw + (0,ht);
+ ne = sw + (wd,ht);
+ c = .5[sw,ne];
+enddef;
+def endsubgraph =
+ endgroup
+enddef;
+%</base>
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Grep}
+% \label{sec:grep}
+%
+% \begin{macro}{\grepfile}
+% The macro |\grepfile{|\meta{pattern}|}{|\meta{in}|}{|\meta{out}|}|
+% writes all lines matching |:|\meta{pattern}|:| from file \meta{in}
+% to file \meta{out} after stripping off the pattern.
+% \begin{dubious}
+% Pattern matching on lines with a single leading colon fails.
+% \end{dubious}
+% \changes{v0.4}{1994/05/28}{%
+% Don't include the \texttt{\protect\bslash grep} macros in the
+% \MP{} version. \texttt{\protect\bslash write} makes them
+% obsolete.}
+% \begin{macrocode}
+%<*style>
+%<*!mp>
+\def\grepfile#1#2#3{%
+ \begingroup
+% \end{macrocode}
+% Hash the pattern and open the input and output streams:
+% \begin{macrocode}
+ \edef\pattern{\csname*grep*#1*\endcsname}%
+ \immediate\openin\grep@infile #2\relax
+ \ifeof\grep@infile
+ \else
+ \grep@outopenfalse
+% \end{macrocode}
+% Don't add anything at the end of input lines and don't expand
+% anything we've read from the file:
+% \changes{v1.05}{1996/05/06}{%
+% Use \texttt{\protect\bslash @sanitize} instead of just changing
+% the \texttt{\protect\bslash catcode} of
+% ``\texttt{\protect\bslash}''. Some styles (in particular
+% \texttt{french.sty}) play dirty tricks with ``\texttt{:}''.}
+% \begin{macrocode}
+ \endlinechar=-1
+ \@sanitize
+% \end{macrocode}
+% But make sure that |{|, |}| and |%| continue to act as delimiters
+% and comment character, respectively. |\@sanitize| will usually have
+% changed at least the |\catcode| of the latter. We need the
+% delimiters for multi-line reading and |%| for commenting out \MF's
+% pregress reports.
+% \begin{macrocode}
+ \catcode`\{=1 \catcode`\}=2 \catcode`\%=14 \relax
+% \end{macrocode}
+% Loop over the input lines until end of file occurs. Note that
+% \TeX's |\read| will automagically continue reading until braces are
+% balanced.
+% \begin{macrocode}
+ \loop
+ \read\grep@infile to \grep@lbuf
+ \ifeof\grep@infile
+ \grep@contfalse
+ \else
+ \grep@conttrue
+% \end{macrocode}
+% Iff the input line is not empty, use |\grep@aline| to examine its
+% contents and, iff the pattern matched, write a line to the output file.
+% \begin{macrocode}
+ \ifx\grep@lbuf\empty
+ \else
+ \expandafter\grep@aline\grep@lbuf\sentinel
+ \ifx\pattern\grep@tag
+% \end{macrocode}
+% Delayed open (this avoids empty files):
+% \begin{macrocode}
+ \ifgrep@outopen
+ \else
+ \immediate\openout\grep@outfile #3\relax
+ \immediate\write\grep@outfile{\p@rcent\space #3 %
+ -- generated automatically from #2}%
+ \immediate\write\grep@outfile{\p@rcent\space
+ Think twice before editing THIS file!}%
+ \grep@outopentrue
+ \fi
+ \immediate\write\grep@outfile{\grep@val}%
+ \fi
+ \fi
+ \fi
+ \ifgrep@cont
+ \repeat
+% \end{macrocode}
+% Close the files after we're done.
+% \changes{v0.1}{1994/05/16}{%
+% Stupid: \texttt{\protect\bslash closein} the input stream,
+% don't use \texttt{\protect\bslash closeout} on it.}
+% \begin{macrocode}
+ \ifgrep@outopen
+ \immediate\closeout\grep@outfile
+ \fi
+ \fi
+ \immediate\closein\grep@infile
+ \endgroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\grep@infile}
+% \begin{macro}{\grep@outfile}
+% The I/O streams for the grep facility
+% \begin{macrocode}
+\newread\grep@infile
+\newwrite\grep@outfile
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\ifgrep@cont}
+% \begin{macro}{\ifgrep@outopen}
+% and flags for the same
+% \begin{macrocode}
+\newif\ifgrep@cont
+\newif\ifgrep@outopen
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\grep@aline}
+% Examine one line and set the variables |\grep@tag| and |\grep@val|
+% iff the line starts with a colon. Subtle point here: |\ifx#1:| will
+% \emph{not} work if |#1| starts with a |{| followed by two identical
+% characters.
+% \begin{macrocode}
+\def\grep@aline#1#2\sentinel{%
+ \ifx:#1%
+ \grep@splitlbuf#2\sentinel
+ \else
+ \edef\grep@tag{\csname*grep*\endcsname}%
+ \def\grep@val{}%
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\grep@splitlbuf}
+% Split the line buffer at the remaining colon, hashing the first part.
+% \begin{macrocode}
+\def\grep@splitlbuf#1:#2\sentinel{%
+ \edef\grep@tag{\csname*grep*#1*\endcsname}%
+ \def\grep@val{#2}}
+%</!mp>
+% \end{macrocode}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Lists}
+%
+% The following macros are stolen from Alan Jeffrey's
+% |lambda.sty|~\cite{Lambda}. Alan's implementation is more complete,
+% this is just the subset we need to do some listprocessing in \TeX's
+% mouth, e.g.~in the body of a |\write|. Actually, you're not
+% supposed to understand these macros from first reading. It's better
+% to read Alan's paper (it is available from CTAN as |lambda.tex|),
+% where they are described. From a programming point of view, Alan's
+% macros are probably my favorites. You will find a whole new
+% perspective on \TeX{} there.
+% \changes{v0.98}{1995/04/26}{List processing macros.}
+% \begin{macrocode}
+\def\Compose#1#2#3{#1{#2{#3}}}
+\def\gobblefalse\else\gobbletrue\fi#1#2{\fi#1}
+\def\gobbletrue\fi#1#2{\fi#2}
+\def\TeXif#1{#1\gobblefalse\else\gobbletrue\fi}
+\def\Nil#1#2{#2}
+\def\Cons#1#2#3#4{#3{#1}{#2}}
+\def\Singleton#1{\Cons{#1}\Nil}
+\def\Foldr#1#2#3{#3{\Foldr@{#1}{#2}}{#2}}
+\def\Foldr@#1#2#3#4{#1{#3}{\Foldr{#1}{#2}{#4}}}
+\def\Map#1{\Foldr{\Compose\Cons{#1}}\Nil}
+\def\Unlistize#1{#1\Unlistize@{}}
+\def\Unlistize@#1{#1\Foldr\Commaize{}}
+\def\Commaize#1#2{, #1#2}
+\def\Listize#1{\Listize@#1,\relax @@@}
+\def\Listize@#1,#2@@@{%
+ \TeXif{\ifx\relax#2}%
+ {\Singleton{#1}}%
+ {\Cons{#1}{\Listize@#2@@@}}}
+% \end{macrocode}
+%
+% Protect \MF's namespace:
+% \changes{v1.03}{1996/02/17}{%
+% Replace \texttt{\protect\bslash pfx} by
+% \texttt{\protect\bslash fmfpfx} for namespace sanity.}
+% \begin{macrocode}
+\def\fmfpfx@#1{__#1}
+\def\fmfpfx#1{\Unlistize{\Map\fmfpfx@{\Listize{#1}}}}
+% \end{macrocode}
+%
+% The other \TeX{} command sequences are defined below, along with the
+% \MF{} macros they are in one-to-one correspondence to.
+% \begin{macrocode}
+%</style>
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{\MF{} macros}
+% \label{sec:mf-code}
+%
+% Now we turn our attention to the \MF{}
+% macros.
+% \begin{dubious}
+% We should find a way (a hack) to index the
+% \MF{} macros with the |doc| option.
+% \end{dubious}
+% Because of name clashes, \FMF{} will not work if the |cmbase| is
+% loaded. Die with an useful error message:
+% \changes{v0.5}{1994/06/13}{Don't accept the Computer Modern Base.}
+% \begin{macrocode}
+%<*base>
+if known cmbase:
+ errhelp
+ "feynmf will only work with plain Metafont, as described in the book.";
+ errmessage "feynmf: CMBASE detected. Please use the PLAIN base.";
+ forever:
+ errmessage "No use in trying! You'd better eXit now ...";
+ errorstopmode;
+ endfor
+fi
+% \end{macrocode}
+%
+% Make the RCS revision number available for feature testing:
+% \changes{v0.1}{1994/05/20}{%
+% Handle arbitrary RCS revision strings.}
+% \begin{macrocode}
+vardef parse_RCS (suffix RCS) (expr s) =
+ save n, c;
+ numeric n, RCS[];
+ string c;
+ RCS[0] := 0;
+ for n = 1 upto length (s):
+ c := substring (n-1,n) of s;
+ exitif ((RCS[0] > 0) and (c = " "));
+ if ((c = "0") or (c = "1") or (c = "2")
+ or (c = "3") or (c = "4") or (c = "5")
+ or (c = "6") or (c = "7") or (c = "8")
+ or (c = "9")):
+ if RCS[0] = 0:
+ RCS[0] := 1;
+ RCS[RCS[0]] := 0;
+ fi
+ RCS[RCS[0]] := 10 * RCS[RCS[0]] + scantokens (c);
+ elseif c = ".":
+ RCS[0] := RCS[0] + 1;
+ RCS[RCS[0]] := 0;
+ else:
+ fi
+ endfor
+enddef;
+% \end{macrocode}
+% Check that \LaTeX{} style and \MF{} macros are in sync:
+% \begin{macrocode}
+vardef require_RCS_revision expr s =
+ save n, TeX_rev, mf_rev;
+ numeric n;
+ parse_RCS (TeX_rev, s);
+ parse_RCS (mf_rev, "$Revision: 1.30 $");
+ for n = 1 upto min (2, TeX_rev[0], mf_rev[0]):
+ if TeX_rev[n] > mf_rev[n]:
+ errhelp
+ "Your version of `feynmf.sty' is higher that of your `feynmf.mf'.";
+ errmessage "feynmf: Metafont macros out of date";
+ elseif TeX_rev[n] < mf_rev[n]:
+ errhelp
+ "Your version of `feynmf.mf' is higher that of your `feynmf.sty'.";
+ errmessage "feynmf: LaTeX style out of date";
+ fi
+ exitif (TeX_rev[n] <> mf_rev[n]);
+ endfor
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{\MP{} support}
+%
+% This \MP{} support just mimics \MF{}, but it works.
+% \changes{v0.4}{1994/05/27}{Preliminary \MP{} support: mimic \MF.}
+% \begin{macrocode}
+%<*mp>
+vardef cullit = \ enddef;
+color foreground;
+foreground = black;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef beginchar (expr c, wd, ht, dp) =
+ LaTeX_file := "";
+ beginfig(c);
+ w:=wd;
+ h:=ht;
+enddef;
+string LaTeX_file;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef endchar =
+ setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle;
+ if LaTeX_file <> "":
+ write EOF to LaTeX_file;
+ LaTeX_file := "";
+ fi
+ endfig
+enddef;
+% \end{macrocode}
+%
+% Sharped dimensions are useless with \MP. We define them anyway
+% with trivial translation, so that the \MF{} code can be used
+% unchanged.
+% \begin{macrocode}
+bp# := bp;
+cc# := cc;
+cm# := cm;
+dd# := dd;
+in# := in;
+mm# := mm;
+pc# := pc;
+pt# := pt;
+% \end{macrocode}
+% As I said: trivial translation.
+% \begin{macrocode}
+vardef define_blacker_pixels(text t) =
+ forsuffixes $=t:
+ $:=$.#;
+ endfor
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+picture unitpixel;
+unitpixel = nullpicture;
+addto unitpixel contour unitsquare;
+def t_ = \ enddef;
+%</mp>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<!mp>mode_setup;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Basics}
+% \label{sec:mf-basics}
+%
+% Allow the user to life dangerously or not, depending on his
+% preferences.
+% \changes{v0.7}{1994/10/23}{\texttt{fmfwizard}: to live dangerously or not.}
+% \begin{macrocode}
+boolean feynmfwizard;
+feynmfwizard := false;
+%</base>
+% \end{macrocode}
+% \begin{macro}{\fmfwizard}
+% \begin{macro}{\fmfnowizard}
+% \begin{macrocode}
+%<*style>
+\def\fmfwizard{\fmfcmd{feynmfwizard := true;}}
+\def\fmfnowizard{\fmfcmd{feynmfwizard := false;}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Default values of style parameters:
+% \begin{macrocode}
+%<*base>
+thin# := 1pt#; % dimension of the lines
+thick# := 2thin#;
+arrow_len# := 4mm#;
+arrow_ang := 15;
+curly_len# := 3mm#;
+dash_len# := 3mm#; % 'photon' lines
+dot_len# := 2mm#; % 'photon' lines
+wiggly_len# := 4mm#; % 'photon' lines
+wiggly_slope := 60;
+zigzag_len# := 2mm#;
+zigzag_width# := 2thick#;
+decor_size# := 5mm#;
+dot_size# := 2thick#;
+% \end{macrocode}
+% Convert ``sharp'' units:
+% \begin{macrocode}
+define_blacker_pixels (thick, thin,
+ dash_len, dot_len, wiggly_len, curly_len,
+ zigzag_len, zigzag_width, arrow_len, decor_size, dot_size);
+% \end{macrocode}
+%
+% Back by popular demand: shrinking dimensions.
+% \changes{v0.5}{1994/06/13}{%
+% Back by popular demand: shrinking dimensions.}
+% \begin{macrocode}
+def shrink expr s =
+ begingroup
+ if shrinkables <> "":
+ save tmp_;
+ forsuffixes $ = scantokens shrinkables:
+% \end{macrocode}
+% The sharp dimension might not be known, e.g.~after
+% |\fmfset{arrow_len}{6mm}|, protect against that:
+% \changes{v1.06}{1995/05/29}{%
+% Make \texttt{shrink} work, even if the sharp dimension is not
+% known.}
+% \begin{macrocode}
+ if known $.#:
+ tmp_ := $.#;
+ save $;
+ $.# := s * tmp_;
+ define_blacker_pixels ($);
+ else:
+ tmp_ := $;
+ save $;
+ $ := s * tmp_;
+ fi
+ endfor
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+def endshrink =
+ endgroup
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfshrink}
+% \begin{macro}{\endfmfshrink}
+% Exporting the whole enchilada to \LaTeX:
+% \begin{macrocode}
+%<*style>
+\def\fmfshrink#1{\fmfcmd{shrink (#1);}}
+\def\endfmfshrink{\fmfcmd{endshrink;}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin {macrocode}
+%<*base>
+string shrinkables;
+shrinkables := "";
+% \end{macrocode}
+%
+% This macro is used to register shrinkable dimensions. It is not
+% really robust, we have add the first enty by hand:
+% \begin {macrocode}
+vardef addto_shrinkables (text l) =
+ forsuffixes $ = l:
+ shrinkables := shrinkables & "," & str $;
+ endfor
+enddef;
+shrinkables := "thick,thin";
+% \end{macrocode}
+%
+% \begin {macrocode}
+addto_shrinkables (dash_len, dot_len);
+addto_shrinkables (wiggly_len, curly_len);
+addto_shrinkables (zigzag_len, zigzag_width);
+addto_shrinkables (arrow_len);
+addto_shrinkables (decor_size, dot_size);
+% \end{macrocode}
+%
+% Default to metric units, but this will be reset by |\begin{fmfgraph}|
+% anyway.
+% \begin {macrocode}
+LaTeX_unitlength := mm;
+% \end{macrocode}
+%
+% Count the number of tokens in the argument:
+% \begin {macrocode}
+vardef count (text list) =
+ forsuffixes $ = list: + 1 endfor
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Parsing options}
+% \label{sec:getopt}
+%
+% Parse the string |s| into comma separated tokens |opt[]|, ignoring
+% blanks before |=|'s. Double commas are passed as a single comma.
+% \changes{v0.8}{1994/10/25}{%
+% Plugged the string memory leak in \texttt{getopt}: don't create
+% intermediate one character strings, \MF{} never claims them back.}
+% \begin {macrocode}
+vardef getopt (suffix opt) (expr s) =
+ save n, argp, escape, anchor, skip;
+ numeric opt.first, opt.last, n, anchor;
+ string opt[], opt[]arg;
+ boolean opt[]tainted, argp, escape, skip;
+ opt.first := 0;
+ opt.last := 0;
+ opt[opt.last] := "";
+ argp := false;
+ escape := false;
+ anchor := 0;
+ skip := true;
+ for n = 1 upto length (s):
+% \end{macrocode}
+% Skip blanks at the beginning of each option or argument:
+% \begin {macrocode}
+ if skip and (substring (n-1, n) of s = " "):
+ anchor := anchor + 1;
+ else:
+ skip := false;
+% \end{macrocode}
+% If we see a comma which has not been escaped, check for a second
+% comma and set the |escape| flags and remember to remove the second
+% comma later or reset the |argp| flag, as appropriate:
+% \begin {macrocode}
+ if not escape and (substring (n-1, n) of s = ","):
+ if substring (n, n+1) of s = ",":
+ escape := true;
+ opt[opt.last]tainted := true;
+% \end{macrocode}
+% Else accept the option or argument:
+% \begin {macrocode}
+ else:
+ if argp:
+ opt[opt.last]arg := substring (anchor, n-1) of s;
+ else:
+ opt[opt.last] := substring (anchor, n-1) of s;
+ fi
+ anchor := n;
+ argp := false;
+ skip := true;
+ opt.last := opt.last + 1;
+ fi
+% \end{macrocode}
+% Start as argument and ignore |=|'s until the next option:
+% \begin {macrocode}
+ elseif not argp and (substring (n-1, n) of s = "="):
+ opt[opt.last] := substring (anchor, n-1) of s;
+ anchor := n;
+ argp := true;
+ skip := true;
+% \end{macrocode}
+% Accept the next character (either option or argument) and reset the
+% |escape| flag:
+% \begin {macrocode}
+ elseif argp or (substring (n-1, n) of s <> " "):
+ escape := false;
+ fi
+ fi
+ endfor
+% \end{macrocode}
+% Accept the final option or argument:
+% \begin {macrocode}
+ if argp:
+ opt[opt.last]arg := substring (anchor, length s) of s;
+ else:
+ opt[opt.last] := substring (anchor, length s) of s;
+ fi
+% \end{macrocode}
+% We still have to remove possible doubled commata from the arguments.
+% Theoretically, we could already have done it above (that's the way
+% earlier versions of \FMF{} did it), but only at the expense of
+% excessive copying of strings (like |opt[n]arg:=opt[n]arg&c|). Given
+% \MF's string handling, we should avoid these \emph{at any cost},
+% because the wasted string memory will \emph{never} be
+% reclaimed!\footnote{Actually, \MP{} has code to compact the string
+% pool, which makes \emph{a lot} of difference in the present case.
+% But this doesn't help us with \MF.}
+% Since the more elegant former version had a serious string memory
+% leak, we'd better stick to the current ugly but space efficient
+% implementation.
+% \begin {macrocode}
+ for n = opt.first upto opt.last:
+ if known opt[n]tainted:
+ if opt[n]tainted:
+ opt[n]arg := untaint_string opt[n]arg;
+ fi
+ fi
+ endfor
+enddef;
+% \end{macrocode}
+% Turn double commata into single commata, using as little string
+% copies as possible:
+% \begin {macrocode}
+vardef untaint_string suffix s =
+ save n, anchor;
+ numeric n, anchor;
+ anchor := 0;
+ for n = 1 upto length (s) - 1:
+ if substring (n-1,n+1) of s = ",,":
+ substring (anchor, n-1) of s &
+ hide (anchor := n)
+ fi
+ endfor
+ substring (anchor, length s) of s
+enddef;
+% \end{macrocode}
+%
+% Split a string into |.|-separated components for matching options.
+% \begin {macrocode}
+vardef split_string (suffix comp) (expr s) =
+ save n, anchor;
+ numeric comp.first, comp.last, n, anchor;
+ string comp[];
+ comp.first := 0;
+ comp.last := 0;
+ comp[comp.last] := "";
+ anchor := 0;
+ for n = 1 upto length (s):
+ if substring (n-1,n) of s = ".":
+ comp[comp.last] := substring (anchor, n-1) of s;
+ comp.last := comp.last + 1;
+ anchor := n;
+ fi
+ endfor
+ comp[comp.last] := substring (anchor, length s) of s;
+enddef;
+% \end{macrocode}
+% Return |true| iff |prefix| is a prefix of |s|:
+% \begin {macrocode}
+vardef match_prefix (expr prefix, s) =
+ (prefix = substring (0, length prefix) of s)
+enddef;
+% \end{macrocode}
+% Match options similarly to |Xt| resource strings, but allowing for
+% abbreviations:
+% \changes{v0.7}{1994/10/23}{More general option parsing.}
+% \begin {macrocode}
+vardef match_option (expr s, option) =
+ save sc, optionc, n, i;
+ numeric sc.first, sc.last, optionc.first, optionc.last;
+ string sc[], optionc[];
+ numeric n, i;
+ split_string (sc, s);
+ split_string (optionc, option);
+ n := sc.last - sc.first;
+ if n <> (optionc.last - optionc.first):
+ false
+ else:
+ true
+ for i = 0 upto n:
+ and match_prefix (sc[sc.first+i],
+ optionc[optionc.first+i])
+ endfor
+ fi
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Manipulating \texttt{picture}s}
+% \label{sec:pictures}
+%
+% This section is leftover from the five year old |feynman.mf| package
+% and is now obsolete for \MF. Ironically, we still need it to mimic
+% our \MF{} clipping code in \MP.
+%
+% |save_picture (list_of_pictures)| |save|'s each member of
+% |list_of_pictures| inside a group and reinitializes them as nullpictures.
+% \begin{macrocode}
+def save_picture text t =
+ save t; picture t; forsuffixes p=t: p:=nullpicture; endfor
+enddef;
+% \end{macrocode}
+%
+% |begin_sketch| pushes the sketchpad stack and perform the following
+% drawing commands (upto the next |end_sketch|) on the new sketchpad.
+% \begin{macrocode}
+def begin_sketch =
+ begingroup save_picture currentpicture;
+ sketchlevel := sketchlevel+1;
+enddef;
+% \end{macrocode}
+%
+% |end_sketch| pops the sketchpad stack.
+% \begin{macrocode}
+def end_sketch =
+ sketchlevel := sketchlevel-1;
+ sketchpad[sketchlevel] := currentpicture;
+ endgroup
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+picture sketchpad[];
+sketchlevel := 1;
+% \end{macrocode}
+%
+% |use_sketch (transformation)| copies the transformed sketchpad into
+% the current picture.
+% \begin{macrocode}
+vardef use_sketch text t =
+ addto currentpicture also (sketchpad[sketchlevel] t)
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Tilings}
+% \label{sec:tilings}
+%
+% Colored drawing is available with \MP{} only:
+% \changes{v0.98}{1995/04/29}{Color support.}
+% \begin{macrocode}
+vardef cdraw expr p =
+%<mp> draw p withcolor foreground
+%<!mp> draw p
+enddef;
+vardef cfill expr p =
+%<mp> fill p withcolor foreground
+%<!mp> fill p
+enddef;
+vardef cfilldraw expr p =
+%<mp> filldraw p withcolor foreground
+%<!mp> filldraw p
+enddef;
+% \end{macrocode}
+% |autorounding| would disturb |cutdraw|.
+% \changes{v1.01}{1995/06/04}{%
+% No \texttt{autorounding} for \texttt{cutdraw}.}
+% \begin{macrocode}
+vardef ccutdraw expr p =
+%<mp> cutdraw p withcolor foreground
+%<!mp> interim autorounding := 0;
+%<!mp> cutdraw p
+enddef;
+vardef cdrawdot expr p =
+%<mp> drawdot p withcolor foreground
+%<!mp> drawdot p
+enddef;
+% \end{macrocode}
+%
+% \changes{v1.01}{1995/06/11}{Implement tilings.}
+% We also need some textprocessing tools. Here's a slow and portable
+% incarnation of |isdigit|:
+% \begin{macrocode}
+vardef isdigit expr s =
+ save n;
+ (s = "0")
+ for n = 1 upto 9:
+ or (s = decimal n)
+ endfor
+enddef;
+% \end{macrocode}
+% it is used in the next function, which return the interval of the
+% first digits after |start| in the string |s|:
+% \begin{macrocode}
+vardef digits_index (expr s, start) =
+ save n, m, from, to;
+ for n = start upto (length s)-1:
+ if isdigit (substring (n,n+1) of s):
+ from := n;
+ for m = n upto length s:
+ if not isdigit (substring (m,m+1) of s):
+ to := m;
+ fi
+ exitif known to;
+ endfor
+ fi
+ exitif known from;
+ endfor
+ (from, if known to: to else: infinity fi)
+enddef;
+% \end{macrocode}
+% The application is in this function, which takes a |suffix| and
+% returns it textual representation, with all sequences of digits
+% replaced by |[]|. We need it later, because declarations like
+% |picture foo1bar2;| are \emph{verboten} in \MF, they have to be
+% replaced by |picture foo[]bar[];|.
+% \begin{macrocode}
+vardef digits_to_brackets suffix suf =
+ save s, idx;
+ string s;
+ pair idx;
+ s = str suf;
+ idx = (0,0);
+ forever:
+ idx := digits_index (s, xpart idx);
+ exitif unknown xpart idx;
+ s := substring (0,xpart idx) of s
+ & "[]" & substring (ypart idx,infinity) of s;
+ endfor
+ s
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+tile_grain := 1in/300;
+% \end{macrocode}
+%
+% Declare a tile.
+% \begin{macrocode}
+vardef def_tile (suffix t) (expr wd, ht) =
+ if not picture tlist.t:
+ picture tlist.scantokens (digits_to_brackets t);
+ fi
+ tlist.t := nullpicture;
+ tlist.t.dx := max (floor wd, 1);
+ tlist.t.dy := max (floor ht, 1);
+enddef;
+% \end{macrocode}
+%
+% Use the tile |t| to tile a rectangle of width |wd| and height |ht|
+% with lower left corner at |(x,y)|. The upper and right boundaries
+% will be rounded to multiples of the tile size. Note that it is
+% vital for our clipping tricks that \emph{no} pixel gets a weight of
+% two or more!
+% \begin{macrocode}
+vardef use_tile (suffix t) (expr x, y, wd, ht) =
+%<*mp>
+ fill unitsquare xscaled wd yscaled ht shifted (x,y)
+ withcolor background;
+ if str t = "shaded":
+ shade_rectangle (4thin, x, y, wd, ht);
+ elseif str t = "hatched":
+ shade_rectangle (5thin, x, y, wd, ht);
+ shade_rectangle (-5thin, x, y, wd, ht);
+ else:
+%</mp>
+ if (picture tlist.t):
+ for nx = 0 upto wd/tlist.t.dx:
+ for ny = 0 upto ht/tlist.t.dy:
+ addto currentpicture
+ also (tlist.t shifted
+ ((x,y) + (nx*tlist.t.dx, ny*tlist.t.dy)) t_);
+ endfor
+ endfor
+ else:
+ errhelp "feynmf: your tiling has not been defined, "
+ & "check spelling and reprocess!";
+ errmessage "feynmf: tiling `" & str t & "' not known, "
+ & "replaced by `shaded'";
+ use_tile (shaded, x, y, wd, ht);
+ fi
+%<*mp>
+ fi
+%</mp>
+enddef;
+% \end{macrocode}
+% Shade a square enclosing the rectangle:
+% \begin{macrocode}
+vardef shade_rectangle (expr dd, x, y, wd, ht) =
+ save d, u, dx, dy, currentpen;
+ pen currentpen;
+ pickup pencircle scaled thin;
+ d := max (floor (abs dd), 1);
+ dx := max (wd, ht);
+ dy := max (wd, ht);
+ for u = 0 step d/dx until 1:
+ if dd > 0:
+ cdraw (x-d,y+u*dy-d)--(x+(1-u)*dx+d,y+dy+d);
+ cdraw (x+u*dx-d,y-d)--(x+dx+d,y+(1-u)*dy+d);
+ else:
+ cdraw (x-d,y+u*dy+d)--(x+u*dx+d,y-d);
+ cdraw (x+(1-u)*dx-d,y+dy+d)--(x+dx+d,y+(1-u)*dy-d);
+ fi
+ endfor
+enddef;
+% \end{macrocode}
+% Syntatic sugar:
+% \begin{macrocode}
+def addto_tile (suffix t) =
+ addto tlist.t
+enddef;
+% \end{macrocode}
+%
+% Construct a tile from a ASCII picture:
+% \begin{macrocode}
+vardef tile_from_string (suffix t) (expr str) =
+ tile_grain := max (floor tile_grain, 1);
+ save grain, mx, x, y, n, c, pic;
+ string c;
+ picture pic;
+ pic := nullpicture;
+ grain := tile_grain;
+ mx := 0;
+ x := 0;
+ y := 0;
+ for n := 1 upto length str:
+ c := substring (n-1,n) of str;
+ if c = "/":
+ mx := max (mx, x);
+ y := y+1;
+ x := 0;
+ elseif c = "*":
+ addto pic also (unitpixel shifted (x,-y) t_);
+ x := x+1;
+ elseif c = ".":
+ x := x+1;
+ fi
+ endfor
+ def_tile (t, grain*mx, grain*(y+1));
+ addto_tile (t) also (pic shifted (0,y) scaled grain t_);
+ pic := nullpicture;
+enddef;
+% \end{macrocode}
+%
+% Some standard tiles:
+% \begin{macrocode}
+tile_from_string (gray10,
+ " ... /"&
+ " .*. /"&
+ " ... ");
+% \end{macrocode}
+% \begin{macrocode}
+tile_from_string (gray25,
+ " .. /"&
+ " *. ");
+% \end{macrocode}
+% \begin{macrocode}
+tile_from_string (gray50,
+ " .* /"&
+ " *. ");
+% \end{macrocode}
+% \begin{macrocode}
+tile_from_string (gray75,
+ " ** /"&
+ " .* ");
+% \end{macrocode}
+% \begin{macrocode}
+tile_from_string (gray90,
+ " *** /"&
+ " *.* /"&
+ " *** ");
+% \end{macrocode}
+%
+% The |shaded| and |hatched| tiles are handled specially:
+% \begin{itemize}
+% \item{} the tiling approach is device dependent and diagonal lines
+% will not look nice if drawn to coarsely.
+% \item{} in \MP, we need to conserve memory, because the tiling
+% approach will quickly exceed \MP's main memory. The solution is
+% to intercept |use_tile|, as done above.
+% \end{itemize}
+% \begin{macrocode}
+%<*!mp>
+def_tile (shaded, 4thin, 4thin);
+pickup pencircle scaled thin;
+begin_sketch
+ save dx, dy;
+ (dx,dy) = (tlist.shaded.dx,tlist.shaded.dy);
+ shade_rectangle (dx, 0, 0, dx, dy);
+ cullit;
+ fill unitsquare xscaled dx yscaled dy;
+ cull currentpicture keeping (2,infinity);
+ tlist.shaded := currentpicture;
+end_sketch;
+% \end{macrocode}
+%
+% \begin{macrocode}
+def_tile (hatched, 5thin, 5thin);
+begin_sketch
+ save dx, dy;
+ (dx,dy) = (tlist.hatched.dx,tlist.hatched.dy);
+ shade_rectangle (dx, 0, 0, dx, dy);
+ shade_rectangle (-dx, 0, 0, dx, dy);
+ cullit;
+ fill unitsquare xscaled dx yscaled dy;
+ cull currentpicture keeping (2,infinity);
+ tlist.hatched := currentpicture;
+end_sketch;
+%</!mp>
+% \end{macrocode}
+%
+% Halftoning is tricky, this solution is not perfect yet. The idea is
+% to use highly nonlinear function for displacing adjacent, in order
+% to avoid regular patterns in thinly populated tiles. The random
+% number solution works somehow, but hand crafted regular patterns are
+% still superior.
+% \begin{macrocode}
+%<*!mp>
+vardef make_halftone (suffix t) (expr g, wd, ht) =
+ tile_grain := max (floor tile_grain, 1);
+ if (halftone_cache_g <> g)
+ or (halftone_cache_grain <> tile_grain)
+ or (halftone_cache_wd <> wd)
+ or (halftone_cache_ht <> ht):
+ halftone_cache_g := g;
+ halftone_cache_grain := tile_grain;
+ halftone_cache_wd := wd;
+ halftone_cache_ht := ht;
+ grain := tile_grain;
+ def_tile (t, grain*wd, grain*ht);
+ if g <= 0:
+ addto_tile (t) contour unitsquare xscaled wd yscaled ht scaled grain t_;
+ elseif g < 1:
+ save period, offset, b, w;
+ period := max (1/g, 1/(1-g));
+ offset := wd - (period * ceiling (wd/period)) mod wd;
+ b := 0;
+ w := 0;
+ randomseed := halftone_randomseed;
+ for y = 0 upto ht-1:
+ for x = 0 upto wd-1:
+ if w > g*(b+w):
+ addto_tile (t) also (unitpixel
+ shifted (floor (x + y*offset + 2*uniformdeviate period)
+ mod wd, y)
+ scaled grain t_);
+ b := b+1;
+ else:
+ w := w+1;
+ fi;
+ endfor
+ endfor
+ cull tlist.t keeping (1,infinity);
+ fi
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+halftone_cache_g := -1;
+halftone_cache_grain := -1;
+halftone_cache_wd := -1;
+halftone_cache_ht := -1;
+halftone_randomseed := 137;
+%</!mp>
+% \end{macrocode}
+% Halftoning is trivial in \MP:
+% \begin{macrocode}
+%<*mp>
+vardef make_halftone (suffix t) (expr g, wd, ht) =
+ def_tile (t, wd, ht);
+ addto tlist.t contour unitsquare
+ xscaled wd yscaled ht withcolor ((1-g)*foreground + g*background)
+enddef;
+%</mp>
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef tile (suffix t) (expr p) =
+ save u, x, y, max_x, min_x, max_y, min_y, xx, yy;
+ -max_x = -max_y = min_x = min_y = infinity;
+ for u = 0 step 0.1 until length p:
+ x := xpart (point u of p);
+ y := ypart (point u of p);
+ max_x := max(max_x, x);
+ max_y := max(max_y, y);
+ min_x := min(min_x, x);
+ min_y := min(min_y, y);
+ endfor
+%<*!mp>
+% \end{macrocode}
+% Give the already drawn parts a weight of 2. Then they will survive
+% along with the intersection of the tiling and the interior of the
+% path |p|:
+% \begin{macrocode}
+ cullit withweight 2;
+ use_tile (t, min_x, min_y, max_x-min_x, max_y-min_y);
+ fill p;
+ cull currentpicture keeping (2,infinity)
+%</!mp>
+%<*mp>
+ begin_sketch
+ use_tile (t, min_x, min_y, max_x-min_x, max_y-min_y);
+ clip currentpicture to p;
+ end_sketch;
+ use_sketch;
+%</mp>
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef drawtile (suffix t) (expr p) =
+ tile (t, p);
+ cdraw p
+enddef;
+% \end{macrocode}
+%
+% Use \MP's haltoning features (if available), because they are much
+% more efficient:
+% \begin{macrocode}
+%<*!mp>
+vardef use_halftone (expr g, x, y, wd, ht) =
+ make_halftone (__tmp_tile__, g, 50, 50);
+ use_tile (__tmp_tile__, x, y, wd, ht)
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef halftone (expr g, p) =
+ make_halftone (__tmp_tile__, g, 50, 50);
+ tile (__tmp_tile__, p)
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef drawhalftone (expr g, p) =
+ halftone (g, p);
+ cdraw p
+enddef;
+%</!mp>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*mp>
+vardef use_halftone (expr g, x, y, wd, ht) =
+ fill unitsquare xscaled wd yscaled ht
+ shifted (x,y) withcolor ((1-g)*foreground + g*background)
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef halftone (expr g, p) =
+ fill p withcolor ((1-g)*foreground + g*background)
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef drawhalftone (expr g, p) =
+ fill p withcolor ((1-g)*foreground + g*background);
+ cdraw p
+enddef;
+%</mp>
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef shade expr p =
+ tile (shaded, p)
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef hatch expr p =
+ tile (hatched, p)
+enddef;
+% \end{macrocode}
+%
+% Here come |filldraw|'s sisters:
+% \begin{macrocode}
+vardef emptydraw expr p =
+ cullit;
+ unfill p;
+ cullit;
+ cdraw p;
+enddef;
+vardef shadedraw expr p =
+ cullit;
+ unfill p;
+ cullit;
+ shade p;
+ cdraw p;
+enddef;
+vardef hatchdraw expr p =
+ cullit;
+ unfill p;
+ cullit;
+ hatch p;
+ cdraw p;
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Arrows}
+% \label{sec:arrows}
+%
+% John Hobby has a particulary nice |arrowhead| macro in plain \MP.
+% Some variations on that theme adapted to our needs are here.
+% \changes{v0.5}{1994/10/20}{New arrows, which look better on curved arcs.}
+% Firstly centered on fraction |frac| of |p|:
+% \changes{v0.99}{1995/05/04}{%
+% More general arrows \texttt{marrow}, \texttt{harrow} and
+% \texttt{tarrow} with reference
+% points in middle, at the head and at the tail, respectively.}
+% \begin{macrocode}
+vardef marrow (expr p, frac) =
+ save a, t, z;
+ pair z;
+ a = angle direction frac*length(p) of p;
+ z = point frac*length(p) of p;
+ (t1,whatever) = p intersectiontimes
+ (halfcircle scaled 2/3arrow_len rotated (a+90) shifted z);
+ (t2,whatever) = p intersectiontimes
+ (halfcircle scaled 4/3arrow_len rotated (a-90) shifted z);
+ arrow_head (p, t1, t2, arrow_ang)
+enddef;
+% \end{macrocode}
+% secondly with reference point at the tail:
+% \begin{macrocode}
+vardef tarrow (expr p, frac) =
+ save a, t, z;
+ pair z;
+ t1 = frac*length p;
+ a = angle direction t1 of p;
+ z = point t1 of p;
+ (t2,whatever) = p intersectiontimes
+ (halfcircle scaled 2arrow_len rotated (a-90) shifted z);
+ arrow_head (p, t1, t2, arrow_ang)
+enddef;
+% \end{macrocode}
+% and finally with reference point at the head:
+% \begin{macrocode}
+vardef harrow (expr p, frac) =
+ save a, t, z;
+ pair z;
+ t2 = frac*length p;
+ a = angle direction t2 of p;
+ z = point t2 of p;
+ (t1,whatever) = p intersectiontimes
+ (halfcircle scaled 2arrow_len rotated (a+90) shifted z);
+ arrow_head (p, t1, t2, arrow_ang)
+enddef;
+% \end{macrocode}
+% Construct an arrowhead on path |p|, ranging from |from| to |to| with
+% opening angle |ang|:
+% compatibility:
+% \begin{macrocode}
+vardef arrow_head (expr p, from, to, ang) =
+ save tip, ap, t;
+ pair tip;
+ path ap;
+ t1 := from;
+ t2 := to;
+% \end{macrocode}
+% |from| and |to| may come from an |intersectiontimes|. This
+% could have failed, typically if the path is too short: protect
+% against it.
+% \changes{v0.6}{1994/10/21}{Fix arrows on too short arcs.}
+% \begin{macrocode}
+ if t1 = -1: t1 := 0; fi
+ if t2 = -1: t2 := infinity; fi
+ tip = point t2 of p;
+ ap = subpath (t1,t2) of p shifted -tip;
+ (ap rotated ang
+ forced_join reverse ap rotated -ang
+ -- cycle) shifted tip
+enddef;
+% \end{macrocode}
+% The old, plainly centered |arrow|. Retain it for convenience and
+% compatibility:
+% \begin{macrocode}
+vardef arrow expr p =
+ marrow (p, .5)
+enddef;
+% \end{macrocode}
+% Join two paths |p| and |q| even if they don't fit exactly by
+% adjusting their common point. This is necessary in |arrow| because
+% rounding errors might induce a small mismatch even if we \emph{know}
+% that they should match theoretically. This is certainly a kludge
+% and should be used with care, but it works.
+% \begin{macrocode}
+tertiarydef p forced_join q =
+ subpath (0, length p - 1) of p
+ & point (length p - 1) of p
+ .. controls postcontrol (length p - 1) of p
+ and precontrol infinity of p
+ .. .5[point infinity of p, point 0 of q]
+ .. controls postcontrol 0 of q and precontrol 1 of q
+ .. point 1 of q
+ & subpath (1, infinity) of q
+enddef;
+% \end{macrocode}
+%
+% |cut_decors| expands to a subpath of |path_arg|, excluding the
+% decoration at the vertices.
+% \changes{v0.7}{1994/10/22}{Cut general vertex decorations.}
+% \changes{v0.9}{1995/04/25}{%
+% Fix \texttt{cut\_decors} to work with tadpoles.}
+% \begin{macrocode}
+vardef cut_decors (suffix from) (expr p) (suffix to) =
+ subpath (if known from.decor.shape:
+ xpart (p intersectiontimes
+ (from.decor.shape scaled from.decor.size
+ shifted from.loc))
+ else:
+ 0
+ fi,
+ if known to.decor.shape:
+ length p
+ - xpart (reverse p intersectiontimes
+ (to.decor.shape scaled to.decor.size
+ shifted to.loc))
+ else:
+ infinity
+ fi) of p
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Blobs}
+% \label{sec:blobs}
+%
+% The following functions are obsolete. We keep them for a couple of
+% releases but users should be aware that they can go away without any
+% warning!
+%
+% The function |make_blob| is the working horse of |draw_blob|.
+% \begin{macrocode}
+vardef make_blob (expr z_arg, diameter) =
+ save p,currentpen; path p; pen currentpen;
+ pickup pencircle scaled thick;
+ p = fullcircle scaled diameter shifted z_arg;
+ shadedraw p;
+enddef;
+% \end{macrocode}
+%
+% |draw_blob (pair_arg, diameter)| draws a shaded blob of diameter
+% |diameter| centered at |pair_arg|. The thickness of the border is
+% controlled by the global variable |thick|.
+%
+% Hint: It saves time to draw blobs of the same size in sequence.
+% \begin{macrocode}
+vardef draw_blob (expr z_arg, diameter) =
+ if sketched_blob_diameter <> diameter: % drawn lately?
+ begin_sketch make_blob (origin, diameter); end_sketch; % redo hard work!
+ sketched_blob_diameter:= diameter; % record it
+ fi
+ use_sketch shifted z_arg; % the easy way ...
+enddef;
+% \end{macrocode}
+%
+% |force_new_blob| forces the redrawing of a blob of the same diameter
+% (in case you only changed the shading parameters).
+% \begin{macrocode}
+def force_new_blob = sketched_blob_diameter := -1; enddef;
+force_new_blob; % initialize it.
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Drawing}
+% \label{sec:drawing}
+%
+% Easier than
+% \begin{equation}
+% \int_0^1 dt \left\vert\frac{dx(t)}{dt}\right\vert
+% \end{equation}
+% with the integrand the square root of a fourth order polynomial, but
+% sufficient for all practical purposes is
+% \begin{macrocode}
+vardef pixlen (expr p, n) =
+ for k=1 upto length(p): + segment_pixlen (subpath (k-1,k) of p, n) endfor
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef segment_pixlen (expr p, n) =
+ for k=1 upto n: + abs (point k/n of p - point (k-1)/n of p) endfor
+enddef;
+% \end{macrocode}
+%
+% |wiggly p| expands to a ``wiggled'' version of |p|. The
+% slope of the wiggles is controlled by the global variable |wiggle_slope|,
+% the length of the wiggles by the global variable |wiggly_len|.
+% \changes{v1.08}{1996/09/01}{%
+% \texttt{wiggly}: integer number of wiggles for full path instead of
+% each segment.}
+% \begin{macrocode}
+vardef wiggly expr p_arg =
+ save wpp;
+ numeric wpp;
+ wpp = ceiling (pixlen (p_arg, 10) / wiggly_len) / length p_arg;
+ for k=0 upto wpp*length(p_arg) - 1:
+ point k/wpp of p_arg
+ {direction k/wpp of p_arg rotated wiggly_slope} ..
+ point (k+.5)/wpp of p_arg
+ {direction (k+.5)/wpp of p_arg rotated - wiggly_slope} ..
+ endfor
+ if cycle p_arg: cycle else: point infinity of p_arg fi
+enddef;
+% \end{macrocode}
+%
+% |curly p| expands to a ``curly'' version of |p|. The
+% the length of the curls is controlled by the global variable
+% |curly_len|.
+% \changes{v1.08}{1996/09/01}{%
+% \texttt{curly}: integer number of curls for full path instead of
+% each segment.}
+% \begin{macrocode}
+vardef curly expr p =
+ save cpp;
+ numeric cpp;
+ cpp := ceiling (pixlen (p, 10) / curly_len) / length p;
+ if cycle p:
+ for k=0 upto cpp*length(p) - 1:
+ point (k+.33)/cpp of p
+ {direction (k+.33)/cpp of p rotated 90} ..
+ point (k-.33)/cpp of p
+ {direction (k-.33)/cpp of p rotated -90} ..
+ endfor
+ cycle
+ else:
+ point 0 of p
+ {direction 0 of p rotated -90} ..
+ for k=1 upto cpp*length(p) - 1:
+ point (k+.33)/cpp of p
+ {direction (k+.33)/cpp of p rotated 90} ..
+ point (k-.33)/cpp of p
+ {direction (k-.33)/cpp of p rotated -90} ..
+ endfor
+ point infinity of p
+ {direction infinity of p rotated 90}
+ fi
+enddef;
+% \end{macrocode}
+%
+% |zigzag p| expands to a ``zig-zag'' version of |p|. The
+% the length of the zags is controlled by the global variable
+% |zigzag_len|.
+% \changes{v0.9}{1995/04/26}{\texttt{zigzag}: new line style.}
+% \changes{v1.08}{1996/09/01}{%
+% \texttt{zigzag}: integer number of zigzacs for full path instead of
+% each segment.}
+% \begin{macrocode}
+vardef zigzag expr p =
+ save zpp;
+ numeric zpp;
+ zpp = ceiling (pixlen (p, 10) / zigzag_len) / length p;
+ if not cycle p:
+ point 0 of p --
+ fi
+ for k = 0 upto zpp*length(p) - 1:
+ point (k+1/3)/zpp of p shifted
+ (zigzag_width
+ * dir angle (direction (k+1/3)/zpp of p rotated 90)) --
+ point (k+2/3)/zpp of p shifted
+ (zigzag_width
+ * dir angle (direction (k+2/3)/zpp of p rotated -90)) --
+ endfor
+ if cycle p:
+ cycle
+ else:
+ point infinity of p
+ fi
+enddef;
+% \end{macrocode}
+%
+% An inventory of valid line styles is implemented as a hash table:
+% \begin{macrocode}
+save vsty_hash;
+% \end{macrocode}
+% This is a bit like |mode_def| in plain \MF{} but doesn't use an
+% array of available modes: |style_def "foo"| will define a macro
+% |draw_foo| drawing a line of a certain style along any given path:
+% \begin{macrocode}
+def style_def suffix s =
+ vsty_hash.s := 1;
+ expandafter quote vardef scantokens ("draw_" & str s)
+enddef;
+% \end{macrocode}
+%
+% Let \MF{} do the lookup: suffices
+% \begin{macrocode}
+vardef vsty_exists suffix s =
+ known vsty_hash.s
+enddef;
+% \end{macrocode}
+% an strings
+% \begin{macrocode}
+vardef valid_style expr s =
+ expandafter vsty_exists scantokens (s)
+enddef;
+% \end{macrocode}
+%
+% \changes{v0.8}{1994/11/21}{Enhance and streamline the line styles.}
+% |phantom| lines are simple, even with arrows.
+% \begin{macrocode}
+style_def phantom expr p =
+ \
+enddef;
+style_def phantom_arrow expr p =
+ cfill (arrow p);
+enddef;
+% \end{macrocode}
+% |plain| lines aren't harder.
+% \begin{macrocode}
+style_def plain expr p =
+ cdraw p;
+enddef;
+style_def plain_arrow expr p =
+ cdraw p;
+ cfill (arrow p);
+enddef;
+style_def dbl_plain expr p =
+ draw_double p;
+enddef;
+style_def dbl_plain_arrow expr p =
+ draw_double_arrow p;
+enddef;
+% \end{macrocode}
+% Wiggly lines use |wiggly| from above
+% \begin{macrocode}
+style_def wiggly expr p =
+ cdraw (wiggly p);
+enddef;
+style_def dbl_wiggly expr p =
+ draw_double (wiggly p);
+enddef;
+% \end{macrocode}
+% and curly lines use |curly| from above
+% \begin{macrocode}
+style_def curly expr p =
+ cdraw (curly p);
+enddef;
+style_def dbl_curly expr p =
+ draw_double (curly p);
+enddef;
+% \end{macrocode}
+% zig-zag ditto:
+% \begin{macrocode}
+style_def zigzag expr p =
+ cdraw (zigzag p);
+enddef;
+style_def dbl_zigzag expr p =
+ draw_double (zigzag p);
+enddef;
+% \end{macrocode}
+% |draw_dashes p| draws a dashed line on |p|
+% \changes{v0.4}{1994/05/27}{%
+% Rename the line style \texttt{dashed} to \texttt{dashes}, to avoid
+% a name clash with \MP.}
+% \changes{v1.08}{1996/09/01}{%
+% \texttt{dashes}, \texttt{dbl\_dashes}:
+% integer number of dashes for full path instead of each segment.}
+% \begin{macrocode}
+style_def dashes expr p =
+ save dpp;
+ numeric dpp;
+ dpp = ceiling (pixlen (p, 10) / dash_len) / length p;
+ for k=0 upto dpp*length(p) - 1:
+ cdraw point k/dpp of p ..
+ point (k+.5)/dpp of p;
+ endfor
+enddef;
+style_def dbl_dashes expr p =
+ save dpp;
+ numeric dpp;
+ dpp = ceiling (pixlen (p, 10) / dash_len) / length p;
+ for k=0 upto dpp*length(p) - 1:
+ draw_double point k/dpp of p ..
+ point (k+.5)/dpp of p;
+ endfor
+enddef;
+% \end{macrocode}
+% Draw arrows for doubled lines larger:
+% \changes{v1.06}{1995/05/29}{%
+% Draw larger arrows for doubled lines (scale factor 1.5).}
+% \begin{macrocode}
+style_def dbl_dashes_arrow expr p =
+ draw_dbl_dashes p;
+ shrink (1.5);
+ cfill (arrow p);
+ endshrink;
+enddef;
+style_def dashes_arrow expr p =
+ draw_dashes p;
+ cfill (arrow p);
+enddef;
+% \end{macrocode}
+%
+% |draw_dots p| draws a dotted line on |path_arg|
+% \changes{v0.4}{1994/05/27}{%
+% Rename the line style \texttt{dotted} to \texttt{dots}, to be
+% consistent with \texttt{dashes}.}
+% \changes{v1.08}{1996/09/01}{%
+% \texttt{dots}, \texttt{dbl\_dots}:
+% integer number of dots for full path instead of each segment.}
+% \begin{macrocode}
+style_def dots expr p =
+ save dpp;
+ numeric dpp;
+ dpp = ceiling (pixlen (p, 10) / dot_len) / length p;
+ for k=0 upto dpp*length(p):
+ cdrawdot point k/dpp of p;
+ endfor
+enddef;
+style_def dbl_dots expr p =
+ save dpp;
+ numeric dpp;
+ dpp = ceiling (pixlen (p, 10) / dot_len) / length p;
+ begingroup
+ save oldpen;
+ pen oldpen;
+ oldpen := currentpen;
+ pickup oldpen scaled 3; % draw a thick linn
+ for k=0 upto dpp*length(p):
+ cdrawdot point k/dpp of p;
+ endfor
+ pickup oldpen;
+ cullit;
+ for k=0 upto dpp*length(p):
+ undrawdot point k/dpp of p;
+ endfor
+ cullit; % and remove the stuffing
+ endgroup;
+enddef;
+style_def dbl_dots_arrow expr p =
+ draw_dbl_dots p;
+ shrink (1.5);
+ cfill (arrow p);
+ endshrink;
+enddef;
+style_def dots_arrow expr p =
+ draw_dots p;
+ cfill (arrow p);
+enddef;
+% \end{macrocode}
+%
+% |draw_double p| draws a double line.
+% \begin{macrocode}
+style_def double expr p =
+ save oldpen;
+ pen oldpen;
+ oldpen := currentpen;
+% \end{macrocode}
+% draw a thick linn
+% \begin{macrocode}
+ pickup oldpen scaled 3;
+ ccutdraw p;
+% \end{macrocode}
+% and remove the stuffing
+% \begin{macrocode}
+ pickup oldpen;
+ cullit; undraw p; cullit;
+enddef;
+style_def double_arrow expr p =
+ draw_double p;
+ shrink (1.5);
+ cfill (arrow p);
+ endshrink;
+enddef;
+% \end{macrocode}
+%
+% Old aliases:
+% \begin{macrocode}
+style_def vanilla expr p = draw_plain p enddef;
+style_def fermion expr p = draw_plain_arrow p enddef;
+style_def quark expr p = draw_plain_arrow p enddef;
+style_def electron expr p = draw_plain_arrow p enddef;
+style_def photon expr p = draw_wiggly p enddef;
+style_def boson expr p = draw_wiggly p enddef;
+style_def gluon expr p = draw_curly p enddef;
+style_def heavy expr p = draw_dbl_plain_arrow p enddef;
+style_def ghost expr p = draw_dots_arrow p enddef;
+style_def scalar expr p = draw_dashes_arrow p enddef;
+% \end{macrocode}
+% More old aliases:
+% \begin{macrocode}
+vardef fermion expr path_arg =
+ cfill (arrow (path_arg));
+ path_arg
+enddef;
+vardef photon expr path_arg =
+ wiggly path_arg
+enddef;
+vardef gluon expr path_arg =
+ curly path_arg
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Graphs of vertices}
+% \label{sec:graphs}
+%
+% Here is the fun part of \FMF: \emph{automagic} placement of
+% vertices.
+% \begin{macrocode}
+%tracingmacros:=1;
+%tracingonline:=1;
+tracingstats:=1;
+% \end{macrocode}
+%
+% You can say |vtracing:=true| to see what's going on.
+% \begin{macrocode}
+boolean vtracing;
+vtracing := false; % true
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Data structures}
+%
+% \DeleteShortVerb{\|}
+% \MakeShortVerb{\"}
+%
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|l|l|}\hline
+% Type & Name & Purpose \\\hline\hline
+% "numeric" & "vlist.first" & pointer to first vertex (usually 1) \\\hline
+% "numeric" & "vlist.last" & pointer to last vertex (starts with 0) \\\hline
+% "string" & "vlist["$i$"]name" & symbolic name of the vertex\\\hline
+% "pair" & "vlist["$i$"]loc" & position of the vertex \\\hline
+% "string" & "vlist["$i$"]lbl" & label \\\hline
+% "numeric" & "vlist["$i$"]lbl.ang" & angle \\\hline
+% "numeric" & "vlist["$i$"]lbl.dist" & distance \\\hline
+% "path" & "vlist["$i$"]decor.shape" & shape of decoration\\\hline
+% "numeric" & "vlist["$i$"]decor.size" & size of decoration\\\hline
+% "numeric" & "vlist["$i$"]decor.sty" & filling style of decoration\\\hline
+% "numeric" & "vlist["$i$"]decor.ang" & rotation angle\\\hline
+% "numeric" & "vlist["$i$"]fore" & foreground color\\\hline
+% "numeric" & "vlist["$i$"]back" & background color\\\hline
+% "numeric" & "vlist["$i$"]arc.first" & pointer to first arc \\\hline
+% "numeric" & "vlist["$i$"]arc.last" & pointer to last arc \\\hline
+% "numeric" & "vlist["$i$"]arc["$j$"]" & $j$th arc of the $i$th vertex \\\hline
+% "string" & "vlist["$i$"]arc["$j$"]sty" & style of the arc\\\hline
+% "numeric" & "vlist["$i$"]arc["$j$"]tns" & tension of the arc\\\hline
+% "string" & "vlist["$i$"]arc["$j$"]lsr" & left, straight, right\\\hline
+% "string" & "vlist["$i$"]arc["$j$"]lbl" & label\\\hline
+% "string" & "vlist["$i$"]arc["$j$"]lbl.side"& side of the label\\\hline
+% "numeric" & "vlist["$i$"]arc["$j$"]lbl.dist"& distance of the label\\\hline
+% "numeric" & "vlist["$i$"]arc["$j$"]tag" & tag \\\hline
+% "numeric" & "vlist["$i$"]arc["$j$"]wd" & width of the arc\\\hline
+% "color" & "vlist["$i$"]arc["$j$"]fore"& foreground color\\\hline
+% "color" & "vlist["$i$"]arc["$j$"]back"& background color\\\hline
+% "numeric" & "vlist["$i$"]constr.first" & first constraint \\\hline
+% "numeric" & "vlist["$i$"]constr.last" & last constraint \\\hline
+% "numeric" & "vlist["$i$"]constr["$j$"]" & constraint on $j$th arc \\\hline
+% "numeric" & "vlist["$i$"]poly.first" & \\\hline
+% "numeric" & "vlist["$i$"]poly.last" & \\\hline
+% "numeric" & "vlist["$i$"]poly["$j$"]" & \\\hline
+% "numeric" & "vlist["$i$"]poly["$j$"]idx"& \\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Vertex data structure}
+% \label{tab:VDS}
+% \end{table}
+%
+% \begin{table}[t]
+% \begin{center}
+% \begin{tabular}{|l|l|l|}\hline
+% Type & Name & Purpose \\\hline\hline
+% "numeric" & "plist.first" & pointer to first polygon (usually 1) \\\hline
+% "numeric" & "plist.last" & pointer to last polygon (starts with 0) \\\hline
+% "numeric" & "plist["$i$"]cnt" & number of edges\\\hline
+% "numeric" & "plist["$i$"]vtx["$j$"]" & pointer to the $j$th vertex\\\hline
+% "numeric" & "plist["$i$"]pull" & distortion\\\hline
+% "string" & "plist["$i$"]cona" & connector after\\\hline
+% "string" & "plist["$i$"]conb" & connector before\\\hline
+% "string" & "plist["$i$"]sty" & filling\\\hline
+% "string" & "plist["$i$"]lbl" & label\\\hline
+% "numeric" & "plist["$i$"]lbl.ang" & direction of the label\\\hline
+% "numeric" & "plist["$i$"]lbl.dist" & distance of the label\\\hline
+% "color" & "plist["$i$"]fore" & foreground color\\\hline
+% "color" & "plist["$i$"]back" & background color\\\hline
+% \end{tabular}
+% \end{center}
+% \caption{Polygon data structure}
+% \label{tab:PDS}
+% \end{table}
+%
+% \DeleteShortVerb{\"}
+% \MakeShortVerb{\|}
+%
+% The data structure for our graph is shown in
+% table~\ref{tab:VDS}\footnote{%
+% \begin{dubious}
+% \texttt{boolean vlist[i]arc[j]smooth} will indicate that this
+% arc belongs to a set of arcs which are to be smoothly connected.
+% The implementation will start by going to the strt of this set,
+% define a long smooth path and finally do the drawing on the
+% various subpaths.
+% \end{dubious}}.
+% \MF{} turns out to be quite powerful, providing such constructs
+% in an unconventional, but flexible and concise way. While we use
+% |save vhash| to forget all previously defined vertices, we leave
+% |vlist| alone, because we will know from $|vlist.last| <
+% |vlist.first|$ that it's empty. Note that we can't |vardef| this
+% because then the |save| would go inside a group.
+% \begin{macrocode}
+def vinit =
+ save vhash;
+ numeric vlist.first, vlist.last;
+ vlist.first := 1;
+ vlist.last := 0;
+ pair vlist[]loc;
+ numeric vlist[]decor.size, vlist[]decor.ang,
+ vlist[]arc.first, vlist[]arc.last,
+ vlist[]arc[], vlist[]arc[]lsr,
+ vlist[]arc[]tns, vlist[]arc[]lbl.dist,
+ vlist[]arc[]tag, vlist[]arc[]wd, vlist[]arc[]rub,
+ vlist[]constr.first, vlist[]constr.last,
+ vlist[]constr[], lambdax[][], lambday[][];
+ string vlist[]name, vlist[]lbl, vlist[]decor.sty,
+ vlist[]arc[]sty, vlist[]arc[]lbl, vlist[]arc[]lbl.side;
+ numeric vlist[]lbl.ang;
+ path vlist[]decor.shape;
+%<*mp>
+ color vlist[]fore, vlist[]back,
+ vlist[]arc[]fore, vlist[]arc[]back;
+%</mp>
+% \end{macrocode}
+% Data structures for polygons (cf.~table~\ref{tab:PDS}):
+% \changes{v1.06}{1996/05/24}{
+% New data structure \texttt{plist} and new entries
+% \texttt{vlist[]poly}.}
+% \begin{macrocode}
+ numeric plist.first, plist.last, plist[]cnt, plist[]vtx[],
+ plist[]pull, plist[]lbl.ang, plist[]lbl.dist;
+ string plist[]lbl, plist[]sty, plist[]cona, plist[]conb;
+ plist.first := 1;
+ plist.last := 0;
+ numeric vlist[]poly.first, vlist[]poly.last,
+ vlist[]poly[], vlist[]poly[]idx;
+ pair lambdap[][];
+%<mp> color plist[]fore, plist[]back;
+enddef;
+%</base>
+% \end{macrocode}
+% \begin{macro}{\fmfinit}
+% We can also ask for initialization explicitely from \TeX{} (usually
+% it is called implicitely by |\begin{fmfgraph}|). This flushes the
+% vertex table.
+% \begin{macrocode}
+%<style>\def\fmfinit{\fmfcmd{vinit;}}
+% \end{macrocode}
+% \end{macro}
+% Useful abstractions are: first for looping over all vertices
+% \begin{macrocode}
+%<*base>
+def vertices =
+ vlist.first upto vlist.last
+enddef;
+% \end{macrocode}
+% second for looping over all arcs of vertex |i|
+% \begin{macrocode}
+def varcs (text i) =
+ vlist[i]arc.first upto vlist[i]arc.last
+enddef;
+% \end{macrocode}
+% and finally for looping over all constraints of vertex |i|
+% \begin{macrocode}
+def vconstr (text i) =
+ vlist[i]constr.first upto vlist[i]constr.last
+enddef;
+% \end{macrocode}
+% \begin{macrocode}
+def polygons =
+ plist.first upto plist.last
+enddef;
+% \end{macrocode}
+% \begin{macrocode}
+def vpoly (text i) =
+ vlist[i]poly.first upto vlist[i]poly.last
+enddef;
+% \end{macrocode}
+% Entering vertices is simple, but note that we have to make
+% |vlist[|$i$|]loc| undefined, because it might be around from an
+% earlier character still.
+% \begin{macrocode}
+vardef venter suffix v =
+ if not vexists v:
+ vlist.last := vlist.last + 1;
+ vhash.v := vlist.last;
+ vlist[vhash.v]name := str v;
+ vlist[vhash.v]loc := (whatever,whatever);
+ vlist[vhash.v]arc.first := 1;
+ vlist[vhash.v]arc.last := 0;
+ vlist[vhash.v]constr.first := 1;
+ vlist[vhash.v]constr.last := 0;
+ vlist[vhash.v]lbl := "";
+ vlist[vhash.v]lbl.ang := whatever;
+ vlist[vhash.v]lbl.dist := 3thick;
+%<*mp>
+ vlist[vhash.v]fore := (whatever, whatever, whatever);
+ vlist[vhash.v]back := (whatever, whatever, whatever);
+%</mp>
+ vlist[vhash.v]poly.first := 1;
+ vlist[vhash.v]poly.last := 0;
+ fi
+enddef;
+% \end{macrocode}
+%
+% The next three \emph{are} trivial. Existence
+% \begin{macrocode}
+vardef vexists suffix v =
+ if known vhash.v: true else: false fi
+enddef;
+% \end{macrocode}
+% index
+% \begin{macrocode}
+vardef vlookup suffix v =
+ if vexists v: vhash.v else: 0 fi
+enddef;
+% \end{macrocode}
+% and location
+% \begin{macrocode}
+vardef vloc suffix v =
+ vlist[vlookup v]loc
+enddef;
+% \end{macrocode}
+% of vertices. We use |vhash.v| instead of |v| so that we can clear
+% the whole hash table with |save vhash|.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Constructing the graph}
+%
+% Connect the vertices in the list |vl| with lines of style |style|,
+% allocating them if necessary.
+% \begin{macrocode}
+vardef vconnect (expr linesty) (text vl) =
+ save from, nfrom, nto, nopt, sty;
+ numeric from, nfrom, nto, nopt;
+ string sty;
+ getopt (opt, linesty);
+ sty := opt[opt.first];
+ if known opt[opt.first]arg:
+ message "feynmf: line styles don't take arguments. "
+ & "Argument `" & opt[opt.first]arg & "' ignored.";
+ fi
+ opt.first := opt.first + 1;
+ forsuffixes to = vl:
+ venter to;
+ nto := vlookup to;
+ if known nfrom:
+% \end{macrocode}
+% Later, on page~\pageref{pg:vfreeze}, it will pay back to enter the
+% arc \emph{both} ways: incoming \emph{and}
+% outgoing:\label{pg:vconnect}
+% \begin{macrocode}
+ vlist[nfrom]arc.last := vlist[nfrom]arc.last + 1;
+ vlist[nfrom]arc[vlist[nfrom]arc.last] := nto;
+ vlist[nfrom]arc[vlist[nfrom]arc.last]tns := 1;
+% \end{macrocode}
+% But do not enter tadpoles twice.
+% \changes{v0.9}{1995/04/25}{Do not enter tadpoles twice.}
+% \begin{macrocode}
+ if nfrom <> nto:
+ vlist[nto]arc.last := vlist[nto]arc.last + 1;
+ vlist[nto]arc[vlist[nto]arc.last] := nfrom;
+ vlist[nto]arc[vlist[nto]arc.last]tns := 1;
+ fi
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lbl := "";
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side := "";
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist := 3thick;
+% \end{macrocode}
+% Handle options, starting with an option |tension|:
+% \begin{macrocode}
+ for nopt = opt.first upto opt.last:
+ if match_option (opt[nopt], "tension"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ vlist[nfrom]arc[vlist[nfrom]arc.last]tns);
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ vlist[nto]arc[vlist[nto]arc.last]tns);
+% \end{macrocode}
+% Handle |left|, |straight| and |right|, which ask for making a
+% halfcircle detour on the specified side or going straight. If given
+% an optional argument, the halfcircle is pulled in or pushed out,
+% according whether it is smaller or larger than 1.
+% \changes{v0.5}{1994/10/20}{Accept optional argument for detours.}
+% \begin{macrocode}
+ elseif match_option (opt[nopt], "left"):
+ if known opt[nopt]arg:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
+ := - scantokens (opt[nopt]arg);
+ else:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := -1;
+ fi
+ elseif match_option (opt[nopt], "straight"):
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 0;
+ ignore_argument (opt[nopt], opt[nopt]arg);
+ elseif match_option (opt[nopt], "right"):
+ if known opt[nopt]arg:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
+ := scantokens (opt[nopt]arg);
+ else:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 1;
+ fi
+% \end{macrocode}
+% Labels and which side they're on:
+% \begin{macrocode}
+ elseif match_option (opt[nopt], "label"):
+ get_argument (opt[nopt], opt[nopt]arg,
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lbl);
+ elseif match_option (opt[nopt], "label.side"):
+ get_argument (opt[nopt], opt[nopt]arg,
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side);
+ elseif match_option (opt[nopt], "label.dist"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist);
+% \end{macrocode}
+% Numeric tags for disambiguating multiple arcs:
+% \changes{v0.9}{1995/04/19}{%
+% \texttt{tag} option for \texttt{vconnect}.}
+% \begin{macrocode}
+ elseif match_option (opt[nopt], "tag"):
+ if known opt[nopt]arg:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]tag
+ := scantokens (opt[nopt]arg);
+ else:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]tag := 0;
+ fi
+% \end{macrocode}
+% Width and color:
+% \changes{v0.98}{1995/04/29}{Width and color.}
+% \begin{macrocode}
+ elseif match_option (opt[nopt], "width"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ vlist[nfrom]arc[vlist[nfrom]arc.last]wd);
+%<*mp>
+ elseif match_option (opt[nopt], "foreground"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ vlist[nfrom]arc[vlist[nfrom]arc.last]fore);
+ elseif match_option (opt[nopt], "background"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ vlist[nfrom]arc[vlist[nfrom]arc.last]back);
+%</mp>
+%<*!mp>
+ elseif match_option (opt[nopt], "foreground")
+ or match_option (opt[nopt], "background"):
+ message "feynmf: color available with MetaPost only!";
+%</!mp>
+ elseif match_option (opt[nopt], "rubout"):
+ if known opt[nopt]arg:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]rub
+ := scantokens (opt[nopt]arg);
+ else:
+ vlist[nfrom]arc[vlist[nfrom]arc.last]rub := 2;
+ fi
+% \end{macrocode}
+% Ignore bogus options:
+% \begin{macrocode}
+ else:
+ ignore_option (opt[nopt], opt[nopt]arg);
+ fi
+ endfor
+ handle_line_style (vlist[nfrom]arc[vlist[nfrom]arc.last]sty, sty);
+ vlist[nto]arc[vlist[nto]arc.last]lsr
+ := vlist[nfrom]arc[vlist[nfrom]arc.last]lsr;
+ fi
+% \end{macrocode}
+% Restart the loop:
+% \begin{macrocode}
+ nfrom := nto;
+ endfor
+enddef;
+% \end{macrocode}
+% \changes{v0.9}{1995/02/20}{Started collapsing duplicate code.}
+% Avoid entering invalid linestyles into the tables, because the
+% delayed evaluation will make errors harder to find (line numbers
+% will be wrong):
+% \begin{macrocode}
+vardef handle_line_style (suffix sty) (expr name) =
+ if valid_style name:
+ sty := name;
+ else:
+ errhelp "feynmf: your linestyle is not recognizable, "
+ & "check spelling and reprocess!";
+ errmessage "feynmf: line style `" & name & "' not known, "
+ & "replaced by `vanilla'";
+ sty := "vanilla";
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef get_argument (expr opt, arg) (suffix variable) =
+ if known arg:
+ variable := arg;
+ else:
+ message "feynmf: option `" & opt & "' needs an argument. Ignored.";
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef ignore_argument (expr opt, arg) =
+ if known arg:
+ message "feynmf: option `" & opt & "' doesn't take an argument. "
+ & "Argument `" & arg & "' ignored.";
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef ignore_option (expr opt, arg)=
+ if known arg:
+ message "feynmf: ignoring option " & opt & "=" & arg & ".";
+ else:
+ message "feynmf: ignoring option " & opt & ".";
+ fi
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmf}
+% \begin{macro}{\fmfn}
+% Since |vconnect| wil be the most frequent macro, we give it the
+% shortest \TeX{} command sequence:
+% \changes{v0.98}{1995/04/26}{%
+% Protect MF's namespace with double underscores.}
+% \changes{v0.98}{1995/04/26}{\texttt{\protect\bslash fmfn}: new command.}
+% \begin{macrocode}
+%<*style>
+\def\fmf#1#2{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vconnect ("\the\fmfbuf@", \fmfpfx{#2});}}
+\def\fmfn#1#2#3{
+ \fmfbuf@={#1}%
+ \fmfcmd{vconnectn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%<*base>
+vardef vconnectn (expr linesty) (suffix v) (expr n) =
+ vconnect (linesty, vmklist (v, n));
+enddef;
+% \end{macrocode}
+%
+% Here's how to deconstruct a graph: |vpath| returns an arc from
+% |nfrom| to |nto|, if any. If a suffix is given, it
+% has to match the |tag| of the arc.
+% \changes{v0.9}{1995/04/19}{%
+% \texttt{vpath}: new function.}
+% \changes{v0.9}{1995/04/20}{%
+% \texttt{vpath}: new syntax.}
+% \begin{macrocode}
+vardef vpath@# (suffix from, to) =
+ save nfrom, nto, origin, index, unknown_path;
+ numeric nfrom, nto, origin, index;
+ path unknown_path;
+ if (known vloc from) and (known vloc to):
+ nfrom := vlookup from;
+ nto := vlookup to;
+ vmatch_path (nfrom, nto, maybe_empty@#);
+ if (unknown origin) or (unknown index):
+ vmatch_path (nto, nfrom, maybe_empty@#);
+ fi
+ fi
+ if (known origin) and (known index):
+ vbuild_cut_arc (origin, index)
+ else:
+ unknown_path
+ fi
+enddef;
+% \end{macrocode}
+% Hack: this will expand to an |unknown| value if the suffix is empty
+% and to the suffix otherwise. We use it to implement an optional
+% argument.
+% \begin{macrocode}
+vardef maybe_empty@# =
+ save _prefix;
+ _prefix=137;
+ if known _prefix@#:
+ whatever
+ else:
+ @#
+ fi
+enddef;
+% \end{macrocode}
+% This is not a real function but a convenience macro and has the side
+% effect of setting |origin| and |index| if a match is found.
+% \begin{macrocode}
+vardef vmatch_path (expr nfrom, nto, t) =
+ save i;
+ for i = varcs (nfrom):
+ if (vlist[nfrom]arc[i] = nto) and (known vlist[nfrom]arc[i]sty):
+ if unknown t:
+ origin := nfrom;
+ index := i;
+ else:
+ if known vlist[nfrom]arc[i]tag:
+ if vlist[nfrom]arc[i]tag = t:
+ origin := nfrom;
+ index := i;
+ fi
+ fi
+ fi
+ fi
+ endfor
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vcyclen (expr sty) (suffix v) (expr n) =
+ for $ = 1 upto n - 1:
+ vconnect (sty, v[$], v[$+1]);
+ endfor
+ vconnect (sty, v[n], v[1]);
+enddef;
+% \end{macrocode}
+% And the reverse:
+% \begin{macrocode}
+vardef vrcyclen (expr sty) (suffix v) (expr n) =
+ vconnect (sty, v[1], v[n]);
+ for $ = n downto 2:
+ vconnect (sty, v[$], v[$-1]);
+ endfor
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfcyclen}
+% \begin{macrocode}
+%<*style>
+\def\fmfcyclen#1#2#3{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vcyclen ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
+\def\fmfrcyclen#1#2#3{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vrcyclen ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Constraints}
+%
+% \begin{macro}{\fmfforce}
+% \begin{macro}{\fmfshift}
+% Explicit placement and shifting of vertices is handled in \TeX{} with
+% \begin{macrocode}
+%<*style>
+\def\fmfforce#1#2{\fmfcmd{vforce ((#1), \fmfpfx{#2});}}
+\def\fmfshift#1#2{\fmfcmd{vshift ((#1), \fmfpfx{#2});}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Force the vertex |v| to be placed at position |z|:
+% \begin{macrocode}
+%<*base>
+vardef vforce (expr z) (suffix v) =
+ venter v;
+ vlist[vlookup v]loc := z;
+enddef;
+% \end{macrocode}
+%
+% Shift the vertex |v| by |z|:
+% \begin{macrocode}
+vardef vshift (expr z) (text vl) =
+ forsuffixes $=vl:
+ if vexists $:
+ vlist[vlookup $]loc := vlist[vlookup $]loc + z;
+ fi
+ endfor
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmffixed}
+% \begin{macro}{\fmffixedx}
+% \begin{macro}{\fmffixedy}
+% \changes{v0.8}{1995/01/07}{New command: \texttt{\protect\bslash fmffixed}.}
+% Place the first two arguments in the distance given by the third
+% argument.
+% \changes{v1.04}{1996/02/20}{%
+% \texttt{\protect\bslash fmffixedx},
+% \texttt{\protect\bslash fmffixedy}: new macros.}
+% \begin{macrocode}
+%<*style>
+\def\fmffixed#1#2{\fmfcmd{vconstraint ((#1), \fmfpfx{#2});}}
+\def\fmffixedx#1#2{\fmfcmd{vconstraint (((#1),whatever), \fmfpfx{#2});}}
+\def\fmffixedy#1#2{\fmfcmd{vconstraint ((whatever,(#1)), \fmfpfx{#2});}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% This amounts to adding one or more constraints into the vertex data
+% structure:
+% \begin{macrocode}
+%<*base>
+vardef vconstraint (expr z) (text vl) =
+ save nfrom, nto;
+ numeric nfrom, nto;
+ forsuffixes to = vl:
+ venter to;
+ nto := vlookup to;
+ if known nfrom:
+ vlist[nfrom]constr.last := vlist[nfrom]constr.last + 1;
+ vlist[nto]constr.last := vlist[nto]constr.last + 1;
+ vlist[nfrom]constr[vlist[nfrom]constr.last] := nto;
+ vlist[nto]constr[vlist[nto]constr.last] := nfrom;
+ vlist[nto]loc = vlist[nfrom]loc + z;
+ fi
+ nfrom := nto;
+ endfor
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Polygons}
+%
+% Define a polygon:
+% \changes{v1.06}{1996/05/24}{
+% New function \texttt{vpolygon}: allocate a polygon.}
+% \begin{macrocode}
+vardef vpolygon (expr psty) (suffix v) (text vl) =
+ save nopt, csty, nfrom, nfrom_, nto, i, n, j;
+ numeric nopt, nfrom, nfrom_, nto, i, n, j;
+ string csty;
+% \end{macrocode}
+% Allocate a fresh polygon:
+% \begin{macrocode}
+ n := count (vl) + 1;
+ plist.last := plist.last + 1;
+ plist[plist.last]cnt := n;
+ plist[plist.last]lbl := "";
+ plist[plist.last]lbl.ang := whatever;
+ plist[plist.last]lbl.dist := 0;
+% \end{macrocode}
+% Parse the options:
+% \begin{macrocode}
+ csty := "phantom";
+ getopt (opt, psty);
+ for nopt = opt.first upto opt.last:
+ if match_option (opt[nopt], "filled"):
+ get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]sty);
+ elseif match_option (opt[nopt], "tension"):
+ if known opt[nopt]arg:
+ csty := csty & ",tension=" & opt[nopt]arg;
+ else:
+ message "feynmf: option `tension' needs an argument. Ignored.";
+ fi
+ elseif match_option (opt[nopt], "label"):
+ get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]lbl);
+ elseif match_option (opt[nopt], "label.angle"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ plist[plist.last]lbl.ang);
+ elseif match_option (opt[nopt], "label.dist"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ plist[plist.last]lbl.dist);
+ elseif match_option (opt[nopt], "pull"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ plist[plist.last]pull);
+ elseif match_option (opt[nopt], "cona"):
+ get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]cona);
+ elseif match_option (opt[nopt], "conb"):
+ get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]conb);
+ elseif match_option (opt[nopt], "smooth"):
+ plist[plist.last]cona := "..";
+ plist[plist.last]conb := "..";
+ ignore_argument (opt[nopt], opt[nopt]arg);
+%<*mp>
+ elseif match_option (opt[nopt], "foreground"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ plist[plist.last]fore);
+ elseif match_option (opt[nopt], "background"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg),
+ plist[plist.last]back);
+%</mp>
+%<*!mp>
+ elseif match_option (opt[nopt], "foreground")
+ or match_option (opt[nopt], "background"):
+ message "feynmf: color available with MetaPost only!";
+%</!mp>
+ elseif match_option (opt[nopt], "phantom"):
+ plist[plist.last]sty := "phantom";
+ elseif match_option (opt[nopt], "empty"):
+ plist[plist.last]sty := "empty";
+ elseif match_option (opt[nopt], "full"):
+ plist[plist.last]sty := "full";
+ elseif match_option (opt[nopt], "hatched"):
+ plist[plist.last]sty := "hatched";
+ elseif match_option (opt[nopt], "shaded"):
+ plist[plist.last]sty := "shaded";
+ else:
+ ignore_option (opt[nopt], opt[nopt]arg);
+ fi
+ endfor
+ canonicalize_filling plist[plist.last]sty;
+% \end{macrocode}
+% Enter the vertices:
+% \begin{macrocode}
+ vconnect (csty, v, vl, v);
+ i := 1;
+ forsuffixes to = v, vl, v:
+ nto := vlookup to;
+ if known nfrom:
+% \end{macrocode}
+% Enter a constraint:
+% \begin{equation}
+% \vec v_{i+1} = \vec v_{i}
+% + R(2\pi/n_P) \left( \vec v_{i} - \vec v_{i-1} \right)
+% \end{equation}
+% \begin{macrocode}
+ if known nfrom_:
+ vlist[nto]loc = vlist[nfrom]loc
+ + (vlist[nfrom]loc - vlist[nfrom_]loc) rotated (360/n);
+ fi
+ vlist[nto]poly.last := vlist[nto]poly.last + 1;
+ vlist[nto]poly[vlist[nto]poly.last] := plist.last;
+ vlist[nto]poly[vlist[nto]poly.last]idx := i;
+ plist[plist.last]vtx[i] := nto;
+ i := i + 1;
+ nfrom_ := nfrom;
+ fi
+ nfrom := nto;
+ endfor
+enddef;
+% \end{macrocode}
+%
+% \changes{v1.06}{1996/05/24}{
+% New function \texttt{canonicalize\_filling}: abstracted from
+% \texttt{vvertex}.}
+% \begin{macrocode}
+vardef canonicalize_filling suffix f =
+ if known f:
+ if is_a_number (f):
+ if scantokens f <= 1:
+ f :=
+ if scantokens f = 1:
+ "full"
+ elseif scantokens f > 0:
+ "shaded"
+ elseif scantokens f = 0:
+ "empty"
+ else:
+ "hatched"
+ fi;
+ fi
+ fi
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vpolygonn (expr sty) (suffix v) (expr n) =
+ vpolygon (sty, v[1], for $=2 upto n-1: v[$], endfor v[n]);
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vrpolygonn (expr sty) (suffix v) (expr n) =
+ vpolygon (sty, v[n], for $=n-1 downto 2: v[$], endfor v[1]);
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfpoly}
+% \begin{macro}{\fmfpolyn}
+% \begin{macro}{\fmfrpolyn}
+% \changes{v1.06}{1996/05/24}{%
+% New macros \texttt{\protect\bslash fmfpoly}
+% \texttt{\protect\bslash fmfpolyn},
+% \texttt{\protect\bslash fmfrpolyn}.}
+% \begin{macrocode}
+%<*style>
+\def\fmfpoly#1#2{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vpolygon ("\the\fmfbuf@", \fmfpfx{#2});}}
+\def\fmfpolyn#1#2#3{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vpolygonn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
+\def\fmfrpolyn#1#2#3{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vrpolygonn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Internal vertices}
+%
+% \begin{macro}{\fmflabel}
+% \begin{macrocode}
+\def\fmflabel#1#2{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vlabel ("\the\fmfbuf@", \fmfpfx{#2});}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%<*base>
+vardef vlabel (expr s) (suffix v) =
+ venter v;
+ vlist[vlookup v]lbl := s;
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfv}
+% \begin{macrocode}
+%<*style>
+\def\fmfv#1#2{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vvertex ("\the\fmfbuf@", \fmfpfx{#2});}}
+\def\fmfvn#1#2#3{%
+ \fmfbuf@={#1}%
+ \fmfcmd{vvertexn ("\the\fmfbuf@", \fmfpfx{#2}, #3);}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+%
+% \changes{v0.7}{1994/10/22}{%
+% \texttt{blob} and \texttt{dot} options obsolete, handle generalized
+% decorations (polygons).}
+% \begin{macrocode}
+%<*base>
+vardef vvertex (expr vtxsty) (text vl) =
+ save nopt, sty, arg;
+ numeric nopt, arg;
+ string sty;
+ getopt (opt, vtxsty);
+ forsuffixes v = vl:
+ venter v;
+ n := vlookup v;
+ for nopt = opt.first upto opt.last:
+ handle_vertex_option (vlist[n], opt[nopt], opt[nopt]arg);
+ endfor
+ endfor
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef handle_vertex_option (suffix v) (expr opt, arg) =
+ if match_option (opt, "label"):
+ get_argument (opt, arg, v.lbl);
+ elseif match_option (opt, "label.angle"):
+ get_argument (opt, scantokens (arg), v.lbl.ang);
+ elseif match_option (opt, "label.dist"):
+ get_argument (opt, scantokens (arg), v.lbl.dist);
+ elseif match_option (opt, "decoration.shape"):
+ if known arg:
+ make_decor_shape (v.decor.shape, arg);
+ else:
+ message "feynmf: option `decor.shape' needs an argument. Ignored.";
+ fi
+% \end{macrocode}
+% \MP{} has |filled| reserved, use |sty| instead.
+% \begin{macrocode}
+ elseif match_option (opt, "decoration.filled"):
+ get_argument (opt, arg, v.decor.sty);
+% \end{macrocode}
+% Continue to support the old numeric argument:
+% \begin{macrocode}
+ canonicalize_filling v.decor.sty;
+ elseif match_option (opt, "decoration.size"):
+ get_argument (opt, scantokens (arg), v.decor.size);
+ elseif match_option (opt, "decoration.angle"):
+ get_argument (opt, scantokens (arg), v.decor.ang);
+%<*mp>
+ elseif match_option (opt, "foreground"):
+ get_argument (opt, scantokens (arg), v.fore);
+ elseif match_option (opt, "background"):
+ get_argument (opt, scantokens (arg), v.back);
+%</mp>
+%<*!mp>
+ elseif match_option (opt, "foreground")
+ or match_option (opt, "background"):
+ message "feynmf: color available with MetaPost only!";
+%</!mp>
+% \end{macrocode}
+% Ignore bogus options:
+% \begin{macrocode}
+ else:
+ ignore_option (opt, arg);
+ fi
+enddef;
+% \end{macrocode}
+% Maybe we should replace this long switch by a hashing scheme:
+% \begin{macrocode}
+vardef make_decor_shape (suffix p) (expr n) =
+ if match_prefix (n, "circle"): p := fullcircle;
+ elseif match_prefix (n, "square"):
+ p := unitsquare shifted -(.5,.5);
+ elseif match_prefix (n, "cross"): p := polycross 4;
+ elseif match_prefix (n, "triangle"): p := polygon 3;
+ elseif match_prefix (n, "triagon"): p := polygon 3;
+ elseif match_prefix (n, "diamond"): p := polygon 4;
+ elseif match_prefix (n, "tetragon"): p := polygon 4;
+ elseif match_prefix (n, "pentagon"): p := polygon 5;
+ elseif match_prefix (n, "hexagon"): p := polygon 6;
+ elseif match_prefix (n, "triagram"): p := polygram 3;
+ elseif match_prefix (n, "tetragram"): p := polygram 4;
+ elseif match_prefix (n, "pentagram"): p := polygram 5;
+ elseif match_prefix (n, "hexagram"): p := polygram 6;
+ elseif match_prefix (n, "triacross"): p := polycross 3;
+ elseif match_prefix (n, "tetracross"): p := polycross 4;
+ elseif match_prefix (n, "pentacross"): p := polycross 5;
+ elseif match_prefix (n, "hexacross"): p := polycross 6;
+ else:
+ if feynmfwizard:
+ p := scantokens(n);
+ else:
+ message "feynmf: invalid argument `" & n
+ & "' to option `decor.shape'. Ignored.";
+ fi
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef is_a_number expr s =
+ save n;
+ if known s:
+ (true
+ for n = 1 upto length s:
+ and ((substring (n-1,n) of s = ".")
+ or (substring (n-1,n) of s = "-")
+ or isdigit substring (n-1,n) of s)
+ endfor)
+ else:
+ false
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vvertexn (expr vtxsty) (suffix v) (expr n) =
+ vvertex (vtxsty, vmklist (v, n));
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfblob}
+% \begin{macro}{\fmfdot}
+% We can decorate vertices with ``blobs'' and dots from \TeX{} with
+% the command sequences:
+% \begin{macrocode}
+%<style>\def\fmfblob#1#2{\fmfcmd{vblob ((#1), \fmfpfx{#2});}}
+%<style>\def\fmfdot#1{\fmfcmd{vdot (\fmfpfx{#1});}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% The vertices in the list |vl| will be drawn with a blob of diameter
+% |bd|:
+% \begin{macrocode}
+%<*base>
+vardef vblob (expr bd) (text vl)=
+ forsuffixes $=vl:
+ if not vexists $: venter $; fi
+ vlist[vlookup $]decor.shape := fullcircle;
+ vlist[vlookup $]decor.size := bd;
+ vlist[vlookup $]decor.sty := "shaded";
+ endfor
+enddef;
+% \end{macrocode}
+%
+% The vertices in the list |vl| will be drawn with a dot.
+% \begin{macrocode}
+vardef vdot (text vl)=
+ forsuffixes $=vl:
+ if not vexists $: venter $; fi
+ vlist[vlookup $]decor.shape := fullcircle;
+ vlist[vlookup $]decor.size := dot_size;
+ vlist[vlookup $]decor.sty := "full";
+ endfor
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vdotn (suffix v) (expr n) =
+ vdot (vmklist (v, n));
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vblobn (suffix v) (expr n) =
+ vblob (vmklist (v, n));
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfdotn}
+% Place |#2| blobs or dots at $|v|_1,\ldots,|v|_{|#1|}$.
+% \begin{macrocode}
+%<style>\def\fmfblobn#1#2{\fmfcmd{vblobn (\fmfpfx{#1}, #2);}}
+%<style>\def\fmfdotn#1#2{\fmfcmd{vdotn (\fmfpfx{#1}, #2);}}
+% \end{macrocode}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{External vertices}
+%
+% \begin{macro}{\fmfleft}
+% \begin{macro}{\fmfright}
+% \begin{macro}{\fmfbottom}
+% \begin{macro}{\fmftop}
+% \begin{macro}{\fmfsurround}
+% External vertices are positioned thusly in \TeX{}:
+% \changes{v0.8}{1994/10/27}{%
+% Make \texttt{\protect\bslash fmfincoming} and
+% \texttt{\protect\bslash fmfoutgoing} obsolescent.
+% Provide \texttt{\protect\bslash fmfleft},
+% \texttt{\protect\bslash fmfright},
+% \texttt{\protect\bslash fmfbottom}
+% and \texttt{\protect\bslash fmftop} instead.}
+% \changes{v0.8}{1994/12/29}{Fix typos in
+% \texttt{\protect\bslash fmfbottom}
+% and \texttt{\protect\bslash fmftop}.}
+% \begin{macrocode}
+%<*style>
+\def\fmfleft#1{\fmfcmd{vleft (\fmfpfx{#1});}}
+\def\fmfright#1{\fmfcmd{vright (\fmfpfx{#1});}}
+\def\fmfbottom#1{\fmfcmd{vbottom (\fmfpfx{#1});}}
+\def\fmftop#1{\fmfcmd{vtop (\fmfpfx{#1});}}
+\let\fmfincoming\fmfleft
+\let\fmfoutgoing\fmfright
+\def\fmfsurround#1{\fmfcmd{vsurround (\fmfpfx{#1});}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% Here are the ``galleries'' we're hooking our external vertices on
+% (see figure~\ref{fig:curvedgalleries}):
+% \changes{v0.99}{1995/05/04}{%
+% Adjust galleries to subgraphs.}
+% \begin{macrocode}
+%<*base>
+vardef curved_left_gallery = .9[se,sw] .. .5[sw,nw] .. .1[nw,ne] enddef;
+vardef curved_right_gallery = .9[sw,se] .. .5[se,ne] .. .1[ne,nw] enddef;
+vardef curved_bottom_gallery = .9[nw,sw] .. .5[sw,se] .. .1[se,ne] enddef;
+vardef curved_top_gallery = .9[sw,nw] .. .5[nw,ne] .. .1[ne,se] enddef;
+vardef curved_surround_gallery =
+ superellipse (.5[se,ne], .5[ne,nw], .5[nw,sw], .5[sw,se], .75)
+enddef;
+% \end{macrocode}
+% Here are their straight brothers (see
+% figure~\ref{fig:straightgalleries}):
+% \begin{macrocode}
+vardef straight_left_gallery = sw -- nw enddef;
+vardef straight_right_gallery = se -- ne enddef;
+vardef straight_bottom_gallery = sw -- se enddef;
+vardef straight_top_gallery = nw -- ne enddef;
+vardef straight_surround_gallery =
+ .5[se,ne] -- ne -- .5[ne,nw] -- nw
+ -- .5[nw,sw] -- sw -- .5[sw,se] -- se -- cycle
+enddef;
+% \end{macrocode}
+% And here's how to switch:
+% \begin{macrocode}
+vardef curved_galleries =
+ vardef left_gallery = curved_left_gallery enddef;
+ vardef right_gallery = curved_right_gallery enddef;
+ vardef bottom_gallery = curved_bottom_gallery enddef;
+ vardef top_gallery = curved_top_gallery enddef;
+ vardef surround_gallery = curved_surround_gallery enddef;
+enddef;
+vardef straight_galleries =
+ vardef left_gallery = straight_left_gallery enddef;
+ vardef right_gallery = straight_right_gallery enddef;
+ vardef bottom_gallery = straight_bottom_gallery enddef;
+ vardef top_gallery = straight_top_gallery enddef;
+ vardef surround_gallery = straight_surround_gallery enddef;
+enddef;
+% \end{macrocode}
+% The \MF{} code which does the hard work for the above
+% \TeX{} macros
+% \begin{macrocode}
+vardef vleft (text vl) = vdistribute (left_gallery, vl) enddef;
+vardef vright (text vl) = vdistribute (right_gallery, vl) enddef;
+vardef vbottom (text vl) = vdistribute (bottom_gallery, vl) enddef;
+vardef vtop (text vl) = vdistribute (top_gallery, vl) enddef;
+vardef vsurround (text vl) = vdistribute (surround_gallery, vl) enddef;
+% \end{macrocode}
+%
+% Curved galleries are the default
+% \begin{macrocode}
+curved_galleries;
+%</base>
+% \end{macrocode}
+% \begin{macro}{\fmfcurved}
+% \begin{macro}{\fmfstraight}
+% but here's how to switch:
+% \changes{v0.98}{1995/04/29}{shortened galleries switch.}
+% \begin{macrocode}
+%<*style>
+\def\fmfcurved{\fmfcmd{curved_galleries;}}
+\def\fmfstraight{\fmfcmd{straight_galleries;}}
+\let\fmfcurvedgalleries\fmfcurved
+\let\fmfstraightgalleries\fmfstraight
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Distribute the vertices in the list |vl| evenly along the path |p|:
+% \begin{macrocode}
+%<*base>
+vardef vdistribute (expr p) (text vl) =
+ save numv, len, off;
+ numeric numv, len, off;
+ numv = count (vl);
+% \end{macrocode}
+% If the path is cyclic, place the first vertex twice:
+% \begin{macrocode}
+ if cycle p: numv := numv + 1; fi
+ len := length (p);
+ if numv = 1:
+ vforce (point len/2 of p, vl);
+ else:
+ off := 0;
+ forsuffixes $ = vl:
+ vforce (point off of p, $);
+ off := off + len/(numv-1);
+ endfor
+ fi
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfleftn}
+% \begin{macro}{\fmfrightn}
+% \begin{macro}{\fmfbottomn}
+% \begin{macro}{\fmftopn}
+% \begin{macro}{\fmfsurroundn}
+% A short cut:
+% \begin{macrocode}
+%<*style>
+\def\fmfleftn#1#2{\fmfcmd{vleftn (\fmfpfx{#1}, #2);}}
+\def\fmfrightn#1#2{\fmfcmd{vrightn (\fmfpfx{#1}, #2);}}
+\def\fmfbottomn#1#2{\fmfcmd{vbottomn (\fmfpfx{#1}, #2);}}
+\def\fmftopn#1#2{\fmfcmd{vtopn (\fmfpfx{#1}, #2);}}
+\let\fmfincomingn\fmfleftn
+\let\fmfoutgoingn\fmfrightn
+\def\fmfsurroundn#1#2{\fmfcmd{vsurroundn (\fmfpfx{#1}, #2);}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%<*base>
+def vmklist (suffix v) (expr n) =
+ for $ = 1 upto n-1: v[$], endfor v[n]
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vleftn (suffix v) (expr n) =
+ vleft (vmklist (v, n));
+enddef;
+vardef vrightn (suffix v) (expr n) =
+ vright (vmklist (v, n));
+enddef;
+vardef vbottomn (suffix v) (expr n) =
+ vbottom (vmklist (v, n));
+enddef;
+vardef vtopn (suffix v) (expr n) =
+ vtop (vmklist (v, n));
+enddef;
+vardef vsurroundn (suffix v) (expr n) =
+ vsurround (vmklist (v, n));
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmffor}
+% \begin{macro}{\endfmffor}
+% \begin{macrocode}
+%<*style>
+\def\fmffor#1#2#3#4{\fmfcmd{for #1 = #2 step #3 until #4:}}
+\def\endfmffor{\fmfcmd{endfor}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fmfgroup}
+% \begin{macro}{\endfmfgroup}
+% Syntactic sugar:
+% \changes{v0.98}{1995/04/29}{\texttt{fmfgroup}: new environment.}
+% \begin{macrocode}
+\def\fmfgroup{\fmfcmd{begingroup}}
+\def\endfmfgroup{\fmfcmd{endgroup;}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fmfset}
+% \changes{v0.98}{1995/04/29}{%
+% \texttt{\protect\bslash fmfset}: new command.}
+% \begin{macrocode}
+\def\fmfset#1#2{\fmfcmd{save #1; #1:=#2;}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Choosing a layout for the graph}
+%
+% The procedure |vfreeze| is called near the end and
+% chooses ``optimal'' vertex positions by minimizing the sum of the
+% weighted lengths of the arcs. Since the quantity to be optimized is
+% quadratic in the vertices
+% \begin{equation}
+% L = \frac{1}{2} \sum_i \sum_{j\in\alpha(i)}
+% t_{ij} (\vec v_i - \vec v_j)^2\,,
+% \end{equation}
+% where~$\alpha(i)$ denotes the set of vertices connectes with the
+% vertex~$i$, we just have to solve a system of linear equations.
+% Adding Lagrange multipliers~$\lambda_{ij}$ for the constraints that
+% have been specified
+% \begin{equation}
+% \Lambda = \sum_i \sum_{j\in\gamma(i) \atop j>i}
+% \vec\lambda_{ij}\cdot(\vec v_i - \vec v_j - \vec d_{ij})\,,
+% \end{equation}
+% where~$\gamma(i)$ denotes the set of vertices which have a fixed
+% distance to the vertex~$i$, the set of linear equations is given by
+% \begin{eqnarray}
+% 0 & = & \frac{\partial}{\partial \vec v_i} (L+\Lambda)
+% = \sum_{j\in\alpha(i)} t_{ij} (\vec v_i - \vec v_j)
+% + \sum_{j\in\gamma(i) \atop j>i} \vec\lambda_{ij}
+% - \sum_{j\in\gamma(i) \atop j<i} \vec\lambda_{ji} \\
+% 0 & = & \vec v_i - \vec v_j - \vec d_{ij}\;\; \mid j \in \gamma(i)\,.
+% \end{eqnarray}
+% The implementation is simple: loop over all vertices in |vlist[]|
+% \begin{macrocode}
+%<*base>
+vardef vfreeze =
+ for i = vertices:
+% \end{macrocode}
+% and iff the position of the vertex has not been fixed yet, add
+% another equation. Note that each arc enters twice (incoming
+% \emph{and} outgoing) in this procedure. Thus it is easiest to store
+% them \emph{both} ways in the |vlist| structure
+% (cf.~page~\pageref{pg:vconnect})\label{pg:vfreeze}.
+% \begin{macrocode}
+ if unknown vlist[i]loc:
+ origin = origin
+ for j = varcs (i):
+ + vlist[i]arc[j]tns * (vlist[i]loc - vlist[vlist[i]arc[j]]loc)
+ endfor
+ for j = vconstr (i):
+ if i < vlist[i]constr[j]:
+ + lambda (i, vlist[i]constr[j])
+ elseif i > vlist[i]constr[j]:
+ - lambda (vlist[i]constr[j], i)
+ fi
+ endfor
+ for j = vpoly (i):
+ + lambdapoly (vlist[i]poly[j], plist[vlist[i]poly[j]]cnt,
+ vlist[i]poly[j]idx)
+ endfor;
+ fi
+ endfor
+% \end{macrocode}
+% Inquiring minds might want to see the result in numbers:
+% \begin{macrocode}
+ if vtracing: vdump; fi
+enddef;
+% \end{macrocode}
+% Separate Langrange multipliers for~$x$ and~$y$:
+% \changes{v1.04}{1996/02/20}{%
+% Have separate Langrange multipliers for~$x$ and~$y$.}
+% \begin{macrocode}
+vardef lambda (expr i, j) =
+ (if known (xpart(vlist[i]loc - vlist[j]loc)):
+ lambdax[i][j]
+ else:
+ 0
+ fi,
+ if known (ypart(vlist[i]loc - vlist[j]loc)):
+ lambday[i][j]
+ else:
+ 0
+ fi)
+enddef;
+% \end{macrocode}
+%
+% The Lagrange multiplier for a polynomial~$P$
+% \begin{equation}
+% \Lambda_P = \sum_{i=2}^{n_P} \vec\lambda_{P,i}
+% \left( \vec v_{i+1} - \vec v_i
+% + R(2\pi/n_P) \left( \vec v_{i-1} - \vec v_i \right)
+% \right)
+% \end{equation}
+% can be reshuffled trivially
+% \begin{eqnarray}
+% \Lambda_P & = &
+% \vec\lambda_{n-1} \vec v_{n}
+% - \vec\lambda_1 \vec v_2
+% + \vec\lambda_2 R(2\pi/n_P) \vec v_1
+% - \vec\lambda_n R(2\pi/n_P) \vec v_{n-1} \\
+% & & \mbox{} + \sum_{i=2}^{n_P}
+% \left( \vec\lambda_{i-1} + \vec\lambda_{i+1} R(2\pi/n_P)
+% - \vec\lambda_i (1 + R(2\pi/n_P)) \right) \vec v_i
+% \nonumber
+% \end{eqnarray}
+% \changes{v1.06}{1996/05/24}{
+% New function \texttt{lambdapoly}: Lagrange multipliers for
+% polygons.}
+% \begin{macrocode}
+vardef lambdapoly (expr p, n, i) =
+ origin
+ if i = 1:
+ + lambdap[p][2] rotated (-360/n)
+ elseif i = 2:
+ - lambdap[p][1]
+ fi
+ if i = n - 1:
+ - lambdap[p][n] rotated (-360/n)
+ elseif i = n:
+ + lambdap[p][n-1]
+ fi
+ if (i > 1) and (i < n):
+ + lambdap[p][i-1] + lambdap[p][i+1] rotated (-360/n)
+ - lambdap[p][i] - lambdap[p][i] rotated (-360/n)
+ fi
+enddef;
+%</base>
+% \end{macrocode}
+% \begin{macro}{\fmffreeze}
+% Again, we can ask for positioning and drawing explicitely from \TeX{}
+% (usually called implicitely by |\end{fmfgraph}|). This is useful for
+% subsequent fine tuning.
+% \changes{v0.9}{1995/04/27}{%
+% \texttt{\protect\bslash fmffreeze}
+% is new name of \texttt{\protect\bslash fmfposition}.}
+% \begin{macrocode}
+%<style>\def\fmffreeze{\fmfcmd{vfreeze;}}
+%<style>\let\fmfposition\fmffreeze
+% \end{macrocode}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Immediate mode commands}
+%
+% This could share some code with |vconnect|, but it doesn't seem
+% worth the extra effort just now.
+% \changes{v0.9}{1995/02/19}{%
+% Started implementing immediate mode commands.}
+% \begin{macrocode}
+%<*base>
+vardef idraw (expr linesty, p) =
+ save nopt, sty, lbl, wd, rub;
+ numeric nopt, lbl.dist, wd, rub;
+%<*mp>
+ save fore, back;
+ color fore, back;
+%</mp>
+ string sty, lbl, lbl.side;
+ getopt (opt, linesty);
+ sty := opt[opt.first];
+ if known opt[opt.first]arg:
+ message "feynmf: line styles don't take arguments. "
+ & "Argument `" & opt[opt.first]arg & "' ignored.";
+ fi
+ opt.first := opt.first + 1;
+ lbl := "";
+ lbl.side := "";
+ lbl.dist := 3thick;
+ for nopt = opt.first upto opt.last:
+ if match_option (opt[nopt], "label"):
+ get_argument (opt[nopt], opt[nopt]arg, lbl);
+ elseif match_option (opt[nopt], "label.side"):
+ get_argument (opt[nopt], opt[nopt]arg, lbl.side);
+ elseif match_option (opt[nopt], "label.dist"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg), lbl.dist);
+ elseif match_option (opt[nopt], "width"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg), wd);
+%<*mp>
+ elseif match_option (opt[nopt], "foreground"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg), fore);
+ elseif match_option (opt[nopt], "background"):
+ get_argument (opt[nopt], scantokens (opt[nopt]arg), back);
+%</mp>
+%<*!mp>
+ elseif match_option (opt[nopt], "foreground")
+ or match_option (opt[nopt], "background"):
+ message "feynmf: color available with MetaPost only!";
+%</!mp>
+ elseif match_option (opt[nopt], "rubout"):
+ if known opt[nopt]arg:
+ rub := scantokens (opt[nopt]arg);
+ else:
+ rub := 2;
+ fi
+ else:
+ ignore_option (opt[nopt], opt[nopt]arg);
+ fi
+ endfor
+ handle_line_style (sty, sty);
+ begingroup
+%<*mp>
+ if known fore:
+ save foreground;
+ color foreground;
+ foreground = fore;
+ fi
+ if known back:
+ save background;
+ color background;
+ foreground = back;
+ fi
+%</mp>
+ vdraw_arc_rubout (rub, sty, wd, p, lbl);
+ endgroup;
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef ivertex (expr vtxsty, pos) =
+ save nopt, v;
+ numeric nopt, v.lbl.ang, v.lbl.dist,
+ v.decor.size, v.decor.ang;
+ pair v.loc;
+ string v.lbl, v.decor.sty;
+ path v.decor.shape;
+ v.loc := pos;
+ v.lbl := "";
+ v.lbl.ang := whatever;
+ v.lbl.dist := 3thick;
+ v.decor.size := decor_size;
+ getopt (opt, vtxsty);
+ for nopt = opt.first upto opt.last:
+ handle_vertex_option (v, opt[nopt], opt[nopt]arg);
+ endfor
+ vdraw_label (v.loc, v.lbl);
+ vdraw_vertex v;
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfi}
+% \begin{macro}{\fmfiv}
+% \begin{macro}{\fmfipath}
+% \begin{macro}{\fmfipair}
+% \begin{macro}{\fmfiset}
+% \begin{macro}{\fmfiequ}
+% \begin{macrocode}
+%<*style>
+\def\fmfi#1#2{%
+ \fmfbuf@={#1}%
+ \fmfcmd{idraw ("\the\fmfbuf@", #2);}}
+\def\fmfiv#1#2{%
+ \fmfbuf@={#1}%
+ \fmfcmd{ivertex ("\the\fmfbuf@", #2);}}
+\def\fmfipath#1{\fmfcmd{path #1;}}
+\def\fmfipair#1{\fmfcmd{pair #1;}}
+\def\fmfiset#1#2{\fmfcmd{#1:=#2;}}
+\def\fmfiequ#1#2{\fmfcmd{#1=#2;}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Drawing the graph}
+%
+% \begin{macro}{\fmfdraw}
+% \begin{macrocode}
+%<style>\def\fmfdraw{\fmfcmd{vdraw;}}
+% \end{macrocode}
+% \end{macro}
+%
+% And here's the actual \MF{} implementation of |vdraw|:
+% \begin{macrocode}
+%<*base>
+vardef vdraw =
+% \end{macrocode}
+% Check for typos:
+% \begin{macrocode}
+ if not feynmfwizard:
+ vcheck_typos;
+ fi
+% \end{macrocode}
+% Check that all vertices are known before attempting to draw the
+% diagram.
+% \begin{macrocode}
+ for i = vertices:
+ if not known vlist[i]loc:
+ errhelp "Your graph specification was not complete (probably a "
+ & "lone vertex). Check logic and reprocess!";
+ errmessage "feynmf: vertex `" & vlist[i]name & "' not determined, "
+ & "replaced by `(0,0)'.";
+ vlist[i]loc := origin;
+ fi
+ if unknown vlist[i]decor.size:
+ vlist[i]decor.size = decor_size;
+ fi
+ endfor
+% \end{macrocode}
+% Now do the actual drawing, looping over vertices and arcs. Draw all
+% arcs without the |rubout| option
+% before any vertex so we can be a bit more sloppy with drawing
+% the endpoints of arcs at decorated vertices.
+% \begin{macrocode}
+ for i = vertices:
+ for j = varcs (i):
+ if known vlist[i]arc[j]sty:
+ if vlist[i]arc[j]sty <> "":
+ if unknown vlist[i]arc[j]rub:
+% \end{macrocode}
+% \changes{v0.5}{1994/10/20}{Implement optional argument for detours.}
+% \begin{macrocode}
+ begingroup
+%<*mp>
+ if known vlist[i]arc[j]fore:
+ save foreground; color foreground;
+ foreground = vlist[i]arc[j]fore;
+ fi
+ if known vlist[i]arc[j]back:
+ save background; color background;
+ background = vlist[i]arc[j]back;
+ fi
+%</mp>
+ vdraw_arc (vlist[i]arc[j]sty, vlist[i]arc[j]wd,
+ vbuild_cut_arc (i, j), vlist[i]arc[j]lbl);
+% \end{macrocode}
+% \changes{v0.6}{1995/05/29}{Draw each vertex only once.}
+% \begin{macrocode}
+ vlist[i]arc[j]sty := "";
+ endgroup;
+ fi
+ fi
+ fi
+ endfor;
+ endfor
+ for i = polygons:
+ vdraw_label (pcenter plist[i], plist[i]lbl);
+ vdraw_polygon plist[i];
+ endfor
+ for i = vertices:
+ vdraw_label (vlist[i]loc, vlist[i]lbl);
+ vdraw_vertex vlist[i];
+ endfor
+% \end{macrocode}
+% Make a second pass over the arcs, now drawing those with a |rubout|
+% option.
+% \begin{macrocode}
+ for i = vertices:
+ for j = varcs (i):
+ if known vlist[i]arc[j]sty:
+ if vlist[i]arc[j]sty <> "":
+ if known vlist[i]arc[j]rub:
+ begingroup
+%<*mp>
+ if known vlist[i]arc[j]fore:
+ save foreground; color foreground;
+ foreground = vlist[i]arc[j]fore;
+ fi
+ if known vlist[i]arc[j]back:
+ save background; color background;
+ background = vlist[i]arc[j]back;
+ fi
+%</mp>
+ vdraw_arc_rubout (vlist[i]arc[j]rub,
+ vlist[i]arc[j]sty,
+ vlist[i]arc[j]wd,
+ vbuild_cut_arc (i, j),
+ vlist[i]arc[j]lbl);
+ vlist[i]arc[j]sty := "";
+ endgroup;
+ fi
+ fi
+ fi
+ endfor;
+ endfor
+enddef;
+% \end{macrocode}
+%
+% Check for the most common typos in vertex names:
+% \changes{v1.06}{1996/05/08}{%
+% New macro \texttt{vcheck\_typo}, checking for common errors.}
+% \begin{macrocode}
+vardef vcheck_typos =
+ save j, err;
+ boolean wrn;
+ wrn := false;
+ for i = vertices:
+ save connections;
+ connections = vlist[i]arc.last - vlist[i]arc.first + 1;
+% \end{macrocode}
+% This vertex has neither been connected nor fixed at a particular
+% position. Issue a warning message.
+% \begin{macrocode}
+ if connections < 1:
+ if unknown vlist[i]loc:
+ message "feynmf: warning: disconnected and unspecified vertex `"
+ & substring (2,infinity) of vlist[i]name
+ & "'.";
+ wrn := true;
+ fi
+ elseif connections = 1:
+ j := vlist[i]arc[vlist[i]arc.last];
+% \end{macrocode}
+% A vertex has only been connected with one other vertex and has not
+% been fixed as an external vertex. Issue a warning message, but only
+% once per connection.
+% \begin{macrocode}
+ if j < i:
+ if vlist[i]loc = vlist[j]loc:
+ message "feynmf: warning: dangling vertex `"
+ & substring (2,infinity) of vlist[i]name
+ & "' colliding with `"
+ & substring (2,infinity) of vlist[j]name
+ & "'.";
+ wrn := true;
+ fi
+ fi
+ fi
+ endfor
+ if wrn:
+ message "feynmf: Have you seen the warning messages above?";
+ message " They are usually caused by misspelling a vertex'";
+ message " name and can trigger errors further below!";
+ message " Fix the typos and run LaTeX and Metafont again.";
+ fi
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Drawing arcs}
+%
+% Construct an arc from |from| to |to|. The arc will be straight if
+% $|lsr| = 0$, a left (approximate) halfcircle if $|lsr| = -1$ and a
+% right halfcircle if $|lsr| = 1$. Othe values of |lsr| will give
+% obvious interpolations. We optimize the most frequent straight
+% line case.
+% \changes{v0.6}{1994/10/22}{%
+% Don't use \texttt{interpath} and halfcircles for detours anymore.
+% Simple paths constructed from three points are better (and
+% simpler).}
+% \begin{macrocode}
+vardef vbuild_arc (expr lsr, from, to) =
+ if unknown lsr:
+ from -- to
+ else:
+ if lsr = 0:
+ from -- to
+ else:
+ from
+ .. (1-lsr)/2 *(to rotatedabout (.5[from,to], 90))
+ + (1+lsr)/2 * (to rotatedabout (.5[from,to], -90))
+ .. to
+ fi
+ fi
+enddef;
+% \end{macrocode}
+% \changes{v0.9}{1995/04/19}{%
+% \texttt{vbuild\_cut\_arc}: new function.}
+% \begin{macrocode}
+vardef vbuild_cut_arc (expr origin, index) =
+ cut_decors (vlist[origin],
+ if vlist[origin]arc[index] <> origin:
+ vbuild_arc (vlist[origin]arc[index]lsr,
+ vlist[origin]loc,
+ vlist[vlist[origin]arc[index]]loc)
+ else:
+ vbuild_tadpole (origin, index)
+ fi,
+ vlist[vlist[origin]arc[index]])
+enddef;
+% \end{macrocode}
+%
+% \changes{v0.9}{1995/04/25}{%
+% \texttt{vbuild\_tadpole}: new function.}
+% \begin{macrocode}
+vardef vbuild_tadpole (expr origin, index) =
+ save j, n, nn, nnn, aidx, aang, agap, bgap, ngap, distsum;
+ n := 0;
+ distsum := 0;
+ for j = varcs (origin):
+ if vlist[origin]arc[j] <> origin:
+% \end{macrocode}
+% This uses the fact that |lsr| has been defined both ways:
+% \begin{macrocode}
+ ang := angle direction 0 of
+ vbuild_arc (vlist[origin]arc[j]lsr,
+ vlist[origin]loc,
+ vlist[vlist[origin]arc[j]]loc);
+ n := n + 1;
+ distsum := distsum
+ + abs (vlist[vlist[origin]arc[j]]loc - vlist[origin]loc);
+% \end{macrocode}
+% A sentinel:
+% \begin{macrocode}
+ aang[n] := 360;
+ for nn = 1 upto n:
+ if ang < aang[nn]:
+ for nnn = n - 1 downto nn:
+ aang[nnn+1] := aang[nnn];
+ aidx[nnn+1] := aidx[nnn];
+ endfor
+ aang[nn] := ang;
+ aidx[nn] := n;
+ fi
+ exitif known aidx[n];
+ endfor
+ fi
+ endfor
+ aidx[n+1] := aidx[1];
+ aang[n+1] := aang[1] + 360;
+ for nn = 1 upto n:
+ agap[nn] = aang[nn+1] - aang[nn];
+ endfor
+ if known vlist[origin]arc[index]lsr:
+% \end{macrocode}
+% Select specified gap:
+% \begin{macrocode}
+ ngap := n;
+ for nn = 1 upto n:
+ if (aang[nn] < vlist[origin]arc[index]lsr)
+ and (vlist[origin]arc[index]lsr < aang[nn+1]):
+ ngap := nn;
+ fi
+ endfor
+ else:
+% \end{macrocode}
+% Select the largest gap:
+% \begin{macrocode}
+ bgap := 0;
+ for nn = 1 upto n:
+ if agap[nn] > bgap:
+ bgap := agap[nn];
+ ngap := nn;
+ fi
+ endfor
+ fi
+ if vtracing: adump (n + 1); fi
+ vlist[origin]loc{dir(aang[ngap]+agap[ngap]/4)}
+ ... vlist[origin]loc + 2/3 * distsum/n
+ / vlist[origin]arc[index]tns
+ * dir(aang[ngap]+agap[ngap]/2)
+ ... {-dir(aang[ngap+1]-agap[ngap]/4)}vlist[origin]loc
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef adump expr n =
+ save i;
+ for i = 1 upto n:
+ message "aidx[" & decimal_ (i) & "]=" & decimal_ (aidx[i])
+ & ", aang[" & decimal_ (i) & "]=" & decimal_ (aang[i])
+ & ", agap[" & decimal_ (i) & "]=" & decimal_ (agap[i]);
+ endfor
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vdraw_arc (expr sty, wd, arc) (suffix lbl) =
+ if known wd:
+ save currentpen;
+ pen currentpen;
+ pickup pencircle scaled wd;
+ fi
+ scantokens ("draw_" & sty) (arc);
+ vdraw_arc_label (arc, lbl);
+enddef;
+% \end{macrocode}
+% Dirty trick: temporarily redefine the |draw| macro.
+% \changes{v1.06}{1996/05/25}{Handle the \texttt{rubout} option.}
+% \begin{macrocode}
+let plain_draw = draw;
+vardef vdraw_arc_rubout (expr rub, sty, wd, arc) (suffix lbl) =
+ if known rub:
+ begingroup
+ def draw expr p =
+ save oldpen; pen oldpen;
+ oldpen := currentpen;
+ save currentpen; pen currentpen;
+ pickup oldpen scaled rub;
+ erase plain_draw (subpath (.1,.9)*length(p) of p)
+ enddef;
+ vdraw_arc (sty, wd, arc, lbl);
+ let draw = plain_draw;
+ endgroup;
+ fi
+ vdraw_arc (sty, wd, arc, lbl);
+enddef;
+% \end{macrocode}
+%
+% Construct the path of a polygon according to |p.cona|, |p.conb| and
+% |p.pull|.
+% \changes{v1.06}{1996/05/24}{
+% New function \texttt{vbuild\_polygon}: construct polygon path.}
+% \begin{macrocode}
+vardef vbuild_polygon suffix p =
+ if known p.pull:
+% \end{macrocode}
+% Connect the vertices with intermediate points:
+% \begin{macrocode}
+ save c; pair c;
+ c := pcenter p;
+ for i = 1 upto (p.cnt - 1):
+ vbuild_polygon_section (p, i, i+1)
+ endfor
+ vbuild_polygon_section (p, p.cnt, 1)
+ else:
+% \end{macrocode}
+% Just connect the vertices:
+% \begin{macrocode}
+ for i = 1 upto p.cnt:
+ vlist[p.vtx[i]]loc
+ if known p.cona: scantokens (p.cona) else: -- fi
+ endfor
+ fi
+ cycle
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+def vbuild_polygon_section (suffix p) (expr from, to) =
+ vlist[p.vtx[from]]loc
+ if known p.cona: scantokens (p.cona) else: -- fi
+ p.pull[c,.5[vlist[p.vtx[from]]loc,vlist[p.vtx[to]]loc]]
+ if known p.conb: scantokens (p.conb) else: -- fi
+enddef;
+% \end{macrocode}
+% Calculate the center of gravity of a polygon:
+% \begin{macrocode}
+vardef pcenter suffix p =
+ (origin for i = 1 upto p.cnt:
+ + vlist[p.vtx[i]]loc
+ endfor) / p.cnt
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Drawing labels}
+%
+% \begin{macrocode}
+vardef vdraw_arc_label (expr arc) (suffix lbl) =
+ if lbl <> "":
+ save _a, _z, _zz, _r;
+ numeric _a;
+ pair _z, _zz, _r;
+ _z := point .5 length (arc) of arc;
+ if lbl.dist = 0:
+ LaTeX_text (_z, whatever, lbl);
+ else:
+ _r := direction .5 length (arc) of arc rotated - 90;
+ if lbl.side = "left":
+ _a := angle (-_r);
+ elseif lbl.side = "right":
+ _a := angle (_r);
+ else:
+% \end{macrocode}
+% Normalize to avoid overflow in |dotprod|:
+% \changes{v0.8}{1995/02/18}{%
+% \texttt{vdraw\_arc\_label}: Protect against divide by zero.}
+% \begin{macrocode}
+ _zz = _z - .5[point 0 of arc, point infinity of arc];
+ if ((_zz if length (_zz) > 0: / length (_zz) fi)
+ dotprod _r) >= 0:
+ _a := angle (_r);
+ else:
+ _a := angle (-_r);
+ fi
+ fi
+ LaTeX_text (_z + lbl.dist * dir _a, _a, lbl);
+ fi
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef vdraw_label (expr loc) (suffix lbl) =
+ if lbl <> "":
+ save a;
+ numeric a;
+ if lbl.dist = 0:
+ LaTeX_text (loc, whatever, lbl);
+ else:
+ if unknown lbl.ang:
+ if loc = (.5w,.5h):
+ a := 0;
+ else:
+ a := angle (loc - (.5w,.5h));
+ fi
+ else:
+ a := lbl.ang;
+ fi
+ LaTeX_text (loc + lbl.dist * dir a, a, lbl);
+ fi
+ fi
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Drawing vertices}
+%
+% \begin{macrocode}
+vardef vdraw_vertex suffix v =
+ if known v.decor.shape:
+%<*mp>
+ if known v.fore:
+ save foreground;
+ color foreground;
+ foreground = v.fore;
+ fi
+ if known v.back:
+ save background;
+ color background;
+ background = v.back;
+ fi
+%</mp>
+ if known v.decor.sty:
+ if v.decor.sty = "empty":
+ emptydraw (
+ elseif v.decor.sty = "full":
+ cfilldraw (
+ elseif is_a_number v.decor.sty:
+ drawhalftone (1 - scantokens v.decor.sty / 100,
+ else:
+ drawtile (scantokens v.decor.sty,
+ fi
+ else:
+ cfilldraw (
+ fi
+ v.decor.shape
+ if known v.decor.ang: rotated v.decor.ang fi
+ scaled v.decor.size shifted v.loc);
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef polygon expr n =
+ if n > 2:
+ for i = 1 upto n:
+ (.5up rotated (360i/n)) --
+ endfor
+ cycle
+ else:
+ fullcircle
+ fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef polygram expr n =
+ if n > 2:
+ for i = 1 upto n:
+ (.5up rotated (360i/n)) --
+ (.2up rotated (360(i+.5)/n)) --
+ endfor
+ cycle
+ else:
+ fullcircle
+ fi
+enddef;
+% \end{macrocode}
+%
+% \changes{v1.01}{1995/06/04}{%
+% \texttt{polycross} for vertices with crosses.}
+% \begin{macrocode}
+vardef polycross expr n =
+ save i;
+ for i = 1 upto n:
+ origin -- .5 dir (360(i-.5)/n) --
+ endfor
+ cycle
+enddef;
+% \end{macrocode}
+%
+% Draw the path of a polygon and fill it according to |p.sty|.
+% \changes{v1.06}{1996/05/24}{
+% New function \texttt{vdraw\_polygon}: draw and fill polygon.}
+% \begin{macrocode}
+vardef vdraw_polygon suffix p =
+%<*mp>
+ if known p.fore:
+ save foreground;
+ color foreground;
+ foreground = p.fore;
+ fi
+ if known p.back:
+ save background;
+ color background;
+ background = p.back;
+ fi
+%</mp>
+ if known p.sty:
+ if p.sty = "phantom":
+ elseif p.sty = "empty":
+ emptydraw (vbuild_polygon p);
+ elseif p.sty = "full":
+ cfilldraw (vbuild_polygon p);
+ elseif is_a_number p.sty:
+ drawhalftone (1 - scantokens p.sty / 100, vbuild_polygon p);
+ else:
+ drawtile (scantokens p.sty, vbuild_polygon p);
+ fi
+ else:
+ cdraw (vbuild_polygon p);
+ fi
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Talking to \LaTeX}
+%
+% Unfortunately, enclosing the |message| in a |batchmode|
+% |errorstopmode| pair doesn't work. The label information isn't
+% written to the terminal, but an empty line is anyway.
+% \changes{v0.4}{1994/05/28}{%
+% \MP: \texttt{write} the label files directly.}
+% \changes{v0.99}{1995/05/07}{%
+% Don't include the filename in the tag for
+% \texttt{\protect\bslash grepfile}: it's a waste.}
+% The good news is that we don't have to worry about too long lines,
+% because |message| will break them automagically and |\read| will
+% splice them together again until braces are balanced.
+% \begin{macrocode}
+vardef LaTeX expr text =
+%<*!mp>
+ message (":" & decimal charcode & ":" & text & "%")
+%</!mp>
+%<*mp>
+ if LaTeX_file = "":
+ LaTeX_file := jobname & ".t" & decimal charcode;
+ write ("% " & LaTeX_file & " -- generated from " & jobname & ".mp")
+ to LaTeX_file;
+ fi
+ write (text & "%") to LaTeX_file
+%</mp>
+enddef;
+vardef LaTeX_text (expr z, a, txt) =
+ LaTeX "\fmfL(" & (decimal (xpart z/LaTeX_unitlength)) & ","
+ & (decimal (ypart z/LaTeX_unitlength)) & ","
+ & (voctant a) & "){" & txt & "}";
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfL}
+% This is an internal macro for squeezing more text into \MF's
+% 80 character wide output.
+% \begin{macrocode}
+%<style>\def\fmfL(#1,#2,#3)#4{\put(#1,#2){\makebox(0,0)[#3]{#4}}}
+% \end{macrocode}
+% \end{macro}
+%
+% This will only be used with $\vert|a|\vert\le180$:
+% \begin{macrocode}
+%<*base>
+vardef voctant expr a =
+ if known a:
+ voctant_list[floor (a/45 + .5)]
+ else:
+ "c"
+ fi
+enddef;
+string voctant_list[];
+voctant_list[-4] := "r";
+voctant_list[-3] := "rt";
+voctant_list[-2] := "t";
+voctant_list[-1] := "lt";
+voctant_list[0] := "l";
+voctant_list[1] := "lb";
+voctant_list[2] := "b";
+voctant_list[3] := "rb";
+voctant_list[4] := "r";
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsubsection{Tracing}
+%
+% \begin{macrocode}
+vardef vdump =
+ message ">>>>> Vertices and arcs for diagram #" & decimal charcode
+ & " of " & jobname & ".mf:";
+ for i = vertices:
+ message "> " & vlist[i]name & "=" & decimal_pair (vlist[i]loc)
+ & ": #lines="
+ & decimal (vlist[i]arc.last - vlist[i]arc.first + 1)
+ if vlist[i]lbl <> "":
+ & ", lbl=" & vlist[i]lbl
+ & ", l.angle=" & decimal_ (vlist[i]lbl.ang)
+ & ", l.dist=" & decimal_ (vlist[i]lbl.dist)
+ fi
+ & ".";
+ endfor
+ for i = vertices:
+ for j = varcs (i):
+ if known vlist[i]arc[j]sty:
+ message "> " & vlist[i]name & "*" & vlist[vlist[i]arc[j]]name
+ & ": " & vlist[i]arc[j]sty
+ & ", tns=" & decimal_ (vlist[i]arc[j]tns)
+ & ", lsr=" & decimal_ (vlist[i]arc[j]lsr)
+ & ", wd=" & decimal_ (vlist[i]arc[j]wd)
+ & ", rub=" & decimal_ (vlist[i]arc[j]rub)
+ if vlist[i]arc[j]lbl <> "":
+ & ", lbl=" & vlist[i]arc[j]lbl
+ & ", l.side=" & vlist[i]arc[j]lbl.side
+ & ", l.dist=" & decimal_ (vlist[i]arc[j]lbl.dist)
+ fi
+ & ".";
+ fi
+ endfor
+ for j = vconstr (i):
+ if i < vlist[i]constr[j]:
+% \end{macrocode}
+% We don't keep an explicit record of the fixed distances, but they're
+% easy to recover:
+% \begin{macrocode}
+ save z;
+ pair z;
+ z = vlist[vlist[i]constr[j]]loc - vlist[i]loc;
+ message "> " & vlist[i]name & "&"
+ & vlist[vlist[i]constr[j]]name
+ & ": " & decimal_pair (z);
+ fi
+ endfor;
+ endfor
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef decimal_ (text n) =
+ if known n: decimal n else: "?" fi
+enddef;
+% \end{macrocode}
+%
+% \begin{macrocode}
+vardef decimal_pair (text z) =
+ "(" & decimal_ (xpart z) & "," & decimal_ (ypart z) & ")"
+enddef;
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Online displays}
+%
+% This is a bit smarter about pictures of varying sizes and some
+% overshooting than |showit|. You can still get burned, though,
+% because \MF{} might not be able to enlarge the screen sufficiently.
+% \changes{v0.8}{1994/10/25}{Online display support.}
+% \begin{macrocode}
+def show_diagram_ expr frame =
+ if (screen_cols < w + 2 xpart frame) or (screen_rows < h + 2 ypart frame):
+ screen_cols := w + 2 xpart frame;
+ screen_rows := h + 2 ypart frame;
+ openwindow currentwindow
+ from origin to (screen_rows, screen_cols)
+ at (- xpart frame, h + ypart frame);
+ fi
+ showit_;
+ if showstopping > 0:
+ stop "This is diagram #" & decimal charcode
+ & ". Hit return to continue...";
+ fi
+enddef;
+% \end{macrocode}
+% Self-modifying code is \emph{fun}: make sure to clear the window the
+% second time around.
+% \begin{macrocode}
+def show_diagram =
+ def show_diagram =
+ display blankpicture inwindow currentwindow;
+ show_diagram_
+ enddef;
+ show_diagram_
+enddef;
+% \end{macrocode}
+% |show_all_diagrams| turns on the above online display mechanism.
+% Creative use of |extra_endchar| allows us to do this from the
+% command line (|showstopping| is used here to slow down the slide
+% show).
+% \begin{verbatim}
+% mf '\mode:=localmode;
+% showstopping:=1;
+% extra_endchar:="show_all_diagrams(100,100);";
+% input foo.mf'
+% \end{verbatim}
+% \begin{macrocode}
+def show_all_diagrams expr frame =
+ def showit = show_diagram frame enddef;
+ displaying:=1;
+enddef;
+%</base>
+% \end{macrocode}
+%
+% \begin{macro}{\fmfdisplay}
+% \begin{macro}{\fmfstopdisplay}
+% Make the display accessible from \TeX{} too.
+% \begin{macrocode}
+%<*style>
+\def\fmfdisplay{\fmfcmd{show_all_diagrams (100,100);}}
+\def\fmfstopdisplay{\fmfcmd{showstopping:=1;}\fmfdisplay}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fmftrace}
+% \begin{macro}{\fmfnotrace}
+% Make the display accessible from \TeX{} too.
+% \begin{macrocode}
+\def\fmftrace{\fmfcmd{vtracing:=true;}}
+\def\fmfnotrace{\fmfcmd{vtracing:=false;}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Now we're done with the \MF{} macros
+% \begin{macrocode}
+%<*base>
+endinput;
+%</base>
+% \end{macrocode}
+% and the \TeX{} macros too:
+% \begin{macrocode}
+%<*style>
+\mdqrestore
+%</style>
+% \end{macrocode}
+%
+% \Finale
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \appendix
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{Driver file}
+%
+% \begin{macrocode}
+%<*driver>
+%<*!209>
+\documentclass[a4paper]{article}
+\usepackage{doc}
+% \end{macrocode}
+% The \MF{} and \MP{} logos come out much nicer if you have |mflogo|
+% installed:
+% \begin{macrocode}
+\IfFileExists{mflogo.sty}%
+ {\usepackage{mflogo}%
+ \def\FMF{\texttt{feyn}\textlogo{MF}}}%
+ {\def\MF{\textsf{META}\-\textsf{FONT}}%
+ \def\MP{\textsf{META}\-\textsf{POST}}%
+ \def\FMF{\texttt{feyn}\textsf{MF}}}
+% \end{macrocode}
+% Here is the place to declare your own PostScript aware |dvi| driver
+% option:
+% \changes{v1.01}{1995/07/05}{%
+% Don't force \texttt{dvips} as \texttt{dvi} driver.}
+% \begin{macrocode}
+\usepackage{graphics}[1994/12/15]
+%<mp>\usepackage{feynmp}
+%<!mp>\usepackage{feynmf}
+%</!209>
+% \end{macrocode}
+% Here's the \LaTeX~2.09 compatibility stuff:
+% \begin{macrocode}
+%<*209>
+%<mp>\documentstyle[doc,feynmp209]{article}
+%<!mp>\documentstyle[doc,feynmf209,epsf]{article}
+%<!mp>\let\includegraphics\epsffile
+\def\textit#1{{\it#1\/}}
+\def\textbf#1{{\bf#1}}
+\def\textsf#1{{\sf#1}}
+\def\texttt#1{{\tt#1}}
+\def\emph#1{{\em#1\/}}
+\let\bfseries\bf
+\def\LaTeXe{\LaTeX$2_\epsilon$}
+\def\MF{\textsf{META}\-\textsf{FONT}}
+\def\MP{\textsf{META}\-\textsf{POST}}
+\def\FMF{\texttt{feyn}\textsf{MF}}
+%</209>
+% \end{macrocode}
+% The rest is common:
+% \begin{macrocode}
+\font\manfnt=manfnt
+\def\dangerousbend/{{\manfnt\char"7F}}
+\def\dubious{\begin{itemize}\item[\dangerousbend/]}
+\def\enddubious{\end{itemize}}
+\def\examples#1{%
+ \begin{list}{}%
+ {\setlength{\leftmargin}{#1}%
+ \addtolength{\leftmargin}{\marginparsep}%
+ \addtolength{\leftmargin}{-\marginparwidth}%
+ \setlength{\rightmargin}{0mm}%
+ \setlength{\itemindent}{\parindent}%
+ \setlength{\listparindent}{\parindent}}%
+ \item}
+\def\endexamples{\end{list}}
+\def\marginexample#1{\marginpar{\hbox to\marginparwidth{#1\hss}}}
+\parindent0pt
+\def\manindex#1{\SortIndex{#1}{#1}}
+%<manual>\OnlyDescription
+\EnableCrossrefs
+\RecordChanges
+\CodelineIndex
+\DoNotIndex{\def,\gdef,\long,\let,\begin,\end,\if,\ifx,\else,\fi}
+\DoNotIndex{\immediate,\write,\newwrite,\openout,\closeout,\typeout}
+\DoNotIndex{\font,\nullfont,\jobname,\documentclass}
+\DoNotIndex{\batchmode,\errorstopmode,\char,\catcode,\ }
+\DoNotIndex{\CodelineIndex,\DocInput,\DoNotIndex,\EnableCrossrefs}
+\DoNotIndex{\filedate,\filename,\fileversion,\logo,\manfnt}
+\DoNotIndex{\NeedsTeXFormat,\ProvidesPackage,\RecordChanges,\space}
+\DoNotIndex{\usepackage,\wlog,\@gobble,\@ifundefined,\@namedef,\@spaces}
+\DoNotIndex{\begingroup,\csname,\edef,\endcsname,\expandafter,\hbox}
+\DoNotIndex{\hskip,\ifeof,\ignorespaces,\item,\leavevmode,\loop,\makebox}
+\DoNotIndex{\newcounter,\newif,\newread,\openin,\par,\parindent,\put}
+\DoNotIndex{\read,\relax,\repeat,\setcounter,\stepcounter,\the}
+\DoNotIndex{\value,\vbox,\vskip}
+\DoNotIndex{\@tempa,\@tempb,\advance,\bf,\bfseries,\closein}
+\DoNotIndex{\CurrentOption,\DeclareOption,\documentstyle,\em,\emph}
+\DoNotIndex{\endgroup,\epsilon,\global,\hfuzz,\input,\it,\LaTeX,\LaTeXe}
+\DoNotIndex{\macrocode,\meaning,\OnlyDescription,\PassOptionsToPackage}
+\DoNotIndex{\ProcessOptions,\RequirePackage,\sf,\string,\textbf,\textit}
+\DoNotIndex{\textsf,\texttt,\tt,\unitlength}
+% \end{macrocode}
+% Cut the linebreaking some slack for macrocode which might conatin
+% long lines (it doesn't really hurt if they stick out a bit).
+% \begin{macrocode}
+\let\origmacrocode\macrocode
+\def\macrocode{\hfuzz 5em\origmacrocode}
+\begin{document}
+ \DocInput{feynmf.dtx}
+\end{document}
+%</driver>
+% \end{macrocode}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
+Local Variables:
+mode:LaTeX
+fill-prefix:"% "
+indent-tabs-mode:nil
+change-log-default-name:"TODO"
+page-delimiter:"^% %%%%%%%%%*\n"
+End:
diff --git a/macros/latex/contrib/feynmf/feynmf.ins b/macros/latex/contrib/feynmf/feynmf.ins
new file mode 100644
index 0000000000..9264e5a12a
--- /dev/null
+++ b/macros/latex/contrib/feynmf/feynmf.ins
@@ -0,0 +1,95 @@
+% feynmf.ins - Feynman diagrams with METAFONT for LaTeX(2e)
+% Copyright (C) 1994,1995 by Thorsten.Ohl@Physik.TH-Darmstadt.de
+% $Id: feynmf.ins,v 1.5 1995/05/06 11:38:11 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.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+\def\batchfile{feynmf.ins}
+\input docstrip.tex
+\keepsilent
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\preamble
+
+Copyright (C) 1989, 1990, 1992-1995 by Thorsten.Ohl@Physik.TH-Darmstadt.de
+
+This file is NOT the source for feynmf, because almost all comments
+have been stripped from it. It is NOT the preferred form of feynmf
+for making modifications to it.
+
+Therefore you can NOT redistribute and/or modify THIS file. You can
+however redistribute the complete source (feynmf.dtx and feynmf.ins)
+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.
+
+As a special exception, you can redistribute parts of this file for
+the electronic distribution of scientific papers, provided that you
+include a short note pointing to the complete source.
+
+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.
+
+\endpreamble
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\Msg{Generating style file feynmf.sty for the feynmf package:}
+\generateFile{feynmf.sty}{f}{\from{feynmf.dtx}{style}}
+\Msg{Generating Metafont base feynmf.mf:}
+\generateFile{feynmf.mf}{f}{\from{feynmf.dtx}{base}}
+\Msg{Generating style file feynmp.sty for the MetaPost version:}
+\generateFile{feynmp.sty}{f}{\from{feynmf.dtx}{style,mp}}
+\Msg{Generating MetaPost base feynmp.mp:}
+\generateFile{feynmp.mp}{f}{\from{feynmf.dtx}{base,mp}}
+\Msg{Generating driver file for manual fmfman.drv:}
+\generateFile{fmfman.drv}{f}{\from{feynmf.dtx}{driver,manual}}
+\Msg{Generating alternate MetaPost driver file fmfmanps.drv:}
+\generateFile{fmfmanps.drv}{f}{\from{feynmf.dtx}{driver,manual,mp}}
+\Msg{Generating driver file for documentation feynmf.drv:}
+\generateFile{feynmf.drv}{f}{\from{feynmf.dtx}{driver}}
+\Msg{Generating alternate MetaPost driver file feynmp.drv:}
+\generateFile{feynmp.drv}{f}{\from{feynmf.dtx}{driver,mp}}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the files}
+\Msg{*}
+\Msg{*\space\space o feynmf.sty into a directory searched by TeX}
+\Msg{*\space\space o feynmf.mf into a directory searched by Metafont}
+\Msg{*\space\space o feynmp.sty into a directory searched by TeX}
+\Msg{*\space\space o feynmp.mp into a directory searched by MetaPost}
+\Msg{*}
+\Msg{* You can remove the latter two if you don't have}
+\Msg{* John Hobby's MetaPost system. Optionally you can copy the}
+\Msg{* files fmfman.dtx and fmfmanps.drv into a directory searched by}
+\Msg{* TeX, so that users can print a copy of the documentation.}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
+Local Variables:
+mode:LaTeX
+fill-prefix:"% "
+page-delimiter:"^% %%%%%%%%%*\n"
+End:
diff --git a/macros/latex/contrib/feynmf/feynmf.pl b/macros/latex/contrib/feynmf/feynmf.pl
new file mode 100644
index 0000000000..d56a054587
--- /dev/null
+++ b/macros/latex/contrib/feynmf/feynmf.pl
@@ -0,0 +1,457 @@
+#! /usr/bin/perl
+# feynmf.pl -- FeynMF driver for UNIX systems
+# Copyright (C) 1996 by Thorsten.Ohl@Physik.TH-Darmstadt.de
+# $Id: feynmf.pl,v 1.5 1996/12/02 01:38:45 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.
+#
+########################################################################
+
+=head1 NAME
+
+B<feynmf> - Process B<LaTeX> files using B<FeynMF>
+
+=head1 SYNOPSIS
+
+B<feynmf> [B<-hvqncfT>] [B<-t> I<tfm> [B<-t> I<tfm> ...]] [B<-m> I<mode>]
+ I<file> [I<file> ...]
+
+B<feynmf> [B<--help>] [B<--version>] [B<--quiet>] [B<--noexec>] [B<--clean>]
+ [B<--force>] [B<--notfm>] [B<--tfm> I<tfm> [B<--tfm> I<tfm> ...]]
+ [B<--mode> I<mode>] I<file> [I<file> ...]
+
+=head1 DESCRIPTION
+
+The most complicated part of using the B<FeynMF> style appears to be the
+proper invocation of B<Metafont>. The B<feynmf> script provides a
+convenient front end and will automagically invoke B<Metafont> with the
+proper mode and magnifincation. It will also avoid cluttering system font
+directories and offers an option to clean them.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-h>, B<--help>
+
+Print a short help text.
+
+=item B<-v>, B<--version>
+
+Print the version of B<feynmf>.
+
+=item B<-q>, B<--quiet>
+
+Don't echo the commands being executed.
+
+=item B<-n>, B<--noexec>
+
+Don't execute B<LaTeX> or B<Metafont>.
+
+=item B<-c>, B<--clean>
+
+Offer to delete font files that have accidentally been placed in a
+system directory by the B<MakeTeXTFM> and B<MakeTeXPK> scripts (these
+scripts are run by B<tex> (and B<latex>) in the background). This
+option has only been tested with recent versions of UNIX TeX.
+
+=item B<-f>, B<--force>
+
+Don't ask any questions.
+
+=item B<-T>, B<--notfm>
+
+Don't try to prepare fake C<.tfm> files for the first run.
+
+=item B<-t>, B<--tfm> I<tfm>
+
+Don't try guess the names of the C<.tfm> files to fake for
+the first run and use the given name(s) instead. This option
+can be useful if our incomplete parsing of the LaTeX input
+files fails.
+
+=item -B<m> I<mode>, B<--mode> I<mode>
+
+Select the METAFONT mode I<mode>. The default is guessed or
+C<localfont> if the guess fails.
+
+=item I<file>
+
+Main B<LaTeX> input files.
+
+=item I<file> ...
+
+Other LaTeX input files that are included by the main file.
+
+=back
+
+=head1 AUTHOR
+
+Thorsten Ohl <Thorsten.Ohl@Physik.TH-Darmstadt.de>
+
+=head1 BUGS
+
+The preparation of C<.tfm> files is not foolproof yet, because we can
+parse B<TeX> files only superficially.
+
+This script has only been tested for recent B<teTeX> distributions
+of UNIX B<TeX>, though it will probably work with other versions of
+UNIX B<TeX>. The author will be grateful for portability suggestions,
+even concerning B<Borg> operating systems, for the benefit of those users
+that are forced to live with DOS or Windows.
+
+=cut
+
+########################################################################
+
+require 5.000;
+# use strict;
+use File::Find;
+use Getopt::Long;
+
+########################################################################
+#
+# Run a program, optionally echoing to standard output.
+#
+########################################################################
+
+sub maybe_run {
+ my ($cmd) = @_;
+ print "feynmf: $cmd\n" unless $opt_quiet;
+ system $cmd unless $opt_noexec;
+}
+
+sub run_latex {
+ my ($tex) = @_;
+ maybe_run "$latex_prog $tex";
+}
+
+########################################################################
+#
+# Search for auxiliary programs, some of which are required for running
+# this script. Bail out if these don't exist.
+#
+########################################################################
+
+sub find_program_on_path {
+ my ($p, $flag) = @_;
+ my (@path, $d);
+ @path = grep {s/^$/./; 1} (split /:/, $ENV{"PATH"});
+ foreach $d (@path) {
+ return "$d/$p" if -x "$d/$p";
+ }
+ if ($flag eq 'REQUIRED') {
+ die "feynmf: fatal: Can't find $p on \$PATH\n";
+ }
+ if ($flag eq 'RECOMMENDED') {
+ warn "feynmf: warning: Can't find $p on \$PATH\n";
+ return;
+ }
+ if (defined $flag) {
+ die "feynmf: fatal: illegal flag in find_program_on_path: $flag\n";
+ }
+ return;
+}
+
+sub find_programs {
+ $kpsexpand_prog = find_program_on_path 'kpsexpand', 'RECOMMENDED';
+ $kpsepath_prog = find_program_on_path 'kpsepath', 'RECOMMENDED';
+ $kpsetool_prog = find_program_on_path 'kpsetool', 'RECOMMENDED';
+ $gftopk_prog = find_program_on_path 'gftopk', 'RECOMMENDED';
+ $pltotf_prog = find_program_on_path 'pltotf', 'RECOMMENDED';
+ $latex_prog = find_program_on_path 'latex', 'REQUIRED';
+ $mf_prog = find_program_on_path 'mf', 'REQUIRED';
+ $dvitype_prog = find_program_on_path 'dvitype', 'REQUIRED';
+}
+
+########################################################################
+#
+# System dependent stuff: guess search paths and Metafont mode.
+#
+########################################################################
+
+sub uniq {
+ my $last = '';
+ my (@result, $d);
+ foreach $d (sort @_) {
+ push @result, $d if $d ne $last;
+ $last = $d;
+ }
+ return @result;
+}
+
+sub path_to_list {
+ my ($p) = @_;
+ grep { s=^~=$1$ENV{HOME}=;
+ s=^!!==;
+ s=//.*$=/=;
+ !m=^\.?$=
+ } split (/:+/, $p);
+}
+
+%TEXENV = (
+ tex => 'TEXINPUTS',
+ mf => 'MFINPUTS',
+ tfm => 'TFMFONTS',
+ pk => 'PKFONTS',
+ gf => 'GFFONTS'
+);
+
+sub guess_path {
+ my ($type) = @_;
+ if ($kpsetool_prog) {
+ return path_to_list
+ (`$kpsetool_prog -p $type` or
+ die "feynmf: can't run $kpsetool_prog: $!\n");
+ } elsif ($kpsepath_prog) {
+ return path_to_list
+ (`$kpsepath_prog $type` or
+ die "feynmf: can't run $kpsepath_prog: $!\n");
+ } elsif ($TEXENV{$type}) {
+ if ($kpsexpand_prog) {
+ return path_to_list
+ (`$kpsexpand_prog '\$$TEXENV{$type}'` or
+ die "feynmf: can't run $kpsexpand_prog: $!\n");
+ } else {
+ return path_to_list ($ENV{$TEXENV{$type}});
+ }
+ } else {
+ return;
+ }
+}
+
+sub guess_mode {
+ my ($TEXMF, $maketex_site, $mode);
+ $mode = "localfont";
+ if ($kpsexpand_prog) {
+ chomp ($TEXMF = `$kpsexpand_prog '\$TEXMF'`);
+ $maketex_site = "$TEXMF/maketex/maketex.site";
+ chomp ($mode = `. $maketex_site; echo \$MT_DEF_MODE`)
+ if -r $maketex_site;
+ }
+ return $mode;
+}
+
+########################################################################
+#
+# Prepare empty TFM files.
+#
+########################################################################
+
+sub guess_tfms {
+ my @tex = @_;
+ my @tfm = ();
+ my $tex;
+ foreach $tex (@tex) {
+ open (TEX, "$tex") or die "feynmf: can't open $tex: $!\n";
+ while (<TEX>) {
+ if (/^[^%]*\\begin\s*\{fmffile\}\s*\{([^}]+)\}/) {
+ push @tfm, $1;
+ }
+ }
+ close (TEX);
+ }
+ return @tfm;
+}
+
+sub fake_tfms {
+ my @tfm = @_;
+ # Prepare a fake temporary PL file
+ # (/dev/null won't do, because the font must not be empty):
+ my ($pl) = "/tmp/feynmf$$.pl";
+ my ($tfm);
+ $pltotf_prog
+ or die "feynmf: fatal: pltopf programm required unless -notfm\n";
+ open (PL, ">$pl") or die "feynmf: can't open temporary file $pl: $!\n";
+ push @temporay_files, $pl;
+ print PL <<__END_PL__;
+ (FAMILY FEYNMF)
+ (DESIGNSIZE R 10.0)
+ (CHARACTER D 1 (CHARWD R 10.0) (CHARHT R 10.0))
+__END_PL__
+ close (PL);
+ foreach $tfm (@tfm) {
+ maybe_run "$pltotf_prog $pl $tfm.tfm" unless -r "$tfm.tfm";
+ }
+}
+
+########################################################################
+#
+# Scan the current directory for Metafont sources and offer to delete
+# TFM, PK and GF files in the system directories that are in the way.
+# If the option `-force' is in effect, no questions are asked and all
+# suspicous files are deleted.
+#
+########################################################################
+
+sub clean_fonts {
+ my (@mfs, $mfre, @junk, $j, $nqya);
+ opendir (DIR, '.') or die "Can't open current directory: $!\n";
+ @mfs = grep { s/\.mf$// } readdir (DIR);
+ closedir (DIR);
+ if (@mfs) {
+ @junk = ();
+ $mfre = '^(' . join ('|', @mfs) . ')(\.|$)';
+ find (sub { push @junk, $File::Find::name if /$mfre/ },
+ grep { -r } uniq (guess_path ('tfm'),
+ guess_path ('pk'),
+ guess_path ('gf')));
+ grep { print "feynmf: $_ suspicious!\n" } @junk;
+ $nqya = 'n';
+ $nqya = 'a' if $opt_force;
+ junk: foreach $j (@junk) {
+ if ($nqya ne 'a') {
+ print "delete $j ? [N/q/y/a] ";
+ chop ($nqya = <STDIN>);
+ $nqya =~ tr/A-Z/a-z/;
+ last junk if $nqya eq 'q'
+ }
+ if ($nqya eq 'y' || $nqya eq 'a') {
+ print "rm $j\n" unless $opt_quiet;
+ if (!unlink $j) {
+ if (-o $j) {
+ warn "feynmf: couldn't unlink your file $j!\n";
+ } else {
+ warn "feynmf: couldn't unlink foreign file $j!\n";
+ }
+ }
+ }
+ }
+ }
+}
+
+########################################################################
+#
+# Run Metafont on the files referenced in the DVI file $dvi:
+#
+########################################################################
+
+sub mf_names {
+ my ($dvi) = @_;
+ my (@mf, $name, $mag);
+ open (DVI, "echo 0 | $dvitype_prog $dvi 2>/dev/null |") or
+ die "feynmf: can't dvitype $dvi: $!\n";
+ while (<DVI>) {
+ if (/^Font\s*\d+:\s*(\S*)\s*(scaled\s*(\d+))?\s*---\s*loaded/) {
+ $name = $1;
+ $mag = $3 ? $3/1000 : 1;
+ push @mf, [$name, $mag];
+ }
+ }
+ close (DVI);
+ return @mf;
+}
+
+sub run_mf {
+ my (@mf) = @_;
+ my ($mf, $name, $mag, $gf);
+ for $mf (@mf) {
+ $name = $$mf[0];
+ $mag = $$mf[1];
+ if (-r "$name.mf") {
+ maybe_run "$mf_prog '\\mode:=$mode; mag:=$mag; input $name'";
+ if (!$opt_noexec) {
+ # Check the log file for the name of the generated font
+ # and run gftopk on it:
+ open (LOG, "$name.log") or
+ die "feynmf: can't open $name.log: $!\n";
+ while (<LOG>) {
+ if (/Output written on\s+(\S+)\s+/) {
+ $gf = $1;
+ maybe_run "$gftopk_prog $gf" if $gftopk_prog;
+ }
+ }
+ close (LOG);
+ }
+ }
+ }
+}
+
+########################################################################
+#
+# Options:
+#
+########################################################################
+
+sub tex_names {
+ my @in = @_;
+ my (@out, $in);
+ foreach $in (@in) {
+ if ($in !~ /\.tex$/ and -r "$in.tex") {
+ push @out, "$in.tex";
+ } else {
+ push @out, $in;
+ }
+ }
+ return @out;
+}
+
+@options = ('help|h', 'version|v', 'debug|D', 'quiet|q', 'noexec|n',
+ 'clean|c', 'force|f', 'notfm|T', 'tfm|t=s@', 'mode|m=s');
+
+$usage = <<__USAGE__;
+usage: feynmf [-hvqncfT] [-t tfm [-t tfm ...]] [-m mode] file [file ...]
+ or: feynmf [--help] [--version] [--quiet] [--noexec] [--clean]
+ [--force] [--notfm] [--tfm tfm [--tfm tfm ...]] [--mode mode]
+ file [file ...]
+__USAGE__
+
+$help = <<__HELP__;
+usage: feynmf [OPTIONS] FILE [FILE ...]
+
+OPTIONS:
+ -h, --help: this message
+ -v, --version: print version to standard output and exit
+ -q, --quiet: shut up
+ -n, --noexec: don't run LaTeX or Metafont
+ -c, --clean: offer to delete suspicious font files
+ -f, --force: just do it (don't ask questions)
+ -T, --notfm: do not initialize TFM files
+ -t tfm, --tfm name: override the guessing of TFM file names
+ -m mode, --mode mode: override the guessing of the Metafont mode
+
+ FILE: primary LaTeX file
+ FILES: included LaTeX files
+__HELP__
+
+die "$usage" unless &GetOptions(@options);
+die 'This is feynmf: $Id: feynmf.pl,v 1.5 1996/12/02 01:38:45 ohl Exp $'
+ . "\n" if $opt_version;
+die $help if $opt_help;
+die "$usage" unless $ARGV[0];
+
+########################################################################
+#
+# Finally, the main program:
+#
+########################################################################
+
+@temporay_files = ();
+sub END { unlink @temporay_files; }
+
+@tex = tex_names @ARGV;
+$tex_main = $tex[0];
+($dvi = $tex_main) =~ s/\.[^.]+$/.dvi/;
+
+find_programs;
+$mode = $opt_mode ? $opt_mode : guess_mode;
+fake_tfms (@opt_tfm ? @opt_tfm : guess_tfms @tex) unless $opt_notfm;
+run_latex $tex_main;
+clean_fonts if $opt_clean;
+run_mf mf_names $dvi;
+run_latex $tex_main;
+
+########################################################################
+
diff --git a/macros/latex/contrib/feynmf/feynmf209.ins b/macros/latex/contrib/feynmf/feynmf209.ins
new file mode 100644
index 0000000000..d1c2eb11a8
--- /dev/null
+++ b/macros/latex/contrib/feynmf/feynmf209.ins
@@ -0,0 +1,86 @@
+% feynmf209.ins - Feynman diagrams with METAFONT for LaTeX(2e)
+% Copyright (C) 1995 by Thorsten.Ohl@Physik.TH-Darmstadt.de
+% $Id: feynmf209.ins,v 1.2 1995/05/06 11:38:11 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.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+\def\batchfile{feynmf209.ins}
+\input docstrip.tex
+\keepsilent
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\preamble
+
+Copyright (C) 1989, 1990, 1992-1995 by Thorsten.Ohl@Physik.TH-Darmstadt.de
+
+This file is NOT the source for feynmf, because almost all comments
+have been stripped from it. It is NOT the preferred form of feynmf
+for making modifications to it.
+
+Therefore you can NOT redistribute and/or modify THIS file. You can
+however redistribute the complete source (feynmf.dtx and feynmf.ins)
+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.
+
+\endpreamble
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\Msg{Generating style file feynmf209.sty for the feynmf package:}
+\generateFile{feynmf209.sty}{f}{\from{feynmf.dtx}{style,209}}
+\Msg{Generating style file feynmp209.sty for the MetaPost version:}
+\generateFile{feynmp209.sty}{f}{\from{feynmf.dtx}{style,209,mp}}
+\Msg{Generating driver file for manual fmfman209.drv:}
+\generateFile{fmfman209.drv}{f}{\from{feynmf.dtx}{driver,209,manual}}
+\Msg{Generating alternate MetaPost driver file fmfman209ps.drv:}
+\generateFile{fmfman209ps.drv}{f}{\from{feynmf.dtx}{driver,209,manual,mp}}
+\Msg{Generating driver file for documentation feynmf209.drv:}
+\generateFile{feynmf209.drv}{f}{\from{feynmf.dtx}{driver,209}}
+\Msg{Generating alternate MetaPost driver file feynmp209.drv:}
+\generateFile{feynmp209.drv}{f}{\from{feynmf.dtx}{driver,209,mp}}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the files}
+\Msg{*}
+\Msg{*\space\space o feynmf209.sty into a directory searched by TeX}
+\Msg{*\space\space o feynmp209.sty into a directory searched by TeX}
+\Msg{*}
+\Msg{* You can remove the latter if you don't have John Hobby's}
+\Msg{* MetaPost system. Optionally you can copy the files}
+\Msg{* fmfman209.dtx and fmfman209ps.drv into a directory}
+\Msg{* searched by TeX, so that users can print a copy of}
+\Msg{* the documentation.}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
+Local Variables:
+mode:LaTeX
+fill-prefix:"% "
+page-delimiter:"^% %%%%%%%%%*\n"
+End:
diff --git a/macros/latex/contrib/feynmf/fmfman.pdf b/macros/latex/contrib/feynmf/fmfman.pdf
new file mode 100644
index 0000000000..84254f9f21
--- /dev/null
+++ b/macros/latex/contrib/feynmf/fmfman.pdf
Binary files differ
diff --git a/macros/latex/contrib/feynmf/manpics.1 b/macros/latex/contrib/feynmf/manpics.1
new file mode 100644
index 0000000000..a3efdb3d0c
--- /dev/null
+++ b/macros/latex/contrib/feynmf/manpics.1
@@ -0,0 +1,377 @@
+%!PS
+%%BoundingBox: -8 -5 378 285
+%%Creator: MetaPost
+%%CreationDate: 1996.12.02:1020
+%%Pages: 1
+%*Font: cmtt10 9.96265 9.96265 23:a777a08000000043fefdffa
+%*Font: cmr10 9.96265 9.96265 0c:8000000000000040808807e4fbe
+%*Font: cmcsc10 9.96265 9.96265 61:8
+%%EndProlog
+%%Page: 1 1
+3 273.54599 moveto
+(%) cmtt10 9.96265 fshow
+13.4607 273.54599 moveto
+(foo.tex) cmtt10 9.96265 fshow
+3 261.59079 moveto
+(...) cmtt10 9.96265 fshow
+3 249.63559 moveto
+(\\usepackage{feynmf}) cmtt10 9.96265 fshow
+3 237.6805 moveto
+(...) cmtt10 9.96265 fshow
+3 225.7253 moveto
+(\\begin{fmffile}{fd}) cmtt10 9.96265 fshow
+3 213.7701 moveto
+(\\begin{fmfchar*}\(100,50\)) cmtt10 9.96265 fshow
+3 201.81499 moveto
+(...) cmtt10 9.96265 fshow
+3 189.85979 moveto
+(\\end{fmfchar*}) cmtt10 9.96265 fshow
+3 177.90459 moveto
+(...) cmtt10 9.96265 fshow
+3 165.9495 moveto
+(\\end{fmffile}) cmtt10 9.96265 fshow
+3 153.9943 moveto
+(...) cmtt10 9.96265 fshow
+ 0 1.5 dtransform truncate idtransform setlinewidth pop [] 0 setdash
+ 1 setlinejoin 10 setmiterlimit
+newpath 0 150.9943 moveto
+136.75851 150.9943 lineto
+136.75851 283.46451 lineto
+0 283.46451 lineto
+ closepath stroke
+201.40671 273.54599 moveto
+(%) cmtt10 9.96265 fshow
+211.8674 273.54599 moveto
+(fd.mf) cmtt10 9.96265 fshow
+243.2494 273.54599 moveto
+(--) cmtt10 9.96265 fshow
+258.94041 273.54599 moveto
+(do) cmtt10 9.96265 fshow
+274.6315 273.54599 moveto
+(not) cmtt10 9.96265 fshow
+295.55281 273.54599 moveto
+(edit) cmtt10 9.96265 fshow
+201.40671 261.5909 moveto
+(input) cmtt10 9.96265 fshow
+232.78871 261.5909 moveto
+(feynmf) cmtt10 9.96265 fshow
+201.40671 249.6357 moveto
+(beginchar\(1,100*1pt#,50*1pt#,0\);) cmtt10 9.96265 fshow
+211.8674 237.6805 moveto
+(vinit;) cmtt10 9.96265 fshow
+211.8674 225.72539 moveto
+(...) cmtt10 9.96265 fshow
+211.8674 213.77019 moveto
+(vfreeze;) cmtt10 9.96265 fshow
+211.8674 201.81499 moveto
+(vdraw;) cmtt10 9.96265 fshow
+201.40671 189.8599 moveto
+(endchar;) cmtt10 9.96265 fshow
+201.40671 177.9047 moveto
+(...) cmtt10 9.96265 fshow
+newpath 198.40671 174.9047 moveto
+377.00789 174.9047 lineto
+377.00789 283.46451 lineto
+198.40671 283.46451 lineto
+ closepath stroke
+139.27658 127.42479 moveto
+(L) cmr10 9.96265 fshow
+141.91669 128.7116 moveto
+(a) cmcsc10 9.96265 fshow
+146.53278 127.42479 moveto
+(T) cmr10 9.96265 fshow
+152.06718 124.4222 moveto
+(E) cmr10 9.96265 fshow
+157.60197 127.42479 moveto
+(X) cmr10 9.96265 fshow
+168.39488 127.42479 moveto
+(lab) cmr10 9.96265 fshow
+181.95518 127.42479 moveto
+(els) cmr10 9.96265 fshow
+150.48738 115.46959 moveto
+(fd.log) cmtt10 9.96265 fshow
+newpath 136.27658 110.25568 moveto
+196.08018 110.25568 lineto
+196.08018 137.3433 lineto
+136.27658 137.3433 lineto
+ closepath stroke
+260.03513 73.72635 moveto
+(fon) cmr10 9.96265 fshow
+273.31862 73.72635 moveto
+(t) cmr10 9.96265 fshow
+280.51392 73.72635 moveto
+(metric) cmr10 9.96265 fshow
+258.78972 61.77126 moveto
+(information) cmr10 9.96265 fshow
+268.43433 49.81606 moveto
+(fd.tfm) cmtt10 9.96265 fshow
+newpath 255.78972 46.81604 moveto
+312.4609 46.81604 lineto
+312.4609 83.64485 lineto
+255.78972 83.64485 lineto
+ closepath stroke
+297.70406 124.92326 moveto
+(fon) cmr10 9.96265 fshow
+310.98766 124.92326 moveto
+(t) cmr10 9.96265 fshow
+318.18286 124.92326 moveto
+(bitmap) cmr10 9.96265 fshow
+302.51956 112.96806 moveto
+(fd.300gf) cmtt10 9.96265 fshow
+newpath 294.70406 107.75415 moveto
+352.17786 107.75415 lineto
+352.17786 134.84178 lineto
+294.70406 134.84178 lineto
+ closepath stroke
+71.11395 73.62527 moveto
+(L) cmr10 9.96265 fshow
+73.75406 74.91208 moveto
+(a) cmcsc10 9.96265 fshow
+78.37015 73.62527 moveto
+(T) cmr10 9.96265 fshow
+83.90456 70.62268 moveto
+(E) cmr10 9.96265 fshow
+89.43935 73.62527 moveto
+(X) cmr10 9.96265 fshow
+100.23225 73.62527 moveto
+(lab) cmr10 9.96265 fshow
+113.79256 73.62527 moveto
+(els) cmr10 9.96265 fshow
+84.93985 61.67007 moveto
+(fd.t1) cmtt10 9.96265 fshow
+newpath 68.11395 58.6701 moveto
+127.91759 58.6701 lineto
+127.91759 83.5438 lineto
+68.11395 83.5438 lineto
+ closepath stroke
+145.09079 73.62529 moveto
+(L) cmr10 9.96265 fshow
+147.7309 74.9121 moveto
+(a) cmcsc10 9.96265 fshow
+152.34698 73.62529 moveto
+(T) cmr10 9.96265 fshow
+157.8814 70.6227 moveto
+(E) cmr10 9.96265 fshow
+163.41618 73.62529 moveto
+(X) cmr10 9.96265 fshow
+174.20909 73.62529 moveto
+(lab) cmr10 9.96265 fshow
+187.7694 73.62529 moveto
+(els) cmr10 9.96265 fshow
+158.91669 61.67009 moveto
+(fd.t2) cmtt10 9.96265 fshow
+newpath 142.0908 58.67009 moveto
+201.89441 58.67009 lineto
+201.89441 83.54381 lineto
+142.0908 83.54381 lineto
+ closepath stroke
+3 26.9103 moveto
+(device) cmr10 9.96265 fshow
+33.1647 26.9103 moveto
+(indep) cmr10 9.96265 fshow
+57.2411 26.9103 moveto
+(enden) cmr10 9.96265 fshow
+82.4245 26.9103 moveto
+(t) cmr10 9.96265 fshow
+21.9567 14.9552 moveto
+(output) cmr10 9.96265 fshow
+54.6121 14.9552 moveto
+(\014le) cmr10 9.96265 fshow
+26.3433 3 moveto
+(foo.dvi) cmtt10 9.96265 fshow
+newpath 0 0 moveto
+89.29892 0 lineto
+89.29892 36.8288 lineto
+0 36.8288 lineto
+ closepath stroke
+344.34131 17.1691 moveto
+(prin) cmr10 9.96265 fshow
+361.8036 17.1691 moveto
+(ter) cmr10 9.96265 fshow
+351.3291 5.2139 moveto
+(lpr) cmtt10 9.96265 fshow
+newpath 341.34131 0 moveto
+377.00789 0 lineto
+377.00789 26.8227 lineto
+341.34131 26.8227 lineto
+ closepath stroke
+ [0 5 ] 2.5 setdash 1 setlinecap
+newpath 60.4738 150.99516 moveto
+46.84723 36.82794 lineto stroke
+ [] 0 setdash
+newpath 45.23123 48.05101 moveto
+46.84723 36.82794 lineto
+51.05927 47.3554 lineto
+ closepath
+gsave fill grestore stroke
+newpath 136.75862 220.95665 moveto
+198.4063 224.31696 lineto stroke
+newpath 187.62993 220.7905 moveto
+198.4063 224.31696 lineto
+187.31047 226.65115 lineto
+ closepath
+gsave fill grestore stroke
+ [3 3 ] 0 setdash
+newpath 225.11256 174.9049 moveto
+181.79681 137.34317 lineto stroke
+ [] 0 setdash
+newpath 188.14877 146.73578 moveto
+181.79681 137.34317 lineto
+191.99408 142.30142 lineto
+ closepath
+gsave fill grestore stroke
+ [3 3 ] 0 setdash
+newpath 286.52142 174.90431 moveto
+284.52765 83.64555 lineto stroke
+ [] 0 setdash
+newpath 281.8328 94.65973 moveto
+284.52765 83.64555 lineto
+287.70093 94.53152 lineto
+ closepath
+gsave fill grestore stroke
+ [3 3 ] 0 setdash
+newpath 305.68536 174.90546 moveto
+318.95493 134.84216 lineto stroke
+ [] 0 setdash
+newpath 312.72559 144.31616 moveto
+318.95493 134.84216 lineto
+318.29718 146.16156 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 148.65826 110.25569 moveto
+114.10428 83.544 lineto stroke
+ [] 0 setdash
+newpath 120.97444 92.56421 moveto
+114.10428 83.544 lineto
+124.56413 87.92065 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 167.67285 110.25569 moveto
+170.62027 83.54402 lineto stroke
+ [] 0 setdash
+newpath 166.50212 94.10835 moveto
+170.62027 83.54402 lineto
+172.33601 94.75209 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 85.42009 58.67027 moveto
+63.29907 36.82858 lineto stroke
+ [] 0 setdash
+newpath 69.03055 46.61168 moveto
+63.29907 36.82858 lineto
+73.15424 42.43526 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 142.0902 58.73383 moveto
+89.1517 36.82872 lineto stroke
+ [] 0 setdash
+newpath 98.14958 43.7278 moveto
+89.1517 36.82872 lineto
+100.39363 38.30455 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 255.79135 59.69133 moveto
+89.29996 27.14331 lineto stroke
+ [] 0 setdash
+newpath 99.485 32.12442 moveto
+89.29996 27.14331 lineto
+100.61101 26.36456 lineto
+ closepath
+gsave fill grestore stroke
+ [6 6 ] 0 setdash
+newpath 310.79498 46.81592 moveto
+341.34155 25.7245 lineto stroke
+ [] 0 setdash
+newpath 330.66159 29.53247 moveto
+341.34155 25.7245 lineto
+333.99643 34.36227 lineto
+ closepath
+gsave fill grestore stroke
+ [6 6 ] 0 setdash
+newpath 327.92677 107.75453 moveto
+354.7327 26.82231 lineto stroke
+ [] 0 setdash
+newpath 348.50327 36.29648 moveto
+354.7327 26.82231 lineto
+354.07495 38.1419 lineto
+ closepath
+gsave fill grestore stroke
+ [6 6 ] 0 setdash
+newpath 89.2971 17.70421 moveto
+341.33954 13.69502 lineto stroke
+ [] 0 setdash
+newpath 330.34155 10.93483 moveto
+341.33954 13.69502 lineto
+330.4349 16.80363 lineto
+ closepath
+gsave fill grestore stroke
+ 0.9 setgray
+newpath 194.80217 235.03342 moveto
+194.80217 241.75908 179.61087 241.76073 167.58246 241.76073 curveto
+155.55405 241.76073 140.36275 241.75908 140.36275 235.03342 curveto
+140.36275 228.30775 155.55405 228.3061 167.58246 228.3061 curveto
+179.61087 228.3061 194.80217 228.30775 194.80217 235.03342 curveto closepath
+ fill
+newpath 47.99121 93.91153 moveto
+47.99121 100.63719 32.79991 100.63884 20.7715 100.63884 curveto
+8.74309 100.63884 -6.44821 100.63719 -6.44821 93.91153 curveto
+-6.44821 87.18587 8.74309 87.18422 20.7715 87.18422 curveto
+32.79991 87.18422 47.99121 87.18587 47.99121 93.91153 curveto closepath fill
+newpath 279.85524 129.27493 moveto
+279.85524 135.59476 271.0797 135.5963 263.5022 135.5963 curveto
+255.9247 135.5963 247.14914 135.59476 247.14914 129.27493 curveto
+247.14914 122.95511 255.9247 122.95357 263.5022 122.95357 curveto
+271.0797 122.95357 279.85524 122.95511 279.85524 129.27493 curveto closepath
+ fill
+newpath 242.53806 3.30302 moveto
+242.53806 10.02869 227.34676 10.03033 215.31834 10.03033 curveto
+203.28993 10.03033 188.09863 10.02869 188.09863 3.30302 curveto
+188.09863 -3.42264 203.28993 -3.42429 215.31834 -3.42429 curveto
+227.34676 -3.42429 242.53806 -3.42264 242.53806 3.30302 curveto closepath fill
+ 0 setgray
+144.0459 231.98926 moveto
+(latex) cmtt10 9.96265 fshow
+175.4279 231.98926 moveto
+(foo) cmtt10 9.96265 fshow
+newpath 194.80217 235.03342 moveto
+194.80217 241.75908 179.61087 241.76073 167.58246 241.76073 curveto
+155.55405 241.76073 140.36275 241.75908 140.36275 235.03342 curveto
+140.36275 228.30775 155.55405 228.3061 167.58246 228.3061 curveto
+179.61087 228.3061 194.80217 228.30775 194.80217 235.03342 curveto closepath
+ stroke
+-2.76506 90.86737 moveto
+(latex) cmtt10 9.96265 fshow
+28.61694 90.86737 moveto
+(foo) cmtt10 9.96265 fshow
+newpath 47.99121 93.91153 moveto
+47.99121 100.63719 32.79991 100.63884 20.7715 100.63884 curveto
+8.74309 100.63884 -6.44821 100.63719 -6.44821 93.91153 curveto
+-6.44821 87.18587 8.74309 87.18422 20.7715 87.18422 curveto
+32.79991 87.18422 47.99121 87.18587 47.99121 93.91153 curveto closepath stroke
+250.42635 126.23077 moveto
+(mf) cmtt10 9.96265 fshow
+266.11734 126.23077 moveto
+(fd) cmtt10 9.96265 fshow
+newpath 279.85524 129.27493 moveto
+279.85524 135.59476 271.0797 135.5963 263.5022 135.5963 curveto
+255.9247 135.5963 247.14914 135.59476 247.14914 129.27493 curveto
+247.14914 122.95511 255.9247 122.95357 263.5022 122.95357 curveto
+271.0797 122.95357 279.85524 122.95511 279.85524 129.27493 curveto closepath
+ stroke
+191.78178 0.25887 moveto
+(dvixx) cmtt10 9.96265 fshow
+223.16379 0.25887 moveto
+(foo) cmtt10 9.96265 fshow
+newpath 242.53806 3.30302 moveto
+242.53806 10.02869 227.34676 10.03033 215.31834 10.03033 curveto
+203.28993 10.03033 188.09863 10.02869 188.09863 3.30302 curveto
+188.09863 -3.42264 203.28993 -3.42429 215.31834 -3.42429 curveto
+227.34676 -3.42429 242.53806 -3.42264 242.53806 3.30302 curveto closepath
+ stroke
+showpage
+%%EOF
diff --git a/macros/latex/contrib/feynmf/manpics.2 b/macros/latex/contrib/feynmf/manpics.2
new file mode 100644
index 0000000000..3e45c4c625
--- /dev/null
+++ b/macros/latex/contrib/feynmf/manpics.2
@@ -0,0 +1,358 @@
+%!PS
+%%BoundingBox: -8 -5 378 285
+%%Creator: MetaPost
+%%CreationDate: 1996.12.02:1020
+%%Pages: 1
+%*Font: cmtt10 9.96265 9.96265 23:a777208000000043fefdffa
+%*Font: cmr10 9.96265 9.96265 0c:8000000000000040898807c4bbe
+%*Font: cmcsc10 9.96265 9.96265 61:8
+%%EndProlog
+%%Page: 1 1
+3 273.54599 moveto
+(%) cmtt10 9.96265 fshow
+13.4607 273.54599 moveto
+(foo.tex) cmtt10 9.96265 fshow
+3 261.59079 moveto
+(...) cmtt10 9.96265 fshow
+3 249.63559 moveto
+(\\usepackage{feynmp}) cmtt10 9.96265 fshow
+3 237.6805 moveto
+(...) cmtt10 9.96265 fshow
+3 225.7253 moveto
+(\\begin{fmffile}{fd}) cmtt10 9.96265 fshow
+3 213.7701 moveto
+(\\begin{fmfchar*}\(100,50\)) cmtt10 9.96265 fshow
+3 201.81499 moveto
+(...) cmtt10 9.96265 fshow
+3 189.85979 moveto
+(\\end{fmfchar*}) cmtt10 9.96265 fshow
+3 177.90459 moveto
+(...) cmtt10 9.96265 fshow
+3 165.9495 moveto
+(\\end{fmffile}) cmtt10 9.96265 fshow
+3 153.9943 moveto
+(...) cmtt10 9.96265 fshow
+ 0 1.5 dtransform truncate idtransform setlinewidth pop [] 0 setdash
+ 1 setlinejoin 10 setmiterlimit
+newpath 0 150.9943 moveto
+136.75851 150.9943 lineto
+136.75851 283.46451 lineto
+0 283.46451 lineto
+ closepath stroke
+201.40671 273.54599 moveto
+(%) cmtt10 9.96265 fshow
+211.8674 273.54599 moveto
+(fd.mp) cmtt10 9.96265 fshow
+243.2494 273.54599 moveto
+(--) cmtt10 9.96265 fshow
+258.94041 273.54599 moveto
+(do) cmtt10 9.96265 fshow
+274.6315 273.54599 moveto
+(not) cmtt10 9.96265 fshow
+295.55281 273.54599 moveto
+(edit) cmtt10 9.96265 fshow
+201.40671 261.5909 moveto
+(input) cmtt10 9.96265 fshow
+232.78871 261.5909 moveto
+(feynmp) cmtt10 9.96265 fshow
+201.40671 249.6357 moveto
+(beginchar\(1,100*1pt#,50*1pt#,0\);) cmtt10 9.96265 fshow
+211.8674 237.6805 moveto
+(vinit;) cmtt10 9.96265 fshow
+211.8674 225.72539 moveto
+(...) cmtt10 9.96265 fshow
+211.8674 213.77019 moveto
+(vfreeze;) cmtt10 9.96265 fshow
+211.8674 201.81499 moveto
+(vdraw;) cmtt10 9.96265 fshow
+201.40671 189.8599 moveto
+(endchar;) cmtt10 9.96265 fshow
+201.40671 177.9047 moveto
+(...) cmtt10 9.96265 fshow
+newpath 198.40671 174.9047 moveto
+377.00789 174.9047 lineto
+377.00789 283.46451 lineto
+198.40671 283.46451 lineto
+ closepath stroke
+80.0949 126.31786 moveto
+(L) cmr10 9.96265 fshow
+82.735 127.60466 moveto
+(a) cmcsc10 9.96265 fshow
+87.35109 126.31786 moveto
+(T) cmr10 9.96265 fshow
+92.8855 123.31526 moveto
+(E) cmr10 9.96265 fshow
+98.42029 126.31786 moveto
+(X) cmr10 9.96265 fshow
+109.2132 126.31786 moveto
+(lab) cmr10 9.96265 fshow
+122.7735 126.31786 moveto
+(els) cmr10 9.96265 fshow
+93.92079 114.36266 moveto
+(fd.t1) cmtt10 9.96265 fshow
+newpath 77.0949 111.36263 moveto
+136.89851 111.36263 lineto
+136.89851 136.23637 lineto
+77.0949 136.23637 lineto
+ closepath stroke
+154.07172 126.31786 moveto
+(L) cmr10 9.96265 fshow
+156.71182 127.60466 moveto
+(a) cmcsc10 9.96265 fshow
+161.32791 126.31786 moveto
+(T) cmr10 9.96265 fshow
+166.86232 123.31526 moveto
+(E) cmr10 9.96265 fshow
+172.39711 126.31786 moveto
+(X) cmr10 9.96265 fshow
+183.19002 126.31786 moveto
+(lab) cmr10 9.96265 fshow
+196.75032 126.31786 moveto
+(els) cmr10 9.96265 fshow
+167.89761 114.36266 moveto
+(fd.t2) cmtt10 9.96265 fshow
+newpath 151.07172 111.36266 moveto
+210.87534 111.36266 lineto
+210.87534 136.23633 lineto
+151.07172 136.23633 lineto
+ closepath stroke
+234.55818 79.07835 moveto
+(encapsulated) cmr10 9.96265 fshow
+239.87158 67.12315 moveto
+(P) cmr10 9.96265 fshow
+246.37498 67.12315 moveto
+(ostScript) cmr10 9.96265 fshow
+256.17159 55.16806 moveto
+(\014le) cmr10 9.96265 fshow
+252.07599 43.21286 moveto
+(fd.1) cmtt10 9.96265 fshow
+newpath 231.55818 40.21284 moveto
+293.51509 40.21284 lineto
+293.51509 88.99686 lineto
+231.55818 88.99686 lineto
+ closepath stroke
+310.6883 149.94449 moveto
+(encapsulated) cmr10 9.96265 fshow
+316.0017 137.98929 moveto
+(P) cmr10 9.96265 fshow
+322.5051 137.98929 moveto
+(ostScript) cmr10 9.96265 fshow
+332.3017 126.0342 moveto
+(\014le) cmr10 9.96265 fshow
+328.2061 114.079 moveto
+(fd.2) cmtt10 9.96265 fshow
+newpath 307.6883 111.079 moveto
+369.6452 111.079 lineto
+369.6452 159.86296 lineto
+307.6883 159.86296 lineto
+ closepath stroke
+3 26.9103 moveto
+(device) cmr10 9.96265 fshow
+33.1647 26.9103 moveto
+(indep) cmr10 9.96265 fshow
+57.2411 26.9103 moveto
+(enden) cmr10 9.96265 fshow
+82.4245 26.9103 moveto
+(t) cmr10 9.96265 fshow
+21.9567 14.9552 moveto
+(output) cmr10 9.96265 fshow
+54.6121 14.9552 moveto
+(\014le) cmr10 9.96265 fshow
+26.3433 3 moveto
+(foo.dvi) cmtt10 9.96265 fshow
+newpath 0 0 moveto
+89.29892 0 lineto
+89.29892 36.8288 lineto
+0 36.8288 lineto
+ closepath stroke
+344.34131 17.1691 moveto
+(prin) cmr10 9.96265 fshow
+361.8036 17.1691 moveto
+(ter) cmr10 9.96265 fshow
+351.3291 5.2139 moveto
+(lpr) cmtt10 9.96265 fshow
+newpath 341.34131 0 moveto
+377.00789 0 lineto
+377.00789 26.8227 lineto
+341.34131 26.8227 lineto
+ closepath stroke
+ [0 5 ] 2.5 setdash 1 setlinecap
+newpath 60.4738 150.99516 moveto
+46.84723 36.82794 lineto stroke
+ [] 0 setdash
+newpath 45.23123 48.05101 moveto
+46.84723 36.82794 lineto
+51.05927 47.3554 lineto
+ closepath
+gsave fill grestore stroke
+newpath 136.75862 220.95665 moveto
+198.4063 224.31696 lineto stroke
+newpath 187.62993 220.7905 moveto
+198.4063 224.31696 lineto
+187.31047 226.65115 lineto
+ closepath
+gsave fill grestore stroke
+ [3 3 ] 0 setdash
+newpath 198.40533 177.10634 moveto
+128.32295 136.23636 lineto stroke
+ [] 0 setdash
+newpath 136.30531 144.28853 moveto
+128.32295 136.23636 lineto
+139.26195 139.21855 lineto
+ closepath
+gsave fill grestore stroke
+ [3 3 ] 0 setdash
+newpath 232.73296 174.9049 moveto
+193.56981 136.23663 lineto stroke
+ [] 0 setdash
+newpath 199.30153 146.0201 moveto
+193.56981 136.23663 lineto
+203.42534 141.84349 lineto
+ closepath
+gsave fill grestore stroke
+ [3 3 ] 0 setdash
+newpath 279.40594 174.90564 moveto
+266.26721 88.99739 lineto stroke
+ [] 0 setdash
+newpath 265.0221 100.26695 moveto
+266.26721 88.99739 lineto
+270.8237 99.37968 lineto
+ closepath
+gsave fill grestore stroke
+ [3 3 ] 0 setdash
+newpath 317.22345 174.9049 moveto
+325.40309 159.86266 lineto stroke
+ [] 0 setdash
+newpath 317.59297 168.08232 moveto
+325.40309 159.86266 lineto
+322.74916 170.88615 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 99.63902 111.36285 moveto
+55.544 36.82936 lineto stroke
+ [] 0 setdash
+newpath 58.59505 47.75027 moveto
+55.544 36.82936 lineto
+63.64674 44.76163 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 164.88574 111.36285 moveto
+68.47069 36.82936 lineto stroke
+ [] 0 setdash
+newpath 75.3413 45.8502 moveto
+68.47069 36.82936 lineto
+78.93123 41.20634 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 231.55711 58.03741 moveto
+89.30014 27.87999 lineto stroke
+ [] 0 setdash
+newpath 99.40572 33.02216 moveto
+89.30014 27.87999 lineto
+100.62291 27.28046 lineto
+ closepath
+gsave fill grestore stroke
+ [0 5 ] 2.5 setdash
+newpath 307.6885 123.1377 moveto
+89.2974 36.19 lineto stroke
+ [] 0 setdash
+newpath 98.3867 42.96718 moveto
+89.2974 36.19 lineto
+100.55754 37.51454 lineto
+ closepath
+gsave fill grestore stroke
+ [6 6 ] 0 setdash
+newpath 293.51459 48.19444 moveto
+341.34091 22.85867 lineto stroke
+ [] 0 setdash
+newpath 330.28876 25.39243 moveto
+341.34091 22.85867 lineto
+333.03635 30.57904 lineto
+ closepath
+gsave fill grestore stroke
+ [6 6 ] 0 setdash
+newpath 342.7651 111.07805 moveto
+356.92136 26.82234 lineto stroke
+ [] 0 setdash
+newpath 352.21228 37.13753 moveto
+356.92136 26.82234 lineto
+358.00076 38.11009 lineto
+ closepath
+gsave fill grestore stroke
+ [6 6 ] 0 setdash
+newpath 89.2971 17.70421 moveto
+341.33954 13.69502 lineto stroke
+ [] 0 setdash
+newpath 330.34155 10.93483 moveto
+341.33954 13.69502 lineto
+330.4349 16.80363 lineto
+ closepath
+gsave fill grestore stroke
+ 0.9 setgray
+newpath 194.80217 235.03342 moveto
+194.80217 241.75908 179.61087 241.76073 167.58246 241.76073 curveto
+155.55405 241.76073 140.36275 241.75908 140.36275 235.03342 curveto
+140.36275 228.30775 155.55405 228.3061 167.58246 228.3061 curveto
+179.61087 228.3061 194.80217 228.30775 194.80217 235.03342 curveto closepath
+ fill
+newpath 47.99121 93.91153 moveto
+47.99121 100.63719 32.79991 100.63884 20.7715 100.63884 curveto
+8.74309 100.63884 -6.44821 100.63719 -6.44821 93.91153 curveto
+-6.44821 87.18587 8.74309 87.18422 20.7715 87.18422 curveto
+32.79991 87.18422 47.99121 87.18587 47.99121 93.91153 curveto closepath fill
+newpath 252.92401 155.57076 moveto
+252.92401 162.53381 243.98402 163.69768 235.87234 163.69768 curveto
+227.76065 163.69768 218.82066 162.53381 218.82066 155.57076 curveto
+218.82066 148.6077 227.76065 147.44383 235.87234 147.44383 curveto
+243.98402 147.44383 252.92401 148.6077 252.92401 155.57076 curveto closepath
+ fill
+newpath 242.53806 3.30302 moveto
+242.53806 10.02869 227.34676 10.03033 215.31834 10.03033 curveto
+203.28993 10.03033 188.09863 10.02869 188.09863 3.30302 curveto
+188.09863 -3.42264 203.28993 -3.42429 215.31834 -3.42429 curveto
+227.34676 -3.42429 242.53806 -3.42264 242.53806 3.30302 curveto closepath fill
+ 0 setgray
+144.0459 231.98926 moveto
+(latex) cmtt10 9.96265 fshow
+175.4279 231.98926 moveto
+(foo) cmtt10 9.96265 fshow
+newpath 194.80217 235.03342 moveto
+194.80217 241.75908 179.61087 241.76073 167.58246 241.76073 curveto
+155.55405 241.76073 140.36275 241.75908 140.36275 235.03342 curveto
+140.36275 228.30775 155.55405 228.3061 167.58246 228.3061 curveto
+179.61087 228.3061 194.80217 228.30775 194.80217 235.03342 curveto closepath
+ stroke
+-2.76506 90.86737 moveto
+(latex) cmtt10 9.96265 fshow
+28.61694 90.86737 moveto
+(foo) cmtt10 9.96265 fshow
+newpath 47.99121 93.91153 moveto
+47.99121 100.63719 32.79991 100.63884 20.7715 100.63884 curveto
+8.74309 100.63884 -6.44821 100.63719 -6.44821 93.91153 curveto
+-6.44821 87.18587 8.74309 87.18422 20.7715 87.18422 curveto
+32.79991 87.18422 47.99121 87.18587 47.99121 93.91153 curveto closepath stroke
+222.7965 153.63354 moveto
+(mp) cmtt10 9.96265 fshow
+238.48749 153.63354 moveto
+(fd) cmtt10 9.96265 fshow
+newpath 252.92401 155.57076 moveto
+252.92401 162.53381 243.98402 163.69768 235.87234 163.69768 curveto
+227.76065 163.69768 218.82066 162.53381 218.82066 155.57076 curveto
+218.82066 148.6077 227.76065 147.44383 235.87234 147.44383 curveto
+243.98402 147.44383 252.92401 148.6077 252.92401 155.57076 curveto closepath
+ stroke
+191.78178 0.25887 moveto
+(dvixx) cmtt10 9.96265 fshow
+223.16379 0.25887 moveto
+(foo) cmtt10 9.96265 fshow
+newpath 242.53806 3.30302 moveto
+242.53806 10.02869 227.34676 10.03033 215.31834 10.03033 curveto
+203.28993 10.03033 188.09863 10.02869 188.09863 3.30302 curveto
+188.09863 -3.42264 203.28993 -3.42429 215.31834 -3.42429 curveto
+227.34676 -3.42429 242.53806 -3.42264 242.53806 3.30302 curveto closepath
+ stroke
+showpage
+%%EOF
diff --git a/macros/latex/contrib/feynmf/manpics.3 b/macros/latex/contrib/feynmf/manpics.3
new file mode 100644
index 0000000000..37ddc92cd8
--- /dev/null
+++ b/macros/latex/contrib/feynmf/manpics.3
@@ -0,0 +1,190 @@
+%!PS
+%%BoundingBox: 0 0 378 284
+%%Creator: MetaPost
+%%CreationDate: 1996.12.02:1020
+%%Pages: 1
+%*Font: cmtt10 9.96265 9.96265 2e:80000000000217b37b85
+%*Font: cmr10 9.96265 9.96265 3a:8050242201f7bee9
+%*Font: cmcsc10 9.96265 9.96265 49:880400988a51
+%*Font: manfnt 9.96265 9.96265 41:8c0e1
+%%EndProlog
+%%Page: 1 1
+ 0.9 setgray
+newpath 0 283.46451 moveto
+377.00789 283.46451 lineto
+377.00789 141.73225 lineto
+0 141.73225 lineto
+ closepath fill
+ 0.6 setgray
+newpath 0 141.73225 moveto
+377.00789 141.73225 lineto
+377.00789 0 lineto
+0 0 lineto
+ closepath fill
+ 0.8 setgray
+newpath 0 255.1185 moveto
+211.12029 225.35455 lineto
+90.48143 41.10217 lineto
+0 28.34601 lineto
+ closepath fill
+ 0.7 setgray
+newpath 211.12029 225.35455 moveto
+301.60172 212.59839 lineto
+301.60172 70.86613 lineto
+90.48143 41.10217 lineto
+ closepath fill
+ 0 setgray 0 1.5 dtransform truncate idtransform setlinewidth pop [] 0 setdash
+ 1 setlinecap 1 setlinejoin 10 setmiterlimit
+newpath 197.92957 161.1049 moveto
+190.7286 165.05524 183.00302 168.08354 174.92825 170.07828 curveto
+160.2565 173.7027 145.27185 173.85275 131.02252 170.87178 curveto stroke
+newpath 141.4189 175.39806 moveto
+137.86195 174.08682 134.39113 172.57457 131.02252 170.87178 curveto
+134.79121 170.66212 138.55318 170.23636 142.2892 169.59346 curveto
+ closepath
+gsave fill grestore stroke
+newpath 102.22244 107.68922 moveto
+109.63477 102.66844 117.87709 98.82445 126.67346 96.37845 curveto
+142.14388 92.0766 157.99133 92.20665 172.7073 96.14563 curveto stroke
+newpath 162.53993 91.12671 moveto
+166.04344 92.5819 169.43913 94.2599 172.7073 96.14563 curveto
+168.93413 96.14662 165.15437 96.39128 161.39265 96.88281 curveto
+ closepath
+gsave fill grestore stroke
+newpath 352.00128 200.6733 moveto
+356.07718 181.37106 358.15634 161.62073 358.15634 141.73225 curveto
+358.15634 121.84378 356.07718 102.09344 352.00128 82.79121 curveto stroke
+newpath 351.16791 94.09874 moveto
+351.5207 90.33415 351.79851 86.56422 352.00128 82.79121 curveto
+353.71217 86.16014 355.35655 89.56389 356.93332 93.0005 curveto
+ closepath
+gsave fill grestore stroke
+ 1 setgray
+newpath 142.72241 178.5822 moveto
+195.79553 178.5822 lineto
+195.79553 192.33093 lineto
+142.72241 192.33093 lineto
+ closepath fill
+ 0 setgray
+145.72241 182.41241 moveto
+(\\fmfforce) cmtt10 9.96265 fshow
+ 1 setgray
+newpath 110.59761 64.45175 moveto
+142.74931 64.45175 lineto
+142.74931 90.70917 lineto
+110.59761 90.70917 lineto
+ closepath fill
+ 0 setgray
+116.21281 81.62085 moveto
+(vloc) cmtt10 9.96265 fshow
+113.59761 69.66565 moveto
+(vpath) cmtt10 9.96265 fshow
+ 1 setgray
+newpath 309.87466 141.73225 moveto
+352.48706 141.73225 lineto
+352.48706 155.48099 lineto
+309.87466 155.48099 lineto
+ closepath fill
+ 0 setgray
+312.87466 145.56247 moveto
+(\\fmfcmd) cmtt10 9.96265 fshow
+ 1 setgray
+newpath 204.28741 75.5525 moveto
+295.93243 75.5525 lineto
+295.93243 207.912 lineto
+204.28741 207.912 lineto
+ closepath fill
+ 0 setgray
+207.28741 198.1042 moveto
+(Immedia) cmcsc10 9.96265 fshow
+246.4403 198.1042 moveto
+(te) cmcsc10 9.96265 fshow
+261.64992 198.1042 moveto
+(Mode) cmcsc10 9.96265 fshow
+233.3778 174.1938 moveto
+(Ob) cmr10 9.96265 fshow
+247.21492 174.1938 moveto
+(jects:) cmr10 9.96265 fshow
+268.49622 162.23871 moveto
+(pairs) cmr10 9.96265 fshow
+265.75641 150.28351 moveto
+(paths) cmr10 9.96265 fshow
+218.15712 126.3732 moveto
+(Commands:) cmr10 9.96265 fshow
+242.53842 114.418 moveto
+(\\fmfi{}{}) cmtt10 9.96265 fshow
+247.76881 102.4628 moveto
+(\\fmfiv{}) cmtt10 9.96265 fshow
+237.30812 90.5077 moveto
+(\\fmfiequ{}) cmtt10 9.96265 fshow
+273.92052 78.5525 moveto
+(...) cmtt10 9.96265 fshow
+ 1 setgray
+newpath 5.66928 69.57495 moveto
+90.87238 69.57495 lineto
+90.87238 213.88956 lineto
+5.66928 213.88956 lineto
+ closepath fill
+ 0 setgray
+12.94829 204.08176 moveto
+(Ver) cmcsc10 9.96265 fshow
+31.94908 204.08176 moveto
+(tex) cmcsc10 9.96265 fshow
+53.26907 204.08176 moveto
+(Mode) cmcsc10 9.96265 fshow
+23.89008 180.17145 moveto
+(Ob) cmr10 9.96265 fshow
+37.72708 180.17145 moveto
+(jects:) cmr10 9.96265 fshow
+48.49228 168.21625 moveto
+(v) cmr10 9.96265 fshow
+53.47368 168.21625 moveto
+(ertices) cmr10 9.96265 fshow
+63.98978 156.26115 moveto
+(arcs) cmr10 9.96265 fshow
+42.98508 144.30595 moveto
+(p) cmr10 9.96265 fshow
+48.79668 144.30595 moveto
+(olygons) cmr10 9.96265 fshow
+8.66928 120.39565 moveto
+(Commands:) cmr10 9.96265 fshow
+39.38799 108.44044 moveto
+(\\fmf{}{}) cmtt10 9.96265 fshow
+34.15758 96.48524 moveto
+(\\fmfv{}{}) cmtt10 9.96265 fshow
+28.92728 84.53015 moveto
+(\\fmfleft{}) cmtt10 9.96265 fshow
+64.43268 72.57495 moveto
+(...) cmtt10 9.96265 fshow
+ 1 setgray
+newpath 326.35895 253.48004 moveto
+358.15634 253.48004 lineto
+358.15634 269.29042 lineto
+326.35895 269.29042 lineto
+ closepath fill
+ 0 setgray
+329.35895 259.48264 moveto
+(L) cmr10 9.96265 fshow
+331.99905 260.76944 moveto
+(a) cmcsc10 9.96265 fshow
+336.61514 259.48264 moveto
+(T) cmr10 9.96265 fshow
+342.14955 256.48004 moveto
+(E) cmr10 9.96265 fshow
+347.68434 259.48264 moveto
+(X) cmr10 9.96265 fshow
+ 1 setgray
+newpath 301.01505 14.17409 moveto
+358.15634 14.17409 lineto
+358.15634 26.1517 lineto
+301.01505 26.1517 lineto
+ closepath fill
+ 0 setgray
+304.01505 17.1741 moveto
+(MET) manfnt 9.96265 fshow
+323.71884 17.1741 moveto
+(AF) manfnt 9.96265 fshow
+336.11674 17.1741 moveto
+(ONT) manfnt 9.96265 fshow
+showpage
+%%EOF
diff --git a/macros/latex/contrib/feynmf/manpics.mp b/macros/latex/contrib/feynmf/manpics.mp
new file mode 100644
index 0000000000..e5e666e6f7
--- /dev/null
+++ b/macros/latex/contrib/feynmf/manpics.mp
@@ -0,0 +1,331 @@
+% manpics.mp -- pictures for the feynmf manual
+% Copyright (C) 1995 by Thorsten.Ohl @ Physik.TH-Darmstadt.de
+% $Id: manpics.mp,v 1.5 1996/10/08 20:22:02 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.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+input boxes
+
+verbatimtex
+ \font\sc=cmcsc10
+ \font\manfnt=manfnt
+ \def\LaTeX{%
+ {\rm L\kern-.36em\raise.3ex\hbox{\sc a}\kern-.15em%
+ T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}
+ \def\cs#1{{\tt\char`\\#1}}
+ \def\arg#1{{\tt\char`\{#1\char`\}}}
+ \def\c{{\tt\char`\%}}
+ \parindent=0pt
+ \parskip=0pt
+ \def\ctr#1{\vbox{\halign{\hfil##\hfil\cr#1\cr}}}
+etex;
+
+def first_latex_pass = \ enddef;
+def second_latex_pass = dashed withdots enddef;
+def mf_pass = dashed evenly enddef;
+def dvixx_pass = dashed evenly scaled 2 enddef;
+
+def connect (suffix from, to) =
+ (from.c -- to.c cutbefore bpath.from cutafter bpath.to)
+enddef;
+
+ahlength := 4mm;
+ahangle := 30;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+beginfig (1);
+ h := 10cm;
+ w := 13.3cm;
+ pickup pencircle scaled 1.5;
+ boxit.tex (btex \tt\vbox{
+ \hbox{\c\ foo.tex}
+ \hbox{...}
+ \hbox{\cs{usepackage}\arg{feynmf}}
+ \hbox{...}
+ \hbox{\cs{begin}\arg{fmffile}\arg{fd}}
+ \hbox{\cs{begin}\arg{fmfchar*}(100,50)}
+ \hbox{...}
+ \hbox{\cs{end}\arg{fmfchar*}}
+ \hbox{...}
+ \hbox{\cs{end}\arg{fmffile}}
+ \hbox{...}}
+ etex);
+ boxit.mf (btex \tt\vbox{
+ \hbox{\c\ fd.mf -- do not edit}
+ \hbox{input feynmf}
+ \hbox{beginchar(1,100*1pt\#,50*1pt\#,0);}
+ \hbox{\quad vinit;}
+ \hbox{\quad ...}
+ \hbox{\quad vfreeze;}
+ \hbox{\quad vdraw;}
+ \hbox{endchar;}
+ \hbox{...}}
+ etex);
+ boxit.log (btex \ctr{\LaTeX{} labels\cr{\tt fd.log}} etex);
+ boxit.t1 (btex \ctr{\LaTeX{} labels\cr{\tt fd.t1}} etex);
+ boxit.t2 (btex \ctr{\LaTeX{} labels\cr{\tt fd.t2}} etex);
+ boxit.tfm (btex \ctr{font metric\cr information\cr{\tt fd.tfm}} etex);
+ boxit.gf (btex \ctr{font bitmap\cr{\tt fd.300gf}} etex);
+ boxit.dvi (btex \ctr{device independent\cr output file\cr{\tt foo.dvi}} etex);
+ boxit.lpr (btex \ctr{printer\cr{\tt lpr}} etex);
+ tex.nw = (0,h); mf.ne = (w,h);
+ dvi.sw = (0,0); lpr.se = (w,0);
+ gf.c = .5[mf.c,lpr.c];
+ log.c = .5[mf.c,dvi.c];
+ tfm.c = .75[log.c,gf.c] - (0,2cm);
+ .5[log.c,dvi.c] = .1[t1.c,t2.c];
+ t2.w - t1.e = (5mm,0);
+ % forsuffixes $ = tex, mf, log, tfm, gf, t1, t2, dvi, lpr:
+ % fill bpath.$ withcolor .9white;
+ % endfor
+ drawboxed (tex, mf, log, tfm, gf, t1, t2, dvi, lpr);
+ drawarrow connect (tex, dvi) second_latex_pass;
+ drawarrow connect (tex, mf) first_latex_pass;
+ drawarrow connect (mf, log) mf_pass;
+ drawarrow connect (mf, tfm) mf_pass;
+ drawarrow connect (mf, gf) mf_pass;
+ drawarrow connect (log, t1) second_latex_pass;
+ drawarrow connect (log, t2) second_latex_pass;
+ drawarrow connect (t1, dvi) second_latex_pass;
+ drawarrow connect (t2, dvi) second_latex_pass;
+ drawarrow connect (tfm, dvi) second_latex_pass;
+ drawarrow connect (tfm, lpr) dvixx_pass;
+ drawarrow connect (gf, lpr) dvixx_pass;
+ drawarrow connect (dvi, lpr) dvixx_pass;
+ circleit.latex1 (btex {\tt latex foo} etex);
+ latex1.dx = latex1.dy;
+ circleit.latex2 (btex {\tt latex foo} etex);
+ latex2.dx = latex2.dy;
+ % circleit.mf.gf (btex {\tt mf fd} etex);
+ % mf.gf.dx = mf.gf.dy;
+ circleit.mf.tfm (btex {\tt mf fd} etex);
+ mf.tfm.dx = mf.tfm.dy;
+ % circleit.mf.log (btex {\tt mf fd} etex);
+ % mf.log.dx = mf.log.dy;
+ circleit.dvixx (btex {\tt dvixx foo} etex);
+ dvixx.dx = dvixx.dy;
+ latex1.s - (0,2mm) = point .5 of connect (tex, mf);
+ latex2.e + (2mm,0) = point .5 of connect (tex, dvi);
+ % mf.gf.w - (2mm,0) = point .5 of connect (mf, gf);
+ mf.tfm.e + (2mm,0) = point .5 of connect (mf, tfm);
+ % mf.log.w - (2mm,0) = point .5 of connect (mf, log);
+ dvixx.n + (0,2mm) = point .5 of connect (dvi, lpr);
+ forsuffixes $ = latex1, latex2, mf.tfm, dvixx:
+ fill bpath.$ withcolor .9white;
+ endfor
+ drawboxed (latex1, latex2, mf.tfm, dvixx);
+endfig;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+beginfig (2);
+ h := 10cm;
+ w := 13.3cm;
+ pickup pencircle scaled 1.5;
+ boxit.tex (btex \tt\vbox{
+ \hbox{\c\ foo.tex}
+ \hbox{...}
+ \hbox{\cs{usepackage}\arg{feynmp}}
+ \hbox{...}
+ \hbox{\cs{begin}\arg{fmffile}\arg{fd}}
+ \hbox{\cs{begin}\arg{fmfchar*}(100,50)}
+ \hbox{...}
+ \hbox{\cs{end}\arg{fmfchar*}}
+ \hbox{...}
+ \hbox{\cs{end}\arg{fmffile}}
+ \hbox{...}}
+ etex);
+ boxit.mp (btex \tt\vbox{
+ \hbox{\c\ fd.mp -- do not edit}
+ \hbox{input feynmp}
+ \hbox{beginchar(1,100*1pt\#,50*1pt\#,0);}
+ \hbox{\quad vinit;}
+ \hbox{\quad ...}
+ \hbox{\quad vfreeze;}
+ \hbox{\quad vdraw;}
+ \hbox{endchar;}
+ \hbox{...}}
+ etex);
+ boxit.t1 (btex \ctr{\LaTeX{} labels\cr{\tt fd.t1}} etex);
+ boxit.t2 (btex \ctr{\LaTeX{} labels\cr{\tt fd.t2}} etex);
+ boxit.p1 (btex \ctr{encapsulated\cr PostScript\cr file\cr{\tt fd.1}} etex);
+ boxit.p2 (btex \ctr{encapsulated\cr PostScript\cr file\cr{\tt fd.2}} etex);
+ boxit.dvi (btex \ctr{device independent\cr output file\cr{\tt foo.dvi}} etex);
+ boxit.lpr (btex \ctr{printer\cr{\tt lpr}} etex);
+ tex.nw = (0,h); mp.ne = (w,h);
+ dvi.sw = (0,0); lpr.se = (w,0);
+ .5[mp.c,dvi.c] = .8[t1.c,t2.c];
+ t2.w - t1.e = (5mm,0);
+ .5[mp.c,lpr.c] = .8[p1.c,p2.c];
+ p2.w - p1.e = (5mm,2.5cm);
+ drawboxed (tex, mp, t1, t2, p1, p2, dvi, lpr);
+ drawarrow connect (tex, dvi) second_latex_pass;
+ drawarrow connect (tex, mp) first_latex_pass;
+ drawarrow connect (mp, t1) mf_pass;
+ drawarrow connect (mp, t2) mf_pass;
+ drawarrow connect (mp, p1) mf_pass;
+ drawarrow connect (mp, p2) mf_pass;
+ drawarrow connect (t1, dvi) second_latex_pass;
+ drawarrow connect (t2, dvi) second_latex_pass;
+ drawarrow connect (p1, dvi) second_latex_pass;
+ drawarrow connect (p2, dvi) second_latex_pass;
+ drawarrow connect (p1, lpr) dvixx_pass;
+ drawarrow connect (p2, lpr) dvixx_pass;
+ drawarrow connect (dvi, lpr) dvixx_pass;
+ circleit.latex1 (btex {\tt latex foo} etex);
+ latex1.dx = latex1.dy;
+ circleit.latex2 (btex {\tt latex foo} etex);
+ latex2.dx = latex2.dy;
+ circleit.run.mp (btex {\tt mp fd} etex);
+ run.mp.dx = run.mp.dy;
+ circleit.dvixx (btex {\tt dvixx foo} etex);
+ dvixx.dx = dvixx.dy;
+ latex1.s - (0,2mm) = point .5 of connect (tex, mp);
+ latex2.e + (2mm,0) = point .5 of connect (tex, dvi);
+ run.mp.w - (2mm,0) = point .5 of connect (mp, t2);
+ dvixx.n + (0,2mm) = point .5 of connect (dvi, lpr);
+ forsuffixes $ = latex1, latex2, run.mp, dvixx:
+ fill bpath.$ withcolor .9white;
+ endfor
+ drawboxed (latex1, latex2, run.mp, dvixx);
+endfig;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+vardef declare_boxes (text l) =
+ forsuffixes $ = l:
+ pair $.n, $.e, $.s, $.w, $.ne, $.se, $.sw, $.nw, $.c;
+ endfor
+enddef;
+
+vardef setup_boxes (text l) =
+ forsuffixes $ = l:
+ $.n = .5[$.nw, $.ne]; $.s = .5[$.sw, $.se];
+ $.w = .5[$.nw, $.sw]; $.e = .5[$.ne, $.se];
+ $.c = .5[$.n, $.s];
+ endfor
+enddef;
+
+vardef border suffix b =
+ b.nw -- b.ne -- b.se -- b.sw -- cycle
+enddef;
+
+beginfig (3);
+ h := 10cm;
+ w := 13.3cm;
+ pickup pencircle scaled 1.5;
+
+ declare_boxes (mf, tex, immediate, list);
+ setup_boxes (mf, tex);
+
+ list.n = .5[list.nw, list.ne];
+ list.s = .5[list.sw, list.se];
+ list.w = .5[list.nw, list.sw];
+ % list.e free!
+ list.c = .5[list.n, list.s];
+
+ immediate.n = .5[immediate.nw, immediate.ne];
+ immediate.s = .5[immediate.sw, immediate.se];
+ % immediate.w free!
+ immediate.e = .5[immediate.ne, immediate.se];
+ immediate.c = .5[immediate.n, immediate.s];
+
+ mf.sw = (0,0); mf.se = (w,0);
+ tex.nw = (0,h); tex.ne = (w,h);
+
+ mf.nw = tex.sw; mf.ne = tex.se;
+ tex.sw = .5[tex.nw,mf.sw]; tex.se = .5[tex.ne,mf.se];
+
+ list.w = .5[tex.nw,mf.sw];
+ list.e - list.w = immediate.e - immediate.w = (.4w,0);
+ list.nw - list.sw = (0,.8h);
+ immediate.ne - immediate.se = (0,.5h);
+ immediate.w = list.e; immediate.nw = list.ne; immediate.sw = list.se;
+
+ list.ne = .7[list.nw,immediate.ne];
+ list.se = .3[list.sw,immediate.se];
+
+ fill border tex withcolor .9white; % draw border tex;
+ fill border mf withcolor .6white; % draw border mf;
+ fill border list withcolor .8white; % draw border list;
+ fill border immediate withcolor .7white; % draw border immediate;
+
+ path imm_to_lst, lst_to_imm, tex_to_mf;
+
+ imm_to_lst = immediate.c .. .7[immediate.sw,immediate.nw] .. list.c;
+ lst_to_imm = list.c .. .3[immediate.sw,immediate.nw] .. immediate.c;
+ tex_to_mf = .85[tex.nw,tex.ne] .. .95[tex.sw,tex.se] .. .85[mf.sw,mf.se];
+
+ drawarrow subpath (.3length(imm_to_lst), .7length(imm_to_lst)) of imm_to_lst;
+ drawarrow subpath (.3length(lst_to_imm), .7length(lst_to_imm)) of lst_to_imm;
+ drawarrow subpath (.3length(tex_to_mf), .7length(tex_to_mf)) of tex_to_mf;
+
+ boxit.name.imm_to_lst (btex \cs{fmfforce} etex);
+ boxit.name.lst_to_imm (btex \tt\ctr{vloc\cr vpath} etex);
+ boxit.name.tex_to_mf (btex \cs{fmfcmd} etex);
+ boxit.name.tex (btex \LaTeX etex);
+ boxit.name.mf (btex \manfnt METAFONT etex);
+
+ name.imm_to_lst.s = point .5length(imm_to_lst) of imm_to_lst + (-2mm,3mm);
+ name.lst_to_imm.n = point .5length(lst_to_imm) of lst_to_imm - (0,2mm);
+ name.tex_to_mf.se = point .5length(tex_to_mf) of tex_to_mf - (2mm,0);
+ name.tex.ne = (.95w,.95h);
+ name.mf.se = (.95w,.05h);
+
+ boxit.name.lst (btex \vbox{\halign{
+ \hfil # \cr
+ {\sc Vertex Mode}\cr\cr
+ Objects:\qquad\cr
+ vertices\cr
+ arcs\cr
+ polygons\cr\cr
+ Commands:\qquad\cr
+ \cs{fmf}\arg{}\arg{}\cr
+ \cs{fmfv}\arg{}\arg{}\cr
+ \cs{fmfleft}\arg{}\cr
+ {\tt ...}\cr}}
+ etex);
+
+ boxit.name.imm (btex \vbox{\halign{
+ \hfil #\cr
+ {\sc Immediate Mode}\cr\cr
+ Objects:\qquad\cr
+ pairs\cr
+ paths\cr\cr
+ Commands:\qquad\cr
+ \cs{fmfi}\arg{}\arg{}\cr
+ \cs{fmfiv}\arg{}\cr
+ \cs{fmfiequ}\arg{}\cr
+ {\tt ...}\cr}}
+ etex);
+
+ name.lst.w = list.w + (2mm,0);
+ name.imm.e = immediate.e - (2mm,0);
+
+ forsuffixes $ = imm_to_lst, lst_to_imm, tex_to_mf, imm, lst, tex, mf:
+ fill bpath.name.$ withcolor white;
+ drawunboxed (name.$);
+ endfor
+
+endfig;
+
+end;
+endinput
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Local Variables:
+compile-command:"sh -c 'mp manpics && tex mproof manpics.[0-9]* && dvips mproof'"
+End:
diff --git a/macros/latex/contrib/feynmf/template.tex b/macros/latex/contrib/feynmf/template.tex
new file mode 100644
index 0000000000..5fa885aaa2
--- /dev/null
+++ b/macros/latex/contrib/feynmf/template.tex
@@ -0,0 +1,24 @@
+% template.tex -- trivial FeynMF example
+% $Id: template.tex,v 1.1 1996/12/02 01:38:45 ohl Exp $
+% To typeset, either use the feynmf script
+% $ feynmf template
+% or run Metafont manually
+% $ latex template
+% $ mf '\mode:=localfont; input fmftempl'
+% $ latex template
+\documentclass{article}
+\usepackage{feynmf}%%%{feynmp}
+\unitlength=1mm
+\begin{document}
+\begin{fmffile}{fmftempl}
+\begin{fmfchar*}(40,25)
+ \fmfleft{em,ep} \fmflabel{$e^+$}{ep} \fmflabel{$e^-$}{em}
+ \fmf{fermion}{em,Zee,ep}
+ \fmf{photon,label=$\gamma,,Z$}{Zee,Zff}
+ \fmf{fermion}{fb,Zff,f}
+ \fmfright{fb,f} \fmflabel{$\bar f'$}{fb} \fmflabel{$f$}{f}
+ \fmfdot{Zee,Zff}
+\end{fmfchar*}
+\end{fmffile}
+\end{document}
+