summaryrefslogtreecommitdiff
path: root/etc/faq2texi.perl
blob: 3a040ab7387622168d7a0afece5aec61252545de (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
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#!/usr/staff/bin/perl
#
# efaq2texinfo : Convert Emacs FAQ to texinfo format
#
# George Ferguson, ferguson@cs.rochester.edu, 24 Jan 1992.
#
# Usage, assuming the list is in the file FAQ:
#	% efaq2texinfo <FAQ >efaq.texinfo
# If you store your FAQ compressed, you can use
#	% zcat FAQ.Z | efaq2texinfo >efaq.texinfo
# In any case, you then need to convert to info format:
#	% makeinfo +fill-column 80 efaq.texinfo
# The result will be files efaq-info and efaq-info-[1-4]. If you don't
# have makeinfo(1), you can try using "texinfo-format-buffer" within
# emacs.
#
# The FAQ can be obtained from pit-manager.mit.edu.
#

$chapter = 0;
$item = 0;
$itemizing = 0;
$enumerating = 0;
$displaying = 0;

# Now process each line
while (<>) {
    if ($. == 1 || /^---Continued---$/) {
	&skipJunk;
    }
    s/^ +$//;					# blanks only -> newline
    s/\t/        /;				# tabs -> spaces (stupidly)
    if (/^([^0-9 \n].*)$/) {			# new chapter heading
	&endDisplay;
	&endLists;
	$chapter += 1;
	$text = $1;
	$text =~ s/ +[-!+]$//;			# remove change marker
	$chapterTitle[$chapter] = $text;
	$item = 0;
#	print "CHAPTER $chapter: \"$text\"\n";
    } elsif (/^([0-9]+): (.*)$/) {
	&endDisplay;
	&endLists;
	$num = $1;
	$text = $2;
	$text =~ s/ +[-!+]$//;			# remove change marker
	$menu[$chapter] .= "* Question $num::\t$text\n";
	$item = $num;
	$itemTitle[$item] = "$text\n";
#	print "QUESTION $item: \"$text\"\n";
    } else {
	if (/^ +\* Topic/) {		# hack for info example
	    &addText("@example\n");
	    &addText("$_");
	    &addText("@end example\n");
	    next;
	} elsif (/^ +\*/) {		# asterisk marks list element
	    if (!$itemizing) {
		&addText("\@itemize \@bullet\n");
		$itemizing = 1;
	    }
	    &endDisplay;
	    &addText("\@item\n");
	    s/^ +\* *//;
	} elsif (/^ +[0-9]\./) {	# digit-period marks list element
	    if (!$enumerating) {
		&addText("\@enumerate\n");
		$enumerating = 1;
	    }
	    &endDisplay;
	    &addText("\@item\n");
	    s/^ +[0-9]+\. *//;
	} elsif (/^ {0,2}[^ \n]/) {	# less whitespace marks end of list
	    &endLists;
	}
	s/  //;				# automatically remove 2 spaces
	if ($itemizing) {		# adjust leading whitespace in lists
	    s/^  //;
	} elsif ($enumerating) {
	    s/^   //;
	}
	if (/^ +/ && !$displaying) {	# extra leading spaces -> display
	    &addText("\@example\n");
	    $displaying = 1;
	}
	if (/^[^ ]/ && $displaying) {	# no leading spaces -> display end
	    &addText("\@end example\n");
	    $displaying = 0;
	}
	s/ +[-!+]$//;			# remove "change" markers (sorry)
	$_ = &formatText;
	&addText($_);
    }
}
# Just in case
&endDisplay;
&endLists;

# Output it all

# Print texinfo header
print "\\input texinfo\n";
print "@setfilename efaq.info\n";
print "@settitle Frequently Asked Questions about Emacs\n";
print "\n";
print "@node Top\n";
print "@top Frequently Asked Questions about Emacs\n";
print "\n";

print $chapterText[0];
print "\@menu\n";
for ($i = 1; $i <= $chapter; $i++) {
    print "* Chapter $i::\t$chapterTitle[$i]\n";
}
print "* Index::\tHosts, usernames, files, etc.\n";
print "\@end menu\n\n";
for ($i = 1; $i <= $chapter; $i++) {
    print "\@node Chapter $i\n";
    print "\@chapter $chapterTitle[$i]\n";
    print $chapterText[$i];
    print "\@menu\n";
    print $menu[$i];
    print "\@end menu\n\n";
}
for ($i = 1; $i <= $item; $i++) {
    print "\@node Question $i\n";
    print "\@section $itemTitle[$i]";	# too many newlines already
    print $itemText[$i];
}

# Print texinfo trailer
print "\n";
print "@node Index\n";
print "@appendix Index\n";
print "\n";
print "@printindex fn\n";
print "\n";
print "@bye\n";

############################################################################

sub addText {
    if ($item == 0) {
	$chapterText[$chapter] .= "$_[0]";
    } else {
	$itemText[$item] .= "$_[0]";
    }
}

sub endLists {
    if ($itemizing) {
	&addText("\@end itemize\n");
    }
    if ($enumerating) {
	&addText("\@end enumerate\n");
    }
    $enumerating = 0;
    $itemizing = 0;
}

sub endDisplay {
    if ($displaying) {
	&addText("\@end example\n");
	$displaying = 0;
    }
}

sub skipJunk {
    local($blank) = 0;
    # skip until double newline (ie. mail headers, etc.)
    while ($_ ne "\n" || !$blank) {
	$blank = ($_ eq "\n");
	$_ = <>;
    }
    # skip next paragraph: "If you are viewing..."
    $_ = <>;
    while ($_ ne "\n") { $_ = <>; }
    # skip next paragraph: "To search for..."
    $_ = <>;
    while ($_ ne "\n") { $_ = <>; }
    # skip next paragraph: "A `+' in the..."
    $_ = <>;
    while ($_ ne "\n") { $_ = <>; }
}

#
# For each line of text in the document, we generate an index entry for
# anything that looks like a hostname, email address, newsgroup, filename
# or emacs command (only long command recognized). This function is complicated
# by the fact that the index entries have to come on lines of their own,
# after the text that contains them.
#
# To recognize host:file as a single entity, add ":?" inside the first
# nested set of brackets but before the multiple-alternatives pattern.
#
# This function also escapes any characters with special meaning to
# texinfo. Returns the line of text.
#
sub formatText {
    # convert special chars to texinfo escapes
    s/@/@@/g;
    s/\{/@{/g;
    s/\}/@}/g;
    # remove trailing spaces
    s/ +$//g;
    # gather the index entries
    local($t) = $_;
    local($tt) = "";
    while ($t =~ /([-a-zA-Z0-9]{2,}((\.|@@|%|!|-|\/)[-@a-zA-Z0-9]+){2,})/) {
	$t = $';
	$tt .= "@findex $1\n";
    }
    # Flag cross-references
    s/(q|Q)uestion ([0-9]+)/@ref\{Question $2\}/g;
    # print the line of text
    return("$_$tt");
}

__END__