summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/feynmf/feynmf.pl
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/feynmf.pl
Initial commit
Diffstat (limited to 'macros/latex/contrib/feynmf/feynmf.pl')
-rw-r--r--macros/latex/contrib/feynmf/feynmf.pl457
1 files changed, 457 insertions, 0 deletions
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;
+
+########################################################################
+