#!/bin/sh

# pdftgif v1.07		Public Domain.	NIDE lab @ Nara-WU.

# ϲ:
#   TgifѤPDF񤭤ġ

# ˡ:
#   pdftgif [-n] input.pdf [work.obj [output.pdf]]
#
#   input.pdfӥåȥޥåײΤŽդ줿TgifԽ̤
#   ɽ졢˲񤤤ƥ֤ƽλȡTgif̤˽񤤤Τ
#   input.pdfξ夫񤭲äPDFե input_out.pdf (
#   ե̾Ρ.pdfפľˡ_outפɲäե̾)
#   (PDFեѹʤΤ)
#   ʤinput.pdfӥåȥޥåײΤTgifԽ̤Ž
#   ǽϤPDFեˤϱƶʤ(ǽϤPDFեˤϸPDF
#   ޤ)
#   ޤTgifԽ̤ŽӥåȥޥåפʬƩTgif
#   Υӥåȥޥåפ겼(Ť͹碌Ȥ)˿ͼϤΤ֤ơ
#   ӥåȥޥåפβ˱ƸƤ⡢Ͻ夬PDFǤϸPDF
#   ˤϤʤʤΤաTgifϤΤϡ夬PDFǤɬ
#   PDF(Ť͹碌Ȥ)
#
# ץ
#   -n: ߴΤ¸ߤ뤬ꤷƤⲿ⤷ʤʤä

# 󥹥ȡˡ:
#   ưɬפʤΡפ򥤥󥹥ȡ塢ʤ
#   PATH̤äǥ쥯ȥ֤
#   ӡźʤpdfunifyobj⥤󥹥ȡ뤵Ƥ뤳Ȥ˾ޤ

# ưɬפʤ:
#   Tgif pdftk poppler-utils Netpbm Ghostscript(gs) LaTeX켰(ܸǤǤOK)
#   dvipdfmx
#   źʤpdfunifyobjưˤPerl+Digest::MD5⥸塼ɬ
#   TgifܸƥȤޤԽԤϥja_JP.eucJP뤳

# ȯηа:
#   UNIXOSPDFԽǤե꡼ΥġɤΤʤ
#   pdfeditȤΤ뤬ΤȤܸ줬ޤȤ˻ȤʤΤ
#   ǤPDF񤭤ǤġܻؤƺäΤ

# ޤή:
#   ޤPDFեӥåȥޥåײѴTgifԽ̤Žդ
#   ʹ֤Ϥξ夫鲿Tgifǽ񤤤Tgifλ
#   ȡTgifνϤΤʹ֤񤤤ʬĤPDFβ
#   ǡEPSLaTeX+dvipdfmxPDFpdftkǸPDFȹ
#   źʤpdfunifyobjưˤĤƤƱեƬ

# Ǥѹ
#   3<&1Τ褦ʵϻȤʤʤäΤǥ뤬kshǤäƤʤưϤ
#   ImageMagickǥեȥƥݥꥷѹPDF򰷤ʤʤä
#   ImageMagick(identify, convert)ǽƤս¾ΤΤ֤
#   źʤpdfunifyobjФȤ褦ˤʤä
#   ˡ0.pdfפꤷȤե̾νäƤΤľ

# Todo:
#   ΤȤ⡼ɤTgifեФƤϰֹ碌ޤʤ
#   (̤˻ȤäƤФΤȤˤʤʤΤ)

usage(){
	echo 'Usage: '"`basename \"$0\"`"' [-n] in.pdf [work.obj [out.pdf]]'>&2
	exit 255
}
die(){
	echo "$@" >&2; exit 1
}
if [ X"`echo -n`" = X-n ]; then
	echon(){
		echo "$@\c"
	}
else
	echon(){
		echo -n "$@"
	}
fi
cmdexist(){
	[ -e "`which \"$1\" 2>/dev/null`" ]
}
if cmdexist seq; then
	:
elif cmdexist gseq; then # GNU seqgseqȤ¸ߤĶ
	seq(){
		gseq "$@";
	}
