aboutsummaryrefslogtreecommitdiff
path: root/toc/toc
blob: 201b6cc7334f3564ab5f98e168bf3f9ac2eab4ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/sh
#
# toc -- run troff in three passes
#
# Permission to use, copy, modify and/or
# distribute this software for any purpose
# with or without fee is hereby granted.
#

if [ $# -eq 0 ]; then
	echo "usage: $0 [cmd ... \|] <troff> [arg ...]" 1>&2
	echo "(input should be given on stdin)" 1>&2
	exit 1
fi

# Create temporary files.
FILES=
for t in f g h i j; do
	x=`mktemp` || exit $?
	FILES="$FILES $x"
	eval $t=\$x
done
trap 'rm $FILES; trap -' INT QUIT EXIT

#
# An awk script separates toc output from troff output.
# The former is printed on standard out, while the latter
# is printer on standard error.
#
AWK='
	/^\(toc\)/ { print substr($0, 6); next }
	{ print > "/dev/stderr" }
'

#
# Troff is run as many times as needed, at most three.
# Toc output is saved in a temporary file. After each pass, an
# analysis of the output determines whether more passes are needed.
#
# The script always exits with the status code of the last troff pass.
#
echo $0: first pass 1>&2
tee $f | { eval "$@" -rte=1 -dtf=; s=$?; } 2>&1 1>$i | awk "$AWK" >$g
[ -s $g ] || { cat $j; exit $s; }

echo $0: second pass 1>&2
{ eval "$@" -rte=1 -dtf=$g; s=$?; } <$f 2>&1 1>$j | awk "$AWK" >$h
diff -q $g $h >/dev/null && { cat $j; exit $s; }

echo $0: third pass 1>&2
{ eval "$@" -rte=0 -dtf=$h; s=$?; } <$f | grep -v '^(toc)'
exit $s