diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-11 23:53:16 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-11 23:53:16 +0000 |
commit | 3b04b2049275c5f020d5d99c2773c4f96a5dc04c (patch) | |
tree | f94db2d156644f9cc2fc5da79e029165c4b3a3f6 /Master/texmf-dist/source/latex/feynmf/feynmf.pl | |
parent | 288710434a8067688ea5f2eaf63122eec2ae1373 (diff) |
trunk/Master/texmf-dist/source/latex/feynmf
git-svn-id: svn://tug.org/texlive/trunk@280 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/feynmf/feynmf.pl')
-rw-r--r-- | Master/texmf-dist/source/latex/feynmf/feynmf.pl | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/feynmf/feynmf.pl b/Master/texmf-dist/source/latex/feynmf/feynmf.pl new file mode 100644 index 00000000000..b753be17b54 --- /dev/null +++ b/Master/texmf-dist/source/latex/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; + +######################################################################## + |