|
|
1.1 root 1: #!/usr/staff/bin/perl
2: #
3: # efaq2texinfo : Convert Emacs FAQ to texinfo format
4: #
5: # George Ferguson, [email protected], 24 Jan 1992.
6: #
7: # Usage, assuming the list is in the file FAQ:
8: # % efaq2texinfo <FAQ >efaq.texinfo
9: # If you store your FAQ compressed, you can use
10: # % zcat FAQ.Z | efaq2texinfo >efaq.texinfo
11: # In any case, you then need to convert to info format:
12: # % makeinfo +fill-column 80 efaq.texinfo
13: # The result will be files efaq-info and efaq-info-[1-4]. If you don't
14: # have makeinfo(1), you can try using "texinfo-format-buffer" within
15: # emacs.
16: #
17: # The FAQ can be obtained from pit-manager.mit.edu.
18: #
19:
20: $chapter = 0;
21: $item = 0;
22: $itemizing = 0;
23: $enumerating = 0;
24: $displaying = 0;
25:
26: # Now process each line
27: while (<>) {
28: if ($. == 1 || /^---Continued---$/) {
29: &skipJunk;
30: }
31: s/^ +$//; # blanks only -> newline
32: s/\t/ /; # tabs -> spaces (stupidly)
33: if (/^([^0-9 \n].*)$/) { # new chapter heading
34: &endDisplay;
35: &endLists;
36: $chapter += 1;
37: $text = $1;
38: $text =~ s/ +[-!+]$//; # remove change marker
39: $chapterTitle[$chapter] = $text;
40: $item = 0;
41: # print "CHAPTER $chapter: \"$text\"\n";
42: } elsif (/^([0-9]+): (.*)$/) {
43: &endDisplay;
44: &endLists;
45: $num = $1;
46: $text = $2;
47: $text =~ s/ +[-!+]$//; # remove change marker
48: $menu[$chapter] .= "* Question $num::\t$text\n";
49: $item = $num;
50: $itemTitle[$item] = "$text\n";
51: # print "QUESTION $item: \"$text\"\n";
52: } else {
53: if (/^ +\* Topic/) { # hack for info example
54: &addText("@example\n");
55: &addText("$_");
56: &addText("@end example\n");
57: next;
58: } elsif (/^ +\*/) { # asterisk marks list element
59: if (!$itemizing) {
60: &addText("\@itemize \@bullet\n");
61: $itemizing = 1;
62: }
63: &endDisplay;
64: &addText("\@item\n");
65: s/^ +\* *//;
66: } elsif (/^ +[0-9]\./) { # digit-period marks list element
67: if (!$enumerating) {
68: &addText("\@enumerate\n");
69: $enumerating = 1;
70: }
71: &endDisplay;
72: &addText("\@item\n");
73: s/^ +[0-9]+\. *//;
74: } elsif (/^ {0,2}[^ \n]/) { # less whitespace marks end of list
75: &endLists;
76: }
77: s/ //; # automatically remove 2 spaces
78: if ($itemizing) { # adjust leading whitespace in lists
79: s/^ //;
80: } elsif ($enumerating) {
81: s/^ //;
82: }
83: if (/^ +/ && !$displaying) { # extra leading spaces -> display
84: &addText("\@example\n");
85: $displaying = 1;
86: }
87: if (/^[^ ]/ && $displaying) { # no leading spaces -> display end
88: &addText("\@end example\n");
89: $displaying = 0;
90: }
91: s/ +[-!+]$//; # remove "change" markers (sorry)
92: $_ = &formatText;
93: &addText($_);
94: }
95: }
96: # Just in case
97: &endDisplay;
98: &endLists;
99:
100: # Output it all
101:
102: # Print texinfo header
103: print "\\input texinfo\n";
104: print "@setfilename efaq.info\n";
105: print "@settitle Frequently Asked Questions about Emacs\n";
106: print "\n";
107: print "@node Top\n";
108: print "@top Frequently Asked Questions about Emacs\n";
109: print "\n";
110:
111: print $chapterText[0];
112: print "\@menu\n";
113: for ($i = 1; $i <= $chapter; $i++) {
114: print "* Chapter $i::\t$chapterTitle[$i]\n";
115: }
116: print "* Index::\tHosts, usernames, files, etc.\n";
117: print "\@end menu\n\n";
118: for ($i = 1; $i <= $chapter; $i++) {
119: print "\@node Chapter $i\n";
120: print "\@chapter $chapterTitle[$i]\n";
121: print $chapterText[$i];
122: print "\@menu\n";
123: print $menu[$i];
124: print "\@end menu\n\n";
125: }
126: for ($i = 1; $i <= $item; $i++) {
127: print "\@node Question $i\n";
128: print "\@section $itemTitle[$i]"; # too many newlines already
129: print $itemText[$i];
130: }
131:
132: # Print texinfo trailer
133: print "\n";
134: print "@node Index\n";
135: print "@appendix Index\n";
136: print "\n";
137: print "@printindex fn\n";
138: print "\n";
139: print "@bye\n";
140:
141: ############################################################################
142:
143: sub addText {
144: if ($item == 0) {
145: $chapterText[$chapter] .= "$_[0]";
146: } else {
147: $itemText[$item] .= "$_[0]";
148: }
149: }
150:
151: sub endLists {
152: if ($itemizing) {
153: &addText("\@end itemize\n");
154: }
155: if ($enumerating) {
156: &addText("\@end enumerate\n");
157: }
158: $enumerating = 0;
159: $itemizing = 0;
160: }
161:
162: sub endDisplay {
163: if ($displaying) {
164: &addText("\@end example\n");
165: $displaying = 0;
166: }
167: }
168:
169: sub skipJunk {
170: local($blank) = 0;
171: # skip until double newline (ie. mail headers, etc.)
172: while ($_ ne "\n" || !$blank) {
173: $blank = ($_ eq "\n");
174: $_ = <>;
175: }
176: # skip next paragraph: "If you are viewing..."
177: $_ = <>;
178: while ($_ ne "\n") { $_ = <>; }
179: # skip next paragraph: "To search for..."
180: $_ = <>;
181: while ($_ ne "\n") { $_ = <>; }
182: # skip next paragraph: "A `+' in the..."
183: $_ = <>;
184: while ($_ ne "\n") { $_ = <>; }
185: }
186:
187: #
188: # For each line of text in the document, we generate an index entry for
189: # anything that looks like a hostname, email address, newsgroup, filename
190: # or emacs command (only long command recognized). This function is complicated
191: # by the fact that the index entries have to come on lines of their own,
192: # after the text that contains them.
193: #
194: # To recognize host:file as a single entity, add ":?" inside the first
195: # nested set of brackets but before the multiple-alternatives pattern.
196: #
197: # This function also escapes any characters with special meaning to
198: # texinfo. Returns the line of text.
199: #
200: sub formatText {
201: # convert special chars to texinfo escapes
202: s/@/@@/g;
203: s/\{/@{/g;
204: s/\}/@}/g;
205: # remove trailing spaces
206: s/ +$//g;
207: # gather the index entries
208: local($t) = $_;
209: local($tt) = "";
210: while ($t =~ /([-a-zA-Z0-9]{2,}((\.|@@|%|!|-|\/)[-@a-zA-Z0-9]+){2,})/) {
211: $t = $';
212: $tt .= "@findex $1\n";
213: }
214: # Flag cross-references
215: s/(q|Q)uestion ([0-9]+)/@ref\{Question $2\}/g;
216: # print the line of text
217: return("$_$tt");
218: }
219:
220: __END__
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.