From dce1a2a6ecd9971433b4ee24c9d36b124cc1280e Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Wed, 29 Dec 2021 03:01:06 +0000 Subject: CTAN sync 202112290301 --- support/latexdiff/latexdiff | 191 ++++++++++++++++++++++++++++++++------------ 1 file changed, 140 insertions(+), 51 deletions(-) (limited to 'support/latexdiff/latexdiff') diff --git a/support/latexdiff/latexdiff b/support/latexdiff/latexdiff index 9c2f45e957..c5291a0ca5 100755 --- a/support/latexdiff/latexdiff +++ b/support/latexdiff/latexdiff @@ -22,7 +22,23 @@ # # Detailed usage information at the end of the file # - +# +# Version 1.3.2 +# API adaptions: +# - latexdiff now completes with exit code 0 after --help or --version command (see issue #248) +# New features / feature extensions +# - extend CUSTOMDIFCMD related postprocessing to deal properly with multiline commands, or a sequence of several commands in the same line (see github issue #204) +# - Support for additional macros from import package (\import, \inputfrom, \includefrom, \subimport,\subinputfrom, \subincludefrom). Provided by janniklasrose in PR #243 (fixes #239) +# - replace default driver dvips->pdftex +# Bug fixes: +# - fix issue #206 affecting proper markup of text commands which are not safe cmd's at the same time and have multiple arguments +# - fix issue #210 by adding \eqref (amsmath package) to the list of safe commands +# - fix bug reported in issue #168 mangled verbatim line environment +# - fix bug reported in issue #218 by replacing \hspace{0pt} after \mbox{..} auxiliary commands with \hskip0pt. +# - more ways to process \frac correctly with atomic arguments (committed by julianuu PR #246 +# - fix a bug in biblatex mode, which prevented proper processing of modified \textcite (see: https://tex.stackexchange.com/questions/555157/latexdiff-and-biblatex-citation-commands) +# - -h string fix: add -driver option +# # Version 1.3.1.1 # - remove spurious \n to fix error: Unknown regexp modifier "/n" at .../latexdiff line 1974, near "=~ " (see github issue #201) # @@ -203,8 +219,8 @@ my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION); my ($versionstring)=<|\['.$brat_n.'\]|\{'. $pat_n . '\}|\(' . $coords .'\))'.$extraspace.')*'; +# standard $cmdoptseq (default: no intrevening spaces, controlled by extraspcae) - a final open parentheses is merged to the commend if it exists to deal properly with multi-argument text command + my $cmdoptseq='\\\\[\w\d@\*]+'.$extraspace.'(?:(?:<'.$abrat0.'>|\['.$brat_n.'\]|\{'. $pat_n . '\}|\(' . $coords .'\))'.$extraspace.')*\{?'; +# Handle tex \def macro: \def\MAKRONAME#1[#2]#3{DEFINITION} my $defseq='\\\\def\\\\[\w\d@\*]+(?:#\d+|\[#\d+\])+(?:\{'. $pat_n . '\})?'; my $backslashnl='\\\\\n'; my $oneletcmd='\\\\.\*?(?:\['.$brat_n.'\]|\{'. $pat_n . '\})*'; @@ -953,6 +972,9 @@ $ulem = ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{ulem\}/ || def # If listings is being used or can be found in the latexdiff search path, add to the preamble auxiliary code to enable line-by-line markup if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { my @listingpreamble=extrapream("LISTINGS"); + if ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) { + @listingpreamble=extrapream("COLORLISTINGS"); + } my @listingDIFcode=(); my $replaced; # note that in case user supplies preamblefile the type might not reflect well the @@ -1115,6 +1137,7 @@ if ( defined $packages{"apacite"} ) { } elsif (defined $packages{"biblatex"}) { print STDERR "biblatex package detected.\n" if $verbose ; $citpat='(?:[cC]ites?|(?:[pP]aren|foot|[Tt]ext|[sS]mart|super)cites?\*?|footnotecitetex)'; + push(@TEXTCMDEXCL, qr/^textcite$/); } else { # citation command pattern for all other citation schemes $citpat='(?:cite\w*|nocite)'; @@ -1391,6 +1414,9 @@ sub add_safe_commands { my $should_be_safe = $2; print STDERR "DEBUG Checking new command: maybe_to_test, should_be_safe: $1 $2\n" if $debug; my $success = 0; + # skip custom diff commands + next if ($maybe_to_test =~ m/^(?:ADD|DEL)?${CUSTOMDIFCMD}$/); + ###print STDERR "DEBUG: really test it. \n"; # test if all latex commands inside it are safe $success = 1; if ($should_be_safe =~ m/\\\\/) { @@ -1433,6 +1459,7 @@ sub remove_endinput { # expands \input and \include commands within text # expands \bibliography command with corresponding bbl file if available # expands \subfile command (from subfiles package - not part of standard text distribution) +# expands \import etc commands (from import package - not part of standard text distribution) # preamble is scanned for includeonly commands # encoding is the encoding sub flatten { @@ -1460,15 +1487,16 @@ sub flatten { # Run through filter, to let filterscript have a pass if it was set $text = filter($text); - # Recursively replace \\import and \\subimport files - $text =~ s/(^(?:[^%\n]|\\%)*)(\\subimport\{(.*?)\}|\\import\{(.*?)\})(?:[\s]*)\{(.*?)\}/{ + # Recursively replace \\import, \\subimport, and related import commands + $text =~ s/(^(?:[^%\n]|\\%)*)(\\(sub)?(?:import|inputfrom|includefrom))\{(.*?)\}(?:[\s]*)\{(.*?)\}/{ + # (--------1-------)(--(=3=)-------------2-------------------) (-4-) (-5-) # $1 is begline - # $3 is directory if subimport - # $4 is directory if import + # $2 is the import macro name + # $3 is (optional) prefix "sub" + # $4 is directory # $5 is filename $begline = (defined($1)? $1 : ""); - $subdir = $3 if defined($3); - $subdir = $4 if defined($4); + $subdir = $4; $fname = $5; $fname .= ".tex" unless $fname =~ m|\.\w{3,4}$|; print STDERR "DEBUG begline:", $begline, "\n" if $debug; @@ -1483,12 +1511,13 @@ sub flatten { print STDERR "importing importfilepath:", $importfilepath,"\n" if $verbose; if ( -f $importfilepath ) { # If file exists, replace input or include command with expanded input + #TODO: need remove_endinput & newpage similar to other replacements inside flatten $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding) or die "Could not open file ",$fullfile,": $!"; } else { # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition # and is not meant to be expanded directly print STDERR "WARNING: Could not find included file ",$importfilepath,". I will continue but not expand |$2|\n"; - $replacement=(defined($3)? "\\subimport" : "\\import"); + $replacement = $2; $replacement .= "{$subdir}{$fname} % Processed"; } "$begline$replacement"; @@ -2158,9 +2187,10 @@ sub marktags { # split this block to split sequences joined in pass1 + ### print STDERR "DEBUG: marktags before splitlatex blocksplit ",join("|",@$block),"\n" if $debug; @$block=splitlatex(join "",@$block); ### print STDERR "DEBUG: marktags $openmark,$closemark,$open,$close,$opencmd,$closecmd,$comment\n" if $debug; - ### print STDERR "DEBUG: marktags blocksplit ",join("|",@$block),"\n" if $debug; + print STDERR "DEBUG: after splitlatex ",join("|",@$block),"\n" if $debug; # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here @@ -2216,6 +2246,7 @@ sub marktags { # $2 (the command) is in context2, just treat it as an ordinary command (i.e. comment it open with $opencmd) # Because we do not want to disable this command # here we do not use $opencmd and $closecmd($opencmd is empty) + print STDERR "DEBUG: Detected text |$word| but not safe command \$2: $2 \$3: $3\n." if $debug; if ($cmd==1) { push (@$retval,$closecmd) ; } elsif ($cmd==0) { @@ -2274,7 +2305,7 @@ sub marktags { if ( $word =~ /^\\(?!\()(\\|[`'^"~=.]|[\w*@]+)(.*?)(\s*)$/s && iscmd($1,\@MBOXCMDLIST,\@MBOXCMDEXCL)) { # $word is a safe command in MBOXCMDLIST ###print STDERR "DEBUG Mboxsafecmd detected:$word:\n" if $debug ; - push(@$retval,"\\mbox{$AUXCMD\n\\" . $1 . $2 . $3 ."}\\hspace{0pt}$AUXCMD\n" ); + push(@$retval,"\\mbox{$AUXCMD\n\\" . $1 . $2 . $3 ."}\\hskip0pt$AUXCMD\n" ); } else { # $word is a normal word or a safe command (not in MBOXCMDLIST) push (@$retval,$word); @@ -2294,22 +2325,22 @@ sub take_comments_and_newline_from_frac() { # some special magic for common usage of frac, which does not conform to the latexdiff requirements but can be made to fit # note that this is a rare exception to the general rule that the new tex can be reconstructed from the diff file - # \frac12 -> \frac{1}{2} - s/\\frac(\d)(\w)/\\frac\{$1\}\{$2\}/g; - - # \frac1{2b} -> \frac{1}{2b} - s/\\frac(\d)/\\frac\{$1\}/g; - - # delete space and comment characters between \frac arguments -# s/\\frac(?:\s*?%[^\n]*?)*?(\{$pat_n\})\s*(\{$pat_n\})/\\frac$1$2/g; - s/\\frac(?:\s|%[^\n]*?)*(\{$pat_n\})(?:\s|%[^\n]*?)*(\{$pat_n\})/\\frac$1$2/g; + # regex that matches space and comment characters + my $space = qr/\s|%[^\n]*?/; + # \frac {abc} -> \frac{abc} + # \frac1 -> \frac{1} + # \frac a -> \frac{a} + # \frac \lambda -> \frac{\lambda} + s/\\frac(?|${space}+\{($pat_n)\}|${space}*(\d)|${space}+(\w)|${space}*(\\[a-zA-Z]+))/\\frac\{$1\}/g; + # same as above for the second argument of frac + s/\\frac(\{$pat_n\})(?|${space}*\{($pat_n)\}|${space}*(\d)|${space}+(\w)|${space}*(\\[a-zA-Z]+))/\\frac$1\{$2\}/g; } # preprocess($string, ..) # carry out the following pre-processing steps for all arguments: # 1. Remove leading white-space # Change \{ to \QLEFTBRACE and \} to \QRIGHTBRACE and \& to \AMPERSAND -# #. Change {,} in comments to \CLEFTBRACE, \CRIGHTBRACE +# #. Change {,},\frac in comments to \CLEFTBRACE, \CRIGHTBRACE, \CFRAC # 2. mark all first empty line (in block of several) with \PAR tokens # 3. Convert all '\%' into '\PERCENTAGE ' and all '\$' into \DOLLAR to make parsing regular expressions easier # 4. Convert all \verb|some verbatim text| commands (where | can be an arbitrary character) @@ -2345,9 +2376,11 @@ sub preprocess { s/(? to file latexdiff.debug.