4 #+##############################################################################
8 # Description: Program to transform most Texinfo documents to HTML #
10 #-##############################################################################
12 $THISPROG = "texi2html 1.52"; # program name and version
13 # This version of texi2html is currently maintained at
14 # ftp://ftp.cs.umb.edu/pub/tex/texi2html by kb@cs.umb.edu.
16 # w schelter: made minor changes to allow the @anchor construct. so
17 # you can do "See @ref{FACTOR} and @ref{GFACTOR}." if you put in
18 # @anchor{FACTOR} just before the definition of FACTOR.. the new
19 # texi2html by olaf does @anchor, but it uses tables so heavily that
20 # netmath cannot view its output properly. Also I like the way the
21 # index is done here as one file, and several other features.
23 # The man page for this program is included at the end of this file and can be
24 # viewed using the command 'nroff -man texi2html'.
25 # Please read the copyright at the end of the man page.
28 # deal with @macro @unmacro @shorttitlepage @detailmenu @image
29 # [plus more fixmes below]
30 # Use <link>s for Up, Index, Glossary?
31 # Inserting copyright links: Having texinfo markup for the online copyright
32 # would allow a link to that from wherever.
34 #+++############################################################################
38 #---############################################################################
48 $BIBRE = '\[[\w\/]+\]'; # RE for a bibliography reference
49 $FILERE = '[\/\w.+-]+'; # RE for a file name
50 $VARRE = '[^\s\{\}]+'; # RE for a variable name
51 $NODERE = '[^@{}:\'`",]+'; # RE for a node name
52 $NODESRE = '[^@{}:\'`"]+'; # RE for a list of node names
53 $XREFRE = '[^@{}]+'; # RE for a xref (should use NODERE)
55 $ERROR = "***"; # prefix for errors and warnings
56 $HOMEPAGE = "http://wwwcn.cern.ch/dci/texi2html/"; # program home page
57 $TODAY = &pretty_date
; # like "20 September 1993"
58 $SPLITTAG = "<!-- SPLIT HERE -->\n"; # tag to know where to split
59 $PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections
60 $TOPTAG = "<!--top-->"; # tag to mark first node (end of preamble)
61 $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//EN">';
64 # language dependent constants
67 #$LDC_SECTION = 'section';
69 #$LDC_TOC = 'Table of Contents';
70 #$LDC_GOTO = 'Go to the';
71 #$LDC_FOOT = 'Footnotes';
72 # TODO: @def* shortcuts
99 # texinfo section names to level
112 'appendixsection', 2,
114 'unnumberedsubsec', 3,
118 'unnumberedsubsubsec', 4,
120 'appendixsubsubsec', 4,
124 # accent map, TeX command to ISO name
133 # fixme: (not Latin1) = H d dotaccent dotless ringaccent
134 # tieaccent u ubaraccent v
138 # texinfo "simple things" (@foo) to HTML ones
143 " ", " ", # nbsp
152 "-", "­", # soft hyphen
157 # texinfo "things" (@foo{}) to HTML ones
161 'br', '<P>', # paragraph break. Gone from texinfo 3.9
163 'copyright', '©',
174 # fixme: output these Latin1 characters as such rather
177 'questiondown', '¿',
179 'exclamdown', '¡',
186 # follow info rendering:
194 # texinfo styles (@foo{bar}) to HTML ones
201 'ctrl', '&do_ctrl', # special case (obsolete)
202 'dfn', 'STRONG', # DFN tag is illegal in the standard
205 'email', '&do_email', # new special case
206 'file', '"TT', # will put quotes, cf. &apply_style
209 'key', 'KBD', # fixme: probably not <KBD>; possibly
210 # enclose in angles like makeinfo now does
211 'r', '', # unsupported
212 'samp', '"SAMP', # will put quotes, cf. &apply_style
213 'sc', '&do_sc', # special case
216 'titlefont', 'B', # make it distinctive, at least
217 'uref', '&do_url', # new special case
218 'url', 'CODE', # new special case
220 'w', '', # unsupported
221 # 'math', 'I', # not very useful, but at least italicize
222 'math', '', # don't want italic numbers
226 # texinfo format (@foo/@end foo) to HTML ones
231 'format', 'PRE', # fixme: shouldn't use tt, but can't avoid?
233 'quotation', 'BLOCKQUOTE',
234 'smallexample', 'PRE',
245 # texinfo definition shortcuts to real ones
265 'defun', 'deffn Function',
266 'defmac', 'deffn Macro',
267 'defspec', 'deffn {Special Form}',
268 'defvar', 'defvr Variable',
269 'defopt', 'defvr {User Option}',
270 'deftypefun', 'deftypefn Function',
271 'deftypevar', 'deftypevr Variable',
272 'defivar', 'defcv {Instance Variable}',
273 'defmethod', 'defop Method',
275 'defunx', 'deffnx Function',
276 'defmacx', 'deffnx Macro',
277 'defspecx', 'deffnx {Special Form}',
278 'defvarx', 'defvrx Variable',
279 'defoptx', 'defvrx {User Option}',
280 'deftypefunx', 'deftypefnx Function',
281 'deftypevarx', 'deftypevrx Variable',
282 'defivarx', 'defcvx {Instance Variable}',
283 'defmethodx', 'defopx Method',
296 'summarycontents', 1,
303 # unsupported commands (formatting)
310 'setchapternewpage', 1,
321 'setchapterstyle', 1,
323 # unsupported formats
330 #+++############################################################################
332 # Argument parsing, initialisation #
334 #---############################################################################
336 $use_bibliography = 1;
343 $invisible_mark = '';
347 $number_sections = 0;
354 To convert a Texinfo file to HMTL: $0 [options] file
355 where options can be:
356 -expandinfo : use \@ifinfo sections, not \@iftex
357 -glossary : handle a glossary
358 -invisible name: use 'name' as an invisible anchor
359 -I dir : search also for files in 'dir'
360 -menu : handle menus and don\'t do the ToC
361 -monolithic : output only one file including ToC
362 -number : number sections
363 -split_chapter : split on main sections
364 -split_node : split on nodes
365 -check : check given file for possible Texinfo commands
366 -usage : print usage instructions
367 -verbose : verbose output
368 To check converted files: $0 -check [-verbose] files
371 while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) {
373 if (/^-acc$/) { $use_acc = 1; next; }
374 if (/^-d(ebug)?(\d+)?$/) { $debug = $2 || shift(@ARGV); next; }
375 if (/^-doctype$/) { $doctype = shift(@ARGV); next; }
376 if (/^-c(heck)?$/) { $check = 1; next; }
377 if (/^-e(xpandinfo)?$/) { $expandinfo = 1; next; }
378 if (/^-g(lossary)?$/) { $use_glossary = 1; next; }
379 if (/^-i(nvisible)?$/) { $invisible_mark = shift(@ARGV); next; }
380 if (/^-iso$/) { $use_iso = 1; next; }
381 if (/^-I(.+)?$/) { push(@include_dirs, $1 || shift(@ARGV)); next; }
382 if (/^-m(enu)?$/) { $show_menu = 1; next; }
383 if (/^-mono(lithic)?$/) { $monolithic = 1; next; }
384 if (/^-n(umber)?$/) { $number_sections = 1; next; }
385 if (/^-s(plit)?_?(n(ode)?|c(hapter)?)?$/) {
393 if (/^-v(erbose)?$/) { $verbose = 1; next; }
397 die $usage unless @ARGV > 0;
402 if (($split_node || $split_chapter) && $monolithic) {
403 warn "Can't use -monolithic with -split, -monolithic ignored.\n";
407 $to_skip{'ifinfo'}++;
408 $to_skip{'end ifinfo'}++;
411 $to_skip{'end iftex'}++;
413 $invisible_mark = '<IMG SRC="invisible.xbm" ALT="">' if $invisible_mark eq 'xbm';
414 die $usage unless @ARGV == 1;
415 $docu = shift(@ARGV);
416 if ($docu =~ /.*\//) {
417 chop($docu_dir = $&);
423 unshift(@include_dirs, $docu_dir);
424 $docu_name =~ s/\.te?x(i|info)?$//; # basename of the document
426 $docu_doc = "$docu_name.html"; # document's contents
428 $docu_toc = $docu_foot = $docu_doc;
430 $docu_toc = "${docu_name}_toc.html"; # document's table of contents
431 $docu_foot = "${docu_name}_foot.html"; # document's footnotes
437 %value = (); # hold texinfo variables
438 $value{'html'} = 1; # predefine html (the output format)
439 $value{'texi2html'} = '1.51a'; # predefine texi2html (the translator)
440 # _foo: internal to track @foo
441 foreach ('_author', '_title', '_subtitle',
442 '_settitle', '_setfilename') {
443 $value{$_} = ''; # prevent -w warnings
445 %node2sec = (); # node to section name
446 %node2href = (); # node to HREF
447 %anchor2href = (); # anchor to HREF
448 %bib2href = (); # bibliography reference to HREF
449 %gloss2href = (); # glossary term to HREF
450 @sections = (); # list of sections
451 %tag2pro = (); # protected sections
465 # can I use ISO8879 characters? (HTML+)
468 $things_map{'bullet'} = "•";
469 $things_map{'copyright'} = "©";
470 $things_map{'dots'} = "…";
471 $things_map{'equiv'} = "≡";
472 $things_map{'expansion'} = "→";
473 $things_map{'point'} = "∗";
474 $things_map{'result'} = "⇒";
478 # read texi2html extensions (if any)
480 $extensions = 'texi2html.ext'; # extensions in working directory
481 if (-f
$extensions) {
482 print "# reading extensions from $extensions\n" if $verbose;
483 require($extensions);
485 ($progdir = $0) =~ s/[^\/]+$//;
486 if ($progdir && ($progdir ne './')) {
487 $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory
488 if (-f
$extensions) {
489 print "# reading extensions from $extensions\n" if $verbose;
490 require($extensions);
494 print "# reading from $docu\n" if $verbose;
496 #+++############################################################################
498 # Pass 1: read source, handle command, variable, simple substitution #
500 #---############################################################################
502 @lines = (); # whole document
503 @toc_lines = (); # table of contents
504 @top_lines = (); # contents of top node
505 $toplevel = 0; # top level seen in hierarchy
506 $curlevel = 0; # current level in TOC
507 $node = ''; # current node name
508 $in_table = 0; # am I inside a table
509 $table_type = ''; # type of table ('', 'f', 'v')
510 @tables = (); # nested table support
511 $in_bibliography = 0; # am I inside a bibliography
512 $in_glossary = 0; # am I inside a glossary
513 $in_top = 0; # am I inside the top node
514 $in_pre = 0; # am I inside a preformatted section
515 $in_list = 0; # am I inside a list
516 $in_html = 0; # am I inside an HTML section (@ifhtml)
517 $in_raw_html = 0; # am I inside an HTML section (@html)
518 $in_preamble = 1; # am I before the top node
519 $first_line = 1; # is it the first line
520 $dont_html = 0; # don't protect HTML on this line
521 $split_num = 0; # split index
522 $deferred_ref = ''; # deferred reference for indexes
523 @html_stack = (); # HTML elements stack
524 $html_element = ''; # current HTML element
527 # build code for simple substitutions
528 # the maps used (%simple_map and %things_map) MUST be aware of this
529 # watch out for regexps, / and escaped characters!
531 foreach (keys(%simple_map)) {
532 ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars
533 $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n";
535 foreach (keys(%things_map)) {
536 $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n";
539 # accentuated characters
540 foreach (keys(%accent_map)) {
542 $subst_code .= "s/$;3";
543 } elsif ($_ eq "'") {
544 $subst_code .= "s/$;4";
546 $subst_code .= "s/\\\@\\$_";
548 $subst_code .= "([aeiou])/&\${1}$accent_map{$_};/gi;\n";
551 eval("sub simple_substitutions { $subst_code }");
554 while ($_ = &next_line
) {
556 # remove \input on the first lines only
567 if (/^\@end\s+(\w+)\b/) {
569 } elsif (/^\@(\w+)\b/) {
573 # handle @ifhtml / @end ifhtml
576 if ($end_tag eq 'ifhtml') {
579 $tag2pro{$in_html} .= $_;
582 } elsif ($tag eq 'ifhtml') {
583 $in_html = $PROTECTTAG . ++$html_num;
584 push(@lines, $in_html);
588 # do raw HTML (no escapes)
591 if ($end_tag eq 'html') {
597 } elsif ($tag eq 'html') {
601 # try to skip the line
604 next if $to_skip{"end $end_tag"};
606 next if $to_skip{$tag};
607 last if $tag eq 'bye';
610 # try to remove inlined comments
611 # syntax from tex-mode.el comment-start-skip
613 s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/;
614 # non-@ substitutions cf. texinfmt.el
617 s/([\w ])---([\w ])/$1--$2/g;
623 &skip_until
($tag), next if $tag eq 'ignore';
625 &skip_until
($tag), next if $tag eq 'iftex';
627 &skip_until
($tag), next if $tag eq 'ifinfo' &&
628 ! $in_preamble; # we want the contents of the top node
630 &skip_until
($tag), next if $tag eq 'tex';
631 # handle special tables
632 if ($tag eq 'table') {
634 } elsif ($tag eq 'ftable') {
637 } elsif ($tag eq 'vtable') {
640 } elsif ($tag eq 'multitable') {
645 if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+Top\s*,/i)) {
646 # We want to stash the contents of the top node (including
650 @lines = (); # ignore all lines before top (title page garbage)
652 } elsif ($tag eq 'node') {
653 push (@lines, "$TOPTAG") if ($in_top); # Mark end of top node
656 warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o;
657 $_ = &protect_html
($_); # if node contains '&' for instance
659 ($node) = split(/,/);
660 &normalise_node
($node);
663 push(@lines, $SPLITTAG) if $split_num++;
664 push(@sections, $node);
667 } elsif ($tag eq 'include') {
668 if (/^\@include\s+($FILERE)\s*$/o) {
671 foreach $dir (@include_dirs) {
678 print "# including $file\n" if $verbose;
680 warn "$ERROR Can't find $file, skipping";
683 warn "$ERROR Bad include line: $_";
686 } elsif ($tag eq 'ifclear') {
687 if (/^\@ifclear\s+($VARRE)\s*$/o) {
688 next unless defined($value{$1});
691 warn "$ERROR Bad ifclear line: $_";
694 } elsif ($tag eq 'ifset') {
695 if (/^\@ifset\s+($VARRE)\s*$/o) {
696 next if defined($value{$1});
699 warn "$ERROR Bad ifset line: $_";
702 } elsif ($tag eq 'menu') {
703 unless ($show_menu) {
708 push(@lines, &html_debug
("\n", __LINE__
));
709 } elsif ($format_map{$tag}) {
710 $in_pre = 1 if $format_map{$tag} eq 'PRE';
711 &html_push_if
($format_map{$tag});
712 push(@lines, &html_debug
("\n", __LINE__
));
713 $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ;
714 push(@lines, &debug
("<$format_map{$tag}>\n", __LINE__
));
716 } elsif ($tag eq 'table') {
717 if (/^\@[fv]?table\s+\@(\w+)\s*$/) {
719 unshift(@tables, join($;, $table_type, $in_table));
720 push(@lines, &debug
("<DL COMPACT>\n", __LINE__
));
722 push(@lines, &html_debug
("\n", __LINE__
));
723 } elsif (/^\@multitable\s+/) {
724 # Note descent to HTML 3.2 necessary for multitable.
726 unshift(@tables, join($;, $table_type, $in_table));
727 push(@lines, &debug
("<TABLE>\n", __LINE__
));
728 &html_push_if
('TABLE');
729 push(@lines, &html_debug
("\n", __LINE__
));
731 warn "$ERROR Bad table line: $_";
734 } elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') {
735 if (/^\@$tag\s+(\w)\w\s+(\w)\w\s*$/) {
736 eval("*${1}index = *${2}index");
738 warn "$ERROR Bad syn*index line: $_";
741 } elsif ($tag eq 'sp') {
742 push(@lines, &debug
("<P>\n", __LINE__
));
744 } elsif ($tag eq 'anchor') {
745 if (/^\@$tag\s*{($NODERE)}\s*$/) {
747 push(@lines,&debug
("<a name=\"$anchor\"></a>", __LINE__
));
749 # warn "$anchor,hello,bib2href=$bib2href{$anchor},$gloss2href{$anchor},";
750 $anchor2href{$anchor} = "$docu_doc#$anchor";
753 } elsif ($tag eq 'setref') {
754 &protect_html
; # if setref contains '&' for instance
755 if (/^\@$tag\s*{($NODERE)}\s*$/) {
757 $setref =~ s/\s+/ /g; # normalize
759 $node2sec{$setref} = $name;
760 $node2href{$setref} = "$docu_doc#$docid";
762 warn "$ERROR Bad setref line: $_";
765 } elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') {
766 if (/^\@$tag\s+(\w\w)\s*$/) {
767 $valid_index{$1} = 1;
769 warn "$ERROR Bad defindex line: $_";
772 } elsif ($tag eq 'direntry') {
775 } elsif (defined($def_map{$tag})) {
776 if ($def_map{$tag}) {
778 $tag = $def_map{$tag};
782 } elsif (defined($user_sub{$tag})) {
784 $sub = $user_sub{$tag};
785 print "# user $tag = $sub, arg: $_" if $debug & $DEBUG_USER;
786 if (defined(&$sub)) {
790 warn "$ERROR Bad user sub for $tag: $sub\n";
794 if (defined($def_map{$tag})) {
797 # extra definition line
803 while (/\{([^\{\}]*)\}/) {
804 # this is a {} construct
805 ($before, $contents, $after) = ($`, $1, $');
807 $contents =~ s/\s+/$;9/g;
808 # restore $_ protecting {}
809 $_ = "$before$;7$contents$;8$after";
811 @args = split(/\s+/, &protect_html($_));
813 s/$;9/ /g; # unprotect spaces
817 $type = shift(@args);
818 $type =~ s/^\{(.*)\}$/$1/;
819 print "# def ($tag): {$type} ", join(', ', @args), "\n"
820 if $debug & $DEBUG_DEF;
821 $type .= ':'; # it's nicer like this
822 $name = shift(@args);
823 $name =~ s/^\{(.*)\}$/$1/;
825 $_ = &debug
("<DT>", __LINE__
);
827 $_ = &debug
("<DL>\n<DT>", __LINE__
);
829 if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') {
830 $_ .= "<U>$type</U> <B>$name</B>";
831 $_ .= " <I>@args</I>" if @args;
832 } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr'
833 || $tag eq 'defcv' || $tag eq 'defop') {
835 $name = shift(@args);
836 $name =~ s/^\{(.*)\}$/$1/;
837 $_ .= "<U>$type</U> $ftype <B>$name</B>";
838 $_ .= " <I>@args</I>" if @args;
840 warn "$ERROR Unknown definition type: $tag\n";
841 $_ .= "<U>$type</U> <B>$name</B>";
842 $_ .= " <I>@args</I>" if @args;
844 $_ .= &debug
("\n<DD>", __LINE__
);
845 $name = &unprotect_html
($name);
846 if ($tag eq 'deffn' || $tag eq 'deftypefn') {
847 unshift(@input_spool, "\@findex $name\n");
848 } elsif ($tag eq 'defop') {
849 unshift(@input_spool, "\@findex $name on $ftype\n");
850 } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') {
851 unshift(@input_spool, "\@vindex $name\n");
853 unshift(@input_spool, "\@tindex $name\n");
858 if ($format_map{$end_tag}) {
859 $in_pre = 0 if $format_map{$end_tag} eq 'PRE';
860 $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ;
861 &html_pop_if
('LI', 'P');
863 push(@lines, &debug
("</$format_map{$end_tag}>\n", __LINE__
));
864 push(@lines, &html_debug
("\n", __LINE__
));
865 } elsif ($end_tag eq 'table' ||
866 $end_tag eq 'ftable' ||
867 $end_tag eq 'vtable' ||
868 $end_tag eq 'multitable') {
871 ($table_type, $in_table) = split($;, $tables[0]);
875 if ($end_tag eq 'multitable') {
876 push(@lines, "</TABLE>\n");
877 &html_pop_if
('TABLE');
879 push(@lines, "</DL>\n");
883 } elsif (defined($def_map{$end_tag})) {
884 push(@lines, &debug
("</DL>\n", __LINE__
));
885 } elsif ($end_tag eq 'menu') {
887 push(@lines, $_); # must keep it for pass 2
894 # protect texi and HTML things
896 $_ = &protect_html
($_) unless $dont_html;
898 # substitution (unsupported things)
899 s/^\@center\s+//g; # fixme: use <center> or <div align=center>?
903 # other substitutions
904 &simple_substitutions
;
905 s/\@value{($VARRE)}/$value{$1}/eg;
906 s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
907 s/\@image\{([^,\}]+)[^\}]*\}/\<img src="$1"\>/g;
909 # analyze the tag again
912 if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) {
913 if (/^\@$tag\s+(.+)$/) {
916 $level = $sec2level{$tag};
917 $name = &update_sec_num
($tag, $level) . " $name"
918 if $number_sections && $tag !~ /^unnumbered/;
919 if ($tag =~ /heading$/) {
920 push(@lines, &html_debug
("\n", __LINE__
));
921 if ($html_element ne 'body') {
922 # We are in a nice pickle here. We are trying to get a H? heading
923 # even though we are not in the body level. So, we convert it to a
924 # nice, bold, line by itself.
925 $_ = &debug
("\n\n<P><STRONG>$name</STRONG></P>\n\n", __LINE__
);
927 $_ = &debug
("<H$level>$name</H$level>\n", __LINE__
);
928 &html_push_if
('body');
930 print "# heading, section $name, level $level\n"
931 if $debug & $DEBUG_TOC;
933 if ($split_chapter) {
935 # first time we see a "section"
936 unless ($level == 1) {
937 warn "$ERROR The first section found is not of level 1: $_";
938 warn "$ERROR I'll split on sections of level $level...\n";
942 if ($level == $toplevel) {
944 push(@lines, $SPLITTAG) if $split_num++;
945 push(@sections, $name);
949 $docid = "SEC$sec_num";
950 $tocid = "TOC$sec_num";
951 # check biblio and glossary
952 $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i);
953 $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i);
956 if ($node2sec{$node}) {
957 warn "$ERROR Duplicate node found: $node\n";
959 $node2sec{$node} = $name;
960 $node2href{$node} = "$docu_doc#$docid";
961 print "# node $node, section $name, level $level\n"
962 if $debug & $DEBUG_TOC;
966 print "# no node, section $name, level $level\n"
967 if $debug & $DEBUG_TOC;
970 while ($level > $curlevel) {
972 push(@toc_lines, "<UL>\n");
974 while ($level < $curlevel) {
976 push(@toc_lines, "</UL>\n");
978 $_ = "<LI>" . &anchor
($tocid, "$docu_doc#$docid", $name, 1);
979 push(@toc_lines, &substitute_style
($_));
981 push(@lines, &html_debug
("\n", __LINE__
));
983 $_ = "<H$level>".&anchor
($docid, "$docu_toc#$tocid", $name)."</H$level>\n";
984 $_ = &debug
($_, __LINE__
);
985 push(@lines, &html_debug
("\n", __LINE__
));
988 foreach $line (split(/\n+/, $_)) {
989 push(@lines, "$line\n");
993 warn "$ERROR Bad section line: $_";
997 $value{$1} = $2, next if /^\@set\s+($VARRE)\s+(.*)$/o;
998 delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o;
1000 $value{'_setfilename'} = $1, next if /^\@setfilename\s+(.*)$/;
1001 $value{'_settitle'} = $1, next if /^\@settitle\s+(.*)$/;
1002 $value{'_author'} .= "$1\n", next if /^\@author\s+(.*)$/;
1003 $value{'_subtitle'} .= "$1\n", next if /^\@subtitle\s+(.*)$/;
1004 $value{'_title'} .= "$1\n", next if /^\@title\s+(.*)$/;
1006 if (/^\@(..?)index\s+/) {
1007 unless ($valid_index{$1}) {
1008 warn "$ERROR Undefined index command: $_";
1011 $id = 'IDX' . ++$idx_num;
1012 $index = $1 . 'index';
1013 $what = &substitute_style
($');
1015 print "# found $index for '$what' id $id\n"
1016 if $debug & $DEBUG_INDEX;
1018 if (defined(\$$index\{\$what\})) {
1019 \$$index\{\$what\} .= "$;$docu_doc#$id";
1021 \$$index\{\$what\} = "$docu_doc#$id";
1025 # dirty hack to see if I can put an invisible anchor...
1027 if ($html_element eq 'P' ||
1028 $html_element eq 'LI' ||
1029 $html_element eq 'DT' ||
1030 $html_element eq 'DD' ||
1031 $html_element eq 'ADDRESS' ||
1032 $html_element eq 'B' ||
1033 $html_element eq 'BLOCKQUOTE' ||
1034 $html_element eq 'PRE' ||
1035 $html_element eq 'SAMP') {
1036 push(@lines, &anchor
($id, '', $invisible_mark, !$in_pre));
1037 } elsif ($html_element eq 'body') {
1038 push(@lines, &debug
("<P>\n", __LINE__
));
1039 push(@lines, &anchor
($id, '', $invisible_mark, !$in_pre));
1041 } elsif ($html_element eq 'DL' ||
1042 $html_element eq 'UL' ||
1043 $html_element eq 'OL' ) {
1044 $deferred_ref .= &anchor
($id, '', $invisible_mark, !$in_pre) . " ";
1049 if (/^\@itemx?\s+/) {
1052 if ($in_bibliography && $use_bibliography) {
1053 if ($what =~ /^$BIBRE$/o) {
1054 $id = 'BIB
' . ++$bib_num;
1055 $bib2href{$what} = "$docu_doc#$id";
1056 print "# found bibliography for '$what' id $id\n"
1057 if $debug & $DEBUG_BIB;
1058 $what = &anchor($id, '', $what);
1060 } elsif ($in_glossary && $use_glossary) {
1061 $id = 'GLOSS
' . ++$gloss_num;
1063 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
1064 $gloss2href{$entry} = "$docu_doc#$id";
1065 print "# found glossary for '$entry' id $id\n"
1066 if $debug & $DEBUG_GLOSS;
1067 $what = &anchor($id, '', $what);
1070 if ($html_element eq 'DL
' || $html_element eq 'DD
') {
1071 if ($things_map{$in_table} && !$what) {
1072 # special case to allow @table @bullet for instance
1073 push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__));
1075 push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__));
1077 push(@lines, "<DD>");
1078 &html_push('DD
') unless $html_element eq 'DD
';
1079 if ($table_type) { # add also an index
1080 unshift(@input_spool, "\@${table_type}index $what\n");
1082 } elsif ($html_element eq 'TABLE
' || $html_element eq 'TR
') {
1083 # Add <br> at ends of rows for non-tables browsers.
1084 push(@lines, "<BR>\n") if $html_element eq 'TR
';
1085 push(@lines, "<TR>$what");
1086 &html_push('TR
') unless $html_element eq 'TR
';
1088 push(@lines, &debug("<LI>$what\n", __LINE__));
1089 &html_push('LI
') unless $html_element eq 'LI
';
1091 push(@lines, &html_debug("\n", __LINE__));
1092 if ($deferred_ref) {
1093 push(@lines, &debug("$deferred_ref\n", __LINE__));
1100 # paragraph separator
1102 next if $#lines >= 0 && $lines[$#lines] eq "\n";
1103 if ($html_element eq 'P
') {
1105 $_ = &debug("</P>\n", __LINE__);
1108 } elsif ($html_element eq 'body
' || $html_element eq 'BLOCKQUOTE
') {
1109 push(@lines, "<P>\n");
1111 $_ = &debug($_, __LINE__);
1119 while ($level < $curlevel) {
1121 push(@toc_lines, "</UL>\n");
1124 print "# end of pass 1\n" if $verbose;
1126 #+++############################################################################
1128 # Pass 2/3: handle style, menu, index, cross-reference #
1130 #---############################################################################
1132 @lines2 = (); # whole document (2nd pass)
1133 @lines3 = (); # whole document (3rd pass)
1134 $in_menu = 0; # am I inside a menu
1140 # special case (protected sections)
1142 if (/^$PROTECTTAG/o) {
1146 if ($in_top && $_ eq "$TOPTAG") {
1148 @top_lines = @lines2; # Contents of the top node.
1149 @lines2 = (); # Don't
use them
in place
.
1155 $in_menu = 1, push(@lines2, &debug
("<UL>\n", __LINE__
)), next if /^\@menu\b/;
1156 $in_menu = 0, push(@lines2, &debug
("</UL>\n", __LINE__
)), next if /^\
@end\s
+menu
\b/;
1158 if (/^\*\s+($NODERE)::/o) {
1161 &menu_entry($1, $1, $descr);
1162 } elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) {
1165 &menu_entry
($1, $2, $descr);
1167 warn "$ERROR Bad menu line: $_";
1168 } else { # description continued?
1176 if (/^\@printindex\s+(\w\w)\b/) {
1177 local($index, *ary
, @keys, $key, $letter, $last_letter, @refs);
1178 if ($predefined_index{$1}) {
1179 $index = $predefined_index{$1} . 'index';
1181 $index = $1 . 'index';
1183 eval("*ary = *$index");
1185 foreach $key (@keys) {
1187 1 while s/<(\w+)>\`(.*)\'<\/\1>/$2/; # remove HTML tags with quotes
1188 1 while s/<(\w+)>(.*)<\/\1>/$2/; # remove HTML tags
1189 $_ = &unprotect_html
($_);
1191 tr/A-Z/a-z/; # lowercase
1192 $key2alpha{$key} = $_;
1193 print "# index $key sorted as $_\n"
1194 if $key ne $_ && $debug & $DEBUG_INDEX;
1196 $last_letter = undef;
1197 foreach $key (sort byalpha
@keys) {
1198 $letter = substr($key2alpha{$key}, 0, 1);
1199 $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;;
1200 if (!defined($last_letter) || $letter ne $last_letter) {
1201 push(@lines2, "</DIR>\n") if defined($last_letter);
1202 push(@lines2, "<H2>" . &protect_html
($letter) . "</H2>\n");
1203 push(@lines2, "<DIR>\n");
1204 $last_letter = $letter;
1207 foreach (split(/$;/, $ary{$key})) {
1208 push(@refs, &anchor
('', $_, $key, 0));
1210 push(@lines2, "<LI>" . join(", ", @refs) . "\n");
1212 push(@lines2, "</DIR>\n") if defined($last_letter);
1217 # simple style substitutions
1219 $_ = &substitute_style
($_);
1223 while (/\@(x|px|info|)ref{($XREFRE)(}?)/o) {
1224 # note: Texinfo may accept other characters
1225 ($type, $nodes, $full) = ($1, $2, $3);
1226 ($before, $after) = ($`, $');
1227 if (! $full && $after) {
1228 warn "$ERROR Bad xref (no ending } on line): $_";
1229 $_ = "$before$;0${type}ref\{$nodes$after";
1234 } elsif ($type eq 'px') {
1236 } elsif ($type eq 'info') {
1242 $next = shift(@lines);
1243 $next = &substitute_style($next);
1244 chop($nodes); # remove final newline
1245 if ($next =~ /\}/) { # split on 2 lines
1250 $next = shift(@lines);
1251 $next = &substitute_style($next);
1253 if ($next =~ /\}/) { # split on 3 lines
1257 warn "$ERROR Bad xref (no ending }): $_";
1258 $_ = "$before$;0xref\{$nodes$after";
1259 unshift(@lines, $next);
1264 $nodes =~ s/\s+/ /g; # remove useless spaces
1265 @args = split(/\s*,\s*/, $nodes);
1266 $node = $args[0]; # the node is always the first arg
1267 &normalise_node($node);
1268 $sec = $node2sec{$node};
1269 $href = $anchor2href{$node};
1270 if (@args == 5) { # reference to another manual
1271 $sec = $args[2] || $node;
1272 $man = $args[4] || $args[3];
1273 $_ = "${before}${type}section `$sec' in \@cite{$man}$after";
1274 } elsif ($type =~ /Info/) { # inforef
1275 warn "$ERROR Wrong number of arguments: $_" unless @args == 3;
1276 ($nn, $_, $in) = @args;
1277 $_ = "${before}${type} file `$in', node
`$nn'$after";
1280 $href = $node2href{$node};
1281 $_ = "${before}${type}section " . &anchor('', $href, $sec) . $after;
1283 $_ = "${before}${type} " . &anchor('', $href, $node) . $after;
1285 warn "$ERROR Undefined node ($node) href=$href: $_";
1286 $_ = "$before$;0xref{$nodes}$after";
1290 # try to guess bibliography references or glossary terms
1292 unless (/^<H\d><A NAME=\"SEC\d/) {
1293 if ($use_bibliography) {
1296 ($pre, $what, $post) = ($`, $&, $');
1297 $href = $bib2href{$what};
1298 if (defined($href) && $post !~ /^[^<]*<\/A>/) {
1299 $done .= $pre . &anchor('', $href, $what);
1301 $done .= "$pre$what";
1307 if ($use_glossary) {
1310 ($pre, $what, $post) = ($`, $&, $');
1312 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
1313 $href = $gloss2href{$entry};
1314 if (defined($href) && $post !~ /^[^<]*<\/A
>/) {
1315 $done .= $pre . &anchor
('', $href, $what);
1317 $done .= "$pre$what";
1327 print "# end of pass 2\n" if $verbose;
1330 # split style substitutions
1333 $_ = shift(@lines2);
1335 # special case (protected sections)
1337 if (/^$PROTECTTAG/o) {
1342 # split style substitutions
1345 while ($old ne $_) {
1348 ($before, $style, $after) = ($`, $1, $');
1349 if (defined($style_map{$style})) {
1362 $_ = shift(@lines2);
1366 die "* Bad syntax (\@$style) after: $before\n";
1368 $text = &apply_style($style, $text);
1369 $_ = "$before$text$after";
1377 print "# end of pass 3\n" if $verbose;
1379 #+++############################################################################
1381 # Pass 4: foot notes, final cleanup #
1383 #---############################################################################
1385 @foot_lines = (); # footnotes
1386 @doc_lines = (); # final document
1387 $end_of_para = 0; # true if last line is <P>
1390 $_ = shift(@lines3);
1392 # special case (protected sections)
1394 if (/^$PROTECTTAG/o) {
1395 push(@doc_lines, $_);
1402 while (/\@footnote([^\{\s]+)\{/) {
1403 ($before, $d, $after) = ($`, $1, $');
1416 $_ = shift(@lines3);
1420 die "* Bad syntax (\@footnote) after: $before\n";
1423 $docid = "DOCF$foot_num";
1424 $footid = "FOOT$foot_num";
1425 $foot = "($foot_num)";
1426 push(@foot_lines, "<H3>" . &anchor($footid, "$d#$docid", $foot) . "</H3>\n");
1427 $text = "<P>$text" unless $text =~ /^\s*<P>/;
1428 push(@foot_lines, "$text\n");
1429 $_ = $before . &anchor($docid, "$docu_foot#$footid", $foot) . $after;
1433 # remove unnecessary <P>
1435 if (/^\s*<P>\s*$/) {
1436 next if $end_of_para++;
1441 push(@doc_lines, $_);
1443 print "# end of pass 4\n" if $verbose;
1445 #+++############################################################################
1447 # Pass 5: print things #
1449 #---############################################################################
1452 <!-- This HTML file has been created by $THISPROG
1453 from $docu on $TODAY -->
1456 $full_title = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
1457 $title = $value{'_settitle'} || $full_title;
1458 $_ = &substitute_style
($full_title);
1460 s/\n$//; # rmv last \n (if any)
1461 $full_title = "<H1>" . join("</H1>\n<H1>", split(/\n/, $_)) . "</H1
>\n";
1466 # ... unless using menus instead. Make the TOC lines empty rather than
1467 # null so we get a ToC page with the top node (including menu).
1468 @toc_lines = ("") if $show_menu;
1470 if (!$monolithic && @toc_lines) {
1471 if (open(FILE, "> $docu_toc")) {
1472 print "# creating $docu_toc...\n" if $verbose;
1473 &print_toplevel_header
("$title - Table of Contents");
1475 &print (*top_lines
, FILE
); # Contents of the top node before the TOC.
1476 &print(*toc_lines
, FILE
);
1477 &print_toplevel_footer
;
1480 warn "$ERROR Can't write to $docu_toc: $!\n";
1487 if (!$monolithic && @foot_lines) {
1488 if (open(FILE
, "> $docu_foot")) {
1489 print "# creating $docu_foot...\n" if $verbose;
1490 &print_toplevel_header
("$title - Footnotes");
1492 &print(*foot_lines
, FILE
);
1493 &print_toplevel_footer
;
1496 warn "$ERROR Can't write to $docu_foot: $!\n";
1503 if ($split_chapter || $split_node) { # split
1505 $last_num = scalar(@sections);
1506 $first_doc = &doc_name
(1);
1507 $last_doc = &doc_name
($last_num);
1509 $section = shift(@sections);
1511 if (open(FILE
, "> $docu_doc")) {
1512 print "# creating $docu_doc...\n" if $verbose;
1513 $prev_doc = ($doc_num == 1 ?
undef : &doc_name
($doc_num - 1));
1514 $next_doc = ($doc_num == $last_num ?
undef : &doc_name
($doc_num + 1));
1515 $links = ($next_doc ?
"<link href=\"$next_doc\" rel=Next>\n" : "");
1516 $links .= ($prev_doc ?
"<link href=\"$prev_doc\" rel=Previous>\n" : "");
1517 $links .= "<link href=\"$docu_toc\" rel=ToC>\n";
1518 # fixme: try rel=Index too?
1519 &print_header
("$title - $section", $links);
1521 $navigation = "<p>Go to the ";
1522 $navigation .= ($prev_doc ?
&anchor
('', $first_doc, "first") : "first");
1523 $navigation .= ", ";
1524 $navigation .= ($prev_doc ?
&anchor
('', $prev_doc, "previous") : "previous");
1525 $navigation .= ", ";
1526 $navigation .= ($next_doc ?
&anchor
('', $next_doc, "next") : "next");
1527 $navigation .= ", ";
1528 $navigation .= ($next_doc ?
&anchor
('', $last_doc, "last") : "last");
1529 $navigation .= " section, " . &anchor
('', $docu_toc, "table of contents") . ".\n";
1530 print FILE
$navigation;
1532 # find corresponding lines
1534 while (@doc_lines) {
1535 $_ = shift(@doc_lines);
1536 last if ($_ eq $SPLITTAG);
1537 push(@tmp_lines, $_);
1539 &print(*tmp_lines
, FILE
);
1541 print FILE
$navigation;
1545 warn "$ERROR Can't write to $docu_doc: $!\n";
1548 } else { # not split
1549 if (open(FILE
, "> $docu_doc")) {
1550 print "# creating $docu_doc...\n" if $verbose;
1551 if ($monolithic || !@toc_lines) {
1552 &print_toplevel_header
($title);
1554 &print_header
($title, "");
1555 print FILE
$full_title;
1557 if ($monolithic && @toc_lines) {
1559 print FILE
"<H1>Table of Contents</H1>\n";
1560 &print(*toc_lines
, FILE
);
1563 &print(*doc_lines
, FILE
);
1564 if ($monolithic && @foot_lines) {
1566 print FILE
"<H1>Footnotes</H1>\n";
1567 &print(*foot_lines
, FILE
);
1569 if ($monolithic || !@toc_lines) {
1570 &print_toplevel_footer
;
1576 warn "$ERROR Can't write to $docu_doc: $!\n";
1580 print "# that's all folks\n" if $verbose;
1582 #+++############################################################################
1584 # Low level functions #
1586 #---############################################################################
1588 sub update_sec_num
{
1589 local($name, $level) = @_;
1591 $level--; # here we start at 0
1592 if ($name =~ /^appendix/) {
1594 if (defined(@appendix_sec_num)) {
1595 &incr_sec_num
($level, @appendix_sec_num);
1597 @appendix_sec_num = ('A', 0, 0, 0);
1599 return(join('.', @appendix_sec_num[0..$level]));
1602 if (defined(@normal_sec_num)) {
1603 &incr_sec_num
($level, @normal_sec_num);
1605 @normal_sec_num = (1, 0, 0, 0);
1607 return(join('.', @normal_sec_num[0..$level]));
1615 foreach $l ($level+1 .. 3) {
1621 local($_, %seen, %context, $before, $match, $after);
1624 if (/\@(\*|\.|\:|\@|\{|\})/) {
1626 $context{$&} .= "> $_" if $verbose;
1631 ($before, $match, $after) = ($`, $&, $');
1632 if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address
1633 $seen{'e-mail address'}++;
1634 $context{'e-mail address'} .= "> $_" if $verbose;
1637 $context{$match} .= "> $_" if $verbose;
1640 $_ = "$before$match$after";
1645 foreach (sort(keys(%seen))) {
1650 print "$_ ($seen{$_})\n";
1659 if (open($fh_name, $name)) {
1660 unshift(@fhs, $fh_name);
1662 warn "$ERROR Can't read file $name: $!\n";
1667 @fhs = (); # hold the file handles to read
1668 @input_spool = (); # spooled lines to read
1677 $line = shift(@input_spool);
1683 return($line) if $line;
1690 # used in pass 1, use &next_line
1695 while ($_ = &next_line) {
1696 return if /^\@end\s+$tag\s*$/;
1698 die "* Failed to find '$tag' after: " . $lines[$#lines];
1702 # HTML stacking to have a better HTML output
1706 @html_stack = ('html');
1707 $html_element = 'body';
1712 push(@html_stack, $html_element);
1713 $html_element = $what;
1718 push(@html_stack, $html_element)
1719 if ($html_element && $html_element ne 'P');
1720 $html_element = $what;
1724 $html_element = pop(@html_stack);
1732 if ($elt eq $html_element) {
1733 $html_element = pop(@html_stack) if @html_stack;
1738 $html_element = pop(@html_stack) if @html_stack;
1743 local($what, $line) = @_;
1744 return("<!-- $line @html_stack, $html_element -->$what")
1745 if $debug & $DEBUG_HTML;
1749 # to debug the output...
1751 local($what, $line) = @_;
1752 return("<!-- $line -->$what")
1753 if $debug & $DEBUG_HTML;
1757 sub normalise_node {
1764 local($entry, $node, $descr) = @_;
1767 &normalise_node($node);
1768 $href = $node2href{$node};
1771 $descr = ": $descr" if $descr;
1772 push(@lines2, "<LI>" . &anchor('', $href, $entry) . "$descr\n");
1774 warn "$ERROR Undefined node ($node): $_";
1779 sub do_email { "<" . &anchor('', "mailto:$_[0]", "<TT>$_[0]</TT>") . ">" }
1781 sub do_url { &anchor('', "$_[0]", "<TT>$_[0]</TT>") }
1783 sub do_ctrl { "^$_[0]" }
1785 sub do_sc { "\U$_[0]\E" }
1788 local($texi_style, $text) = @_;
1791 $style = $style_map{$texi_style};
1792 if (defined($style)) { # known style
1793 if ($style =~ /^\"/) { # add quotes
1795 $text = "\`$text\'";
1797 if ($style =~ /^\&/) { # custom
1799 $text = &$style($text);
1800 } elsif ($style) { # good style
1801 $text = "<$style>$text</$style>";
1804 } else { # unknown style
1810 # remove Texinfo styles
1813 s/\@\w+{([^\{\}]+)}/$1/g;
1817 sub substitute_style {
1819 local($changed, $done, $style, $text);
1825 while (/\@(\w+){([^\{\}]+)}/) {
1826 $text = &apply_style($1, $2);
1841 local($name, $href, $text, $newline) = @_;
1845 $result .= " NAME=\"$name\"" if $name;
1846 $result .= " HREF=\"$href\"" if $href;
1847 $result .= ">$text</A>";
1848 $result .= "\n" if $newline;
1853 local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
1855 @MoY = ('January
', 'Febuary
', 'March
', 'April
', 'May
', 'June
',
1856 'July
', 'August
', 'September
', 'October
', 'November
', 'December
');
1857 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
1858 $year += ($year < 70) ? 2000 : 1900;
1859 return("$mday $MoY[$mon] $year");
1865 return("${docu_name}_$num.html");
1869 $docu_doc = &doc_name(++$doc_num);
1873 local(*lines, $fh) = @_;
1878 if (/^$PROTECTTAG/o) {
1888 print FILE "<P><HR><P>\n";
1896 $_ = &remove_style($_[0]);
1899 if ($doctype eq 'html2
') {
1900 print FILE $html2_doctype; # Wrong if any multitable used
1901 } elsif ($doctype) {
1902 print FILE $doctype;
1915 sub print_toplevel_header
{
1918 &print_header
($_[0], "");
1919 print FILE
$full_title;
1920 if ($value{'_subtitle'}) {
1921 $value{'_subtitle'} =~ s/\n+$//;
1922 foreach (split(/\n/, $value{'_subtitle'})) {
1923 $_ = &substitute_style
($_);
1925 print FILE
"<H2>$_</H2>\n";
1928 if ($value{'_author'}) {
1929 $value{'_author'} =~ s/\n+$//;
1930 foreach (split(/\n/, $value{'_author'})) {
1931 $_ = &substitute_style
($_);
1933 # s/[\w.-]+\@[\w.-]+/<A HREF="mailto:$&">$&<\/A>/g;
1934 print FILE
"<ADDRESS>$_</ADDRESS>\n";
1947 sub print_toplevel_footer
{
1950 This document was generated on $TODAY using the
1951 <A HREF=\"$HOMEPAGE\">texi2html</A>
1952 translator version 1.51a.</P>
1969 $what =~ s/\&/\&\#38;/g;
1970 $what =~ s/\</\&\#60;/g;
1971 $what =~ s/\>/\&\#62;/g;
1972 # but recognize some HTML things
1973 $what =~ s/\&\#60;\/A\&\#62;/<\
/A>/g; # </A>
1974 $what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g; # <A [^&]+>
1975 $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+>
1979 sub unprotect_texi
{
1987 sub unprotect_html
{
1989 $what =~ s/\&\#38;/\&/g;
1990 $what =~ s/\&\#60;/\</g;
1991 $what =~ s/\&\#62;/\>/g;
1996 $key2alpha{$a} cmp $key2alpha{$b};
1999 ##############################################################################
2001 # These next few lines are legal in both Perl and nroff.
2005 'di \" finish diversion--previous line must be blank
2006 .nr nl 0-1 \" fake up transition to first page again
2007 .nr % 0 \" start at page 1
2008 '; __END__
############# From here on it's a standard manual page ############
2009 .TH TEXI2HTML
1 "08/12/97"
2012 texi2html \
- a Texinfo to HTML converter
2014 .B texi2html
[OPTION
]... FILE
2016 .B texi2html
-check
[-verbose
] FILE
...
2019 converts the
given Texinfo file to a set of HTML files
. It tries to handle
2020 most of the Texinfo commands
. It creates hypertext links
for cross
-references
,
2023 It also tries to add links from a reference to its corresponding entry
in the
2024 bibliography
(if any
). It may also handle a glossary
(see the
2029 creates several files depending on the contents of the Texinfo file
and on
2030 the chosen options
(see FILES
).
2032 The HTML files created by
2034 are closer to TeX than to Info
, that
's why
2036 converts @iftex sections and not @ifinfo ones by default. You can reverse
2037 this with the \-expandinfo option.
2041 Check the given file and give the list of all things that may be Texinfo commands.
2042 This may be used to check the output of
2044 to find the Texinfo commands that have been left in the HTML file.
2047 Expand @ifinfo sections, not @iftex ones.
2050 Use the section named 'Glossary
' to build a list of terms and put links in the HTML
2051 document from each term toward its definition.
2053 .B \-invisible \fIname\fP
2054 Use \fIname\fP to create invisible destination anchors for index links. This is a workaround
2055 for a known bug of many WWW browsers, including xmosaic.
2058 Look also in \fIdir\fP to find included files.
2061 Show the Texinfo menus; by default they are ignored.
2064 Output only one file, including the table of contents and footnotes.
2067 Number the sections.
2070 Split the output into several HTML files (one per main section:
2071 chapter, appendix...).
2074 Split the output into several HTML files (one per node).
2077 Print usage instructions, listing the current available command-line options.
2080 Give a verbose output. Can be used with the
2087 creates the following files (foo being the name of the Texinfo file):
2090 The table of contents.
2093 The document's contents
.
2096 The footnotes
(if any
).
2100 option
, it creates several files
(one per chapter
or node
), named
2102 (n being the indice of the chapter
or node
), instead of the single
2108 option
, it creates only one file
:
2112 predefines the following variables
: \fBhtml
\fP
, \fBtexi
2html
\fP
.
2113 .SH ADDITIONAL COMMANDS
2115 implements the following non
-Texinfo commands
:
2118 This indicates the start of an HTML section
, this section will passed through
2119 without any modofication
.
2122 This indcates the end of an HTML section
.
2124 This is
\fItexi
2html
\fP version
1.51a
, 1997-07-29.
2126 The latest version of
\fItexi
2html
\fP can be found
2127 ftp
://ftp
.cs
.umb
.edu
/pub/tex
/texi2html
2129 The main author is Lionel Cons
, CERN CN
/DCI/UWS
.
2130 This version is maintained at ftp
://ftp
.cs
.umb
.edu
/pub/tex
/texi2html
2132 Many other people around the net contributed to this program
.
2134 This program is the intellectual property of the European
2135 Laboratory
for Particle Physics
(known as CERN
). No guarantee whatsoever is
2136 provided by CERN
. No liability whatsoever is accepted
for any loss
or damage
2137 of any kind resulting from any defect
or inaccuracy
in this information
or
2140 CERN
, 1211 Geneva
23, Switzerland
2142 GNU Texinfo Documentation Format
,
2143 HyperText Markup Language
(HTML
),
2144 World Wide Web
(WWW
).
2146 This program does
not understand all Texinfo commands
(yet
).
2148 TeX specific commands
(normally enclosed
in @iftex) will be