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