else
	seq(){ # ܥץȤǻȤǾ¤seq
		awk 'BEGIN{ # seq [-f fmt] [from [inc]] to
			i = 1; fmt = "%g"
			while(i + 2 < ARGC && ARGV[i] == "-f"){
				fmt = ARGV[i+1]; i += 2
			}
			if(ARGC - i == 1){
				from = 1; inc = 1; to = ARGV[i]
			} else if(ARGC - i == 2){
				from = ARGV[i]; inc = 1; to = ARGV[i+1]
			} else if(ARGC - i == 3){
				from = ARGV[i]; inc = ARGV[i+1]; to = ARGV[i+2]
			} else {
				print "seq: arg count" > "/dev/stderr"; exit(1)
			} # ΰɤϸƤʤ
			for(num = from; inc<0 ? num>=to : num<=to; num += inc){
				printf fmt, num; print ""
			}
		}' "$@"
	}
fi
excl(){ # 1O_EXCLǥץǤ뤫Ĵ٤(Ρ>|פȤ鷺)
	perl -e '
		use Fcntl;
		sysopen(OUT, $ARGV[0], O_WRONLY|O_APPEND|O_CREAT|O_EXCL)
			|| exit 1;
	' "$1"
}

MD5CMD='openssl md5'
for i in md5sum md5; do if cmdexist $i; then MD5CMD=$i; break; fi; done

# TgifܸϤϥ뤬ja_JP.eucJPǤʤưʤΤǡ뤬
# ja_JP.utf8ʤɤäja_JP.eucJPˤtgifư륷ؿTGIF
AWKSCR='BEGIN{
	IGNORECASE = 1
	lang = ENVIRON["LC_ALL"]; if(!lang) lang = ENVIRON["LANG"]
	if(lang !~ /^ja_JP\./ || lang ~ /^ja_JP\.(ujis|euc-?jp)$/) exit
	while("exec locale -a 2>/dev/null" | getline > 0)
		if(/^ja_JP.(ujis|euc-?jp)$/){print; exit}
}'
TGIFLANG="`awk \"$AWKSCR\"`" # ʤtgif򤳤Υǵư
case "$TGIFLANG" in
'')	TGIF(){ tgif "$@"; };;
*)	TGIF(){ LC_ALL="$TGIFLANG" tgif "$@"; };;
esac

# xpmե(TgifǤԽ˿ʤ褦)뤿
# ꥹȡTgifν(11Tgif50DebianTgifʣ)
TGIF_COLORS='
	65535	  0 65535
	65535	  0	0
	    0 65535	0
	    0	  0 65535
	65535 65535	0
	65535 49344 52171
	    0 65535 65535
	24415 40606 41120
	65535 65535 65535
	    0	  0	0
	12079 20303 20303

	    0	  0	0
	65535 65535 65535
	    0	  0 32896
	    0 32896	0
	    0 32896 32896
	32896	  0	0
	32896	  0 32896
	65535 32896	0
	32896 32896 32896
	49344 49344 49344
	    0	  0 65535
	    0 65535	0
	    0 65535 65535
	65535	  0	0
	65535	  0 65535
	65535 65535	0
	19532 19532 19532
	46003 46003 46003
	59110 59110 59110
	56540  8995	0
	65535 13107 13107
	47288 18247 18247
	39321 10280 19532
	38036 18247 27499
	39321 26214 52428
	27499  8995 38036
	24158  4369 42662
	18247	  0 47288
	 8995  8995 56540
	    0 39321 65535
	39321 52428 65535
	    0 56540 65535
	 8995 47288 56540
	13107 41891 41891
	13621 24158	0
	32125 42662 18247
	    0 44718	0
	15677 60395 15677
	65535 65535 39321
	59110 59110 19532
	46003 46003	0
	26214 26214	0
	19532  6425	0
	26214 13107	0
	32896 19532  6425
	39321 26214 13107
	52428 26214 13107
	65535 26214 13107
	65535 39321 26214
	65535 52428 39321
'
# TgifǤԽ˺ǽ餫ɲäƤ
TGIF_ADD_COLORS='
	65535 19275	0
