summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorAlejandro Colomar <alx@kernel.org>2023-12-01 00:55:11 +0100
committerAlejandro Colomar <alx@kernel.org>2023-12-01 14:13:35 +0100
commit6d87a75a6df0696e780255d865bf65da09f36f01 (patch)
tree29ba88f56caa7af21d4f264e753aeaafbc2f198b /scripts
parent6b3b989bd81f42caf41d17728566a570da3bfaf6 (diff)
scripts/LinuxManBook/: Simplify pipeline
Call the groff(1) pipeline only once. This optimizes around 2 seconds, while also simplifying the code. This change was originally written by Deri, with some parts written by Brian. I took the script that Deri sent, and split it so that the groff(1) pipeline is called from the shell script, and the Perl script is limited to editing the man(7) pages. This helps me understand the process, since my understanding of Perl is very limited. It also makes this change smaller, so that it's less of a big-bang. Link: <https://lore.kernel.org/linux-man/ZWkO4qPC4BxkwBNm@debian/T/#m3d453440b02dd189bc12d2e629c4026206025b40> Co-developed-by: Deri James <deri@chuzzlewit.myzen.co.uk> Co-developed-by: Brian Inglis <Brian.Inglis@Shaw.ca> Signed-off-by: Alejandro Colomar <alx@kernel.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/LinuxManBook/LMBfront.roff (renamed from scripts/LinuxManBook/LMBfront.ms)23
-rw-r--r--scripts/LinuxManBook/anmark.tmac4
-rwxr-xr-xscripts/LinuxManBook/build.sh18
-rwxr-xr-xscripts/LinuxManBook/prepare.pl174
-rw-r--r--scripts/LinuxManBook/utp.mac742
5 files changed, 110 insertions, 851 deletions
diff --git a/scripts/LinuxManBook/LMBfront.ms b/scripts/LinuxManBook/LMBfront.roff
index c034dd58a..fdf1a9820 100644
--- a/scripts/LinuxManBook/LMBfront.ms
+++ b/scripts/LinuxManBook/LMBfront.roff
@@ -1,6 +1,3 @@
-.ig
- front.t
-..
.de Hl
.br
\l'\\n[.l]u-\\n[.i]u\&\\$1'
@@ -8,31 +5,29 @@
..
.ps 10
.vs 12
-.nr PS 10
-.nr VS 12
-.nr SS_prefix 1v
-.nr do-page 0
-.Nh 0 0
-.\" .so utp.mac
-.\" .utp
+.po 2c
+.ll 17c
+.sp 2.5c
\Z@\D't 8p'@
.Hl
\D't 0'
.sp .6i
-.DS R
+.ad r
.ps 52
\m[maroon]GNU/Linux\m[]
.sp 18p
.ps 16
\f[BMB]THE MAN-PAGES BOOK\fP
-.sp 30p
-.sp 1.4i
+.sp 6i
.ps 12
\f[HB]Maintainers:\fP
.sp 2p
.ps 10
\f[HB]Alejandro Colomar <alx@kernel.org> 2020 - present (5.09 - HEAD)
+.brp
Michael Kerrisk <mtk.manpages@gmail.com> 2004 - 2021 (2.00 - 5.13)
+.brp
Andries Brouwer <aeb@cwi.nl> 1995 - 2004 (1.6 - 1.70)
+.brp
Rik Faith 1993 - 1995 \0(1.0 - 1.5)\fP
-.DE
+.bp
diff --git a/scripts/LinuxManBook/anmark.tmac b/scripts/LinuxManBook/anmark.tmac
deleted file mode 100644
index 9bf4e168b..000000000
--- a/scripts/LinuxManBook/anmark.tmac
+++ /dev/null
@@ -1,4 +0,0 @@
-.nr PDFOUTLINE.FOLDLEVEL 1
-.defcolor pdf:href.colour rgb 0.00 0.25 0.75
-.pdfinfo /Title "The Linux man-pages Book"
-.special S TINOR
diff --git a/scripts/LinuxManBook/build.sh b/scripts/LinuxManBook/build.sh
index a6e578f64..8e373c073 100755
--- a/scripts/LinuxManBook/build.sh
+++ b/scripts/LinuxManBook/build.sh
@@ -3,25 +3,13 @@
# SPDX-License-Identifier: GPL-3.0-or-later
(
- "$(dirname "$0")"/prepare.pl "$1" \
- | preconv \
- | pic \
- | tbl \
- | eqn -Tpdf \
- | troff -Tpdf -dPDF.EXPORT=1 -dLABEL.REFS=1 -dpaper=a4 \
- -M"$(dirname "$0")" -mandoc -manmark -rC1 -rCHECKSTYLE=3 \
- 2>&1 >/dev/null \
- | LC_ALL=C grep '^\. *ds ';
-
+ cat "$(dirname "$0")"/LMBfront.roff;
+ cat "$(dirname "$0")"/an.tmac;
"$(dirname "$0")"/prepare.pl "$1";
) \
| preconv \
| pic \
| tbl \
| eqn -Tpdf \
-| (
- troff -Tpdf -ms <"$(dirname "$0")"/LMBfront.ms;
- troff -Tpdf -M"$(dirname "$0")" -mandoc -manmark \
- -F"$(dirname "$0")" -dpaper=a4;
-) \
+| troff -Tpdf -F"$(dirname "$0")" -dpaper=a4 \
| gropdf -F"$(dirname "$0")" -pa4;
diff --git a/scripts/LinuxManBook/prepare.pl b/scripts/LinuxManBook/prepare.pl
index 5a4aad429..d42941856 100755
--- a/scripts/LinuxManBook/prepare.pl
+++ b/scripts/LinuxManBook/prepare.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
#
-# BuildLinuxMan.pl : Build Linux manpages book
-# Deri James : 15 Dec 2022
+# BuildLinuxMan.pl : Build Linux manpages book
+# Deri James (& Brian Inglis) : 15 Dec 2022
#
# Params:-
#
@@ -22,11 +22,8 @@
#
use strict;
+use File::Basename;
-my $dir=shift || '.';
-my @aliases=`egrep -l '^\\.so' $dir/man*/*`;
-my %alias;
-my %target;
my $inTS=0;
my $inBlock=0;
@@ -47,81 +44,66 @@ my %Sections=
"9" => "Kernel Developer's Manual",
);
-my $Section='';
+my $dir=shift || '.';
+my $dir2=$dir;
+$dir2=~tr[.][_];
+my %files;
+my %aliases;
+my %target;
-LoadAlias();
-BuildBook();
+foreach my $al (`grep -E '^\\.so' $dir/man*/*`)
+{
+ #$al=~tr[.][_];
+ $al=~m/^$dir\/man\d[a-z]*\/(.*):\.\s*so\s*man\d[a-z]*\/(.*)/o;
-# Aliases are the man pages which .so another man page, so build a hash of them so
-# that when we are processing referenced man page we can add the target for the
-# bookmark.
+ $aliases{$1}=$2;
+}
-sub LoadAlias
+foreach my ($k,$v) (%aliases)
{
- foreach my $fn (@aliases) {
- chomp($fn);
- my (@pth)=split('/',$fn);
- my $nm=pop(@pth);
- my $bkmark="$1_$2" if $nm=~m/(.*)\.(\w+)/;
-
- if (open(F,"<$fn")) {
- while (<F>) {
- next if m/^\.\\"/;
-
- if (m/^.so\s+(man\w+\/(.+)\.(.+?))$/) {
- $alias{$bkmark}=["$2_$3",$2,$3];
- push(@{$target{"$2_$3"}},$bkmark);
- last;
- } else {
- print STDERR "Alias fail: $fn\n";
- }
- }
-
- close(F);
- } else {
- print STDERR "Open fail: $fn\n";
- }
+ while (exists($aliases{$v})) {
+ $v=$aliases{$v};
}
}
-sub BuildBook
+foreach my $fn (glob "$dir/man*/*")
{
- print ".pdfpagenumbering D . 1\n";
-
- foreach my $fn (sort glob("$dir/man*")) {
- BuildSec($fn);
- }
+ my ($nm,$sec)=GetNmSec($fn,qr/\.\d[a-z]*/);
+ $files{"${nm}.$sec"}=[$fn,(exists($aliases{"${nm}.$sec"}))?$aliases{"${nm}.$sec"}:"${nm}.$sec"];
}
-sub BuildSec
+my $Section='';
+
+BuildBook();
+
+sub BuildBook
{
- my $manSdir=shift;
+ print ".pdfpagenumbering D . 1\n.nr PDFOUTLINE.FOLDLEVEL 0\n.defcolor pdf:href.colour rgb 0.00 0.25 0.75\n.pdfinfo /Title \"The Linux man-pages Book\"\n.special TINOR S\n";
- foreach my $fn (sort sortman glob("$manSdir/*")) {
- BuildPage($fn);
+ foreach my $bkmark (sort sortman keys %files) {
+ BuildPage($bkmark);
}
}
sub BuildPage
{
- my $page=shift;
+ my $bkmark=shift;
- my ($nm,$sec,$srt)=GetNmSec($page);
+ my $fn=$files{$bkmark}->[0];
+ my ($nm,$sec,$srt)=GetNmSec($bkmark,qr/\.[\da-z]+/);
- my $bkmark="$1_$2" if $nm=~m/(.*)\.(\w+)/;
- my $title= "$1\\($2\\)";
+ my $title= "$nm\\($sec\\)";
+
+ print ".\\\" >>>>>> $nm($sec) <<<<<<\n.lf 0 $bkmark\n";
# If this is an alias, just add it to the outline panel.
- if (exists($alias{$bkmark})) {
- print ".eo\n.device ps:exec [/Dest /$alias{$bkmark}->[0] /Title ($title) /Level 2 /OUT pdfmark\n.ec\n";
- print ".if dPDF.EXPORT .tm .ds pdf:look($bkmark) $alias{$bkmark}->[1]($alias{$bkmark}->[2])\n";
+ if (exists($aliases{$bkmark})) {
+ print ".eo\n.device ps:exec [/Dest /$aliases{$bkmark} /Title ($title) /Level 2 /OUT pdfmark\n.ec\n.fl\n";
return;
}
- print ".\\\" >>>>>> $1($2) <<<<<<\n.lf 0 $bkmark\n";
-
- if (open(F,'<',$page)) {
+ if (open(F,'<',$fn)) {
while (<F>) {
if (m/^\.\\"/) {
print $_;
@@ -139,13 +121,22 @@ sub BuildPage
next if !$_;
# s/^\s+//;
- if (m/^\.BR\s+([-\w\\.]+)\s+\((.+?)\)(.*)/) {
+ s/\\-/-/g if /^\.[BM]R\s+/;
+
+ if (m/^\.BR\s+([-\w\\.]+)\s+\((.+?)\)(.*)/ or m/^\.MR\s+([-\w\\.]+)\s+(\w+)\s+(.*)/) {
my $bkmark="$1";
my $sec=$2;
my $after=$3;
+ $after=~s/\s\\".*//;
my $dest=$bkmark;
$dest=~s/\\-/-/g;
- $_=".MR \"$bkmark\" \"$sec\" \"$after\" \"$dest\"";
+
+ if (exists($files{"${bkmark}.$sec"})) {
+ my $dest=$files{"${bkmark}.$sec"}->[1];
+ $_=".pdfhref L -D \"$dest\" -A \"$after\" -- \\fI$bkmark\\fP($sec)";
+ } else {
+ $_=".IR ".substr($_,4);
+ }
}
s/^\.BI \\fB/.BI /;
@@ -162,7 +153,7 @@ sub BuildPage
$inBlock+=()=$c=~m/T\{/g;
$inBlock-=()=$c=~m/T\}/g;
- my $mtch=$c=~s/\s*\\fB([-\w.]+)\\fP\((\w+)\)/\n.MR $1 $2 \\c\n/g;
+ my $mtch=$c=~s/\s*\\fB([-\w.]+)\\fP\((\w+)\)/doMR($1,$2)/ge;
$c="T{\n${c}\nT}" if $mtch and !$inBlock;
}
@@ -171,25 +162,23 @@ sub BuildPage
}
if (m/^\.TH\s+([-\w\\.]+)\s+(\w+)/) {
+
# if new section add top level bookmark
+
if ($sec ne $Section) {
- print ".nr PDFOUTLINE.FOLDLEVEL 1\n.fl\n";
+ print ".nr PDFOUTLINE.FOLDLEVEL 1\n";
print ".pdfbookmark 1 $Sections{$sec}\n";
print ".nr PDFOUTLINE.FOLDLEVEL 2\n";
$Section=$sec;
}
+
print "$_\n";
# Add a level two bookmark. We don't set it in the TH macro since the name passed
# may be different from the filename, i.e. file = unimplemented.2, TH = UNIMPLEMENTED 2
- print ".pdfbookmark -T $bkmark 2 $1($2)\n";
- # If this page is referenced by an alias plant a destination label for the alias.
- if (exists($target{$bkmark})) {
- foreach my $targ (@{$target{$bkmark}}) {
- print ".pdf*href.set $targ\n";
- }
- }
+ print ".pdfbookmark -T $bkmark 2 $nm($sec)\n";
+
next;
}
print "$_\n";
@@ -198,27 +187,60 @@ sub BuildPage
}
}
+sub doMR
+{
+ my $nm=shift;
+ my $sec=shift;
+
+ if (exists($files{"${nm}.$sec"})) {
+ return("\n.pdfhref L -D \"$files{\"${nm}.$sec\"}->[1]\" -A \"\\c\" -- \\fI$nm\\fP($sec)\n");
+ } else {
+ return("\\fI$nm\\fP($sec)");
+ }
+}
+
sub GetNmSec
{
- my (@pth)=split('/',shift);
- my $nm=pop(@pth);
- my $sec=substr(pop(@pth),3);
+ my ($nm,$pth,$sec)=fileparse($_[0],$_[1]);
+ $sec=substr($sec,1);
my $srt=$nm;
+ $srt=~s/\..+?$//;
$srt=~s/^_+//;
- $srt="$sec/$srt";
+ $srt=$1.sprintf("%04d",$2) if $srt=~m/^(.+)(\d+)$/;
+ #$srt="$sec/$srt";
return($nm,$sec,$srt);
}
+# add rpmvercmp
+#use RPM::VersionSort;
+#use Sort::Versions;
+
sub sortman
{
# Sort - ignore case but frig it so that intro is the first entry.
- my (undef,$s1,$c)=GetNmSec($a);
- my (undef,$s2,$d)=GetNmSec($b);
+ my (undef,$s1,$c)=GetNmSec($a,qr/\.\d[a-z]*/);
+ my (undef,$s2,$d)=GetNmSec($b,qr/\.\d[a-z]*/);
my $cmp=$s1 cmp $s2;
+
return $cmp if $cmp;
- return -1 if ($c=~m/\/intro/ and $d!~m/\/intro/);
- return 1 if ($d=~m/\/intro/ and $c!~m/\/intro/);
- return (lc($c) cmp lc($d));
+ return -1 if ($c=~m/^intro/ and $d!~m/^intro/);
+ return 1 if ($d=~m/^intro/ and $c!~m/^intro/);
+ $c=~tr[-_(][!" ];
+ $d=~tr[-_(][!" ];
+ $cmp=lc($c) cmp lc($d);
+ return($c cmp $d) if $cmp == 0;
+ return($cmp);
+}
+
+sub strhex
+{
+ my $res='';
+
+ foreach my $c (split('',$_[0])) {
+ $res.=sprintf("%02X",ord($c));
+ }
+
+ return($res);
}
diff --git a/scripts/LinuxManBook/utp.mac b/scripts/LinuxManBook/utp.mac
deleted file mode 100644
index ed9027ab7..000000000
--- a/scripts/LinuxManBook/utp.mac
+++ /dev/null
@@ -1,742 +0,0 @@
-.ig
-vim:syntax=off
-
-Macros for typesetting _Unix Text Processing_.
-Based on the macros from Chapter 17 and Appendix F
-of that book.
-
-Adapted by Jon Snader as part of a project to make this classic
-book available again.
-
-Version of 16 November 2002
-..
-.RT
-.nr nH 0 \" don't number [ABCD]-heads
-.nr gE 0 \" don't add chapter number to [ABCD]-heads
-.nr chapter_page 0 \" avoid diag. if there's no .Se call
-.ds chapter_name
-\#
-\# Redefine LP so that it can take an argument to suppress spacing
-\#
-.de par*start*nospace
-.ds@auto-end
-.nr \\n[.ev]:pli \\$1
-.nr \\n[.ev]:pri \\$2
-.par@reset
-.ne 1v+\\n(.Vu
-..
-.de LP \"Non indented paragraph. Don't skip space if \\$1 == 0
-.ie '\\$1'0' .par*start*nospace 0 0
-.el .par*start 0 0
-.nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
-..
-\#
-\# Nh - set behavior of numbered headings
-\# $1:
-\# 0 - no numbering
-\# 1 - number all headings
-\# 2 - number A-head only
-\#
-\# $2 (if present):
-\# 0 - don't add section numbers to headers
-\# 1 - prefix headers with section number
-\#
-.de Nh
-. nr nH \\$1
-. if !'\\$2'' .nr gE \\$2
-..
-\#
-\# Square centered vertically
-\#
-.ds square \v'-.25v'\s6\(sq\s0\v'.25v'
-\#
-\# Special A-head for UTP
-\#
-.de utp_Ah
-.sp 26p
-.RT
-.pdfbookmark 2 \\$1
-.ne 6
-.ps 14
-.vs 16
-.lg 0
-.ce
-\fB\*[square] \\$1 \*[square]\fP
-.LP 0
-.lg
-.sp 18p
-.ns
-.if \\n[Ref] .tm Ah: \\*[PDFBOOKMARK.NAME] \\n(PN \\$1
-..
-\#
-\# The [ABCD]-head macros
-\#
-.de standard_Ah \" A-head. $1: title
-.sp 26p
-.RT
-.ne 6
-.ps 14
-.vs 16
-.lg 0
-.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
-\fB\c
-.if \\n[nH] \{. \"if producing numbered headings
-. ie \\n[gE] .sec# 2 \" if Se (chapter) macro is
-. \" numbered, then this is on the second level
-. el .sec# 1 \" otherwise it's on the first level
-.\}
-\&\\$1\fP
-.LP 0 \" reset paragraph, but not font size, etc.
-.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz
-.lg
-.sp 18p
-.ns
-..
-.als Ah standard_Ah
-\#
-.de Bh \" B-head. $1: title
-.sp 23p
-.pdfbookmark 3 \\$1
-.RT
-.ne 6
-.ps 14
-.vs 16
-.lg 0
-\fB\c
-.if '\\n[nH]'1' \{. \"if producing numbered headings
-. ie \\n[gE] .sec# 3 \" if Se (chapter) macro is
-. \" numbered, then this is on the third level
-. el .sec# 2 \" otherwise it's on the second level
-.\}
-\&\\$1\fP
-.LP 0 \" reset paragraph, but not font size, etc.
-.lg
-.sp 15.5p
-.ns
-..
-\#
-.de Ch \" C-head. $1: title
-.sp 18p
-.RT
-.ne 6
-.ps 12
-.vs 14
-.lg 0
-\fB\c
-.if '\\n[nH]'1' \{. \"if producing numbered headings
-. ie \\n[gE] .sec# 4 \" if Se (chapter) macro is
-. \" numbered, then this is on the fourth level
-. el .sec# 3 \" otherwise it's on the third level
-.\}
-\&\\$1\fP
-.LP 0 \" reset paragraph, but not font size, etc.
-.lg
-.sp 12p
-.ns
-..
-\#
-.de Dh \" D-head. $1: title
-.sp 18p
-.RT
-.ne 6
-.ps 10
-.vs 12
-.lg 0
-\fB\c
-.if '\\n[nH]'1' \{. \"if producing numbered headings
-. ie \\n[gE] .sec# 5 \" if Se (chapter) macro is
-. \" numbered, then this is on the fifth level
-. el .sec# 4 \" otherwise it's on the fourth level
-.\}
-\&\\$1.\fP
-.lg
-..
-\#
-\# The Section macro
-\#
-\# This is for Chapters and Appendices
-\#
-.de Se \" Section. $1: number, $2: name
-. \" $3: type (Chapter, Appendix, ...)
-. \" $4: non-null => don't map to uppercase
-.if e \{\
-\&
-.bp
-.\}
-.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
-. if '\\$1'B' .set_section 2
-. if '\\$1'C' .set_section 3
-. if '\\$1'D' .set_section 4
-. if '\\$1'E' .set_section 5
-. if '\\$1'F' .set_section 6
-. if '\\$1'G' .set_section 7
-. if '\\$1'H' .set_section 8
-. if '\\$1'I' .set_section 9
-. if '\\$1'J' .set_section 10
-. if '\\$1'K' .set_section 11
-. if '\\$1'L' .set_section 12
-. if '\\$1'M' .set_section 13
-. if '\\$1'N' .set_section 14
-. if '\\$1'O' .set_section 15
-. if '\\$1'P' .set_section 16
-. if '\\$1'Q' .set_section 17
-. if '\\$1'R' .set_section 18
-. if '\\$1'S' .set_section 19
-. if '\\$1'T' .set_section 20
-. if '\\$1'U' .set_section 21
-. if '\\$1'V' .set_section 22
-. if '\\$1'W' .set_section 23
-. if '\\$1'X' .set_section 24
-. if '\\$1'Y' .set_section 25
-. if '\\$1'Z' .set_section 26
-. if !\\n[is_alpha] \{\
-. nr section \\$1
-. nr intH1 \\$1
-. \}
-.\}
-.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
-.if \\n[%]>1 .bp
-.nr PN \\n[%]
-.ie '\\$3'NONE' .af PN i
-.el .af PN 1
-.nr chapter_page 1 \" This page starts a chapter, number at bottom
-.if !\\n[gE] .nr intH1 0
-.nr intH2 0 \" rescind lower level numbering
-.nr intH3 0
-.nr intH4 0
-.nr intH5 0
-.nr fig_num 0 \" Reset figure number
-.nr table_num 0 \" Reset table number
-.format_section "\\$1" "\\$2" \\$3 \\$4
-.ie '\\$1'' \{\
-.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: \\*[PDFBOOKMARK.NAME] \\n(PN \\$1 \\$2
-..
-\#
-\# Set section number for alphabet chapters (appendices)
-\#
-.de set_section
-.nr intH1 \\$1
-.af intH1 A
-.nr section \\$1
-.nr is_alpha 1
-..
-\#
-\# Draw a horizontal line
-\#
-.de horizontal_line
-.br
-\l'\\n[.l]u-\\n[.i]u\&\\$1'
-.br
-..
-.als Hl horizontal_line
-\#
-\# Standard Section Formatting Routine
-\#
-.de format_standard_section
-.RT
-.in 0
-.lg 0
-.if '\\$4'' .tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
-.sp
-.na
-.\" Set section type--default is Chapter
-.ie !'\\$3'' \{\
-. ie '\\$3'NONE' .ds chapter_type
-. el .ds chapter_type \\$3
-.\}
-.el .ds chapter_type Chapter
-.\" If there is a section number, output Type and section number
-.if !'\\$1'' \s14\fB\\*[chapter_type] \\$1\fP\s0
-.\" If there is no section number, but there is a type, then output it
-.if '\\$1'' .if !'\\$3'' \s14\fB\\*[chapter_type]\fP\s0
-.sp 5p
-.\" Print the section title if there is one
-\#.if !'\\$2'' \s14\fB\\$2\fP\s0
-.if !'\\$2'' \{\
-.ps 14
-.B
-\&\\$2
-.R
-.ps \\n[PS] \" Reset to PS in case of inline \s
-.\}
-.sp 6p
-.ad b \" Adjust both margins
-.horizontal_line \" Draw horizontal line
-.if '\\$4'' .tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz
-.sp 3
-.ns
-..
-.als format_section format_standard_section
-\#
-\# numbered header Macros
-\# Special version of NH to generate just the string
-\# Used internally.
-\#
-.de sec#
-.nr NS \\$1 \" Current level
-.if !\\n[.$] .nr NS 1 \" Default is level 1
-.if !\\n[NS] .nr NS 1 \" In case it's NULL or negative
-.nr intH\\n[NS] +1 \" Increment count on current level
-.\" Rescind lower levels
-.if !\\n[NS]-4 .nr intH5 0
-.if !\\n[NS]-3 .nr intH4 0
-.if !\\n[NS]-2 .nr intH3 0
-.if !\\n[NS]-1 .nr intH2 0
-.\" Build up the string
-.if !\\$1 .if \\n[.$] .nr intH1 1
-.ds SN \\n[intH1]
-.ie \\n[NS]-1 .as SN .\\n[intH2]
-.el .as SN . \" either x.y or x.
-.if \\n[NS]-2 .as SN .\\n[intH3]
-.if \\n[NS]-3 .as SN .\\n[intH4]
-.if \\n[NS]-4 .as SN .\\n[intH5]
-'ti \\n[.i]u
-\\*[SN] \" print answer
-..
-\#
-\# Figure start and end macros
-\#
-.de Fs \" start figure $1: reserved space $2: float figure
-.RT
-.ie 'F'\\$2' \{. \" if figure can float
-. nr floating_keep 1
-. KF
-.\}
-.el .nr floating_keep 0
-.if !'\\$1'' \{. \" if space specified
-. ne \\$1
-. fl
-. rs
-. sp \\$1
-.\}
-..
-.de Fe \" end figure $1: title
-.sp
-.nr fig_num +1 \" increment figure counter
-.ie \\n[section] .ds figure \\*[chapter_head].\\n[fig_num]
-.el .ds figure \\n[fig_num]
-.ce
-\f[BI]Figure \\*[figure] \\$1\fP
-.sp
-.if \\n[floating_keep] .KE
-..
-\#
-\# Table start and end macros
-\#
-.de Ts \" table start $1: title
-.nr table_num +1 \" increment table number
-.ie \\n[section] .ds table \\*[chapter_head].\\n[table_num]
-.el .ds table \\n[table_num]
-.sp
-.ce
-\f[BI]Table \\*[table] \\$1\fP
-.LP
-..
-.de Te
-.RT
-.sp
-..
-\#
-\# Numbered lists
-\#
-.nr l0 0 1
-.de Ls
-.\" list start $1: A - ALPHA
-.\" a - alpha
-.\" B - bullet
-.\" N - numeric
-.\" R - ROMAN NUMERALS
-.\" r - roman numerals
-.\" $2: indent
-.\" $3: alternate bullet character
-.br
-.if !'\\$1'A' .if !'\\$1'a' .if !'\\$1'B' .if !'\\$1'N' \
-. if !'\\$1'R' .if !'\\$1'r' .if !'\\$1'' \
-. tm Ls: Need A, a, B, N, R, or r as type
-.nr l\\n+[l0] 0 1
-.ie '\\$1'' \{. \" set defaults
-. if '\\n[l0]'1' .af l\\n[l0] 1 \"numeric at 1st level
-. if '\\n[l0]'2' .af l\\n[l0] a \"alpha at 2nd level
-. if '\\n[l0]'3' .af l\\n[l0] i \"roman at 3rd level
-. if '\\n[l0]'4' .ds l\\n[l0] \(bu \"bullet at 4th level
-. if '\\n[l0]'5' .ds l\\n[l0] \- \"dash at 5th level
-. if \\n[l0]-5 .ds l\\n[l0] \(bu \"bullet above 5th level
-. if \\n[l0]-3 .nr l\\n[l0] 0-1 \"mark bullet and dash as non-incrementing
-.\}
-.el \{\
-. if '\\$1'A' .af l\\n[l0] A
-. if '\\$1'a' .af l\\n[l0] a
-. if '\\$1'B' \{\
-. ie '\\$3'' .ds l\\n[l0] \(bu
-. el .ds l\\n[l0] \\$3
-. nr l\\n[l0] 0-1 \"mark as non-incrementing
-. \}
-. if '\\$1'R' .af l\\n[l0] I
-. if '\\$1'r' .af l\\n[l0] i
-.\}
-.ie !'\\$2'' .nr i\\n[l0] \\$2 \"set list indent
-.el .nr i\\n[l0] 5 \"default indent
-.RS
-..
-.de Li \" List start $1 == 0: no blank line preceding
-.br
-.if '\\$1'0' .ns
-.ie '\\n[l\\n[l0]]'-1' .intIP "\\*[l\\n[l0]]" "\\n[i\\n[l0]]"
-.el \{\
-. nr l\\n[l0] +1
-. intIP "\\n[l\\n[l0]]." "\\n[i\\n[l0]]"
-.\}
-..
-.de Le \" List end $1 == 0: no blank line after
-.br
-.rr l\\n[l0] \" remove number registers
-.rr i\\n[l0]
-.rm l\\n[l0] \" and string register, if any
-.nr l0 -1 \" back one level of nesting
-.RE
-.ie !\\n[l0] \{\
-. ie '\\$1'0' .LP 0
-. el .LP
-.\}
-.el .if !'\\$1'0' .sp \\n[PD]u
-..
-\#
-\# intIP - internal version of IP that centers tag
-\#
-.de intIP
-.sp \\n[PD]u
-.in \\n[\\n[.ev]:il]u*\\n[PI]u-\\n[PI]u+\\$2n
-.nr indent1 \\$2n/2u+\w'\\$1' \" amount to move left
-\#.nr indent2 \\$2n+\w'\\$1' \" amount to move back
-\#.ta \\n[indent2]u
-.ta \\n[indent1]u
-.ti -\\n[indent1]u
-\\$1\t\c
-..
-\#
-\# Printout and listing macros
-\#
-.ev printout \" set up the listing environment
-.ns
-.ps 9
-.vs 10
-.ft C
-.nf
-.ev
-.de Ps \" printout start $1: indent
-.br
-.ev printout
-.sp \\n[PD]u
-.ie !'\\$1'' .in +\\$1n
-.el .in +5n
-..
-.de Pe \" printout end $1: non-null => no following space
-.br
-.if '\\$1'' .sp \\n[PD]u
-.in
-.ev
-..
-\#
-\# X[1-4]: Side by side virtual display screens
-\# Contributed by Heinz-Jürgen Oertel
-\#
-.\" Macro definition
-.\" window width
-.\" Should be calculated, so that the width is 25 equal spaced chars
-.nr my_wid \w'\f(CW12345678901234567890123456\fP'
-.de X1
-.sp
-.mk x_box
-.nf
-.\" left and right page offset
-.po +(u;\\n[.ll]/40)
-.ll \n[my_wid]u
-.in +1n
-.CW
-..
-.de X2
-.mk here
-.in -1n
-.draw_screen \n[my_wid]u \\n[here]u-\\n[x_box]u+\\n[.v]u
-.po +(u;\n[my_wid])
-.\" line length of the centered text
-.ll (u;(\\n[LL]u)-(2*\n[my_wid]u)-(\\n[LL]/20u))
-.sp |\\n[x_box]u
-.ce 10
-.R
-..
-.de X3
-.ce 0
-.sp |\\n[x_box]u
-.po +(u;(\\n[LL]u)-(2*\n[my_wid]u)-(\\n[LL]/20u))
-.ll \n[my_wid]u
-.nf
-.in +1n
-.CW
-..
-.de X4
-.in -1n
-.draw_screen \n[my_wid]u \\n[here]u-\\n[x_box]u+\\n[.v]u
-.R
-.fi
-.po \\n(POu
-.ll \\n(LLu
-..
-\#
-\# Helvetica font change macros
-\#
-.de H \" Helvetica
-.ie !\\n[.$] .ft H
-.el \&\\$3\fH\\$1\fP\\$2
-..
-.de HB \" Helvetica Bold
-.ie !\\n[.$] .ft HB
-.el \&\\$3\f[HB]\\$1\fP\\$2
-..
-.de HI \" Helvetica Italic
-.ie !\\n[.$] .ft HI
-.el \&\\$3\f[HI]\\$1\fP\\$2
-..
-\#
-\# Screen Boxes
-\#
-.de draw_screen \" Draw box with rounded corners, $1: wid $2: ht
-.nr radius (((\\$1)<?(\\$2))/4u)<?.25i
-\v'-\\n[radius]u'\D'a \\n[radius]u 0 0 \\n[radius]u'\c
-\D'l (\\$1)-(2u*\\n[radius]u) 0'\c
-\D'a 0 -\\n[radius]u \\n[radius]u 0'\D'l 0 -(\\$2)+(2u*\\n[radius]u)'\c
-\D'a -\\n[radius]u 0 0 -\\n[radius]u'\D'l -(\\$1)+(2u*\\n[radius]u) 0'\c
-\D'a 0 \\n[radius]u -\\n[radius]u 0'\D'l 0 (\\$2)-(2u*\\n[radius]u)'
-..
-.de SS
-.nr li_save \\n[\\n[.ev]:li]
-.nr ri_save \\n[\\n[.ev]:ri]
-.nr \\n[.ev]:li +3n
-.nr \\n[.ev]:ri +3n
-.br
-.sp \\n[SS_prefix]u
-.ie \\n[.$] \{\
-. nr width \\$1
-. nr height \\$2
-. mk screen_start
-.\}
-.el .nr width 0
-.di screen_div
-.sp .5v
-.in +3n \" Leave extra room for the rounded corners
-.ll -3n
-.lt -3n
-\&
-..
-.de SE
-.br
-.di
-.ne \\n[dn]u
-.ev nf
-.screen_div
-.ev
-.in -3n
-.ll +3n
-.lt +3n
-.nr \\n[.ev]:li \\n[li_save]
-.nr \\n[.ev]:ri \\n[ri_save]
-.ie !\\n[width] \{\
-. mk screen_end
-\#. draw_screen \\n[dl]u+3n \\n[dn]u+\\n[.v]u
-. draw_screen \\n[.l]u \\n[dn]u+\\n[.v]u
-.\}
-.el \{\
-. sp |\\n[screen_start]u+\\n[height]u-\\n[.v]u
-. mk screen_end
-. draw_screen \\n[width]u \\n[height]u
-.\}
-.sp |\\n[screen_end]u+1
-..
-\#
-\# Notes macros
-\#
-.nr note_counter 0
-.nr rnotes 0
-.ev notes
-.par*env-init
-.ll \n[LL]u
-.lt \n[LL]u
-.ps \n[PS]
-.vs \n[VS]
-.ev
-.de Rn \" Reviewer note, $1: note
-.sp
-\fBNote to reviewers:\fP \\$1
-.sp
-.ev notes
-.da rev_notes
-.sp 0.2v
-.in 0
-.ie \\n[do-page] \(sq Page \\n[PN] (\\*[page-utp]): \\$1
-.el \(sq Page \\n(PN: \\$1
-.br
-.da
-.nr rnotes 1
-.ev
-..
-.de Pn \" Personal note, $1: note
-.ev notes
-.if \\n[note_counter]<1 .nr note_counter 0 1
-.da pers_notes
-.br
-.IP \\n+[note_counter]. 5n
-\\$1
-.ie \\n[do-page] \ (Page \\n[PN]/\\*[page-utp])
-.el \ (Page \\n(PN)
-.br
-.da
-.ev
-..
-\#
-\# End Macro
-\#
-\# Output diverted material
-\#
-.de EM
-.br
-.if \\n[rnotes]=1 \{\
-\&\c
-' bp
-. ce
-\fBNotes to Reviewers\fP
-. sp 2
-. ev notes
-. nf
-. rev_notes
-. ev
-.\}
-.if \\n[note_counter]>0 \{\
-. br
-\&\c
-' bp
-. ce
-\fBPersonal Notes\fP
-. sp 2
-. ev notes
-. nf
-. pers_notes
-. ev
-.\}
-..
-\#
-\# UTP top and bottom page processing
-\#
-.de utp_top
-.ev header_footer
-.nr PN \\n[%]
-.if !\\n[chapter_page2] \{. \" if this page doesn't start a chapter
-. ie o .tl ''\\*[chapter_name]'\\n[PN]'
-. el .tl '\\n[PN]'\*[square] Unix Text Processing \*[square]''
-.\}
-.ev
-..
-.de utp_bottom
-.ev header_footer
-.if \\n[chapter_page] \{\
-. tl ''\\n[PN]''
-. nr chapter_page 0
-. nr chapter_page2 0
-.\}
-.ev
-..
-\#.de page
-\#.mk page-vpos
-\#.nr page-hpos \\n[.k]
-\#.po \\n[PO]u-4n
-\#.br
-\#\\$1
-\#.br
-\#.po \\n[PO]u
-\#.sp |\\n[page-vpos]u
-\#\h'|\\n[page-hpos]u'
-\#..
-.de do-page \" Enable the .page macro
-.nr do-page 1
-..
-.de page \" Capture the original UTP page numbers
-.ds page-utp \\$1
-.if \\n[do-page] \{\
-. mk page-pos
-. ev page-env
-' di page-num
-' nf
-\\$1
-. ev
-. di
-. mk page-trap
-. nr page-trap +.1v
-. wh \\n[page-trap]u page-put
-.\}
-..
-.de page-put \" Place the UTP page number in the left margin
-.mk page-end
-.wh \\n[page-trap]u
-'sp |\\n[page-pos]u
-.ev page-env
-'po \\n[PO]u-5n
-'fi
-.page-num
-.br
-.ev
-'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
-\#
-.de utp
-.ps 10
-.vs 12
-.nr PS 10
-.nr VS 12
-.nr SS_prefix 1v
-.nr do-page 0
-.Nh 0 0
-.als Ah utp_Ah
-.als chapter Se
-.als PT utp_top
-.als BT utp_bottom
-.ev header_footer
-.ll \\n[LL]u
-.lt \\n[LL]u
-.ps \\n[PS]
-.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