4 #+##############################################################################
8 # Description: Program to transform most Texinfo documents to HTML #
10 #-##############################################################################
12 # @(#)texi2html 1.52a 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.
16 # The man page for this program is included at the end of this file and can be
17 # viewed using the command 'nroff -man texi2html'.
18 # Please read the copyright at the end of the man page.
20 #+++############################################################################
24 #---############################################################################
34 $BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference
35 $FILERE = '[\/\w.+-]+'; # RE for a file name
36 $VARRE = '[^\s\{\}]+'; # RE for a variable name
37 $NODERE = '[^@{}:\'`",]+'; # RE for a node name
38 $NODESRE = '[^@{}:\'`"]+'; # RE for a list of node names
39 $XREFRE = '[^@{}]+'; # RE for a xref (should use NODERE)
41 $ERROR = "***"; # prefix for errors and warnings
42 $THISPROG = "texi2html 1.52a"; # program name and version
43 $HOMEPAGE = "http://wwwinfo.cern.ch/dis/texi2html/"; # program home page
44 $TODAY = &pretty_date
; # like "20 September 1993"
45 $SPLITTAG = "<!-- SPLIT HERE -->\n"; # tag to know where to split
46 $PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections
47 $html2_doctype = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//EN">';
50 # language dependent constants
53 #$LDC_SECTION = 'section';
55 #$LDC_TOC = 'Table of Contents';
56 #$LDC_GOTO = 'Go to the';
57 #$LDC_FOOT = 'Footnotes';
58 # TODO: @def* shortcuts
85 # texinfo section names to level
100 'unnumberedsubsec', 3,
104 'unnumberedsubsubsec', 4,
106 'appendixsubsubsec', 4,
110 # accent map, TeX command to ISO name
121 # texinfo "simple things" (@foo) to HTML ones
138 # texinfo "things" (@foo{}) to HTML ones
142 'br', '<P>', # paragraph break
161 'exclamdown', '¡',
162 'questiondown', '¿',
167 # texinfo styles (@foo{bar}) to HTML ones
174 'ctrl', '&do_ctrl', # special case
175 'dfn', 'EM', # DFN tag is illegal in the standard
177 'email', '&do_email', # insert a clickable email address
179 'file', '"TT', # will put quotes, cf. &apply_style
184 'r', '', # unsupported
185 'samp', '"SAMP', # will put quotes, cf. &apply_style
186 'sc', '&do_sc', # special case
189 'titlefont', '', # useless
190 'uref', '&do_uref', # insert a clickable URL
191 'url', '&do_url', # insert a clickable URL
193 'w', '', # unsupported
194 '"', '&do_diaeresis',
195 '\'', '&do_acuteaccent', # doesn't work??
196 '\`', '&do_graveaccent', # doesn't work??
197 '~', '&do_tildeaccent',
199 '^', '&do_circumflex',
203 # texinfo format (@foo/@end foo) to HTML ones
210 'quotation', 'BLOCKQUOTE',
211 'smallexample', 'PRE',
222 # texinfo definition shortcuts to real ones
242 'defun', 'deffn Function',
243 'defmac', 'deffn Macro',
244 'defspec', 'deffn {Special Form}',
245 'defvar', 'defvr Variable',
246 'defopt', 'defvr {User Option}',
247 'deftypefun', 'deftypefn Function',
248 'deftypevar', 'deftypevr Variable',
249 'defivar', 'defcv {Instance Variable}',
250 'defmethod', 'defop Method',
252 'defunx', 'deffnx Function',
253 'defmacx', 'deffnx Macro',
254 'defspecx', 'deffnx {Special Form}',
255 'defvarx', 'defvrx Variable',
256 'defoptx', 'defvrx {User Option}',
257 'deftypefunx', 'deftypefnx Function',
258 'deftypevarx', 'deftypevrx Variable',
259 'defivarx', 'defcvx {Instance Variable}',
260 'defmethodx', 'defopx Method',
273 'summarycontents', 1,
279 # unsupported commands (formatting)
286 'setchapternewpage', 1,
296 'paragraphindent', 1,
297 # unsupported formats
304 #+++############################################################################
306 # Argument parsing, initialisation #
308 #---############################################################################
310 %value = (); # hold texinfo variables, see also -D
312 $use_bibliography = 1;
319 $invisible_mark = '';
323 $number_sections = 0;
330 To convert a Texinfo file to HMTL: $0 [options] file
331 where options can be:
332 -expandinfo : use \@ifinfo sections, not \@iftex
333 -glossary : handle a glossary
334 -invisible name: use 'name' as an invisible anchor
335 -Dname : define name like with \@set
336 -I dir : search also for files in 'dir'
338 -monolithic : output only one file including ToC
339 -number : number sections
340 -split_chapter : split on main sections
341 -split_node : split on nodes
342 -usage : print usage instructions
343 -verbose : verbose output
344 To check converted files: $0 -check [-verbose] files
347 while (@ARGV && $ARGV[0] =~ /^-/) {
349 if (/^-acc$/) { $use_acc = 1; next; }
350 if (/^-d(ebug)?(\d+)?$/) { $debug = $2 || shift(@ARGV); next; }
351 if (/^-doctype$/) { $doctype = shift(@ARGV); next; }
352 if (/^-c(heck)?$/) { $check = 1; next; }
353 if (/^-e(xpandinfo)?$/) { $expandinfo = 1; next; }
354 if (/^-g(lossary)?$/) { $use_glossary = 1; next; }
355 if (/^-i(nvisible)?$/) { $invisible_mark = shift(@ARGV); next; }
356 if (/^-iso$/) { $use_iso = 1; next; }
357 if (/^-D(.+)?$/) { $value{$1 || shift(@ARGV)} = 1; next; }
358 if (/^-I(.+)?$/) { push(@include_dirs, $1 || shift(@ARGV)); next; }
359 if (/^-m(enu)?$/) { $show_menu = 1; next; }
360 if (/^-mono(lithic)?$/) { $monolithic = 1; next; }
361 if (/^-n(umber)?$/) { $number_sections = 1; next; }
362 if (/^-s(plit)?_?(n(ode)?|c(hapter)?)?$/) {
370 if (/^-v(erbose)?$/) { $verbose = 1; next; }
374 die $usage unless @ARGV > 0;
379 if (($split_node || $split_chapter) && $monolithic) {
380 warn "Can't use -monolithic with -split, -monolithic ignored.\n";
384 $to_skip{'ifinfo'}++;
385 $to_skip{'end ifinfo'}++;
388 $to_skip{'end iftex'}++;
390 $invisible_mark = '<IMG SRC="invisible.xbm">' if $invisible_mark eq 'xbm';
391 die $usage unless @ARGV == 1;
392 $docu = shift(@ARGV);
393 if ($docu =~ /.*\//) {
394 chop($docu_dir = $&);
400 unshift(@include_dirs, $docu_dir);
401 $docu_name =~ s/\.te?x(i|info)?$//; # basename of the document
403 $docu_doc = "$docu_name.html"; # document's contents
405 $docu_toc = $docu_foot = $docu_doc;
407 $docu_toc = "${docu_name}_toc.html"; # document's table of contents
408 $docu_foot = "${docu_name}_foot.html"; # document's footnotes
414 $value{'html'} = 1; # predefine html (the output format)
415 $value{'texi2html'} = '1.52a'; # predefine texi2html (the translator)
416 # _foo: internal to track @foo
417 foreach ('_author', '_title', '_subtitle',
418 '_settitle', '_setfilename') {
419 $value{$_} = ''; # prevent -w warnings
421 %node2sec = (); # node to section name
422 %node2href = (); # node to HREF
423 %bib2href = (); # bibliography reference to HREF
424 %gloss2href = (); # glossary term to HREF
425 @sections = (); # list of sections
426 %tag2pro = (); # protected sections
440 # can I use ISO8879 characters? (HTML+)
443 $things_map{'bullet'} = "•";
444 $things_map{'copyright'} = "©";
445 $things_map{'dots'} = "…";
446 $things_map{'equiv'} = "≡";
447 $things_map{'expansion'} = "→";
448 $things_map{'point'} = "∗";
449 $things_map{'result'} = "⇒";
453 # read texi2html extensions (if any)
455 $extensions = 'texi2html.ext'; # extensions in working directory
456 if (-f
$extensions) {
457 print "# reading extensions from $extensions\n" if $verbose;
458 require($extensions);
460 ($progdir = $0) =~ s/[^\/]+$//;
461 if ($progdir && ($progdir ne './')) {
462 $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory
463 if (-f
$extensions) {
464 print "# reading extensions from $extensions\n" if $verbose;
465 require($extensions);
469 print "# reading from $docu\n" if $verbose;
471 #+++############################################################################
473 # Pass 1: read source, handle command, variable, simple substitution #
475 #---############################################################################
477 @lines = (); # whole document
478 @toc_lines = (); # table of contents
479 $toplevel = 0; # top level seen in hierarchy
480 $curlevel = 0; # current level in TOC
481 $node = ''; # current node name
482 $in_table = 0; # am I inside a table
483 $table_type = ''; # type of table ('', 'f', 'v', 'multi')
484 @tables = (); # nested table support
485 $in_bibliography = 0; # am I inside a bibliography
486 $in_glossary = 0; # am I inside a glossary
487 $in_top = 0; # am I inside the top node
488 $in_pre = 0; # am I inside a preformatted section
489 $in_list = 0; # am I inside a list
490 $in_html = 0; # am I inside an HTML section
491 $first_line = 1; # is it the first line
492 $dont_html = 0; # don't protect HTML on this line
493 $split_num = 0; # split index
494 $deferred_ref = ''; # deferred reference for indexes
495 @html_stack = (); # HTML elements stack
496 $html_element = ''; # current HTML element
499 # build code for simple substitutions
500 # the maps used (%simple_map and %things_map) MUST be aware of this
501 # watch out for regexps, / and escaped characters!
503 foreach (keys(%simple_map)) {
504 ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars
505 $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n";
507 foreach (keys(%things_map)) {
508 $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n";
511 # accentuated characters
512 foreach (keys(%accent_map)) {
514 $subst_code .= "s/$;3";
515 } elsif ($_ eq "'") {
516 $subst_code .= "s/$;4";
518 $subst_code .= "s/\\\@\\$_";
520 $subst_code .= "([aeiou])/&\${1}$accent_map{$_};/gi;\n";
523 eval("sub simple_substitutions { $subst_code }");
526 while ($_ = &next_line
) {
528 # remove \input on the first lines only
539 if (/^\@end\s+(\w+)\b/) {
541 } elsif (/^\@(\w+)\b/) {
545 # handle @ifhtml / @end ifhtml
548 if ($end_tag eq 'ifhtml') {
551 $tag2pro{$in_html} .= $_;
554 } elsif ($tag eq 'ifhtml') {
555 $in_html = $PROTECTTAG . ++$html_num;
556 push(@lines, $in_html);
560 # try to skip the line
563 next if $to_skip{"end $end_tag"};
565 next if $to_skip{$tag};
566 last if $tag eq 'bye';
569 # parsing the top node
570 if ($tag eq 'node' || $tag eq 'include' || $sec2level{$tag}) {
579 # try to remove inlined comments
580 # syntax from tex-mode.el comment-start-skip
582 s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/;
583 # non-@ substitutions cf. texinfmt.el
587 s/([\w ])---([\w ])/$1--$2/g;
594 &skip_until
($tag), next if $tag eq 'ignore';
596 &skip_until
($tag), next if $tag eq 'iftex';
598 &skip_until
($tag), next if $tag eq 'ifinfo';
600 &skip_until
($tag), next if $tag eq 'tex';
601 # handle special tables
602 if ($tag =~ /^(|f|v|multi)table$/) {
607 if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) {
609 @lines = (); # ignore all lines before top (title page garbage)
611 } elsif ($tag eq 'node') {
613 warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o;
614 $_ = &protect_html
($_); # if node contains '&' for instance
616 ($node) = split(/,/);
617 &normalise_node
($node);
620 push(@lines, $SPLITTAG) if $split_num++;
621 push(@sections, $node);
624 } elsif ($tag eq 'include') {
625 if (/^\@include\s+($FILERE)\s*$/o) {
628 foreach $dir (@include_dirs) {
635 print "# including $file\n" if $verbose;
637 warn "$ERROR Can't find $file, skipping";
640 warn "$ERROR Bad include line: $_";
643 } elsif ($tag eq 'ifclear') {
644 if (/^\@ifclear\s+($VARRE)\s*$/o) {
645 next unless defined($value{$1});
648 warn "$ERROR Bad ifclear line: $_";
651 } elsif ($tag eq 'ifset') {
652 if (/^\@ifset\s+($VARRE)\s*$/o) {
653 next if defined($value{$1});
656 warn "$ERROR Bad ifset line: $_";
659 } elsif ($tag eq 'menu') {
660 unless ($show_menu) {
665 push(@lines, &html_debug
("\n", __LINE__
));
666 } elsif ($format_map{$tag}) {
667 $in_pre = 1 if $format_map{$tag} eq 'PRE';
668 &html_push_if
($format_map{$tag});
669 push(@lines, &html_debug
("\n", __LINE__
));
670 $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ;
671 push(@lines, &debug
("<$format_map{$tag}>\n", __LINE__
));
673 } elsif ($tag eq 'table') {
674 if (/^\@(|f|v|multi)table\s+\@(\w+)/) {
676 unshift(@tables, join($;, $table_type, $in_table));
677 if ($table_type eq "multi") {
678 push(@lines, &debug
("<TABLE BORDER>\n", __LINE__
));
679 &html_push_if
('TABLE');
681 push(@lines, &debug
("<DL COMPACT>\n", __LINE__
));
684 push(@lines, &html_debug
("\n", __LINE__
));
686 warn "$ERROR Bad table line: $_";
689 } elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') {
690 if (/^\@$tag\s+(\w)\w\s+(\w)\w\s*$/) {
691 eval("*${1}index = *${2}index");
693 warn "$ERROR Bad syn*index line: $_";
696 } elsif ($tag eq 'sp') {
697 push(@lines, &debug
("<P>\n", __LINE__
));
699 } elsif ($tag eq 'setref') {
700 &protect_html
; # if setref contains '&' for instance
701 if (/^\@$tag\s*{($NODERE)}\s*$/) {
703 $setref =~ s/\s+/ /g; # normalize
705 $node2sec{$setref} = $name;
706 $node2href{$setref} = "$docu_doc#$docid";
708 warn "$ERROR Bad setref line: $_";
711 } elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') {
712 if (/^\@$tag\s+(\w\w)\s*$/) {
713 $valid_index{$1} = 1;
715 warn "$ERROR Bad defindex line: $_";
718 } elsif (defined($def_map{$tag})) {
719 if ($def_map{$tag}) {
721 $tag = $def_map{$tag};
725 } elsif (defined($user_sub{$tag})) {
727 $sub = $user_sub{$tag};
728 print "# user $tag = $sub, arg: $_" if $debug & $DEBUG_USER;
729 if (defined(&$sub)) {
733 warn "$ERROR Bad user sub for $tag: $sub\n";
737 if (defined($def_map{$tag})) {
740 # extra definition line
746 while (/\{([^\{\}]*)\}/) {
747 # this is a {} construct
748 ($before, $contents, $after) = ($`, $1, $');
750 $contents =~ s/\s+/$;9/g;
751 # restore $_ protecting {}
752 $_ = "$before$;7$contents$;8$after";
754 @args = split(/\s+/, &protect_html($_));
756 s/$;9/ /g; # unprotect spaces
760 $type = shift(@args);
761 $type =~ s/^\{(.*)\}$/$1/;
762 print "# def ($tag): {$type} ", join(', ', @args), "\n"
763 if $debug & $DEBUG_DEF;
764 $type .= ':'; # it's nicer like this
765 $name = shift(@args);
766 $name =~ s/^\{(.*)\}$/$1/;
768 $_ = &debug
("<DT>", __LINE__
);
770 $_ = &debug
("<DL>\n<DT>", __LINE__
);
772 if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') {
773 $_ .= "<U>$type</U> <B>$name</B>";
774 $_ .= " <I>@args</I>" if @args;
775 } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr'
776 || $tag eq 'defcv' || $tag eq 'defop') {
778 $name = shift(@args);
779 $name =~ s/^\{(.*)\}$/$1/;
780 $_ .= "<U>$type</U> $ftype <B>$name</B>";
781 $_ .= " <I>@args</I>" if @args;
783 warn "$ERROR Unknown definition type: $tag\n";
784 $_ .= "<U>$type</U> <B>$name</B>";
785 $_ .= " <I>@args</I>" if @args;
787 $_ .= &debug
("\n<DD>", __LINE__
);
788 $name = &unprotect_html
($name);
789 if ($tag eq 'deffn' || $tag eq 'deftypefn') {
790 unshift(@input_spool, "\@findex $name\n");
791 } elsif ($tag eq 'defop') {
792 unshift(@input_spool, "\@findex $name on $ftype\n");
793 } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') {
794 unshift(@input_spool, "\@vindex $name\n");
796 unshift(@input_spool, "\@tindex $name\n");
801 if ($format_map{$end_tag}) {
802 $in_pre = 0 if $format_map{$end_tag} eq 'PRE';
803 $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ;
804 &html_pop_if
('LI', 'P');
806 push(@lines, &debug
("</$format_map{$end_tag}>\n", __LINE__
));
807 push(@lines, &html_debug
("\n", __LINE__
));
808 } elsif ($end_tag =~ /^(|f|v|multi)table$/) {
810 warn "$ERROR \@end $end_tag without \@*table\n";
813 ($table_type, $in_table) = split($;, shift(@tables));
814 unless ($1 eq $table_type) {
815 warn "$ERROR \@end $end_tag without matching \@$end_tag\n";
818 if ($table_type eq "multi") {
819 push(@lines, "</TR></TABLE>\n");
822 push(@lines, "</DL>\n");
827 ($table_type, $in_table) = split($;, $tables[0]);
831 } elsif (defined($def_map{$end_tag})) {
832 push(@lines, &debug
("</DL>\n", __LINE__
));
833 } elsif ($end_tag eq 'menu') {
835 push(@lines, $_); # must keep it for pass 2
842 # protect texi and HTML things
844 $_ = &protect_html
($_) unless $dont_html;
846 # substitution (unsupported things)
851 # other substitutions
852 &simple_substitutions
;
853 s/\@value{($VARRE)}/$value{$1}/eg;
854 s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
856 # analyze the tag again
859 if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) {
860 if (/^\@$tag\s+(.+)$/) {
863 $level = $sec2level{$tag};
864 $name = &update_sec_num
($tag, $level) . " $name"
865 if $number_sections && $tag !~ /^unnumbered/;
866 if ($tag =~ /heading$/) {
867 push(@lines, &html_debug
("\n", __LINE__
));
868 if ($html_element ne 'body') {
869 # We are in a nice pickle here. We are trying to get a H? heading
870 # even though we are not in the body level. So, we convert it to a
871 # nice, bold, line by itself.
872 $_ = &debug
("\n\n<P><STRONG>$name</STRONG></P>\n\n", __LINE__
);
874 $_ = &debug
("<H$level>$name</H$level>\n", __LINE__
);
875 &html_push_if
('body');
877 print "# heading, section $name, level $level\n"
878 if $debug & $DEBUG_TOC;
880 if ($split_chapter) {
882 # first time we see a "section"
883 unless ($level == 1) {
884 warn "$ERROR The first section found is not of level 1: $_";
885 warn "$ERROR I'll split on sections of level $level...\n";
889 if ($level == $toplevel) {
891 push(@lines, $SPLITTAG) if $split_num++;
892 push(@sections, $name);
896 $docid = "SEC$sec_num";
897 $tocid = "TOC$sec_num";
898 # check biblio and glossary
899 $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i);
900 $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i);
903 if ($node2sec{$node}) {
904 warn "$ERROR Duplicate node found: $node\n";
906 $node2sec{$node} = $name;
907 $node2href{$node} = "$docu_doc#$docid";
908 print "# node $node, section $name, level $level\n"
909 if $debug & $DEBUG_TOC;
913 print "# no node, section $name, level $level\n"
914 if $debug & $DEBUG_TOC;
917 while ($level > $curlevel) {
919 push(@toc_lines, "<UL>\n");
921 while ($level < $curlevel) {
923 push(@toc_lines, "</UL>\n");
925 $_ = "<LI>" . &anchor
($tocid, "$docu_doc#$docid", $name, 1);
926 push(@toc_lines, &substitute_style
($_));
928 push(@lines, &html_debug
("\n", __LINE__
));
930 $_ = "<H$level>".&anchor
($docid, "$docu_toc#$tocid", $name)."</H$level>\n";
931 $_ = &debug
($_, __LINE__
);
932 push(@lines, &html_debug
("\n", __LINE__
));
935 foreach $line (split(/\n+/, $_)) {
936 push(@lines, "$line\n");
940 warn "$ERROR Bad section line: $_";
944 $value{$1} = $2, next if /^\@set\s+($VARRE)\s+(.*)$/o;
945 delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o;
947 $value{'_setfilename'} = $1, next if /^\@setfilename\s+(.*)$/;
948 $value{'_settitle'} = $1, next if /^\@settitle\s+(.*)$/;
949 $value{'_author'} .= "$1\n", next if /^\@author\s+(.*)$/;
950 $value{'_subtitle'} .= "$1\n", next if /^\@subtitle\s+(.*)$/;
951 $value{'_title'} .= "$1\n", next if /^\@title\s+(.*)$/;
953 if (/^\@(..?)index\s+/) {
954 unless ($valid_index{$1}) {
955 warn "$ERROR Undefined index command: $_";
958 $id = 'IDX' . ++$idx_num;
959 $index = $1 . 'index';
960 $what = &substitute_style
($');
962 print "# found $index for '$what' id $id\n"
963 if $debug & $DEBUG_INDEX;
965 if (defined(\$$index\{\$what\})) {
966 \$$index\{\$what\} .= "$;$docu_doc#$id";
968 \$$index\{\$what\} = "$docu_doc#$id";
972 # dirty hack to see if I can put an invisible anchor...
974 if ($html_element eq 'P' ||
975 $html_element eq 'LI' ||
976 $html_element eq 'DT' ||
977 $html_element eq 'DD' ||
978 $html_element eq 'ADDRESS' ||
979 $html_element eq 'B' ||
980 $html_element eq 'BLOCKQUOTE' ||
981 $html_element eq 'PRE' ||
982 $html_element eq 'SAMP') {
983 push(@lines, &anchor
($id, '', $invisible_mark, !$in_pre));
984 } elsif ($html_element eq 'body') {
985 push(@lines, &debug
("<P>\n", __LINE__
));
986 push(@lines, &anchor
($id, '', $invisible_mark, !$in_pre));
988 } elsif ($html_element eq 'DL' ||
989 $html_element eq 'UL' ||
990 $html_element eq 'OL' ) {
991 $deferred_ref .= &anchor
($id, '', $invisible_mark, !$in_pre) . " ";
996 if (/^\@itemx?\s+/) {
999 if ($in_bibliography && $use_bibliography) {
1000 if ($what =~ /^$BIBRE$/o) {
1001 $id = 'BIB
' . ++$bib_num;
1002 $bib2href{$what} = "$docu_doc#$id";
1003 print "# found bibliography for '$what' id $id\n"
1004 if $debug & $DEBUG_BIB;
1005 $what = &anchor($id, '', $what);
1007 } elsif ($in_glossary && $use_glossary) {
1008 $id = 'GLOSS
' . ++$gloss_num;
1010 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
1011 $gloss2href{$entry} = "$docu_doc#$id";
1012 print "# found glossary for '$entry' id $id\n"
1013 if $debug & $DEBUG_GLOSS;
1014 $what = &anchor($id, '', $what);
1017 if ($html_element eq 'DL
' || $html_element eq 'DD
') {
1018 if ($things_map{$in_table} && !$what) {
1019 # special case to allow @table @bullet for instance
1020 push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__));
1022 push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__));
1024 push(@lines, "<DD>");
1025 &html_push('DD
') unless $html_element eq 'DD
';
1026 if ($table_type) { # add also an index
1027 unshift(@input_spool, "\@${table_type}index $what\n");
1029 } elsif ($html_element eq 'TABLE
') {
1030 push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
1032 } elsif ($html_element eq 'TR
') {
1033 push(@lines, &debug("</TR>\n", __LINE__));
1034 push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
1036 push(@lines, &debug("<LI>$what\n", __LINE__));
1037 &html_push('LI
') unless $html_element eq 'LI
';
1039 push(@lines, &html_debug("\n", __LINE__));
1040 if ($deferred_ref) {
1041 push(@lines, &debug("$deferred_ref\n", __LINE__));
1045 } elsif (/^\@tab\s+(.*)$/) {
1046 push(@lines, "<TD>$1</TD>\n");
1051 # paragraph separator
1053 next if $#lines >= 0 && $lines[$#lines] eq "\n";
1054 if ($html_element eq 'P
') {
1056 $_ = &debug("</P>\n", __LINE__);
1059 } elsif ($html_element eq 'body
' || $html_element eq 'BLOCKQUOTE
') {
1060 push(@lines, "<P>\n");
1062 $_ = &debug($_, __LINE__);
1070 while ($level < $curlevel) {
1072 push(@toc_lines, "</UL>\n");
1075 print "# end of pass 1\n" if $verbose;
1077 #+++############################################################################
1079 # Pass 2/3: handle style, menu, index, cross-reference #
1081 #---############################################################################
1083 @lines2 = (); # whole document (2nd pass)
1084 @lines3 = (); # whole document (3rd pass)
1085 $in_menu = 0; # am I inside a menu
1090 # special case (protected sections)
1092 if (/^$PROTECTTAG/o) {
1099 $in_menu = 1, push(@lines2, &debug("<UL>\n", __LINE__)), next if /^\@menu\b/;
1100 $in_menu = 0, push(@lines2, &debug("</UL>\n", __LINE__)), next if /^\@end\s+menu\b/;
1102 if (/^\*\s+($NODERE)::/o) {
1105 &menu_entry
($1, $1, $descr);
1106 } elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) {
1109 &menu_entry($1, $2, $descr);
1111 warn "$ERROR Bad menu line: $_";
1112 } else { # description continued?
1120 if (/^\@printindex\s+(\w\w)\b/) {
1121 local($index, *ary, @keys, $key, $letter, $last_letter, @refs);
1122 if ($predefined_index{$1}) {
1123 $index = $predefined_index{$1} . 'index';
1125 $index = $1 . 'index';
1127 eval("*ary = *$index");
1129 foreach $key (@keys) {
1131 1 while s/<(\w+)>\`(.*)\´<\/\1>/$2/; # remove HTML tags with quotes
1132 1 while s/<(\w+)>(.*)<\/\1>/$2/; # remove HTML tags
1133 $_ = &unprotect_html($_);
1135 tr/A-Z/a-z/; # lowercase
1136 $key2alpha{$key} = $_;
1137 print "# index $key sorted as $_\n"
1138 if $key ne $_ && $debug & $DEBUG_INDEX;
1140 push(@lines2, "Jump to:\n");
1141 $last_letter = undef;
1142 foreach $key (sort byalpha @keys) {
1143 $letter = substr($key2alpha{$key}, 0, 1);
1144 $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;;
1145 if (!defined($last_letter) || $letter ne $last_letter) {
1146 push(@lines2, "-\n") if defined($last_letter);
1147 push(@lines2, "<A HREF=\"#$index\_$letter\">" . &protect_html($letter) . "</A>\n");
1148 $last_letter = $letter;
1151 push(@lines2, "<P>\n");
1152 $last_letter = undef;
1153 foreach $key (sort byalpha @keys) {
1154 $letter = substr($key2alpha{$key}, 0, 1);
1155 $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;;
1156 if (!defined($last_letter) || $letter ne $last_letter) {
1157 push(@lines2, "</DIR>\n") if defined($last_letter);
1158 push(@lines2, "<H2><A NAME=\"$index\_$letter\">" . &protect_html($letter) . "</A></H2>\n");
1159 push(@lines2, "<DIR>\n");
1160 $last_letter = $letter;
1163 foreach (split(/$;/, $ary{$key})) {
1164 push(@refs, &anchor('', $_, $key, 0));
1166 push(@lines2, "<LI>" . join(", ", @refs) . "\n");
1168 push(@lines2, "</DIR>\n") if defined($last_letter);
1172 # simple style substitutions
1174 $_ = &substitute_style($_);
1178 while (/\@(x|px|info|)ref{($XREFRE)(}?)/o) {
1179 # note: Texinfo may accept other characters
1180 ($type, $nodes, $full) = ($1, $2, $3);
1181 ($before, $after) = ($`, $');
1182 if (! $full && $after) {
1183 warn "$ERROR Bad xref (no ending } on line): $_";
1184 $_ = "$before$;0${type}ref\{$nodes$after";
1189 } elsif ($type eq 'px') {
1191 } elsif ($type eq 'info') {
1197 $next = shift(@lines);
1198 $next = &substitute_style
($next);
1199 chop($nodes); # remove final newline
1200 if ($next =~ /\}/) { # split on 2 lines
1205 $next = shift(@lines);
1206 $next = &substitute_style($next);
1208 if ($next =~ /\}/) { # split on 3 lines
1212 warn "$ERROR Bad xref (no ending }): $_";
1213 $_ = "$before$;0xref\{$nodes$after";
1214 unshift(@lines, $next);
1219 $nodes =~ s/\s+/ /g; # remove useless spaces
1220 @args = split(/\s*,\s*/, $nodes);
1221 $node = $args[0]; # the node is always the first arg
1222 &normalise_node
($node);
1223 $sec = $node2sec{$node};
1224 if (@args == 5) { # reference to another manual
1225 $sec = $args[2] || $node;
1226 $man = $args[4] || $args[3];
1227 $_ = "${before}${type}section `$sec' in \@cite{$man}$after";
1228 } elsif ($type =~ /Info/) { # inforef
1229 warn "$ERROR Wrong number of arguments: $_" unless @args == 3;
1230 ($nn, $_, $in) = @args;
1231 $_ = "${before}${type} file `$in', node `$nn'$after";
1233 $href = $node2href{$node};
1234 $_ = "${before}${type}section " . &anchor
('', $href, $sec) . $after;
1236 warn "$ERROR Undefined node ($node): $_";
1237 $_ = "$before$;0xref{$nodes}$after";
1241 # try to guess bibliography references or glossary terms
1243 unless (/^<H\d><A NAME=\"SEC\d/) {
1244 if ($use_bibliography) {
1247 ($pre, $what, $post) = ($`, $&, $');
1248 $href = $bib2href{$what};
1249 if (defined($href) && $post !~ /^[^<]*<\/A>/) {
1250 $done .= $pre . &anchor('', $href, $what);
1252 $done .= "$pre$what";
1258 if ($use_glossary) {
1261 ($pre, $what, $post) = ($`, $&, $');
1263 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
1264 $href = $gloss2href{$entry};
1265 if (defined($href) && $post !~ /^[^<]*<\/A>/) {
1266 $done .= $pre . &anchor('', $href, $what);
1268 $done .= "$pre$what";
1278 print "# end of pass 2\n" if $verbose;
1281 # split style substitutions
1284 $_ = shift(@lines2);
1286 # special case (protected sections)
1288 if (/^$PROTECTTAG/o) {
1293 # split style substitutions
1296 while ($old ne $_) {
1298 if (/\@(\w+|"|\~|,|\^)\{/) {
1299 ($before, $style, $after) = ($`, $1, $');
1300 if (defined($style_map{$style})) {
1313 $_ = shift(@lines2);
1317 die "* Bad syntax (\@$style) after: $before\n";
1319 $text = &apply_style($style, $text);
1320 $_ = "$before$text$after";
1328 print "# end of pass 3\n" if $verbose;
1330 #+++############################################################################
1332 # Pass 4: foot notes, final cleanup #
1334 #---############################################################################
1336 @foot_lines = (); # footnotes
1337 @doc_lines = (); # final document
1338 $end_of_para = 0; # true if last line is <P>
1341 $_ = shift(@lines3);
1343 # special case (protected sections)
1345 if (/^$PROTECTTAG/o) {
1346 push(@doc_lines, $_);
1353 while (/\@footnote([^\{\s]+)\{/) {
1354 ($before, $d, $after) = ($`, $1, $');
1367 $_ = shift(@lines3);
1371 die "* Bad syntax (\@footnote) after: $before\n";
1374 $docid = "DOCF$foot_num";
1375 $footid = "FOOT$foot_num";
1376 $foot = "($foot_num)";
1377 push(@foot_lines, "<H3>" . &anchor
($footid, "$d#$docid", $foot) . "</H3>\n");
1378 $text = "<P>$text" unless $text =~ /^\s*<P>/;
1379 push(@foot_lines, "$text\n");
1380 $_ = $before . &anchor
($docid, "$docu_foot#$footid", $foot) . $after;
1384 # remove unnecessary <P>
1386 if (/^\s*<P>\s*$/) {
1387 next if $end_of_para++;
1392 push(@doc_lines, $_);
1394 print "# end of pass 4\n" if $verbose;
1396 #+++############################################################################
1398 # Pass 5: print things #
1400 #---############################################################################
1403 <!-- This HTML file has been created by $THISPROG
1404 from $docu on $TODAY -->
1407 $full_title = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
1408 $title = $value{'_settitle'} || $full_title;
1409 $_ = &substitute_style
($full_title);
1411 s/\n$//; # rmv last \n (if any)
1412 $full_title = "<H1>" . join("</H1>\n<H1>", split(/\n/, $_)) . "</H1
>\n";
1417 if (!$monolithic && @toc_lines) {
1418 if (open(FILE, "> $docu_toc")) {
1419 print "# creating $docu_toc...\n" if $verbose;
1420 &print_toplevel_header
("$title - Table of Contents");
1422 &print(*toc_lines
, FILE
);
1423 &print_toplevel_footer
;
1426 warn "$ERROR Can't write to $docu_toc: $!\n";
1433 if (!$monolithic && @foot_lines) {
1434 if (open(FILE
, "> $docu_foot")) {
1435 print "# creating $docu_foot...\n" if $verbose;
1436 &print_toplevel_header
("$title - Footnotes");
1438 &print(*foot_lines
, FILE
);
1439 &print_toplevel_footer
;
1442 warn "$ERROR Can't write to $docu_foot: $!\n";
1449 if ($split_chapter || $split_node) { # split
1451 $last_num = scalar(@sections);
1452 $first_doc = &doc_name
(1);
1453 $last_doc = &doc_name
($last_num);
1455 $section = shift(@sections);
1457 if (open(FILE
, "> $docu_doc")) {
1458 print "# creating $docu_doc...\n" if $verbose;
1459 &print_header
("$title - $section");
1460 $prev_doc = ($doc_num == 1 ?
undef : &doc_name
($doc_num - 1));
1461 $next_doc = ($doc_num == $last_num ?
undef : &doc_name
($doc_num + 1));
1462 $navigation = "Go to the ";
1463 $navigation .= ($prev_doc ?
&anchor
('', $first_doc, "first") : "first");
1464 $navigation .= ", ";
1465 $navigation .= ($prev_doc ?
&anchor
('', $prev_doc, "previous") : "previous");
1466 $navigation .= ", ";
1467 $navigation .= ($next_doc ?
&anchor
('', $next_doc, "next") : "next");
1468 $navigation .= ", ";
1469 $navigation .= ($next_doc ?
&anchor
('', $last_doc, "last") : "last");
1470 $navigation .= " section, " . &anchor
('', $docu_toc, "table of contents") . ".\n";
1471 print FILE
$navigation;
1473 # find corresponding lines
1475 while (@doc_lines) {
1476 $_ = shift(@doc_lines);
1477 last if ($_ eq $SPLITTAG);
1478 push(@tmp_lines, $_);
1480 &print(*tmp_lines
, FILE
);
1482 print FILE
$navigation;
1486 warn "$ERROR Can't write to $docu_doc: $!\n";
1489 } else { # not split
1490 if (open(FILE
, "> $docu_doc")) {
1491 print "# creating $docu_doc...\n" if $verbose;
1492 if ($monolithic || !@toc_lines) {
1493 &print_toplevel_header
($title);
1495 &print_header
($title);
1496 print FILE
$full_title;
1498 if ($monolithic && @toc_lines) {
1500 print FILE
"<H1>Table of Contents</H1>\n";
1501 &print(*toc_lines
, FILE
);
1504 &print(*doc_lines
, FILE
);
1505 if ($monolithic && @foot_lines) {
1507 print FILE
"<H1>Footnotes</H1>\n";
1508 &print(*foot_lines
, FILE
);
1510 if ($monolithic || !@toc_lines) {
1511 &print_toplevel_footer
;
1517 warn "$ERROR Can't write to $docu_doc: $!\n";
1521 print "# that's all folks\n" if $verbose;
1523 #+++############################################################################
1525 # Low level functions #
1527 #---############################################################################
1529 sub update_sec_num
{
1530 local($name, $level) = @_;
1532 $level--; # here we start at 0
1533 if ($name =~ /^appendix/) {
1535 if (defined(@appendix_sec_num)) {
1536 &incr_sec_num
($level, @appendix_sec_num);
1538 @appendix_sec_num = ('A', 0, 0, 0);
1540 return(join('.', @appendix_sec_num[0..$level]));
1543 if (defined(@normal_sec_num)) {
1544 &incr_sec_num
($level, @normal_sec_num);
1546 @normal_sec_num = (1, 0, 0, 0);
1548 return(join('.', @normal_sec_num[0..$level]));
1556 foreach $l ($level+1 .. 3) {
1562 local($_, %seen, %context, $before, $match, $after);
1565 if (/\@(\*|\.|\:|\@|\{|\})/) {
1567 $context{$&} .= "> $_" if $verbose;
1572 ($before, $match, $after) = ($`, $&, $');
1573 if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address
1574 $seen{'e-mail address'}++;
1575 $context{'e-mail address'} .= "> $_" if $verbose;
1578 $context{$match} .= "> $_" if $verbose;
1581 $_ = "$before$match$after";
1586 foreach (sort(keys(%seen))) {
1591 print "$_ ($seen{$_})\n";
1600 if (open($fh_name, $name)) {
1601 unshift(@fhs, $fh_name);
1603 warn "$ERROR Can't read file $name: $!\n";
1608 @fhs = (); # hold the file handles to read
1609 @input_spool = (); # spooled lines to read
1618 $line = shift(@input_spool);
1624 return($line) if $line;
1631 # used in pass 1, use &next_line
1636 while ($_ = &next_line) {
1637 return if /^\@end\s+$tag\s*$/;
1639 die "* Failed to find '$tag' after: " . $lines[$#lines];
1643 # HTML stacking to have a better HTML output
1647 @html_stack = ('html');
1648 $html_element = 'body';
1653 push(@html_stack, $html_element);
1654 $html_element = $what;
1659 push(@html_stack, $html_element)
1660 if ($html_element && $html_element ne 'P');
1661 $html_element = $what;
1665 $html_element = pop(@html_stack);
1673 if ($elt eq $html_element) {
1674 $html_element = pop(@html_stack) if @html_stack;
1679 $html_element = pop(@html_stack) if @html_stack;
1684 local($what, $line) = @_;
1685 return("<!-- $line @html_stack, $html_element -->$what")
1686 if $debug & $DEBUG_HTML;
1690 # to debug the output...
1692 local($what, $line) = @_;
1693 return("<!-- $line -->$what")
1694 if $debug & $DEBUG_HTML;
1698 sub normalise_node {
1705 local($entry, $node, $descr) = @_;
1708 &normalise_node($node);
1709 $href = $node2href{$node};
1712 $descr = ": $descr" if $descr;
1713 push(@lines2, "<LI>" . &anchor('', $href, $entry) . "$descr\n");
1715 warn "$ERROR Undefined node ($node): $_";
1719 sub do_ctrl { "^$_[0]" }
1722 local($addr, $text) = split(/,\s*/, $_[0]);
1724 $text = $addr unless $text;
1725 &anchor('', "mailto:$addr", $text);
1728 sub do_sc { "\U$_[0]\E" }
1731 local($url, $text) = split(/,\s*/, $_[0]);
1733 $text = $url unless $text;
1734 &anchor('', $url, $text);
1737 sub do_url { &anchor('', $_[0], $_[0]) }
1739 sub do_diaeresis { return "&$_[0]uml;"; }
1740 sub do_acuteaccent { return "&$_[0]acute;"; }
1741 sub do_graveaccent { return "&$_[0]grave;"; }
1742 sub do_tildeaccent { return "&$_[0]tilde;"; }
1743 sub do_cedilla { return "&$_[0]cedil;"; }
1744 sub do_circumflex { return "&$_[0]circ;"; }
1747 local($texi_style, $text) = @_;
1750 $style = $style_map{$texi_style};
1751 if (defined($style)) { # known style
1752 if ($style =~ /^\"/) { # add quotes
1754 $text = "\`$text\
´
;";
1756 if ($style =~ /^\&/) { # custom
1758 $text = &$style($text);
1759 } elsif ($style) { # good style
1760 $text = "<$style>$text</$style>";
1763 } else { # unknown style
1769 # remove Texinfo styles
1772 s/\@\w+{([^\{\}]+)}/$1/g;
1776 sub substitute_style {
1778 local($changed, $done, $style, $text);
1784 while (/\@(\w+|"|\
~|,|\
^){([^\
{\
}]+)}/) {
1785 $text = &apply_style
($1, $2);
1800 local($name, $href, $text, $newline) = @_;
1804 $result .= " NAME=\"$name\"" if $name;
1805 $result .= " HREF=\"$href\"" if $href;
1806 $result .= ">$text</A>";
1807 $result .= "\n" if $newline;
1812 local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
1814 @MoY = ('January', 'Febuary', 'March', 'April', 'May', 'June',
1815 'July', 'August', 'September', 'October', 'November', 'December');
1816 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
1817 $year += ($year < 70) ?
2000 : 1900;
1818 return("$mday $MoY[$mon] $year");
1824 return("${docu_name}_$num.html");
1828 $docu_doc = &doc_name
(++$doc_num);
1832 local(*lines
, $fh) = @_;
1837 if (/^$PROTECTTAG/o) {
1847 print FILE
"<P><HR><P>\n";
1854 $_ = &remove_style
($_[0]);
1857 if ($doctype eq 'html2') {
1858 print FILE
$html2_doctype;
1859 } elsif ($doctype) {
1860 print FILE
$doctype;
1872 sub print_toplevel_header
{
1875 &print_header
; # pass given arg...
1876 print FILE
$full_title;
1877 if ($value{'_subtitle'}) {
1878 $value{'_subtitle'} =~ s/\n+$//;
1879 foreach (split(/\n/, $value{'_subtitle'})) {
1880 $_ = &substitute_style
($_);
1882 print FILE
"<H2>$_</H2>\n";
1885 if ($value{'_author'}) {
1886 $value{'_author'} =~ s/\n+$//;
1887 foreach (split(/\n/, $value{'_author'})) {
1888 $_ = &substitute_style
($_);
1890 s/[\w.-]+\@[\w.-]+/<A HREF="mailto:$&">$&<\/A
>/g
;
1891 print FILE
"<ADDRESS>$_</ADDRESS>\n";
1904 sub print_toplevel_footer
{
1907 This document was generated on $TODAY using the
1908 <A HREF=\"$HOMEPAGE\">texi2html</A>
1909 translator version 1.52a.</P>
1926 $what =~ s/\&/\&\#38;/g;
1927 $what =~ s/\</\&\#60;/g;
1928 $what =~ s/\>/\&\#62;/g;
1929 # but recognize some HTML things
1930 $what =~ s/\&\#60;\/A\&\#62;/<\
/A>/g; # </A>
1931 $what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g; # <A [^&]+>
1932 $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+>
1936 sub unprotect_texi
{
1944 sub unprotect_html
{
1946 $what =~ s/\&\#38;/\&/g;
1947 $what =~ s/\&\#60;/\</g;
1948 $what =~ s/\&\#62;/\>/g;
1953 $key2alpha{$a} cmp $key2alpha{$b};
1956 ##############################################################################
1958 # These next few lines are legal in both Perl and nroff.
1962 'di \" finish diversion--previous line must be blank
1963 .nr nl 0-1 \" fake up transition to first page again
1964 .nr % 0 \" start at page 1
1965 '; __END__
############# From here on it's a standard manual page ############
1966 .TH TEXI2HTML
1 "01/05/98"
1969 texi2html \
- a Texinfo to HTML converter
1971 .B texi2html
[options
] file
1973 .B texi2html
-check
[-verbose
] files
1976 converts the
given Texinfo file to a set of HTML files
. It tries to handle
1977 most of the Texinfo commands
. It creates hypertext links
for cross
-references
,
1980 It also tries to add links from a reference to its corresponding entry
in the
1981 bibliography
(if any
). It may also handle a glossary
(see the
1986 creates several files depending on the contents of the Texinfo file
and on
1987 the chosen options
(see FILES
).
1989 The HTML files created by
1991 are closer to TeX than to Info
, that
's why
1993 converts @iftex sections and not @ifinfo ones by default. You can reverse
1994 this with the \-expandinfo option.
1998 Check the given file and give the list of all things that may be Texinfo commands.
1999 This may be used to check the output of
2001 to find the Texinfo commands that have been left in the HTML file.
2004 Expand @ifinfo sections, not @iftex ones.
2007 Use the section named 'Glossary
' to build a list of terms and put links in the HTML
2008 document from each term toward its definition.
2010 .B \-invisible \fIname\fP
2011 Use \fIname\fP to create invisible destination anchors for index links
2012 (you can for instance use the invisible.xbm file shipped with this program).
2013 This is a workaround for a known bug of many WWW browsers, including netscape.
2016 Look also in \fIdir\fP to find included files.
2019 Show the Texinfo menus; by default they are ignored.
2022 Output only one file, including the table of contents and footnotes.
2025 Number the sections.
2028 Split the output into several HTML files (one per main section:
2029 chapter, appendix...).
2032 Split the output into several HTML files (one per node).
2035 Print usage instructions, listing the current available command-line options.
2038 Give a verbose output. Can be used with the
2045 creates the following files (foo being the name of the Texinfo file):
2048 The table of contents.
2051 The document's contents
.
2054 The footnotes
(if any
).
2058 option
, it creates several files
(one per chapter
or node
), named
2060 (n being the indice of the chapter
or node
), instead of the single
2066 option
, it creates only one file
:
2070 predefines the following variables
: \fBhtml
\fP
, \fBtexi
2html
\fP
.
2071 .SH ADDITIONAL COMMANDS
2073 implements the following non
-Texinfo commands
(maybe they are
in Texinfo now
...):
2076 This indicates the start of an HTML section
, this section will passed through
2077 without any modification
.
2080 This indicates the end of an HTML section
.
2082 This is
\fItexi
2html
\fP version
1.52a
, 01/05/98.
2084 The latest version of
\fItexi
2html
\fP can be found
in WWW
, cf
. URL
2085 http
://wwwinfo
.cern
.ch
/dis/texi2html
/
2087 The main author is Lionel Cons
, CERN IT
/DIS/OSE
, Lionel
.Cons
@cern.ch
.
2088 Many other people around the net contributed to this program
.
2090 This program is the intellectual property of the European
2091 Laboratory
for Particle Physics
(known as CERN
). No guarantee whatsoever is
2092 provided by CERN
. No liability whatsoever is accepted
for any loss
or damage
2093 of any kind resulting from any defect
or inaccuracy
in this information
or
2096 CERN
, 1211 Geneva
23, Switzerland
2098 GNU Texinfo Documentation Format
,
2099 HyperText Markup Language
(HTML
),
2100 World Wide Web
(WWW
).
2102 This program does
not understand all Texinfo commands
(yet
).
2104 TeX specific commands
(normally enclosed
in @iftex) will be