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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#! /usr/bin/perl
=pod
This is a silly little program for generating the libc FAQ.
The input format is:
top boilerplate
^L
? section name (one line)
?? question...
...
{ID} answer...
...
^L
{ID} name <email@address>
...
which gets mapped to:
top boilerplate
^L
1. section 1...
1.1. q1.1
1.2. q1.2
...
^L
1. section 1...
1.1. q1.1
answer 1.1....
^L
Answers were provided by:
...
=cut
# We slurp the whole file into a pair of assoc arrays indexed by
# the 'section.question' number.
%questions = ();
%answers = ();
$question = 0;
# These arrays and counter keep track of the sections.
@sectcount = ();
@sections = ();
$section = 0;
# Cross reference list.
%refs = ();
# Separators.
$sepmaj = "\f\n" . ('~ ' x 36) . "\n\n";
$sepmin = "\f\n" . ('. ' x 36) . "\n\n";
# Pass through the top boilerplate.
while(<>)
{
last if $_ eq "\f\n";
print;
}
# Now the body.
while(<>)
{
/\f/ && do
{
$sectcount[$section] = $question;
last;
};
s/^\?\s+// && do
{
chomp;
$sectcount[$section] = $question if $section > 0;
$section++;
$sections[$section] = $_;
$question = 0;
next;
};
s/^\?\?(\w*?)\s+// && do
{
$cur = \%questions;
$question++;
$questions{$section,$question} = $_;
$refs{$1} = "$section.$question" if $1 ne "";
next;
};
/^\{/ && do
{
$cur = \%answers;
$answers{$section,$question} .= $_;
next;
};
${$cur}{$section,$question} .= $_;
}
# Now we have to clean up the newlines and deal with cross references.
foreach(keys %questions) { $questions{$_} =~ s/\n+$//; }
foreach(keys %answers)
{
$answers{$_} =~ s/\n+$//;
$answers{$_} =~ s/(\s)\?(\w+)\b/$1 . "question " . ($refs{$2} or badref($2,$_), "!!$2")/eg;
}
# Now output the formatted FAQ.
print $sepmaj;
for($i = 1; $i <= $section; $i++)
{
print "$i. $sections[$i]\n\n";
for($j = 1; $j <= $sectcount[$i]; $j++)
{
print "$i.$j.\t$questions{$i,$j}\n";
}
print "\n";
}
print $sepmaj;
for($i = 1; $i <= $section; $i++)
{
print "$i. $sections[$i]\n\n";
for($j = 1; $j <= $sectcount[$i]; $j++)
{
print "$i.$j.\t$questions{$i,$j}\n\n";
print $answers{$i,$j}, "\n\n";
print "\n" if $j < $sectcount[$i];
}
print $sepmin if $i < $section;
}
print $sepmaj;
# Pass through the trailer.
while(<>) { print; }
sub badref
{
my($ref,$quest) = @_;
$quest =~ s/$;/./;
print STDERR "Undefined reference to $ref in answer to Q$quest\n";
}
|