'
makecolor(){ # RGBοꥹȤstdinpnmե
	awk '
		{sub(/#.*/, "")}
		NF{l = l $0 "\n"; n++}
		END{printf "P3\n" n " 1\n65535\n%s", l}
	'
}

pdfpages_by_pdftk(){ # ǽϤȤ PDFѹΥå
	pdftk "$1" dumpdata | awk '/^NumberOfPages:/{print $2}'
}

PDFINFO_REG='{sub(/[ \t]*:/, ": "); $1 = $1}' # pdfinfoνĴ
pdfpages(){ # pdfpages XXX.pdf
	pdfinfo -- "$1" | awk "$PDFINFO_REG"'/^Pages?:/{print $2}'
}
pdfsize_in_tgif(){ # Ϥstdout˽Ф
	pdfinfo -l "`pdfpages \"$1\"`" -- "$1" | awk "$PDFINFO_REG"'
		function max(x, y){return(x+0 > y+0 ? x : y)}
		function roundup(x, y){y = int(x); return y + (x != y)}
		function pt2tgif(x){return roundup((x+.5)/72*128)}
		function register(w, h, i){wa[i] = w; ha[i] = h}
		function rregister(r, i){if(r == 90 || r == 270) ra[i]}
		/^Page [0-9]+ size:/{register($4, $6, $2)}
		/^Page [0-9]+ rot:/{rregister($4, $2)}
		END{
			for(i in ra){tmp = wa[i]; wa[i] = ha[i]; ha[i] = tmp}
			for(i in wa){wmax = max(wmax, wa[i])
				     hmax = max(hmax, ha[i])}
			if(wmax hmax == ""){
				print "Cannot examine size of PDF" \
					> "/dev/stderr"
				exit(1)
			}
			print pt2tgif(wmax) "," pt2tgif(hmax)
		}
	' # Ϥpt(TeXǤbp)TgifΥɥåñ̤ѴƤ
} # ʣڡξϺͤФ

PERLSCR_POPT_EXEC_CAT='
	print;
	print while(read(ARGV, $_, 1024));
'

# ΥåĴ
while getopts n OPTC; do
	case "$OPTC" in
	n)	:;;
	*)	usage;;
	esac
done
shift `expr $OPTIND - 1`
[ $# -lt 1 -o 3 -lt $# ] && usage

case "$1" in
*.pdf)	PDFFILE="$1";;
*)	[ ! -e "$1" ] && PDFFILE="$1.pdf" || PDFFILE="$1";;
esac
[ -e "$PDFFILE" ] || die "$PDFFILE" not found
PDFBASE="`expr X\"$PDFFILE\" : '.\(.*\)\.pdf$'`"
[ X"$PDFBASE" = X ] && PDFBASE="$PDFFILE"
# $PDFFILE0.pdfΤ褦ʾ硢
# PDFBASE="`expr X\"$PDFFILE\" : '.\(.*\)\.pdf$' '|' \"$PDFFILE\"`" ǤϤ

case "$#:$2" in
1:|[23]:-)
	OBJFILE="$PDFBASE".obj;;
*:*.obj)
	OBJFILE="$2";;
*)
	[ ! -e "$2" ] && OBJFILE="$2.obj" || OBJFILE="$2";;
esac

case "$#:$3" in
[12]:)
	OUTFILE="$PDFBASE"_out.pdf;;
*:*.pdf)
	OUTFILE="$3";;
*)
	[ ! -e "$3" ] && OUTFILE="$3.pdf" || OUTFILE="$3";;
esac

# exec echo "$PDFFILE" "$OBJFILE" "$OUTFILE"

# PDFΥڡ롣ǤʤХ顼λ
PDFPAGES=`pdfpages_by_pdftk "$PDFFILE"`
case "$PDFPAGES" in ''|*[!0-9]*) die 'Not a PDF?';; esac
# ǼԤ pdftops -paper match orig.pdf - | ps2pdf - new.pdf
# ȤPDFؤȤޤȤ

SIGS='1 2 3 13 15'

