[BACK]Return to texi2html CVS log [TXT][DIR] Up to [local] / OpenXM / src / asir-doc

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:               "-", "&#173;",   # 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:     &check;
        !           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'} = "&bull;";
        !           440:     $things_map{'copyright'} = "&copy;";
        !           441:     $things_map{'dots'} = "&hellip;";
        !           442:     $things_map{'equiv'} = "&equiv;";
        !           443:     $things_map{'expansion'} = "&rarr;";
        !           444:     $things_map{'point'} = "&lowast;";
        !           445:     $things_map{'result'} = "&rArr;";
        !           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>&nbsp;$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>