git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Matthieu Moy <Matthieu.Moy@imag.fr>
To: git@vger.kernel.org, gitster@pobox.com
Cc: Matthieu Moy <Matthieu.Moy@imag.fr>
Subject: [PATCH v4] git-latexdiff: new command in contrib, to use latexdiff and Git
Date: Thu, 16 Feb 2012 15:08:20 +0100	[thread overview]
Message-ID: <1329401300-28166-1-git-send-email-Matthieu.Moy@imag.fr> (raw)
In-Reply-To: <m3d39esxrg.fsf@localhost.localdomain>

git-latexdiff is a wrapper around latexdiff
(http://www.ctan.org/pkg/latexdiff) that allows using it to diff two
revisions of a LaTeX file.

git-latexdiff is made to work on documents split accross multiple .tex
files (plus possibly figures and other non-diffable files), hence could
not be implemented as a per-file diff driver.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
Sorry, I forgot to commit before sending v3, so it was obviously wrong.

This one should contain what I promised in v2, i.e:

- Try 'open' on MacOS to view PDF file.
- Shell style issues (thanks to Jakub)

Jakub, I also forgot to send this before the patch (I got interrupted,
and it seems my mental context-switch implementation loses data ;-) ):

> Why we autodetect PDF viewer unconditionally?

We don't really do that: the test is inside a test on $PDFVIEWER, so
it's essentially the same. I just wrote it this way because I thought
"break" wasn't POSIX, but it is actually, so I'm taking your version.

 contrib/latex/Makefile      |   22 ++++
 contrib/latex/README        |   12 ++
 contrib/latex/git-latexdiff |  256 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 290 insertions(+), 0 deletions(-)
 create mode 100644 contrib/latex/Makefile
 create mode 100644 contrib/latex/README
 create mode 100755 contrib/latex/git-latexdiff

