GraphicsMagickでPDFを差分比較（シェルスクリプト版）

[[デザイナー向け] GulpとGraphicsMagickで校正途中のPDFを差分比較する。マルチページ・マルチファイル対応](http://qiita.com/y_hokkey/items/417e108e212210b4e635)がめっちゃ便利そうだったので、シェルスクリプトに移植してみました。GraphicsMagickについては前掲の記事をご覧ください。

# 使い方
とりあえずGraphicsMagickをインストールすれば使えるはずです。`#!/bin/bash`としていますがshでもいけるかもしれません（未確認）。

後述のスクリプトを`pdfdiff`とか適当な名前でパスの通ったディレクトリに保存し、実行フラグを立てておけばOKです。

`pdfdiff compare`で\_oldディレクトリと\_newディレクトリ内のPDFを1ページごとに比較し、\_diff.pdf（および、比較に使った各ページを結合したPDF）を出力します。各ディレクトリに入っているPDFはファイル名とページ数を合わせておいてください。\_diff.pdfとして差分が出力されます。

細かい使い方は`help`を見ていただければと。

# Gulp版と比べて便利なところ
* 古いPDF、新しいPDFが入っているフォルダを指定できる
    * が、そのせいでcleanサブコマンドが若干ややこしくなっています……
* 比較方法を指定できる
* パスの通ったところに置いておけば、どこでも実行できる

# スクリプト本体
シェルスクリプトのお作法とかサブコマンドがある場合のオプション解析のしかた、Usageの書きかた（と英語）などなどかなり自信がないので、まずいところありましたらぜひともご指摘ください！

```bash
#!/bin/bash

# dependency check
if type gm > /dev/null 2>&1; then
  GM=gm
else
  echo 'Please install GraphicsMagick.'
  exit 1
fi

# set variables
TEMP_OLD='.temp_old'
TEMP_NEW='.temp_new'
TEMP_OUT='.temp_out'

DIR_OLD='_old'
DIR_NEW='_new'

OUTPUT_OLD='_old.pdf'
OUTPUT_NEW='_new.pdf'
OUTPUT_DIFF='_diff.pdf'

GM_DENSITY='-density 150x150'
GM_FORMAT='.pdf'
GM_COMPARE_STYLE='xor'

# set subcommand
SUBCOMMAND=$1
shift


# make temporary directories and split pdf(s)
function split() {
local _dir=$1
local _temp_dir=$2

if [ ! -d $_dir ]; then
  echo "Directory '$_dir' is not found."
  clean_temp
  exit 1
fi

mkdir $_temp_dir
for _pdf in $(ls $_dir | grep ".*\.pdf$"); do
  _basename=$(basename ${_pdf%.pdf})
  $GM convert -verbose $GM_DENSITY $_dir/${_basename}.pdf +adjoin $_temp_dir/${_basename}%03d$GM_FORMAT
done
}

# remove temporary files
function clean_temp() {
rm -frv $TEMP_OLD
rm -frv $TEMP_NEW
rm -frv $TEMP_OUT
}


# compare subcommand
function compare() {
split $DIR_OLD $TEMP_OLD
split $DIR_NEW $TEMP_NEW

mkdir $TEMP_OUT
for _file in $(ls $TEMP_NEW); do
  $GM compare -verbose -highlight-style $GM_COMPARE_STYLE -file $TEMP_OUT/$_file $TEMP_OLD/$_file $TEMP_NEW/$_file
done
$GM convert -verbose $TEMP_OUT/* $OUTPUT_DIFF
$GM convert -verbose $TEMP_OLD/* $OUTPUT_OLD
$GM convert -verbose $TEMP_NEW/* $OUTPUT_NEW

clean_temp
}

# clean subcommand
function clean() {
clean_temp
rm -fv $OUTPUT_OLD
rm -fv $OUTPUT_NEW
rm -fv $OUTPUT_DIFF
}

# help subcommand
function help() {
cat << EOS
$(basename $0) compare [-s <style>] [-o <old_dir>] [-n <new_dir>]
    Compare "old" PDFs with those os "new" and output diff.

    With -s <style> option, set GraphicsMagick's compare style, instead of xor.

    With -o <old_dir> option, set a directory for "old" PDFs <old_dir>, instead of _old.

    With -n <new_dir> option, set a directory for "new" PDFs <new_dir>, instead of _new.

$(basename $0) clean [-o <old_filename>] [-n <new_filename]
    Remove temporary directories and output files.

    With -o <old_filename> option, remove <old_filename>.pdf, instead of "_old.pdf".

    With -n <new_filename> option, remove <new_filename>.pdf, instead of "_new.pdf".

$(basename $0) help
    Show this message.

EOS
}

# execute
while getopts s:o:n: _opts; do
  case $_opts in
    s) GM_COMPARE_STYLE=$OPTARG ;;
    o)
      DIR_OLD=$OPTARG
      OUTPUT_OLD=${OPTARG}.pdf ;;
    n)
      DIR_NEW=$OPTARG
      OUTPUT_NEW=${OPTARG}.pdf ;;
  esac
done

case $SUBCOMMAND in
  compare)
    compare
    exit 0 ;;
  clean)
    clean
    exit 0 ;;
  help)
    help
    exit 0 ;;
  *)
    help
    exit 1 ;;
esac
```

# 最後に
y_hokkeyさん、便利なものを作ってくださってありがとうございます！これちょうど困っていたんですよ！！