#!/usr/bin/env bash
# Summarize commit history and diff of Markdown files in the current Git repo
# Usage:
#     markdown-git-changes [COMMIT [MARKDOWN_FILE]...]
# 
# You can specify COMMIT as `--' to automatically see changes of given files
# against the upstream branch, HEAD^, or HEAD.
#
# Author: Jaeho Shin <netj@cs.stanford.edu>
# Created: 2013-11-18
set -eu

Here=$(dirname "$0")
PATH="$Here:$PATH" # add this directory to PATH for markdown-format-wdiff

# TODO passthru any diff options

# how to find markdown files in the current git repo
files=()
find_markdown_files() {
    local IFS=$'\n'
    set -- $(git ls-files | grep '\.\(md\|mkd\|markdn\|markdown\)$')
    files=("$@")
}

# diff against given commit, or upstream branch, or HEAD^ if no local changes, or HEAD
since=--; [ $# -eq 0 ] || { since=$1; shift; }
if [ x"$since" = x"--" ]; then
    find_markdown_files
    since=`
        git rev-parse --abbrev-ref HEAD@{upstream} 2>/dev/null ||
        case $(git status --porcelain --untracked-files=no "${files[@]}" | wc -l) in
            0) echo 'HEAD^' ;;
            *) echo 'HEAD'
        esac
    `
fi
# unless list of files are given, find Markdown documents in the Git repo
if [ $# -gt 0 ]; then
    files=("$@")
elif [ ${#files[@]} -eq 0 ]; then
    find_markdown_files
fi

# make sure ${files[@]} isn't empty
[ ${#files[@]} -gt 0 ] || files+=(.)


# summarize commit history
{
    echo "\$ git log --oneline "$since"..HEAD $*"
    git log --oneline "$since"..HEAD "${files[@]}"
} |
sed 's/^/    /'
echo

# and embed the overall word diff
git diff ${GIT_DIFF_OPTS:-} --word-diff --patch-with-stat \
    --minimal --patience \
    "$since" -- "${files[@]}" |
sed '
    # format prologue
    1,/^diff /{
        /^diff/! s/^/    /
    }

    # format file headers
    /^diff /,/^+++ /{
        /^diff /{
            s|^diff .* \([^/]/\)\(.*\)|<div class="file-start"><code>\2</code></div>|
            a\
    \

        }
        /^<div class="file-start">/! s/^/    /
    }

    # format hunks
    /^@@ -.* +.* @@/{
        s| @@.*| @@|
        s|^|<div class="hunk-start"><code>|
        s|$|</code></div>|
    }
' |
markdown-format-wdiff
echo '
<style>
    pre:first-of-type { width: 78%; margin-left: auto; margin-right: auto; }
    .file-start + p + pre,
    .file-start + pre { margin-left: 61.8%; }
    .file-start,
    .hunk-start{ text-align: right; }

    .file-start code{ font-size: inherit; }

    .file-start/*:not(:first-of-type)*/{
        font-size: 150%;
        margin-top: 23.6%;
        border-bottom: 1ex solid #ccc;
        padding-bottom: 1ex;
    }
    .hunk-start{
        margin-top: 2ex;
        border-bottom: 1ex dashed #ccc;
        padding-bottom: 1ex;
    }
</style>
'