diff --git a/contrib/latex/Makefile b/contrib/latex/Makefile
new file mode 100644
index 0000000..4617906
--- /dev/null
+++ b/contrib/latex/Makefile
@@ -0,0 +1,22 @@
+-include ../../config.mak
+-include ../../config.mak.autogen
+
+ifndef SHELL_PATH
+	SHELL_PATH = /bin/sh
+endif
+
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
+
+SCRIPT=git-latexdiff
+
+.PHONY: install help
+help:
+	@echo 'This is the help target of the Makefile. Current configuration:'
+	@echo '  gitexecdir = $(gitexecdir_SQ)'
+	@echo '  SHELL_PATH = $(SHELL_PATH_SQ)'
+	@echo 'Run "$(MAKE) install" to install $(SCRIPT) in gitexecdir.'
+
+install:
+	sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' $(SCRIPT) > '$(gitexecdir_SQ)/$(SCRIPT)'
+	chmod 755 '$(gitexecdir)/$(SCRIPT)'
diff --git a/contrib/latex/README b/contrib/latex/README
new file mode 100644
index 0000000..2d7fdd6
--- /dev/null
+++ b/contrib/latex/README
@@ -0,0 +1,12 @@
+git-latexdiff is a wrapper around latexdiff
+(http://www.ctan.org/pkg/latexdiff) that allows using it to diff two
+revisions of a LaTeX file.
+
+The script internally checks out the full tree for the specified
+revisions, and calls latexdiff with the --flatten option, hence this
+works if the document is split into multiple .tex files.
+
+Try "git latexdiff -h" for more information.
+
+To install, either drop git-latexdiff in your $PATH, or run "make
+install".
diff --git a/contrib/latex/git-latexdiff b/contrib/latex/git-latexdiff
new file mode 100755
index 0000000..19b9783
--- /dev/null
+++ b/contrib/latex/git-latexdiff
@@ -0,0 +1,256 @@
+#! /bin/sh
+
+# Author: Matthieu Moy <Matthieu.Moy@imag.fr> (2012)
+
+# Missing features (patches welcome ;-) :
+# - diff the index or the current worktree 
+# - checkout only a subdirectory of the repo
+# - hardlink temporary checkouts as much as possible
+
+usage () {
+            cat << EOF
+Usage: $(basename $0) [options] OLD [NEW]
+Call latexdiff on two Git revisions of a file.
+
+OLD and NEW are Git revision identifiers. NEW defaults to HEAD.
+
+Options:
+    --help                this help message
+    --main <file.tex>     name of the main LaTeX file
+    --no-view             don't display the resulting PDF file
+    --view                view the resulting PDF file
+                            (default if -o is not used)
+    --pdf-viewer <cmd>    use <cmd> to view the PDF file (default: \$PDFVIEWER)
+    --no-cleanup          don't cleanup temp dir after running
+    -o <file>, --output <file>
+                          copy resulting PDF into <file>
+                             (usually ending with .pdf)
+EOF
+}
+
+die () {
+    echo "fatal: $@"
+    exit 1
+}
+
+verbose () {
+    if test "$verbose" = 1 ; then
+	printf "%s ..." "$@"
+    fi
+}
+
+verbose_progress () {
+    if test "$verbose" = 1 ; then
+	printf "." "$@"
+    fi
+}
+
+verbose_done () {
+    if test "$verbose" = 1 ; then
+	echo " ${1:-done}."
+    fi
+}
+
+old=
+new=
+main=
+view=maybe
+cleanup=1
+verbose=0
+output=
+initial_dir=$PWD
+
+while test $# -ne 0; do
+    case "$1" in
+        "--help"|"-h")
+            usage
+            exit 0
+            ;;
+	"--main")
+	    test $# -gt 1 && shift || die "missing argument for $1"
+	    main=$1
+	    ;;
+	"--no-view")
+	    view=0
+	    ;;
+	"--view")
+	    view=1
+	    ;;
+	"--pdf-viewer")
+	    test $# -gt 1 && shift || die "missing argument for $1"
+	    PDFVIEWER="$1"
+	    ;;
+	"--no-cleanup")
+	    cleanup=0
+	    ;;
+	"-o"|"--output")
+	    test $# -gt 1 && shift || die "missing argument for $1"
+	    output=$1
+	    ;;
+	"--verbose"|"-v")
+	    verbose=1
+	    ;;
+        *)
+	    if test -z "$1" ; then
+		echo "Empty string not allowed as argument"
+		usage
+		exit 1
+	    elif test -z "$old" ; then
+		old=$1
+	    elif test -z "$new" ; then
+		new=$1
+	    else
+		echo "Bad argument $1"
+		usage
+		exit 1
+	    fi
+            ;;
+    esac
+    shift
+done
+
+if test -z "$new" ; then
+    new=HEAD
+fi
+
+if test -z "$old" ; then
+    echo "fatal: Please, provide at least one revision to diff with."
+    usage
+    exit 1
+fi
+
+if test -z "$PDFVIEWER" ; then
+    verbose "Auto-detecting PDF viewer"
+    candidates="xdg-open evince okular xpdf acroread"
+    if test "$(uname)" = Darwin ; then
+        # open exists on GNU/Linux, but does not open PDFs
+	candidates="open $candidates"
+    fi
+    
+    for command in $candidates; do
+	if command -v "$command" >/dev/null 2>&1; then
+	    PDFVIEWER="$command"
+	    break
+	else
+	    verbose_progress
+	fi
+    done
+    verbose_done "$PDFVIEWER"
+fi
+
+case "$view" in
+    maybe|1)
+	if test -z "$PDFVIEWER" ; then
+	    echo "warning: could not find a PDF viewer on your system."
+	    echo "warning: Please set \$PDFVIEWER or use --pdf-viewer CMD."
+	    PDFVIEWER=false
+	fi
+	;;
+esac
+
+if test -z "$main" ; then
+    printf "%s" "No --main provided, trying to guess ... "
+    main=$(git grep -l '^[ \t]*\\documentclass')
+    # May return multiple results, but if so the result won't be a file.
+    if test -r "$main" ; then
+	echo "Using $main as the main file."
+    else
+	if test -z "$main" ; then
+	    echo "No candidate for main file."
+	else
+	    echo "Multiple candidates for main file:"
+	    printf "%s\n" "$main" | sed 's/^/\t/'
+	fi
+	die "Please, provide a main file with --main FILE.tex."
+    fi
+fi
+
+if test ! -r "$main" ; then
+    die "Cannot read $main."
+fi
+
+verbose "Creating temporary directories"
+
+git_prefix=$(git rev-parse --show-prefix)
+cd "$(git rev-parse --show-cdup)" || die "Can't cd back to repository root"
+git_dir="$(git rev-parse --git-dir)" || die "Not a git repository?"
+git_dir=$(cd "$git_dir"; pwd)
+
+main=$git_prefix/$main
+
+tmpdir=$initial_dir/git-latexdiff.$$
+mkdir "$tmpdir" || die "Cannot create temporary directory."
+
+cd "$tmpdir" || die "Cannot cd to $tmpdir"
+
+mkdir old new diff || die "Cannot create old, new and diff directories."
+
+verbose_done
+verbose "Checking out old and new version"
+
+cd old || die "Cannot cd to old/"
+git --git-dir="$git_dir" --work-tree=. checkout "$old" -- . || die "checkout failed for old/"
+verbose_progress
+cd ../new || die "Cannot cd to new/"
+git --git-dir="$git_dir" --work-tree=. checkout "$new" -- . || die "checkout failed for new/"
+verbose_progress
+cd ..
+
+verbose_done
+verbose "Running latexdiff --flatten old/$main new/$main > $main"
+
+latexdiff --flatten old/"$main" new/"$main" > diff.tex || die "latexdiff failed"
+
+mv -f diff.tex new/"$main"
+
+verbose_done
+
+mainbase=$(basename "$main" .tex)
+maindir=$(dirname "$main")
+
+verbose "Compiling result"
+
+compile_error=0
+cd new/"$maindir" || die "Can't cd to new/$maindir"
+if test -f Makefile ; then
+    make || compile_error=1
+else
+    pdflatex --interaction errorstopmode "$mainbase" || compile_error=1
+fi
+
+verbose_done
+
+pdffile="$mainbase".pdf
+if test ! -r "$pdffile" ; then
+    echo "No PDF file generated."
+    compile_error=1
+fi
+
+if test ! -s "$pdffile" ; then
+    echo "PDF file generated is empty."
+    compile_error=1
+fi
+
+if test "$compile_error" = "1" ; then
+    echo "Error during compilation. Please examine and cleanup if needed:"
+    echo "Directory: $tmpdir/new/$maindir/"
+    echo "     File: $mainbase.tex"
+    # Don't clean up to let the user diagnose.
+    exit 1
+fi
+
+if test -n "$output" ; then
+    abs_pdffile="$PWD/$pdffile"
+    (cd "$initial_dir" && cp "$abs_pdffile" "$output")
+    echo "Output written on $output"
+fi
+
+if test "$view" = 1  || test "$view" = maybe  && test -z "$output" ; then
+    "$PDFVIEWER" "$pdffile"
+fi
+
+if test "$cleanup" = 1 ; then
+    verbose "Cleaning-up result"
+    rm -fr "$tmpdir"
+    verbose_done
+fi
-- 
1.7.9.111.gf3fb0.dirty

  reply	other threads:[~2012-02-16 14:09 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-15 15:49 [PATCH] git-latexdiff: new command in contrib, to use latexdiff and Git Matthieu Moy
2012-02-15 23:33 ` Tim Haga
2012-02-16  8:34   ` Matthieu Moy
2012-02-16  8:39     ` [PATCH v2] " Matthieu Moy
2012-02-16  9:15       ` Jakub Narebski
2012-02-16 19:24       ` David Aguilar
2012-02-16  8:47     ` [PATCH] " Steven Michalske
2012-02-16  8:59       ` Matthieu Moy
2012-02-16 12:36     ` [PATCH v3] " Matthieu Moy
2012-02-16 13:40       ` Jakub Narebski
2012-02-16 14:08         ` Matthieu Moy [this message]
2012-02-16 14:15         ` Matthieu Moy
2012-02-16 20:10     ` [PATCH] " Junio C Hamano
2012-02-16 21:04       ` Junio C Hamano
2012-02-17  8:10       ` Matthieu Moy
2012-02-17 13:31         ` Junio C Hamano
2012-02-17 14:19           ` Matthieu Moy
2012-02-17 17:25             ` Junio C Hamano
2012-02-17 18:40               ` Jakub Narebski
2012-02-20  8:50                 ` Matthieu Moy
2012-02-20  9:05                   ` Junio C Hamano
2012-02-20 12:00                     ` Matthieu Moy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1329401300-28166-1-git-send-email-Matthieu.Moy@imag.fr \
    --to=matthieu.moy@imag.fr \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).