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