
| Current Path : /bin/X11/X11/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : //bin/X11/X11/feynmf |
#! /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 magnification. 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) = `/bin/tempfile -p feynmf -s .pl`;
my ($tfm);
$pltotf_prog
or die "feynmf: fatal: pltopf programm required unless -notfm\n";
chop ($pl);
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;
########################################################################