summaryrefslogtreecommitdiff
path: root/obsolete/support/prv
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 /obsolete/support/prv
Initial commit
Diffstat (limited to 'obsolete/support/prv')
-rwxr-xr-xobsolete/support/prv/prv1907
-rwxr-xr-xobsolete/support/prv/prvps183
2 files changed, 2090 insertions, 0 deletions
diff --git a/obsolete/support/prv/prv b/obsolete/support/prv/prv
new file mode 100755
index 0000000000..8aee8e2909
--- /dev/null
+++ b/obsolete/support/prv/prv
@@ -0,0 +1,1907 @@
+#!/usr/bin/perl -w
+# prv - compile, preview, and print LaTeX document
+$version_num = '0.7'; # version history at the end
+
+=head1 NAME
+
+ prv - compile, preview, and print LaTeX document
+
+=head1 SYNOPSIS
+
+Options are shown in logically identical pairs, with the full version
+in the second column and the minimum shorthand (without any parameters)
+in the first:
+
+ prv [-b] [-batch <selection>]
+ [-cl] [-clean]
+ [-co] [-continue]
+ [-dr] [-draft]
+ [-dv] [-dvi_filter <filter>]
+ [-f] [-full_clean]
+ [-g] [-go]
+ [-h] [-help]
+ [-ig] [-ignore_missing_includes]
+ [-in] [-intensity_draft <intensity>]
+ [-l] [-landscape]
+ [-m] [-message_draft <message>]
+ [-pr] [-printout]
+ [-ps] [-ps]
+ [-ps_] [-ps_filter <filter>]
+ [-pv] [-pv]
+ [-pvc] [-pvc]
+ [-q] [-quiet]
+ [-r] [-rcfile <rcfile]
+ [-scal] [-scale_draft <scale>]
+ [-scan] [-scan]
+ [-scan_] [-scan_force]
+ [file ...]
+
+Boolean options can be negated by a no-prefix. So -noquiet makes a
+previous -quiet undone. Useful in combination with rcfiles.
+
+=cut
+
+# more pod at the end
+
+use Getopt::Long;
+use Carp;
+use Cwd;
+use Env;
+use File::Basename;
+use Config;
+use Term::ReadKey qw(ReadLine);
+
+# following initialized because of -w noise
+use vars qw ( $quiet $help $version
+ $message_draft $scan_force $scan $go
+ $name
+ );
+$msdos = $Config{'osname'} =~ /ms/i;
+$texfile_search=$clean_ext=$full_clean_ext="";
+@cus_dep_list=();
+$comline=join(' ',@ARGV);
+
+if ($msdos) {
+ $TEMP= "\\tmp\\";
+ $tonull = "> ${TEMP}tonull";
+ $fromnull = "< ${TEMP}fromnull";
+ system("echo > ${TEMP}fromnull");
+ $systemrcfile = "\\lib\\prv\\prv";
+ $userrcfile = "$HOME\\prv.rc";
+ $rc_file = "prv.rc";
+ $copy = "copy";
+ $lpr = 'print';
+ $ps_previewer = 'gv';
+ $ps_previewer_landscape = 'gv';
+ $dvi_previewer = 'windvi';
+ $dvi_previewer_landscape = 'windvi';
+ $dvi_cont_previewer = 'dviwin2 -1 -c';
+ $dvi_cont_previewer_landscape = 'dviwin2 -1 -c';
+} else {
+ $TEMP= "/tmp/";
+ $tonull = "> /dev/null";
+ $fromnull = "< /dev/null";
+ $systemrcfile = '/etc/prvrc';
+ $userrcfile = "$HOME/.prvrc";
+ $rc_file = ".prvrc";
+ $copy = "cp -p";
+ $lpr = 'lpr';
+ $ps_previewer = 'gv';
+ $ps_previewer_landscape = 'gv -swap';
+ $dvi_previewer = 'xdvi';
+ $dvi_previewer_landscape = 'xdvi -paper a4r';
+ $dvi_cont_previewer = 'xdvi';
+ $dvi_cont_previewer_landscape = 'xdvi -paper a4r';
+}
+-d $TEMP or die "Missing directory $TEMP\n";
+-w $TEMP or die "Unwritable directory $TEMP\n";
+
+## default document processing programs.
+$latex = 'latex';
+$bibtex = 'bibtex -terse';
+$makeindex = 'makeindex';
+$dvips = 'dvips -s';
+$dvips_landscape= 'dvips -tlandscape';
+$pscmd = 'ps x'; # This works for SunOs. Solaris should just be 'ps'
+$touch = 'touch';
+$psselect = 'psselect';
+$pstops = 'pstops';
+$diff = 'diff';
+$dvi_filter = "";
+$ps_filter = "";
+$leader=$trailer= "";
+
+# default flag settings.
+$bibtex_mode = 0; # is there a bibliography needing bibtexing?
+$index_mode = 0; # is there an index needing makeindex run?
+$sleep_time = 2; # time to sleep b/w checks for file changes in -pvc mode
+
+# Read rc files.
+for ($systemrcfile,$userrcfile,$rc_file) {
+ -e $_ and do $_;
+}
+
+print_help() unless @ARGV;
+
+# Process command line args.
+$batch='';
+GetOptions(
+ "die" => \$die,
+ "intensity_draft=f" => \$intensity_draft,
+ "message_draft=s" => \$message_draft,
+ "scale_draft=i" => \$scale_draft,
+ "batch=s" => \$batch,
+ "clean!" => \$clean,
+ "full_clean!" => \$full_clean,
+ "draft!" => \$draft,
+ "dvi_filter=s" => \$dvi_filter,
+ "continue!" => \$continue,
+ "ignore_missing_includes!" => \$ignore_missing_includes,
+ "go!" => \$go,
+ "help" => \$help,
+ "scan!" => \$scan,
+ "scan_force!" => \$scan_force,
+ "landscape!" => \$landscape,
+ "printout!" => \$printout,
+ "ps!" => \$ps,
+ "ps_filter=s" => \$ps_filter,
+ "pv!" => \$pv,
+ "pvc!" => \$pvc,
+ "quiet!" => \$quiet,
+ "rcfile=s" => \$rcfile,
+ "version" => \$version,
+) or print_help("Option problem in `".$comline."'");
+
+# $batch must contain valid printing commands:
+if ($batch) {
+ for (split(/\s+/,$batch)) {
+ CASE: {
+ /^q$/ and last CASE; # drop on n of q
+ /^x[0-9]+$/ and last CASE; # x3 -> lpr -#3
+ /^b$/ and last CASE; # print a5 booklet
+ /^t$/ and last CASE; # print twosided
+ /^a$/ and last CASE; # print all
+ /^(([0-9]+-?[0-9]*|[0-9]*-?[0-9]+),?)+$/ # n-m or n- or -m
+ and last CASE;
+ die "Illegal argument for -batch option: $batch\nUse q if you want no printout\n";
+ }
+ }
+}
+
+$version and warn "\nprv $version_num\n";
+$help and print_help("");
+$pvc and $quiet=1;
+$draft=1 if $message_draft;
+$scale_draft = 220 unless $scale_draft;
+$intensity_draft = 0.95 unless $intensity_draft;
+$message_draft = 'DRAFT' unless $message_draft;
+do $rcfile if $rcfile;
+$clean=1 if $full_clean;
+$pv=0 if $batch or $pvc;
+($intensity_draft <0 || $intensity_draft > 1) and
+ die "Banner intensity must be 0 - 1\n";
+($scale_draft <10 || $scale_draft > 10000) and
+ die "Banner scale must be 10 - 10000\n";
+
+# If no files specified, try and find some
+@ARGV=glob($texfile_search) unless @ARGV;
+
+# If still no files, exit.
+print_help("prv: No filename specified\n") if (!@ARGV);
+
+# If landscape mode, change modes
+if ( $landscape ) {
+ $dvips = $dvips_landscape;
+ $dvi_previewer = $dvi_previewer_landscape;
+ $dvi_cont_previewer = $dvi_cont_previewer_landscape;
+ $ps_previewer = $ps_previewer_landscape;
+}
+
+if ($quiet) {
+ $dvips.=" -q";
+ $dvips_landscape.=" -q";
+}
+
+=pod
+
+This is how it works:
+
+=head2 do some initializations.
+
+=head2 read the rc-files for customization:
+
+ /etc/prvrc, $HOME/.prvrc, and ./.prvrc, in that order under Unix, or
+ \\lib\\prv\\prv", $HOME\\prv.rc", and prv.rc" under MD-DOS
+
+These files may contain Perl-statements that set some variables
+
+=head2 handle the command line options and get the filename(s) to be compiled
+
+prv looks for filenames on the command line and, if there are none, in the
+variable $texfile_search that may have been set in an rc-file.
+
+=head2 save current working directory
+
+=head2 for each source to be compiled:
+
+return to the starting directory, get the source's path and
+chdir to the source's directory.
+If the file is'nt found there,
+
+=cut
+
+
+# save current working directory, we'll want to get back here:
+$startdir=cwd;
+
+RESTART:
+# Process for each file.
+for $filename ( @ARGV ) {
+ chdir $startdir; # look from here, for relative paths
+
+ # add a .tex extension if it lacks.
+ # if a path is given, move to it
+ ($root_filename,$path,$ext)=fileparse($filename,'\.tex');
+ $tex_filename="$root_filename.tex";
+ $linenum=1; # editing sessions start at this line
+ @filestack=($tex_filename); # file to be edited
+ chdir $path;
+ if ( (! -f $tex_filename) && # if the file is not found here
+ ($path eq "./") && # and no path was specified
+ ($leader || $trailer)) { # then try adding leader and trailers
+ # to the original name:
+ $filename=$leader.$filename.$trailer;
+ redo;
+ }
+ -f $tex_filename or die "No file $path$tex_filename found\n";
+
+ if ($clean) {
+ warn "Cleaning for $root_filename\n" unless $quiet;
+ # Do clean if necessary
+ cleanup();
+ cleanup_full() if ($full_clean);
+ } else {
+ # Make file
+ # Find includes
+ $includes = '';
+ $read_depend = 0; # True to read depend file, false to generate it.
+ $depfile = "$root_filename.dep";
+
+ # Figure out if we read the dependency file or generate a new one.
+ if ( ! $scan_force ) {
+ if ( $scan ) {
+ if ( -e $depfile ) {
+ # Compare timestamp of dependency file and root tex file.
+ $dep_mtime = &get_mtime("$depfile");
+ $tex_mtime = &get_mtime("$tex_filename");
+ $read_depend = 1 if ( $tex_mtime < $dep_mtime );
+ }
+ } elsif ( -e $depfile ) { # If dependency file already exists.
+ $read_depend = 1;
+ }
+ }
+
+ if ( $read_depend ) {
+ # Read the dependency file
+ open(DEPFILE,$depfile) ||
+ die "prv: Couldn't open dependency file [$root_filename.dep]\n";
+ while(<DEPFILE>) { eval; }
+ close(DEPFILE);
+ } else {
+ # Generate dependency file.
+ # get search paths for includes.
+ if (!$TEXINPUTS) { $TEXINPUTS = '.'; }
+ if (!$BIBINPUTS) { $BIBINPUTS = $TEXINPUTS; }
+
+ &scan_for_includes("$tex_filename");
+ &update_depend_file;
+ }
+
+ ## put root tex file into list of includes.
+ $includes .= " $tex_filename";
+
+ ## before munging, save existing .aux file.
+ ## - if latex bombs, kill .aux, restore this backup to get back most
+ ## useful bib/ref info.
+ sys("$copy $root_filename.aux $root_filename.auk $tonull")
+ if -f "$root_filename.aux";
+
+ #************************************************************
+
+ &make_dependents("$includes");
+ &make_latex_dvi;
+ &make_dvi_filtered;
+ &make_preview_continuous;
+ &make_postscript;
+ &make_preview;
+ &make_printout;
+ }
+}
+
+#************************************************************
+#### Subroutines
+#************************************************************
+
+sub make_latex_dvi {
+ $changed_dvi = 0 ; # flag if anything changed.
+ ## get initial last modified times.
+ $tex_mtime = &get_latest_mtime($includes);
+ $aux_mtime = &get_mtime("$root_filename.aux");
+ $bbl_mtime = &get_mtime("$root_filename.bbl");
+ $ilg_mtime = &get_mtime("$root_filename.ilg");
+ $ind_mtime = &get_mtime("$root_filename.ind");
+
+ ## - if no dvi file, or .aux older than tex file or bib file, run latex.
+ if ( $go || !(-e "$root_filename.dvi")
+ || ($aux_mtime < $tex_mtime)
+ || ($aux_mtime < $bbl_mtime)
+ || ($aux_mtime < $ilg_mtime)
+ || ($aux_mtime < $ind_mtime)
+ || !(-e "$root_filename.aux")) {
+ message("Running first $latex [$tex_filename]");
+ &backup_toc;
+ unlink "$root_filename.dvi"; # just in case latex produces no output...
+ $return = run_latex();
+ unless (-f "$root_filename.dvi") {
+ warn "Latex produced no output!\n" unless $return;
+ $return=1;
+ }
+ die "Giving up...\n" if $return && $die;
+ $changed_dvi = 1;
+
+ if (!$continue && $return) {
+ message("$latex found an error in\n$startdir/$root_filename.tex");
+ unlink "$startdir/$root_filename.dvi";
+ edit(1);
+ }
+
+ if ($index_mode) {
+ message("Running $makeindex [$root_filename]");
+ $return = sys("$makeindex $root_filename");
+
+ if (!$continue && $return) {
+ &exit_msg('Makeindex found an error');
+ }
+ $ilg_mtime = &get_mtime("$root_filename.ilg");
+ $ind_mtime = &get_mtime("$root_filename.ind");
+ }
+ }
+
+ $bib_mtime = &get_latest_mtime($bib_files);
+ ## if no .bbl or .bib changed since last bibtex run, run bibtex.
+ if ($bibtex_mode && (&check_for_bad_citation || !(-e "$root_filename.bbl")
+ || ($bbl_mtime < $bib_mtime))) {
+ message("Running $bibtex [$root_filename]");
+ $return = sys("$bibtex $root_filename");
+ $bbl_mtime = &get_mtime("$root_filename.bbl");
+ }
+
+ if ($bibtex_mode && &check_for_bibtex_errors) {
+ if (!$continue) {
+ # touch a .bib file so that will rerun bibtex to fix errors.
+ @split_bib_files = split(' ',$bib_files);
+ sys("$touch $split_bib_files[0]");
+ &exit_msg('Bibtex reported an error',0);
+ }
+ }
+
+ ## now, if need to, rerun latex up to twice to generate valid .dvi
+ ## w/ citations resolved.
+
+ $dvi_mtime = &get_mtime("$root_filename.dvi");
+ if ( ($dvi_mtime <= $bbl_mtime) || &check_for_reference_change
+ || ($dvi_mtime <= $ilg_mtime)
+ || ($dvi_mtime <= $ind_mtime)
+ || (&check_toc)) {
+ message("Running second $latex [$tex_filename]");
+ &backup_toc;
+ $return = run_latex();
+ $changed_dvi = 1;
+ }
+
+ if (!$continue && $return) {
+ &exit_msg('$latex found an error',1);
+ }
+
+ if (&check_for_reference_change || &check_toc) {
+ message("Running third $latex [$tex_filename]");
+ &backup_toc;
+ $return = run_latex();
+ $changed_dvi = 1;
+ }
+
+ if (!$continue && &check_for_bad_reference) {
+ &exit_msg('$latex could not resolve all references');
+ }
+
+ if (!$continue && &check_for_bad_citation) {
+ &exit_msg('$latex could not resolve all citations or labels');
+ }
+ return(1);
+}
+
+#************************************************************
+
+sub make_dvi_filtered {
+ return if ( length($dvi_filter) == 0 );
+ message("Running $dvi_filter [$root_filename]");
+ sys("$dvi_filter < $root_filename.dvi > $root_filename.dvf");
+}
+
+#************************************************************
+
+sub make_dependents {
+ local($file,$dep,$base_name,$ch,$toext,$fromext,
+ $proptoext,$must,$func_name,$return);
+
+ for $file (split(' ',$_[0])) { $ch = '';
+ $toext = '';
+ $base_name = $file;
+ while (( $ch ne '.' ) && ( $ch ne '/' ) && ( $base_name ne '' )) {
+ $toext = $ch . $toext;
+ $ch = chop $base_name;
+ }
+ if (( $ch eq '.' ) && ( $base_name ne '' )) {
+ #Extracted proper extension.
+ for $dep ( @cus_dep_list ) {
+ ($fromext,$proptoext,$must,$func_name) = split(' ',$dep);
+ if ( $toext eq $proptoext ) {
+ # Found match
+ if ( -e "$base_name.$fromext" ) {
+ # From file exists, now check if it is newer
+ if (( ! (-e "$base_name.$toext" ))
+ || ( &get_mtime("$base_name.$toext")
+ < &get_mtime("$base_name.$fromext") )) {
+ message("Running $func_name [$base_name]");
+ $return = &$func_name($base_name);
+ if ( !$continue && $return ) {
+ &exit_msg("$func_name found an error");
+ }
+ }
+ } else {
+ if ( !$continue && ( $must != 0 )) {
+ &exit_msg("File '$base_name.$fromext' does not exist".
+ "to build '$base_name.$toext'\n");
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+#************************************************************
+
+sub make_printout {
+ $printout or return;
+ $batch=~/^q$/ and return;
+
+ local ($ext);
+ $ext = $ps_filter ? '.psF' : '.ps';
+ my $tmp = "${TEMP}$$";
+ my $sel="${tmp}sel";
+ my $print_prompt="printer ready? then turn pack and type return ";
+ my $front_spec='"4:-3L@.707(210mm,0)+0L@.707(210mm,148.5mm)"';
+ my $back_spec='"4:1L@.707(210mm,0)+-2L@.707(210mm,148.5mm)"';
+
+ while (1) {
+ my ($selection,$booklet,$twosided,$lpropt)=ask_selection($batch);
+ defined($selection) or return;
+ if ($selection) { # if anything was set
+ print STDERR "\n";
+ make_postscript();
+ $selection =~ /[1-9]/ or $selection.=" -e -o ";
+ sys("$psselect -q $selection $root_filename.ps $sel");
+ if ($booklet) {
+ sys("$pstops -q $front_spec $sel >$tmp"); # no piping: non-Unix OS
+ sys("$lpr $lpropt $tmp"); # can get problems
+ print STDERR $print_prompt; ReadLine 0;
+ sys("$pstops -q $back_spec $sel >$tmp");
+ sys("$lpr $lpropt $tmp");
+ unlink $tmp;
+ } elsif ($twosided) {
+ sys("$pstops 2:0 $sel >$tmp");
+ sys("$lpr $lpropt $tmp");
+ print STDERR $print_prompt; ReadLine 0;
+ sys("$pstops 2:1 $sel >$tmp");
+ sys("$lpr $lpropt $tmp");
+ } else {
+ sys("$lpr $lpropt $sel");
+ }
+ }
+ unlink $sel;
+ last if $batch;
+ }
+}
+
+sub ask_selection {
+ my $prompt='Pages ([range[,range...]|a] [b|t] [x<n>])? ';
+ my $com=shift || ask($prompt);
+ chomp($com);
+ my ($booklet,$twosided,$selection,$lpropt)=('','','','');
+ for (split(/\s+/,$com)) {
+ CASE: {
+ /^q$/ # drop on q
+ and return undef;
+ /^e$/ # edit $root_filename.tex, then exit
+ and edit(0);
+ /^x[0-9]+$/ # x3 -> lpr -#3
+ and do {
+ s/x//;
+ $batch or print STDERR " $_ copies";
+ $lpropt = '-#'.$_;
+ $selection.=" -q";
+ },
+ last CASE;
+ /^b$/ # print a5 booklet
+ and do {
+ $selection.=" -q ";
+ $batch or print STDERR " booklet";
+ $booklet=1;
+ },
+ last CASE;
+ /^t$/ # print twosided
+ and do {
+ $selection.=" -q";
+ $twosided=1;
+ $batch or print STDERR " twosided";
+ },
+ last CASE;
+ /^a$/ # print all
+ and do {
+ $selection="-e -o";
+ $batch or print STDERR " all pages";
+ },
+ last CASE;
+ /^(([0-9]+-?[0-9]*|[0-9]*-?[0-9]+),?)+$/ # n-m or n- or -m
+ and do {
+ s/^-/1-/;
+ ($selection=$_) =~ s/,$//;
+ $batch or print STDERR " pages: $selection";
+ },
+ last CASE;
+
+ warn
+ "Illegal specification(s)\n".
+ "Examples of page specifications:\n".
+ "5 to print page 5\n".
+ "5- to print pages 5 through the end\n".
+ "5-7 to print pages 5, 6 and 7\n".
+ "-7 to print the first 7 pages\n".
+ "5-7,19- to print pages 5, 6, 7 and 19 through the end\n".
+ "a to print the whole document\n".
+ "a x3 to print 3 copies of the document\n".
+ "x3 the same\n".
+ "5 x3 to print 3 copies of page 5\n".
+ "t print the whole document twosided\n".
+ "t 2- print twosided starting at page 2\n".
+ "b to print the whole document as an a5 size booklet\n".
+ "b -12 to print the first 12 pages as an a5 size booklet\n".
+ "e edit the tex source and rerun prv\n".
+ "q quit\n".
+ "";
+
+ }
+ }
+ ($selection,$booklet,$twosided,$lpropt)
+}
+sub ask {
+ print $_[0];
+ my $x=ReadLine 0;
+ chomp($x);
+ $x;
+}
+
+#************************************************************
+sub edit {
+ $EDITOR or die "EDITOR environment variable undefined\n";
+ my $x;
+ if ($_[0]) {
+ while(($x=ask("=====> e(dit) q(uit) "))!~/^(q|e)$/) { warn "you must type e or q\n" }
+ $x eq 'q' and exit;
+ }
+ die unless $linenum;
+ system("$EDITOR +$linenum ".(pop(@filestack)));
+ goto RESTART;
+}
+
+sub make_postscript {
+ if ( ! $draft ) {
+ return if (!$ps && !$printout);
+ }
+ local ($tmpfile,$header,$dvi_file);
+
+ # Figure out the dvi file name
+ if ( length($dvi_filter) == 0 ) {
+ $dvi_file = "$root_filename.dvi";
+ } else {
+ $dvi_file = "$root_filename.dvf";
+ }
+
+ # Do banner stuff
+ if ( $draft ) {
+ ## Make temp banner file
+ local(*OUTFILE,$count);
+
+ $tmpfile = "${TEMP}prv.$$";
+ $count = 0;
+ while ( -e $tmpfile ) {
+ $count = $count + 1;
+ $tmpfile = "${TEMP}prv.$$.$count";
+ }
+ if ( ! open(OUTFILE, ">$tmpfile") ) {
+ die "prv: Could not open temporary file [$tmpfile]\n"; }
+ print OUTFILE "userdict begin /bop-hook{gsave 200 30 translate\n";
+ print OUTFILE "65 rotate /Times-Roman findfont $scale_draft".
+ "scalefont setfont\n";
+ print OUTFILE "0 0 moveto $intensity_draft setgrays".
+ "($message_draft) show grestore}def end\n";
+ close(OUTFILE);
+ $header = "-h $tmpfile";
+ } else {
+ $header = ''
+ }
+
+ $ps_mtime = &get_mtime("$root_filename.ps");
+ $dvi_mtime = &get_mtime("$dvi_file");
+ if (( $ps_mtime < $dvi_mtime ) || $draft ) {
+ message("Running $dvips [$root_filename]");
+ sys("$dvips $header $dvi_file -o $root_filename.ps");
+ }
+ unlink("$tmpfile") if $draft;
+
+ ## Do we have postscript filtering?
+ if ( length($ps_filter) != 0 ) {
+ message("Running $ps_filter [$root_filename]");
+ sys("$ps_filter < $root_filename.ps > $root_filename.psF");
+ }
+}
+
+#************************************************************
+# run appropriate previewer.
+
+sub make_preview {
+ return if (!$pv);
+ $viewer = $dvi_previewer;
+ $ext = '.dvi';
+ if ($ps) {
+ $viewer = $ps_previewer;
+ $ext = '.ps';
+ if ( length($ps_filter) != 0 ) {
+ $ext = '.psF';
+ }
+ } else {
+ if ( length($dvi_filter) != 0 ) {
+ $ext = '.dvf';
+ }
+ }
+ message("Starting previewer: $viewer $root_filename$ext");
+ sys("$viewer $root_filename$ext");
+}
+
+sub backup_toc {
+ if ( -e "$root_filename.toc" ) {
+ sys("$copy $root_filename.toc $root_filename.tok $tonull");
+ }
+}
+
+#************************************************************
+# Compare the toc file with the backup. If they differ then
+# return non-zero.
+sub check_toc {
+ local($return);
+
+ if ( -e "$root_filename.toc" ) {
+ if ( -e "$root_filename.tok" ) {
+ $return = sys("$diff $root_filename.tok $root_filename.toc $tonull");
+ } else {
+ $return = 1
+ }
+ } else {
+ $return = 0;
+ }
+ return($return);
+}
+
+#************************************************************
+# arg1 = name
+
+sub find_process_id {
+ local(@command);
+ @ps_output = `$pscmd`;
+ shift(@ps_output); # Discard the header line from ps
+ for (@ps_output) {
+ ($pid,$tt,$tt,$tt,@command) = split(' ',$_);
+ return($pid) if "@command" eq "$_[0]";
+ }
+ return(0);
+}
+
+#************************************************************
+
+sub make_preview_continuous {
+ return if (!$pvc);
+ #
+ local ($dvi_file);
+ # get the value of SIGUSR1, defaults to Linux value.
+ # try kill -l to figure your value out
+ if (!(do 'signal.ph'))
+ {
+ eval 'sub SIGUSR1 {10;}';
+ }
+ # Figure out the dvi file name
+ if ( length($dvi_filter) == 0 )
+ {
+ $dvi_file = "$root_filename.dvi";
+ }
+ else
+ {
+ $dvi_file = "$root_filename.dvf";
+ }
+ # note, we only launch a previewer if one isnt already running...
+ # otherwise we'll send reopen signals to the existing previewer.
+ if ($msdos) {
+ warn "$dvi_cont_previewer $dvi_file\n";
+ sys("$dvi_cont_previewer $dvi_file");
+ } else {
+ if ($previewer_pid = &find_process_id("$dvi_cont_previewer $dvi_file")) {
+ message("Reattached to existing previewer, pid=$pid");
+ kill &SIGUSR1,$previewer_pid;
+ } else {
+ if (!($previewer_pid = fork)) {
+ # in forked child, close off from parent so previewer runs on
+ # after parent 'prv' dies.
+ setpgrp($$,0);
+ message("$dvi_cont_previewer $dvi_file");
+ exec("$dvi_cont_previewer $dvi_file");
+ }
+ }
+ }
+ # Loop forever, rebuilding .dvi as necessary.
+ while ( 1 )
+ {
+ sleep($sleep_time);
+ &make_latex_dvi;
+ if ($changed_dvi)
+ {
+ kill &SIGUSR1,$previewer_pid;
+ }
+ }
+}
+
+#************************************************************
+
+sub get_mtime {
+ my $m=(stat($_[0]))[9];
+ $m ? $m : 0;
+}
+
+#************************************************************
+
+sub check_for_reference_change {
+ local($logfile) = "$root_filename.log";
+ open(LOGFILE,$logfile) ||
+ die "prv: Could not open log file to check for reference check\n";
+ while(<LOGFILE>) {
+ return(1) if (/Rerun/);
+ }
+ 0;
+}
+
+#************************************************************
+
+sub check_for_bad_reference {
+ local($logfile) = "$root_filename.log";
+ open(LOGFILE,$logfile) ||
+ die "prv: Could not open log file to check for bad reference\n";
+ while (<LOGFILE>)
+ {
+ if (/LaTeX Warning: Reference[^\001]*undefined./) { return 1; }
+ }
+ 0;
+}
+
+#************************************************************
+# check for citation which latex couldnt resolve.
+
+sub check_for_bad_citation {
+ local($logfile) = "$root_filename.log";
+ open(LOGFILE,$logfile) ||
+ die "prv: Could not open log file to check for bad citation\n";
+ while (<LOGFILE>)
+ { chomp;
+ warn WHITE,ON_RED,BOLD,substr($_,2),RESET,"\n" if /^--/;
+ if (/LaTeX Warning: Citation[^\001]*undefined./) { return 1; }
+ }
+ 0;
+}
+
+#************************************************************
+# check for citation which bibtex didnt find.
+
+sub check_for_bibtex_errors {
+ local($logfile) = "$root_filename.blg";
+ open(LOGFILE,$logfile) ||
+ die "prv: Could not open bibtex log file error check\n";
+ while (<LOGFILE>)
+ {
+# if (/Warning--/) { return 1; }
+ if (/error message/) { return 1; }
+ }
+ 0;
+}
+
+#************************************************************
+# cleanup
+# - erases all generated files, exits w/ no other processing.
+
+sub cleanup {
+ unlink("$root_filename.aux");
+ unlink("$root_filename.auk");
+ unlink("$root_filename.bbl");
+ unlink("$root_filename.blg");
+ unlink("$root_filename.log");
+ unlink("$root_filename.ind");
+ unlink("$root_filename.idx");
+ unlink("$root_filename.ilg");
+ unlink("$root_filename.toc");
+ unlink("$root_filename.tok");
+ unlink("$root_filename.lof");
+ unlink("$root_filename.lot");
+ unlink("$root_filename.dep");
+ unlink("texput.log");
+ unlink("texput.aux");
+
+ # .aux files are also made for \include'd files
+ if ($includes) {
+ for $include (split(' ',$includes)) {
+ $include =~ s/\.[^\.]*$/.aux/;
+ unlink($include);
+ }
+ }
+ # Do any other file extensions specified
+ for $ext (split(' ',$clean_ext))
+ {
+ unlink("$root_filename.$ext");
+ }
+}
+
+#************************************************************
+sub cleanup_full {
+ unlink("$root_filename.dvi");
+ unlink("$root_filename.ps");
+ unlink("$root_filename.dvf");
+ unlink("$root_filename.psF");
+ unlink("texput.dvi");
+ # Do any other file extensions specified
+ for $ext (split(' ',$full_clean_ext)) {
+ unlink("$root_filename.$ext");
+ }
+}
+
+#************************************************************
+sub print_help {
+ exit(1) if $full_clean;
+ while (<DATA>) { print STDERR }
+ $_=$_[0] and die "\nError in prv version $version_num: $_[0]\n";
+ exit(1);
+}
+
+#************************************************************
+# - stats all files listed in first arg, returns most recent modify time of all.
+
+sub get_latest_mtime {
+ return 0 unless $_[0];
+ local($return_mtime) = 0;
+ for $include (split(' ',$_[0])) {
+ $include_mtime = &get_mtime($include);
+ if ($include_mtime > $return_mtime)
+ {
+ $return_mtime = $include_mtime;
+ }
+ }
+ $return_mtime;
+}
+
+#************************************************************
+# - looks recursively for included & inputted and graphics files and puts
+# them into $includes.
+# - note only primitive comment removal: cannot deal with escaped %s, but then,
+# when would they occur in any line important to prv??
+
+sub scan_for_includes {
+ message("Generating Dependency File [$root_filename]");
+ $bib_files=$includes=$graphicspath='';
+ &scan_for_includes_($_[0]);
+}
+
+sub scan_for_includes_ {
+ local(*FILE,$orgfile); # because this sub calls itself
+ my %commands=('include' =>'.tex',
+ 'input' =>'.tex',
+ 'includegraphics'=>'.ps',
+ 'verbatimfile' =>'.tex',
+ 'verbatiminput' =>'.tex',
+ 'bibliography' =>'',
+ 'graphicspath' =>'',
+ );
+ if (!open(FILE,$_[0])) {
+ warn "prv: could not open input file [$_[0]]\n";
+ return;
+ }
+ while(<FILE>) {
+ chomp;
+ s/^%\\input/\input/; # a line beginning with %\input can be used to
+ # indicate dependency files that would not be
+ # recognised otherwise
+ s/%.*//;
+ /^\\documentclass.*landscape/ and do {
+ warn " Detected landscape mode\n" unless $quiet;
+ $landscape = 1;
+ };
+ /\\makeindex/ and do {
+ warn " Detected index mode\n" unless $quiet;
+ $index_mode = 1;
+ };
+ s/\\\\//g; # remove newlines
+ s/\[.*?\]//g; # remove optional parameters
+ s/([^\\])%.*/$1/; # remove comment
+ /\\verb(.)/ and s/\\verb$1.*?$1//g; # remove \verb!...!
+ next unless /\\/; # skip if no commands
+ s/.*?\\/\\/; # remove upto first \backslash
+ for ((split(/\\/))) {
+ s/{{(.*)}}/{$1}/; # graphicspath{{p1}{p2}} -> ...path{p1}{p2}
+ s/}{/:/g; # -> ...path{p1,p2}
+ s/(.*}).*/$1/; # remove all after last }
+ s/\s*([{}])\s*/$1/g; # remove space around { and }
+ s/}.*//; # remove all after }
+ $keys=join('|',(keys %commands)); # input|include|...
+
+ next unless /^($keys)(\[.*?\])?{(.*)/;
+ $orgfile=$file=$3;
+ $command=$1;
+ if ($command eq 'bibliography') {
+ $file=~s/\.bib\b//g; # remove .bib extensions
+ my $com="kpsewhich ".join(".bib ",split(/,/,$file)).".bib";
+ $bib_files=join(' ',(split(/\n/,`$com`)));
+ warn " Found bibliography files [$bib_files]\n" unless $quiet;
+ $bibtex_mode = 1;
+ } elsif ($command eq 'graphicspath') {
+ ($graphicspath = $file) =~ s/{(.*?)}/:$1/g;
+ } else {
+ next if $file=~/#/; # skip if it is a parameter in a command
+ my $opt=$command eq 'includegraphics' && $graphicspath ? "--path=$graphicspath" : '';
+ my $ext=$commands{$command};
+ $file=~/$ext$/ or $file.=$ext; # append default extension if its lacks
+ chomp($file = `kpsewhich $opt $file`); # lookup in the tex-tree
+ $file||chomp($file=`kpsewhich $opt $orgfile`); # on fail, try without default extension
+
+ if ($file) {
+ $includes.="$file ";
+ warn " Added '$file'\n" unless $quiet;
+ $file=~/\.tex$/ and scan_for_includes_($file);
+ } else {
+ warn "Missing file $orgfile for \\$command command\n";
+ die "Quitting....\n" unless $ignore_missing_includes;
+ }
+ }
+ }
+ }
+}
+
+#************************************************************
+sub exit_msg
+{ my ($message,$fatal)=@_;
+ warn "\n------------\n";
+ carp "prv: $message.\n";
+ warn "-- Use the -continue option to force complete processing.\n";
+ sys("grep 'LaTeX Warning' $root_filename.log");
+ if ($fatal) {
+ warn "prv: restoring last $root_filename.aux file\n";
+ sys("$copy $root_filename.auk $root_filename.aux $tonull");
+ exit(1);
+ }
+}
+
+#************************************************************
+
+sub update_depend_file
+{
+ message("Writing dependency file [$root_filename.dep]\n");
+ $rc_file = ">$root_filename.dep";
+ open(RCFILE,$rc_file) ||
+ die "prv: Unable to open dependency file [$rc_file] for updating\n";
+ print RCFILE '$includes = \'' . "$includes';\n";
+ print RCFILE '$bib_files = \'' . "$bib_files';\n";
+ print RCFILE '$bibtex_mode = 1;' . "\n" if $bibtex_mode;
+ print RCFILE '$index_mode = 1;' . "\n" if $index_mode;
+ close RCFILE;
+}
+
+#************************************************************
+
+sub message {
+ return 0 if $quiet;
+ my $mess=shift;
+ carp "----------\n$mess\n----------\n";
+}
+
+#************************************************************
+
+sub run_latex {
+ my $myquiet=$quiet;
+ my $err=$myquiet ? sys("$latex $tex_filename $tonull $fromnull")
+ : sys("$latex $tex_filename");
+ if ($err) {
+ @filestack=($filestack[0]); # empty @filestack except for the first entry (the main document)
+ warn "found error $err\n";
+ open(IN,"$root_filename.log");
+ while(<IN>) {
+ my $line=$_;
+ $line=~s/\(.*?\)//g; # remove (...)
+ while ($line=~/\)/g) { pop(@filestack) } # each ) closes a previous file
+ $line=~/\(([^(]*)/ and push(@filestack,$1); # push new filename
+ /^l\.(\d+)/ and $linenum=$1; # error's linenumber
+ if ($quiet) { # just report the error
+ last if /^(\?|Type X)/ && !$myquiet;
+ $myquiet=0 if /^\!/ || /^Runaway/;
+ print STDERR unless $myquiet;
+ } else { # report everything
+ print STDERR;
+ }
+ }
+ close(IN);
+ return $err;
+ } else { # check log file to see if a rerun is needed:
+ open(LOG,"$root_filename.log");
+ while (<LOG>) {
+ /LaTeX Warning.*Rerun/ and run_latex(),last;
+ }
+ close LOG;
+ }
+ return 0;
+}
+
+sub sys {
+ my $command=shift;
+ print STDERR "system call: $command\n" unless $quiet;
+ system($command);
+}
+
+=pod
+
+=head1 DESCRIPTION
+
+B<prv> completely automates the process of generating a LaTeX
+document. Essentially, it is a highly specialized relative of the
+general make utility. Given the source files for a document,
+B<prv> issues the appropriate sequence of commands to generate a
+.dvi, .ps or hardcopy version of the document.
+
+B<prv> will scan source files for all included files, placing the
+resulting dependency information into a dependency file with the same
+name as the root file with the extension .dep. This option allows the
+user to essentially leave all the work to B<prv>. The program will
+find all LaTeX \include, \input, and \includegraphics commands which
+input other source files. As a special case, B<prv> will interpret lines
+beginning with exactly "%\input" as if they were lines beginning with
+"\input". You can use such lines to force recognition of file
+dependencies that would not otherwise be recognized. For example, the moreverb.sty
+package has a command \listinginput that includes a file, but would not be found
+by B<prv>.
+
+When B<prv> is run, it will examine the
+timestamps on those files and run the various LaTeX processing
+programs as necessary, if any of the source files have been changed
+since the last document generation. If the dependencies of the
+document are changed (e.g., by adding or removing a \include command),
+an additional pass of B<prv> -scan or prv -scan_force will update the
+dependency file.
+
+By default, if no dependency exists, the source files are scanned and
+the dependency file generated. If the dependency file exists, it is
+read instead (even if the root file is newer than the dependency file
+(see -scan option))
+
+B<prv> has two different previewing options. In the simple -pv
+option, a postscript or dvi previewer is automatically run after
+generating the postscript or dvi version of the document. The type of
+viewer is selected automatically depending on the -ps option. When a
+document is reaching the final stages of editing, the user frequently
+wants to make small changes to the source files and examine the
+effects in a previewer; for this phase, B<prv> provides the
+powerful -pvc option (mnemonic: "preview continuously"). With this
+option, B<prv> forks a child process to run an xdvi (or other
+specified) previewer on the document, and then B<prv> repeatedly
+monitors the source files of the document to see if any changes have
+been made since the last .dvi file was produced. When changes are
+detected, B<prv> runs the appropriate LaTeX commands to regenerate
+the .dvi file, and then sends a signal to xdvi job, indicating that
+the previewer should update its display. Thus the user can simply
+edit a file and, when the changes are written to disk, B<prv>
+completely automates the cycle of updating the .dvi and refreshing the
+previewer's display. It's not quite WYSIWYG, but LaTeX has never been
+closer.
+
+B<prv> has the ability to print a banner in gray diagonally across
+each page when making the postscript file.
+
+This script is derived from LatexMk version 2.0, which has undergone a
+major revision by wybo@servalys.nl. In particular, the options
+have been renamed to long names using the Getops::Long module. And
+page and print-format selection has been built in.
+
+=head1 OPTIONS
+
+Before evaluating any options, B<prv> will try to read a system rc-file,
+a user rc-file, and, finally an rc-file in the current directory.
+The system rc-file, if it exists, is /etc/prvrc (\prv.rc for
+MSDOS users), the user rc-file is $HOME/.prvrc ($HOME\prv.rc for MSDOS users) and the
+local one is .prvrc (prv.rc for MSDOS).
+Options can be set in the rc-files with statements like:
+
+ $quiet=1;
+ $message_draft="ENTWURF";
+
+So if you usually like B<prv> to work quietly, you can indicate so in your rc-file
+and change your mind in some cases by using the -noquiet (or perhaps -noq) option.
+See also the section on RC FILES.
+
+=over 4
+
+=item file
+
+One or more files can be specified. If no files are specified,
+B<prv> will run on any files that match any file masks specified
+in the $texfile_search variable.
+
+B<prv> requires source files to have a .tex extension. If the filename
+is specified without it, it is automatically appended.
+So if you specify:
+
+ prv foo
+
+then B<prv> will try to operate on the file "foo.tex".
+
+=item -batch <printing command string>
+
+Prevents the -printout option the interrogate the user about pages to be
+printed. Instead the document is printed according to the mandatory <print command string>.
+Also sets previewing off.
+Thus the command
+
+ prv -batch '2-3 x3' test
+
+print 3 copies of pages 2 and 3 of test.tex, without previewing.
+
+=item -clean
+
+Clean up (remove) all unnecessary files generated by latex and bibtex
+except dvi and postscript.
+
+=item -continue
+
+Force B<prv> to continue document processing despite errors.
+Normally, when B<prv> detects that latex has found an error which
+will not be resolved by further processing, the program terminates.
+
+=item -draft
+
+Set draft mode. This prints the banner message "DRAFT" across your
+page when converting the dvi file to postscript. Size and intensity
+can be modified with the -scale_draft and -intensity_draft options.
+The -message_draft option will override this option as this is really
+just a short way of specifying:
+
+B<prv> -message_draft DRAFT
+
+Note that if the -draft option is specified, the -ps option is assumed
+and the postscript file is always generated, even if it is newer than
+the dvi file.
+
+=item -dvi_filter
+
+Dvi file filtering. The argument to this option is a filter which
+will generate a filtered dvi file with the extension ".dvf". All
+extra processing (e.g. conversion to postscript, preview, printing)
+will then be performed on this filtered dvi file.
+
+Exampe usage: Use dviselect to select only the even pages of the dvi
+file:
+
+B<prv> -dvi_filter 'dviselect even' foo.tex
+
+=item -full_clean
+
+Clean up (remove) all unnecessary files generated by latex and bibtex
+including dvi and postscript.
+
+=item -go
+
+Force B<prv> to process document, disregarding the timestamps of
+the source files. This option is particularly useful when updating
+style files, which are not included in the file dependency
+information.
+
+=item -help
+
+Print help information.
+
+=item -ignore_missing_includes
+
+Force B<prv> to include files that don't exist when generating
+dependency files. A warning is produced instead of an error message
+and the program terminating. If the file name is not an absolute
+path, it is assumed to be relative to the current working directory.
+
+=item -intensity_draft <intensity>
+
+How dark to print the banner message. A decimal number between 0 and
+1. 0 is black and 1 is white, default is 0.95 which is ok unless your
+toner cartridge is getting low.
+
+=item -landscape
+
+Run in landscape mode, using the landscape mode previewers and dvi to
+postscript converters.
+
+=item -message_draft <message>
+
+A banner message to print diagonally accross each page when converting
+the dvi file to postscript. The message must be a single argument on
+the command line so be careful with quoting spaces and such.
+
+Note that if the -message_draft option is specified, the -ps option
+is assumed and the postscript file is always generated, even if it is
+newer than the dvi file.
+
+=item -printout
+
+Print out the file using lpr after generating the postscript version.
+Unless the -batch option was given, the user is given the opportunity
+to select pages and double-sided or booklet printing formats (see
+section on PAGE SELECTION. With the -batch option the complete
+document will be printed.
+
+=item -ps
+
+Generate postscript version of document.
+
+=item -ps_filter
+
+Postscript file filtering. The argument to this option is a filter
+which will generate a filtered postscript file with the extension
+".psF". All extra processing (e.g. preview, printing) will then be
+performed on this filtered postscript file.
+
+Exampe usage: Use psnup to print two pages on the one page:
+
+B<prv> -ps -ps_filter 'psnup -2' foo.tex
+
+=item -pv
+
+Run file previewer; if -ps is specified, will run postscript previewer,
+otherwise runs dvi previewer.
+
+=item -pvc
+
+Run a dvi-previewer and continually update the .dvi file whenever
+changes are made to source files (see the Description above). Note
+that if B<prv> dies because it encounters an error, the forked
+previewer will continue to run. Successive invocations with the -pvc
+option will not fork new previewers, but will find the existing
+previewer and send it the signals indicating the .dvi has been
+updated. This option implies the -quiet option.
+
+For xdvi you need at least version 21.27k to have this
+option work properly.
+
+You normally use this option by typing:
+
+ prv -pvc file.tex&
+ vi file.tex # or another editor
+
+=item -quiet
+
+Suppresses messages about the progress B<prv> is making.
+However, Latex log-file messages starting with -- will be printed in red to
+STDERR, even in quiet mode. You can use this to run quietly and nevertheless
+tell yourself urgent messages, like:
+
+ \typeout{-- please use colored paper for this job}
+
+or
+
+ \typeout{-- print frontpages separately on glossy paper}
+
+=item -rcfile <rcfile>
+
+Read specified RC file before processing. The contents of the RC file
+may override options specified before the -rcfile option, therefore it
+is a good idea have the habit of specifying the -rcfile option first.
+
+=item -scale_draft <scale>
+
+A decimal number that specifies how large the banner message will be
+printed. Experimentation is necessary to get the right scale for your
+message, as a rule of thumb the scale should be about equal to 1100
+divided by the number of characters in the message. Default is 220.0
+which is just right for 5 character messages.
+
+=item -scan
+
+Scan source files and generate new dependency file if root file is
+newer than dependency file or dependency file does not exist.
+
+=item -scan_force
+
+Always scan source files and generate new dependency file, even if
+newer dependency file exists. This forces a scan.
+
+=item -version
+
+Print version number of B<prv>.
+
+
+=back
+
+If -ps is specified when the dependency file is created or
+updated, then these options are stored in the dependency file. This
+means that these options will automatically be activated without
+having to be explicitly specified on the command line in future runs.
+Of coarse, if the dependency file is updated or deleted, these
+automatic settings will be lost.
+
+Options -pv and -pvc require one and only one filename specified on
+the command line.
+
+Options -pv and -pvc are mutually exclusive.
+
+=head1 PAGE SELECTION
+
+When you select the -printout option, and you did not also
+use the -batch option, B<prv> interrogates you about the pages you
+want to print. To that end the following prompt appears:
+
+Pages ([range[,range...]|a] [b|t] [x<n>])?
+
+You can react to this as in the following examples:
+
+ 5 # to print page 5
+ 5- # to print pages 5 through the end
+ 5-7 # to print pages 5, 6 and 7
+ -7 # to print the first 7 pages
+ 5-7,19- # to print pages 5, 6, 7 and 19 through the end
+ a # to print the whole document
+ a x3 # to print 3 copies of the document
+ x3 # the same
+ 5 x3 # to print 3 copies of page 5
+ t # print the whole document twosided
+ t 2- # print twosided starting at page 2
+ b # to print the whole document as an a5 size booklet
+ b -12 # to print the first 12 pages as an a5 size booklet
+ e # edit the tex sourcefile and rerun prv
+ q # quit
+
+If you use b to print a booklet, or t to print twosided, then you will
+have to arrange your printer such that, with the printed sides up, the
+first page printed will be at the bottom of the stack, and the last
+page printed will be on top. Normally you will then have your output
+come out the back of your printer.
+
+B<prv> will first print one side of the
+paper and prompt you for a return when the printer is ready and you
+have turned the stack and put it back in the paper feed.
+
+Finally, if you used the b option to print a booklet, you will have to
+reshuffle your pages manually as follows:
+- take the bottom page from the stack and put it aside without
+ changing its position
+- take the top page from the stack and put it upside down on the
+ bottom page
+- repeat these two actions until the stack is empty
+- if you find out how to prevent this manual action, please tell me how
+ you did it!! (wybo@servalys.nl)
+
+When you use B<e> to edit the tex sourcefile, the environment variable EDITOR
+must point to your editor. Or you car set this variable in your startup file:
+$EDITOR='my_favorite_editor';
+
+=head1 EXAMPLES
+
+ % prv thesis # scan for includes, setup thesis.dep
+ # if thesis.tex is does not exist
+
+ % prv -include thesis # scan for includes, setup thesis.dep
+ # if thesis.tex is newer
+
+ % prv -scan_force thesis # scan for includes, setup thesis.dep
+
+ % prv -clean # remove .aux, .log, .bbl, .blg, .dep,
+ # .dvi, .ps & .bbe files
+
+=head1 EMACS
+
+You can use prv for previewing and printing under emacs by creating functions
+for it in your .emacs file like this:
+
+ (defun prv ()
+ "preview latex document in the current buffer
+ after saving the buffer if necessary"
+ (interactive)
+ (save-buffer)
+ (message "Running prv.....")
+ (shell-command (concat "prv -noprintout " buffer-file-name))
+ (message "")
+ )
+
+ (defun prvpr (selection)
+ "print (a selection of pages from) the latex document
+ in the current buffer after saving it if necessary and
+ asking the user for a selection"
+ (interactive "sPages ([range[,range...]|a] [b|t] [x<n>]) [a] ")
+ (if (equal selection "")(setq selection "a"))
+ (save-buffer)
+ (message "Running prv.....")
+ (shell-command (concat "prv -b " selection " " buffer-file-name))
+ (message "")
+ )
+
+and binding those to function keys:
+
+ (global-set-key [f3] 'prv)
+ (global-set-key [\C-f3] 'prvpr)
+
+=HEAD1 VI
+
+You can use prv for previewing and printing under vi by adding this line to your .vimrc file:
+
+ map <F3> :w^M:!prv %^M
+
+Pressing F3 then shows an xdvi preview (or error messages...) and after quitting this you can
+print (part of) your document and return to vi.
+
+=head1 RC FILE
+
+There are four RC files that B<prv> can read at startup:
+
+The system RC file: UNIX: /etc/prvrc MSDOS: C:\lib\prv\prv
+
+The user's RC file: UNIX: $HOME/.prvrc MSDOS: $HOME\prv.rc
+
+The local RC file: UNIX: .prvrc MSDOS: prv.rc
+
+The command-line RC files specified on the command line with the -rcfile option.
+
+=head1 RC VARIABLES
+
+The available variables that can be set are shown below. Syntax is of
+the form:
+
+ $bibtex='bibtex';
+
+Default values are indicated in brackets.
+
+=over 4
+
+=item $leader and $trailer ['']
+
+If non-empty and a filename is a non-existing file, it will be given another try
+after packing it between $leader and $trailer. So if you like to have you latex files
+in ~/mydata/<some_number>/main.tex you can preview from any directory with:
+
+ prv 2134
+
+which will give you ~/mydata/2134/main.tex.
+
+=item $draft [0]
+
+The equivalent of the -draft option.
+
+=item $intensity_draft [0.95]
+
+The equivalent of the -intensity_draft option.
+
+=item $message_draft ['DRAFT']
+
+The equivalent to the -message_draft option.
+
+=item $scale_draft [220.0]
+
+The equivalent of the -scale_draft option.
+
+=item $bibtex ['bibtex']
+
+The BibTeX processing program.
+
+=item $bibtex_mode [0]
+
+If nonzero, the document has a bibtex bibliography. Set by the
+-scan and -scan_force options and saved in the dependency
+file. Should not need to set this in an RC file.
+
+=item $clean [0]
+
+The equivalent of the -clean option. Recommend that this is not
+set from an RC file.
+
+=item $clean_ext ['']
+
+Extra extensions of files for B<prv> to remove when the -clean
+option is selected.
+
+=item $full_clean_ext ['']
+
+Extra extensions of files for B<prv> to remove when the
+-full_clean option is selected.
+
+=item $cus_dep_list [empty]
+
+Custom dependency list (see below).
+
+=item $dvi_cont_previewer ['xdvi']
+
+The dvi-previewer to run with the -pvc option.
+
+=item $dvi_cont_previewer_landscape ['xdvi']
+
+The dvi-previewer to run with the -pvc option in landscape mode.
+
+=item $dvi_filter [empty]
+
+The equivalent of the -dvi_filter option.
+
+=item $dvi_previewer ['xdvi']
+
+The dvi-previewer to run with the -pv option.
+
+=item $dvi_previewer_landscape ['xdvi -paper a4r']
+
+The dvi-previewer to run with the -pv option in landscape mode.
+
+=item $dvips ['dvips']
+
+The program to used as a filter to convert a .dvi file to a .ps file.
+
+=item $dvips_landscape ['dvips -tlandscape']
+
+The program to used as a filter to convert a .dvi file to a .ps file
+in landscape mode.
+
+=item $scan_force [0]
+
+The equivalent of the -scan_force option.
+
+=item $continue [0]
+
+The equivalent of the -continue option.
+
+=item $ignore_missing_includes [0]
+
+The equivalent of the -ignore_missing_includes option.
+
+=item $scan [0]
+
+The equivalent of the -scan option.
+
+=item $go [0]
+
+The equivalent of the -go option.
+
+=item $index_mode [0]
+
+If nonzero, run makeindex to produce index of document. Set by the
+-scan and -scan_force options and saved in the dependency file.
+Should not need to set this in an RC file.
+
+
+=item $landscape [0]
+
+The equivalent of the -landscape option.
+
+=item $latex ['latex']
+
+The LaTeX processing program.
+
+=item $lpr ['lpr']
+
+The printing program.
+
+=item $makeindex ['makeindex']
+
+The index processing program.
+
+=item $ps [0]
+
+Equivalent to the -ps option.
+
+=item $pvc [0]
+
+The equivalent of the -pvc option.
+
+=item $preview [0]
+
+The equivalent of the -pv option.
+
+=item $printout [0]
+
+The equivalent of the -printout
+option. Recommend that this is not set from an RC file or you could
+waste lots of paper.
+
+=item $pscmd ['ps B<-x>']
+
+Command used to get all the processes currently run by the user. This
+is used by the -pvc option to try and reattach itself to the already
+existing previewer from a previous run with -pvc on the same file. The
+default works for SunOS (BSD UNIX?). For Solaris (System V?) try 'ps'
+in the B<prv> RC file.
+
+=item $ps_filter [empty]
+
+The equivalent of the -ps_filter option.
+
+=item $ps_previewer ['gs']
+
+The postscript previewer to run with the -pv option.
+
+=item $ps_previewer_landscape ['gs -swap']
+
+The postscript previewer to run with the -pv option in landscape mode.
+
+=item $sleep_time [2]
+
+The time to sleep (in seconds) between checking for source file
+changes when running the -pvc option.
+
+=item $texfile_search ['']
+
+If no files were specified on the command line, then B<prv> will
+search for files that match the file mask specifed in this variable.
+
+e.g.: $texfile_search = "$texfile_search *.ftex *.c.tex";
+
+=item $tmpdir [$TMP]
+
+Directory to store very small temporary files that B<prv>
+generates while running.
+
+=back
+
+=head1 CUSTOM DEPENDENCIES
+
+In any RC file a set of custom dependencies can be set up to convert a
+file with one extension to a file with another. An example use of
+this would be to allow B<prv> to convert a .fig file to
+dependencies are set up by using the @cus_dep_list array. Each string
+in the array has four arguments, separated by a space:
+
+=over 4
+
+=item from extension:
+
+The extension of the file we are converting from (e.g. "fig").
+
+=item to extension:
+
+The extension of the file we are converting to (e.g. "eps").
+
+=item must:
+
+If non-zero, the file we are converting from must exist, if it doesn't
+exist B<prv> will give an error message and exit unless the -continue
+option is specified. If must is zero and the file we are converting
+from doesn't exist, then no action is taken.
+
+
+=item function:
+
+The name of the subroutine that B<prv> should call to perform the
+file conversion. The first argument to the subroutine is the base
+name of the file to be converted without any extension. The
+subroutines are declared in the syntax of perl.
+
+=back
+
+Example in an RC file to convert a .fig file to a .eps file:
+
+@cus_dep_list = (@cus_dep_list, "fig eps 0 fig2eps");
+
+sub fig2eps {
+system("fig2dev -Lps $_[0].fig $_[0].eps"); }
+
+The subroutine fig2eps will only be called if the .fig file was
+modified more recently then the .eps file, or the .eps file does not
+exist.
+
+If the return value of the subroutine is non-zero, then B<prv>
+will assume an error occurred during the execution of the subroutine.
+
+=head1 ENVIRONMENT
+
+B<prv> needs several external programs; the following tabulates
+their function, default Unix name and default MS-Dos name:
+
+=over 4
+
+=item
+
+Function: Unix: MS-Dos:
+
+latex latex latex
+
+bibtex bibtex bibtex
+
+makeindex makeindex makeindex
+
+dvips dvips -s dvips -s
+
+dvips_landscape dvips -tlandscape dvips -tlandscape
+
+pscmd ps -x ps -x
+
+touch touch touch
+
+psselect psselect psselect
+
+pstops pstops pstops
+
+diff diff diff
+
+copy cp -p copy
+
+lpr lpr print
+
+ps_previewer gv gv
+
+ps_previewer_landscape gv -swap gv
+
+dvi_previewer xdvi windvi
+
+dvi_previewer_landscape xdvi -paper a4r windvi
+
+dvi_cont_previewer xdvi dviwin2 -1 -c
+
+dvi_cont_previewer_landscape xdvi -paper a4r dviwin2 -1 -c
+
+=back
+
+B<prv> needs the following environment variables:
+
+ HOME user's home directory, for rc files
+ TEXINPUTS user's directory for style files etc.
+ EDITOR editor to be used, is needed
+
+=head1 SEE ALSO
+
+latex(1), bibtex(1).
+
+=head1 BUGS
+
+If you use macros for generating input file names in your document,
+B<prv> will not be able to figure out what the name should be when
+trying to generate a dependency file. Using the -ignore_missing_includes option
+will make B<prv> ignore these, but B<prv> will also obviously
+not have a complete dependency list.
+
+\includegraphics[...]{ is unseen
+\includegraphics{file} is treated as \includegraphics{file.tex}
+
+=head1 IDENTIFICATION
+
+Modifications and enhancements by Wybo Dekker
+(wybo@servalys.nl), based on LatexMk by Evan McLean (Version
+2.0), original script called "go" by David J. Musliner (RCS Version
+3.2)
+
+=cut
+
+# This script is derived from LatexMk version 2.0, which has undergone a
+# major revision by wybo@servalys.nl. In particular:
+# - The options have been renamed to long names using the Getops::Long module.
+# - Page and print-format selection has been built in.
+# - The manpage has been converted to pod
+# - Works now also under MSDOS/Windows-95/NT
+# - Allows for interactive pages selection in the printing phase
+# - Facilities for printing reduced size booklets have been built in
+# - the -quiet option was added for silencing both prv and latex
+
+# version history
+# 0.2
+# - previous version did not work under MSDOS because of open(IN,"latex|")
+# construction.
+# - if a filename contains a path specification it is now detected and latex
+# is run in the directory where the .tex file is. Previously, it was run in
+# the starting directory, causing .aux, etcetera files to be created there
+# - source files are now required to have a .tex extension. The extension is
+# added if it is lacking.
+# - replaced .dviF with dvf for sake of MSDOS
+# - moved system rc file to /etc
+# - negation of boolean options built in (-noq besides -q)
+# - for path-less filenames another try is now given by packing it
+# between $leader and $trailer (which can be defined in an rc-file
+# - added -s option to dvips. Prevents bop-hooks to be copied documents
+# printed later
+# - changed the -batch option: now needs a string for format/page selection
+# - system calls now reported unless $quiet
+# - \typeout messages starting with -- now are printed in red to STDERR,
+# even in quiet mode
+# 0.3
+# - moved some variable from the `use vars' statement to an ="" statement,
+# because of uninitialized messages.
+# 0.4
+# - latex now runs in batchmode (-interaction=batchmode);
+# with the quiet option, if latex finds an error, only the error and
+# its explanation is reported.
+# 0.5
+# - revised testing of included files, removing tests on
+# \blackandwhite, \colorslides, \psfig, \epsfig, \epsfbox, \epsffile, but
+# adding \includegraphics
+# - if TEXINPUTS path ends in ::, the last dir is now searched with find
+# - Environment variable TMP *must* have been set now and must not end
+# in a / (MSDOS: \) any more
+# - new option e introduced in print menu: can be used to edit the source file
+# and rerun prv.
+# - lines beginning with exactly %\input can now be used to make prv recognise
+# dependency files that it would not find otherwise. For example, the moreverb
+# package has a command \listinginput{file}, or a user can create his own
+# commands for file inclusion.
+# - bibtex warnings are not seen as an error anymore
+# 0.6
+# - replaced Term::ReadLine interface with Term::Query
+# - for unix, replaced /tmp/{to,from}null with /dev/null
+# - sub latex_run now checks log file for Rerun request.
+# - removed slitex
+# - if no sourcefiles are given on the command line prv does not try to compile
+# *.tex anymore, since this would also imply compilation of input and include files.
+# Prv still looks in the variable $texfile_search though
+# - prv now offers the included file for editing if it contains the error
+# - the editor starts on the erroneous line
+# - temporary files are removed
+# - added comment about previewing under vi
+# - choosing -pvc now automatically cancels -pv instead of dying
+# - "Runaway argument" error messages now also displayed in quiet mode
+# 0.7
+# - removed requirement of environment variable TMP.
+# prv now supposes /tmp (\tmp for msdos) to be present and writable.
+# - search for included files now performed with kpsewhich
+# - $opt_variables renamed to the same without $opt_
+# - included files now are searched with their default extension appended,
+# but if that fails, the search is tried without it.
+# - Latex correctly producing no output is now seen as an error
+__DATA__
+Usage: prv [prv_options] [filename ...]
+
+prv_options:
+
+-b -batch <selection> run in batchmode, printing the selection
+-cl -clean clean up (remove) all nonessential files
+-co -continue force continued processing past errors
+-dr -draft Print `DRAFT' across the page (in PostScript)
+-dv -dvi_filter <filter> Filter to apply to dvi file
+-f -full_clean remove nonessential files including .dvi + .ps
+-g -go process regardless of file timestamps
+-h -help print help
+-ig -ignore_missing_includes Ignore missing files when making dependencies
+-in -intensity_draft <intensity> Set contrast or intensity of banner
+-l -landscape force landscape mode
+-m -message_draft <message> Print message across the page (in PostScript)
+-pr -printout print document after generating postscript
+-ps -ps generate postscript
+-ps_ -ps_filter <filter> Filter to apply to postscript file
+-pv -pv preview document
+-pvc -pvc preview document and continuously update
+-q -quiet Operate silently
+-r -rcfile <file> Read custom RC file
+-scal -scale_draft <scale> Set scale for draft-string
+-scan -scan rescan for includes if .dep older than .tex
+-scan_ -scan_force force rescan for includes
+-v -version display program version
+
+filename: the root filename of LaTeX document
+
+Remarks:
+-printout, -pv and -pvc are mutually exclusive
+-help, -clean and -full_clean overide all other options: they just help/clean.
+-pv and -pvc require exactly one filename specified
+-rcfile's file contents override earlier options on the command line
diff --git a/obsolete/support/prv/prvps b/obsolete/support/prv/prvps
new file mode 100755
index 0000000000..230d8aed9b
--- /dev/null
+++ b/obsolete/support/prv/prvps
@@ -0,0 +1,183 @@
+#!/usr/bin/perl -w
+use Env;
+use Config;
+use Term::ReadLine;
+
+=head1 NAME
+
+prvps - preview postscript document and eventually print it
+
+=head1 SYNOPSIS
+
+system call:
+
+ prvps [<filename>]
+
+=head1 DESCRIPTION
+
+B<prvps> previews PostScript documents and eventually
+prints them, letting you choose the pages and the output
+format. Without a F<filename>, standard input is used.
+If a file with F<filename> does not exist, F<filename.eps> is tried or,
+if that also does not exist, F<filename.ps>.
+B<prvps> displays your Postscript document
+using B<gv>, and then interrogates you about the pages you
+want to print. To that end the following prompt appears:
+
+Pages ([range[,range...]|a] [b|t] [x<n>])?
+
+You can react to this as in the following examples:
+
+ 5 # to print page 5
+ 5- # to print pages 5 through the end
+ 5-7 # to print pages 5, 6 and 7
+ -7 # to print the first 7 pages
+ 5-7,19- # to print pages 5, 6, 7 and 19 through the end
+ a # to print the whole document
+ a x3 # to print 3 copies of the document
+ x3 # the same
+ 5 x3 # to print 3 copies of page 5
+ t # print the whole document twosided
+ t 2- # print twosided starting at page 2
+ b # to print the whole document as an a5 size booklet
+ b -12 # to print the first 12 pages as an a5 size booklet
+
+If you use b to print a booklet, or t to print twosided, then you will
+have to arrange your printer such that, with the printed sides up, the
+first page printed will be at the bottom of the stack, and the last
+page printed will be on top. Normally you will then have your output
+come out the back of your printer.
+
+B<prvps> will first print one side of the
+paper and prompt you for a return when the printer is ready and you
+have turned the stack and put it back in the paper feed.
+
+Finally, if you used the b option to print a booklet, you will have to
+reshuffle your pages manually as follows:
+- take the bottom page from the stack and put it aside without
+ changing its position
+- take the top page from the stack and put it upside down on the
+ bottom page
+- repeat these two actions until the stack is empty
+- if you find out how to prevent this manual action, please tell me how
+ you did it!! (wybo@servalys.hobby.nl)
+
+=cut
+
+$term=new Term::ReadLine 'test';
+
+$TMP='/tmp' unless $TMP;
+$in = "$TMP/$$.in"; # temp file for saving standard input
+$sel = "$TMP/$$.sel"; # temp file for selected pages
+$front = "$TMP/$$.front"; # temp file for front pages
+$back = "$TMP/$$.back"; # temp file for back pages
+$print = $Config{'lpr'} or $print='lpr';
+$booklet=$selection=$lpropt=$doit="";
+$prompt='Pages ([range[,range...]|a] [b|t] [x<n>])? ';
+$print_prompt="printer ready? then turn pack and type return ";
+
+$file=shift or $file=""; # empty -> stdin
+if ($file) { # if a filename was given
+ if (! -f $file) { # and it does not exist
+ if (-f "$file.ps") { $file.=".ps" }
+ elsif (-f "$file.eps") { $file.='.eps' }
+ else { die "no file $file.eps or $file.ps found\n" }
+ }
+} else {
+ $file=$in;
+ open(OUT,">$in") or die("Could not open $file");
+ while(<>) { print OUT }; close OUT;
+}
+
+# look in the first non-empty line to check if it is right:
+open(IN,$file); do { chomp($_=<IN>) } until $_; close IN;
+
+/^%!PS/ or die("Input file is not a PostScript file\n");
+
+system "gv -scale 2 -spartan $file";
+
+
+$front_spec='"4:-3L@.707(210mm,0)+0L@.707(210mm,148.5mm)"';
+$back_spec='"4:1L@.707(210mm,0)+-2L@.707(210mm,148.5mm)"';
+while (1) {
+ if ($selection) { # if anything was set
+ print STDERR "\n";
+ $selection =~ /[1-9]/ or $selection.=" -e -o ";
+ system("psselect -q $selection $file $sel");
+ if ($booklet) {
+ system("pstops -q $front_spec $sel >$front");
+ system("$print $lpropt $front");
+ $term->readline($print_prompt);
+ system("pstops -q $back_spec $sel >$back");
+ system("$print $lpropt $back");
+ } elsif ($twosided) {
+ system("pstops 2:0 $sel >$front");
+ system("$print $lpropt $front");
+ $term->readline($print_prompt);
+ system("pstops 2:1 $sel >$back");
+ system("$print $lpropt $back");
+ } else {
+ system("$print $lpropt $sel");
+ }
+ }
+ $booklet=$twosided=$selection=$lpropt=$doit="";
+
+ $com=$term->readline($prompt);
+
+ for (split(/\s+/,$com)) {
+ CASE: {
+ /^q$/ # die on n of q
+ and goto READY; # don't just exit: may be called with do
+ /^x[0-9]+$/ # x3 -> lpr -#3
+ and do { s/x//;
+ print STDERR " $_ copies";
+ $lpropt = '-#'.$_;
+ $selection.=" -q";
+ },
+ last CASE;
+ /^b$/ # print a5 booklet
+ and do { $selection.=" -q ";
+ print STDERR " booklet";
+ $booklet=1;
+ },
+ last CASE;
+ /^t$/ # print twosided
+ and do { $selection.=" -q";
+ $twosided=1;
+ print STDERR " twosided";
+ },
+ last CASE;
+ /^a$/ # print all
+ and do { $selection="-e -o";
+ print STDERR " all pages";
+ },
+ last CASE;
+ /^(([0-9]+-?[0-9]*|[0-9]*-?[0-9]+),?)+$/ # n-m or n- or -m
+ and do { ($selection=$_) =~ s/,$//;
+ print STDERR " pages: $selection";
+ },
+ last CASE;
+
+ warn
+ "Illegal specification(s)\n".
+ "Examples of page specifications:\n".
+ "5 to print page 5\n".
+ "5- to print pages 5 through the end\n".
+ "5-7 to print pages 5, 6 and 7\n".
+ "-7 to print the first 7 pages\n".
+ "5-7,19- to print pages 5, 6, 7 and 19 through the end\n".
+ "a to print the whole document\n".
+ "a x3 to print 3 copies of the document\n".
+ "x3 the same\n".
+ "5 x3 to print 3 copies of page 5\n".
+ "t print the whole document twosided\n".
+ "t 2- print twosided starting at page 2\n".
+ "b to print the whole document as an a5 size booklet\n".
+ "b -12 to print the first 12 pages as an a5 size booklet\n";
+
+ }
+ }
+}
+READY:
+for (glob "/tmp/$$*") { unlink $_ }
+