All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
To: git@vger.kernel.org
Subject: git-latexdiff: Git and Latexdiff working together
Date: Tue, 14 Feb 2012 14:22:45 +0100	[thread overview]
Message-ID: <vpq7gzph7mi.fsf@bauges.imag.fr> (raw)

[-- Attachment #1: Type: text/plain, Size: 721 bytes --]

Hi,

You may know latexdiff, a neat tool to visualize differences between
LaTeX files (it annotates your .tex file with colors for removed/added
parts, producing another compilable .tex file).

I wrote a little shell-script that allows one to use latexdiff on files
versionned by Git, with e.g.

  git latexdiff HEAD^ --main foo.tex --output foo.pdf

Essentially, it does a checkout of the old and new revisions, and calls
latexdiff + pdflatex for you.

The result is attached in case anyone is interested.

It may be relevant to add this to contrib/ in git.git. If anyone's
interested, let me know, and I'll resend the code in the form of a
patch doing that.

Regards,

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

[-- Attachment #2: git-latexdiff --]
[-- Type: application/octet-stream, Size: 4613 bytes --]

#! /bin/sh

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)
	--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 [ "$verbose" = 1 ]; then
	printf "%s ..." "$@"
    fi
}

verbose_progress () {
    if [ "$verbose" = 1 ]; then
	printf "." "$@"
    fi
}

verbose_done () {
    if [ "$verbose" = 1 ]; then
	echo " 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")
	    shift
	    main=$1
	    ;;
	"--no-view")
	    view=0
	    ;;
	"--view")
	    view=1
	    ;;
	"--no-cleanup")
	    cleanup=0
	    ;;
	"-o"|"--output")
	    shift
	    output=$1
	    ;;
	"--verbose"|"-v")
	    verbose=1
	    ;;
        *)
	    if [ "$1" = "" ]; then
		echo "Empty string not allowed as argument"
		usage
		exit 1
	    elif [ "$old" = "" ]; then
		old=$1
	    elif [ "$new" = "" ]; then
		new=$1
	    else
		echo "Bad argument $1"
		usage
		exit 1
	    fi
            ;;
    esac
    shift
done

if [ "$new" = "" ]; then
    new=HEAD
fi

if [ "$old" = "" ]; then
    echo "fatal: Please, provide at least one revision to diff with."
    usage
    exit 1
fi

if [ "$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 [ -r "$main" ]; then
	echo "Using $main as the main file."
    else
	if [ "$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 [ ! -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 ../diff || die "Cannot cd to diff/"
git --git-dir="$git_dir" --work-tree=. checkout "$new" -- . || die "checkout failed for diff/"
verbose_progress
cd .. || die "Cannot cd back to toplevel"

verbose_done
verbose "Running latexdiff --flatten old/$main new/$main > diff/$main"

latexdiff --flatten old/$main new/$main > diff/$main || die "latexdiff failed"

verbose_done

mainbase=$(basename "$main" .tex)
maindir=$(dirname "$main")

verbose "Compiling result"

compile_error=0
cd diff/"$maindir" || die "Can't cd to diff/$maindir"
if [ -f Makefile ]; then
    make || compile_error=1
else
    pdflatex --interaction errorstopmode "$mainbase" || compile_error=1
fi

verbose_done

pdffile="$mainbase".pdf
if [ ! -r "$pdffile" ]; then
    echo "No PDF file generated."
    compile_error=1
fi

if [ ! -s "$pdffile" ]; then
    echo "PDF file generated is empty."
    compile_error=1
fi

if [ "$compile_error" = "1" ]; then
    echo "Error during compilation. Please examine and cleanup if needed:"
    echo "Directory: $tmpdir/diff/$maindir/"
    echo "     File: $mainbase.tex"
    # Don't clean up to let the user diagnose.
    exit 1
fi

if [ "$output" != "" ]; then
    abs_pdffile="$PWD/$pdffile"
    (cd "$initial_dir" && cp "$abs_pdffile" "$output")
    echo "Output written on $output"
fi

if [ "$view" = 1 ] || [ "$view" = maybe ] && [ "$output" = "" ]; then
    xpdf "$pdffile"
fi

if [ "$cleanup" = 1 ]; then
    verbose "Cleaning-up result"
    rm -fr "$tmpdir"
    verbose_done
fi

             reply	other threads:[~2012-02-14 13:22 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-14 13:22 Matthieu Moy [this message]
2012-02-14 20:19 ` git-latexdiff: Git and Latexdiff working together Tim Haga
2012-02-14 21:16 ` Jeff King
2012-02-14 23:13   ` Matthieu Moy
2012-02-14 23:31     ` Jeff King

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=vpq7gzph7mi.fsf@bauges.imag.fr \
    --to=matthieu.moy@grenoble-inp.fr \
    --cc=git@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.