diff options
author | Karl Berry <karl@freefriends.org> | 2014-08-04 00:09:56 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-08-04 00:09:56 +0000 |
commit | f952e56a75da8832693dc815964d8e0d70d0cba1 (patch) | |
tree | ad5d7f70a26688ef813b6d7817e05204196b8466 /Master/texmf-dist/doc/support/latexdiff | |
parent | c14edad764061790360f3d3fae1951bb8d4d6603 (diff) |
latexdiff
git-svn-id: svn://tug.org/texlive/trunk@34824 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/support/latexdiff')
-rw-r--r-- | Master/texmf-dist/doc/support/latexdiff/Makefile | 64 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/latexdiff/README | 5 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/latexdiff/contrib/README.latexchanges | 13 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/latexdiff/contrib/latexchanges.py | 67 | ||||
-rwxr-xr-x | Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff-wrap | 192 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff.spec | 58 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/latexdiff/doc/example-diff.tex | 4 | ||||
-rw-r--r-- | Master/texmf-dist/doc/support/latexdiff/doc/latexdiff-man.pdf | bin | 283199 -> 261188 bytes | |||
-rwxr-xr-x | Master/texmf-dist/doc/support/latexdiff/latexdiff | 291 | ||||
-rwxr-xr-x | Master/texmf-dist/doc/support/latexdiff/latexdiff-fast | 291 |
10 files changed, 815 insertions, 170 deletions
diff --git a/Master/texmf-dist/doc/support/latexdiff/Makefile b/Master/texmf-dist/doc/support/latexdiff/Makefile new file mode 100644 index 00000000000..45467307879 --- /dev/null +++ b/Master/texmf-dist/doc/support/latexdiff/Makefile @@ -0,0 +1,64 @@ +# Modify these paths to the requirements of your own system +# For the current setting you will need root permission but +# it is perfectly acceptable to choose user directories +# +INSTALLPATH = /usr/local +INSTALLMANPATH = $(INSTALLPATH)/man +INSTALLEXECPATH = $(INSTALLPATH)/bin + +default: + @echo "To install stand-alone version type: make install" + @echo " (Note the standard version requires prior installation" + @echo " of the PERL package Algorithm::Diff available from " + @echo " the PERL archive www.cpan.org)" + @echo " " + @echo "To install fast version (using UNIX diff) type: make install fast " + @echo " " + @echo "To install the version which uses the system Algorithm::Diff package type: make install-ext" + @echo " " + +install: install-so + +install-ext: install-latexdiff install-latexrevise install-latexdiff-vc install-man + +install-so: install-latexdiff-so install-latexrevise install-latexdiff-vc install-man + +install-fast: install-latexdiff-fast install-latexrevise install-latexdiff-vc install-man + +install-man: + install latexrevise.1 latexdiff.1 latexdiff-vc.1 $(INSTALLMANPATH)/man1 + +install-latexdiff: + install latexdiff $(INSTALLEXECPATH) + +install-latexdiff-so: + if [ -e $(INSTALLEXECPATH)/latexdiff ]; then rm $(INSTALLEXECPATH)/latexdiff; fi + install latexdiff-so $(INSTALLEXECPATH) + cd $(INSTALLEXECPATH); ln -s latexdiff-so latexdiff + +install-latexdiff-fast: + if [ -e $(INSTALLEXECPATH)/latexdiff ]; then rm $(INSTALLEXECPATH)/latexdiff; fi + install latexdiff-fast $(INSTALLEXECPATH) + cd $(INSTALLEXECPATH); ln -s latexdiff-fast latexdiff + +install-latexrevise: + install latexrevise $(INSTALLEXECPATH) + +install-latexdiff-vc: + install latexdiff-vc $(INSTALLEXECPATH) + cd $(INSTALLEXECPATH); for vcs in cvs rcs svn ; do if [ -e latexdiff-$$vcs ]; then rm latexdiff-$$vcs; fi; ln -s latexdiff-vc latexdiff-$$vcs ; done + +test-ext: + @echo "latexdiff example/example-draft.tex example/example-rev.tex (system Algorithm::Diff)" + ./latexdiff -V example/example-draft.tex example/example-rev.tex > example/example-diff.tex + @echo "Difference file created: example/example-diff.tex" + +test-so: + @echo "latexdiff example/example-draft.tex example/example-rev.tex (stand-alone version)" + ./latexdiff-so -V example/example-draft.tex example/example-rev.tex > example/example-diff.tex + @echo "Difference file created: example/example-diff.tex" + +test-fast: + @echo "latexdiff example/example-draft.tex example/example-rev.tex (stand-alone version)" + ./latexdiff-fast -V example/example-draft.tex example/example-rev.tex > example/example-diff.tex + @echo "Difference file created: example/example-diff.tex" diff --git a/Master/texmf-dist/doc/support/latexdiff/README b/Master/texmf-dist/doc/support/latexdiff/README index 7c7ff86766b..e9e189350e0 100644 --- a/Master/texmf-dist/doc/support/latexdiff/README +++ b/Master/texmf-dist/doc/support/latexdiff/README @@ -48,7 +48,7 @@ The basic installation procedure is almost trivial: 3. Optionally create soft links latexdiff-cvs latexdiff-rcs, and latexdiff-svn for latexdiff-vc. -The attached Makefile contains example commands to carry out above +The attached trivial Makefile contains example commands to carry out above steps as root for a typical UNIX installation. Type make install (for the stand alone version) @@ -65,7 +65,8 @@ or or make test-fast -to test the respective versions on a brief example before installation +to test the respective versions on a brief example before installation. It will often be +as easy to carry out these steps manually instead of using the Makefile. DOCUMENTATION: diff --git a/Master/texmf-dist/doc/support/latexdiff/contrib/README.latexchanges b/Master/texmf-dist/doc/support/latexdiff/contrib/README.latexchanges new file mode 100644 index 00000000000..4a027658444 --- /dev/null +++ b/Master/texmf-dist/doc/support/latexdiff/contrib/README.latexchanges @@ -0,0 +1,13 @@ +latexchanges.py (Jan-Ake Larsson): +Here's a wrapper I wrote for latexdiff, intended as a drop-in +replacement for latex, when you have several numbered (or dated) +versions of a manuscript. My coauthors don't as a rule know what CVS or +SVN is, they simply use a number or date for the different versions. + +latexchanges replaces the current DVI with one that includes a +latexdiff to the last version. The last version is selected as the +TEX file in the same directory with the same prefix (up to a number +or a dot), that has an mtime immediately preceding the given TEX +file. + + diff --git a/Master/texmf-dist/doc/support/latexdiff/contrib/latexchanges.py b/Master/texmf-dist/doc/support/latexdiff/contrib/latexchanges.py new file mode 100644 index 00000000000..de7acbe8258 --- /dev/null +++ b/Master/texmf-dist/doc/support/latexdiff/contrib/latexchanges.py @@ -0,0 +1,67 @@ +#! /bin/env python +# latexchanges +# +# Wrapper for latexdiff, intended as a drop-in replacement for latex, +# when you have several numbered (or dated) versions of a manuscript. +# My coauthors don't as a rule know what CVS or SVN is, they simply +# use a number or date for the different versions. +# +# latexchanges replaces the current DVI with one that includes a +# latexdiff to the last version. The last version is selected as the +# TEX file in the same directory with the same prefix (up to a number +# or a dot), that has an mtime immediately preceding the given TEX +# file. +# +# (I should probably add CVS version numbering too, at some point.) +# +# Copyright (C) 2009 by Jan-\AA{}ke Larsson <jan-ake.larsson@liu.se> +# Released under the terms of the GNU General Public License (GPL) +# Version 2. See http://www.gnu.org/ for details. +# +# Please do provide patches and bug reports, but remember: if it +# breaks, you get to keep the pieces. +# +# Jan-\AA{}ke Larsson +# Sept 16 2009 + +from os import listdir,system,stat +from sys import argv +from re import split + +name="" +newarg=[] + +# Find filename argument +for i in range(1,len(argv)): + if argv[i][-4:]==".tex": + basename=split('[0-9.]',argv[i])[0] + name=argv[i][:-4] + newarg.append(name+".changes.tex") + else: + newarg.append(argv[i]) + +if name: + print "Filename",name+".tex" + print "Prefix is",basename + # Find last archived version + mtime=stat(name+".tex").st_mtime + old_mtime=0 + ls=listdir(".") + for j in ls: + if j.startswith(basename) and j.endswith(".tex")\ + and not j.endswith(".changes.tex"): + tmptime=stat(j).st_mtime + if mtime>tmptime and old_mtime<tmptime: + oldname=j + old_mtime=tmptime + + # Archived version found? + if old_mtime>0: + print "Comparing with",oldname + system ("/bin/cp "+name+".aux "+name+".changes.aux") + system ("/bin/cp "+name+".bbl "+name+".changes.bbl") + system ("latexdiff "+oldname+" "+name+".tex > "+name+".changes.tex") + system ("latex "+" ".join(newarg)) + system ("cp "+name+".changes.dvi "+name+".dvi") + else: + system ("latex "+" ".join(argv[1:])) diff --git a/Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff-wrap b/Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff-wrap new file mode 100755 index 00000000000..894b424de36 --- /dev/null +++ b/Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff-wrap @@ -0,0 +1,192 @@ +#!/bin/bash +# +# latexdiff-wrap +# +# Wrapper for latexdiff, to +# * provide support for documents consiting of more than 1 latex file +# * provide my common arguments +# +# Copyright (C) by Volker Kuhlmann <VolkerKuhlmann@gmx.de> +# Released under the terms of the GNU General Public License (GPL) Version 2. +# See http://www.gnu.org/ for details. +# +# Volker Kuhlmann +# 5, 6, 7, 12, 16, 17 Oct 2005 +# 31 Jan; 5, 7, 13, 15 Feb 2006 +# + +VERSION="0.6, 15 Feb 2006" +AUTHOR="Volker Kuhlmann <VolkerKuhlmann@gmx.de>" +COPYRIGHT="Copyright (C) 2005-2006" + + +#### +#### Constants and initialised variables +# +diffcmd="latexdiff" +diffrc="$HOME/texmf/latexdiff" +#diffargs="-e latin1 --ignore-warnings -p latexdiff-preamble.sty" +diffargs="-e latin1 --ignore-warnings" +diffargs="$diffargs --append-safecmd $diffrc/safe-cmds" +diffargs="$diffargs --append-textcmd $diffrc/text-cmds" +# Note: Can't use multiple --append-safecmd +# show current command lists: +#diffcmd="$diffcmd --show-safecmd --show-textcmd --show-config" + + +#### +#### Version, Usage, Help +# +show_version() { + echo "${0##*/} version $VERSION +$COPYRIGHT by $AUTHOR" +} + +show_usage() { + echo " +Usage: ${0##*/} OLDDIR NEWDIR DIFFDIR [DIFFARGS --] FILE.tex [...] + ${0##*/} --show [DIFFARGS] +Version $VERSION +$COPYRIGHT by $AUTHOR +" +} + +show_help() { + show_usage + echo "\ +For each FILE.tex, build a new file DIFFDIR/FILE.tex with markup of the changes +which were made from OLDDIR/FILE.tex to NEWDIR/FILE.tex. +Any path given with FILE.tex is stripped off. +Any DIFFARGS are added to the latexdiff call, if present (remember to follow +them with a double-hyphen on its own before the FILE arguments). + +With --show, shows the settings latexdiff would be running with, including the +changes applied by the user. +" +} + +# For scripts not using function library only: +Version() { show_version; exitwith ErrVersion; } +Usage() { show_help; exitwith ErrUsage; } +Help() { test "$1" && exitwith ErrHelp show_help; show_help; exitwith ErrOK; } + + +#### +#### Error/Exit codes +# +exitwith() { + exec 1>&2 # write stdout on stderr instead + case "$1" in + ErrOK) + exit 0;; + ErrVersion|ErrUsage|ErrHelp) + # Output generated by function (program) $2, if given + test -n "$2" && "$2" + exit 1;; + # more codes in here + # more codes in here + ErrBadoption) + echo "Bad option '$2'." + echo "Call with -h for help." + exit 9;; + ErrMissingParameter) + echo "A required parameter for option $2 is missing." + echo "Call with -h for help." + exit 9;; + *) + echo "Internal error: exitwith() called with illegal error code '$1'." + exit 19;; + esac +} + + +#### +#### Parse command line parameters +# + +# If the next arg starts with a "-", collect additional argument for latexdiff +# until "--". +scanextraargs() { + addargs=() + case "$1" in -*) + while [ $# -gt 0 -a "$1" != "--" ]; do + addargs=( "${addargs[@]}" "$1" ) + shift + done + test "$1" == "--" && shift + ;; esac + fileargs=( "$@" ) +} + +case "$1" in + --version) Version;; + --usage) Usage;; + --help|-h|-help) Help;; + --show) + shift + scanextraargs "$@" + (set -x + $diffcmd $diffargs "${addargs[@]}" \ + --show-safecmd --show-textcmd --show-config + ) | fmt + exit $? ;; +esac + +olddir="${1%/}" +newdir="${2%/}" +diffdir="${3%/}" + +if ! [ -d "$olddir" -a -d "$newdir" -a -d "$diffdir" ]; then + Help 1>&2 err +fi + +shift 3 + +scanextraargs "$@" +set -- "${fileargs[@]}" + + + +#### +#### Functions +# +#set -x +Log() { echo 1>&2 "+ $@"; "$@"; } + + +#### +#### Main +# + +# Create output directory, just in case. +(set -x +mkdir -p "$diffdir" +) +while [ $# -gt 0 ]; do + file="${1##*/}" + echo Examining: "$file" + # No point running latexdiff if both files are identical, + # but run latexdiff on top-level LaTeX file in any case. + if cmp --quiet "$olddir/$file" "$newdir/$file" \ + && ! grep -lq '\\begin.*{document}' "$newdir/$file"; then + (set -x + cp -p "$olddir/$file" "$diffdir" + ) + else + # Delete file, to make sure it's not clobbered by redirecting stdout + # in case it's a symlink to te original. + test -f "$diffdir/$file" && (set -x + rm "$diffdir/$file" + ) + # Run latexdiff if both input files are present. + run=1 + test -f "$olddir/$file" || { echo 1>&2 "No file: $olddir/$file"; run=; } + test -f "$newdir/$file" || { echo 1>&2 "No file: $newdir/$file"; run=; } + test -n "$run" && \ + (set -x + $diffcmd $diffargs "${addargs[@]}" \ + "$olddir/$file" "$newdir/$file" > "$diffdir/$file" + ) + fi + shift +done diff --git a/Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff.spec b/Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff.spec new file mode 100644 index 00000000000..9255a69fea9 --- /dev/null +++ b/Master/texmf-dist/doc/support/latexdiff/contrib/latexdiff.spec @@ -0,0 +1,58 @@ +Summary: Diff for LaTeX files +Name: latexdiff +Version: 0.5 +Release: 1 +License: GPL +Group: Productivity/Publishing/TeX/Utilities +URL: http://www.tug.org/tex-archive/help/Catalogue/entries/latexdiff.html +Source0: %{name}.zip +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +# only required for 'make install-ext' +# Requires: perl-Algorithm-Diff + + +%description +latexdiff is a Perl script, which compares two latex files and marks +up significant differences between them (i.e. a diff for latex files). + Various options are available for visual markup using standard latex +packages such as "color.sty". Changes not directly affecting visible +text, for example in formatting commands, are still marked in +the latex source. + +(C) 2004 Frederik Tilmann <tilmann@esc.cam.ac.uk> + + +%prep +%setup -n %{name} + + +%build +# quick had to adapt the Makefile +%{__mv} Makefile Makefile.old +%{__sed} \ + -e "s;INSTALLPATH = /usr/local;INSTALLPATH = \${DESTDIR}%{_prefix};" \ + -e "s;INSTALLMANPATH = \$(INSTALLPATH)/man;INSTALLMANPATH = \${DESTDIR}%{_mandir};" \ + Makefile.old > Makefile + + +%install +%{__mkdir_p} $RPM_BUILD_ROOT%{_bindir} +%{__mkdir_p} $RPM_BUILD_ROOT%{_mandir}/man1 + +%makeinstall + + +%clean +[ "${RPM_BUILD_ROOT}" != "/" ] && [ -d "${RPM_BUILD_ROOT}" ] && %{__rm} -rf "${RPM_BUILD_ROOT}" + + +%files +%defattr(-,root,root) +%doc example CHANGES LICENSE README +%{_bindir}/* +%{_mandir}/man*/* + +%changelog +* Thu Jan 4 2007 Till Dörges <till@doerges.net> - 0.5-1 +- Initial build. diff --git a/Master/texmf-dist/doc/support/latexdiff/doc/example-diff.tex b/Master/texmf-dist/doc/support/latexdiff/doc/example-diff.tex index a4764813b58..7166571f398 100644 --- a/Master/texmf-dist/doc/support/latexdiff/doc/example-diff.tex +++ b/Master/texmf-dist/doc/support/latexdiff/doc/example-diff.tex @@ -1,7 +1,7 @@ \documentclass[12pt,a4paper]{article} %DIF LATEXDIFF DIFFERENCE FILE -%DIF DEL example-draft.tex Sun Jan 27 23:50:07 2013 -%DIF ADD example-rev.tex Sun Jan 27 23:50:07 2013 +%DIF DEL example-draft.tex Thu Jun 12 00:01:26 2014 +%DIF ADD example-rev.tex Thu Jun 12 00:01:26 2014 \setlength{\topmargin}{-0.2in} \setlength{\textheight}{9.5in} diff --git a/Master/texmf-dist/doc/support/latexdiff/doc/latexdiff-man.pdf b/Master/texmf-dist/doc/support/latexdiff/doc/latexdiff-man.pdf Binary files differindex 30242d8b36a..a3d640adfe2 100644 --- a/Master/texmf-dist/doc/support/latexdiff/doc/latexdiff-man.pdf +++ b/Master/texmf-dist/doc/support/latexdiff/doc/latexdiff-man.pdf diff --git a/Master/texmf-dist/doc/support/latexdiff/latexdiff b/Master/texmf-dist/doc/support/latexdiff/latexdiff index febae2d5be1..717a0933a2f 100755 --- a/Master/texmf-dist/doc/support/latexdiff/latexdiff +++ b/Master/texmf-dist/doc/support/latexdiff/latexdiff @@ -3,9 +3,9 @@ # latexdiff - differences two latex files on the word level # and produces a latex file with the differences marked up. # -# Copyright (C) 2004-12 F J Tilmann (tilmann@gfz-potsdam.de, ftilmann@users.berlios.de) +# Copyright (C) 2004-12 F J Tilmann (tilmann@gfz-potsdam.de) # -# Project webpages: http://latexdiff.berlios.de/ +# Repository/issue tracker: https://github.com/ftilmann/latexdiff # CTAN page: http://www.ctan.org/tex-archive/support/latexdiff # # This program is free software: you can redistribute it and/or modify @@ -22,14 +22,34 @@ # # Detailed usage information at the end of the file # +# ToDo: +# +# Version 1.0.4 +# - introduce list UNSAFEMATHCMD, which holds list of commands which cannot be marked up with \DIFadd or \DIFdel commands (only relevant for WHOLE and COARSE math markup modes) +# - new subtype LABEL which gives each change a label. This can later be used to only display pages where changes +# have been made (instructions for that are put as comments into the diff'ed file) inspired by answer on http://tex.stackexchange.com/questions/166049/invisible-markers-in-pdfs-using-pdflatex +# - Configuration variables take into accout some commands from additional packages: +# tikzpicture environment now treated as PICTUREENV, and \smallmatrix in ARRENV (amsmath) +# - --flatten: support for \subfile command (subfiles package) (in response to http://tex.stackexchange.com/questions/167620/latexdiff-with-subfiles ) +# - --flatten: \bibliography commands expand if corresponding bbl file present +# - angled bracket optional commands now parsed correctly (patch #3570) submitted by Dave Kleinschmidt (thanks) +# - \RequirePackage now treated as synonym of \usepackage with respect to setting packages +# - special rules for apacite package (redefine citation commands) +# - recognise /dev/null as 'file-like' arguments for --preamble and --config options +# - fix units package incompatibility with ulem for text maths statements $ ..$ (thanks to Stuart Prescott for reporting this) +# - amsmath environment cases treated correctly (Bug fix #19029) (thanks to Jalar) +# - {,} in comments no longer confuse latexdiff (Bug fix #19146) +# - \% in one-letter sub/Superscripts was not converted correctly +# # Version 1.0.3 # - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator # command in preamble -# - \(..\) inline math expressions were not parsed correctly, if the contained a linebreak +# - \(..\) inline math expressions were not parsed correctly, if they contained a linebreak # - applied patch contributed by tomflannaghan via Berlios: [ Patch #3431 ] Adds correct handling of \left< and \right> # - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug -# and sketching out the solution) -# - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript (thanks to Wail Yahyaoui for pointing out this bug) +# and sketching out the solution) +# - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript +# (thanks to Wail Yahyaoui for pointing out this bug) # # Version 1.0.1 - treat \big,\bigg etc. equivalently to \left and # \right - include starred version in MATHENV - apply @@ -92,28 +112,30 @@ my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION); my ($versionstring)=<<EOF ; -This is LATEXDIFF 1.0.3 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) - (c) 2004-2013 F J Tilmann +This is LATEXDIFF 1.0.4 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) + (c) 2004-2014 F J Tilmann EOF # Configuration variables: these have to be visible from the subroutines my $MINWORDSBLOCK=3; # minimum number of tokens to form an independent block # shorter identical blocks will be merged to the previous word my $FLOATENV='(?:figure|table|plate)[\w\d*@]*' ; # Environments in which FL variants of defined commands are used -my $PICTUREENV='(?:picture|DIFnomarkup)[\w\d*@]*' ; # Environments in which all change markup is removed +my $PICTUREENV='(?:picture|tikzpicture|DIFnomarkup)[\w\d*@]*' ; # Environments in which all change markup is removed my $MATHENV='(?:equation[*]?|displaymath|DOLLARDOLLAR)[*]?' ; # Environments turning on display math mode (code also knows about \[ and \]) my $MATHREPL='displaymath'; # Environment introducing deleted maths blocks my $MATHARRENV='(?:eqnarray|align|alignat|gather|multline|flalign)[*]?' ; # Environments turning on eqnarray math mode my $MATHARRREPL='eqnarray*'; # Environment introducing deleted maths blocks -my $ARRENV='(?:array|[pbvBV]matrix)'; # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block +my $ARRENV='(?:array|[pbvBV]?matrix|smallmatrix|cases|split)'; # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block my $COUNTERCMD='(?:footnote|part|chapter|section|subsection|subsubsection|paragraph|subparagraph)'; # textcmds which are associated with a counter # If any of these commands occur in a deleted block # they will be succeeded by an \addtocounter{...}{-1} # for the associated counter such that the overall numbers # should be the same as in the new file +my @UNSAFEMATHCMD=('qedhere'); # Commands which are definitely unsafe for marking up (amsmath qedhere only tested to not work with UNDERLINE markup) my $CITECMD=0 ; # \cite-type commands which need to be protected within an mbox in UNDERLINE and other modes using ulem; pattern simply designed to never match; will be overwritten later for selected styles my $CITE2CMD=0; # \cite-type commands which should be reinstated in deleted blocks - +my $MBOXINLINEMATH=0; # if set to 1 then surround marked-up inline maths expression with \mbox ( to get around compatibility + # problems between some maths packages and ulem package # Markup strings @@ -176,7 +198,7 @@ my ($type,$subtype,$floattype,$config,$preamblefile,$encoding,$nolabel,$visiblel $replacecontext1,$appendcontext1, $replacecontext2,$appendcontext2, $help,$verbose,$driver,$version,$ignorewarnings, - $enablecitmark,$disablecitmark,$allowspaces,$flatten,$debug); ###$disablemathmark, + $enablecitmark,$disablecitmark,$allowspaces,$flatten,$debug,$earlylatexdiffpreamble); ###$disablemathmark, # MNEMNONICS for mathmarkup my $mathmarkup; use constant { @@ -205,6 +227,11 @@ $mathmarkup=COARSE; $verbose=0; # output debug and intermediate files, set to 0 in final distribution $debug=0; +# insert preamble directly after documentclass - experimental feature, set to 0 in final distribution +# Note that this failed with mini example (or other files, where packages used in latexdiff preamble +# are called again with incompatible options in preamble of resulting file) +$earlylatexdiffpreamble=0; + # define character properties sub IsNonAsciiPunct { return <<'END' # Unicode punctuation but excluding ASCII punctuation +utf8::IsPunct @@ -312,29 +339,6 @@ foreach $excludesafe ( @excludesafelist ) { init_regex_arr_ext(\@SAFECMDEXCL, $excludesafe); } -# Special: treat all cite commands as safe except in UNDERLINE and FONTSTRIKE mode -# (there is a conflict between citation and ulem package, see -# package documentation) -# Use post-processing - -if ( uc($type) ne "UNDERLINE" && uc($type) ne "FONTSTRIKE" && uc($type) ne "CULINECHBAR" ) { - push (@SAFECMDLIST, qr/^cite.*$/); -} else { - ### Experimental: disable text and emph commands - push (@SAFECMDLIST, qr/^cite.*$/) unless $disablecitmark; - push(@SAFECMDEXCL, qr/^emph$/, qr/^text..$/); - # replace \cite{..} by \mbox{\cite{..}} in added or deleted blocks in post-processing - if ( uc($subtype) eq "COLOR" or uc($subtype) eq "DVIPSCOL" ) { - # remove \cite command again from list of safe commands - pop @SAFECMDLIST; - # deleted cite commands - $CITE2CMD='(?:cite\w*|nocite)' unless $disablecitmark ; # \cite-type commands which should be reinstated in deleted blocks - } else { - $CITECMD='(?:cite\w*|nocite)' unless $disablecitmark ; # \cite commands which need to be protected within an mbox in UNDERLINE and other modes using ulem - } -} -$CITECMD='(?:cite\w*|nocite)' if $enablecitmark ; # as above for explicit selection - # setting up @TEXTCMDLIST and @TEXTCMDEXCL if (defined($replacetext)) { init_regex_arr_ext(\@TEXTCMDLIST,$replacetext); @@ -373,7 +377,7 @@ foreach $appendcontext2 ( @appendcontext2list ) { # setting configuration variables @config=(); foreach $config ( @configlist ) { - if (-f $config ) { + if (-f $config || lc $config eq '/dev/null' ) { open(FILE,$config) or die ("Couldn't open configuration file $config: $!"); while (<FILE>) { chomp; @@ -484,6 +488,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); my $pat5 = '(?:[^{}]|\{'.$pat4.'\})*'; my $pat6 = '(?:[^{}]|\{'.$pat5.'\})*'; my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; + my $abrat0 = '(?:[^<>])*'; my $quotemarks = '(?:\'\')|(?:\`\`)'; my $punct='[0.,\/\'\`:;\"\?\(\)\[\]!~\p{IsNonAsciiPunct}\p{IsNonAsciiS}]'; @@ -495,7 +500,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); my $word='(?:[-\w\d*]|\\\\[\"\'\`~^][A-Za-z\*])+'; my $cmdleftright='\\\\(?:left|right|[Bb]igg?[lrm]?|middle)\s*(?:[<>()\[\]|]|\\\\(?:[|{}]|\w+))'; - my $cmdoptseq='\\\\[\w\d\*]+'.$extraspace.'(?:(?:\['.$brat0.'\]|\{'. $pat6 . '\}|\(' . $coords .'\))'.$extraspace.')*'; + my $cmdoptseq='\\\\[\w\d\*]+'.$extraspace.'(?:(?:<'.$abrat0.'>|\['.$brat0.'\]|\{'. $pat6 . '\}|\(' . $coords .'\))'.$extraspace.')*'; my $backslashnl='\\\\\n'; my $oneletcmd='\\\\.\*?(?:\['.$brat0.'\]|\{'. $pat6 . '\})*'; my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; @@ -504,8 +509,6 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); my $comment='%.*?\n'; my $pat=qr/(?:\A\s*)?(?:${and}|${quotemarks}|${number}|${word}|$cmdleftright|${cmdoptseq}|${math}|${backslashnl}|${oneletcmd}|${comment}|${punct}|${mathpunct}|\{|\})\s*/ ; - - # now we are done setting up and can start working my ($oldfile, $newfile) = @ARGV; # check for existence of input files @@ -559,6 +562,9 @@ if ($flatten) { $newbody=flatten($newbody,$newpreamble,$newfile,$encoding); } + + + my @auxlines; if ( length $oldpreamble && length $newpreamble ) { # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) @@ -572,13 +578,25 @@ if ( length $oldpreamble && length $newpreamble ) { # Base this assessment on the new preamble add_safe_commands($newpreamble); + # get a list of packages from preamble if not predefine %packages=list_packages(@newpreamble) unless %packages; + ### if ( %packages ) {print STDERR "DEBUG Packages: ",%packages,"\n" ;} if (defined $packages{"hyperref"} ) { + # deleted lines should not generate or appear in link names: print STDERR "hyperref package detected.\n" if $verbose ; $latexdiffpreamble =~ s/\{\\DIFadd\}/{\\DIFaddtex}/g; $latexdiffpreamble =~ s/\{\\DIFdel\}/{\\DIFdeltex}/g; $latexdiffpreamble .= join "\n",(extrapream("HYPERREF"),""); } + + if (defined $packages{"units"} && ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{ulem\}/ ) ) { + # protect inlined maths environments by surrounding with an \mbox + # this is done to get around an incompatibility between the ulem and units package + # where spaces in the argument to underlined or crossed-out \unit commands cause an error message + print STDERR "units package detected at the same time as style using ulem.\n" if $verbose ; + $MBOXINLINEMATH=1; + } + print STDERR "Differencing preamble.\n" if $verbose; # insert dummy first line such that line count begins with line 1 (rather than perl's line 0) - just so that line numbers inserted by linediff are correct @@ -596,7 +614,14 @@ if ( length $oldpreamble && length $newpreamble ) { push @diffpreamble,"%DIF DELETED TITLE COMMANDS FOR MARKUP"; push @diffpreamble,join("\n",@auxlines); } - push @diffpreamble,$latexdiffpreamble; + if ( $earlylatexdiffpreamble) { + # insert latexdiff command directly after documentclass at beginning of preamble + # note that grep is only run for its side effect + ( grep { s/^([^%]*\\documentclass.*)$/$1$latexdiffpreamble/ } @diffpreamble )==1 or die "Could not find documentclass statement in preamble"; + } else { + # insert latexdiff commands at the end of preamble (default behaviour) + push @diffpreamble,$latexdiffpreamble; + } push @diffpreamble,'\begin{document}'; } elsif ( !length $oldpreamble && !length $newpreamble ) { @@ -606,6 +631,43 @@ elsif ( !length $oldpreamble && !length $newpreamble ) { exit(2); } +# Special: treat all cite commands as safe except in UNDERLINE and FONTSTRIKE mode +# (there is a conflict between citation and ulem package, see +# package documentation) +# Use post-processing +# and $packages{"apacite"}!~/natbibpapa/ +my ($citpat,$citpatsafe); + +if ( defined $packages{"apacite"} ) { + print STDERR "DEBUG apacite citation commands\n" if $debug; + $citpatsafe=qr/^(?:mask)?(?:full|short)?cite(?:A|author|year)?(?:NP)?$/; + $citpat='(?:mask)?(?:full|short|no)?cite(?:A|author|year|meta)?(?:NP)?'; +} else { + # citation command pattern for all other citation schemes + $citpatsafe=qr/^cite.*$/; + $citpat='(?:cite\w*|nocite)'; +}; + +if ( uc($type) ne "UNDERLINE" && uc($type) ne "FONTSTRIKE" && uc($type) ne "CULINECHBAR" ) { + push (@SAFECMDLIST, $citpatsafe); +} else { + ### Experimental: disable text and emph commands + push (@SAFECMDLIST, $citpatsafe) unless $disablecitmark; + push(@SAFECMDEXCL, qr/^emph$/, qr/^text..$/); + # replace \cite{..} by \mbox{\cite{..}} in added or deleted blocks in post-processing + if ( uc($subtype) eq "COLOR" or uc($subtype) eq "DVIPSCOL" ) { + # remove \cite command again from list of safe commands + pop @SAFECMDLIST; + # deleted cite commands + $CITE2CMD=$citpat unless $disablecitmark ; # \cite-type commands which should be reinstated in deleted blocks + } else { + $CITECMD=$citpat unless $disablecitmark ; # \cite commands which need to be protected within an mbox in UNDERLINE and other modes using ulem + } +} +$CITECMD=$citpat if $enablecitmark ; # as above for explicit selection + +print STDERR "CITECMD:|$CITECMD|\n" if $debug; + if (defined $packages{"amsmath"} or defined $packages{"amsart"} or defined $packages{"amsbook"} ) { print STDERR "amsmath package detected.\n" if $verbose ; $MATHARRREPL='align*'; @@ -697,7 +759,7 @@ sub read_file_with_encoding { } # %packages=list_packages(@preamble) -# scans the arguments for \documentclass and \usepackage statements and constructs a hash +# scans the arguments for \documentclass,\RequirePackage and \usepackage statements and constructs a hash # whose keys are the included packages, and whose values are the associated optional arguments sub list_packages { my (@preamble)=@_; @@ -705,7 +767,7 @@ sub list_packages { foreach $line ( @preamble ) { # get rid of comments $line=~s/(?<!\\)%.*$// ; - if ( $line =~ m/\\(?:documentclass|usepackage)(?:\[(.+?)\])?\{(.*?)\}/ ) { + if ( $line =~ m/\\(?:documentclass|usepackage|RequirePackage)(?:\[(.+?)\])?\{(.*?)\}/ ) { # print STDERR "Found something: |$line|\n"; if (defined($1)) { $packages{$2}=$1; @@ -742,7 +804,7 @@ sub add_safe_commands { } } - while ( $preamble =~ m/\\(?:|re|provide)newcommand\s*{\\(\w*)\}(?:|\[\d*\])\s*\{(${pat6})\}/osg ) { + while ( $preamble =~ m/\\(?:new|renew|provide)command\s*{\\(\w*)\}(?:|\[\d*\])\s*\{(${pat6})\}/osg ) { my $maybe_to_test = $1; my $should_be_safe = $2; my $success = 0; @@ -772,14 +834,20 @@ sub add_safe_commands { # flatten($text,$preamble,$filename,$encoding) # 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) # preamble is scanned for includeonly commands # encoding is the encoding sub flatten { my ($text,$preamble,$filename,$encoding)=@_; - my ($includeonly,$dirname,$fname,$newpage,$replacement,$begline); + my ($includeonly,$dirname,$fname,$newpage,$replacement,$begline,$bblfile,$subfile); + my ($subpreamble,$subbody,$subpost); require File::Basename ; require File::Spec ; $dirname = File::Basename::dirname($filename); + $bblfile = $filename; + $bblfile=~s/\.tex$//; + $bblfile.=".bbl"; if ( ($includeonly) = ($preamble =~ m/\\includeonly{(.*?)}/ ) ) { $includeonly =~ s/,/|/g; @@ -789,9 +857,10 @@ sub flatten { print STDERR "DEBUG: includeonly $includeonly\n" if $debug; + # recursively replace \\input and \\include files $text=~s/(^(?:[^%\n]|\\%)*)\\input{(.*?)}|\\include{(${includeonly}(?:\.tex)?)}/{ $fname = $2 if defined($2) ; - $fname = $3 if defined($3) ; + $fname = $3 if defined($3) ; # # add tex extension unless there is a three letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3}|; print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ; @@ -805,6 +874,34 @@ sub flatten { $newpage=(defined($3)? " \\newpage " : "") ; "$begline$newpage$replacement$newpage"; }/exgm; + # replace bibliography with bbl file if it exists + $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography{(.*?)}/{ + if ( -f $bblfile ){ + $replacement=read_file_with_encoding(File::Spec->catfile($bblfile), $encoding); + } else { + warn "Bibliography file $bblfile cannot be found. No flattening of \\bibliography done. Run bibtex on old and new files first"; + $replacement="\\bibliography{$2}"; + } + $begline=(defined($1)? $1 : "") ; + "$begline$replacement"; + }/exgm; + # replace subfile with contents (subfile package) + $text=~s/(^(?:[^%\n]|\\%)*)\\subfile{(.*?)}/{ + $fname = $2; + # # add tex extension unless there is a three letter extension already + $fname .= ".tex" unless $fname =~ m|\.\w{3}|; + print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ; + print STDERR "Include file as subfile $fname\n" if $verbose; + print STDERR "DEBUG looking for file ",File::Spec->catfile($dirname,$fname), "\n" if $debug; + # content of file becomes replacement value (use recursion) + # now strip away everything outside and including \begin{document} and \end{document} pair# + # # note: no checking for comments is made + $subfile=read_file_with_encoding(File::Spec->catfile($dirname,$fname), $encoding) or die "Couldn't find file ",File::Spec->catfile($dirname,$fname),": $!"; + ($subpreamble,$subbody,$subpost)=splitdoc($subfile,'\\\\begin\{document\}','\\\\end\{document\}'); + $replacement=flatten($subbody, $preamble,$filename,$encoding); + $begline=(defined($1)? $1 : "") ; + "$begline$replacement"; + }/exgm; return($text); } @@ -830,7 +927,7 @@ sub extrapream { while (@_) { $copy=0; $type=shift ; - if ( -f $type ) { + if ( -f $type || lc $type eq '/dev/null' ) { open (FILE,$type) or die "Cannot open preamble file $type: $!"; print STDERR "Reading preamble file $type\n" if $verbose ; while (<FILE>) { @@ -1398,7 +1495,7 @@ sub marktags { # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to # "" local @SAFECMDLIST=(".*"); - local @SAFECMDEXCL=('\\','\\\\'); + local @SAFECMDEXCL=('\\','\\\\',@UNSAFEMATHCMD); push(@$retval,$command,marktags("","",$open,$close,"","",$comment,\@argtext)#@argtext ,$closingbracket); } else { @@ -1433,9 +1530,8 @@ sub marktags { # preprocess($string, ..) # carry out the following pre-processing steps for all arguments: # 1. Remove leading white-space -# Change \{ to \LEFTBRACE and \} to \RIGHTBRACE -# #. change begin and end commands within comments to BEGINDIF, ENDDIF -# so they don't disturb the pattern matching (if there are several \begin or \end in one line +# Change \{ to \QLEFTBRACE and \} to \QRIGHTBRACE +# #. Change {,} in comments to \CLEFTBRACE, \CRIGHTBRACE # 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) @@ -1462,11 +1558,9 @@ sub preprocess { # Change \{ to \QLEFTBRACE and \} to \QRIGHTBRACE s/(?<!\\)\\{/\\QLEFTBRACE /sg; s/(?<!\\)\\}/\\QRIGHTBRACE /sg; - # change begin and end commands within comments such that they - # don't disturb the pattern matching (if there are several \begin or \end in one line - # this substitution is insufficient but that appears unlikely) - s/(%.*)\\begin\{(.*)$/$1\\BEGINDIF\{$2/mg ; - s/(%.*)\\end\{(.*)$/$1\\ENDDIF\{$2/mg ; +# replace {,} in comments with \\CLEFTBRACE,\\CRIGHTBRACE + 1 while s/((?<!\\)%.*)\{(.*)$/$1\\CLEFTBRACE $2/mg ; + 1 while s/((?<!\\)%.*)\}(.*)$/$1\\CRIGHTBRACE $2/mg ; s/\n(\s*?)\n((?:\s*\n)*)/\n$1\\PAR\n$2/g ; s/(?<!\\)\\%/\\PERCENTAGE /g ; # (?<! is negative lookbehind assertion to prevent \\% from being converted @@ -1579,7 +1673,7 @@ sub fromhash { # 9.. remove all \PAR tokens # 10. package specific processing: endfloat: make sure \begin{figure} and \end{figure} are always # on a line by themselves, similarly for table environment -# 4, undo renaming of the \begin and \end in comments +# 4, undo renaming of the \begin, \end,{,} in comments # Change \QLEFTBRACE, \QRIGHTBRACE to \{,\} # # Note have to manually synchronize substitution commands below and @@ -1705,8 +1799,14 @@ sub postprocess { } # or protect \cite commands with \mbox if ($CITECMD) { - $delblock=~s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat6\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; + $delblock=~s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat6\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; } + # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox + if ( $MBOXINLINEMATH ) { + # note additional \newline after command is omitted from output if right at the end of deleted block (otherwise a spurious empty line is generated) + $delblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; + } + # splice in modified delblock substr($_,$begin,$len)=$delblock; pos = $begin + length($delblock); @@ -1728,7 +1828,16 @@ sub postprocess { } if ($CITECMD) { my $addblockbefore=$addblock; - $addblock=~ s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat2\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; + #(?:mask)?(?:full|short|no)?cite(?:A|author|year|meta)(?:NP)?$/ + ###my $CITECMD; $CITECMD="cite(?:A)$"; + $addblock=~ s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat2\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; + print STDERR "DEBUG: CITECMD $CITECMD\nDEBUG: addblock before:|$addblockbefore|\n" if $debug; + print STDERR "DEBUG: addblock after: |$addblock|\n" if $debug; + } + # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox + if ( $MBOXINLINEMATH ) { + ##$addblock=~s/($math)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; + $addblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } # splice in modified addblock substr($_,$begin,$len)=$addblock; @@ -1736,13 +1845,6 @@ sub postprocess { } - ### old place for BEGINDIF, ENDDIF replacement - # change begin and end commands within comments such that they - # don't disturb the pattern matching (if there are several \begin or \end in one line - # this substitution is insufficient but that appears unlikely) - # This needs to be repeated here to also get rid of DIFdelcmd-protected environments - s/(%.*)\\begin\{(.*)$/$1\\BEGINDIF\{$2/mg ; - s/(%.*)\\end\{(.*)$/$1\\ENDDIF\{$2/mg ; # Replace MATHMODE environments from step 1a above by the correct Math environment @@ -1809,8 +1911,8 @@ sub postprocess { s/(\\verb\*?)\{([-\d]*?)\}/"${1}". fromhash(\%verbhash,$2)/esg; s/${DELCMDOPEN}\\(verbatim\*?)\{([-\d]*?)\}/"${DELCMDOPEN}\\begin{${1}}".fromhash(\%verbhash,$2,$DELCMDOPEN)."${DELCMDOPEN}\\end{${1}}"/esg; s/\\(verbatim\*?)\{([-\d]*?)\}/"\\begin{${1}}".fromhash(\%verbhash,$2)."\\end{${1}}"/esg; - # Convert '\PERCENTAGE ' back into '\%' - s/\\PERCENTAGE /\\%/g; + # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated + s/\\PERCENTAGE ?/\\%/g; # Convert '\DOLLAR ' back into '\$' s/\\DOLLAR /\\\$/g; # remove all \PAR tokens (taking care to properly keep commented out PAR's @@ -1833,9 +1935,7 @@ sub postprocess { # split lines with remaining characters after float enviroment conmmand s/(\\(?:begin|end)\{(?:figure|table)\})(.+)$/$1\n$2/mg; } - # undo renaming of the \begin and \end and dollars in comments - s/(%.*)\\BEGINDIF\{(.*)$/$1\\begin\{$2/mg ; - s/(%.*)\\ENDDIF\{(.*)$/$1\\end\{$2/mg ; + # undo renaming of the \begin and \end,{,} and dollars in comments 1 while s/(%.*)DOLLARDIF/$1\$/mg ; # undo renaming of the \cite.. commands in comments if ( $CITECMD ) { @@ -1847,11 +1947,15 @@ sub postprocess { # 4. Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$ s/\\begin\{DOLLARDOLLAR\}(.*?)\\end\{DOLLARDOLLAR\}/\$\$$1\$\$/sg; # 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn} - 1 while s/\\SUPERSCRIPTNB{($pat0)}/^$1/g ; 1 while s/\\SUPERSCRIPT{($pat6)}/^{$1}/g ; + 1 while s/\\SUPERSCRIPTNB{($pat0)}/^$1/g ; # Convert \SUBSCRIPNB{n} into _n and \SUBCRIPT{nn} into _{nnn} - 1 while s/\\SUBSCRIPTNB{($pat0)}/_$1/g ; 1 while s/\\SUBSCRIPT{($pat6)}/_{$1}/g ; + 1 while s/\\SUBSCRIPTNB{($pat0)}/_$1/g ; + 1 while s/(%.*)\\CRIGHTBRACE (.*)$/$1\}$2/mg ; + 1 while s/(%.*)\\CLEFTBRACE (.*)$/$1\{$2/mg ; + + # Change \QLEFTBRACE, \QRIGHTBRACE to \{,\} s/\\QLEFTBRACE /\\{/sg; s/\\QRIGHTBRACE /\\}/sg; @@ -2114,7 +2218,7 @@ format as new.tex but has all changes relative to old.tex marked up or commented --subtype=markstyle -s markstyle Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin) - Available styles: SAFE MARGINAL DVIPSCOL COLOR + Available styles: SAFE MARGINAL DVIPSCOL COLOR LABEL [ Default: SAFE ] --floattype=markstyle @@ -2213,7 +2317,7 @@ format as new.tex but has all changes relative to old.tex marked up or commented Use of the --packages option disables automatic scanning, so if for any reason package specific parsing needs to be switched off, use --packages=none. The following packages trigger special behaviour: - endfloat hyperref amsmath + endfloat hyperref amsmath apacite [ Default: scan the preamble for \\usepackage commands to determine loaded packages.] @@ -2269,7 +2373,7 @@ Miscelleneous options --no-label Suppress inclusion of old and new file names as comment in output file ---visble-label Include old and new filenames (or labels set with --label option) as +--visible-label Include old and new filenames (or labels set with --label option) as visible output --flatten Replace \\input and \\include commands within body by the content @@ -2294,7 +2398,6 @@ Miscelleneous options --version Show version number. -For further information, consult http://latexdiff.berlios.de EOF } @@ -2457,7 +2560,7 @@ B<-s markstyle> Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin). This option defines C<\DIFaddbegin>, C<\DIFaddend>, C<\DIFdelbegin> and C<\DIFdelend> commands. -Available styles: C<SAFE MARGINAL COLOR DVIPSCOL> +Available styles: C<SAFE MARGINAL COLOR DVIPSCOL LABEL> [ Default: C<SAFE> ] @@ -2526,6 +2629,10 @@ define new C<\DIFadd> and C<\DIFdel> commands, which provide a wrapper for these using them for the text but not for the link defining command (where any markup would cause errors). +=item C<apacite> + +Redefine the commands recognised as citation commands. + =back [ Default: scan the preamble for C<\\usepackage> commands to determine @@ -2698,6 +2805,7 @@ Protect citation commands in changed sections with \\mbox command [i.e. use defa =head2 Miscellaneous =over 4 + =item B<--verbose> or B<-V> Output various status information to stderr during processing. @@ -2962,9 +3070,7 @@ Option allow-spaces not implemented entirely consistently. It breaks the rules that number and type of white space does not matter, as different numbers of inter-argument spaces are treated as significant. -Please submit bug reports on the latexdiff project page I<http://latexdiff.berlios.de>, -send them to user discussion list C<latexdiff-users@lists.berlios,de> (prior subscription -to list required, also on project webpage) +Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, or send them to I<tilmann@gfz-potsdam.de>. Include the serial number of I<latexdiff> (from comments at the top of the source or use B<--version>). If you come across latex files that are error-free and conform to the specifications set out @@ -2992,7 +3098,7 @@ I<latexdiff-fast> requires the I<diff> command to be present. =head1 AUTHOR -Version 1.0.2 +Version 1.0.4 Copyright (C) 2004-2012 Frederik Tilmann This program is free software; you can redistribute it and/or modify @@ -3000,7 +3106,7 @@ it under the terms of the GNU General Public License Version 3 Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, T. Connors, Sebastian Gouezel and many others. -Thanks to the many people who send in bug reports, feature suggestions, and other feedback. +Thanks to the many people who sent in bug reports, feature suggestions, and other feedback. =cut @@ -3373,7 +3479,26 @@ institute \providecommand{\DIFdelend}{\protect\color{black}} %DIF END COLOR PREAMBLE - +%DIF LABEL PREAMBLE +% To show only pages with changes (pdf) (external program pdftk needs to be installed) +% (only works for simple documents with non-repeated page numbers) +% pdflatex diff.tex +% pdflatex diff.tex +% pdftk diff.pdf cat `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ' '` output diff-changedpages.pdf +% To show only pages with changes (dvips/dvipdf) +% latex diff.tex +% latex diff.tex +% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi +\typeout{Check comments in preamble of output for instructions how to show only pages where changes have been made} +\newcount\DIFcounterb +\global\DIFcounterb 0\relax +\newcount\DIFcountere +\global\DIFcountere 0\relax +\providecommand{\DIFaddbegin}{\global\advance\DIFcounterb 1\relax\label{DIFchgb\the\DIFcounterb}} %DIF PREAMBLE +\providecommand{\DIFaddend}{\global\advance\DIFcountere 1\relax\label{DIFchge\the\DIFcountere}} %DIF PREAMBLE +\providecommand{\DIFdelbegin}{\global\advance\DIFcounterb 1\relax\label{DIFchgb\the\DIFcounterb}} %DIF PREAMBLE +\providecommand{\DIFdelend}{\global\advance\DIFcountere 1\relax\label{DIFchge\the\DIFcountere}} %DIF PREAMBLE +%DIF END LABEL PREAMBLE %% FLOAT TYPES %DIF FLOATSAFE PREAMBLE @@ -3403,7 +3528,7 @@ institute \providecommand{\DIFaddendFL}{} \providecommand{\DIFdelbeginFL}{} \providecommand{\DIFdelendFL}{} -%DIF END FLOATSAFE PREAMBLE +%DIF END TRADITIONALSAFE PREAMBLE %% SPECIAL PACKAGE PREAMBLE COMMANDS diff --git a/Master/texmf-dist/doc/support/latexdiff/latexdiff-fast b/Master/texmf-dist/doc/support/latexdiff/latexdiff-fast index e53afc12fe6..22f2f8f0344 100755 --- a/Master/texmf-dist/doc/support/latexdiff/latexdiff-fast +++ b/Master/texmf-dist/doc/support/latexdiff/latexdiff-fast @@ -3,9 +3,9 @@ # latexdiff - differences two latex files on the word level # and produces a latex file with the differences marked up. # -# Copyright (C) 2004-12 F J Tilmann (tilmann@gfz-potsdam.de, ftilmann@users.berlios.de) +# Copyright (C) 2004-12 F J Tilmann (tilmann@gfz-potsdam.de) # -# Project webpages: http://latexdiff.berlios.de/ +# Repository/issue tracker: https://github.com/ftilmann/latexdiff # CTAN page: http://www.ctan.org/tex-archive/support/latexdiff # # This program is free software: you can redistribute it and/or modify @@ -22,14 +22,34 @@ # # Detailed usage information at the end of the file # +# ToDo: +# +# Version 1.0.4 +# - introduce list UNSAFEMATHCMD, which holds list of commands which cannot be marked up with \DIFadd or \DIFdel commands (only relevant for WHOLE and COARSE math markup modes) +# - new subtype LABEL which gives each change a label. This can later be used to only display pages where changes +# have been made (instructions for that are put as comments into the diff'ed file) inspired by answer on http://tex.stackexchange.com/questions/166049/invisible-markers-in-pdfs-using-pdflatex +# - Configuration variables take into accout some commands from additional packages: +# tikzpicture environment now treated as PICTUREENV, and \smallmatrix in ARRENV (amsmath) +# - --flatten: support for \subfile command (subfiles package) (in response to http://tex.stackexchange.com/questions/167620/latexdiff-with-subfiles ) +# - --flatten: \bibliography commands expand if corresponding bbl file present +# - angled bracket optional commands now parsed correctly (patch #3570) submitted by Dave Kleinschmidt (thanks) +# - \RequirePackage now treated as synonym of \usepackage with respect to setting packages +# - special rules for apacite package (redefine citation commands) +# - recognise /dev/null as 'file-like' arguments for --preamble and --config options +# - fix units package incompatibility with ulem for text maths statements $ ..$ (thanks to Stuart Prescott for reporting this) +# - amsmath environment cases treated correctly (Bug fix #19029) (thanks to Jalar) +# - {,} in comments no longer confuse latexdiff (Bug fix #19146) +# - \% in one-letter sub/Superscripts was not converted correctly +# # Version 1.0.3 # - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator # command in preamble -# - \(..\) inline math expressions were not parsed correctly, if the contained a linebreak +# - \(..\) inline math expressions were not parsed correctly, if they contained a linebreak # - applied patch contributed by tomflannaghan via Berlios: [ Patch #3431 ] Adds correct handling of \left< and \right> # - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug -# and sketching out the solution) -# - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript (thanks to Wail Yahyaoui for pointing out this bug) +# and sketching out the solution) +# - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript +# (thanks to Wail Yahyaoui for pointing out this bug) # # Version 1.0.1 - treat \big,\bigg etc. equivalently to \left and # \right - include starred version in MATHENV - apply @@ -653,28 +673,30 @@ my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION); my ($versionstring)=<<EOF ; -This is LATEXDIFF 1.0.3 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) - (c) 2004-2013 F J Tilmann +This is LATEXDIFF 1.0.4 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) + (c) 2004-2014 F J Tilmann EOF # Configuration variables: these have to be visible from the subroutines my $MINWORDSBLOCK=3; # minimum number of tokens to form an independent block # shorter identical blocks will be merged to the previous word my $FLOATENV='(?:figure|table|plate)[\w\d*@]*' ; # Environments in which FL variants of defined commands are used -my $PICTUREENV='(?:picture|DIFnomarkup)[\w\d*@]*' ; # Environments in which all change markup is removed +my $PICTUREENV='(?:picture|tikzpicture|DIFnomarkup)[\w\d*@]*' ; # Environments in which all change markup is removed my $MATHENV='(?:equation[*]?|displaymath|DOLLARDOLLAR)[*]?' ; # Environments turning on display math mode (code also knows about \[ and \]) my $MATHREPL='displaymath'; # Environment introducing deleted maths blocks my $MATHARRENV='(?:eqnarray|align|alignat|gather|multline|flalign)[*]?' ; # Environments turning on eqnarray math mode my $MATHARRREPL='eqnarray*'; # Environment introducing deleted maths blocks -my $ARRENV='(?:array|[pbvBV]matrix)'; # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block +my $ARRENV='(?:array|[pbvBV]?matrix|smallmatrix|cases|split)'; # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block my $COUNTERCMD='(?:footnote|part|chapter|section|subsection|subsubsection|paragraph|subparagraph)'; # textcmds which are associated with a counter # If any of these commands occur in a deleted block # they will be succeeded by an \addtocounter{...}{-1} # for the associated counter such that the overall numbers # should be the same as in the new file +my @UNSAFEMATHCMD=('qedhere'); # Commands which are definitely unsafe for marking up (amsmath qedhere only tested to not work with UNDERLINE markup) my $CITECMD=0 ; # \cite-type commands which need to be protected within an mbox in UNDERLINE and other modes using ulem; pattern simply designed to never match; will be overwritten later for selected styles my $CITE2CMD=0; # \cite-type commands which should be reinstated in deleted blocks - +my $MBOXINLINEMATH=0; # if set to 1 then surround marked-up inline maths expression with \mbox ( to get around compatibility + # problems between some maths packages and ulem package # Markup strings @@ -737,7 +759,7 @@ my ($type,$subtype,$floattype,$config,$preamblefile,$encoding,$nolabel,$visiblel $replacecontext1,$appendcontext1, $replacecontext2,$appendcontext2, $help,$verbose,$driver,$version,$ignorewarnings, - $enablecitmark,$disablecitmark,$allowspaces,$flatten,$debug); ###$disablemathmark, + $enablecitmark,$disablecitmark,$allowspaces,$flatten,$debug,$earlylatexdiffpreamble); ###$disablemathmark, # MNEMNONICS for mathmarkup my $mathmarkup; use constant { @@ -766,6 +788,11 @@ $mathmarkup=COARSE; $verbose=0; # output debug and intermediate files, set to 0 in final distribution $debug=0; +# insert preamble directly after documentclass - experimental feature, set to 0 in final distribution +# Note that this failed with mini example (or other files, where packages used in latexdiff preamble +# are called again with incompatible options in preamble of resulting file) +$earlylatexdiffpreamble=0; + # define character properties sub IsNonAsciiPunct { return <<'END' # Unicode punctuation but excluding ASCII punctuation +utf8::IsPunct @@ -873,29 +900,6 @@ foreach $excludesafe ( @excludesafelist ) { init_regex_arr_ext(\@SAFECMDEXCL, $excludesafe); } -# Special: treat all cite commands as safe except in UNDERLINE and FONTSTRIKE mode -# (there is a conflict between citation and ulem package, see -# package documentation) -# Use post-processing - -if ( uc($type) ne "UNDERLINE" && uc($type) ne "FONTSTRIKE" && uc($type) ne "CULINECHBAR" ) { - push (@SAFECMDLIST, qr/^cite.*$/); -} else { - ### Experimental: disable text and emph commands - push (@SAFECMDLIST, qr/^cite.*$/) unless $disablecitmark; - push(@SAFECMDEXCL, qr/^emph$/, qr/^text..$/); - # replace \cite{..} by \mbox{\cite{..}} in added or deleted blocks in post-processing - if ( uc($subtype) eq "COLOR" or uc($subtype) eq "DVIPSCOL" ) { - # remove \cite command again from list of safe commands - pop @SAFECMDLIST; - # deleted cite commands - $CITE2CMD='(?:cite\w*|nocite)' unless $disablecitmark ; # \cite-type commands which should be reinstated in deleted blocks - } else { - $CITECMD='(?:cite\w*|nocite)' unless $disablecitmark ; # \cite commands which need to be protected within an mbox in UNDERLINE and other modes using ulem - } -} -$CITECMD='(?:cite\w*|nocite)' if $enablecitmark ; # as above for explicit selection - # setting up @TEXTCMDLIST and @TEXTCMDEXCL if (defined($replacetext)) { init_regex_arr_ext(\@TEXTCMDLIST,$replacetext); @@ -934,7 +938,7 @@ foreach $appendcontext2 ( @appendcontext2list ) { # setting configuration variables @config=(); foreach $config ( @configlist ) { - if (-f $config ) { + if (-f $config || lc $config eq '/dev/null' ) { open(FILE,$config) or die ("Couldn't open configuration file $config: $!"); while (<FILE>) { chomp; @@ -1045,6 +1049,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); my $pat5 = '(?:[^{}]|\{'.$pat4.'\})*'; my $pat6 = '(?:[^{}]|\{'.$pat5.'\})*'; my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; + my $abrat0 = '(?:[^<>])*'; my $quotemarks = '(?:\'\')|(?:\`\`)'; my $punct='[0.,\/\'\`:;\"\?\(\)\[\]!~\p{IsNonAsciiPunct}\p{IsNonAsciiS}]'; @@ -1056,7 +1061,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); my $word='(?:[-\w\d*]|\\\\[\"\'\`~^][A-Za-z\*])+'; my $cmdleftright='\\\\(?:left|right|[Bb]igg?[lrm]?|middle)\s*(?:[<>()\[\]|]|\\\\(?:[|{}]|\w+))'; - my $cmdoptseq='\\\\[\w\d\*]+'.$extraspace.'(?:(?:\['.$brat0.'\]|\{'. $pat6 . '\}|\(' . $coords .'\))'.$extraspace.')*'; + my $cmdoptseq='\\\\[\w\d\*]+'.$extraspace.'(?:(?:<'.$abrat0.'>|\['.$brat0.'\]|\{'. $pat6 . '\}|\(' . $coords .'\))'.$extraspace.')*'; my $backslashnl='\\\\\n'; my $oneletcmd='\\\\.\*?(?:\['.$brat0.'\]|\{'. $pat6 . '\})*'; my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; @@ -1065,8 +1070,6 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); my $comment='%.*?\n'; my $pat=qr/(?:\A\s*)?(?:${and}|${quotemarks}|${number}|${word}|$cmdleftright|${cmdoptseq}|${math}|${backslashnl}|${oneletcmd}|${comment}|${punct}|${mathpunct}|\{|\})\s*/ ; - - # now we are done setting up and can start working my ($oldfile, $newfile) = @ARGV; # check for existence of input files @@ -1120,6 +1123,9 @@ if ($flatten) { $newbody=flatten($newbody,$newpreamble,$newfile,$encoding); } + + + my @auxlines; if ( length $oldpreamble && length $newpreamble ) { # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) @@ -1133,13 +1139,25 @@ if ( length $oldpreamble && length $newpreamble ) { # Base this assessment on the new preamble add_safe_commands($newpreamble); + # get a list of packages from preamble if not predefine %packages=list_packages(@newpreamble) unless %packages; + ### if ( %packages ) {print STDERR "DEBUG Packages: ",%packages,"\n" ;} if (defined $packages{"hyperref"} ) { + # deleted lines should not generate or appear in link names: print STDERR "hyperref package detected.\n" if $verbose ; $latexdiffpreamble =~ s/\{\\DIFadd\}/{\\DIFaddtex}/g; $latexdiffpreamble =~ s/\{\\DIFdel\}/{\\DIFdeltex}/g; $latexdiffpreamble .= join "\n",(extrapream("HYPERREF"),""); } + + if (defined $packages{"units"} && ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{ulem\}/ ) ) { + # protect inlined maths environments by surrounding with an \mbox + # this is done to get around an incompatibility between the ulem and units package + # where spaces in the argument to underlined or crossed-out \unit commands cause an error message + print STDERR "units package detected at the same time as style using ulem.\n" if $verbose ; + $MBOXINLINEMATH=1; + } + print STDERR "Differencing preamble.\n" if $verbose; # insert dummy first line such that line count begins with line 1 (rather than perl's line 0) - just so that line numbers inserted by linediff are correct @@ -1157,7 +1175,14 @@ if ( length $oldpreamble && length $newpreamble ) { push @diffpreamble,"%DIF DELETED TITLE COMMANDS FOR MARKUP"; push @diffpreamble,join("\n",@auxlines); } - push @diffpreamble,$latexdiffpreamble; + if ( $earlylatexdiffpreamble) { + # insert latexdiff command directly after documentclass at beginning of preamble + # note that grep is only run for its side effect + ( grep { s/^([^%]*\\documentclass.*)$/$1$latexdiffpreamble/ } @diffpreamble )==1 or die "Could not find documentclass statement in preamble"; + } else { + # insert latexdiff commands at the end of preamble (default behaviour) + push @diffpreamble,$latexdiffpreamble; + } push @diffpreamble,'\begin{document}'; } elsif ( !length $oldpreamble && !length $newpreamble ) { @@ -1167,6 +1192,43 @@ elsif ( !length $oldpreamble && !length $newpreamble ) { exit(2); } +# Special: treat all cite commands as safe except in UNDERLINE and FONTSTRIKE mode +# (there is a conflict between citation and ulem package, see +# package documentation) +# Use post-processing +# and $packages{"apacite"}!~/natbibpapa/ +my ($citpat,$citpatsafe); + +if ( defined $packages{"apacite"} ) { + print STDERR "DEBUG apacite citation commands\n" if $debug; + $citpatsafe=qr/^(?:mask)?(?:full|short)?cite(?:A|author|year)?(?:NP)?$/; + $citpat='(?:mask)?(?:full|short|no)?cite(?:A|author|year|meta)?(?:NP)?'; +} else { + # citation command pattern for all other citation schemes + $citpatsafe=qr/^cite.*$/; + $citpat='(?:cite\w*|nocite)'; +}; + +if ( uc($type) ne "UNDERLINE" && uc($type) ne "FONTSTRIKE" && uc($type) ne "CULINECHBAR" ) { + push (@SAFECMDLIST, $citpatsafe); +} else { + ### Experimental: disable text and emph commands + push (@SAFECMDLIST, $citpatsafe) unless $disablecitmark; + push(@SAFECMDEXCL, qr/^emph$/, qr/^text..$/); + # replace \cite{..} by \mbox{\cite{..}} in added or deleted blocks in post-processing + if ( uc($subtype) eq "COLOR" or uc($subtype) eq "DVIPSCOL" ) { + # remove \cite command again from list of safe commands + pop @SAFECMDLIST; + # deleted cite commands + $CITE2CMD=$citpat unless $disablecitmark ; # \cite-type commands which should be reinstated in deleted blocks + } else { + $CITECMD=$citpat unless $disablecitmark ; # \cite commands which need to be protected within an mbox in UNDERLINE and other modes using ulem + } +} +$CITECMD=$citpat if $enablecitmark ; # as above for explicit selection + +print STDERR "CITECMD:|$CITECMD|\n" if $debug; + if (defined $packages{"amsmath"} or defined $packages{"amsart"} or defined $packages{"amsbook"} ) { print STDERR "amsmath package detected.\n" if $verbose ; $MATHARRREPL='align*'; @@ -1258,7 +1320,7 @@ sub read_file_with_encoding { } # %packages=list_packages(@preamble) -# scans the arguments for \documentclass and \usepackage statements and constructs a hash +# scans the arguments for \documentclass,\RequirePackage and \usepackage statements and constructs a hash # whose keys are the included packages, and whose values are the associated optional arguments sub list_packages { my (@preamble)=@_; @@ -1266,7 +1328,7 @@ sub list_packages { foreach $line ( @preamble ) { # get rid of comments $line=~s/(?<!\\)%.*$// ; - if ( $line =~ m/\\(?:documentclass|usepackage)(?:\[(.+?)\])?\{(.*?)\}/ ) { + if ( $line =~ m/\\(?:documentclass|usepackage|RequirePackage)(?:\[(.+?)\])?\{(.*?)\}/ ) { # print STDERR "Found something: |$line|\n"; if (defined($1)) { $packages{$2}=$1; @@ -1303,7 +1365,7 @@ sub add_safe_commands { } } - while ( $preamble =~ m/\\(?:|re|provide)newcommand\s*{\\(\w*)\}(?:|\[\d*\])\s*\{(${pat6})\}/osg ) { + while ( $preamble =~ m/\\(?:new|renew|provide)command\s*{\\(\w*)\}(?:|\[\d*\])\s*\{(${pat6})\}/osg ) { my $maybe_to_test = $1; my $should_be_safe = $2; my $success = 0; @@ -1333,14 +1395,20 @@ sub add_safe_commands { # flatten($text,$preamble,$filename,$encoding) # 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) # preamble is scanned for includeonly commands # encoding is the encoding sub flatten { my ($text,$preamble,$filename,$encoding)=@_; - my ($includeonly,$dirname,$fname,$newpage,$replacement,$begline); + my ($includeonly,$dirname,$fname,$newpage,$replacement,$begline,$bblfile,$subfile); + my ($subpreamble,$subbody,$subpost); require File::Basename ; require File::Spec ; $dirname = File::Basename::dirname($filename); + $bblfile = $filename; + $bblfile=~s/\.tex$//; + $bblfile.=".bbl"; if ( ($includeonly) = ($preamble =~ m/\\includeonly{(.*?)}/ ) ) { $includeonly =~ s/,/|/g; @@ -1350,9 +1418,10 @@ sub flatten { print STDERR "DEBUG: includeonly $includeonly\n" if $debug; + # recursively replace \\input and \\include files $text=~s/(^(?:[^%\n]|\\%)*)\\input{(.*?)}|\\include{(${includeonly}(?:\.tex)?)}/{ $fname = $2 if defined($2) ; - $fname = $3 if defined($3) ; + $fname = $3 if defined($3) ; # # add tex extension unless there is a three letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3}|; print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ; @@ -1366,6 +1435,34 @@ sub flatten { $newpage=(defined($3)? " \\newpage " : "") ; "$begline$newpage$replacement$newpage"; }/exgm; + # replace bibliography with bbl file if it exists + $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography{(.*?)}/{ + if ( -f $bblfile ){ + $replacement=read_file_with_encoding(File::Spec->catfile($bblfile), $encoding); + } else { + warn "Bibliography file $bblfile cannot be found. No flattening of \\bibliography done. Run bibtex on old and new files first"; + $replacement="\\bibliography{$2}"; + } + $begline=(defined($1)? $1 : "") ; + "$begline$replacement"; + }/exgm; + # replace subfile with contents (subfile package) + $text=~s/(^(?:[^%\n]|\\%)*)\\subfile{(.*?)}/{ + $fname = $2; + # # add tex extension unless there is a three letter extension already + $fname .= ".tex" unless $fname =~ m|\.\w{3}|; + print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ; + print STDERR "Include file as subfile $fname\n" if $verbose; + print STDERR "DEBUG looking for file ",File::Spec->catfile($dirname,$fname), "\n" if $debug; + # content of file becomes replacement value (use recursion) + # now strip away everything outside and including \begin{document} and \end{document} pair# + # # note: no checking for comments is made + $subfile=read_file_with_encoding(File::Spec->catfile($dirname,$fname), $encoding) or die "Couldn't find file ",File::Spec->catfile($dirname,$fname),": $!"; + ($subpreamble,$subbody,$subpost)=splitdoc($subfile,'\\\\begin\{document\}','\\\\end\{document\}'); + $replacement=flatten($subbody, $preamble,$filename,$encoding); + $begline=(defined($1)? $1 : "") ; + "$begline$replacement"; + }/exgm; return($text); } @@ -1391,7 +1488,7 @@ sub extrapream { while (@_) { $copy=0; $type=shift ; - if ( -f $type ) { + if ( -f $type || lc $type eq '/dev/null' ) { open (FILE,$type) or die "Cannot open preamble file $type: $!"; print STDERR "Reading preamble file $type\n" if $verbose ; while (<FILE>) { @@ -1959,7 +2056,7 @@ sub marktags { # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to # "" local @SAFECMDLIST=(".*"); - local @SAFECMDEXCL=('\\','\\\\'); + local @SAFECMDEXCL=('\\','\\\\',@UNSAFEMATHCMD); push(@$retval,$command,marktags("","",$open,$close,"","",$comment,\@argtext)#@argtext ,$closingbracket); } else { @@ -1994,9 +2091,8 @@ sub marktags { # preprocess($string, ..) # carry out the following pre-processing steps for all arguments: # 1. Remove leading white-space -# Change \{ to \LEFTBRACE and \} to \RIGHTBRACE -# #. change begin and end commands within comments to BEGINDIF, ENDDIF -# so they don't disturb the pattern matching (if there are several \begin or \end in one line +# Change \{ to \QLEFTBRACE and \} to \QRIGHTBRACE +# #. Change {,} in comments to \CLEFTBRACE, \CRIGHTBRACE # 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) @@ -2023,11 +2119,9 @@ sub preprocess { # Change \{ to \QLEFTBRACE and \} to \QRIGHTBRACE s/(?<!\\)\\{/\\QLEFTBRACE /sg; s/(?<!\\)\\}/\\QRIGHTBRACE /sg; - # change begin and end commands within comments such that they - # don't disturb the pattern matching (if there are several \begin or \end in one line - # this substitution is insufficient but that appears unlikely) - s/(%.*)\\begin\{(.*)$/$1\\BEGINDIF\{$2/mg ; - s/(%.*)\\end\{(.*)$/$1\\ENDDIF\{$2/mg ; +# replace {,} in comments with \\CLEFTBRACE,\\CRIGHTBRACE + 1 while s/((?<!\\)%.*)\{(.*)$/$1\\CLEFTBRACE $2/mg ; + 1 while s/((?<!\\)%.*)\}(.*)$/$1\\CRIGHTBRACE $2/mg ; s/\n(\s*?)\n((?:\s*\n)*)/\n$1\\PAR\n$2/g ; s/(?<!\\)\\%/\\PERCENTAGE /g ; # (?<! is negative lookbehind assertion to prevent \\% from being converted @@ -2140,7 +2234,7 @@ sub fromhash { # 9.. remove all \PAR tokens # 10. package specific processing: endfloat: make sure \begin{figure} and \end{figure} are always # on a line by themselves, similarly for table environment -# 4, undo renaming of the \begin and \end in comments +# 4, undo renaming of the \begin, \end,{,} in comments # Change \QLEFTBRACE, \QRIGHTBRACE to \{,\} # # Note have to manually synchronize substitution commands below and @@ -2266,8 +2360,14 @@ sub postprocess { } # or protect \cite commands with \mbox if ($CITECMD) { - $delblock=~s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat6\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; + $delblock=~s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat6\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; } + # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox + if ( $MBOXINLINEMATH ) { + # note additional \newline after command is omitted from output if right at the end of deleted block (otherwise a spurious empty line is generated) + $delblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; + } + # splice in modified delblock substr($_,$begin,$len)=$delblock; pos = $begin + length($delblock); @@ -2289,7 +2389,16 @@ sub postprocess { } if ($CITECMD) { my $addblockbefore=$addblock; - $addblock=~ s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat2\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; + #(?:mask)?(?:full|short|no)?cite(?:A|author|year|meta)(?:NP)?$/ + ###my $CITECMD; $CITECMD="cite(?:A)$"; + $addblock=~ s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat2\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; + print STDERR "DEBUG: CITECMD $CITECMD\nDEBUG: addblock before:|$addblockbefore|\n" if $debug; + print STDERR "DEBUG: addblock after: |$addblock|\n" if $debug; + } + # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox + if ( $MBOXINLINEMATH ) { + ##$addblock=~s/($math)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; + $addblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } # splice in modified addblock substr($_,$begin,$len)=$addblock; @@ -2297,13 +2406,6 @@ sub postprocess { } - ### old place for BEGINDIF, ENDDIF replacement - # change begin and end commands within comments such that they - # don't disturb the pattern matching (if there are several \begin or \end in one line - # this substitution is insufficient but that appears unlikely) - # This needs to be repeated here to also get rid of DIFdelcmd-protected environments - s/(%.*)\\begin\{(.*)$/$1\\BEGINDIF\{$2/mg ; - s/(%.*)\\end\{(.*)$/$1\\ENDDIF\{$2/mg ; # Replace MATHMODE environments from step 1a above by the correct Math environment @@ -2370,8 +2472,8 @@ sub postprocess { s/(\\verb\*?)\{([-\d]*?)\}/"${1}". fromhash(\%verbhash,$2)/esg; s/${DELCMDOPEN}\\(verbatim\*?)\{([-\d]*?)\}/"${DELCMDOPEN}\\begin{${1}}".fromhash(\%verbhash,$2,$DELCMDOPEN)."${DELCMDOPEN}\\end{${1}}"/esg; s/\\(verbatim\*?)\{([-\d]*?)\}/"\\begin{${1}}".fromhash(\%verbhash,$2)."\\end{${1}}"/esg; - # Convert '\PERCENTAGE ' back into '\%' - s/\\PERCENTAGE /\\%/g; + # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated + s/\\PERCENTAGE ?/\\%/g; # Convert '\DOLLAR ' back into '\$' s/\\DOLLAR /\\\$/g; # remove all \PAR tokens (taking care to properly keep commented out PAR's @@ -2394,9 +2496,7 @@ sub postprocess { # split lines with remaining characters after float enviroment conmmand s/(\\(?:begin|end)\{(?:figure|table)\})(.+)$/$1\n$2/mg; } - # undo renaming of the \begin and \end and dollars in comments - s/(%.*)\\BEGINDIF\{(.*)$/$1\\begin\{$2/mg ; - s/(%.*)\\ENDDIF\{(.*)$/$1\\end\{$2/mg ; + # undo renaming of the \begin and \end,{,} and dollars in comments 1 while s/(%.*)DOLLARDIF/$1\$/mg ; # undo renaming of the \cite.. commands in comments if ( $CITECMD ) { @@ -2408,11 +2508,15 @@ sub postprocess { # 4. Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$ s/\\begin\{DOLLARDOLLAR\}(.*?)\\end\{DOLLARDOLLAR\}/\$\$$1\$\$/sg; # 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn} - 1 while s/\\SUPERSCRIPTNB{($pat0)}/^$1/g ; 1 while s/\\SUPERSCRIPT{($pat6)}/^{$1}/g ; + 1 while s/\\SUPERSCRIPTNB{($pat0)}/^$1/g ; # Convert \SUBSCRIPNB{n} into _n and \SUBCRIPT{nn} into _{nnn} - 1 while s/\\SUBSCRIPTNB{($pat0)}/_$1/g ; 1 while s/\\SUBSCRIPT{($pat6)}/_{$1}/g ; + 1 while s/\\SUBSCRIPTNB{($pat0)}/_$1/g ; + 1 while s/(%.*)\\CRIGHTBRACE (.*)$/$1\}$2/mg ; + 1 while s/(%.*)\\CLEFTBRACE (.*)$/$1\{$2/mg ; + + # Change \QLEFTBRACE, \QRIGHTBRACE to \{,\} s/\\QLEFTBRACE /\\{/sg; s/\\QRIGHTBRACE /\\}/sg; @@ -2675,7 +2779,7 @@ format as new.tex but has all changes relative to old.tex marked up or commented --subtype=markstyle -s markstyle Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin) - Available styles: SAFE MARGINAL DVIPSCOL COLOR + Available styles: SAFE MARGINAL DVIPSCOL COLOR LABEL [ Default: SAFE ] --floattype=markstyle @@ -2774,7 +2878,7 @@ format as new.tex but has all changes relative to old.tex marked up or commented Use of the --packages option disables automatic scanning, so if for any reason package specific parsing needs to be switched off, use --packages=none. The following packages trigger special behaviour: - endfloat hyperref amsmath + endfloat hyperref amsmath apacite [ Default: scan the preamble for \\usepackage commands to determine loaded packages.] @@ -2830,7 +2934,7 @@ Miscelleneous options --no-label Suppress inclusion of old and new file names as comment in output file ---visble-label Include old and new filenames (or labels set with --label option) as +--visible-label Include old and new filenames (or labels set with --label option) as visible output --flatten Replace \\input and \\include commands within body by the content @@ -2855,7 +2959,6 @@ Miscelleneous options --version Show version number. -For further information, consult http://latexdiff.berlios.de EOF } @@ -3018,7 +3121,7 @@ B<-s markstyle> Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin). This option defines C<\DIFaddbegin>, C<\DIFaddend>, C<\DIFdelbegin> and C<\DIFdelend> commands. -Available styles: C<SAFE MARGINAL COLOR DVIPSCOL> +Available styles: C<SAFE MARGINAL COLOR DVIPSCOL LABEL> [ Default: C<SAFE> ] @@ -3087,6 +3190,10 @@ define new C<\DIFadd> and C<\DIFdel> commands, which provide a wrapper for these using them for the text but not for the link defining command (where any markup would cause errors). +=item C<apacite> + +Redefine the commands recognised as citation commands. + =back [ Default: scan the preamble for C<\\usepackage> commands to determine @@ -3259,6 +3366,7 @@ Protect citation commands in changed sections with \\mbox command [i.e. use defa =head2 Miscellaneous =over 4 + =item B<--verbose> or B<-V> Output various status information to stderr during processing. @@ -3523,9 +3631,7 @@ Option allow-spaces not implemented entirely consistently. It breaks the rules that number and type of white space does not matter, as different numbers of inter-argument spaces are treated as significant. -Please submit bug reports on the latexdiff project page I<http://latexdiff.berlios.de>, -send them to user discussion list C<latexdiff-users@lists.berlios,de> (prior subscription -to list required, also on project webpage) +Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, or send them to I<tilmann@gfz-potsdam.de>. Include the serial number of I<latexdiff> (from comments at the top of the source or use B<--version>). If you come across latex files that are error-free and conform to the specifications set out @@ -3553,7 +3659,7 @@ I<latexdiff-fast> requires the I<diff> command to be present. =head1 AUTHOR -Version 1.0.2 +Version 1.0.4 Copyright (C) 2004-2012 Frederik Tilmann This program is free software; you can redistribute it and/or modify @@ -3561,7 +3667,7 @@ it under the terms of the GNU General Public License Version 3 Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, T. Connors, Sebastian Gouezel and many others. -Thanks to the many people who send in bug reports, feature suggestions, and other feedback. +Thanks to the many people who sent in bug reports, feature suggestions, and other feedback. =cut @@ -3934,7 +4040,26 @@ institute \providecommand{\DIFdelend}{\protect\color{black}} %DIF END COLOR PREAMBLE - +%DIF LABEL PREAMBLE +% To show only pages with changes (pdf) (external program pdftk needs to be installed) +% (only works for simple documents with non-repeated page numbers) +% pdflatex diff.tex +% pdflatex diff.tex +% pdftk diff.pdf cat `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ' '` output diff-changedpages.pdf +% To show only pages with changes (dvips/dvipdf) +% latex diff.tex +% latex diff.tex +% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi +\typeout{Check comments in preamble of output for instructions how to show only pages where changes have been made} +\newcount\DIFcounterb +\global\DIFcounterb 0\relax +\newcount\DIFcountere +\global\DIFcountere 0\relax +\providecommand{\DIFaddbegin}{\global\advance\DIFcounterb 1\relax\label{DIFchgb\the\DIFcounterb}} %DIF PREAMBLE +\providecommand{\DIFaddend}{\global\advance\DIFcountere 1\relax\label{DIFchge\the\DIFcountere}} %DIF PREAMBLE +\providecommand{\DIFdelbegin}{\global\advance\DIFcounterb 1\relax\label{DIFchgb\the\DIFcounterb}} %DIF PREAMBLE +\providecommand{\DIFdelend}{\global\advance\DIFcountere 1\relax\label{DIFchge\the\DIFcountere}} %DIF PREAMBLE +%DIF END LABEL PREAMBLE %% FLOAT TYPES %DIF FLOATSAFE PREAMBLE @@ -3964,7 +4089,7 @@ institute \providecommand{\DIFaddendFL}{} \providecommand{\DIFdelbeginFL}{} \providecommand{\DIFdelendFL}{} -%DIF END FLOATSAFE PREAMBLE +%DIF END TRADITIONALSAFE PREAMBLE %% SPECIAL PACKAGE PREAMBLE COMMANDS |