summaryrefslogtreecommitdiff
path: root/support/latexmk/latexmk.pl
diff options
context:
space:
mode:
Diffstat (limited to 'support/latexmk/latexmk.pl')
-rwxr-xr-xsupport/latexmk/latexmk.pl295
1 files changed, 185 insertions, 110 deletions
diff --git a/support/latexmk/latexmk.pl b/support/latexmk/latexmk.pl
index ca0c8c3aa4..efe984e9dd 100755
--- a/support/latexmk/latexmk.pl
+++ b/support/latexmk/latexmk.pl
@@ -124,7 +124,7 @@ use warnings;
# Test for already running previewer gets wrong answer if another
# process has the viewed file in its command line
-## Copyright John Collins 1998-2019
+## Copyright John Collins 1998-2020
## (username jcc8 at node psu.edu)
## (and thanks to David Coppit (username david at node coppit.org)
## for suggestions)
@@ -162,6 +162,32 @@ use warnings;
##
## 12 Jan 2012 STILL NEED TO DOCUMENT some items below
##
+## 16 Apr 2020 John Collins Correct contents of "All targets (...) are up-to-date" message
+## V. 4.69a.
+## 12 Mar 2020 John Collins Version is 4.69
+## 7 Feb 2020 John Collins Report rc files read
+## 6 Feb 2020 John Collins Fix bug when -cd and -outdir are used, and outdir is
+## same as document directory. (Bug is caused by
+## problem in perl module Cwd.)
+## 2,3 Feb 2020 John Collins Correction in find_basename.
+## 31 Jan 2020 John Collins Cleanup sub exit_msg1: incorrect comment etc.
+## Extra @file_not_found entry for message from
+## \input on not-found-file
+## Remove use of $extension_treatment: Too hard to
+## check. Always use what was called 'unix' method.
+## When command-line-specified tex file not found,
+## test for cusdep to make it, then try kpsewhich,
+## and only if all 3 fail report an error.
+## 15 Jan 2020 John Collins Add -MSWinBackSlash -MSWinBackSlash- options to
+## control whether directory separator '\' is
+## used for filenames on command line for
+## called programs under MSWin.
+## 3 Jan 2020 John Collins Add -E option to default command for xdvipdfmx, to
+## match call made by xetex (see XeTeX_ext.c in
+## xetex source). This forces xdvipdfmx to always
+## try to embed fonts, ignoring licensing flags, etc.
+##
+## Current version (4.67, 26 Dec 2019) to CTAN
## 26 Dec 2019 John Collins Change place of setting of $view_file
## Make fully consistent set of options for engines:
## -latex, -latex=...,
@@ -254,8 +280,8 @@ use warnings;
$my_name = 'latexmk';
$My_name = 'Latexmk';
-$version_num = '4.67';
-$version_details = "$My_name, John Collins, 26 Dec. 2019";
+$version_num = '4.69a';
+$version_details = "$My_name, John Collins, 17 Apr. 2020";
use Config;
use File::Basename;
@@ -293,7 +319,7 @@ use FileHandle;
use File::Find;
use List::Util qw( max );
use Cwd; # To be able to change cwd
-use Cwd "chdir"; # Ensure $ENV{PWD} tracks cwd
+#use Cwd "chdir"; # Ensure $ENV{PWD} tracks cwd. NO NEED, and it messes up -cd -outdir=
use Digest::MD5;
#use strict;
@@ -337,6 +363,7 @@ $log_wrap = 79;
@file_not_found = (
'^No file\\s*(.*)\\.$',
'^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.',
+ '^\\! I can\\\'t find file `([^\\\']*)\\\'\\.',
'.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.',
'^LaTeX Warning: File `([^\\\']*)\\\' not found',
'^Package .* [fF]ile `([^\\\']*)\\\' not found',
@@ -653,7 +680,7 @@ $dvips_silent_switch = '-q';
$ps2pdf = 'ps2pdf %O %S %D';
## Command to convert xdv file to pdf file
-$xdvipdfmx = 'xdvipdfmx -o %D %O %S';
+$xdvipdfmx = 'xdvipdfmx -E -o %D %O %S';
$xdvipdfmx_silent_switch = '-q';
@@ -669,13 +696,6 @@ $print_type = 'auto'; # When printing, print the postscript file.
# 'auto' ==> set print type according to the printable
# file(s) being made: priority 'ps', 'pdf', 'dvi'
-## Which treatment of default extensions and filenames with
-## multiple extensions is used, for given filename on
-## tex/latex's command line? See sub find_basename for the
-## possibilities.
-## Current tex's treat extensions like UNIX teTeX:
-$extension_treatment = 'unix';
-
# Viewers. These are system dependent, so default to none:
$pdf_previewer = $ps_previewer = $ps_previewer_landscape = $dvi_previewer = $dvi_previewer_landscape = "NONE";
@@ -914,6 +934,8 @@ elsif ( $^O eq "cygwin" ) {
# NT executables.
$tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.';
+ # Which rc files did I read?
+ @rc_files_read = ();
## List of possibilities for the system-wide initialization file.
## The first one found (if any) is used.
## We could stay with MSWin files here, since cygwin perl understands them
@@ -1676,7 +1698,6 @@ sub read_first_rc_file_in_list {
" and in that case it should be a regular text file, not a directory.\n";
}
elsif ( -e $rc_file ) {
- #print "===Reading rc file \"$rc_file\" ...\n";
process_rc_file( $rc_file );
return;
}
@@ -1801,6 +1822,8 @@ while ($_ = $ARGV[0])
shift;
}
elsif ( /^-MP$/ ) { $dependents_phony = 1; }
+ elsif ( /-MSWinBackSlash$/ ) { $MSWin_back_slash = 1; }
+ elsif ( /-MSWinBackSlash-$/ ) { $MSWin_back_slash = 0; }
elsif (/^-new-viewer$/) {
$new_viewer_always = 1;
}
@@ -1990,6 +2013,9 @@ while ($_ = $ARGV[0])
}
}
+show_array( "Rc files read:", @rc_files_read )
+ unless ( $silent && ! $diagnostics );
+
if ( $bad_options > 0 ) {
&exit_help( "Bad options specified" );
}
@@ -2413,7 +2439,7 @@ foreach $filename ( @file_list )
($filename, $path) = fileparse( $filename );
warn "$My_name: Changing directory to '$path'\n"
if !$silent;
- pushd( $path );
+ pushd( dirname_no_tail( $path ) );
}
else {
$path = '';
@@ -2880,6 +2906,8 @@ sub set_dirs_etc {
# Normalize versions terminating in directory/path separator
# and versions referring to current directory
# These actions in a subroutine so they can be used elsewhere.
+ $out_dir = dirname_no_tail( $out_dir );
+ $aux_dir = dirname_no_tail( $aux_dir );
$out_dir1 = $out_dir;
$aux_dir1 = $aux_dir;
foreach ( $aux_dir1, $out_dir1 ) {
@@ -3410,84 +3438,76 @@ sub find_basename {
# 2 - Where to place base file
# 3 - Where to place tex file
# Returns non-zero if tex file does not exist
- #
- # The rules for determining this depend on the implementation of TeX.
- # The variable $extension_treatment determines which rules are used.
-
- # !!!!!!!! I still need to implement use of kpsewhich to match behavior
- # of (pdf)latex correctly.
-
- local($given_name, $base_name, $ext, $path, $tex_name);
- $given_name = $_[0];
- if ( "$extension_treatment" eq "miktex_old" ) {
- # Miktex v. 1.20d:
- # 1. If the filename has an extension, then use it.
- # 2. Else append ".tex".
- # 3. The basename is obtained from the filename by
- # removing the path component, and the extension, if it
- # exists. If a filename has a multiple extension, then
- # all parts of the extension are removed.
- # 4. The names of generated files (log, aux) are obtained by
- # appending .log, .aux, etc to the basename. Note that
- # these are all in the CURRENT directory, and the drive/path
- # part of the originally given filename is ignored.
- #
- # Thus when the given filename is "\tmp\a.b.c", the tex
- # filename is the same, and the basename is "a".
-
- ($base_name, $path, $ext) = fileparse( $given_name, '\..*' );
- if ( "$ext" eq "") { $tex_name = "$given_name.tex"; }
- else { $tex_name = $given_name; }
- $_[1] = $base_name;
- $_[2] = $tex_name;
- }
- elsif ( "$extension_treatment" eq "unix" ) {
- # unix (at least TeXLive 2016) =>
- # A. Finding of tex file:
- # 1. If filename.tex exists, use it,
- # 2. else if kpsewhich finds filename.tex, use it
- # 3. else if filename exists, use it,
- # 4. else if kpsewhich finds filename, use it.
- # (Probably can unify the above by
- # 1'. If kpsewhich finds filename.tex, use result.
- # 2'. else if kpsewhich finds filename, use result.
- # 3'. else report file not found.
- # B. The base filename is obtained by deleting the path
- # component and, if an extension exists, the last
- # component of the extension, even if the extension is
- # null. (A name ending in "." has a null extension.)
- # C. The names of generated files (log, aux) are obtained by
- # appending .log, .aux, etc to the basename. Note that
- # these are all in the CURRENT directory, and the drive/path
- # part of the originally given filename is ignored.
- #
- # Thus when the given filename is "/tmp/a.b.c", there are two
- # cases:
- # a. /tmp/a.b.c.tex exists. Then this is the tex file,
- # and the basename is "a.b.c".
- # b. /tmp/a.b.c.tex does not exist. Then the tex file is
- # "/tmp/a.b.c", and the basename is "a.b".
- # But there are also modifications of this when a file can be
- # found by kpsewhich.
-
- if ( -f "$given_name.tex" ) {
- $tex_name = "$given_name.tex";
- }
- else {
- $tex_name = "$given_name";
- }
- ($base_name, $path, $ext) = fileparse( $tex_name, '\.[^\.]*' );
- $_[1] = $base_name;
- $_[2] = $tex_name;
- }
- else {
- die "$My_name: Incorrect configuration gives \$extension_treatment=",
- "'$extension_treatment'\n";
- }
- if ($diagnostics) {
- print "Given='$given_name', tex='$tex_name', base='$base_name'\n";
- }
- return ! -e $tex_name;
+
+ my $fail = 0;
+ local ( $given_name, $base_name, $ext, $path, $tex_name, $source_name );
+ $given_name = $_[0];
+ $source_name = '';
+ $tex_name = $given_name; # Default name if I don't find the tex file
+ ($base_name, $path, $ext) = fileparseB( $given_name );
+
+ # Treatment of extensions (in TeXLive 2019), with omission of path search:
+ # Exists: always means exists as a file, i.e., not as a directory.
+ # A. Finding of tex file:
+ # 1. If extension is .tex and given_name.tex exists, use it.
+ # 2. Else if given_name.tex exists, use it.
+ # 3. Else if givne_name exists, use it.
+ # B. The base filename is obtained by deleting the path
+ # component and the extension.
+ # C. The names of generated files (log, aux) are obtained by appending
+ # .log, .aux, etc to the basename. Note that these are all in the
+ # CURRENT directory (or the output or aux directory, as appropriate).
+ # The drive/path part of the originally given filename is ignored.
+
+ # Here we'll do:
+ # 1. Find the tex file by the above method, if possible.
+ # 2. If not, find a custom dependency with a source file that exists to
+ # make the tex file so that after the tex file is made, the above
+ # rules find the tex file.
+ # 3. If that also fails, use kpsewhich on given_name to find the tex
+ # file
+ # 4. If that also fails, report non-existent tex file.
+
+
+ if ( ($ext eq '.tex') && (-f $given_name) ) {
+ $tex_name = "$given_name";
+ }
+ elsif ( -f "$given_name.tex" ) {
+ $tex_name = "$given_name.tex";
+ $base_name .= $ext;
+ }
+ elsif ( -f $given_name ) {
+ $tex_name = $given_name;
+ }
+ elsif ( ($ext eq '.tex') && find_cus_dep( $given_name, $source_name ) ) {
+ $tex_name = $given_name;
+ }
+ elsif ( find_cus_dep( "$given_name.tex", \$source_name ) ) {
+ $tex_name = "$given_name.tex";
+ $base_name .= $ext;
+ }
+ elsif ( ($ext =~ /^\..+/) && find_cus_dep( $given_name, $source_name ) ) {
+ $tex_name = $given_name;
+ }
+ else {
+ my @kpse_result = kpsewhich( $given_name );
+ if ($#kpse_result < 0) {
+ $fail = 1;
+ }
+ else {
+ $tex_name = $kpse_result[0];
+ ($base_name) = fileparseB( $tex_name );
+ }
+ }
+
+ $_[1] = $base_name;
+ $_[2] = $tex_name;
+
+ if ($diagnostics) {
+ print "Given='$given_name', tex='$tex_name', base='$base_name', ext= $ext, source='$source_name'\n";
+ }
+ return $fail;
+
} #END find_basename
#************************************************************
@@ -3728,8 +3748,8 @@ sub process_rc_file {
# Exit with code 2 if is a syntax error or other problem.
my $rc_file = $_[0];
my $ret_code = 0;
- warn "$My_name: Executing Perl code in file '$rc_file'...\n"
- if $diagnostics;
+ push @rc_files_read, $rc_file;
+
# I could use the do command of perl, but the preceeding -r test
# to get good diagnostics gets the wrong result under cygwin
# (e.g., on /cygdrive/c/latexmk/LatexMk)
@@ -3878,10 +3898,9 @@ sub traceback {
sub exit_msg1
{
- # exit_msg1( error_message, retcode [, action])
+ # exit_msg1( error_message, retcode )
# 1. display error message
- # 2. if action set, then restore aux file
- # 3. exit with retcode
+ # 2. exit with retcode
warn "\n------------\n";
warn "$My_name: $_[0].\n";
warn "-- Use the -f option to force complete processing.\n";
@@ -3985,6 +4004,10 @@ sub print_help
" -M - Show list of dependent files after processing\n",
" -MF file - Specifies name of file to receives list dependent files\n",
" -MP - List of dependent files includes phony target for each source file.\n",
+ " -MSWinBackSlash under MSWin use backslash (\\) for directory separators\n",
+ " for filenames given to called programs\n",
+ " -MSWinBackSlash- under MSWin use forward slash (/) for directory separators\n",
+ " for filenames given to called programs\n",
" -new-viewer - in -pvc mode, always start a new viewer\n",
" -new-viewer- - in -pvc mode, start a new viewer only if needed\n",
" -nobibtex - never use bibtex\n",
@@ -5396,6 +5419,30 @@ sub parse_fls {
#************************************************************
+sub dirname_no_tail {
+ my $dirname = $_[0];
+# print "DNT1 = '$dirname'\n";
+ foreach ($dirname) {
+ # Normalize name to use / to separate directory components:
+ # (Note both / and \ are allowed under MSWin.)
+ s(\\)(/)g;
+ # Change multiple trailing / to single /
+ # (Note internal // or \\ can have special meaning on MSWin)
+ s(/+$)(/);
+ # Remove trailing /,
+ # BUT **not** if that changes the semantics, i.e., if name is "/" or "C:/".
+ if ( m(/$) ) {
+ if ( ( ! m(^/+$) ) && ( ! m(:/+$) ) ) {
+ s(/$)();
+ }
+ }
+ }
+# print "DNT2 = '$dirname'\n";
+ return $dirname;
+}
+
+#************************************************************
+
sub clean_filename {
# Convert quoted filename as found in log file to filename without quotes
# Allows arbitrarily embedded double-quoted substrings, includes the
@@ -5427,13 +5474,17 @@ sub normalize_filename {
# (Note both / and \ are allowed under MSWin.)
foreach ($cwd, $file, @dirs) {
s(\\)(/)g;
+ $_ = dirname_no_tail( $_ );
}
# Remove initial component equal to current working directory.
# Use \Q and \E round directory name in regex to avoid interpretation
# of metacharacters in directory name:
foreach my $dir ( @dirs, '.', $cwd ) {
- if ( $file =~ s(^\Q$dir\E/)() ) {
- last;
+ if ( $dir =~ /^\s*$/ ) {
+ next;
+ }
+ if ( $file =~ s(^\Q$dir\E/)() ) {
+ last;
}
}
return $file;
@@ -6172,6 +6223,7 @@ sub rdb_set_latex_deps {
}
&parse_log;
+
my $missing_dirs = 'none'; # Status of missing directories
if (@missing_subdirs) {
$missing_dirs = 'success';
@@ -6639,7 +6691,7 @@ MISSING_FILE:
foreach my $dep (@cus_dep_list){
my ($fromext,$toext) = split('\s+',$dep);
if ( ( "$ext" eq "$toext" )
- && ( -e "$path$base.$fromext" )
+ && ( -f "$path$base.$fromext" )
) {
# Source file for the missing file exists
# So we have a real include file, and it will be made
@@ -6657,14 +6709,14 @@ MISSING_FILE:
# and $_ doesn't have an extension
foreach my $dep (@cus_dep_list){
my ($fromext,$toext) = split('\s+',$dep);
- if ( -e "$path$base.$fromext" ) {
+ if ( -f "$path$base.$fromext" ) {
# Source file for the missing file exists
# So we have a real include file, and it will be made
# next time by &rdb__dependents
$new_includes{"$path$base.$toext"} = 1;
# next MISSING_FILE;
}
- if ( -e "$path$base.$toext" ) {
+ if ( -f "$path$base.$toext" ) {
# We've found the extension for the missing file,
# and the file exists
$new_includes{"$path$base.$toext"} = 1;
@@ -7265,8 +7317,10 @@ sub rdb_make {
print "$My_name: Errors, so I did not complete making targets\n";
}
else {
+# local @dests = ( keys %current_primaries, @pre_primary, @post_primary, @unusual_one_time );
+ local @rules = ( keys %current_primaries, @post_primary, @unusual_one_time );
local @dests = ();
- rdb_for_some( [@_], sub{ push @dests, $$Pdest if ($$Pdest); } );
+ rdb_for_some( [@rules], sub{ push @dests, $$Pdest if ($$Pdest); } );
print "$My_name: All targets (@dests) are up-to-date\n";
}
}
@@ -7440,7 +7494,7 @@ sub rdb_make1 {
$rules_applied{$rule} = 1;
$runs++;
- $pass{$rule}++;
+ $pass{$rule}++;
if ($bibtex_not_run > 0) {
if ($bibtex_not_run == 1 ) {
show_array ("$My_name: I WON'T RUN '$rule' because I don't find the following files:",
@@ -7449,7 +7503,7 @@ sub rdb_make1 {
elsif ($bibtex_not_run == 2 ) {
warn "$My_name: I AM CONFIGURED/INVOKED NOT TO RUN '$rule'\n";
}
- $return = &rdb_dummy_run1;
+ $return = &rdb_dummy_run0;
}
else {
warn_running( "Run number $pass{$rule} of rule '$rule'" );
@@ -7822,7 +7876,7 @@ sub rdb_run1 {
#-----------------
-sub rdb_dummy_run1 {
+sub rdb_dummy_run0 {
# Assumes contexts for: rule.
# Update rule state as if the rule ran successfully,
# but don't run the rule.
@@ -7844,7 +7898,7 @@ sub rdb_dummy_run1 {
$$Pout_of_date = $$Pout_of_date_user = 0;
return 0;
-} # END rdb_dummy_run1
+} # END rdb_dummy_run0
#-----------------
@@ -9211,8 +9265,6 @@ sub create_empty_file {
#************************************************************
sub find_file1 {
-#?? Need to use kpsewhich, if possible
-
# Usage: find_file1(name, ref_to_array_search_path)
# Modified find_file, which doesn't die.
# Given filename and path, return array of:
@@ -9407,6 +9459,29 @@ sub show_cus_dep {
####################################################
+sub find_cus_dep {
+ # Usage find_cus_dep( dest, source )
+ # Given dest, if a cus_dep to make it is found, set source.
+ # Return 1 or 0 on success or failure.
+ #
+ my $dest = $_[0];
+ my ($base, $path, $ext) = fileparseB( $dest );
+ $ext =~ s/^\.//;
+ if (! $ext ) { return 0; }
+ foreach my $dep ( @cus_dep_list ) {
+ my ($fromext, $toext) = split( '\s+', $dep );
+ if ( ( "$ext" eq "$toext" ) && ( -f "$path$base.$fromext" ) ) {
+ # We have a way of making $dest
+ $_[1] = "$path$base.$fromext";
+ return 1
+ }
+ }
+ return 0;
+}
+
+####################################################
+####################################################
+
sub add_aux_hook {
# Usage: add_aux_hook( sub_name )
# Add the name subroutine to the array of hooks for
@@ -9975,7 +10050,7 @@ sub good_cwd {
sub pushd {
push @dir_stack, [cwd(), $cache{cwd}];
if ( $#_ > -1) {
- chdir $_[0];
+ chdir dirname_no_tail( $_[0] );
&cache_good_cwd;
}
}