p11. How to make a HTML page from diff output

Sometimes it is handy to make an HTML page with the diff between two files.

diff2html can be used: https://github.com/rtfpessoa/diff2html-cli

It can be used straight from two commits, if inside a git repo, or from two files.

# First make the diff file:
$ diff merged-before-commit.txt merged-current.txt > diff.txt

# Then run diff2html:
$ /opt/local/bin/diff2html --style side --file diff.html --input file -- diff.txt

Another simpler script can be used,

$ cat diff.txt | ~/bin/diff2html.sh > diff.html

See script diff2html.sh below, it is slower, but makes much smaller files:

# First make diff file:

$ diff merged-before-commit.txt merged-current.txt > diff.txt

# Then, run script:

$ cat diff.txt | ~/bin/diff2html.sh > diff.html

#!/bin/bash
#
# Convert diff output to colorized HTML.
cat <<EOF
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Colorized Diff</title>
</head>
<style>
.diffdiv  { border: solid 1px black;           }
.comment  { color: gray;                       }
.diff     { color: #8A2BE2;                    }
.minus3   { color: blue;                       }
.plus3    { color: maroon;                     }
.at2      { color: lime;                       }
.plus     { color: green; background: #E7E7E7; }
.minus    { color: red;   background: #D7D7D7; }
.only     { color: purple;                     }
pre       { white-space: pre-wrap;             }
</style>
<body>
<pre>
EOF
echo -n '<span class="comment">'
first=1
diffseen=0
lastonly=0
OIFS=$IFS
IFS='
'
# The -r option keeps the backslash from being an escape char.
read -r s
while [[ $? -eq 0 ]]
do
    # Get beginning of line to determine what type
    # of diff line it is.
    t1=${s:0:1}
    t2=${s:0:2}
    t3=${s:0:3}
    t4=${s:0:4}
    t7=${s:0:7}
    # Determine HTML class to use.
    if    [[ "$t7" == 'Only in' ]]; then
	cls='only'
	if [[ $diffseen -eq 0 ]]; then
	    diffseen=1
	    echo -n '</span>'
	else
	    if [[ $lastonly -eq 0 ]]; then
		echo "</div>"
	    fi
	fi
	if [[ $lastonly -eq 0 ]]; then
	    echo "<div class='diffdiv'>"
	fi
	lastonly=1
    elif [[ "$t4" == 'diff' ]]; then
	cls='diff'
	if [[ $diffseen -eq 0 ]]; then
	    diffseen=1
	    echo -n '</span>'
	else
	    echo "</div>"
	fi
	echo "<div class='diffdiv'>"
	lastonly=0
    elif  [[ "$t3" == '+++'  ]]; then
	cls='plus3'
	lastonly=0
    elif  [[ "$t3" == '---'  ]]; then
	cls='minus3'
	lastonly=0
    elif  [[ "$t2" == '@@'   ]]; then
	cls='at2'
	lastonly=0
    elif  [[ "$t1" == '+'    ]]; then
	cls='plus'
	lastonly=0
    elif  [[ "$t1" == '-'    ]]; then
	cls='minus'
	lastonly=0
    else
	cls=
	lastonly=0
    fi
    # Convert &, <, > to HTML entities.
    s=$(sed -e 's/\&/\&amp;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g' <<<"$s")
    if &#91;&#91; $first -eq 1 &#93;&#93;; then
	first=0
    else
	echo
    fi
    # Output the line.
    if &#91;&#91; "$cls" &#93;&#93;; then
	echo -n '<span class="'${cls}'">'${s}'</span>'
    else
	echo -n ${s}
    fi
    read -r s
done
IFS=$OIFS
if [[ $diffseen -eq 0  &&  $onlyseen -eq 0 ]]; then 
    echo -n '</span>'
else
    echo "</div>"
fi
echo
cat <<EOF
</pre>
</body>
</html>
EOF


[p11. How to make a HTML page from diff output, last update 2017-12-08]