texi2html revision 1.1 1 1.1 christos #!/usr/local/bin/perl
2 1.1 christos 'di ';
3 1.1 christos 'ig 00 ';
4 1.1 christos #+##############################################################################
5 1.1 christos # #
6 1.1 christos # File: texi2html #
7 1.1 christos # #
8 1.1 christos # Description: Program to transform most Texinfo documents to HTML #
9 1.1 christos # #
10 1.1 christos #-##############################################################################
11 1.1 christos
12 1.1 christos # @(#)texi2html 1.52b 01/05/98 Written (mainly) by Lionel Cons, Lionel.Cons (at] cern.ch
13 1.1 christos # 1.52a: Use acute accent instead of apostrophe. Add support for ISO-8859-1
14 1.1 christos # characters with cedilla, circumflex etc.
15 1.1 christos # 1.52b: Add option -expandtex. Expand @ifhtml by default, not @ifinfo.
16 1.1 christos # Use Unicode quotation marks instead of grave and acute accents.
17 1.1 christos # Emit charset=UTF-8 declaration.
18 1.1 christos
19 1.1 christos # The man page for this program is included at the end of this file and can be
20 1.1 christos # viewed using the command 'nroff -man texi2html'.
21 1.1 christos # Please read the copyright at the end of the man page.
22 1.1 christos
23 1.1 christos #+++############################################################################
24 1.1 christos # #
25 1.1 christos # Constants #
26 1.1 christos # #
27 1.1 christos #---############################################################################
28 1.1 christos
29 1.1 christos $DEBUG_TOC = 1;
30 1.1 christos $DEBUG_INDEX = 2;
31 1.1 christos $DEBUG_BIB = 4;
32 1.1 christos $DEBUG_GLOSS = 8;
33 1.1 christos $DEBUG_DEF = 16;
34 1.1 christos $DEBUG_HTML = 32;
35 1.1 christos $DEBUG_USER = 64;
36 1.1 christos
37 1.1 christos $BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference
38 1.1 christos $FILERE = '[\/\w.+-]+'; # RE for a file name
39 1.1 christos $VARRE = '[^\s\{\}]+'; # RE for a variable name
40 1.1 christos $NODERE = '[^@{}:\'`",]+'; # RE for a node name
41 1.1 christos $NODESRE = '[^@{}:\'`"]+'; # RE for a list of node names
42 1.1 christos $XREFRE = '[^@{}]+'; # RE for a xref (should use NODERE)
43 1.1 christos
44 1.1 christos $ERROR = "***"; # prefix for errors and warnings
45 1.1 christos $THISPROG = "texi2html 1.52b"; # program name and version
46 1.1 christos $HOMEPAGE = "http://wwwinfo.cern.ch/dis/texi2html/"; # program home page
47 1.1 christos $TODAY = &pretty_date; # like "20 September 1993"
48 1.1 christos $SPLITTAG = "<!-- SPLIT HERE -->\n"; # tag to know where to split
49 1.1 christos $PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections
50 1.1 christos $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//EN">';
51 1.1 christos
52 1.1 christos #
53 1.1 christos # language dependent constants
54 1.1 christos #
55 1.1 christos #$LDC_SEE = 'see';
56 1.1 christos #$LDC_SECTION = 'section';
57 1.1 christos #$LDC_IN = 'in';
58 1.1 christos #$LDC_TOC = 'Table of Contents';
59 1.1 christos #$LDC_GOTO = 'Go to the';
60 1.1 christos #$LDC_FOOT = 'Footnotes';
61 1.1 christos # TODO: @def* shortcuts
62 1.1 christos
63 1.1 christos #
64 1.1 christos # pre-defined indices
65 1.1 christos #
66 1.1 christos %predefined_index = (
67 1.1 christos 'cp', 'c',
68 1.1 christos 'fn', 'f',
69 1.1 christos 'vr', 'v',
70 1.1 christos 'ky', 'k',
71 1.1 christos 'pg', 'p',
72 1.1 christos 'tp', 't',
73 1.1 christos );
74 1.1 christos
75 1.1 christos #
76 1.1 christos # valid indices
77 1.1 christos #
78 1.1 christos %valid_index = (
79 1.1 christos 'c', 1,
80 1.1 christos 'f', 1,
81 1.1 christos 'v', 1,
82 1.1 christos 'k', 1,
83 1.1 christos 'p', 1,
84 1.1 christos 't', 1,
85 1.1 christos );
86 1.1 christos
87 1.1 christos #
88 1.1 christos # texinfo section names to level
89 1.1 christos #
90 1.1 christos %sec2level = (
91 1.1 christos 'top', 0,
92 1.1 christos 'chapter', 1,
93 1.1 christos 'unnumbered', 1,
94 1.1 christos 'majorheading', 1,
95 1.1 christos 'chapheading', 1,
96 1.1 christos 'appendix', 1,
97 1.1 christos 'section', 2,
98 1.1 christos 'unnumberedsec', 2,
99 1.1 christos 'heading', 2,
100 1.1 christos 'appendixsec', 2,
101 1.1 christos 'appendixsection', 2,
102 1.1 christos 'subsection', 3,
103 1.1 christos 'unnumberedsubsec', 3,
104 1.1 christos 'subheading', 3,
105 1.1 christos 'appendixsubsec', 3,
106 1.1 christos 'subsubsection', 4,
107 1.1 christos 'unnumberedsubsubsec', 4,
108 1.1 christos 'subsubheading', 4,
109 1.1 christos 'appendixsubsubsec', 4,
110 1.1 christos );
111 1.1 christos
112 1.1 christos #
113 1.1 christos # accent map, TeX command to ISO name
114 1.1 christos #
115 1.1 christos %accent_map = (
116 1.1 christos '"', 'uml',
117 1.1 christos '~', 'tilde',
118 1.1 christos '^', 'circ',
119 1.1 christos '`', 'grave',
120 1.1 christos '\'', 'acute',
121 1.1 christos );
122 1.1 christos
123 1.1 christos #
124 1.1 christos # texinfo "simple things" (@foo) to HTML ones
125 1.1 christos #
126 1.1 christos %simple_map = (
127 1.1 christos # cf. makeinfo.c
128 1.1 christos "*", "<BR>", # HTML+
129 1.1 christos " ", " ",
130 1.1 christos "\n", "\n",
131 1.1 christos "|", "",
132 1.1 christos # spacing commands
133 1.1 christos ":", "",
134 1.1 christos "!", "!",
135 1.1 christos "?", "?",
136 1.1 christos ".", ".",
137 1.1 christos "-", "",
138 1.1 christos );
139 1.1 christos
140 1.1 christos #
141 1.1 christos # texinfo "things" (@foo{}) to HTML ones
142 1.1 christos #
143 1.1 christos %things_map = (
144 1.1 christos 'TeX', 'TeX',
145 1.1 christos 'br', '<P>', # paragraph break
146 1.1 christos 'bullet', '*',
147 1.1 christos 'copyright', '(C)',
148 1.1 christos 'dots', '...',
149 1.1 christos 'equiv', '==',
150 1.1 christos 'error', 'error-->',
151 1.1 christos 'expansion', '==>',
152 1.1 christos 'minus', '-',
153 1.1 christos 'point', '-!-',
154 1.1 christos 'print', '-|',
155 1.1 christos 'result', '=>',
156 1.1 christos 'today', $TODAY,
157 1.1 christos 'aa', 'å',
158 1.1 christos 'AA', 'Å',
159 1.1 christos 'ae', 'æ',
160 1.1 christos 'AE', 'Æ',
161 1.1 christos 'o', 'ø',
162 1.1 christos 'O', 'Ø',
163 1.1 christos 'ss', 'ß',
164 1.1 christos 'exclamdown', '¡',
165 1.1 christos 'questiondown', '¿',
166 1.1 christos 'pounds', '£'
167 1.1 christos );
168 1.1 christos
169 1.1 christos #
170 1.1 christos # texinfo styles (@foo{bar}) to HTML ones
171 1.1 christos #
172 1.1 christos %style_map = (
173 1.1 christos 'asis', '',
174 1.1 christos 'b', 'B',
175 1.1 christos 'cite', 'CITE',
176 1.1 christos 'code', 'CODE',
177 1.1 christos 'ctrl', '&do_ctrl', # special case
178 1.1 christos 'dfn', 'EM', # DFN tag is illegal in the standard
179 1.1 christos 'dmn', '', # useless
180 1.1 christos 'email', '&do_email', # insert a clickable email address
181 1.1 christos 'emph', 'EM',
182 1.1 christos 'file', '"TT', # will put quotes, cf. &apply_style
183 1.1 christos 'i', 'I',
184 1.1 christos 'kbd', 'KBD',
185 1.1 christos 'key', 'KBD',
186 1.1 christos 'math', 'EM',
187 1.1 christos 'r', '', # unsupported
188 1.1 christos 'samp', '"SAMP', # will put quotes, cf. &apply_style
189 1.1 christos 'sc', '&do_sc', # special case
190 1.1 christos 'strong', 'STRONG',
191 1.1 christos 't', 'TT',
192 1.1 christos 'titlefont', '', # useless
193 1.1 christos 'uref', '&do_uref', # insert a clickable URL
194 1.1 christos 'url', '&do_url', # insert a clickable URL
195 1.1 christos 'var', 'VAR',
196 1.1 christos 'w', '', # unsupported
197 1.1 christos '"', '&do_diaeresis',
198 1.1 christos '\'', '&do_acuteaccent', # doesn't work??
199 1.1 christos '\`', '&do_graveaccent', # doesn't work??
200 1.1 christos '~', '&do_tildeaccent',
201 1.1 christos ',', '&do_cedilla',
202 1.1 christos '^', '&do_circumflex',
203 1.1 christos );
204 1.1 christos
205 1.1 christos #
206 1.1 christos # texinfo format (@foo/@end foo) to HTML ones
207 1.1 christos #
208 1.1 christos %format_map = (
209 1.1 christos 'display', 'PRE',
210 1.1 christos 'example', 'PRE',
211 1.1 christos 'format', 'PRE',
212 1.1 christos 'lisp', 'PRE',
213 1.1 christos 'quotation', 'BLOCKQUOTE',
214 1.1 christos 'smallexample', 'PRE',
215 1.1 christos 'smalllisp', 'PRE',
216 1.1 christos # lists
217 1.1 christos 'itemize', 'UL',
218 1.1 christos 'enumerate', 'OL',
219 1.1 christos # poorly supported
220 1.1 christos 'flushleft', 'PRE',
221 1.1 christos 'flushright', 'PRE',
222 1.1 christos );
223 1.1 christos
224 1.1 christos #
225 1.1 christos # texinfo definition shortcuts to real ones
226 1.1 christos #
227 1.1 christos %def_map = (
228 1.1 christos # basic commands
229 1.1 christos 'deffn', 0,
230 1.1 christos 'defvr', 0,
231 1.1 christos 'deftypefn', 0,
232 1.1 christos 'deftypevr', 0,
233 1.1 christos 'defcv', 0,
234 1.1 christos 'defop', 0,
235 1.1 christos 'deftp', 0,
236 1.1 christos # basic x commands
237 1.1 christos 'deffnx', 0,
238 1.1 christos 'defvrx', 0,
239 1.1 christos 'deftypefnx', 0,
240 1.1 christos 'deftypevrx', 0,
241 1.1 christos 'defcvx', 0,
242 1.1 christos 'defopx', 0,
243 1.1 christos 'deftpx', 0,
244 1.1 christos # shortcuts
245 1.1 christos 'defun', 'deffn Function',
246 1.1 christos 'defmac', 'deffn Macro',
247 1.1 christos 'defspec', 'deffn {Special Form}',
248 1.1 christos 'defvar', 'defvr Variable',
249 1.1 christos 'defopt', 'defvr {User Option}',
250 1.1 christos 'deftypefun', 'deftypefn Function',
251 1.1 christos 'deftypevar', 'deftypevr Variable',
252 1.1 christos 'defivar', 'defcv {Instance Variable}',
253 1.1 christos 'defmethod', 'defop Method',
254 1.1 christos # x shortcuts
255 1.1 christos 'defunx', 'deffnx Function',
256 1.1 christos 'defmacx', 'deffnx Macro',
257 1.1 christos 'defspecx', 'deffnx {Special Form}',
258 1.1 christos 'defvarx', 'defvrx Variable',
259 1.1 christos 'defoptx', 'defvrx {User Option}',
260 1.1 christos 'deftypefunx', 'deftypefnx Function',
261 1.1 christos 'deftypevarx', 'deftypevrx Variable',
262 1.1 christos 'defivarx', 'defcvx {Instance Variable}',
263 1.1 christos 'defmethodx', 'defopx Method',
264 1.1 christos );
265 1.1 christos
266 1.1 christos #
267 1.1 christos # things to skip
268 1.1 christos #
269 1.1 christos %to_skip = (
270 1.1 christos # comments
271 1.1 christos 'c', 1,
272 1.1 christos 'comment', 1,
273 1.1 christos # useless
274 1.1 christos 'contents', 1,
275 1.1 christos 'shortcontents', 1,
276 1.1 christos 'summarycontents', 1,
277 1.1 christos 'footnotestyle', 1,
278 1.1 christos 'end ifclear', 1,
279 1.1 christos 'end ifset', 1,
280 1.1 christos 'titlepage', 1,
281 1.1 christos 'end titlepage', 1,
282 1.1 christos # unsupported commands (formatting)
283 1.1 christos 'afourpaper', 1,
284 1.1 christos 'cropmarks', 1,
285 1.1 christos 'finalout', 1,
286 1.1 christos 'headings', 1,
287 1.1 christos 'need', 1,
288 1.1 christos 'page', 1,
289 1.1 christos 'setchapternewpage', 1,
290 1.1 christos 'everyheading', 1,
291 1.1 christos 'everyfooting', 1,
292 1.1 christos 'evenheading', 1,
293 1.1 christos 'evenfooting', 1,
294 1.1 christos 'oddheading', 1,
295 1.1 christos 'oddfooting', 1,
296 1.1 christos 'smallbook', 1,
297 1.1 christos 'vskip', 1,
298 1.1 christos 'filbreak', 1,
299 1.1 christos 'paragraphindent', 1,
300 1.1 christos # unsupported formats
301 1.1 christos 'cartouche', 1,
302 1.1 christos 'end cartouche', 1,
303 1.1 christos 'group', 1,
304 1.1 christos 'end group', 1,
305 1.1 christos );
306 1.1 christos
307 1.1 christos #+++############################################################################
308 1.1 christos # #
309 1.1 christos # Argument parsing, initialisation #
310 1.1 christos # #
311 1.1 christos #---############################################################################
312 1.1 christos
313 1.1 christos %value = (); # hold texinfo variables, see also -D
314 1.1 christos
315 1.1 christos $use_bibliography = 1;
316 1.1 christos $use_acc = 0;
317 1.1 christos $debug = 0;
318 1.1 christos $doctype = '';
319 1.1 christos $check = 0;
320 1.1 christos $expandinfo = 0;
321 1.1 christos $expandtex = 0;
322 1.1 christos $use_glossary = 0;
323 1.1 christos $invisible_mark = '';
324 1.1 christos $use_iso = 0;
325 1.1 christos @include_dirs = ();
326 1.1 christos $show_menu = 0;
327 1.1 christos $number_sections = 0;
328 1.1 christos $split_node = 0;
329 1.1 christos $split_chapter = 0;
330 1.1 christos $monolithic = 0;
331 1.1 christos $verbose = 0;
332 1.1 christos $usage = <<EOT;
333 1.1 christos This is $THISPROG
334 1.1 christos To convert a Texinfo file to HMTL: $0 [options] file
335 1.1 christos where options can be:
336 1.1 christos -expandinfo : use \@ifinfo sections, not \@ifhtml
337 1.1 christos -expandtex : use \@iftex sections, not \@ifhtml
338 1.1 christos -glossary : handle a glossary
339 1.1 christos -invisible name: use 'name' as an invisible anchor
340 1.1 christos -Dname : define name like with \@set
341 1.1 christos -I dir : search also for files in 'dir'
342 1.1 christos -menu : handle menus
343 1.1 christos -monolithic : output only one file including ToC
344 1.1 christos -number : number sections
345 1.1 christos -split_chapter : split on main sections
346 1.1 christos -split_node : split on nodes
347 1.1 christos -usage : print usage instructions
348 1.1 christos -verbose : verbose output
349 1.1 christos To check converted files: $0 -check [-verbose] files
350 1.1 christos EOT
351 1.1 christos
352 1.1 christos while (@ARGV && $ARGV[0] =~ /^-/) {
353 1.1 christos $_ = shift(@ARGV);
354 1.1 christos if (/^-acc$/) { $use_acc = 1; next; }
355 1.1 christos if (/^-d(ebug)?(\d+)?$/) { $debug = $2 || shift(@ARGV); next; }
356 1.1 christos if (/^-doctype$/) { $doctype = shift(@ARGV); next; }
357 1.1 christos if (/^-c(heck)?$/) { $check = 1; next; }
358 1.1 christos if (/^-expandi(nfo)?$/) { $expandinfo = 1; next; }
359 1.1 christos if (/^-expandt(ex)?$/) { $expandtex = 1; next; }
360 1.1 christos if (/^-g(lossary)?$/) { $use_glossary = 1; next; }
361 1.1 christos if (/^-i(nvisible)?$/) { $invisible_mark = shift(@ARGV); next; }
362 1.1 christos if (/^-iso$/) { $use_iso = 1; next; }
363 1.1 christos if (/^-D(.+)?$/) { $value{$1 || shift(@ARGV)} = 1; next; }
364 1.1 christos if (/^-I(.+)?$/) { push(@include_dirs, $1 || shift(@ARGV)); next; }
365 1.1 christos if (/^-m(enu)?$/) { $show_menu = 1; next; }
366 1.1 christos if (/^-mono(lithic)?$/) { $monolithic = 1; next; }
367 1.1 christos if (/^-n(umber)?$/) { $number_sections = 1; next; }
368 1.1 christos if (/^-s(plit)?_?(n(ode)?|c(hapter)?)?$/) {
369 1.1 christos if ($2 =~ /^n/) {
370 1.1 christos $split_node = 1;
371 1.1 christos } else {
372 1.1 christos $split_chapter = 1;
373 1.1 christos }
374 1.1 christos next;
375 1.1 christos }
376 1.1 christos if (/^-v(erbose)?$/) { $verbose = 1; next; }
377 1.1 christos die $usage;
378 1.1 christos }
379 1.1 christos if ($check) {
380 1.1 christos die $usage unless @ARGV > 0;
381 1.1 christos ✓
382 1.1 christos exit;
383 1.1 christos }
384 1.1 christos
385 1.1 christos if (($split_node || $split_chapter) && $monolithic) {
386 1.1 christos warn "Can't use -monolithic with -split, -monolithic ignored.\n";
387 1.1 christos $monolithic = 0;
388 1.1 christos }
389 1.1 christos if ($expandinfo) {
390 1.1 christos $to_skip{'ifinfo'}++;
391 1.1 christos $to_skip{'end ifinfo'}++;
392 1.1 christos $to_skip{'ifnottex'}++;
393 1.1 christos $to_skip{'end ifnottex'}++;
394 1.1 christos $to_skip{'ifnothtml'}++;
395 1.1 christos $to_skip{'end ifnothtml'}++;
396 1.1 christos } elsif ($expandtex) {
397 1.1 christos $to_skip{'ifnotinfo'}++;
398 1.1 christos $to_skip{'end ifnotinfo'}++;
399 1.1 christos $to_skip{'iftex'}++;
400 1.1 christos $to_skip{'end iftex'}++;
401 1.1 christos $to_skip{'ifnothtml'}++;
402 1.1 christos $to_skip{'end ifnothtml'}++;
403 1.1 christos } else {
404 1.1 christos $to_skip{'ifnotinfo'}++;
405 1.1 christos $to_skip{'end ifnotinfo'}++;
406 1.1 christos $to_skip{'ifnottex'}++;
407 1.1 christos $to_skip{'end ifnottex'}++;
408 1.1 christos $to_skip{'ifhtml'}++;
409 1.1 christos $to_skip{'end ifhtml'}++;
410 1.1 christos }
411 1.1 christos $invisible_mark = '<IMG SRC="invisible.xbm">' if $invisible_mark eq 'xbm';
412 1.1 christos die $usage unless @ARGV == 1;
413 1.1 christos $docu = shift(@ARGV);
414 1.1 christos if ($docu =~ /.*\//) {
415 1.1 christos chop($docu_dir = $&);
416 1.1 christos $docu_name = $';
417 1.1 christos } else {
418 1.1 christos $docu_dir = '.';
419 1.1 christos $docu_name = $docu;
420 1.1 christos }
421 1.1 christos unshift(@include_dirs, $docu_dir);
422 1.1 christos $docu_name =~ s/\.te?x(i|info)?$//; # basename of the document
423 1.1 christos
424 1.1 christos $docu_doc = "$docu_name.html"; # document's contents
425 1.1 christos if ($monolithic) {
426 1.1 christos $docu_toc = $docu_foot = $docu_doc;
427 1.1 christos } else {
428 1.1 christos $docu_toc = "${docu_name}_toc.html"; # document's table of contents
429 1.1 christos $docu_foot = "${docu_name}_foot.html"; # document's footnotes
430 1.1 christos }
431 1.1 christos
432 1.1 christos #
433 1.1 christos # variables
434 1.1 christos #
435 1.1 christos $value{'html'} = 1; # predefine html (the output format)
436 1.1 christos $value{'texi2html'} = '1.52b'; # predefine texi2html (the translator)
437 1.1 christos # _foo: internal to track @foo
438 1.1 christos foreach ('_author', '_title', '_subtitle',
439 1.1 christos '_settitle', '_setfilename') {
440 1.1 christos $value{$_} = ''; # prevent -w warnings
441 1.1 christos }
442 1.1 christos %node2sec = (); # node to section name
443 1.1 christos %node2href = (); # node to HREF
444 1.1 christos %bib2href = (); # bibliography reference to HREF
445 1.1 christos %gloss2href = (); # glossary term to HREF
446 1.1 christos @sections = (); # list of sections
447 1.1 christos %tag2pro = (); # protected sections
448 1.1 christos
449 1.1 christos #
450 1.1 christos # initial indexes
451 1.1 christos #
452 1.1 christos $bib_num = 0;
453 1.1 christos $foot_num = 0;
454 1.1 christos $gloss_num = 0;
455 1.1 christos $idx_num = 0;
456 1.1 christos $sec_num = 0;
457 1.1 christos $doc_num = 0;
458 1.1 christos $html_num = 0;
459 1.1 christos
460 1.1 christos #
461 1.1 christos # can I use ISO8879 characters? (HTML+)
462 1.1 christos #
463 1.1 christos if ($use_iso) {
464 1.1 christos $things_map{'bullet'} = "•";
465 1.1 christos $things_map{'copyright'} = "©";
466 1.1 christos $things_map{'dots'} = "…";
467 1.1 christos $things_map{'equiv'} = "≡";
468 1.1 christos $things_map{'expansion'} = "→";
469 1.1 christos $things_map{'point'} = "∗";
470 1.1 christos $things_map{'result'} = "⇒";
471 1.1 christos }
472 1.1 christos
473 1.1 christos #
474 1.1 christos # read texi2html extensions (if any)
475 1.1 christos #
476 1.1 christos $extensions = 'texi2html.ext'; # extensions in working directory
477 1.1 christos if (-f $extensions) {
478 1.1 christos print "# reading extensions from $extensions\n" if $verbose;
479 1.1 christos require($extensions);
480 1.1 christos }
481 1.1 christos ($progdir = $0) =~ s/[^\/]+$//;
482 1.1 christos if ($progdir && ($progdir ne './')) {
483 1.1 christos $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory
484 1.1 christos if (-f $extensions) {
485 1.1 christos print "# reading extensions from $extensions\n" if $verbose;
486 1.1 christos require($extensions);
487 1.1 christos }
488 1.1 christos }
489 1.1 christos
490 1.1 christos print "# reading from $docu\n" if $verbose;
491 1.1 christos
492 1.1 christos #+++############################################################################
493 1.1 christos # #
494 1.1 christos # Pass 1: read source, handle command, variable, simple substitution #
495 1.1 christos # #
496 1.1 christos #---############################################################################
497 1.1 christos
498 1.1 christos @lines = (); # whole document
499 1.1 christos @toc_lines = (); # table of contents
500 1.1 christos $toplevel = 0; # top level seen in hierarchy
501 1.1 christos $curlevel = 0; # current level in TOC
502 1.1 christos $node = ''; # current node name
503 1.1 christos $in_table = 0; # am I inside a table
504 1.1 christos $table_type = ''; # type of table ('', 'f', 'v', 'multi')
505 1.1 christos @tables = (); # nested table support
506 1.1 christos $in_bibliography = 0; # am I inside a bibliography
507 1.1 christos $in_glossary = 0; # am I inside a glossary
508 1.1 christos $in_top = 0; # am I inside the top node
509 1.1 christos $in_pre = 0; # am I inside a preformatted section
510 1.1 christos $in_list = 0; # am I inside a list
511 1.1 christos $in_html = 0; # am I inside an HTML section
512 1.1 christos $first_line = 1; # is it the first line
513 1.1 christos $dont_html = 0; # don't protect HTML on this line
514 1.1 christos $split_num = 0; # split index
515 1.1 christos $deferred_ref = ''; # deferred reference for indexes
516 1.1 christos @html_stack = (); # HTML elements stack
517 1.1 christos $html_element = ''; # current HTML element
518 1.1 christos &html_reset;
519 1.1 christos
520 1.1 christos # build code for simple substitutions
521 1.1 christos # the maps used (%simple_map and %things_map) MUST be aware of this
522 1.1 christos # watch out for regexps, / and escaped characters!
523 1.1 christos $subst_code = '';
524 1.1 christos foreach (keys(%simple_map)) {
525 1.1 christos ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars
526 1.1 christos $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n";
527 1.1 christos }
528 1.1 christos foreach (keys(%things_map)) {
529 1.1 christos $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n";
530 1.1 christos }
531 1.1 christos if ($use_acc) {
532 1.1 christos # accentuated characters
533 1.1 christos foreach (keys(%accent_map)) {
534 1.1 christos if ($_ eq "`") {
535 1.1 christos $subst_code .= "s/$;3";
536 1.1 christos } elsif ($_ eq "'") {
537 1.1 christos $subst_code .= "s/$;4";
538 1.1 christos } else {
539 1.1 christos $subst_code .= "s/\\\@\\$_";
540 1.1 christos }
541 1.1 christos $subst_code .= "([aeiou])/&\${1}$accent_map{$_};/gi;\n";
542 1.1 christos }
543 1.1 christos }
544 1.1 christos eval("sub simple_substitutions { $subst_code }");
545 1.1 christos
546 1.1 christos &init_input;
547 1.1 christos while ($_ = &next_line) {
548 1.1 christos #
549 1.1 christos # remove \input on the first lines only
550 1.1 christos #
551 1.1 christos if ($first_line) {
552 1.1 christos next if /^\\input/;
553 1.1 christos $first_line = 0;
554 1.1 christos }
555 1.1 christos #
556 1.1 christos # parse texinfo tags
557 1.1 christos #
558 1.1 christos $tag = '';
559 1.1 christos $end_tag = '';
560 1.1 christos if (/^\@end\s+(\w+)\b/) {
561 1.1 christos $end_tag = $1;
562 1.1 christos } elsif (/^\@(\w+)\b/) {
563 1.1 christos $tag = $1;
564 1.1 christos }
565 1.1 christos #
566 1.1 christos # handle @ifhtml / @end ifhtml
567 1.1 christos #
568 1.1 christos if ($in_html) {
569 1.1 christos if ($end_tag eq 'ifhtml') {
570 1.1 christos $in_html = 0;
571 1.1 christos } else {
572 1.1 christos $tag2pro{$in_html} .= $_;
573 1.1 christos }
574 1.1 christos next;
575 1.1 christos } elsif ($tag eq 'ifhtml') {
576 1.1 christos $in_html = $PROTECTTAG . ++$html_num;
577 1.1 christos push(@lines, $in_html);
578 1.1 christos next;
579 1.1 christos }
580 1.1 christos #
581 1.1 christos # try to skip the line
582 1.1 christos #
583 1.1 christos if ($end_tag) {
584 1.1 christos next if $to_skip{"end $end_tag"};
585 1.1 christos } elsif ($tag) {
586 1.1 christos next if $to_skip{$tag};
587 1.1 christos last if $tag eq 'bye';
588 1.1 christos }
589 1.1 christos if ($in_top) {
590 1.1 christos # parsing the top node
591 1.1 christos if ($tag eq 'node' || $tag eq 'include' || $sec2level{$tag}) {
592 1.1 christos # no more in top
593 1.1 christos $in_top = 0;
594 1.1 christos } else {
595 1.1 christos # skip it
596 1.1 christos next;
597 1.1 christos }
598 1.1 christos }
599 1.1 christos #
600 1.1 christos # try to remove inlined comments
601 1.1 christos # syntax from tex-mode.el comment-start-skip
602 1.1 christos #
603 1.1 christos s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/;
604 1.1 christos # non-@ substitutions cf. texinfmt.el
605 1.1 christos unless ($in_pre) {
606 1.1 christos s/``//g;
607 1.1 christos s/''//g;
608 1.1 christos s/([\w ])---([\w ])/$1--$2/g;
609 1.1 christos }
610 1.1 christos #
611 1.1 christos # analyze the tag
612 1.1 christos #
613 1.1 christos if ($tag) {
614 1.1 christos # skip lines
615 1.1 christos &skip_until($tag), next if $tag eq 'ignore';
616 1.1 christos if ($expandinfo) {
617 1.1 christos &skip_until($tag), next if $tag eq 'ifnotinfo';
618 1.1 christos &skip_until($tag), next if $tag eq 'iftex';
619 1.1 christos &skip_until($tag), next if $tag eq 'ifhtml';
620 1.1 christos } elsif ($expandtex) {
621 1.1 christos &skip_until($tag), next if $tag eq 'ifinfo';
622 1.1 christos &skip_until($tag), next if $tag eq 'ifnottex';
623 1.1 christos &skip_until($tag), next if $tag eq 'ifhtml';
624 1.1 christos } else {
625 1.1 christos &skip_until($tag), next if $tag eq 'ifinfo';
626 1.1 christos &skip_until($tag), next if $tag eq 'iftex';
627 1.1 christos &skip_until($tag), next if $tag eq 'ifnothtml';
628 1.1 christos }
629 1.1 christos &skip_until($tag), next if $tag eq 'tex';
630 1.1 christos # handle special tables
631 1.1 christos if ($tag =~ /^(|f|v|multi)table$/) {
632 1.1 christos $table_type = $1;
633 1.1 christos $tag = 'table';
634 1.1 christos }
635 1.1 christos # special cases
636 1.1 christos if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) {
637 1.1 christos $in_top = 1;
638 1.1 christos @lines = (); # ignore all lines before top (title page garbage)
639 1.1 christos next;
640 1.1 christos } elsif ($tag eq 'node') {
641 1.1 christos $in_top = 0;
642 1.1 christos warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o;
643 1.1 christos $_ = &protect_html($_); # if node contains '&' for instance
644 1.1 christos s/^\@node\s+//;
645 1.1 christos ($node) = split(/,/);
646 1.1 christos &normalise_node($node);
647 1.1 christos if ($split_node) {
648 1.1 christos &next_doc;
649 1.1 christos push(@lines, $SPLITTAG) if $split_num++;
650 1.1 christos push(@sections, $node);
651 1.1 christos }
652 1.1 christos next;
653 1.1 christos } elsif ($tag eq 'include') {
654 1.1 christos if (/^\@include\s+($FILERE)\s*$/o) {
655 1.1 christos $file = $1;
656 1.1 christos unless (-e $file) {
657 1.1 christos foreach $dir (@include_dirs) {
658 1.1 christos $file = "$dir/$1";
659 1.1 christos last if -e $file;
660 1.1 christos }
661 1.1 christos }
662 1.1 christos if (-e $file) {
663 1.1 christos &open($file);
664 1.1 christos print "# including $file\n" if $verbose;
665 1.1 christos } else {
666 1.1 christos warn "$ERROR Can't find $file, skipping";
667 1.1 christos }
668 1.1 christos } else {
669 1.1 christos warn "$ERROR Bad include line: $_";
670 1.1 christos }
671 1.1 christos next;
672 1.1 christos } elsif ($tag eq 'ifclear') {
673 1.1 christos if (/^\@ifclear\s+($VARRE)\s*$/o) {
674 1.1 christos next unless defined($value{$1});
675 1.1 christos &skip_until($tag);
676 1.1 christos } else {
677 1.1 christos warn "$ERROR Bad ifclear line: $_";
678 1.1 christos }
679 1.1 christos next;
680 1.1 christos } elsif ($tag eq 'ifset') {
681 1.1 christos if (/^\@ifset\s+($VARRE)\s*$/o) {
682 1.1 christos next if defined($value{$1});
683 1.1 christos &skip_until($tag);
684 1.1 christos } else {
685 1.1 christos warn "$ERROR Bad ifset line: $_";
686 1.1 christos }
687 1.1 christos next;
688 1.1 christos } elsif ($tag eq 'menu') {
689 1.1 christos unless ($show_menu) {
690 1.1 christos &skip_until($tag);
691 1.1 christos next;
692 1.1 christos }
693 1.1 christos &html_push_if($tag);
694 1.1 christos push(@lines, &html_debug("\n", __LINE__));
695 1.1 christos } elsif ($format_map{$tag}) {
696 1.1 christos $in_pre = 1 if $format_map{$tag} eq 'PRE';
697 1.1 christos &html_push_if($format_map{$tag});
698 1.1 christos push(@lines, &html_debug("\n", __LINE__));
699 1.1 christos $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ;
700 1.1 christos push(@lines, &debug("<$format_map{$tag}>\n", __LINE__));
701 1.1 christos next;
702 1.1 christos } elsif ($tag eq 'table') {
703 1.1 christos if (/^\@(|f|v|multi)table\s+\@(\w+)/) {
704 1.1 christos $in_table = $2;
705 1.1 christos unshift(@tables, join($;, $table_type, $in_table));
706 1.1 christos if ($table_type eq "multi") {
707 1.1 christos push(@lines, &debug("<TABLE BORDER>\n", __LINE__));
708 1.1 christos &html_push_if('TABLE');
709 1.1 christos } else {
710 1.1 christos push(@lines, &debug("<DL COMPACT>\n", __LINE__));
711 1.1 christos &html_push_if('DL');
712 1.1 christos }
713 1.1 christos push(@lines, &html_debug("\n", __LINE__));
714 1.1 christos } else {
715 1.1 christos warn "$ERROR Bad table line: $_";
716 1.1 christos }
717 1.1 christos next;
718 1.1 christos } elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') {
719 1.1 christos if (/^\@$tag\s+(\w)\w\s+(\w)\w\s*$/) {
720 1.1 christos eval("*${1}index = *${2}index");
721 1.1 christos } else {
722 1.1 christos warn "$ERROR Bad syn*index line: $_";
723 1.1 christos }
724 1.1 christos next;
725 1.1 christos } elsif ($tag eq 'sp') {
726 1.1 christos push(@lines, &debug("<P>\n", __LINE__));
727 1.1 christos next;
728 1.1 christos } elsif ($tag eq 'setref') {
729 1.1 christos &protect_html; # if setref contains '&' for instance
730 1.1 christos if (/^\@$tag\s*{($NODERE)}\s*$/) {
731 1.1 christos $setref = $1;
732 1.1 christos $setref =~ s/\s+/ /g; # normalize
733 1.1 christos $setref =~ s/ $//;
734 1.1 christos $node2sec{$setref} = $name;
735 1.1 christos $node2href{$setref} = "$docu_doc#$docid";
736 1.1 christos } else {
737 1.1 christos warn "$ERROR Bad setref line: $_";
738 1.1 christos }
739 1.1 christos next;
740 1.1 christos } elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') {
741 1.1 christos if (/^\@$tag\s+(\w\w)\s*$/) {
742 1.1 christos $valid_index{$1} = 1;
743 1.1 christos } else {
744 1.1 christos warn "$ERROR Bad defindex line: $_";
745 1.1 christos }
746 1.1 christos next;
747 1.1 christos } elsif (defined($def_map{$tag})) {
748 1.1 christos if ($def_map{$tag}) {
749 1.1 christos s/^\@$tag\s+//;
750 1.1 christos $tag = $def_map{$tag};
751 1.1 christos $_ = "\@$tag $_";
752 1.1 christos $tag =~ s/\s.*//;
753 1.1 christos }
754 1.1 christos } elsif (defined($user_sub{$tag})) {
755 1.1 christos s/^\@$tag\s+//;
756 1.1 christos $sub = $user_sub{$tag};
757 1.1 christos print "# user $tag = $sub, arg: $_" if $debug & $DEBUG_USER;
758 1.1 christos if (defined(&$sub)) {
759 1.1 christos chop($_);
760 1.1 christos &$sub($_);
761 1.1 christos } else {
762 1.1 christos warn "$ERROR Bad user sub for $tag: $sub\n";
763 1.1 christos }
764 1.1 christos next;
765 1.1 christos }
766 1.1 christos if (defined($def_map{$tag})) {
767 1.1 christos s/^\@$tag\s+//;
768 1.1 christos if ($tag =~ /x$/) {
769 1.1 christos # extra definition line
770 1.1 christos $tag = $`;
771 1.1 christos $is_extra = 1;
772 1.1 christos } else {
773 1.1 christos $is_extra = 0;
774 1.1 christos }
775 1.1 christos while (/\{([^\{\}]*)\}/) {
776 1.1 christos # this is a {} construct
777 1.1 christos ($before, $contents, $after) = ($`, $1, $');
778 1.1 christos # protect spaces
779 1.1 christos $contents =~ s/\s+/$;9/g;
780 1.1 christos # restore $_ protecting {}
781 1.1 christos $_ = "$before$;7$contents$;8$after";
782 1.1 christos }
783 1.1 christos @args = split(/\s+/, &protect_html($_));
784 1.1 christos foreach (@args) {
785 1.1 christos s/$;9/ /g; # unprotect spaces
786 1.1 christos s/$;7/\{/g; # ... {
787 1.1 christos s/$;8/\}/g; # ... }
788 1.1 christos }
789 1.1 christos $type = shift(@args);
790 1.1 christos $type =~ s/^\{(.*)\}$/$1/;
791 1.1 christos print "# def ($tag): {$type} ", join(', ', @args), "\n"
792 1.1 christos if $debug & $DEBUG_DEF;
793 1.1 christos $type .= ':'; # it's nicer like this
794 1.1 christos $name = shift(@args);
795 1.1 christos $name =~ s/^\{(.*)\}$/$1/;
796 1.1 christos if ($is_extra) {
797 1.1 christos $_ = &debug("<DT>", __LINE__);
798 1.1 christos } else {
799 1.1 christos $_ = &debug("<DL>\n<DT>", __LINE__);
800 1.1 christos }
801 1.1 christos if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') {
802 1.1 christos $_ .= "<U>$type</U> <B>$name</B>";
803 1.1 christos $_ .= " <I>@args</I>" if @args;
804 1.1 christos } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr'
805 1.1 christos || $tag eq 'defcv' || $tag eq 'defop') {
806 1.1 christos $ftype = $name;
807 1.1 christos $name = shift(@args);
808 1.1 christos $name =~ s/^\{(.*)\}$/$1/;
809 1.1 christos $_ .= "<U>$type</U> $ftype <B>$name</B>";
810 1.1 christos $_ .= " <I>@args</I>" if @args;
811 1.1 christos } else {
812 1.1 christos warn "$ERROR Unknown definition type: $tag\n";
813 1.1 christos $_ .= "<U>$type</U> <B>$name</B>";
814 1.1 christos $_ .= " <I>@args</I>" if @args;
815 1.1 christos }
816 1.1 christos $_ .= &debug("\n<DD>", __LINE__);
817 1.1 christos $name = &unprotect_html($name);
818 1.1 christos if ($tag eq 'deffn' || $tag eq 'deftypefn') {
819 1.1 christos unshift(@input_spool, "\@findex $name\n");
820 1.1 christos } elsif ($tag eq 'defop') {
821 1.1 christos unshift(@input_spool, "\@findex $name on $ftype\n");
822 1.1 christos } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') {
823 1.1 christos unshift(@input_spool, "\@vindex $name\n");
824 1.1 christos } else {
825 1.1 christos unshift(@input_spool, "\@tindex $name\n");
826 1.1 christos }
827 1.1 christos $dont_html = 1;
828 1.1 christos }
829 1.1 christos } elsif ($end_tag) {
830 1.1 christos if ($format_map{$end_tag}) {
831 1.1 christos $in_pre = 0 if $format_map{$end_tag} eq 'PRE';
832 1.1 christos $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ;
833 1.1 christos &html_pop_if('LI', 'P');
834 1.1 christos &html_pop_if();
835 1.1 christos push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__));
836 1.1 christos push(@lines, &html_debug("\n", __LINE__));
837 1.1 christos } elsif ($end_tag =~ /^(|f|v|multi)table$/) {
838 1.1 christos unless (@tables) {
839 1.1 christos warn "$ERROR \@end $end_tag without \@*table\n";
840 1.1 christos next;
841 1.1 christos }
842 1.1 christos ($table_type, $in_table) = split($;, shift(@tables));
843 1.1 christos unless ($1 eq $table_type) {
844 1.1 christos warn "$ERROR \@end $end_tag without matching \@$end_tag\n";
845 1.1 christos next;
846 1.1 christos }
847 1.1 christos if ($table_type eq "multi") {
848 1.1 christos push(@lines, "</TR></TABLE>\n");
849 1.1 christos &html_pop_if('TR');
850 1.1 christos } else {
851 1.1 christos push(@lines, "</DL>\n");
852 1.1 christos &html_pop_if('DD');
853 1.1 christos }
854 1.1 christos &html_pop_if();
855 1.1 christos if (@tables) {
856 1.1 christos ($table_type, $in_table) = split($;, $tables[0]);
857 1.1 christos } else {
858 1.1 christos $in_table = 0;
859 1.1 christos }
860 1.1 christos } elsif (defined($def_map{$end_tag})) {
861 1.1 christos push(@lines, &debug("</DL>\n", __LINE__));
862 1.1 christos } elsif ($end_tag eq 'menu') {
863 1.1 christos &html_pop_if();
864 1.1 christos push(@lines, $_); # must keep it for pass 2
865 1.1 christos }
866 1.1 christos next;
867 1.1 christos }
868 1.1 christos #
869 1.1 christos # misc things
870 1.1 christos #
871 1.1 christos # protect texi and HTML things
872 1.1 christos &protect_texi;
873 1.1 christos $_ = &protect_html($_) unless $dont_html;
874 1.1 christos $dont_html = 0;
875 1.1 christos # substitution (unsupported things)
876 1.1 christos s/^\@center\s+//g;
877 1.1 christos s/^\@exdent\s+//g;
878 1.1 christos s/\@noindent\s+//g;
879 1.1 christos s/\@refill\s+//g;
880 1.1 christos # other substitutions
881 1.1 christos &simple_substitutions;
882 1.1 christos s/\@value{($VARRE)}/$value{$1}/eg;
883 1.1 christos s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
884 1.1 christos #
885 1.1 christos # analyze the tag again
886 1.1 christos #
887 1.1 christos if ($tag) {
888 1.1 christos if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) {
889 1.1 christos if (/^\@$tag\s+(.+)$/) {
890 1.1 christos $name = $1;
891 1.1 christos $name =~ s/\s+$//;
892 1.1 christos $level = $sec2level{$tag};
893 1.1 christos $name = &update_sec_num($tag, $level) . " $name"
894 1.1 christos if $number_sections && $tag !~ /^unnumbered/;
895 1.1 christos if ($tag =~ /heading$/) {
896 1.1 christos push(@lines, &html_debug("\n", __LINE__));
897 1.1 christos if ($html_element ne 'body') {
898 1.1 christos # We are in a nice pickle here. We are trying to get a H? heading
899 1.1 christos # even though we are not in the body level. So, we convert it to a
900 1.1 christos # nice, bold, line by itself.
901 1.1 christos $_ = &debug("\n\n<P><STRONG>$name</STRONG></P>\n\n", __LINE__);
902 1.1 christos } else {
903 1.1 christos $_ = &debug("<H$level>$name</H$level>\n", __LINE__);
904 1.1 christos &html_push_if('body');
905 1.1 christos }
906 1.1 christos print "# heading, section $name, level $level\n"
907 1.1 christos if $debug & $DEBUG_TOC;
908 1.1 christos } else {
909 1.1 christos if ($split_chapter) {
910 1.1 christos unless ($toplevel) {
911 1.1 christos # first time we see a "section"
912 1.1 christos unless ($level == 1) {
913 1.1 christos warn "$ERROR The first section found is not of level 1: $_";
914 1.1 christos warn "$ERROR I'll split on sections of level $level...\n";
915 1.1 christos }
916 1.1 christos $toplevel = $level;
917 1.1 christos }
918 1.1 christos if ($level == $toplevel) {
919 1.1 christos &next_doc;
920 1.1 christos push(@lines, $SPLITTAG) if $split_num++;
921 1.1 christos push(@sections, $name);
922 1.1 christos }
923 1.1 christos }
924 1.1 christos $sec_num++;
925 1.1 christos $docid = "SEC$sec_num";
926 1.1 christos $tocid = "TOC$sec_num";
927 1.1 christos # check biblio and glossary
928 1.1 christos $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i);
929 1.1 christos $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i);
930 1.1 christos # check node
931 1.1 christos if ($node) {
932 1.1 christos if ($node2sec{$node}) {
933 1.1 christos warn "$ERROR Duplicate node found: $node\n";
934 1.1 christos } else {
935 1.1 christos $node2sec{$node} = $name;
936 1.1 christos $node2href{$node} = "$docu_doc#$docid";
937 1.1 christos print "# node $node, section $name, level $level\n"
938 1.1 christos if $debug & $DEBUG_TOC;
939 1.1 christos }
940 1.1 christos $node = '';
941 1.1 christos } else {
942 1.1 christos print "# no node, section $name, level $level\n"
943 1.1 christos if $debug & $DEBUG_TOC;
944 1.1 christos }
945 1.1 christos # update TOC
946 1.1 christos while ($level > $curlevel) {
947 1.1 christos $curlevel++;
948 1.1 christos push(@toc_lines, "<UL>\n");
949 1.1 christos }
950 1.1 christos while ($level < $curlevel) {
951 1.1 christos $curlevel--;
952 1.1 christos push(@toc_lines, "</UL>\n");
953 1.1 christos }
954 1.1 christos $_ = "<LI>" . &anchor($tocid, "$docu_doc#$docid", $name, 1);
955 1.1 christos push(@toc_lines, &substitute_style($_));
956 1.1 christos # update DOC
957 1.1 christos push(@lines, &html_debug("\n", __LINE__));
958 1.1 christos &html_reset;
959 1.1 christos $_ = "<H$level>".&anchor($docid, "$docu_toc#$tocid", $name)."</H$level>\n";
960 1.1 christos $_ = &debug($_, __LINE__);
961 1.1 christos push(@lines, &html_debug("\n", __LINE__));
962 1.1 christos }
963 1.1 christos # update DOC
964 1.1 christos foreach $line (split(/\n+/, $_)) {
965 1.1 christos push(@lines, "$line\n");
966 1.1 christos }
967 1.1 christos next;
968 1.1 christos } else {
969 1.1 christos warn "$ERROR Bad section line: $_";
970 1.1 christos }
971 1.1 christos } else {
972 1.1 christos # track variables
973 1.1 christos $value{$1} = $2, next if /^\@set\s+($VARRE)\s+(.*)$/o;
974 1.1 christos delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o;
975 1.1 christos # store things
976 1.1 christos $value{'_setfilename'} = $1, next if /^\@setfilename\s+(.*)$/;
977 1.1 christos $value{'_settitle'} = $1, next if /^\@settitle\s+(.*)$/;
978 1.1 christos $value{'_author'} .= "$1\n", next if /^\@author\s+(.*)$/;
979 1.1 christos $value{'_subtitle'} .= "$1\n", next if /^\@subtitle\s+(.*)$/;
980 1.1 christos $value{'_title'} .= "$1\n", next if /^\@title\s+(.*)$/;
981 1.1 christos # index
982 1.1 christos if (/^\@(..?)index\s+/) {
983 1.1 christos unless ($valid_index{$1}) {
984 1.1 christos warn "$ERROR Undefined index command: $_";
985 1.1 christos next;
986 1.1 christos }
987 1.1 christos $id = 'IDX' . ++$idx_num;
988 1.1 christos $index = $1 . 'index';
989 1.1 christos $what = &substitute_style($');
990 1.1 christos $what =~ s/\s+$//;
991 1.1 christos print "# found $index for '$what' id $id\n"
992 1.1 christos if $debug & $DEBUG_INDEX;
993 1.1 christos eval(<<EOC);
994 1.1 christos if (defined(\$$index\{\$what\})) {
995 1.1 christos \$$index\{\$what\} .= "$;$docu_doc#$id";
996 1.1 christos } else {
997 1.1 christos \$$index\{\$what\} = "$docu_doc#$id";
998 1.1 christos }
999 1.1 christos EOC
1000 1.1 christos #
1001 1.1 christos # dirty hack to see if I can put an invisible anchor...
1002 1.1 christos #
1003 1.1 christos if ($html_element eq 'P' ||
1004 1.1 christos $html_element eq 'LI' ||
1005 1.1 christos $html_element eq 'DT' ||
1006 1.1 christos $html_element eq 'DD' ||
1007 1.1 christos $html_element eq 'ADDRESS' ||
1008 1.1 christos $html_element eq 'B' ||
1009 1.1 christos $html_element eq 'BLOCKQUOTE' ||
1010 1.1 christos $html_element eq 'PRE' ||
1011 1.1 christos $html_element eq 'SAMP') {
1012 1.1 christos push(@lines, &anchor($id, '', $invisible_mark, !$in_pre));
1013 1.1 christos } elsif ($html_element eq 'body') {
1014 1.1 christos push(@lines, &debug("<P>\n", __LINE__));
1015 1.1 christos push(@lines, &anchor($id, '', $invisible_mark, !$in_pre));
1016 1.1 christos &html_push('P');
1017 1.1 christos } elsif ($html_element eq 'DL' ||
1018 1.1 christos $html_element eq 'UL' ||
1019 1.1 christos $html_element eq 'OL' ) {
1020 1.1 christos $deferred_ref .= &anchor($id, '', $invisible_mark, !$in_pre) . " ";
1021 1.1 christos }
1022 1.1 christos next;
1023 1.1 christos }
1024 1.1 christos # list item
1025 1.1 christos if (/^\@itemx?\s+/) {
1026 1.1 christos $what = $';
1027 1.1 christos $what =~ s/\s+$//;
1028 1.1 christos if ($in_bibliography && $use_bibliography) {
1029 1.1 christos if ($what =~ /^$BIBRE$/o) {
1030 1.1 christos $id = 'BIB' . ++$bib_num;
1031 1.1 christos $bib2href{$what} = "$docu_doc#$id";
1032 1.1 christos print "# found bibliography for '$what' id $id\n"
1033 1.1 christos if $debug & $DEBUG_BIB;
1034 1.1 christos $what = &anchor($id, '', $what);
1035 1.1 christos }
1036 1.1 christos } elsif ($in_glossary && $use_glossary) {
1037 1.1 christos $id = 'GLOSS' . ++$gloss_num;
1038 1.1 christos $entry = $what;
1039 1.1 christos $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
1040 1.1 christos $gloss2href{$entry} = "$docu_doc#$id";
1041 1.1 christos print "# found glossary for '$entry' id $id\n"
1042 1.1 christos if $debug & $DEBUG_GLOSS;
1043 1.1 christos $what = &anchor($id, '', $what);
1044 1.1 christos }
1045 1.1 christos &html_pop_if('P');
1046 1.1 christos if ($html_element eq 'DL' || $html_element eq 'DD') {
1047 1.1 christos if ($things_map{$in_table} && !$what) {
1048 1.1 christos # special case to allow @table @bullet for instance
1049 1.1 christos push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__));
1050 1.1 christos } else {
1051 1.1 christos push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__));
1052 1.1 christos }
1053 1.1 christos push(@lines, "<DD>");
1054 1.1 christos &html_push('DD') unless $html_element eq 'DD';
1055 1.1 christos if ($table_type) { # add also an index
1056 1.1 christos unshift(@input_spool, "\@${table_type}index $what\n");
1057 1.1 christos }
1058 1.1 christos } elsif ($html_element eq 'TABLE') {
1059 1.1 christos push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
1060 1.1 christos &html_push('TR');
1061 1.1 christos } elsif ($html_element eq 'TR') {
1062 1.1 christos push(@lines, &debug("</TR>\n", __LINE__));
1063 1.1 christos push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
1064 1.1 christos } else {
1065 1.1 christos push(@lines, &debug("<LI>$what\n", __LINE__));
1066 1.1 christos &html_push('LI') unless $html_element eq 'LI';
1067 1.1 christos }
1068 1.1 christos push(@lines, &html_debug("\n", __LINE__));
1069 1.1 christos if ($deferred_ref) {
1070 1.1 christos push(@lines, &debug("$deferred_ref\n", __LINE__));
1071 1.1 christos $deferred_ref = '';
1072 1.1 christos }
1073 1.1 christos next;
1074 1.1 christos } elsif (/^\@tab\s+(.*)$/) {
1075 1.1 christos push(@lines, "<TD>$1</TD>\n");
1076 1.1 christos next;
1077 1.1 christos }
1078 1.1 christos }
1079 1.1 christos }
1080 1.1 christos # paragraph separator
1081 1.1 christos if ($_ eq "\n") {
1082 1.1 christos next if $#lines >= 0 && $lines[$#lines] eq "\n";
1083 1.1 christos if ($html_element eq 'P') {
1084 1.1 christos push(@lines, "\n");
1085 1.1 christos $_ = &debug("</P>\n", __LINE__);
1086 1.1 christos &html_pop;
1087 1.1 christos }
1088 1.1 christos } elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE') {
1089 1.1 christos push(@lines, "<P>\n");
1090 1.1 christos &html_push('P');
1091 1.1 christos $_ = &debug($_, __LINE__);
1092 1.1 christos }
1093 1.1 christos # otherwise
1094 1.1 christos push(@lines, $_);
1095 1.1 christos }
1096 1.1 christos
1097 1.1 christos # finish TOC
1098 1.1 christos $level = 0;
1099 1.1 christos while ($level < $curlevel) {
1100 1.1 christos $curlevel--;
1101 1.1 christos push(@toc_lines, "</UL>\n");
1102 1.1 christos }
1103 1.1 christos
1104 1.1 christos print "# end of pass 1\n" if $verbose;
1105 1.1 christos
1106 1.1 christos #+++############################################################################
1107 1.1 christos # #
1108 1.1 christos # Pass 2/3: handle style, menu, index, cross-reference #
1109 1.1 christos # #
1110 1.1 christos #---############################################################################
1111 1.1 christos
1112 1.1 christos @lines2 = (); # whole document (2nd pass)
1113 1.1 christos @lines3 = (); # whole document (3rd pass)
1114 1.1 christos $in_menu = 0; # am I inside a menu
1115 1.1 christos
1116 1.1 christos while (@lines) {
1117 1.1 christos $_ = shift(@lines);
1118 1.1 christos #
1119 1.1 christos # special case (protected sections)
1120 1.1 christos #
1121 1.1 christos if (/^$PROTECTTAG/o) {
1122 1.1 christos push(@lines2, $_);
1123 1.1 christos next;
1124 1.1 christos }
1125 1.1 christos #
1126 1.1 christos # menu
1127 1.1 christos #
1128 1.1 christos $in_menu = 1, push(@lines2, &debug("<UL>\n", __LINE__)), next if /^\@menu\b/;
1129 1.1 christos $in_menu = 0, push(@lines2, &debug("</UL>\n", __LINE__)), next if /^\@end\s+menu\b/;
1130 1.1 christos if ($in_menu) {
1131 1.1 christos if (/^\*\s+($NODERE)::/o) {
1132 1.1 christos $descr = $';
1133 1.1 christos chop($descr);
1134 1.1 christos &menu_entry($1, $1, $descr);
1135 1.1 christos } elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) {
1136 1.1 christos $descr = $';
1137 1.1 christos chop($descr);
1138 1.1 christos &menu_entry($1, $2, $descr);
1139 1.1 christos } elsif (/^\*/) {
1140 1.1 christos warn "$ERROR Bad menu line: $_";
1141 1.1 christos } else { # description continued?
1142 1.1 christos push(@lines2, $_);
1143 1.1 christos }
1144 1.1 christos next;
1145 1.1 christos }
1146 1.1 christos #
1147 1.1 christos # printindex
1148 1.1 christos #
1149 1.1 christos if (/^\@printindex\s+(\w\w)\b/) {
1150 1.1 christos local($index, *ary, @keys, $key, $letter, $last_letter, @refs);
1151 1.1 christos if ($predefined_index{$1}) {
1152 1.1 christos $index = $predefined_index{$1} . 'index';
1153 1.1 christos } else {
1154 1.1 christos $index = $1 . 'index';
1155 1.1 christos }
1156 1.1 christos eval("*ary = *$index");
1157 1.1 christos @keys = keys(%ary);
1158 1.1 christos foreach $key (@keys) {
1159 1.1 christos $_ = $key;
1160 1.1 christos 1 while s/<(\w+)>\`(.*)\´<\/\1>/$2/; # remove HTML tags with quotes
1161 1.1 christos 1 while s/<(\w+)>(.*)<\/\1>/$2/; # remove HTML tags
1162 1.1 christos $_ = &unprotect_html($_);
1163 1.1 christos &unprotect_texi;
1164 1.1 christos tr/A-Z/a-z/; # lowercase
1165 1.1 christos $key2alpha{$key} = $_;
1166 1.1 christos print "# index $key sorted as $_\n"
1167 1.1 christos if $key ne $_ && $debug & $DEBUG_INDEX;
1168 1.1 christos }
1169 1.1 christos push(@lines2, "Jump to:\n");
1170 1.1 christos $last_letter = undef;
1171 1.1 christos foreach $key (sort byalpha @keys) {
1172 1.1 christos $letter = substr($key2alpha{$key}, 0, 1);
1173 1.1 christos $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;;
1174 1.1 christos if (!defined($last_letter) || $letter ne $last_letter) {
1175 1.1 christos push(@lines2, "-\n") if defined($last_letter);
1176 1.1 christos push(@lines2, "<A HREF=\"#$index\_$letter\">" . &protect_html($letter) . "</A>\n");
1177 1.1 christos $last_letter = $letter;
1178 1.1 christos }
1179 1.1 christos }
1180 1.1 christos push(@lines2, "<P>\n");
1181 1.1 christos $last_letter = undef;
1182 1.1 christos foreach $key (sort byalpha @keys) {
1183 1.1 christos $letter = substr($key2alpha{$key}, 0, 1);
1184 1.1 christos $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;;
1185 1.1 christos if (!defined($last_letter) || $letter ne $last_letter) {
1186 1.1 christos push(@lines2, "</DIR>\n") if defined($last_letter);
1187 1.1 christos push(@lines2, "<H2><A NAME=\"$index\_$letter\">" . &protect_html($letter) . "</A></H2>\n");
1188 1.1 christos push(@lines2, "<DIR>\n");
1189 1.1 christos $last_letter = $letter;
1190 1.1 christos }
1191 1.1 christos @refs = ();
1192 1.1 christos foreach (split(/$;/, $ary{$key})) {
1193 1.1 christos push(@refs, &anchor('', $_, $key, 0));
1194 1.1 christos }
1195 1.1 christos push(@lines2, "<LI>" . join(", ", @refs) . "\n");
1196 1.1 christos }
1197 1.1 christos push(@lines2, "</DIR>\n") if defined($last_letter);
1198 1.1 christos next;
1199 1.1 christos }
1200 1.1 christos #
1201 1.1 christos # simple style substitutions
1202 1.1 christos #
1203 1.1 christos $_ = &substitute_style($_);
1204 1.1 christos #
1205 1.1 christos # xref
1206 1.1 christos #
1207 1.1 christos while (/\@(x|px|info|)ref{($XREFRE)(}?)/o) {
1208 1.1 christos # note: Texinfo may accept other characters
1209 1.1 christos ($type, $nodes, $full) = ($1, $2, $3);
1210 1.1 christos ($before, $after) = ($`, $');
1211 1.1 christos if (! $full && $after) {
1212 1.1 christos warn "$ERROR Bad xref (no ending } on line): $_";
1213 1.1 christos $_ = "$before$;0${type}ref\{$nodes$after";
1214 1.1 christos next; # while xref
1215 1.1 christos }
1216 1.1 christos if ($type eq 'x') {
1217 1.1 christos $type = 'See ';
1218 1.1 christos } elsif ($type eq 'px') {
1219 1.1 christos $type = 'see ';
1220 1.1 christos } elsif ($type eq 'info') {
1221 1.1 christos $type = 'See Info';
1222 1.1 christos } else {
1223 1.1 christos $type = '';
1224 1.1 christos }
1225 1.1 christos unless ($full) {
1226 1.1 christos $next = shift(@lines);
1227 1.1 christos $next = &substitute_style($next);
1228 1.1 christos chop($nodes); # remove final newline
1229 1.1 christos if ($next =~ /\}/) { # split on 2 lines
1230 1.1 christos $nodes .= " $`";
1231 1.1 christos $after = $';
1232 1.1 christos } else {
1233 1.1 christos $nodes .= " $next";
1234 1.1 christos $next = shift(@lines);
1235 1.1 christos $next = &substitute_style($next);
1236 1.1 christos chop($nodes);
1237 1.1 christos if ($next =~ /\}/) { # split on 3 lines
1238 1.1 christos $nodes .= " $`";
1239 1.1 christos $after = $';
1240 1.1 christos } else {
1241 1.1 christos warn "$ERROR Bad xref (no ending }): $_";
1242 1.1 christos $_ = "$before$;0xref\{$nodes$after";
1243 1.1 christos unshift(@lines, $next);
1244 1.1 christos next; # while xref
1245 1.1 christos }
1246 1.1 christos }
1247 1.1 christos }
1248 1.1 christos $nodes =~ s/\s+/ /g; # remove useless spaces
1249 1.1 christos @args = split(/\s*,\s*/, $nodes);
1250 1.1 christos $node = $args[0]; # the node is always the first arg
1251 1.1 christos &normalise_node($node);
1252 1.1 christos $sec = $node2sec{$node};
1253 1.1 christos if (@args == 5) { # reference to another manual
1254 1.1 christos $sec = $args[2] || $node;
1255 1.1 christos $man = $args[4] || $args[3];
1256 1.1 christos $_ = "${before}${type}section $sec in \@cite{$man}$after";
1257 1.1 christos } elsif ($type =~ /Info/) { # inforef
1258 1.1 christos warn "$ERROR Wrong number of arguments: $_" unless @args == 3;
1259 1.1 christos ($nn, $_, $in) = @args;
1260 1.1 christos $_ = "${before}${type} file $in, node $nn$after";
1261 1.1 christos } elsif ($sec) {
1262 1.1 christos $href = $node2href{$node};
1263 1.1 christos $_ = "${before}${type}section " . &anchor('', $href, $sec) . $after;
1264 1.1 christos } else {
1265 1.1 christos warn "$ERROR Undefined node ($node): $_";
1266 1.1 christos $_ = "$before$;0xref{$nodes}$after";
1267 1.1 christos }
1268 1.1 christos }
1269 1.1 christos #
1270 1.1 christos # try to guess bibliography references or glossary terms
1271 1.1 christos #
1272 1.1 christos unless (/^<H\d><A NAME=\"SEC\d/) {
1273 1.1 christos if ($use_bibliography) {
1274 1.1 christos $done = '';
1275 1.1 christos while (/$BIBRE/o) {
1276 1.1 christos ($pre, $what, $post) = ($`, $&, $');
1277 1.1 christos $href = $bib2href{$what};
1278 1.1 christos if (defined($href) && $post !~ /^[^<]*<\/A>/) {
1279 1.1 christos $done .= $pre . &anchor('', $href, $what);
1280 1.1 christos } else {
1281 1.1 christos $done .= "$pre$what";
1282 1.1 christos }
1283 1.1 christos $_ = $post;
1284 1.1 christos }
1285 1.1 christos $_ = $done . $_;
1286 1.1 christos }
1287 1.1 christos if ($use_glossary) {
1288 1.1 christos $done = '';
1289 1.1 christos while (/\b\w+\b/) {
1290 1.1 christos ($pre, $what, $post) = ($`, $&, $');
1291 1.1 christos $entry = $what;
1292 1.1 christos $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
1293 1.1 christos $href = $gloss2href{$entry};
1294 1.1 christos if (defined($href) && $post !~ /^[^<]*<\/A>/) {
1295 1.1 christos $done .= $pre . &anchor('', $href, $what);
1296 1.1 christos } else {
1297 1.1 christos $done .= "$pre$what";
1298 1.1 christos }
1299 1.1 christos $_ = $post;
1300 1.1 christos }
1301 1.1 christos $_ = $done . $_;
1302 1.1 christos }
1303 1.1 christos }
1304 1.1 christos # otherwise
1305 1.1 christos push(@lines2, $_);
1306 1.1 christos }
1307 1.1 christos print "# end of pass 2\n" if $verbose;
1308 1.1 christos
1309 1.1 christos #
1310 1.1 christos # split style substitutions
1311 1.1 christos #
1312 1.1 christos while (@lines2) {
1313 1.1 christos $_ = shift(@lines2);
1314 1.1 christos #
1315 1.1 christos # special case (protected sections)
1316 1.1 christos #
1317 1.1 christos if (/^$PROTECTTAG/o) {
1318 1.1 christos push(@lines3, $_);
1319 1.1 christos next;
1320 1.1 christos }
1321 1.1 christos #
1322 1.1 christos # split style substitutions
1323 1.1 christos #
1324 1.1 christos $old = '';
1325 1.1 christos while ($old ne $_) {
1326 1.1 christos $old = $_;
1327 1.1 christos if (/\@(\w+|"|\~|,|\^)\{/) {
1328 1.1 christos ($before, $style, $after) = ($`, $1, $');
1329 1.1 christos if (defined($style_map{$style})) {
1330 1.1 christos $_ = $after;
1331 1.1 christos $text = '';
1332 1.1 christos $after = '';
1333 1.1 christos $failed = 1;
1334 1.1 christos while (@lines2) {
1335 1.1 christos if (/\}/) {
1336 1.1 christos $text .= $`;
1337 1.1 christos $after = $';
1338 1.1 christos $failed = 0;
1339 1.1 christos last;
1340 1.1 christos } else {
1341 1.1 christos $text .= $_;
1342 1.1 christos $_ = shift(@lines2);
1343 1.1 christos }
1344 1.1 christos }
1345 1.1 christos if ($failed) {
1346 1.1 christos die "* Bad syntax (\@$style) after: $before\n";
1347 1.1 christos } else {
1348 1.1 christos $text = &apply_style($style, $text);
1349 1.1 christos $_ = "$before$text$after";
1350 1.1 christos }
1351 1.1 christos }
1352 1.1 christos }
1353 1.1 christos }
1354 1.1 christos # otherwise
1355 1.1 christos push(@lines3, $_);
1356 1.1 christos }
1357 1.1 christos print "# end of pass 3\n" if $verbose;
1358 1.1 christos
1359 1.1 christos #+++############################################################################
1360 1.1 christos # #
1361 1.1 christos # Pass 4: foot notes, final cleanup #
1362 1.1 christos # #
1363 1.1 christos #---############################################################################
1364 1.1 christos
1365 1.1 christos @foot_lines = (); # footnotes
1366 1.1 christos @doc_lines = (); # final document
1367 1.1 christos $end_of_para = 0; # true if last line is <P>
1368 1.1 christos
1369 1.1 christos while (@lines3) {
1370 1.1 christos $_ = shift(@lines3);
1371 1.1 christos #
1372 1.1 christos # special case (protected sections)
1373 1.1 christos #
1374 1.1 christos if (/^$PROTECTTAG/o) {
1375 1.1 christos push(@doc_lines, $_);
1376 1.1 christos $end_of_para = 0;
1377 1.1 christos next;
1378 1.1 christos }
1379 1.1 christos #
1380 1.1 christos # footnotes
1381 1.1 christos #
1382 1.1 christos while (/\@footnote([^\{\s]+)\{/) {
1383 1.1 christos ($before, $d, $after) = ($`, $1, $');
1384 1.1 christos $_ = $after;
1385 1.1 christos $text = '';
1386 1.1 christos $after = '';
1387 1.1 christos $failed = 1;
1388 1.1 christos while (@lines3) {
1389 1.1 christos if (/\}/) {
1390 1.1 christos $text .= $`;
1391 1.1 christos $after = $';
1392 1.1 christos $failed = 0;
1393 1.1 christos last;
1394 1.1 christos } else {
1395 1.1 christos $text .= $_;
1396 1.1 christos $_ = shift(@lines3);
1397 1.1 christos }
1398 1.1 christos }
1399 1.1 christos if ($failed) {
1400 1.1 christos die "* Bad syntax (\@footnote) after: $before\n";
1401 1.1 christos } else {
1402 1.1 christos $foot_num++;
1403 1.1 christos $docid = "DOCF$foot_num";
1404 1.1 christos $footid = "FOOT$foot_num";
1405 1.1 christos $foot = "($foot_num)";
1406 1.1 christos push(@foot_lines, "<H3>" . &anchor($footid, "$d#$docid", $foot) . "</H3>\n");
1407 1.1 christos $text = "<P>$text" unless $text =~ /^\s*<P>/;
1408 1.1 christos push(@foot_lines, "$text\n");
1409 1.1 christos $_ = $before . &anchor($docid, "$docu_foot#$footid", $foot) . $after;
1410 1.1 christos }
1411 1.1 christos }
1412 1.1 christos #
1413 1.1 christos # remove unnecessary <P>
1414 1.1 christos #
1415 1.1 christos if (/^\s*<P>\s*$/) {
1416 1.1 christos next if $end_of_para++;
1417 1.1 christos } else {
1418 1.1 christos $end_of_para = 0;
1419 1.1 christos }
1420 1.1 christos # otherwise
1421 1.1 christos push(@doc_lines, $_);
1422 1.1 christos }
1423 1.1 christos print "# end of pass 4\n" if $verbose;
1424 1.1 christos
1425 1.1 christos #+++############################################################################
1426 1.1 christos # #
1427 1.1 christos # Pass 5: print things #
1428 1.1 christos # #
1429 1.1 christos #---############################################################################
1430 1.1 christos
1431 1.1 christos $header = <<EOT;
1432 1.1 christos <!-- This HTML file has been created by $THISPROG
1433 1.1 christos from $docu on $TODAY -->
1434 1.1 christos EOT
1435 1.1 christos
1436 1.1 christos $full_title = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
1437 1.1 christos $title = $value{'_settitle'} || $full_title;
1438 1.1 christos $_ = &substitute_style($full_title);
1439 1.1 christos &unprotect_texi;
1440 1.1 christos s/\n$//; # rmv last \n (if any)
1441 1.1 christos $full_title = "<H1>" . join("</H1>\n<H1>", split(/\n/, $_)) . "</H1>\n";
1442 1.1 christos
1443 1.1 christos #
1444 1.1 christos # print ToC
1445 1.1 christos #
1446 1.1 christos if (!$monolithic && @toc_lines) {
1447 1.1 christos if (open(FILE, "> $docu_toc")) {
1448 1.1 christos print "# creating $docu_toc...\n" if $verbose;
1449 1.1 christos &print_toplevel_header("$title - Table of Contents");
1450 1.1 christos &print_ruler;
1451 1.1 christos &print(*toc_lines, FILE);
1452 1.1 christos &print_toplevel_footer;
1453 1.1 christos close(FILE);
1454 1.1 christos } else {
1455 1.1 christos warn "$ERROR Can't write to $docu_toc: $!\n";
1456 1.1 christos }
1457 1.1 christos }
1458 1.1 christos
1459 1.1 christos #
1460 1.1 christos # print footnotes
1461 1.1 christos #
1462 1.1 christos if (!$monolithic && @foot_lines) {
1463 1.1 christos if (open(FILE, "> $docu_foot")) {
1464 1.1 christos print "# creating $docu_foot...\n" if $verbose;
1465 1.1 christos &print_toplevel_header("$title - Footnotes");
1466 1.1 christos &print_ruler;
1467 1.1 christos &print(*foot_lines, FILE);
1468 1.1 christos &print_toplevel_footer;
1469 1.1 christos close(FILE);
1470 1.1 christos } else {
1471 1.1 christos warn "$ERROR Can't write to $docu_foot: $!\n";
1472 1.1 christos }
1473 1.1 christos }
1474 1.1 christos
1475 1.1 christos #
1476 1.1 christos # print document
1477 1.1 christos #
1478 1.1 christos if ($split_chapter || $split_node) { # split
1479 1.1 christos $doc_num = 0;
1480 1.1 christos $last_num = scalar(@sections);
1481 1.1 christos $first_doc = &doc_name(1);
1482 1.1 christos $last_doc = &doc_name($last_num);
1483 1.1 christos while (@sections) {
1484 1.1 christos $section = shift(@sections);
1485 1.1 christos &next_doc;
1486 1.1 christos if (open(FILE, "> $docu_doc")) {
1487 1.1 christos print "# creating $docu_doc...\n" if $verbose;
1488 1.1 christos &print_header("$title - $section");
1489 1.1 christos $prev_doc = ($doc_num == 1 ? undef : &doc_name($doc_num - 1));
1490 1.1 christos $next_doc = ($doc_num == $last_num ? undef : &doc_name($doc_num + 1));
1491 1.1 christos $navigation = "Go to the ";
1492 1.1 christos $navigation .= ($prev_doc ? &anchor('', $first_doc, "first") : "first");
1493 1.1 christos $navigation .= ", ";
1494 1.1 christos $navigation .= ($prev_doc ? &anchor('', $prev_doc, "previous") : "previous");
1495 1.1 christos $navigation .= ", ";
1496 1.1 christos $navigation .= ($next_doc ? &anchor('', $next_doc, "next") : "next");
1497 1.1 christos $navigation .= ", ";
1498 1.1 christos $navigation .= ($next_doc ? &anchor('', $last_doc, "last") : "last");
1499 1.1 christos $navigation .= " section, " . &anchor('', $docu_toc, "table of contents") . ".\n";
1500 1.1 christos print FILE $navigation;
1501 1.1 christos &print_ruler;
1502 1.1 christos # find corresponding lines
1503 1.1 christos @tmp_lines = ();
1504 1.1 christos while (@doc_lines) {
1505 1.1 christos $_ = shift(@doc_lines);
1506 1.1 christos last if ($_ eq $SPLITTAG);
1507 1.1 christos push(@tmp_lines, $_);
1508 1.1 christos }
1509 1.1 christos &print(*tmp_lines, FILE);
1510 1.1 christos &print_ruler;
1511 1.1 christos print FILE $navigation;
1512 1.1 christos &print_footer;
1513 1.1 christos close(FILE);
1514 1.1 christos } else {
1515 1.1 christos warn "$ERROR Can't write to $docu_doc: $!\n";
1516 1.1 christos }
1517 1.1 christos }
1518 1.1 christos } else { # not split
1519 1.1 christos if (open(FILE, "> $docu_doc")) {
1520 1.1 christos print "# creating $docu_doc...\n" if $verbose;
1521 1.1 christos if ($monolithic || !@toc_lines) {
1522 1.1 christos &print_toplevel_header($title);
1523 1.1 christos } else {
1524 1.1 christos &print_header($title);
1525 1.1 christos print FILE $full_title;
1526 1.1 christos }
1527 1.1 christos if ($monolithic && @toc_lines) {
1528 1.1 christos &print_ruler;
1529 1.1 christos print FILE "<H1>Table of Contents</H1>\n";
1530 1.1 christos &print(*toc_lines, FILE);
1531 1.1 christos }
1532 1.1 christos &print_ruler;
1533 1.1 christos &print(*doc_lines, FILE);
1534 1.1 christos if ($monolithic && @foot_lines) {
1535 1.1 christos &print_ruler;
1536 1.1 christos print FILE "<H1>Footnotes</H1>\n";
1537 1.1 christos &print(*foot_lines, FILE);
1538 1.1 christos }
1539 1.1 christos if ($monolithic || !@toc_lines) {
1540 1.1 christos &print_toplevel_footer;
1541 1.1 christos } else {
1542 1.1 christos &print_footer;
1543 1.1 christos }
1544 1.1 christos close(FILE);
1545 1.1 christos } else {
1546 1.1 christos warn "$ERROR Can't write to $docu_doc: $!\n";
1547 1.1 christos }
1548 1.1 christos }
1549 1.1 christos
1550 1.1 christos print "# that's all folks\n" if $verbose;
1551 1.1 christos
1552 1.1 christos #+++############################################################################
1553 1.1 christos # #
1554 1.1 christos # Low level functions #
1555 1.1 christos # #
1556 1.1 christos #---############################################################################
1557 1.1 christos
1558 1.1 christos sub update_sec_num {
1559 1.1 christos local($name, $level) = @_;
1560 1.1 christos
1561 1.1 christos $level--; # here we start at 0
1562 1.1 christos if ($name =~ /^appendix/) {
1563 1.1 christos # appendix style
1564 1.1 christos if (defined(@appendix_sec_num)) {
1565 1.1 christos &incr_sec_num($level, @appendix_sec_num);
1566 1.1 christos } else {
1567 1.1 christos @appendix_sec_num = ('A', 0, 0, 0);
1568 1.1 christos }
1569 1.1 christos return(join('.', @appendix_sec_num[0..$level]));
1570 1.1 christos } else {
1571 1.1 christos # normal style
1572 1.1 christos if (defined(@normal_sec_num)) {
1573 1.1 christos &incr_sec_num($level, @normal_sec_num);
1574 1.1 christos } else {
1575 1.1 christos @normal_sec_num = (1, 0, 0, 0);
1576 1.1 christos }
1577 1.1 christos return(join('.', @normal_sec_num[0..$level]));
1578 1.1 christos }
1579 1.1 christos }
1580 1.1 christos
1581 1.1 christos sub incr_sec_num {
1582 1.1 christos local($level, $l);
1583 1.1 christos $level = shift(@_);
1584 1.1 christos $_[$level]++;
1585 1.1 christos foreach $l ($level+1 .. 3) {
1586 1.1 christos $_[$l] = 0;
1587 1.1 christos }
1588 1.1 christos }
1589 1.1 christos
1590 1.1 christos sub check {
1591 1.1 christos local($_, %seen, %context, $before, $match, $after);
1592 1.1 christos
1593 1.1 christos while (<>) {
1594 1.1 christos if (/\@(\*|\.|\:|\@|\{|\})/) {
1595 1.1 christos $seen{$&}++;
1596 1.1 christos $context{$&} .= "> $_" if $verbose;
1597 1.1 christos $_ = "$`XX$'";
1598 1.1 christos redo;
1599 1.1 christos }
1600 1.1 christos if (/\@(\w+)/) {
1601 1.1 christos ($before, $match, $after) = ($`, $&, $');
1602 1.1 christos if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address
1603 1.1 christos $seen{'e-mail address'}++;
1604 1.1 christos $context{'e-mail address'} .= "> $_" if $verbose;
1605 1.1 christos } else {
1606 1.1 christos $seen{$match}++;
1607 1.1 christos $context{$match} .= "> $_" if $verbose;
1608 1.1 christos }
1609 1.1 christos $match =~ s/^\@/X/;
1610 1.1 christos $_ = "$before$match$after";
1611 1.1 christos redo;
1612 1.1 christos }
1613 1.1 christos }
1614 1.1 christos
1615 1.1 christos foreach (sort(keys(%seen))) {
1616 1.1 christos if ($verbose) {
1617 1.1 christos print "$_\n";
1618 1.1 christos print $context{$_};
1619 1.1 christos } else {
1620 1.1 christos print "$_ ($seen{$_})\n";
1621 1.1 christos }
1622 1.1 christos }
1623 1.1 christos }
1624 1.1 christos
1625 1.1 christos sub open {
1626 1.1 christos local($name) = @_;
1627 1.1 christos
1628 1.1 christos ++$fh_name;
1629 1.1 christos if (open($fh_name, $name)) {
1630 1.1 christos unshift(@fhs, $fh_name);
1631 1.1 christos } else {
1632 1.1 christos warn "$ERROR Can't read file $name: $!\n";
1633 1.1 christos }
1634 1.1 christos }
1635 1.1 christos
1636 1.1 christos sub init_input {
1637 1.1 christos @fhs = (); # hold the file handles to read
1638 1.1 christos @input_spool = (); # spooled lines to read
1639 1.1 christos $fh_name = 'FH000';
1640 1.1 christos &open($docu);
1641 1.1 christos }
1642 1.1 christos
1643 1.1 christos sub next_line {
1644 1.1 christos local($fh, $line);
1645 1.1 christos
1646 1.1 christos if (@input_spool) {
1647 1.1 christos $line = shift(@input_spool);
1648 1.1 christos return($line);
1649 1.1 christos }
1650 1.1 christos while (@fhs) {
1651 1.1 christos $fh = $fhs[0];
1652 1.1 christos $line = <$fh>;
1653 1.1 christos return($line) if $line;
1654 1.1 christos close($fh);
1655 1.1 christos shift(@fhs);
1656 1.1 christos }
1657 1.1 christos return(undef);
1658 1.1 christos }
1659 1.1 christos
1660 1.1 christos # used in pass 1, use &next_line
1661 1.1 christos sub skip_until {
1662 1.1 christos local($tag) = @_;
1663 1.1 christos local($_);
1664 1.1 christos
1665 1.1 christos while ($_ = &next_line) {
1666 1.1 christos return if /^\@end\s+$tag\s*$/;
1667 1.1 christos }
1668 1.1 christos die "* Failed to find '$tag' after: " . $lines[$#lines];
1669 1.1 christos }
1670 1.1 christos
1671 1.1 christos #
1672 1.1 christos # HTML stacking to have a better HTML output
1673 1.1 christos #
1674 1.1 christos
1675 1.1 christos sub html_reset {
1676 1.1 christos @html_stack = ('html');
1677 1.1 christos $html_element = 'body';
1678 1.1 christos }
1679 1.1 christos
1680 1.1 christos sub html_push {
1681 1.1 christos local($what) = @_;
1682 1.1 christos push(@html_stack, $html_element);
1683 1.1 christos $html_element = $what;
1684 1.1 christos }
1685 1.1 christos
1686 1.1 christos sub html_push_if {
1687 1.1 christos local($what) = @_;
1688 1.1 christos push(@html_stack, $html_element)
1689 1.1 christos if ($html_element && $html_element ne 'P');
1690 1.1 christos $html_element = $what;
1691 1.1 christos }
1692 1.1 christos
1693 1.1 christos sub html_pop {
1694 1.1 christos $html_element = pop(@html_stack);
1695 1.1 christos }
1696 1.1 christos
1697 1.1 christos sub html_pop_if {
1698 1.1 christos local($elt);
1699 1.1 christos
1700 1.1 christos if (@_) {
1701 1.1 christos foreach $elt (@_) {
1702 1.1 christos if ($elt eq $html_element) {
1703 1.1 christos $html_element = pop(@html_stack) if @html_stack;
1704 1.1 christos last;
1705 1.1 christos }
1706 1.1 christos }
1707 1.1 christos } else {
1708 1.1 christos $html_element = pop(@html_stack) if @html_stack;
1709 1.1 christos }
1710 1.1 christos }
1711 1.1 christos
1712 1.1 christos sub html_debug {
1713 1.1 christos local($what, $line) = @_;
1714 1.1 christos return("<!-- $line @html_stack, $html_element -->$what")
1715 1.1 christos if $debug & $DEBUG_HTML;
1716 1.1 christos return($what);
1717 1.1 christos }
1718 1.1 christos
1719 1.1 christos # to debug the output...
1720 1.1 christos sub debug {
1721 1.1 christos local($what, $line) = @_;
1722 1.1 christos return("<!-- $line -->$what")
1723 1.1 christos if $debug & $DEBUG_HTML;
1724 1.1 christos return($what);
1725 1.1 christos }
1726 1.1 christos
1727 1.1 christos sub normalise_node {
1728 1.1 christos $_[0] =~ s/\s+/ /g;
1729 1.1 christos $_[0] =~ s/ $//;
1730 1.1 christos $_[0] =~ s/^ //;
1731 1.1 christos }
1732 1.1 christos
1733 1.1 christos sub menu_entry {
1734 1.1 christos local($entry, $node, $descr) = @_;
1735 1.1 christos local($href);
1736 1.1 christos
1737 1.1 christos &normalise_node($node);
1738 1.1 christos $href = $node2href{$node};
1739 1.1 christos if ($href) {
1740 1.1 christos $descr =~ s/^\s+//;
1741 1.1 christos $descr = ": $descr" if $descr;
1742 1.1 christos push(@lines2, "<LI>" . &anchor('', $href, $entry) . "$descr\n");
1743 1.1 christos } else {
1744 1.1 christos warn "$ERROR Undefined node ($node): $_";
1745 1.1 christos }
1746 1.1 christos }
1747 1.1 christos
1748 1.1 christos sub do_ctrl { "^$_[0]" }
1749 1.1 christos
1750 1.1 christos sub do_email {
1751 1.1 christos local($addr, $text) = split(/,\s*/, $_[0]);
1752 1.1 christos
1753 1.1 christos $text = $addr unless $text;
1754 1.1 christos &anchor('', "mailto:$addr", $text);
1755 1.1 christos }
1756 1.1 christos
1757 1.1 christos sub do_sc { "\U$_[0]\E" }
1758 1.1 christos
1759 1.1 christos sub do_uref {
1760 1.1 christos local($url, $text) = split(/,\s*/, $_[0]);
1761 1.1 christos
1762 1.1 christos $text = $url unless $text;
1763 1.1 christos &anchor('', $url, $text);
1764 1.1 christos }
1765 1.1 christos
1766 1.1 christos sub do_url { &anchor('', $_[0], $_[0]) }
1767 1.1 christos
1768 1.1 christos sub do_diaeresis { return "&$_[0]uml;"; }
1769 1.1 christos sub do_acuteaccent { return "&$_[0]acute;"; }
1770 1.1 christos sub do_graveaccent { return "&$_[0]grave;"; }
1771 1.1 christos sub do_tildeaccent { return "&$_[0]tilde;"; }
1772 1.1 christos sub do_cedilla { return "&$_[0]cedil;"; }
1773 1.1 christos sub do_circumflex { return "&$_[0]circ;"; }
1774 1.1 christos
1775 1.1 christos sub apply_style {
1776 1.1 christos local($texi_style, $text) = @_;
1777 1.1 christos local($style);
1778 1.1 christos
1779 1.1 christos $style = $style_map{$texi_style};
1780 1.1 christos if (defined($style)) { # known style
1781 1.1 christos if ($style =~ /^\"/) { # add quotes
1782 1.1 christos $style = $';
1783 1.1 christos $text = "\‘$text\’";
1784 1.1 christos }
1785 1.1 christos if ($style =~ /^\&/) { # custom
1786 1.1 christos $style = $';
1787 1.1 christos $text = &$style($text);
1788 1.1 christos } elsif ($style) { # good style
1789 1.1 christos $text = "<$style>$text</$style>";
1790 1.1 christos } else { # no style
1791 1.1 christos }
1792 1.1 christos } else { # unknown style
1793 1.1 christos $text = undef;
1794 1.1 christos }
1795 1.1 christos return($text);
1796 1.1 christos }
1797 1.1 christos
1798 1.1 christos # remove Texinfo styles
1799 1.1 christos sub remove_style {
1800 1.1 christos local($_) = @_;
1801 1.1 christos s/\@\w+{([^\{\}]+)}/$1/g;
1802 1.1 christos return($_);
1803 1.1 christos }
1804 1.1 christos
1805 1.1 christos sub substitute_style {
1806 1.1 christos local($_) = @_;
1807 1.1 christos local($changed, $done, $style, $text);
1808 1.1 christos
1809 1.1 christos $changed = 1;
1810 1.1 christos while ($changed) {
1811 1.1 christos $changed = 0;
1812 1.1 christos $done = '';
1813 1.1 christos while (/\@(\w+|"|\~|,|\^){([^\{\}]+)}/) {
1814 1.1 christos $text = &apply_style($1, $2);
1815 1.1 christos if ($text) {
1816 1.1 christos $_ = "$`$text$'";
1817 1.1 christos $changed = 1;
1818 1.1 christos } else {
1819 1.1 christos $done .= "$`\@$1";
1820 1.1 christos $_ = "{$2}$'";
1821 1.1 christos }
1822 1.1 christos }
1823 1.1 christos $_ = $done . $_;
1824 1.1 christos }
1825 1.1 christos return($_);
1826 1.1 christos }
1827 1.1 christos
1828 1.1 christos sub anchor {
1829 1.1 christos local($name, $href, $text, $newline) = @_;
1830 1.1 christos local($result);
1831 1.1 christos
1832 1.1 christos $result = "<A";
1833 1.1 christos $result .= " NAME=\"$name\"" if $name;
1834 1.1 christos $result .= " HREF=\"$href\"" if $href;
1835 1.1 christos $result .= ">$text</A>";
1836 1.1 christos $result .= "\n" if $newline;
1837 1.1 christos return($result);
1838 1.1 christos }
1839 1.1 christos
1840 1.1 christos sub pretty_date {
1841 1.1 christos local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
1842 1.1 christos
1843 1.1 christos @MoY = ('January', 'Febuary', 'March', 'April', 'May', 'June',
1844 1.1 christos 'July', 'August', 'September', 'October', 'November', 'December');
1845 1.1 christos ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
1846 1.1 christos $year += ($year < 70) ? 2000 : 1900;
1847 1.1 christos return("$mday $MoY[$mon] $year");
1848 1.1 christos }
1849 1.1 christos
1850 1.1 christos sub doc_name {
1851 1.1 christos local($num) = @_;
1852 1.1 christos
1853 1.1 christos return("${docu_name}_$num.html");
1854 1.1 christos }
1855 1.1 christos
1856 1.1 christos sub next_doc {
1857 1.1 christos $docu_doc = &doc_name(++$doc_num);
1858 1.1 christos }
1859 1.1 christos
1860 1.1 christos sub print {
1861 1.1 christos local(*lines, $fh) = @_;
1862 1.1 christos local($_);
1863 1.1 christos
1864 1.1 christos while (@lines) {
1865 1.1 christos $_ = shift(@lines);
1866 1.1 christos if (/^$PROTECTTAG/o) {
1867 1.1 christos $_ = $tag2pro{$_};
1868 1.1 christos } else {
1869 1.1 christos &unprotect_texi;
1870 1.1 christos }
1871 1.1 christos print $fh $_;
1872 1.1 christos }
1873 1.1 christos }
1874 1.1 christos
1875 1.1 christos sub print_ruler {
1876 1.1 christos print FILE "<P><HR><P>\n";
1877 1.1 christos }
1878 1.1 christos
1879 1.1 christos sub print_header {
1880 1.1 christos local($_);
1881 1.1 christos
1882 1.1 christos # clean the title
1883 1.1 christos $_ = &remove_style($_[0]);
1884 1.1 christos &unprotect_texi;
1885 1.1 christos # print the header
1886 1.1 christos if ($doctype eq 'html2') {
1887 1.1 christos print FILE $html2_doctype;
1888 1.1 christos } elsif ($doctype) {
1889 1.1 christos print FILE $doctype;
1890 1.1 christos }
1891 1.1 christos print FILE <<EOT;
1892 1.1 christos <HTML>
1893 1.1 christos <HEAD>
1894 1.1 christos $header
1895 1.1 christos <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
1896 1.1 christos <TITLE>$_</TITLE>
1897 1.1 christos </HEAD>
1898 1.1 christos <BODY>
1899 1.1 christos EOT
1900 1.1 christos }
1901 1.1 christos
1902 1.1 christos sub print_toplevel_header {
1903 1.1 christos local($_);
1904 1.1 christos
1905 1.1 christos &print_header; # pass given arg...
1906 1.1 christos print FILE $full_title;
1907 1.1 christos if ($value{'_subtitle'}) {
1908 1.1 christos $value{'_subtitle'} =~ s/\n+$//;
1909 1.1 christos foreach (split(/\n/, $value{'_subtitle'})) {
1910 1.1 christos $_ = &substitute_style($_);
1911 1.1 christos &unprotect_texi;
1912 1.1 christos print FILE "<H2>$_</H2>\n";
1913 1.1 christos }
1914 1.1 christos }
1915 1.1 christos if ($value{'_author'}) {
1916 1.1 christos $value{'_author'} =~ s/\n+$//;
1917 1.1 christos foreach (split(/\n/, $value{'_author'})) {
1918 1.1 christos $_ = &substitute_style($_);
1919 1.1 christos &unprotect_texi;
1920 1.1 christos s/[\w.-]+\@[\w.-]+/<A HREF="mailto:$&">$&<\/A>/g;
1921 1.1 christos print FILE "<ADDRESS>$_</ADDRESS>\n";
1922 1.1 christos }
1923 1.1 christos }
1924 1.1 christos print FILE "<P>\n";
1925 1.1 christos }
1926 1.1 christos
1927 1.1 christos sub print_footer {
1928 1.1 christos print FILE <<EOT;
1929 1.1 christos </BODY>
1930 1.1 christos </HTML>
1931 1.1 christos EOT
1932 1.1 christos }
1933 1.1 christos
1934 1.1 christos sub print_toplevel_footer {
1935 1.1 christos &print_ruler;
1936 1.1 christos print FILE <<EOT;
1937 1.1 christos This document was generated on $TODAY using the
1938 1.1 christos <A HREF=\"$HOMEPAGE\">texi2html</A>
1939 1.1 christos translator version 1.52b.</P>
1940 1.1 christos EOT
1941 1.1 christos &print_footer;
1942 1.1 christos }
1943 1.1 christos
1944 1.1 christos sub protect_texi {
1945 1.1 christos # protect @ { } ` '
1946 1.1 christos s/\@\@/$;0/go;
1947 1.1 christos s/\@\{/$;1/go;
1948 1.1 christos s/\@\}/$;2/go;
1949 1.1 christos s/\@\`/$;3/go;
1950 1.1 christos s/\@\'/$;4/go;
1951 1.1 christos }
1952 1.1 christos
1953 1.1 christos sub protect_html {
1954 1.1 christos local($what) = @_;
1955 1.1 christos # protect & < >
1956 1.1 christos $what =~ s/\&/\&\#38;/g;
1957 1.1 christos $what =~ s/\</\&\#60;/g;
1958 1.1 christos $what =~ s/\>/\&\#62;/g;
1959 1.1 christos # but recognize some HTML things
1960 1.1 christos $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g; # </A>
1961 1.1 christos $what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g; # <A [^&]+>
1962 1.1 christos $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+>
1963 1.1 christos return($what);
1964 1.1 christos }
1965 1.1 christos
1966 1.1 christos sub unprotect_texi {
1967 1.1 christos s/$;0/\@/go;
1968 1.1 christos s/$;1/\{/go;
1969 1.1 christos s/$;2/\}/go;
1970 1.1 christos s/$;3/\`/go;
1971 1.1 christos s/$;4/\'/go;
1972 1.1 christos }
1973 1.1 christos
1974 1.1 christos sub unprotect_html {
1975 1.1 christos local($what) = @_;
1976 1.1 christos $what =~ s/\&\#38;/\&/g;
1977 1.1 christos $what =~ s/\&\#60;/\</g;
1978 1.1 christos $what =~ s/\&\#62;/\>/g;
1979 1.1 christos return($what);
1980 1.1 christos }
1981 1.1 christos
1982 1.1 christos sub byalpha {
1983 1.1 christos $key2alpha{$a} cmp $key2alpha{$b};
1984 1.1 christos }
1985 1.1 christos
1986 1.1 christos ##############################################################################
1987 1.1 christos
1988 1.1 christos # These next few lines are legal in both Perl and nroff.
1989 1.1 christos
1990 1.1 christos .00 ; # finish .ig
1991 1.1 christos
1992 1.1 christos 'di \" finish diversion--previous line must be blank
1993 1.1 christos .nr nl 0-1 \" fake up transition to first page again
1994 1.1 christos .nr % 0 \" start at page 1
1995 1.1 christos '; __END__ ############# From here on it's a standard manual page ############
1996 1.1 christos .TH TEXI2HTML 1 "01/05/98"
1997 1.1 christos .AT 3
1998 1.1 christos .SH NAME
1999 1.1 christos texi2html \- a Texinfo to HTML converter
2000 1.1 christos .SH SYNOPSIS
2001 1.1 christos .B texi2html [options] file
2002 1.1 christos .PP
2003 1.1 christos .B texi2html -check [-verbose] files
2004 1.1 christos .SH DESCRIPTION
2005 1.1 christos .I Texi2html
2006 1.1 christos converts the given Texinfo file to a set of HTML files. It tries to handle
2007 1.1 christos most of the Texinfo commands. It creates hypertext links for cross-references,
2008 1.1 christos footnotes...
2009 1.1 christos .PP
2010 1.1 christos It also tries to add links from a reference to its corresponding entry in the
2011 1.1 christos bibliography (if any). It may also handle a glossary (see the
2012 1.1 christos .B \-glossary
2013 1.1 christos option).
2014 1.1 christos .PP
2015 1.1 christos .I Texi2html
2016 1.1 christos creates several files depending on the contents of the Texinfo file and on
2017 1.1 christos the chosen options (see FILES).
2018 1.1 christos .PP
2019 1.1 christos The HTML files created by
2020 1.1 christos .I texi2html
2021 1.1 christos are closer to TeX than to Info, that's why
2022 1.1 christos .I texi2html
2023 1.1 christos converts @ifhtml sections and not @ifinfo or @iftex ones by default. You can
2024 1.1 christos change this with the \-expandinfo or \-expandtex options.
2025 1.1 christos .SH OPTIONS
2026 1.1 christos .TP 12
2027 1.1 christos .B \-check
2028 1.1 christos Check the given file and give the list of all things that may be Texinfo commands.
2029 1.1 christos This may be used to check the output of
2030 1.1 christos .I texi2html
2031 1.1 christos to find the Texinfo commands that have been left in the HTML file.
2032 1.1 christos .TP
2033 1.1 christos .B \-expandinfo
2034 1.1 christos Expand @ifinfo sections, not @ifhtml ones.
2035 1.1 christos .TP
2036 1.1 christos .B \-expandtex
2037 1.1 christos Expand @iftex sections, not @ifhtml ones.
2038 1.1 christos .TP
2039 1.1 christos .B \-glossary
2040 1.1 christos Use the section named 'Glossary' to build a list of terms and put links in the HTML
2041 1.1 christos document from each term toward its definition.
2042 1.1 christos .TP
2043 1.1 christos .B \-invisible \fIname\fP
2044 1.1 christos Use \fIname\fP to create invisible destination anchors for index links
2045 1.1 christos (you can for instance use the invisible.xbm file shipped with this program).
2046 1.1 christos This is a workaround for a known bug of many WWW browsers, including netscape.
2047 1.1 christos .TP
2048 1.1 christos .B \-I \fIdir\fP
2049 1.1 christos Look also in \fIdir\fP to find included files.
2050 1.1 christos .TP
2051 1.1 christos .B \-menu
2052 1.1 christos Show the Texinfo menus; by default they are ignored.
2053 1.1 christos .TP
2054 1.1 christos .B \-monolithic
2055 1.1 christos Output only one file, including the table of contents and footnotes.
2056 1.1 christos .TP
2057 1.1 christos .B \-number
2058 1.1 christos Number the sections.
2059 1.1 christos .TP
2060 1.1 christos .B \-split_chapter
2061 1.1 christos Split the output into several HTML files (one per main section:
2062 1.1 christos chapter, appendix...).
2063 1.1 christos .TP
2064 1.1 christos .B \-split_node
2065 1.1 christos Split the output into several HTML files (one per node).
2066 1.1 christos .TP
2067 1.1 christos .B \-usage
2068 1.1 christos Print usage instructions, listing the current available command-line options.
2069 1.1 christos .TP
2070 1.1 christos .B \-verbose
2071 1.1 christos Give a verbose output. Can be used with the
2072 1.1 christos .B \-check
2073 1.1 christos option.
2074 1.1 christos .PP
2075 1.1 christos .SH FILES
2076 1.1 christos By default
2077 1.1 christos .I texi2html
2078 1.1 christos creates the following files (foo being the name of the Texinfo file):
2079 1.1 christos .TP 16
2080 1.1 christos .B foo_toc.html
2081 1.1 christos The table of contents.
2082 1.1 christos .TP
2083 1.1 christos .B foo.html
2084 1.1 christos The document's contents.
2085 1.1 christos .TP
2086 1.1 christos .B foo_foot.html
2087 1.1 christos The footnotes (if any).
2088 1.1 christos .PP
2089 1.1 christos When used with the
2090 1.1 christos .B \-split
2091 1.1 christos option, it creates several files (one per chapter or node), named
2092 1.1 christos .B foo_n.html
2093 1.1 christos (n being the indice of the chapter or node), instead of the single
2094 1.1 christos .B foo.html
2095 1.1 christos file.
2096 1.1 christos .PP
2097 1.1 christos When used with the
2098 1.1 christos .B \-monolithic
2099 1.1 christos option, it creates only one file:
2100 1.1 christos .B foo.html
2101 1.1 christos .SH VARIABLES
2102 1.1 christos .I texi2html
2103 1.1 christos predefines the following variables: \fBhtml\fP, \fBtexi2html\fP.
2104 1.1 christos .SH ADDITIONAL COMMANDS
2105 1.1 christos .I texi2html
2106 1.1 christos implements the following non-Texinfo commands (maybe they are in Texinfo now...):
2107 1.1 christos .TP 16
2108 1.1 christos .B @ifhtml
2109 1.1 christos This indicates the start of an HTML section, this section will passed through
2110 1.1 christos without any modification.
2111 1.1 christos .TP
2112 1.1 christos .B @end ifhtml
2113 1.1 christos This indicates the end of an HTML section.
2114 1.1 christos .SH VERSION
2115 1.1 christos This is \fItexi2html\fP version 1.52b, 01/05/98.
2116 1.1 christos .PP
2117 1.1 christos The latest version of \fItexi2html\fP can be found in WWW, cf. URL
2118 1.1 christos http://wwwinfo.cern.ch/dis/texi2html/
2119 1.1 christos .SH AUTHOR
2120 1.1 christos The main author is Lionel Cons, CERN IT/DIS/OSE, Lionel.Cons (at] cern.ch.
2121 1.1 christos Many other people around the net contributed to this program.
2122 1.1 christos .SH COPYRIGHT
2123 1.1 christos This program is the intellectual property of the European
2124 1.1 christos Laboratory for Particle Physics (known as CERN). No guarantee whatsoever is
2125 1.1 christos provided by CERN. No liability whatsoever is accepted for any loss or damage
2126 1.1 christos of any kind resulting from any defect or inaccuracy in this information or
2127 1.1 christos code.
2128 1.1 christos .PP
2129 1.1 christos CERN, 1211 Geneva 23, Switzerland
2130 1.1 christos .SH "SEE ALSO"
2131 1.1 christos GNU Texinfo Documentation Format,
2132 1.1 christos HyperText Markup Language (HTML),
2133 1.1 christos World Wide Web (WWW).
2134 1.1 christos .SH BUGS
2135 1.1 christos This program does not understand all Texinfo commands (yet).
2136 1.1 christos .ex
2137