| 1 | #!/bin/bash |
| 2 | |
| 3 | # NAME |
| 4 | # color-wdiff - visualize differences between text files |
| 5 | |
| 6 | # SYNOPSIS |
| 7 | # color-wdiff FILE0 FILE1 |
| 8 | |
| 9 | # DEPENDENCIES |
| 10 | # wdiff, reformat-html in $HOME/bin. |
| 11 | |
| 12 | # DESCRIPTION |
| 13 | # 1. If the input files are HTML, they are reformatted, to remove |
| 14 | # indentation among other things. |
| 15 | # 2. The markup is inactivated by replacing angle brackets with the |
| 16 | # corresponding entities. |
| 17 | # 3. The files are compared with wdiff, using options which label |
| 18 | # insertions and deletions. The labels are HTML tags with specific |
| 19 | # classes. |
| 20 | # 4. The diff is turned into a valid HTML page by adding the required |
| 21 | # markup, plus CSS style for the insertion and deletion classes. |
| 22 | # |
| 23 | # The diff file is created in the directory where FILE0 resides. |
| 24 | |
| 25 | # ORIGIN OF THE SCRIPT |
| 26 | # This script was extracted from GNUN's GNUmakefile (function |
| 27 | # "mark-outdated"), and adapted. |
| 28 | # GNUN (http://www.gnu.org/software/gnun/) is under GPLv3. |
| 29 | |
| 30 | # ============================================================================= |
| 31 | |
| 32 | # Command-line arguments |
| 33 | arg=($1 $2) |
| 34 | |
| 35 | set -e |
| 36 | |
| 37 | close_term () { |
| 38 | printf '\n%s' '*** Close the terminal window or press Return.'; read OK |
| 39 | test -z "$OK" && exit $1 |
| 40 | } |
| 41 | |
| 42 | f[0]=$(mktemp -t cdif.XXXXXX) || close_or_exit 1 |
| 43 | f[1]=$(mktemp -t cdif.XXXXXX) || close_or_exit 1 |
| 44 | trap 'rm -f "${f[0]}" "${f[1]}"' EXIT |
| 45 | |
| 46 | ## Prepare the pages to be compared. |
| 47 | |
| 48 | for n in 0 1; do |
| 49 | # Input a valid file. |
| 50 | input=${arg[$n]} |
| 51 | if test ! -f "$input" -o ! -s "$input"; then |
| 52 | echo "*** color-wdiff - Please enter file $n."; read input |
| 53 | input=${input%\'}; input=${input#\'} |
| 54 | test -f "$input" -a -s "$input" \ |
| 55 | || (echo 1>&2 "!!! This file doesn't exist or is empty."; close_term 1) |
| 56 | fi |
| 57 | |
| 58 | # Name the diff after file 0. |
| 59 | test "$n" == "0" && diff_file=${input%.html}-diff.html |
| 60 | |
| 61 | # If the file is an HTML but not a diff, process it: |
| 62 | if test "${input%.html}" != "$input" -a "${input%-diff.html}" == "$input"; |
| 63 | then |
| 64 | # - Standardize the format for easier reading of the diff. |
| 65 | if test -f "$HOME/bin/reformat-html"; then |
| 66 | $HOME/bin/reformat-html $input ${f[$n]} |
| 67 | else |
| 68 | cp $input ${f[$n]} |
| 69 | fi |
| 70 | # - Replace chevrons with HTML entities. The page becomes simple text. |
| 71 | sed -i "s/</\</g;s/>/\>/g" ${f[$n]} |
| 72 | fi |
| 73 | done |
| 74 | |
| 75 | ## Build the diff page. |
| 76 | |
| 77 | # Add an HTML header to the wdiff output, with style for visualizing the |
| 78 | # insertions and deletions, and write the title of the page. |
| 79 | cat > $diff_file << EOF |
| 80 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
| 81 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| 82 | <!-- Generated by GNUN --> |
| 83 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| 84 | <head> |
| 85 | <meta http-equiv="content-type" content="text/html; charset=utf-8" /> |
| 86 | <title>${diff_file##*\/}</title> |
| 87 | <style type="text/css"> |
| 88 | span.removed { background-color: #f22; color: #000; } |
| 89 | span.inserted { background-color: #2f2; color: #000; } |
| 90 | </style></head> |
| 91 | <body><pre> |
| 92 | EOF |
| 93 | |
| 94 | # Run wdiff with options to add the proper markup at the beginning and end of |
| 95 | # deletions and insertions. |
| 96 | wdiff --start-delete '<span class="removed"><del><strong>' \ |
| 97 | --end-delete '</strong></del></span>' \ |
| 98 | --start-insert '<span class="inserted"><ins><em>' \ |
| 99 | --end-insert '</em></ins></span>' \ |
| 100 | ${f[0]} ${f[1]} >> $diff_file || true |
| 101 | |
| 102 | # Add the closing tags. |
| 103 | echo '</pre></body></html>' >> ${diff_file} |
| 104 | |
| 105 | echo -e "\n The diff file is $diff_file." |
| 106 | close_term 0 |