I have now completed the patch to the Unix Text Professing book to add pdf
bookmarks to it.
The results can be downloaded here:-
<http://chuzzlewit.co.uk/utp_book-1.1.pdf>
The attached patch can be applied to the existing UTP source by doing:-
patch -p1 <../patch-utp-1.0-v3.diff
rm -rf index #optional - no longer used
chmod +x mkindex.pl
make
There is a second make file which you can use to generate the same book but
using pdfroff instead of gropdf. It can be used as "make -f Makefile.pdfroff".
Notes:-
Gropdf version.
Unless you use the latest CVS version of groff the pdf produced has two
faults:-
A) The thick line on the front page will have square caps instead of round
caps, and
B) The entries for "Preface" and "Chapter 4" will be open in the bookmarks
pane of the pdf reader (should be closed).
PDFroff version.
A further patch is required to pdfmark.tmac changing it to use the \! to
communicate with grops instead of \X. The reason is because in certain
circumstances groff can insert a blank line when planting a bookmark. The
newer \! escape does not do this. Without the patch you will see extra space
in the book which should not be there. This patch is not "release quality
since it only corrects the behaviour if the length of the pdfmark inserted
into the postscript is greater than 255 characters (none of the UTP
bookmarks). On further thought, it may be better to use the .ouput directive
now it is available.
Cheers
Deri
diff -uNBb a/ch03.t b/ch03.t
--- a/ch03.t 2003-07-28 01:59:46.000000000 +0100
+++ b/ch03.t 2013-01-22 17:39:00.035204544 +0000
@@ -2848,7 +2848,9 @@
.Ps
number window=20 wrapmargin=10
.Pe
-See Appendix A for a description of what these options mean.
+See
+.pdfhref L -D AppendixA -- Appendix A
+for a description of what these options mean.
.ix [.exrc] file %key exrc file
.Bh "The \f(CB.exrc\fP File
.LP 0
diff -uNBb a/ch04.t b/ch04.t
--- a/ch04.t 2003-07-28 01:59:46.000000000 +0100
+++ b/ch04.t 2013-01-22 17:47:58.388044348 +0000
@@ -1791,7 +1791,9 @@
depend on the resolution of the output device.
For example, units for a 300 dot-per-inch (dpi) laser printer will be
1/300 of an inch in either a vertical or a horizontal direction.
-See Appendix D for more information on
+See
+.pdfhref L -D AppendixD -- Appendix D
+for more information on
.CW ditroff
device units.
.PP
@@ -3371,7 +3373,9 @@
position 10.
Which fonts are mounted, and in which positions, depends on the output
device.
-See Appendix D for details.
+See
+.pdfhref L -D AppendixD -- Appendix D
+for details.
The font that is mounted in position 1 will be used for the body type of
the text\c
\(em\c
@@ -3653,7 +3657,9 @@
.CW DESC\.out
in the device subdirectory of
.CW /usr/lib/font .
-See Appendix D for details.
+See
+.pdfhref L -D AppendixD Appendix D
+for details.
.ix %end fonts, changing
.ix %end [troff] formatter, fonts %key troff formatter, fonts
.Bh "Special Characters"
diff -uNBb a/ch05.t b/ch05.t
--- a/ch05.t 2003-07-28 01:59:46.000000000 +0100
+++ b/ch05.t 2013-01-22 17:31:10.054485575 +0000
@@ -1989,7 +1989,7 @@
.CW troff
feature called
.I environments
-(see Chapter 14),
+.pdfhref L -D Chapter14 -P "(see " -A ), -- Chapter 14
so that parameters like line length or font that are set
inside a footnote are saved independently of the body text.
So, for example, if you issued the requests:
diff -uNBb a/ch06.t b/ch06.t
--- a/ch06.t 2003-07-28 01:59:46.000000000 +0100
+++ b/ch06.t 2013-01-22 17:47:58.460045530 +0000
@@ -160,7 +160,8 @@
device name using the
.CW -T
option.
-For a list of available devices, see Appendix B.
+For a list of available devices, see
+.pdfhref L -D AppendixB -P . -- Appendix B
The
.CW mm
command also has a
diff -uNBb a/ch08.t b/ch08.t
--- a/ch08.t 2003-07-28 01:59:45.000000000 +0100
+++ b/ch08.t 2013-01-22 17:32:27.274753348 +0000
@@ -494,7 +494,8 @@
T{
delim (\f[I]xy\fP)
T} T{
-Set \f[I]x\fP and \f[I]y\fP as \f[CW]eqn\fP delimiters. See Chapter 9
+Set \f[I]x\fP and \f[I]y\fP as \f[CW]eqn\fP delimiters. See
+.pdfhref L -D Chapter9 -- Chapter 9
for information on the equation preprocessor
\f[CW]eqn\fP.
T}
diff -uNBb a/ch09.t b/ch09.t
--- a/ch09.t 2013-01-10 01:50:40.000000000 +0000
+++ b/ch09.t 2013-01-22 18:26:01.615546441 +0000
@@ -753,9 +753,12 @@
Note that special names don't exist for all uppercase Greek letters,
such as ALPHA or ETA, because they are identical to the equivalent
English letters.
-See Table 9-1 for a list of Greek letters.
+See
+.pdfhref L -D Tab9.1 -- Table 9-1
+for a list of Greek letters.
.ix Greek characters
.KS
+.pdfhref M -N Tab9.1 -E
.Ts " Names for Greek Letters"
.TS
center,box;
diff -uNBb a/ch12.t b/ch12.t
--- a/ch12.t 2003-07-28 01:59:45.000000000 +0100
+++ b/ch12.t 2013-01-22 17:49:51.323899426 +0000
@@ -3712,7 +3712,9 @@
*The preceding sections have not covered all
.CW sed
commands.
-See Appendix A for a complete list of
+See
+.pdfhref L -D AppendixA -- Appendix A
+for a complete list of
.CW sed
commands.
.FE
diff -uNBb a/ch13.t b/ch13.t
--- a/ch13.t 2003-07-28 01:59:45.000000000 +0100
+++ b/ch13.t 2013-01-22 18:25:51.547381320 +0000
@@ -1962,7 +1962,9 @@
(You have already seen how the
.CW length
function works).
-See Appendix A for the syntax of these functions.
+See
+.pdfhref L -D AppendixA -- Appendix A
+for the syntax of these functions.
.PP
Going back to our report generator, we need to split each field
into subvalues.
diff -uNBb a/ch16.t b/ch16.t
--- a/ch16.t 2003-07-28 01:59:44.000000000 +0100
+++ b/ch16.t 2013-01-22 18:27:07.276623339 +0000
@@ -511,7 +511,9 @@
footnotes, as well as counters for automatic numbering of
figures, examples, equations, tables, and
section headings.
-(See Appendix B for a complete listing).
+(See
+.pdfhref L -D AppendixB Appendix B
+for a complete listing).
However, the registers used in
.CW ms
should give you a sufficient idea of the kinds of values
diff -uNBb a/front.t b/front.t
--- a/front.t 2004-06-15 03:54:30.000000000 +0100
+++ b/front.t 2013-01-12 19:31:30.384975268 +0000
@@ -6,8 +6,9 @@
.so utp.mac
.utp
.page iii
-.ps 200
+\Z@\D't 8p'@
.Hl
+\D't 0'
.sp .6i
.DS R
.ps 52
Common subdirectories: a/index and b/index
diff -uNBb a/ix.macro b/ix.macro
--- a/ix.macro 2003-07-28 02:07:15.000000000 +0100
+++ b/ix.macro 1970-01-01 01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-.de ix
-.ie '\\n(.z'' .tm ix: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 \\n%
-.el \\!.ix \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
diff -uNBb a/Makefile b/Makefile
--- a/Makefile 2003-07-29 04:26:26.000000000 +0100
+++ b/Makefile 2013-01-22 18:46:51.989146666 +0000
@@ -15,15 +15,15 @@
ch15.t ch16.t ch17.t ch18.t appa.t appb.t appc.t appd.t appe.t \
appf.t appg.t
-utp_book.ps: toc.t utp_ix.t
- $(GROFF) -step -ms -rRef=0 utp_book.t >[email protected]
+utp_book.pdf: toc.t utp_ix.t
+ $(GROFF) -Tpdf -P-e -P-pletter -step -ms -z -rpdf:bm.nr=1 -rRef=0 -dPDF.EXPORT=1 utp_book.t 2>&1 | grep '^.ds' | $(GROFF) -Tpdf -mpdfmark -P-pletter -P-e -step -ms -rRef=0 - utp_book.t >[email protected]
mv [email protected] $@
clean::
- rm -f utp_book.ps utp_book.ps.tmp
+ rm -f utp_book.pdf
toc.t: $(CHAPTERS)
- $(GROFF) -step -ms -rRef=1 ix.macro utp_book.t >/dev/null 2>utp.aux.tmp
+ $(GROFF) -Tpdf -P-e -P-pletter -z -step -rpdf:bm.nr=1 -ms -rRef=1 -wall utp_book.t >/dev/null 2>utp.aux.tmp
mv utp.aux.tmp utp.aux
$(AWK) -f toc.awk utp.aux >[email protected]
mv [email protected] $@
@@ -32,7 +32,7 @@
rm -f utp.aux.tmp utp.aux toc.t toc.t.tmp
utp_ix.t: $(CHAPTERS)
- cd index && ./make.index ../utp.aux >../[email protected]
+ ./mkindex.pl utp.aux > [email protected]
mv [email protected] $@
clean::
@@ -50,7 +49,6 @@
$(VIEW) x.ps
%.pdf : %.t
- groff -step -ms -rRef=0 $< > x.ps
- ps2pdf x.ps
+ groff -step -ms -rRef=0 -Tpdf $< > x.pdf
mv x.pdf $@
- $(VIEW) x.ps
+ $(VIEW) x.pdf
diff -uNBb a/Makefile.pdfroff b/Makefile.pdfroff
--- a/Makefile.pdfroff 1970-01-01 01:00:00.000000000 +0100
+++ b/Makefile.pdfroff 2013-01-22 19:33:56.811081246 +0000
@@ -0,0 +1,55 @@
+#
+# Makefile for _Unix Text Processing_
+#
+# 16 November 2002 - jcs
+#
+#
+# Set the next two lines for the paths for groff and awk on your system
+#
+GROFF = /usr/bin/groff
+AWK = /usr/bin/awk
+VIEW = gv
+
+CHAPTERS= front.t preface.t ch01.t ch02.t ch03.t ch04.t ch05.t \
+ch06.t ch07.t ch08.t ch09.t ch10.t ch11.t ch12.t ch13.t ch14.t \
+ch15.t ch16.t ch17.t ch18.t appa.t appb.t appc.t appd.t appe.t \
+appf.t appg.t
+
+utp_book-pdfroff.pdf: toc.t utp_ix.t
+ pdfroff -step -ms -mpdfmark -P-pletter --no-toc --emit-ps --no-kill-null-pages utp_book.t > @.tmp
+ perl -pe 's!\\f\(..|\\fP|\\f\[.+?\]!!g if m!OUT pdfmark!' @.tmp > utp_book-pdfroff.ps
+ ps2pdf -sPAPERSIZE=letter utp_book-pdfroff.ps && rm -f utp_book-pdfroff.ps @.tmp
+
+clean::
+ rm -f utp_book-pdfroff.pdf
+
+toc.t: $(CHAPTERS)
+ $(GROFF) -Tpdf -P-e -P-pletter -z -step -rpdf:bm.nr=1 -ms -rRef=1 -wall utp_book.t >/dev/null 2>utp.aux.tmp
+ mv utp.aux.tmp utp.aux
+ $(AWK) -f toc.awk utp.aux >[email protected]
+ mv [email protected] $@
+
+clean::
+ rm -f utp.aux.tmp utp.aux toc.t toc.t.tmp
+
+utp_ix.t: $(CHAPTERS)
+ ./mkindex.pl utp.aux > [email protected]
+ mv [email protected] $@
+
+clean::
+ rm -f utp_ix.t utp_ix.t.tmp
+#########################################################################
+# helpers to maintain single chapters
+# make ch03
+#########################################################################
+
+.SUFFIXES: .t .html .pdf
+
+% : %.t
+ groff -step -ms -rRef=0 $< > x.ps 2>ix.raw
+ $(VIEW) x.ps
+
+%.pdf : %.t
+ groff -step -ms -rRef=0 -Tpdf $< > x.pdf
+ mv x.pdf $@
+ $(VIEW) x.pdf
diff -uNBb a/mkindex.pl b/mkindex.pl
--- a/mkindex.pl 1970-01-01 01:00:00.000000000 +0100
+++ b/mkindex.pl 2013-01-10 23:32:01.198153816 +0000
@@ -0,0 +1,412 @@
+#!/usr/bin/perl -w
+#
+# mkindex.pl : Make index for UTP project
+# Deri James : Monday 07 Jan 2013
+#
+# Input file produced by .ix macro
+#
+
+use strict;
+use constant {
+ TXT => 0,
+ PAGE => 1,
+ LABEL => 2,
+ TYPE => 3,
+};
+
+my (%idx,%bkm,%wds,%ltr);
+
+while (<>)
+{
+ chomp;
+
+ next if ! s/^ix: //;
+
+ my (@r)=split("\t");
+
+ # clean
+
+ foreach (@r)
+ {
+ s/^ +//;
+ s/ +$//;
+ s/ +/ /g;
+ }
+
+ # deroman
+
+# $r[PAGE]=1000-from_roman($r[PAGE]) if $r[PAGE]=~m/^[ivxlc]+$/;
+
+ # range.prep
+
+ $r[TYPE]='a';
+ $r[TYPE]='b' if $r[TXT]=~s/\%begin //;
+ $r[TYPE]='e' if $r[TXT]=~s/\%end //;
+
+ # rotate
+
+ my (@tok,@keys);
+
+ if ($r[TXT]=~m/ %key /)
+ {
+ $tok[0]=$r[TXT];
+ }
+ else
+ {
+ (@tok)=split(' ',$r[TXT]);
+ }
+
+ foreach (@tok) {s/%~/QQ1QQ/g; tr/~/ /; s/QQ1QQ/%~/g;}
+
+ foreach my $j (0..$#tok)
+ {
+ my $key=join(' ',@tok[$j..$#tok]);
+ $key.=', '.join(' ',@tok[0..$j-1]) if $j>0;
+
+ if ($r[TYPE] eq 'a')
+ {
+ push(@{$idx{$key}->{DATA}},[$r[LABEL],$r[PAGE]]);
+ }
+ elsif ($r[TYPE] eq 'b')
+ {
+ $idx{$key}->{$r[TYPE]}=[$r[LABEL],$r[PAGE]];
+ }
+ else
+ {
+ if (exists($idx{$key}->{b}))
+ {
+ my $st=$idx{$key}->{b}->[1];
+ my $lab=$idx{$key}->{b}->[0];
+ $st.="\\[en]$r[PAGE]" if $r[PAGE] > $st;
+ push(@{$idx{$key}->{DATA}},[$lab,$st]);
+ delete($idx{$key}->{b});
+ }
+ else
+ {
+ print STDERR "No matching %begin record for key '$key'\n";
+ }
+ }
+ }
+}
+
+# see terms
+
+if (open(F,"<see.terms"))
+{
+ while (<F>)
+ {
+ chomp;
+
+ my (@r)=split("\t");
+
+ if ($r[2] and $r[2]=~m/\%also/)
+ {
+ push(@{$idx{"$r[0], {see also} $r[1]"}->{DATA}},[]);
+ }
+ else
+ {
+ push(@{$idx{"$r[0], {see} $r[1]"}->{DATA}},[]);
+ }
+ }
+
+ close(F);
+}
+
+# gen.key
+
+foreach my $key (keys %idx)
+{
+ my ($skey,$val);
+
+ if ($key=~m/^(.*) %key (.*)/)
+ {
+ $skey=$2;
+ $val=$1;
+ $skey=~tr'/''d;
+ }
+ else
+ {
+ $skey=Clean($key);
+ $val=$key;
+
+ }
+
+ $skey="!!$skey" if $skey=~m/^[^a-zA-Z]+$/;
+ $skey="!$skey" if $skey=~m/^[0-9]/;
+
+# $skey=lc($skey);
+ if (exists($bkm{$skey}))
+ {
+ push(@{$bkm{$skey}->{DATA}},@{$idx{$key}->{DATA}});
+ $bkm{$skey}->{CT}+=$#{$idx{$key}->{DATA}}+1;
+ print STDERR "Duplicate key '$skey' merged\n";
+ }
+ else
+ {
+ $bkm{$skey}->{DATA}=$idx{$key}->{DATA};
+ $bkm{$skey}->{CT}=$#{$idx{$key}->{DATA}}+1;
+ $bkm{$skey}->{AKEY}=$val;
+ }
+}
+
+foreach my $key (sort {lc($a) cmp lc($b)} keys %bkm)
+{
+ my $skey=$key;
+ $skey=~tr[,][]d;
+ my ($wd1,$wd2)=split(' ',$skey);
+ $wd2='' if !defined($wd2);
+ my $flt=substr($wd1,0,1);
+ my $typ=2;
+ my $txt=$bkm{$key}->{AKEY};
+
+ # types: 1="{see...}",2=normal,4="^[...]", 3="...[...]..."
+
+ if ($txt=~m/{see/)
+ {
+ $typ=1;
+ }
+ elsif ($txt=~m/^\[/)
+ {
+ $typ=4;
+ }
+ elsif ($txt=~m/\[.*\]/)
+ {
+ $typ=3;
+ }
+
+ my $nowds=split(' ',$txt);
+
+ $wd2=Clean($wd2);
+
+ $wds{$wd1}->[$typ]->{WCT}++,$wds{$wd1}->[$typ]->{MINWDS}=$nowds if !exists($wds{$wd1}->[$typ]->{WORDS}->{$wd2});
+ push(@{$wds{$wd1}->[$typ]->{WORDS}->{$wd2}},$bkm{$key});
+ $wds{$wd1}->[$typ]->{CT}++;
+ $wds{$wd1}->[$typ]->{MINWDS}=$nowds if $wds{$wd1}->[$typ]->{MINWDS} > $nowds;
+}
+
+my $lastflt='';
+
+print <<'EOF';
+.ig
+Index formatting macros, lifted from CSTR #128
+with slight changes to fit the UTP manual
+..
+.so utp.mac
+.\" Precedes each index term
+.de XX
+.br
+.ti -.2i
+.ne 2
+..
+.de ZZ
+.br
+..
+.\" Header between letters
+.de YY
+.sp 1.5
+.ne 3
+.ce
+- \\$1 -
+.sp .5
+..
+.Se "" "Index" NONE
+.af PN 1
+.nr PS 8
+.nr VS 9
+.\" Just do one column for nroff...
+.if t .2C
+.na
+.in .2i
+.hy 0
+EOF
+
+foreach my $key (sort {lc($a) cmp lc($b)} keys %wds)
+{
+ my $flt=lc(substr($key,0,1));
+
+ $lastflt=$flt,print ".YY $flt ",uc($flt),"\n" if ($flt ne $lastflt and $flt ne '!');
+
+ foreach my $j (1..4)
+ {
+ next if !defined($wds{$key}->[$j]);
+
+ my $wd=$wds{$key}->[$j];
+
+ if ($wd->{WCT}==1)
+ {
+ if ($wd->{CT}==1)
+ {
+ # simple entry - one word, one entry
+
+ doref($wd->{WORDS},'XX',0,0,0,0);
+ }
+ else
+ {
+ # multi...
+
+ if ($wd->{MINWDS} == 2)
+ {
+ # The 2 words match the keys
+
+ doref($wd->{WORDS},'XX',0,0,0,0);
+ doref($wd->{WORDS},'ZZ',2,1,9999,0);
+ }
+ else
+ {
+ # 2 words math, create a leader
+
+ doref($wd->{WORDS},'XX',0,0,0,2);
+ doref($wd->{WORDS},'ZZ',2,0,9999,0);
+ }
+ }
+ }
+ else
+ {
+ # Only 1 word match
+
+ if ($wd->{MINWDS} == 1 or exists($wd->{WORDS}->{''}))
+ {
+ # The words matches the keys
+
+ doref($wd->{WORDS},'XX',0,0,0,0);
+ doref($wd->{WORDS},'ZZ',1,1,9999,0);
+ }
+ else
+ {
+ # create a leader
+
+ doref($wd->{WORDS},'XX',0,0,0,1);
+ doref($wd->{WORDS},'ZZ',1,0,9999,0);
+ }
+
+ }
+ }
+}
+
+sub doref
+{
+ my $w=shift;
+ my $typ=shift;
+ my $drop=shift;
+ my $from=shift;
+ my $to=shift;
+ my $leader=shift;
+ my $outbuf=".$typ\n";
+ my $j=-1;
+
+ foreach my $key (sort {lc($a) cmp lc($b)} keys %{$w})
+ {
+ foreach my $e (@{$w->{$key}})
+ {
+ $j++;
+ next if $j < $from;
+ last if $j > $to;
+
+ my $ent=$e->{AKEY};
+
+ if ($drop or $leader)
+ {
+ my (@l)=split(' ',$ent);
+ $ent=join(' ',@l[0..$leader-1]) if $leader;
+ $ent=join(' ',@l[$drop..$#l]) if $drop;
+ }
+
+ $ent=~s/\[(.*?)\]/\\f[CW]$1\\f[P]/g;
+ $ent=~s/\{(.*?)\}/\\f[2]$1\\f[P]/g;
+
+ $ent=" $ent" if $typ eq 'ZZ';
+ $ent=~s/,+$//;
+
+ my $ref=$e->{DATA};
+ my $refct=0;
+ my $reftot=$#{$ref};
+
+ if (!$leader and $#{$ref->[0]} >= 0)
+ {
+ $outbuf.="$ent, \\c\n";
+ foreach my $r (@{$ref})
+ {
+ my $prefix='';
+
+ $prefix='-A ,' if $refct < $reftot;
+ $outbuf.=".pdfhref L -D $r->[0] $prefix -E -- $r->[1]\n";
+ $refct++;
+ }
+ }
+ else
+ {
+ $outbuf.="$ent\n";
+ }
+ }
+ }
+ print $outbuf;
+}
+
+sub Clean
+{
+ my $skey=shift;
+
+ $skey=~tr/_/0/;
+
+ my $quoted=0;
+
+ if ($skey=~m/%/)
+ {
+ $quoted=1;
+ $skey=~s/%%/QQ0QQ/g;
+ $skey=~s/%\[/QQ1QQ/g;
+ $skey=~s/%\]/QQ2QQ/g;
+ $skey=~s/%\{/QQ3QQ/g;
+ $skey=~s/%\}/QQ4QQ/g;
+ $skey=~s/%~/QQ5QQ/g;
+ }
+
+ $skey=~s/%e/\\/g; # implement troff escape
+ $skey=~s/~/ /g; # remove tildes
+ $skey=~tr'%()/[]{}''d; # remove % and font-changing []{}
+
+ if ($quoted)
+ { # restore literals but without escape charcter
+ $skey=~s/QQ0QQ/%/g;
+ $skey=~s/QQ1QQ/[/g;
+ $skey=~s/QQ2QQ/]/g;
+ $skey=~s/QQ3QQ/{/g;
+ $skey=~s/QQ4QQ/}/g;
+ $skey=~s/QQ5QQ/~/g;
+ }
+
+ return($skey);
+}
+
+my $end=1;
+
+my @trans = (
+ [M => 1000], [CM => 900],
+ [D => 500], [CD => 400],
+ [C => 100], [XC => 90],
+ [L => 50], [XL => 40],
+ [X => 10], [IX => 9],
+ [V => 5], [IV => 4],
+ [I => 1],
+);
+
+sub firstword
+{
+ my $wd=shift;
+
+ my ($ret)=split(' ',$wd,2);
+ $ret=~s/,//;
+ return $ret;
+}
+
+sub from_roman {
+ my $r = shift;
+ my $n = 0;
+ foreach my $pair (@trans) {
+ my ($k, $v) = @$pair;
+ $n += $v while $r =~ s/^$k//i;
+ }
+ return $n
+
+
+}
diff -uNBb a/see.terms b/see.terms
--- a/see.terms 1970-01-01 01:00:00.000000000 +0100
+++ b/see.terms 2013-01-10 17:39:56.513311965 +0000
@@ -0,0 +1,16 @@
+drawing [pic] preprocessor %also
+extensions to [ms] macros extended ms macros
+files, searching within [grep] %also
+formatting defaults, [mm] [mm] macros %also
+formatting defaults, [ms] [ms] macros %also
+graphics [pic] preprocessor %also
+integrals [eqn]
+keep and release displays %also
+macros [mm] and [ms] %also
+[mS] macros extended [ms] macros
+[nroff] formatter [troff] %also
+search [grep] %also
+subscripts [eqn] %also
+superscripts [eqn] %also
+[vi] editor, [ex] commands in [ex] %also
+[view] command [vi] editor
diff -uNBb a/toc.awk b/toc.awk
--- a/toc.awk 2003-07-28 02:07:15.000000000 +0100
+++ b/toc.awk 2013-01-11 21:30:58.991727280 +0000
@@ -7,24 +7,27 @@
print ".Se \"\" Contents NONE";
print ".af PN i";
print ".vs 12";
- print ".ta \\n(.luR";
+ print ".nr llen \\n(.lu-.25i";
+ print ".ta \\n[llen]uR";
print ".nf";
print ".sp 2"
}
/^Se:/ {
- if ( $4 == "Contents" )
+ if ( $5 == "Contents" )
next;
- gsub(/\\f\(CW/, "\\f\(CB" );
- gsub(/\\f\[CW\]/, "\\f\[CB\]" );
- gsub(/\\fC/, "\\f\[CB\]" );
+ gsub(/\\f\(CW/, "\\f[CB]" );
+ gsub(/\\f\(CB/, "\\f[CB]" );
+ gsub(/\\f\[CW\]/, "\\f[CB]" );
+ gsub(/\\fC/, "\\f[CB]" );
print ".ps 12\n.sp";
- print $3"\\h'|.25i'\\fB"$4"\\fR "$2;
+ print $4"\\h'|.25i'\\fB\\c";
+ print ".pdfhref L -D "$2" -E -- "$5"\t\\fR"$3;
print ".ps 10\n.sp";
}
/^Ah:/ {
- gsub(/\\f\(CB/, "\\f\(CW" );
- gsub(/\\f\[CB\]/, "\\f\[CW\]" );
- print "\\h'|.25i'"$3""$2;
+ gsub(/\\f\(CB/, "\\f[CW]" );
+ gsub(/\\f\[CB\]/, "\\f[CW]" );
+ print ".pdfhref L -D "$2" -P \\h'|.25i' -E -- "$4""$3;
}
# default (skip index entries)
{ next; }
diff -uNBb a/utp_book.t b/utp_book.t
--- a/utp_book.t 2003-07-29 04:25:47.000000000 +0100
+++ b/utp_book.t 2013-01-12 00:49:42.180412230 +0000
@@ -8,6 +8,14 @@
* Still a couple of minor warnings under groff 1.18
**************************************************************
..
+.nr ixno 0 1
+.ds PDFHREF.COLOUR 0.0 0.3 0.9
+.ds PDFHREF.TEXT.COLOUR pdf:href.colour
+.defcolor pdf:href.colour rgb \*[PDFHREF.COLOUR]
+.nr PDFOUTLINE.FOLDLEVEL 1
+.pdfinfo /Title Unix Text Processing
+.pdfinfo /Author Dale Dougherty and Tim O'Reilly
+.pdfview /PageMode /UseOutlines
.nr chapter_page2 1
.so front.t
.nr chapter_page2 1
@@ -95,3 +103,5 @@
.bp
.nr chapter_page2 1
.so utp_ix.t
+.pdfsync
+
diff -uNBb a/utp.mac b/utp.mac
--- a/utp.mac 2003-07-28 02:07:15.000000000 +0100
+++ b/utp.mac 2013-01-22 19:35:24.159533458 +0000
@@ -55,6 +55,7 @@
.de utp_Ah
.sp 26p
.RT
+.pdfbookmark 2 \\$1
.ne 6
.ps 14
.vs 16
@@ -65,7 +66,7 @@
.lg
.sp 18p
.ns
-.if \\n[Ref] .tm Ah: \\n(PN \\$1
+.if \\n[Ref] .tm Ah: \\*[PDFBOOKMARK.NAME] \\n(PN \\$1
..
\#
\# The [ABCD]-head macros
@@ -95,6 +96,7 @@
\#
.de Bh \" B-head. $1: title
.sp 23p
+.pdfbookmark 3 \\$1
.RT
.ne 6
.ps 14
@@ -163,6 +165,7 @@
.\}
.ds chapter_name \\$2
.ie !'\\$1'' \{. \" If we have a section number
+. utpbookmark -T "\\$3\\$1" 1 "\\$1. \\$2"
. ds chapter_head \\$1
. nr is_alpha 0
. if '\\$1'A' .set_section 1
@@ -198,6 +201,7 @@
.\}
.el \{. \" Illegal Chapter Appendix number
. nr section 0
+. utpbookmark -T \\$2 1 \\$2
. \" Might be Preface, etc. so no error diag.
.\}
.nr chapter_page2 1 \" Next page starts a chapter, so no header
@@ -215,10 +219,10 @@
.nr table_num 0 \" Reset table number
.format_section "\\$1" "\\$2" \\$3 \\$4
.ie '\\$1'' \{\
-.ie '\\$2'' .if \\n[Ref] .tm Se: \\n(PN \\$3
-.el .if \\n[Ref] .tm Se: \\n(PN \\$1 \\$2
+.ie '\\$2'' .if \\n[Ref] .tm Se: \\*[PDFBOOKMARK.NAME] \\n(PN \\$3
+.el .if \\n[Ref] .tm Se: \\*[PDFBOOKMARK.NAME] \\n(PN \\$1 \\$2
.\}
-.el .if \\n[Ref] .tm Se: \\n(PN \\$1 \\$2
+.el .if \\n[Ref] .tm Se: \\*[PDFBOOKMARK.NAME] \\n(PN \\$1 \\$2
..
\#
\# Set section number for alphabet chapters (appendices)
@@ -695,6 +699,16 @@
'po \\n[PO]u
'sp |\\n[page-end]u
..
+.de ix
+.ie '\\n(.z'' \{\
+. if !'\\$1'%end' \{\
+. ds ixbk ix:bm\\n+[ixno]
+. pdfhref M -N \\*[ixbk]
+. \}
+. if \\n[Ref] .tm ix: \\$* \\n% \\*[ixbk]
+.\}
+.el \\!.ix \\$*
+..
\#
\# Set defaults for UTP
\#
@@ -717,5 +731,12 @@
.vs \\n[VS]
.ev
..
+.de utpbookmark
+.ie '\\*[.T]'ps' \{\
+. pdfhref M -N \\$2 -- \\$4
+. if !dpdf:href.map .tm gropdf-info:href \\$2 \\$4
+. pdfbookmark \\$3 \\$4
+.\}
+.el .pdfbookmark \\$*
+..
.em EM
-
--- a/contrib/pdfmark/pdfmark.tmac 2010-12-23 21:24:53.000000000 +0000
+++ b/contrib/pdfmark/pdfmark.tmac 2012-06-11 11:49:35.000000000 +0100
@@ -110,7 +110,7 @@
. \"
. \" This PDFMARK is suitable for single chunk output ...
. \"
-. nop \X'ps:exec [\\$* pdfmark'\c
+. nop \!x X ps:exec [\\$* pdfmark
. \}
. el \{\
. \" ... but, when the limit would be violated, then we must