# ȥǥ쥯ȥäƤǤʤХ顼λ
WORKDIR="`expr X\"$OBJFILE\" : '.\(.*\)\.obj$'`"
[ X"$WORKDIR" = X ] && WORKDIR="$OBJFILE"; WORKDIR="$WORKDIR".imgs
mkdir -m 0700 -p -- "$WORKDIR" || exit 1
PERLSCR='
	$ARGV[0] =~ s/["\n\\]/$& eq "\n" ? "\\n" : "\\$&"/eg;
	print $ARGV[0];
'
QWORKDIR="`perl -e \"$PERLSCR\" \"$WORKDIR\"`"
case "$WORKDIR" in /*) :;; *) WORKDIR="`pwd`/$WORKDIR";; esac	# CDPATH褱

# ʣưɤ٤$WORKDIR.lckä¹
trap '' $SIGS
LCKFILE="$WORKDIR"/.lck
excl "$LCKFILE" || {
	die Another pdftgif is working on "$PDFFILE"
}
# $WORKDIR_*.lckϽλ˾õ
settrap(){
	trap '
		ST=$?; trap 0; trap "" $SIGS
		'"$*"'; rm -rf "$WORKDIR"/_*; rm -f "$LCKFILE"
		exit $ST
	' 0 $SIGS
}
settrap :

# PDF鿧ĴXPM
# ޤ¸߸ XPM롢ޤʤΤɤ餫Ǥʤȥ顼λ
# tar+lzop̤ƤXPMƤ(̥ե¸)
PAGES_ARC=pages.xpm.tar.lzo
if cmdexist lzop; then lzop -V; tar; fi >/dev/null 2>&1
case "`
	cd \"$WORKDIR\" || exit
	exec 2>/dev/null; trap '' $SIGS
	cmdexist lzop && [ -f "$PAGES_ARC" ] &&
		lzop -d < "$PAGES_ARC" | tar xf -
	seq -f %.0f.xpm $PDFPAGES | xargs ls -d | awk 'END{print NR}'
`" in
'')
	die Failed to generate page images
;;	
$PDFPAGES) # 粿⤷ʤ
	:
;;
0) # ʤ˸¤ºݤXPM ߤ򸡽Фæ
	rm -f "$WORKDIR/$PAGES_ARC"
	echo Generating page images >&2
	_trapcmd(){
		echo Interrupted >&2
		cd "$WORKDIR" && {
			seq -f %.0f.xpm $PDFPAGES | xargs rm -f
			rm -f "$PAGES_ARC"
		}
	}
	settrap _trapcmd

	(
		gs -r128 -dNOPAUSE -dBATCH -sDEVICE=png256 -dSAFER -q \
			-sOutputFile="$WORKDIR"/__%d.png "$PDFFILE" &&
		cd "$WORKDIR" || exit 1
		# $WORKDIR__*ϤΥ֥Τߤǻ
		echo "$TGIF_COLORS" "$TGIF_ADD_COLORS" | makecolor > __col.pnm
		echon Page >&2
		for PAGE in `seq $PDFPAGES`; do
			# ǥڡѤPDFб뤿 Ȳ
			# 1ιä
			pngtopnm __$PAGE.png | pnmremap -map=__col.pnm |
				pnmpad -right 1 -bottom 1 > __pag.pnm
			echon " $PAGE" >&3
			rm -f __$PAGE.png &
			pnminvert __pag.pnm | ppmcolormask black > __msk.pnm
			# __pag.pnmʬƩᤵxpmˤ褦ȤƤ
			# Τʤ white __pag.pnm Ǥʤʤ
			# ppmcolormaskΥХ
			ppmtoxpm -alphamask=__msk.pnm __pag.pnm > $PAGE.xpm ||
				exit 1
		done 3>&2 2>/dev/null
		echo '' >&2
		rm -rf __*
	) || die Failed to generate page images

	# PDFβˤ Tgif˼ݤ˿ޥåפ뤳Ȥ
	# ɤö256¤ θpnmremap-mapץȤä
	# Tgifν˹碌

	# trap򸵤᤹
	settrap :
;;
*)
	rm -f "$WORKDIR/$PAGES_ARC"
	die XPM files in "$WORKDIR" are partly missing
;;
esac

# Tgifե뤬¸Ǥʤʤ
if [ ! -e "$OBJFILE" ]; then
	echo "$TGIF_ADD_COLORS" | makecolor |
		ppmtoxpm > "$WORKDIR"/_addcol.xpm 2>/dev/null
	cat <<-EOF | tgif -exec - -- "$OBJFILE" >/dev/null
		import_file("$QWORKDIR/_addcol.xpm",xpm,0,0)
		call_simple_shortcut(SelectAll)
                delete_selected_obj()
		call_simple_shortcut(Save)
		call_simple_shortcut(Quit)
	EOF
	rm -f "$WORKDIR"/_addcol.xpm
	[ $? -eq 0 -a -e "$OBJFILE" ] || die Cannot create "$OBJFILE"

	# ξ硢ڡPDF˹碌
	AWKSCR=' # Ի
		function roundup(x, y){y = int(x); return y + (x != y)}
		function pt2tgif(x){return roundup((x+.5)/72*128)}
		/^%%BoundingBox: 0 0 /{
			print pt2tgif($4) "," pt2tgif($5); exit(ok = 1)
		}
		END{exit(!ok)}
	' # PDFΥڡTgifΥɥåñ̤Ѵ
	TGIFPAGESIZE=`pdfsize_in_tgif "$PDFFILE"` || exit 1
	perl -i -pe '
		if(/^state\(.*\)\.$/){
			s/^((?:.*?,){36})(?:\d+,)(?:\d+,)(?#
				)/${1}'"$TGIFPAGESIZE"',/;
			'"$PERLSCR_POPT_EXEC_CAT"'
		}
	' -- "$OBJFILE" || exit 1
fi

# TgifեΥڡڡڡ⡼ɡڡĴ٤Ƥ
AWKSCR='
	BEGIN{
		FS=","; varname[32] = "TILED"
		varname[33] = "OBJPPARA1"; varname[34] = "OBJPPARA2"
		varname[37] = "OBJPWID"; varname[38] = "OBJPHGT"
	}
	/^state\(.*\)\.$/{
		if(recognized || NF != 42) exit(recognized = 0)
		for(i in varname)
			if($i !~ /^[0-9]+$/) exit(recognized = 0)
		for(i in varname) printf("%s=%d\n", varname[i], $i)
		recognized = 1
	}
	END{exit(!recognized)}
'
TMPSET="`awk \"$AWKSCR\" \"$OBJFILE\"`" || die "$OBJFILE" not reconized
eval "$TMPSET"
if [ $TILED = 0 ]; then
	OBJPPOS=$OBJPPARA1; OBJPAGES=$OBJPPARA2
else
	OBJPPOS=1; OBJPAGES=`expr $OBJPPARA1 \* $OBJPPARA2`
fi
# echo $TILED $OBJPPARA1 $OBJPPARA2 $OBJPPOS $OBJPAGES $OBJPWID $OBJPHGT

# Tgifե뤬PDFΥڡ­ʤϥڡ䤹
if [ $OBJPAGES -lt $PDFPAGES ]; then
	OBJPAGES=$PDFPAGES
	if [ $TILED = 0 ]; then
		OBJPPARA2=$OBJPAGES
	else
		OBJPPARA2=`expr \( $OBJPAGES + $OBJPPARA1 - 1 \) / $OBJPPARA1`
	fi
	perl -i -pe '
		if(/^state\(.*\)\.$/){
			s/^((?:.*?,){33})(?:\d+,)/${1}'$OBJPPARA2',/;
			'"$PERLSCR_POPT_EXEC_CAT"'
		}
	' -- "$OBJFILE" || exit 1
fi

# Ӥ뤿ᡢobjեMD5äƤ â
# $OUTFILEʤmd5sumޥɤʤϡ-פϿƤΤ
# objMD5Ȱפ뤳ȤϤʤ
OBJMD5="`[ -e \"$OUTFILE\" ] && $MD5CMD < \"$OBJFILE\" || echo -`"

# name°/__pdftgif\d+/βä̿
rmimgcmds(){ # rmimgcmds $TILED $OBJFILE
	perl -ne '
		BEGIN{$tiled = '$1'}
		if(/^attr\("name=",\s*"(__pdftgif)(\d+)",/){
			print "call_one_arg_shortcut(GotoPage,$2)\n" if !$tiled;
			print "select_obj_by_name($1$2)\n";
			print "delete_selected_obj()\n";
		}
	' -- "$2"
}

echo Reading page images >&2
{
	# βĤäƤ(̿)
	rmimgcmds $TILED "$OBJFILE"

	# PDFƥڡβɤ߹ޤ
	for PAGE in `seq $PDFPAGES -1 1`; do
		if [ $TILED = 0 ]; then
			cat <<-EOF
				call_one_arg_shortcut(GotoPage,$PAGE)
			EOF
			TMPX=0,0
		else
			TMPX=`expr $PAGE - 1`
			TMPY=`expr $TMPX / $OBJPPARA1 \* $OBJPHGT`
			TMPX=`expr $TMPX % $OBJPPARA1 \* $OBJPWID`,$TMPY
		fi
		# tgif-4.1.42ˤޤʤshuffle_obj_to_bottomȤʤ褦
		# (MacportsΤ̤ˤΥСʤΤ)
		cat <<-EOF
			// create 2 dummy obj
			create_box_obj(0,0,1,1)
			select_top_obj()
			add_attr_to_selected_obj(name,__pdftgifA,NULL,NULL)
			create_box_obj(0,0,1,1)
			select_top_obj()
			add_attr_to_selected_obj(name,__pdftgifB,NULL,NULL)
			// group all
			call_simple_shortcut(SelectAll)
			call_simple_shortcut(Group)
			add_attr_to_selected_obj(name,__pdftgifC,NULL,NULL)
			// import page image
			import_file("$QWORKDIR/$PAGE.xpm",xpm,$TMPX)
			select_top_obj()
			add_attr_to_selected_obj(name,__pdftgif$PAGE,NULL,NULL)
			call_simple_shortcut(Lock)
			unselect_all_obj()
			hide_attr(__pdftgif$PAGE.name)
			// move grouped obj to top and ungroup
			shuffle_obj_to_top(__pdftgifC)
			select_obj_by_name(__pdftgifC)
			delete_attr_from_selected_obj(__pdftgifC.name)
			call_simple_shortcut(UnGroup)
			// delete 2 dummy obj
			select_obj_by_name(__pdftgifA)
			delete_selected_obj()
			select_obj_by_name(__pdftgifB)
			delete_selected_obj()
		EOF
		# 1󤬽ޤǤ__pdftgif[A-C]̾objƾä
		# Τ᥿⡼ɤǤ⤳ǤȤꤢپʤ
	done
	[ $TILED = 0 ] && cat <<-EOF
		call_one_arg_shortcut(GotoPage,$OBJPPOS)
	EOF
	cat <<-'EOF'
		call_simple_shortcut(Save)
		call_simple_shortcut(Quit)
	EOF
} | tgif -print -print_cmd cat -exec - -- "$OBJFILE" >/dev/null ||
	die Failed to pre-process Tgif .obj file
echo done >&2

# objեؤXPMμߤϽλΤ
# $WORKDIRXPMեlzop()+tarǥХå饦ɤˤư
# ̥ե¸֤ƤϾ񤭤ʤ
# θ󰵽̥եõ
settrap wait
if cmdexist lzop; then (
	cd "$WORKDIR" || exit
	exec 2>/dev/null; trap '' $SIGS
	if [ ! -f "$PAGES_ARC" ]; then
		seq -f %.0f.xpm $PDFPAGES | tar -T - -cf - |
			LZOP= lzop > "$PAGES_ARC" || rm -f "$PAGES_ARC"
	fi
	[ -f "$PAGES_ARC" ] && seq -f %.0f.xpm $PDFPAGES | xargs rm -f
) & fi

# ǥ桼
# öSaveΤǷŪFlushUndoBuffer
echo '
	set_output_format(Text,1)
' > "$LCKFILE"	# printƥȷڤؤ $LCKFILEǷͤ
TGIF -exec "$LCKFILE" -- "$OBJFILE" || die tgif abended
# -exec filenameפʤˡ--פtgif-4.1.42Ǥޤưʤ

# Tgifե뤫ű
{
	# ƸڡĴ($TILED0ΤȤ)
	if [ $TILED = 0 ]; then
		AWKSCR='/^state\(/{print $33; exit}'
		OBJPPOS="`awk -F, \"$AWKSCR\" \"$OBJFILE\"`"
	fi

	# ű
	rmimgcmds $TILED "$OBJFILE"
	# Υڡ
	[ $TILED = 0 ] && cat <<-EOF
		call_one_arg_shortcut(GotoPage,$OBJPPOS)
	EOF

	cat <<-'EOF'
		call_simple_shortcut(Save)
		call_simple_shortcut(Quit)
	EOF
} | tgif -print -print_cmd cat -exec - -- "$OBJFILE" >/dev/null ||
	die Failed to post-process Tgif .obj file

if [ X"$OBJMD5" = X"`$MD5CMD < \"$OBJFILE\"`" ]; then
	echo No changes made >&2; exit
fi # 뤷ǤobjѤΤǤޤܤϤʤ

wait	# Хå饦ɤlzop򵯤ƤץνλǰΤԤ
trap '' $SIGS
TMPDIR="`mktemp -d /tmp/.tgXXXXXX`"
# ϳޤ줿TMPDIRäƽλλwait
_trapcmd(){
	rm -rf "$TMPDIR"
}
settrap _trapcmd

# Tgifե뤫PDF
cat <<-EOF > "$TMPDIR"/ps2pdf	# ps2pdfΥХworkaround
	#!/bin/sh
	'`which ps2pdf`' "\$@" || ps2pdf12 "\$@"
EOF
chmod 500 "$TMPDIR"/ps2pdf
# ps2pdf(gs)Хäݤ˰ե뤬ĤΤɤ٤TEMP
PATH="$TMPDIR:$PATH" TEMP="$TMPDIR" tgif -print -color -pdf -o"$TMPDIR" -- \
	"$OBJFILE" || die Failed to create PDF from "$OBJFILE"
rm -f "$TMPDIR"/ps2pdf "$TMPDIR"/gs_*

case "$PDFFILE" in /*) :;; *) PDFFILE="`pwd`/$PDFFILE";; esac
case "$OUTFILE" in /*|-) :;; *) OUTFILE="`pwd`/$OUTFILE";; esac
# ʸTMPDIRǺ
cd "$TMPDIR" || die Cannot utilize temporary directory

# 衢ꥸʥPDFȹ pdftkȤ
# pdftk multistampstamp¦򾡼resizeƤޤΤǤ
# pdftk burstdoc_data.txtΤTMPDIRǤ
# : (1) TgifäPDFa.pdf˲̾ (2) PDFx%d.pdf˥ڡʬ
# (3) a.pdfy%d.pdf˥ڡʬ (4) {x,y}%d.pdfڡ˹z%d.pdf
# (latexdvipdfmxȤäƤ) (5) z%d.pdfϢ뤷b.pdf
# PDF˥ԡ

OBJBASE="`basename \"$OBJFILE\" .obj`"
[ -e "$OBJBASE".pdf ] || { echo Did not generate any PDF >&2; exit; }
case "$OBJBASE" in a) :;; *) mv -- "$OBJBASE".pdf a.pdf;; esac

pdftk "$PDFFILE" burst output x%d.pdf	# PDFʬ
pdftk a.pdf burst output y%d.pdf	# TgifǺäʬ

if cmdexist dvipdfmx; then
	DVIPDFM=dvipdfmx; DVIPDFMOPT=$DVIPDFM
	kpsewhich $DVIPDFM.def >/dev/null || DVIPDFMOPT=dvipdfm
else
	DVIPDFM=dvipdfm; DVIPDFMOPT=$DVIPDFM
fi
# extractbbΤdvipdfmx.defʤ(դ̵ͭ)Τ
# extractbbdvipdfmx.defʤdvipdfm.defѡפȤϤʤ
if cmdexist extractbb; then
	myebb(){ # PDFꡣˤϡ.pdfפʬͿ
		extractbb "$1".pdf
		ln "$1".xbb "$1".bb
	} # dvipdfm{,x}.defΤɤѤǤɤ褦.bb.xbbξ˥󥯤
else
	myebb(){
		ebb "$1".pdf
		ln "$1".bb "$1".xbb && return
		# ebbPDF1.4ʹߤˤϻȤʤΤǰľʲ (ȯ:
		# ebbϼԤƤ֤0 äebb֤ͤϿԲ)
		# $TMPDIRǺȤƤ뤳Ȥ
		echo '(trying ebb workaround)' >&2
		{ echo '%PDF-1.3'; tail -n +2 "$1".pdf; } > _ebbtmp.pdf
		ebb _ebbtmp.pdf; mv _ebbtmp.bb "$1".bb; rm _ebbtmp.pdf
		ln "$1".bb "$1".xbb
	}
fi
echon generating page >&2
for PAGE in `seq $PDFPAGES`; do
	myebb x$PAGE && myebb y$PAGE || exit 1

	{
		cat <<-'EOF'
			\documentclass{article}
		EOF
		cat <<-EOF
			\\usepackage[$DVIPDFMOPT]{graphics}
		EOF
		awk '
			{sub(/:/, ": ")} # just in case
			/^%%BoundingBox:/{w = $4 - $2; h = $5 - $3}
			/^%%HiResBoundingBox:/{w = $4 - $2; h = $5 - $3; exit}
			END{
				if(w != ""){
					print "\\paperwidth" w "bp"
					print "\\paperheight" h "bp"
				}
			}
		' x$PAGE.bb # PDFեʬ򤷤bb
		cat <<-'EOF'
			\headheight0pt \headsep0pt \parindent0pt \topskip0pt
			\hoffset-1in \voffset-1in
			\topmargin0pt \oddsidemargin0pt
			\textwidth\paperwidth \textheight\paperheight
			\pagestyle{empty}
			\AtBeginDvi{\special
				{papersize=\the\paperwidth,\the\paperheight}}

			\newbox\tmpbox\newdimen\tmpdim
			\def\fullsync#1{\setbox\tmpbox\hbox{#1}%
				\tmpdim\the\ht\tmpbox
				\raisebox{-\tmpdim}{\usebox{\tmpbox}}}
			\def\putgraphics#1{\put(0,0){\makebox[0pt][t]{%
				\fullsync{\includegraphics{#1}}}}}
			\begin{document}\unitlength1cm
			\begin{picture}(0,0)
		EOF
		cat <<-EOF
				\\putgraphics{x$PAGE.pdf}
				\\putgraphics{y$PAGE.pdf}
		EOF
		cat <<-'EOF'
			\end{picture}
			\end{document}
		EOF
	} > z$PAGE.tex || exit 1

	echon " $PAGE" >&2
	latex z$PAGE </dev/null >/dev/null && $DVIPDFM z$PAGE.dvi 2>/dev/null ||
		die latex or $DVIPDFM failed
done
echo '' >&2
pdftk `seq -f z%.0f.pdf $PDFPAGES` cat output b.pdf &&
if [ $PDFPAGES -gt 1 ] && cmdexist pdfunifyobj; then
	# PDFʣڡǡźʤpdfunifyobjȤС̤
	pdfunifyobj b.pdf "$OUTFILE"
else
	pdftk b.pdf output "$OUTFILE"
fi && echo "$OUTFILE" generated >&2
# $PDFFILE$OUTFILEƱեǤOK $OUTFILE-פʤstdout
# ŤpdftkˤcatburstνϤxrefХ뤬
# pdftk in.pdf output out.pdf̤н
