1#! /usr/bin/perl
2'di ';
3'ig 00 ';
4#+##############################################################################
5#
6# texi2html: Program to transform Texinfo documents to HTML
7#
8#    Copyright (C) 1999, 2000  Free Software Foundation, Inc.
9#
10#   This program is free software: you can redistribute it and/or modify
11#   it under the terms of the GNU General Public License as published by
12#   the Free Software Foundation, either version 3 of the License, or
13#   (at your option) any later version.
14#
15#   This program is distributed in the hope that it will be useful,
16#   but WITHOUT ANY WARRANTY; without even the implied warranty of
17#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18#   GNU General Public License for more details.
19#
20#   You should have received a copy of the GNU General Public License
21#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22#
23#-##############################################################################
24
25# This requires perl version 5 or higher
26require 5.0;
27
28#++##############################################################################
29#
30# NOTE FOR DEBUGGING THIS SCRIPT:
31# You can run 'perl texi2html.pl' directly, provided you have
32# the environment variable T2H_HOME set to the directory containing
33# the texi2html.init file
34#
35#--##############################################################################
36
37# CVS version:
38# $Id: texi2html 7792 2004-06-07 09:07:27Z korli $
39
40# Homepage:
41$T2H_HOMEPAGE = <<EOT;
42http://www.mathematik.uni-kl.de/~obachman/Texi2html
43EOT
44
45# Authors:  
46$T2H_AUTHORS = <<EOT;
47Written by: Lionel Cons <Lionel.Cons\@cern.ch> (original author)
48            Karl Berry  <karl\@freefriends.org>
49            Olaf Bachmann <obachman\@mathematik.uni-kl.de>
50            and many others.
51Maintained by: Olaf Bachmann <obachman\@mathematik.uni-kl.de>
52Send bugs and suggestions to <texi2html\@mathematik.uni-kl.de>
53EOT
54
55# Version: set in configure.in
56$THISVERSION = '1.64';
57$THISPROG = "texi2html $THISVERSION";	# program name and version
58  
59# The man page for this program is included at the end of this file and can be
60# viewed using the command 'nroff -man texi2html'.
61
62# Identity:
63
64$T2H_TODAY = &pretty_date;		# like "20 September 1993"
65# the eval prevents this from breaking on system which do not have
66# a proper getpwuid implemented
67eval { ($T2H_USER = (getpwuid ($<))[6]) =~ s/,.*//;}; # Who am i
68
69#+++############################################################################
70#                                                                              #
71# Initialization                                                               #
72# Pasted content of File $(srcdir)/texi2html.init: Default initializations     # 
73#                                                                              #
74#---############################################################################
75
76# leave this within comments, and keep the require statement
77# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init
78# exists.
79
80# 
81# -*-perl-*-
82######################################################################
83# File: texi2html.init
84#
85# Sets default values for command-line arguments and for various customizable
86# procedures
87#
88# A copy of this file is pasted into the beginning of texi2html by
89# 'make texi2html'
90#
91# Copy this file and make changes to it, if you like.
92# Afterwards, either, load it with command-line option -init_file <your_init_file>
93#
94# $Id: texi2html 7792 2004-06-07 09:07:27Z korli $
95
96######################################################################
97# stuff which can also be set by command-line options
98#
99#
100# Note: values set here, overwrite values set by the command-line
101# options before -init_file and might still be overwritten by
102# command-line arguments following the -init_file option
103#
104
105# T2H_OPTIONS is a hash whose keys are the (long) names of valid
106# command-line options and whose values are a hash with the following keys:
107# type    ==> one of !|=i|:i|=s|:s (see GetOpt::Long for more info)
108# linkage ==> ref to scalar, array, or subroutine (see GetOpt::Long for more info)
109# verbose ==> short description of option (displayed by -h)
110# noHelp  ==> if 1 -> for "not so important options": only print description on -h 1
111#                2 -> for obsolete options: only print description on -h 2
112
113$T2H_DEBUG = 0;
114$T2H_OPTIONS -> {debug} =
115{
116 type => '=i',
117 linkage => \$main::T2H_DEBUG,
118 verbose => 'output HTML with debuging information',
119};
120
121$T2H_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'; 
122$T2H_OPTIONS -> {doctype} = 
123{
124 type => '=s',
125 linkage => \$main::T2H_DOCTYPE,
126 verbose => 'document type which is output in header of HTML files',
127 noHelp => 1
128};
129
130$T2H_CHECK = 0;
131$T2H_OPTIONS -> {check} =
132{
133 type => '!',
134 linkage => \$main::T2H_CHECK,
135 verbose => 'if set, only check files and output all things that may be Texinfo commands',
136 noHelp => 1
137};
138
139# -expand
140# if set to "tex" (or, "info") expand @iftex and @tex (or, @ifinfo) sections
141# else, neither expand @iftex, @tex, nor @ifinfo sections
142$T2H_EXPAND = "info";
143$T2H_OPTIONS -> {expand} = 
144{
145 type => '=s',
146 linkage => \$T2H_EXPAND,
147 verbose => 'Expand info|tex|none section of texinfo source',
148};
149
150# - glossary
151#if set, uses section named `Footnotes' for glossary
152$T2H_USE_GLOSSARY = 0;
153T2H_OPTIONS -> {glossary} =
154{
155 type => '!',
156 linkage => \$T2H_USE_GLOSSARY,
157 verbose => "if set, uses section named `Footnotes' for glossary",
158 noHelp  => 1,
159};
160
161
162# -invisible
163# $T2H_INVISIBLE_MARK is the text used to create invisible destination
164# anchors for index links (you can for instance use the invisible.xbm
165# file shipped with this program). This is a workaround for a known
166# bug of many WWW browsers, including netscape.
167# For me, it works fine without it -- on the contrary: if there, it
168# inserts space between headers and start of text (obachman 3/99)
169$T2H_INVISIBLE_MARK = '';
170# $T2H_INVISIBLE_MARK = '&#160;';
171$T2H_OPTIONS -> {invisible} =
172{
173 type => '=s',
174 linkage => \$T2H_INVISIBLE_MARK,
175 verbose => 'use text in invisble anchot',
176 noHelp  => 1,
177};
178
179# -iso
180# if set, ISO8879 characters are used for special symbols (like copyright, etc)
181$T2H_USE_ISO = 0;
182$T2H_OPTIONS -> {iso} =
183{
184 type => 'iso',
185 linkage => \$T2H_USE_ISO,
186 verbose => 'if set, ISO8879 characters are used for special symbols (like copyright, etc)',
187 noHelp => 1,
188};
189
190# -I
191# list directories where @include files are searched for (besides the
192# directory of the doc file) additional '-I' args add to this list
193@T2H_INCLUDE_DIRS = (".");
194$T2H_OPTIONS -> {I} =
195{
196 type => '=s',
197 linkage => \@T2H_INCLUDE_DIRS,
198 verbose => 'append $s to the @include search path',
199};
200
201# -top_file
202# uses file of this name for top-level file
203# extension is manipulated appropriately, if necessary.
204# If empty, <basename of document>.html is used
205# Typically, you would set this to "index.html".
206$T2H_TOP_FILE = '';
207$T2H_OPTIONS -> {top_file} =
208{
209 type => '=s',
210 linkage => \$T2H_TOP_FILE,
211 verbose => 'use $s as top file, instead of <docname>.html',
212};
213
214
215# -toc_file
216# uses file of this name for table of contents file
217# extension is manipulated appropriately, if necessary.
218# If empty, <basename of document>_toc.html is used
219$T2H_TOC_FILE = '';
220$T2H_OPTIONS -> {toc_file} =
221{
222 type => '=s',
223 linkage => \$T2H_TOC_FILE,
224 verbose => 'use $s as ToC file, instead of <docname>_toc.html',
225};
226
227# -frames
228# if set, output two additional files which use HTML 4.0 "frames".
229$T2H_FRAMES = 0;
230$T2H_OPTIONS -> {frames} =
231{
232 type => '!',
233 linkage => \$T2H_FRAMES,
234 verbose => 'output files which use HTML 4.0 frames (experimental)',
235 noHelp => 1,
236};
237
238
239# -menu | -nomenu
240# if set, show the Texinfo menus
241$T2H_SHOW_MENU = 1;
242$T2H_OPTIONS -> {menu} =
243{
244 type => '!',
245 linkage => \$T2H_SHOW_MENU,
246 verbose => 'ouput Texinfo menus',
247};
248
249# -number | -nonumber
250# if set, number sections and show section names and numbers in references 
251# and menus
252$T2H_NUMBER_SECTIONS = 1;
253$T2H_OPTIONS -> {number} =
254{
255 type => '!',
256 linkage => \$T2H_NUMBER_SECTIONS,
257 verbose => 'use numbered sections'
258};
259
260# if set, and T2H_NUMBER_SECTIONS is set, then use node names in menu
261# entries, instead of section names
262$T2H_NODE_NAME_IN_MENU = 0;
263
264# if set and menu entry equals menu descr, then do not print menu descr.
265# Likewise, if node name equals entry name, do not print entry name.
266$T2H_AVOID_MENU_REDUNDANCY = 1;
267
268# -split section|chapter|none 
269# if set to 'section' (resp. 'chapter') create one html file per (sub)section
270# (resp. chapter) and separate pages for Top, ToC, Overview, Index,
271# Glossary, About.
272# otherwise, create monolithic html file which contains whole document
273#$T2H_SPLIT = 'section';
274$T2H_SPLIT = '';
275$T2H_OPTIONS -> {split} =
276{
277 type => '=s',
278 linkage => \$T2H_SPLIT,
279 verbose => 'split document on section|chapter else no splitting',
280};
281
282# -section_navigation|-no-section_navigation
283# if set, then navigation panels are printed at the beginning of each section
284# and, possibly at the end (depending on whether or not there were more than 
285# $T2H_WORDS_IN_PAGE  words on page
286# This is most useful if you do not want to have section navigation 
287# on -split chapter
288$T2H_SECTION_NAVIGATION = 1;
289$T2H_OPTIONS -> {sec_nav} =
290{
291 type => '!',
292 linkage => \$T2H_SECTION_NAVIGATION,
293 verbose => 'output navigation panels for each section',
294};
295
296# -subdir
297# if set put result files in this directory
298# if not set result files are put into current directory
299#$T2H_SUBDIR = 'html';
300$T2H_SUBDIR = '';
301$T2H_OPTIONS -> {subdir} =
302{
303 type => '=s',
304 linkage => \$T2H_SUBDIR,
305 verbose => 'put HTML files in directory $s, instead of $cwd',
306};
307
308# -short_extn
309# If this is set all HTML file will have extension ".htm" instead of
310# ".html". This is helpful when shipping the document to PC systems.
311$T2H_SHORTEXTN = 0;
312$T2H_OPTIONS -> {short_ext} =
313{
314 type => '!',
315 linkage => \$T2H_SHORTEXTN,
316 verbose => 'use "htm" extension for output HTML files',
317};
318
319
320# -prefix
321# Set the output file prefix, prepended to all .html, .gif and .pl files.
322# By default, this is the basename of the document
323$T2H_PREFIX = '';
324$T2H_OPTIONS -> {prefix} =
325{
326 type => '=s',
327 linkage => \$T2H_PREFIX,
328 verbose => 'use as prefix for output files, instead of <docname>',
329};
330
331# -o filename
332# If set, generate monolithic document output html into $filename
333$T2H_OUT = '';
334$T2H_OPTIONS -> {out_file} =
335{
336 type => '=s',
337 linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';},
338 verbose => 'if set, all HTML output goes into file $s',
339};
340
341# -short_ref
342#if set cross-references are given without section numbers
343$T2H_SHORT_REF = '';
344$T2H_OPTIONS -> {short_ref} =
345{
346 type => '!',
347 linkage => \$T2H_SHORT_REF,
348 verbose => 'if set, references are without section numbers',
349};
350
351# -idx_sum
352# if value is set, then for each @prinindex $what
353# $docu_name_$what.idx is created which contains lines of the form
354# $key\t$ref sorted alphabetically (case matters)
355$T2H_IDX_SUMMARY = 0;
356$T2H_OPTIONS -> {idx_sum} =
357{
358 type => '!',
359 linkage => \$T2H_IDX_SUMMARY,
360 verbose => 'if set, also output index summary',
361 noHelp  => 1,
362};
363
364# -verbose
365# if set, chatter about what we are doing
366$T2H_VERBOSE = '';
367$T2H_OPTIONS -> {Verbose} =
368{
369 type => '!',
370 linkage => \$T2H_VERBOSE,
371 verbose => 'print progress info to stdout',
372};
373
374# -lang
375# For page titles use $T2H_WORDS->{$T2H_LANG}->{...} as title.
376# To add a new language, supply list of titles (see $T2H_WORDS below).
377# and use ISO 639 language codes (see e.g. perl module Locale-Codes-1.02 
378# for  definitions)
379# Default's to 'en' if not set or no @documentlanguage is specified
380$T2H_LANG = '';
381$T2H_OPTIONS -> {lang} =
382{
383 type => '=s',
384 linkage => sub {SetDocumentLanguage($_[1])},
385 verbose => 'use $s as document language (ISO 639 encoding)',
386};
387
388# -l2h
389# if set, uses latex2html for generation of math content 
390$T2H_L2H = '';
391$T2H_OPTIONS -> {l2h} =
392{
393 type => '!',
394 linkage => \$T2H_L2H,
395 verbose => 'if set, uses latex2html for @math and @tex',
396};
397
398######################
399# The following options are only relevant if $T2H_L2H is set
400#
401# -l2h_l2h
402# name/location of latex2html progam
403$T2H_L2H_L2H = "latex2html";
404$T2H_OPTIONS -> {l2h_l2h} =
405{
406 type => '=s',
407 linkage => \$T2H_L2H_L2H,
408 verbose => 'program to use for latex2html translation',
409 noHelp => 1,
410};
411
412# -l2h_skip
413# if set, skips actual call to latex2html tries to reuse previously generated 
414# content, instead
415$T2H_L2H_SKIP = '';
416$T2H_OPTIONS -> {l2h_skip} =
417{
418 type => '!',
419 linkage => \$T2H_L2H_SKIP,
420 verbose => 'if set, tries to reuse previously latex2html output',
421 noHelp => 1,
422};
423
424# -l2h_tmp
425# if set, l2h uses this directory for temporarary files. The path
426# leading to this directory may not contain a dot (i.e., a "."),
427# otherwise, l2h will fail
428$T2H_L2H_TMP = '';
429$T2H_OPTIONS -> {l2h_tmp} =
430{
431 type => '=s',
432 linkage => \$T2H_L2H_TMP,
433 verbose => 'if set, uses $s as temporary latex2html directory',
434 noHelp => 1,
435};
436
437# if set, cleans intermediate files (they all have the prefix $doc_l2h_) 
438# of l2h 
439$T2H_L2H_CLEAN = 1;
440$T2H_OPTIONS -> {l2h_clean} =
441{
442 type => '!',
443 linkage => \$T2H_L2H_CLEAN,
444 verbose => 'if set, do not keep intermediate latex2html files for later reuse',
445 noHelp => 1,
446};
447
448$T2H_OPTIONS -> {D} =
449{
450 type => '=s',
451 linkage => sub {$main::value{@_[1]} = 1;},
452 verbose => 'equivalent to Texinfo "@set $s 1"',
453 noHelp => 1,
454};
455
456$T2H_OPTIONS -> {init_file} =
457{
458 type => '=s',
459 linkage => \&LoadInitFile,
460 verbose => 'load init file $s'
461};
462
463
464##############################################################################
465#
466# The following can only be set in the init file
467#
468##############################################################################
469
470# if set, center @image by default
471# otherwise, do not center by default
472$T2H_CENTER_IMAGE = 1;
473
474# used as identation for block enclosing command @example, etc
475# If not empty, must be enclosed in <td></td>
476$T2H_EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';
477# same as above, only for @small
478$T2H_SMALL_EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';
479# font size for @small
480$T2H_SMALL_FONT_SIZE = '-1';
481
482# if non-empty, and no @..heading appeared in Top node, then
483# use this as header for top node/section, otherwise use value of 
484# @settitle or @shorttitle (in that order)
485$T2H_TOP_HEADING = '';
486
487# if set, use this chapter for 'Index' button, else
488# use first chapter whose name matches 'index' (case insensitive)
489$T2H_INDEX_CHAPTER = '';
490
491# if set and $T2H_SPLIT is set, then split index pages at the next letter
492# after they have more than that many entries
493$T2H_SPLIT_INDEX = 100;
494
495# if set (e.g., to index.html) replace hrefs to this file 
496# (i.e., to index.html) by ./
497$T2H_HREF_DIR_INSTEAD_FILE = '';
498
499########################################################################
500# Language dependencies: 
501# To add a new language extend T2H_WORDS hash and create $T2H_<...>_WORDS hash
502# To redefine one word, simply do:
503# $T2H_WORDS->{<language>}->{<word>} = 'whatever' in your personal init file.
504#
505$T2H_WORDS_EN =
506{
507 # titles  of pages
508 'ToC_Title' => 'Table of Contents',
509 'Overview_Title' => 'Short Table of Contents',
510 'Index_Title' => 'Index',
511 'About_Title' => 'About this document',
512 'Footnotes_Title' => 'Footnotes',
513 'See' => 'See',
514 'see' => 'see',
515 'section' => 'section',
516# If necessary, we could extend this as follows: 
517#  # text for buttons
518#  'Top_Button' => 'Top',
519#  'ToC_Button' => 'Contents',
520#  'Overview_Button' => 'Overview',
521#  'Index_button' => 'Index',
522#  'Back_Button' => 'Back',
523#  'FastBack_Button' => 'FastBack',
524#  'Prev_Button' => 'Prev',
525#  'Up_Button' => 'Up',
526#  'Next_Button' => 'Next',
527#  'Forward_Button' =>'Forward',
528#  'FastWorward_Button' => 'FastForward',
529#  'First_Button' => 'First',
530#  'Last_Button' => 'Last',
531#  'About_Button' => 'About'
532};
533
534$T2H_WORD_DE =
535{
536 'ToC_Title' => 'Inhaltsverzeichniss',
537 'Overview_Title' => 'Kurzes Inhaltsverzeichniss',
538 'Index_Title' => 'Index',
539 'About_Title' => '&Uuml;ber dieses Dokument',
540 'Footnotes_Title' => 'Fu&szlig;noten',
541 'See' => 'Siehe',
542 'see' => 'siehe',
543 'section' => 'Abschnitt',
544};
545
546$T2H_WORD_NL =
547{
548 'ToC_Title' => 'Inhoudsopgave',
549 'Overview_Title' => 'Korte inhoudsopgave',
550 'Index_Title' => 'Index', #Not sure ;-)
551 'About_Title' => 'No translation available!', #No translation available!
552 'Footnotes_Title' => 'No translation available!', #No translation available!
553 'See' => 'Zie',
554 'see' => 'zie',
555 'section' => 'sectie',
556};
557
558$T2H_WORD_ES =
559{
560 'ToC_Title' => '&iacute;ndice General',
561 'Overview_Title' => 'Resumen del Contenido',
562 'Index_Title' => 'Index', #Not sure ;-)
563 'About_Title' => 'No translation available!', #No translation available!
564 'Footnotes_Title' => 'Fu&szlig;noten',
565 'See' => 'V&eacute;ase',
566 'see' => 'v&eacute;ase',
567 'section' => 'secci&oacute;n',
568};
569
570$T2H_WORD_NO =
571{
572 'ToC_Title' => 'Innholdsfortegnelse',
573 'Overview_Title' => 'Kort innholdsfortegnelse',
574 'Index_Title' => 'Indeks', #Not sure ;-)
575 'About_Title' => 'No translation available!', #No translation available!
576 'Footnotes_Title' => 'No translation available!',
577 'See' => 'Se',
578 'see' => 'se',
579 'section' => 'avsnitt',
580};
581
582$T2H_WORD_PT =
583{
584 'ToC_Title' => 'Sum&aacute;rio',
585 'Overview_Title' => 'Breve Sum&aacute;rio',
586 'Index_Title' => '&Iacute;ndice', #Not sure ;-)
587 'About_Title' => 'No translation available!', #No translation available!
588 'Footnotes_Title' => 'No translation available!',
589 'See' => 'Veja',
590 'see' => 'veja',
591 'section' => 'Se&ccedil;&atilde;o',
592};
593
594$T2H_WORDS =
595{
596 'en' => $T2H_WORDS_EN,
597 'de' => $T2H_WORDS_DE,
598 'nl' => $T2H_WORDS_NL,
599 'es' => $T2H_WORDS_ES,
600 'no' => $T2H_WORDS_NO,
601 'pt' => $T2H_WORDS_PT
602};
603
604@MONTH_NAMES_EN =
605(
606 'January', 'February', 'March', 'April', 'May',
607 'June', 'July', 'August', 'September', 'October',
608 'November', 'December'
609);
610
611@MONTH_NAMES_DE =
612(
613 'Januar', 'Februar', 'M&auml;rz', 'April', 'Mai',
614 'Juni', 'Juli', 'August', 'September', 'Oktober',
615 'November', 'Dezember'
616);
617
618@MONTH_NAMES_NL =
619(
620 'Januari', 'Februari', 'Maart', 'April', 'Mei',
621 'Juni', 'Juli', 'Augustus', 'September', 'Oktober',
622 'November', 'December'
623);
624
625@MONTH_NAMES_ES =
626(
627 'enero', 'febrero', 'marzo', 'abril', 'mayo',
628 'junio', 'julio', 'agosto', 'septiembre', 'octubre',
629 'noviembre', 'diciembre'
630);
631
632@MONTH_NAMES_NO =
633(
634
635 'januar', 'februar', 'mars', 'april', 'mai',
636 'juni', 'juli', 'august', 'september', 'oktober',
637 'november', 'desember'
638);
639
640@MONTH_NAMES_PT =
641(
642 'Janeiro', 'Fevereiro', 'Mar&ccedil;o', 'Abril', 'Maio',
643 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro',
644 'Novembro', 'Dezembro'
645);
646
647
648$MONTH_NAMES =
649{
650    'en' => \@MONTH_NAMES_EN,
651    'de' => \@MONTH_NAMES_DE,
652    'es' => \@MONTH_NAMES_ES,
653    'nl' => \@MONTH_NAMES_NL,
654    'no' => \@MONTH_NAMES_NO,
655    'pt' => \@MONTH_NAMES_PT
656};
657########################################################################
658# Control of Page layout:
659# You can make changes of the Page layout at two levels:
660# 1.) For small changes, it is often enough to change the value of
661#     some global string/hash/array variables
662# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines,
663#     give them another name, and assign them to the respective
664#     $T2H_<fnc> variable.
665
666# As a general interface, the hashes T2H_HREF, T2H_NAME, T2H_NODE hold 
667# href, html-name, node-name of
668# This     -- current section (resp. html page)
669# Top      -- top page ($T2H_TOP_FILE)
670# Contents -- Table of contents
671# Overview -- Short table of contents
672# Index    -- Index page
673# About    -- page which explain "navigation buttons"
674# First    -- first node 
675# Last     -- last node
676#
677# Whether or not the following hash values are set, depends on the context 
678# (all values are w.r.t. 'This' section)
679# Next        -- next node of texinfo
680# Prev        -- previous node of texinfo
681# Up          -- up node of texinfo
682# Forward     -- next node in reading order
683# Back        -- previous node in reading order
684# FastForward -- if leave node, up and next, else next node
685# FastBackward-- if leave node, up and prev, else prev node
686#
687# Furthermore, the following global variabels are set:
688# $T2H_THISDOC{title}     -- title as set by @setttile
689# $T2H_THISDOC{fulltitle} -- full title as set by @title...
690# $T2H_THISDOC{subtitle}  -- subtitle as set by @subtitle
691# $T2H_THISDOC{author}    -- author as set by @author
692# 
693# and pointer to arrays of lines which need to be printed by t2h_print_lines 
694# $T2H_OVERVIEW      -- lines of short table of contents
695# $T2H_TOC           -- lines of table of contents
696# $T2H_TOP           -- lines of Top texinfo node 
697# $T2H_THIS_SECTION  -- lines of 'This' section
698
699#
700# There are the following subs which control the layout:
701#
702$T2H_print_section            = \&T2H_DEFAULT_print_section;
703$T2H_print_Top_header         = \&T2H_DEFAULT_print_Top_header;       
704$T2H_print_Top_footer	      = \&T2H_DEFAULT_print_Top_footer;       
705$T2H_print_Top		      = \&T2H_DEFAULT_print_Top;              
706$T2H_print_Toc		      = \&T2H_DEFAULT_print_Toc;              
707$T2H_print_Overview	      = \&T2H_DEFAULT_print_Overview;         
708$T2H_print_Footnotes	      = \&T2H_DEFAULT_print_Footnotes;        
709$T2H_print_About	      = \&T2H_DEFAULT_print_About;            
710$T2H_print_misc_header	      = \&T2H_DEFAULT_print_misc_header;      
711$T2H_print_misc_footer	      = \&T2H_DEFAULT_print_misc_footer;      
712$T2H_print_misc		      = \&T2H_DEFAULT_print_misc;
713$T2H_print_chapter_header     = \&T2H_DEFAULT_print_chapter_header;      
714$T2H_print_chapter_footer     = \&T2H_DEFAULT_print_chapter_footer;      
715$T2H_print_page_head	      = \&T2H_DEFAULT_print_page_head;        
716$T2H_print_page_foot	      = \&T2H_DEFAULT_print_page_foot;        
717$T2H_print_head_navigation    = \&T2H_DEFAULT_print_head_navigation;  
718$T2H_print_foot_navigation    = \&T2H_DEFAULT_print_foot_navigation;  
719$T2H_button_icon_img	      = \&T2H_DEFAULT_button_icon_img;        
720$T2H_print_navigation	      = \&T2H_DEFAULT_print_navigation;       
721$T2H_about_body		      = \&T2H_DEFAULT_about_body;            
722$T2H_print_frame              = \&T2H_DEFAULT_print_frame;
723$T2H_print_toc_frame          = \&T2H_DEFAULT_print_toc_frame;
724
725########################################################################
726# Layout for html for every sections
727#
728sub T2H_DEFAULT_print_section
729{
730  my $fh = shift;
731  local $T2H_BUTTONS = \@T2H_SECTION_BUTTONS;
732  &$T2H_print_head_navigation($fh) if $T2H_SECTION_NAVIGATION;
733  my $nw = t2h_print_lines($fh);
734  if ($T2H_SPLIT eq 'section' && $T2H_SECTION_NAVIGATION)
735  {
736    &$T2H_print_foot_navigation($fh, $nw);
737  }
738  else
739  {
740    print $fh '<HR SIZE="6">' . "\n";
741  }
742}
743
744###################################################################
745# Layout of top-page I recommend that you use @ifnothtml, @ifhtml,
746# @html within the Top texinfo node to specify content of top-level
747# page. 
748#
749# If you enclose everything in @ifnothtml, then title, subtitle,
750# author and overview is printed
751# T2H_HREF of Next, Prev, Up, Forward, Back are not defined
752# if $T2H_SPLIT then Top page is in its own html file
753sub T2H_DEFAULT_print_Top_header
754{
755  &$T2H_print_page_head(@_) if $T2H_SPLIT;
756  t2h_print_label(@_); # this needs to be called, otherwise no label set
757  &$T2H_print_head_navigation(@_);
758}
759sub T2H_DEFAULT_print_Top_footer
760{
761  &$T2H_print_foot_navigation(@_);
762  &$T2H_print_page_foot(@_) if $T2H_SPLIT; 
763}
764sub T2H_DEFAULT_print_Top
765{
766  my $fh = shift;
767
768  # for redefining navigation buttons use:
769  # local $T2H_BUTTONS = [...];
770  # as it is, 'Top', 'Contents', 'Index', 'About' are printed
771  local $T2H_BUTTONS = \@T2H_MISC_BUTTONS;
772  &$T2H_print_Top_header($fh);
773  if ($T2H_THIS_SECTION)
774  {
775    # if top-level node has content, then print it with extra header
776    print $fh "<H1>$T2H_NAME{Top}</H1>"
777      unless ($T2H_HAS_TOP_HEADING);
778    t2h_print_lines($fh, $T2H_THIS_SECTION)
779  }
780  else
781  {
782    # top-level node is fully enclosed in @ifnothtml
783    # print fulltitle, subtitle, author, Overview
784    print $fh 
785      "<CENTER>\n<H1>" .
786      join("</H1>\n<H1>", split(/\n/,  $T2H_THISDOC{fulltitle})) .
787      "</H1>\n";
788    print $fh "<H2>$T2H_THISDOC{subtitle}</H2>\n" if $T2H_THISDOC{subtitle};
789    print $fh "$T2H_THISDOC{author}\n" if $T2H_THISDOC{author};
790    print $fh <<EOT;
791</CENTER>
792<HR>
793<P></P>  
794<H2> Overview: </H2>
795<BLOCKQUOTE>  
796EOT
797    t2h_print_lines($fh, $T2H_OVERVIEW);
798    print $fh "</BLOCKQUOTE>\n";
799  }
800  &$T2H_print_Top_footer($fh);
801}
802
803###################################################################
804# Layout of Toc, Overview, and Footnotes pages
805# By default, we use "normal" layout 
806# T2H_HREF of Next, Prev, Up, Forward, Back, etc are not defined
807# use: local $T2H_BUTTONS = [...] to redefine navigation buttons
808sub T2H_DEFAULT_print_Toc
809{
810  return &$T2H_print_misc(@_);
811}
812sub T2H_DEFAULT_print_Overview
813{
814  return &$T2H_print_misc(@_);
815}
816sub T2H_DEFAULT_print_Footnotes
817{
818  return &$T2H_print_misc(@_);
819}
820sub T2H_DEFAULT_print_About
821{
822  return &$T2H_print_misc(@_);
823}
824
825sub T2H_DEFAULT_print_misc_header
826{
827  &$T2H_print_page_head(@_) if $T2H_SPLIT;
828  # this needs to be called, otherwise, no labels are set
829  t2h_print_label(@_); 
830  &$T2H_print_head_navigation(@_);
831}
832sub T2H_DEFAULT_print_misc_footer
833{
834  &$T2H_print_foot_navigation(@_);
835  &$T2H_print_page_foot(@_) if $T2H_SPLIT; 
836}
837sub T2H_DEFAULT_print_misc
838{
839  my $fh = shift;
840  local $T2H_BUTTONS = \@T2H_MISC_BUTTONS;
841  &$T2H_print_misc_header($fh);
842  print $fh "<H1>$T2H_NAME{This}</H1>\n";
843  t2h_print_lines($fh);
844  &$T2H_print_misc_footer($fh);
845}
846
847###################################################################
848# chapter_header and chapter_footer are only called if
849# T2H_SPLIT eq 'chapter'
850# chapter_header: after print_page_header, before print_section
851# chapter_footer: after print_section of last section, before print_page_footer
852# 
853# If you want to get rid of navigation stuff after each section,
854# redefine print_section such that it does not call print_navigation,
855# and put print_navigation into print_chapter_header
856@T2H_CHAPTER_BUTTONS =
857  (
858   'FastBack', 'FastForward', ' ', 
859   ' ', ' ', ' ', ' ',
860   'Top', 'Contents', 'Index', 'About', 
861  );
862
863sub T2H_DEFAULT_print_chapter_header
864{
865  # nothing to do there, by default
866  if (! $T2H_SECTION_NAVIGATION)
867  {
868    my $fh = shift;
869    local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS;
870    &$T2H_print_navigation($fh);
871    print $fh "\n<HR SIZE=2>\n";
872  }
873}
874
875sub T2H_DEFAULT_print_chapter_footer
876{
877  local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS;
878  &$T2H_print_navigation(@_);
879}
880###################################################################
881$T2H_TODAY = &pretty_date;		# like "20 September 1993"
882
883sub pretty_date {
884    local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
885
886    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
887    $year += ($year < 70) ? 2000 : 1900;
888    # obachman: Let's do it as the Americans do
889    return($MONTH_NAMES->{$T2H_LANG}[$mon] . ", " . $mday . " " . $year);
890}
891
892
893###################################################################
894# Layout of standard header and footer
895#
896
897# Set the default body text, inserted between <BODY ... > 
898###$T2H_BODYTEXT = 'LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"';
899$T2H_BODYTEXT = 'LANG="' . $T2H_LANG . '" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"';
900# text inserted after <BODY ...>
901$T2H_AFTER_BODY_OPEN = '';
902#text inserted before </BODY>
903$T2H_PRE_BODY_CLOSE = '';
904# this is used in footer
905$T2H_ADDRESS = "by <I>$T2H_USER</I> " if $T2H_USER;
906$T2H_ADDRESS .= "on <I>$T2H_TODAY</I>";
907# this is added inside <HEAD></HEAD> after <TITLE> and some META NAME stuff
908# can be used for <style> <script>, <meta> tags
909$T2H_EXTRA_HEAD = '';
910
911sub T2H_DEFAULT_print_page_head
912{
913  my $fh = shift; 
914  my $longtitle = "$T2H_THISDOC{title}: $T2H_NAME{This}";
915  print $fh <<EOT;
916<HTML>
917$T2H_DOCTYPE
918<!-- Created on $T2H_TODAY by $THISPROG -->
919<!-- 
920$T2H_AUTHORS 
921-->
922<HEAD>
923<TITLE>$longtitle</TITLE>
924
925<META NAME="description" CONTENT="$longtitle">
926<META NAME="keywords" CONTENT="$longtitle">
927<META NAME="resource-type" CONTENT="document">
928<META NAME="distribution" CONTENT="global">
929<META NAME="Generator" CONTENT="$THISPROG">
930$T2H_EXTRA_HEAD
931</HEAD>
932
933<BODY $T2H_BODYTEXT>
934$T2H_AFTER_BODY_OPEN
935EOT
936}
937
938sub T2H_DEFAULT_print_page_foot
939{
940  my $fh = shift;
941  print $fh <<EOT;
942<BR>  
943<FONT SIZE="-1">
944This document was generated
945$T2H_ADDRESS
946using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A>
947$T2H_PRE_BODY_CLOSE
948</BODY>
949</HTML>
950EOT
951}
952
953###################################################################
954# Layout of navigation panel
955
956# if this is set, then a vertical navigation panel is used
957$T2H_VERTICAL_HEAD_NAVIGATION = 0;
958sub T2H_DEFAULT_print_head_navigation
959{
960  my $fh = shift;
961  if ($T2H_VERTICAL_HEAD_NAVIGATION)
962  {
963    print $fh <<EOT;
964<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
965<TR VALIGN="TOP">
966<TD ALIGN="LEFT">
967EOT
968  }
969  &$T2H_print_navigation($fh, $T2H_VERTICAL_HEAD_NAVIGATION);
970  if ($T2H_VERTICAL_HEAD_NAVIGATION)
971  {
972    print $fh <<EOT;
973</TD>
974<TD ALIGN="LEFT">
975EOT
976  }
977  elsif ($T2H_SPLIT eq 'section')
978  {
979    print $fh "<HR SIZE=1>\n";
980  }
981}
982
983# Specifies the minimum page length required before a navigation panel
984# is placed at the bottom of a page (the default is that of latex2html)
985# T2H_THIS_WORDS_IN_PAGE holds number of words of current page
986$T2H_WORDS_IN_PAGE = 300;
987sub T2H_DEFAULT_print_foot_navigation
988{
989  my $fh = shift;
990  my $nwords = shift;
991  if ($T2H_VERTICAL_HEAD_NAVIGATION)
992  {
993    print $fh <<EOT;
994</TD>
995</TR>
996</TABLE>
997EOT
998  }
999  print $fh "<HR SIZE=1>\n";
1000  &$T2H_print_navigation($fh) if ($nwords >= $T2H_WORDS_IN_PAGE)
1001}
1002
1003######################################################################
1004# navigation panel
1005#
1006# specify in this array which "buttons" should appear in which order
1007# in the navigation panel for sections; use ' ' for empty buttons (space)
1008@T2H_SECTION_BUTTONS =
1009  (
1010   'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward',  
1011   ' ', ' ', ' ', ' ',
1012   'Top', 'Contents', 'Index', 'About', 
1013  );
1014
1015# buttons for misc stuff
1016@T2H_MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About');
1017
1018# insert here name of icon images for buttons 
1019# Icons are used, if $T2H_ICONS and resp. value are set
1020%T2H_ACTIVE_ICONS =
1021  (
1022   'Top',      '',
1023   'Contents', '',
1024   'Overview', '',
1025   'Index',    '',
1026   'Back',     '',
1027   'FastBack', '',
1028   'Prev',     '',
1029   'Up',       '',
1030   'Next',     '',
1031   'Forward',  '',
1032   'FastForward', '',
1033   'About' ,    '',
1034   'First',    '',
1035   'Last',     '',
1036   ' ',        ''
1037  );
1038
1039# insert here name of icon images for these, if button is inactive
1040%T2H_PASSIVE_ICONS =
1041  (
1042   'Top',      '',
1043   'Contents', '',
1044   'Overview', '',
1045   'Index',    '',
1046   'Back',     '',
1047   'FastBack', '',
1048   'Prev',     '',
1049   'Up',       '',
1050   'Next',     '',
1051   'Forward',  '',
1052   'FastForward', '',
1053   'About',     '',
1054   'First',    '',
1055   'Last',     '',
1056  );
1057
1058# how to create IMG tag
1059sub T2H_DEFAULT_button_icon_img
1060{
1061  my $button = shift;
1062  my $icon = shift;
1063  my $name = shift;
1064  return qq{<IMG SRC="$icon" BORDER="0" ALT="$button: $name" ALIGN="MIDDLE">};
1065}
1066
1067# Names of text as alternative for icons
1068%T2H_NAVIGATION_TEXT =
1069  (
1070   'Top',      'Top',
1071   'Contents', 'Contents',
1072   'Overview', 'Overview',
1073   'Index',    'Index',
1074   ' ',        ' &nbsp; ',
1075   'Back',     ' &lt; ',
1076   'FastBack', ' &lt;&lt; ',
1077   'Prev',     'Prev',
1078   'Up',       ' Up ',
1079   'Next',     'Next',
1080   'Forward',  ' &gt; ',
1081   'FastForward',  ' &gt;&gt; ',
1082   'About',     ' ? ',
1083   'First',    ' |&lt; ',
1084   'Last',     ' &gt;| '
1085  );
1086
1087sub T2H_DEFAULT_print_navigation
1088{
1089  my $fh = shift;
1090  my $vertical = shift;
1091  my $spacing = 1;
1092  print $fh "<TABLE CELLPADDING=$spacing CELLSPACING=$spacing BORDER=0>\n";
1093
1094  print $fh "<TR>" unless $vertical;
1095  for $button (@$T2H_BUTTONS)
1096  {
1097    print $fh qq{<TR VALIGN="TOP" ALIGN="LEFT">\n} if $vertical;
1098    print $fh qq{<TD VALIGN="MIDDLE" ALIGN="LEFT">};
1099
1100    if (ref($button) eq 'CODE')
1101    {
1102      &$button($fh, $vertical);
1103    }
1104    elsif ($button eq ' ')
1105    { # handle space button
1106      print $fh 
1107	$T2H_ICONS && $T2H_ACTIVE_ICONS{' '} ? 
1108	 &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{' '}) :
1109	 $T2H_NAVIGATION_TEXT{' '};
1110      next;
1111    }
1112    elsif ($T2H_HREF{$button})
1113    { # button is active
1114      print $fh   
1115	 $T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? # use icon ? 
1116	   t2h_anchor('', $T2H_HREF{$button},  # yes
1117		    &$T2H_button_icon_img($button,
1118					$T2H_ACTIVE_ICONS{$button},
1119					$T2H_NAME{$button})) 
1120	 : # use text
1121	 "[" . 
1122	 t2h_anchor('', $T2H_HREF{$button}, $T2H_NAVIGATION_TEXT{$button}) .
1123	 "]";  
1124    }
1125    else
1126    { # button is passive 
1127      print $fh 
1128	$T2H_ICONS && $T2H_PASSIVE_ICONS{$button} ?
1129	 &$T2H_button_icon_img($button,
1130			       $T2H_PASSIVE_ICONS{$button},
1131			       $T2H_NAME{$button}) :
1132	 
1133	 "[" . $T2H_NAVIGATION_TEXT{$button} . "]";
1134    }
1135    print $fh "</TD>\n";
1136    print $fh "</TR>\n" if $vertical;
1137  }
1138  print $fh "</TR>" unless $vertical;
1139  print $fh "</TABLE>\n";
1140}
1141
1142######################################################################
1143# Frames: this is from "Richard Y. Kim" <ryk@coho.net>
1144# Should be improved to be more conforming to other _print* functions
1145
1146sub T2H_DEFAULT_print_frame
1147{
1148  my $fh = shift;
1149  print $fh <<EOT;
1150<HTML>
1151<HEAD><TITLE>$T2H_THISDOC{title}</TITLE></HEAD>
1152<FRAMESET cols="140,*"> 
1153  <FRAME name=toc  src="$docu_toc_frame_file">
1154  <FRAME name=main src="$docu_doc">
1155</FRAMESET> 
1156</HTML>
1157EOT
1158}
1159
1160sub T2H_DEFAULT_print_toc_frame
1161{
1162  my $fh = shift;
1163  &$T2H_print_page_head($fh);
1164  print $fh <<EOT;
1165<H2>Content</H2>
1166EOT
1167  print $fh map {s/HREF=/target=\"main\" HREF=/; $_;} @stoc_lines;
1168  print $fh "</BODY></HTML>\n";
1169}
1170
1171######################################################################
1172# About page
1173#
1174
1175# T2H_PRE_ABOUT might be a function
1176$T2H_PRE_ABOUT = <<EOT;
1177This document was generated $T2H_ADDRESS
1178using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A>
1179<P></P>  
1180EOT
1181$T2H_AFTER_ABOUT = '';
1182
1183sub T2H_DEFAULT_about_body
1184{
1185  my $about;
1186  if (ref($T2H_PRE_ABOUT) eq 'CODE')
1187  {
1188    $about = &$T2H_PRE_ABOUT();
1189  }
1190  else
1191  {
1192    $about = $T2H_PRE_ABOUT;
1193  }
1194  $about .= <<EOT;
1195The buttons in the navigation panels have the following meaning:
1196<P></P>
1197<table border = "1">
1198<TR>
1199<TH> Button </TH>
1200<TH> Name </TH>
1201<TH> Go to </TH>
1202<TH> From 1.2.3 go to</TH>
1203</TR>
1204EOT
1205  
1206  for $button (@T2H_SECTION_BUTTONS)
1207  {
1208    next if $button eq ' ' || ref($button) eq 'CODE';
1209    $about .= <<EOT;
1210<TR>
1211<TD ALIGN="CENTER">
1212EOT
1213    $about .= 	
1214      ($T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ?
1215       &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{$button}) :
1216       " [" . $T2H_NAVIGATION_TEXT{$button} . "] ");
1217    $about .= <<EOT;
1218</TD>
1219<TD ALIGN="CENTER">
1220$button
1221</TD>
1222<TD>
1223$T2H_BUTTONS_GOTO{$button}
1224</TD>
1225<TD>
1226$T2H_BUTTONS_EXAMPLE{$button}
1227</TD>
1228</TR>
1229EOT
1230  }
1231
1232  $about .= <<EOT;
1233</TABLE>
1234<P></P>
1235where the <STRONG> Example </STRONG> assumes that the current position 
1236is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 
1237the following structure:
1238<UL>
1239<LI> 1. Section One  </LI>
1240<UL>
1241<LI>1.1 Subsection One-One</LI>
1242<UL>
1243<LI> ... </LI>
1244</UL>
1245<LI>1.2 Subsection One-Two</LI>
1246<UL>
1247<LI>1.2.1 Subsubsection One-Two-One
1248</LI><LI>1.2.2 Subsubsection One-Two-Two
1249</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
1250&lt;== Current Position </STRONG>
1251</LI><LI>1.2.4 Subsubsection One-Two-Four
1252</LI></UL>
1253<LI>1.3 Subsection One-Three</LI>
1254<UL>
1255<LI> ... </LI>
1256</UL>
1257<LI>1.4 Subsection One-Four</LI>
1258</UL>
1259</UL>
1260$T2H_AFTER_ABOUT
1261EOT
1262  return $about;  
1263}
1264
1265  
1266%T2H_BUTTONS_GOTO =
1267  (
1268   'Top',      'cover (top) of document',
1269   'Contents', 'table of contents',
1270   'Overview', 'short table of contents',
1271   'Index',    'concept index',
1272   'Back',     'previous section in reading order',
1273   'FastBack', 'previous or up-and-previous section ',
1274   'Prev',     'previous section same level',
1275   'Up',       'up section',
1276   'Next',     'next section same level',
1277   'Forward',  'next section in reading order',
1278   'FastForward', 'next or up-and-next section',
1279   'About' ,    'this page',
1280   'First',    'first section in reading order',
1281   'Last',     'last section in reading order',
1282  );
1283
1284%T2H_BUTTONS_EXAMPLE = 
1285(
1286   'Top',      ' &nbsp; ',
1287   'Contents', ' &nbsp; ',
1288   'Overview', ' &nbsp; ',
1289   'Index',    ' &nbsp; ',
1290   'Back',     '1.2.2',
1291   'FastBack', '1.1',
1292   'Prev',     '1.2.2',
1293   'Up',       '1.2',
1294   'Next',     '1.2.4',
1295   'Forward',  '1.2.4',
1296   'FastForward', '1.3',
1297   'About',     ' &nbsp; ',
1298   'First',    '1.',
1299   'Last',     '1.2.4',
1300);
1301
1302
1303######################################################################
1304# from here on, its l2h init stuff 
1305#
1306
1307## initialization for latex2html as for Singular manual generation
1308## obachman 3/99
1309
1310#
1311# Options controlling Titles, File-Names, Tracing and Sectioning
1312#
1313$TITLE = '';
1314
1315$SHORTEXTN = 0;
1316
1317$LONG_TITLES = 0;
1318
1319$DESTDIR = ''; # should be overwritten by cmd-line argument
1320
1321$NO_SUBDIR = 0;# should be overwritten by cmd-line argument
1322
1323$PREFIX = '';  # should be overwritten by cmd-line argument
1324
1325$AUTO_PREFIX = 0; # this is needed, so that prefix settings are used
1326
1327$AUTO_LINK = 0; 
1328
1329$SPLIT = 0;
1330
1331$MAX_LINK_DEPTH = 0;
1332
1333$TMP = ''; # should be overwritten by cmd-line argument
1334
1335$DEBUG = 0;
1336
1337$VERBOSE = 1;
1338
1339#
1340# Options controlling Extensions and Special Features 
1341#
1342$HTML_VERSION = "3.2";
1343
1344$TEXDEFS = 1; # we absolutely need that
1345
1346$EXTERNAL_FILE = '';
1347
1348$SCALABLE_FONTS = 1;
1349
1350$NO_SIMPLE_MATH = 1;
1351
1352$LOCAL_ICONS = 1;
1353
1354$SHORT_INDEX = 0;
1355
1356$NO_FOOTNODE = 1;
1357
1358$ADDRESS = '';
1359
1360$INFO = '';
1361
1362#
1363# Switches controlling Image Generation 
1364#
1365$ASCII_MODE = 0;
1366
1367$NOLATEX = 0;
1368
1369$EXTERNAL_IMAGES = 0;
1370
1371$PS_IMAGES = 0;
1372
1373$NO_IMAGES = 0;
1374
1375$IMAGES_ONLY = 0;
1376
1377$REUSE = 2;
1378
1379$ANTI_ALIAS = 1;
1380
1381$ANTI_ALIAS_TEXT = 1;
1382
1383#
1384#Switches controlling Navigation Panels
1385#
1386$NO_NAVIGATION = 1;
1387$ADDRESS = '';
1388$INFO = 0;              # 0 = do not make a "About this document..." section 
1389
1390#
1391#Switches for Linking to other documents 
1392#
1393# actuall -- we don't care
1394
1395$MAX_SPLIT_DEPTH = 0;	# Stop making separate files at this depth
1396
1397$MAX_LINK_DEPTH = 0;    # Stop showing child nodes at this depth   
1398
1399$NOLATEX = 0;           # 1 = do not pass unknown environments to Latex
1400
1401$EXTERNAL_IMAGES = 0;   # 1 = leave the images outside the document 
1402
1403$ASCII_MODE = 0;        # 1 = do not use any icons or internal images
1404
1405# 1 =  use links to external postscript images rather than inlined bitmap
1406# images.
1407$PS_IMAGES = 0;
1408$SHOW_SECTION_NUMBERS = 0;
1409
1410### Other global variables ###############################################
1411$CHILDLINE = "";
1412
1413# This is the line width measured in pixels and it is used to right justify
1414# equations and equation arrays; 
1415$LINE_WIDTH = 500;		
1416
1417# Used in conjunction with AUTO_NAVIGATION
1418$WORDS_IN_PAGE = 300;	
1419
1420# Affects ONLY the way accents are processed 
1421$default_language = 'english';	
1422
1423# The value of this variable determines how many words to use in each 
1424# title that is added to the navigation panel (see below)
1425# 
1426$WORDS_IN_NAVIGATION_PANEL_TITLES = 0;
1427
1428# This number will determine the size of the equations, special characters,
1429# and anything which will be converted into an inlined image
1430# *except* "image generating environments" such as "figure", "table" 
1431# or "minipage".
1432# Effective values are those greater than 0.
1433# Sensible values are between 0.1 - 4.
1434$MATH_SCALE_FACTOR = 1.5;
1435
1436# This number will determine the size of 
1437# image generating environments such as "figure", "table" or "minipage".
1438# Effective values are those greater than 0.
1439# Sensible values are between 0.1 - 4.
1440$FIGURE_SCALE_FACTOR = 1.6;
1441
1442
1443#  If both of the following two variables are set then the "Up" button
1444#  of the navigation panel in the first node/page of a converted document
1445#  will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set
1446#  to some text which describes this external link.
1447$EXTERNAL_UP_LINK = "";
1448$EXTERNAL_UP_TITLE = "";
1449
1450# If this is set then the resulting HTML will look marginally better if viewed 
1451# with Netscape.
1452$NETSCAPE_HTML = 1;
1453
1454# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0"
1455# Paper sizes has no effect other than in the time it takes to create inlined
1456# images and in whether large images can be created at all ie
1457#  - larger paper sizes *MAY* help with large image problems 
1458#  - smaller paper sizes are quicker to handle
1459$PAPERSIZE = "a4";
1460
1461# Replace "english" with another language in order to tell LaTeX2HTML that you 
1462# want some generated section titles (eg "Table of Contents" or "References")
1463# to appear in a different language. Currently only "english" and "french"
1464# is supported but it is very easy to add your own. See the example in the
1465# file "latex2html.config" 
1466$TITLES_LANGUAGE = "english";
1467
14681;	# This must be the last non-comment line
1469
1470# End File texi2html.init
1471######################################################################
1472
1473
1474require "$ENV{T2H_HOME}/texi2html.init" 
1475  if ($0 =~ /\.pl$/ &&
1476      -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init");
1477
1478#+++############################################################################
1479#                                                                              #
1480# Initialization                                                               #
1481# Pasted content of File $(srcdir)/MySimple.pm: Command-line processing        #
1482#                                                                              #
1483#---############################################################################
1484
1485# leave this within comments, and keep the require statement
1486# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init
1487# exists.
1488
1489# 
1490package Getopt::MySimple;
1491
1492# Name:
1493#	Getopt::MySimple.
1494#
1495# Documentation:
1496#	POD-style (incomplete) documentation is in file MySimple.pod
1497#
1498# Tabs:
1499#	4 spaces || die.
1500#
1501# Author:
1502#	Ron Savage	rpsavage@ozemail.com.au.
1503#	1.00	19-Aug-97	Initial version.
1504#	1.10	13-Oct-97	Add arrays of switches (eg '=s@').
1505#	1.20	 3-Dec-97	Add 'Help' on a per-switch basis.
1506#	1.30	11-Dec-97	Change 'Help' to 'verbose'. Make all hash keys lowercase.
1507#	1.40	10-Nov-98	Change width of help report. Restructure tests.
1508#               1-Jul-00        Modifications for Texi2html
1509
1510# --------------------------------------------------------------------------
1511# Locally modified by obachman (Display type instead of env, order by cmp)
1512# $Id: texi2html 7792 2004-06-07 09:07:27Z korli $
1513
1514# use strict;
1515# no strict 'refs';
1516
1517use vars qw(@EXPORT @EXPORT_OK @ISA);
1518use vars qw($fieldWidth $opt $VERSION);
1519
1520use Exporter();
1521use Getopt::Long;
1522
1523@ISA		= qw(Exporter);
1524@EXPORT		= qw();
1525@EXPORT_OK	= qw($opt);	# An alias for $self -> {'opt'}.
1526
1527# --------------------------------------------------------------------------
1528
1529$fieldWidth	= 20;
1530$VERSION	= '1.41';
1531
1532# --------------------------------------------------------------------------
1533
1534sub byOrder
1535{
1536	my($self) = @_;
1537	
1538	return uc($a) cmp (uc($b));
1539}
1540
1541# --------------------------------------------------------------------------
1542
1543sub dumpOptions
1544{
1545	my($self) = @_;
1546
1547	print 'Option', ' ' x ($fieldWidth - length('Option') ), "Value\n";
1548
1549	for (sort byOrder keys(%{$self -> {'opt'} }) )
1550	{
1551	  print "-$_", ' ' x ($fieldWidth - (1 + length) ), "${$self->{'opt'} }{$_}\n";
1552	}
1553
1554	print "\n";
1555
1556}	# End of dumpOptions.
1557
1558# --------------------------------------------------------------------------
1559# Return:
1560#	0 -> Error.
1561#	1 -> Ok.
1562
1563sub getOptions
1564{
1565	push(@_, 0) if ($#_ == 2);	# Default for $ignoreCase is 0.
1566	push(@_, 1) if ($#_ == 3);	# Default for $helpThenExit is 1.
1567
1568	my($self, $default, $helpText, $versionText, 
1569	   $helpThenExit, $versionThenExit, $ignoreCase) = @_;
1570	
1571	$helpThenExit = 1 unless (defined($helpThenExit));
1572	$versionThenExit = 1 unless (defined($versionThenExit));
1573	$ignoreCase = 0 unless (defined($ignoreCase));
1574
1575	$self -> {'default'}		= $default;
1576	$self -> {'helpText'}		= $helpText;
1577	$self -> {'versionText'}        = $versionText;
1578	$Getopt::Long::ignorecase	= $ignoreCase;
1579
1580	unless (defined($self -> {'default'}{'help'}))
1581	{
1582	  $self -> {'default'}{'help'} = 
1583	  { 
1584	   type => ':i', 
1585	   default => '',
1586	   linkage => sub {$self->helpOptions($_[1]); exit (0) if $helpThenExit;},
1587	   verbose => "print help and exit"
1588	  };
1589	}
1590
1591	unless (defined($self -> {'default'}{'version'}))
1592	{
1593	  $self -> {'default'}{'version'} = 
1594	  { 
1595	   type => '', 
1596	   default => '',
1597	   linkage => sub {print $self->{'versionText'};  exit (0) if versionTheExit;},
1598	   verbose => "print version and exit"
1599	  };
1600	}
1601
1602	for (keys(%{$self -> {'default'} }) )
1603	{
1604	  my $type = ${$self -> {'default'} }{$_}{'type'};
1605	  push(@{$self -> {'type'} }, "$_$type");
1606	  $self->{'opt'}->{$_} =  ${$self -> {'default'} }{$_}{'linkage'}
1607            if ${$self -> {'default'} }{$_}{'linkage'};
1608	}
1609
1610	my($result) = &GetOptions($self -> {'opt'}, @{$self -> {'type'} });
1611
1612        return $result unless $result;
1613
1614	for (keys(%{$self -> {'default'} }) )
1615	{
1616 	   if (! defined(${$self -> {'opt'} }{$_})) #{
1617            {
1618 	     ${$self -> {'opt'} }{$_} = ${$self -> {'default'} }{$_}{'default'};
1619            }
1620	}
1621
1622	$result;
1623}	# End of getOptions.
1624
1625# --------------------------------------------------------------------------
1626
1627sub helpOptions
1628{
1629	my($self) = shift;
1630	my($noHelp) = shift;
1631	$noHelp = 0 unless $noHelp;
1632	my($optwidth, $typewidth, $defaultwidth, $maxlinewidth, $valind, $valwidth) 
1633	  = (10, 5, 9, 78, 4, 11);
1634
1635	print "$self->{'helpText'}" if ($self -> {'helpText'});
1636
1637	print ' Option', ' ' x ($optwidth - length('Option') -1 ),
1638		'Type', ' ' x ($typewidth - length('Type') + 1),
1639		'Default', ' ' x ($defaultwidth - length('Default') ),
1640	        "Description\n";
1641
1642	for (sort byOrder keys(%{$self -> {'default'} }) )
1643	{
1644	  my($line, $help, $option, $val);
1645	  $option = $_;
1646	  next if ${$self->{'default'} }{$_}{'noHelp'} && ${$self->{'default'} }{$_}{'noHelp'} > $noHelp;
1647		$line = " -$_ " . ' ' x ($optwidth - (2 + length) ) .
1648			"${$self->{'default'} }{$_}{'type'} ".
1649			' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) ));
1650
1651                 $val = ${$self->{'default'} }{$_}{'linkage'};
1652                if ($val)
1653                {
1654                  if (ref($val) eq 'SCALAR')
1655		  {
1656		    $val = $$val; 
1657		  }
1658		  else
1659		  {
1660		    $val = '';
1661		  }
1662                }
1663		else
1664		{
1665		  $val = ${$self->{'default'} }{$_}{'default'};
1666		}
1667	        $line .= "$val  ";
1668		$line .= ' ' x ($optwidth + $typewidth + $defaultwidth + 1 - length($line));
1669		
1670		if (defined(${$self -> {'default'} }{$_}{'verbose'}) &&
1671		  ${$self -> {'default'} }{$_}{'verbose'} ne '')
1672	      {
1673		$help = "${$self->{'default'} }{$_}{'verbose'}";
1674	      }
1675	      else
1676	      {
1677		$help = ' ';
1678	      }
1679	      if ((length("$line") + length($help)) < $maxlinewidth)
1680	      {
1681		print $line , $help, "\n";
1682	      }
1683	      else
1684	      {
1685		print $line, "\n", ' ' x $valind, $help, "\n";
1686	      }
1687	      for $val (sort byOrder keys(%{${$self->{'default'}}{$option}{'values'}}))
1688	      {
1689	        print ' ' x ($valind + 2);
1690	        print $val, '  ', ' ' x ($valwidth - length($val) - 2);
1691	        print ${$self->{'default'}}{$option}{'values'}{$val}, "\n";
1692	      }
1693	}
1694
1695	print <<EOT;
1696Note: 'Options' may be abbreviated. 'Type' specifications mean:
1697 <none>| !    no argument: variable is set to 1 on -foo (or, to 0 on -nofoo)
1698    =s | :s   mandatory (or, optional)  string argument
1699    =i | :i   mandatory (or, optional)  integer argument
1700EOT
1701}	# End of helpOptions.
1702
1703#-------------------------------------------------------------------
1704
1705sub new
1706{
1707	my($class)				= @_;
1708	my($self)				= {};
1709	$self -> {'default'}	= {};
1710	$self -> {'helpText'}	= '';
1711	$self -> {'opt'}		= {};
1712	$opt					= $self -> {'opt'};	 # An alias for $self -> {'opt'}.
1713	$self -> {'type'}		= ();
1714
1715	return bless $self, $class;
1716
1717}	# End of new.
1718
1719# --------------------------------------------------------------------------
1720
17211;
1722
1723# End MySimple.pm
1724
1725require "$ENV{T2H_HOME}/MySimple.pm" 
1726  if ($0 =~ /\.pl$/ &&
1727      -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init");
1728
1729package main;
1730
1731#+++############################################################################
1732#                                                                              #
1733# Constants                                                                    #
1734#                                                                              #
1735#---############################################################################
1736
1737$DEBUG_TOC   =  1;
1738$DEBUG_INDEX =  2;
1739$DEBUG_BIB   =  4;
1740$DEBUG_GLOSS =  8;
1741$DEBUG_DEF   = 16;
1742$DEBUG_HTML  = 32;
1743$DEBUG_USER  = 64;
1744$DEBUG_L2H   = 128;
1745
1746
1747$BIBRE = '\[[\w\/-]+\]';		# RE for a bibliography reference
1748$FILERE = '[\/\w.+-]+';			# RE for a file name
1749$VARRE = '[^\s\{\}]+';			# RE for a variable name
1750$NODERE = '[^,:]+';		        # RE for a node name
1751$NODESRE = '[^:]+';		        # RE for a list of node names
1752
1753$ERROR = "***";			        # prefix for errors 
1754$WARN  = "**";                          # prefix for warnings
1755  
1756                                        # program home page
1757$PROTECTTAG = "_ThisIsProtected_";	# tag to recognize protected sections
1758
1759$CHAPTEREND = "<!-- End chapter -->\n"; # to know where a chpater ends
1760$SECTIONEND = "<!-- End section -->\n"; # to know where section ends
1761$TOPEND     = "<!-- End top     -->\n"; # to know where top ends
1762
1763  
1764
1765#
1766# pre-defined indices
1767#
1768$index_properties =
1769{
1770 'c' => { name => 'cp'},
1771 'f' => { name => 'fn', code => 1},
1772 'v' => { name => 'vr', code => 1},
1773 'k' => { name => 'ky', code => 1},
1774 'p' => { name => 'pg', code => 1},
1775 't' => { name => 'tp', code => 1}
1776};
1777
1778
1779%predefined_index = (
1780		    'cp', 'c',
1781		    'fn', 'f',
1782		    'vr', 'v',
1783		    'ky', 'k',
1784		    'pg', 'p',
1785		    'tp', 't',
1786	            );
1787
1788#
1789# valid indices
1790#
1791%valid_index = (
1792		    'c', 1,
1793		    'f', 1,
1794		    'v', 1,
1795		    'k', 1,
1796		    'p', 1,
1797		    't', 1,
1798		);
1799
1800#
1801# texinfo section names to level
1802#
1803%sec2level = (
1804	      'top', 0,
1805	      'chapter', 1,
1806	      'unnumbered', 1,
1807	      'majorheading', 1,
1808	      'chapheading', 1,
1809	      'appendix', 1,
1810	      'section', 2,
1811	      'unnumberedsec', 2,
1812	      'heading', 2,
1813	      'appendixsec', 2,
1814	      'appendixsection', 2,
1815	      'subsection', 3,
1816	      'unnumberedsubsec', 3,
1817	      'subheading', 3,
1818	      'appendixsubsec', 3,
1819	      'subsubsection', 4,
1820	      'unnumberedsubsubsec', 4,
1821	      'subsubheading', 4,
1822	      'appendixsubsubsec', 4,
1823	      );
1824
1825#
1826# accent map, TeX command to ISO name
1827#
1828%accent_map = (
1829	       '"',  'uml',
1830	       '~',  'tilde',
1831	       '^',  'circ',
1832	       '`',  'grave',
1833	       '\'', 'acute',
1834	       );
1835
1836#
1837# texinfo "simple things" (@foo) to HTML ones
1838#
1839%simple_map = (
1840	       # cf. makeinfo.c
1841	       "*", "<BR>",		# HTML+
1842	       " ", " ",
1843	       "\t", " ",
1844  	       "-", "&#173;",	# soft hyphen
1845	       "\n", "\n",
1846	       "|", "",
1847	       'tab', '<\/TD><TD>',
1848	       # spacing commands
1849	       ":", "",
1850	       "!", "!",
1851	       "?", "?",
1852	       ".", ".",
1853	       "-", "",
1854	       );
1855
1856#
1857# texinfo "things" (@foo{}) to HTML ones
1858#
1859%things_map = (
1860	       'TeX', 'TeX',
1861	       'br', '<P>',		# paragraph break
1862	       'bullet', '*',
1863	       'copyright', '(C)',
1864	       'dots', '<small>...<\/small>',
1865	       'enddots', '<small>....<\/small>',
1866	       'equiv', '==',
1867	       'error', 'error-->',
1868	       'expansion', '==>',
1869	       'minus', '-',
1870	       'point', '-!-',
1871	       'print', '-|',
1872	       'result', '=>',
1873	       'today', $T2H_TODAY,
1874	       'aa', '&aring;',
1875	       'AA', '&Aring;',
1876	       'ae', '&aelig;',
1877	       'oe', '&#156;',
1878	       'AE', '&AElig;',
1879	       'OE', '&#140;',
1880	       'o',  '&oslash;',
1881	       'O',  '&Oslash;',
1882	       'ss', '&szlig;',
1883	       'l', '\/l',
1884	       'L', '\/L',
1885	       'exclamdown', '&iexcl;',
1886	       'questiondown', '&iquest;',
1887	       'pounds', '&pound;'
1888	       );
1889
1890#
1891# texinfo styles (@foo{bar}) to HTML ones
1892#
1893%style_map = (
1894	      'acronym', '&do_acronym',
1895	      'asis', '',
1896	      'b', 'B',
1897	      'cite', 'CITE',
1898	      'code', 'CODE',
1899	      'command', 'CODE',
1900	      'ctrl', '&do_ctrl',	# special case
1901	      'dfn', 'EM',		# DFN tag is illegal in the standard
1902	      'dmn', '',		# useless
1903	      'email', '&do_email',     # insert a clickable email address
1904	      'emph', 'EM',
1905	      'env', 'CODE',
1906	      'file', '"TT',		# will put quotes, cf. &apply_style
1907	      'i', 'I',
1908	      'kbd', 'KBD',
1909	      'key', 'KBD',
1910	      'math', '&do_math',
1911	      'option', '"SAMP',        # will put quotes, cf. &apply_style
1912	      'r', '',			# unsupported
1913	      'samp', '"SAMP',		# will put quotes, cf. &apply_style
1914	      'sc', '&do_sc',		# special case
1915	      'strong', 'STRONG',
1916	      't', 'TT',
1917	      'titlefont', '',		# useless
1918	      'uref', '&do_uref',       # insert a clickable URL
1919	      'url', '&do_url',         # insert a clickable URL
1920	      'var', 'VAR',
1921	      'w', '',			# unsupported
1922	      'H', '&do_accent',
1923	      'dotaccent', '&do_accent',
1924	      'ringaccent','&do_accent',
1925	      'tieaccent', '&do_accent',
1926	      'u','&do_accent',
1927	      'ubaraccent','&do_accent',
1928	      'udotaccent','&do_accent',
1929	      'v', '&do_accent',
1930	      ',', '&do_accent',
1931	      'dotless', '&do_accent'
1932	      );
1933
1934#
1935# texinfo format (@foo/@end foo) to HTML ones
1936#
1937%format_map = (
1938	       'quotation', 'BLOCKQUOTE',
1939	       # lists
1940	       'itemize', 'UL',
1941	       'enumerate', 'OL',
1942	       # poorly supported
1943	       'flushleft', 'PRE',
1944	       'flushright', 'PRE',
1945	       );
1946
1947#
1948# an eval of these $complex_format_map->{what}->[0] yields beginning
1949# an eval of these $complex_format_map->{what}->[1] yieleds end
1950$complex_format_map =
1951{
1952 example => 
1953 [
1954  q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td class=example><pre>"},
1955  q{'</pre></td></tr></table>'}
1956 ],
1957 smallexample => 
1958 [
1959  q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td class=smallexample><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre>"},
1960  q{'</FONT></pre></td></tr></table>'}
1961 ],
1962 display =>
1963 [
1964  q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td class=display><pre " . 'style="font-family: serif">'},
1965  q{'</pre></td></tr></table>'}
1966 ],
1967 smalldisplay =>
1968 [
1969  q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td class=smalldisplay><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre " . 'style="font-family: serif">'},
1970  q{'</pre></FONT></td></tr></table>'}
1971 ]
1972};
1973
1974$complex_format_map->{lisp} = $complex_format_map->{example};
1975$complex_format_map->{smalllisp} = $complex_format_map->{smallexample};
1976$complex_format_map->{format} = $complex_format_map->{display};
1977$complex_format_map->{smallformat} = $complex_format_map->{smalldisplay};
1978
1979#
1980# texinfo definition shortcuts to real ones
1981#
1982%def_map = (
1983	    # basic commands
1984	    'deffn', 0,
1985	    'defvr', 0,
1986	    'deftypefn', 0,
1987	    'deftypevr', 0,
1988	    'defcv', 0,
1989	    'defop', 0,
1990	    'deftp', 0,
1991	    # basic x commands
1992	    'deffnx', 0,
1993	    'defvrx', 0,
1994	    'deftypefnx', 0,
1995	    'deftypevrx', 0,
1996	    'defcvx', 0,
1997	    'defopx', 0,
1998	    'deftpx', 0,
1999	    # shortcuts
2000	    'defun', 'deffn Function',
2001	    'defmac', 'deffn Macro',
2002	    'defspec', 'deffn {Special Form}',
2003	    'defvar', 'defvr Variable',
2004	    'defopt', 'defvr {User Option}',
2005	    'deftypefun', 'deftypefn Function',
2006	    'deftypevar', 'deftypevr Variable',
2007	    'defivar', 'defcv {Instance Variable}',
2008	    'deftypeivar', 'defcv {Instance Variable}', # NEW: FIXME
2009	    'defmethod', 'defop Method',
2010	    'deftypemethod', 'defop Method', # NEW:FIXME
2011	    # x shortcuts
2012	    'defunx', 'deffnx Function',
2013	    'defmacx', 'deffnx Macro',
2014	    'defspecx', 'deffnx {Special Form}',
2015	    'defvarx', 'defvrx Variable',
2016	    'defoptx', 'defvrx {User Option}',
2017	    'deftypefunx', 'deftypefnx Function',
2018	    'deftypevarx', 'deftypevrx Variable',
2019	    'defivarx', 'defcvx {Instance Variable}',
2020	    'defmethodx', 'defopx Method',
2021	    );
2022
2023#
2024# things to skip
2025#
2026%to_skip = (
2027	    # comments
2028	    'c', 1,
2029	    'comment', 1,
2030            'ifnotinfo', 1,
2031            'ifnottex', 1,
2032	    'ifhtml', 1,
2033	    'end ifhtml', 1,
2034            'end ifnotinfo', 1,
2035            'end ifnottex', 1,
2036	    # useless
2037	    'detailmenu', 1,
2038            'direntry', 1,
2039	    'contents', 1,
2040	    'shortcontents', 1,
2041	    'summarycontents', 1,
2042	    'footnotestyle', 1,
2043	    'end ifclear', 1,
2044	    'end ifset', 1,
2045	    'titlepage', 1,
2046	    'end titlepage', 1,
2047	    # unsupported commands (formatting)
2048	    'afourpaper', 1,
2049	    'cropmarks', 1,
2050	    'finalout', 1,
2051	    'headings', 1,
2052            'sp', 1,
2053	    'need', 1,
2054	    'page', 1,
2055	    'setchapternewpage', 1,
2056	    'everyheading', 1,
2057	    'everyfooting', 1,
2058	    'evenheading', 1,
2059	    'evenfooting', 1,
2060	    'oddheading', 1,
2061	    'oddfooting', 1,
2062	    'smallbook', 1,
2063	    'vskip', 1,
2064	    'filbreak', 1,
2065	    'paragraphindent', 1,
2066	    # unsupported formats
2067	    'cartouche', 1,
2068	    'end cartouche', 1,
2069	    'group', 1,
2070	    'end group', 1,
2071	    );
2072
2073#+++############################################################################
2074#                                                                              #
2075# Argument parsing, initialisation                                             #
2076#                                                                              #
2077#---############################################################################
2078
2079#
2080# flush stdout and stderr after every write
2081#
2082select(STDERR);
2083$| = 1;
2084select(STDOUT);
2085$| = 1;
2086
2087
2088%value = ();				# hold texinfo variables, see also -D
2089$use_bibliography = 1;
2090$use_acc = 1;
2091
2092#
2093# called on -init-file
2094sub LoadInitFile
2095{
2096  my $init_file = shift;
2097  # second argument is value of options
2098  $init_file = shift;
2099  if (-f $init_file)
2100  {
2101    print "# reading initialization file from $init_file\n" 
2102      if ($T2H_VERBOSE);
2103    require($init_file);
2104  }
2105  else
2106  {
2107    print "$ERROR Error: can't read init file $int_file\n";
2108    $init_file = '';
2109  }
2110}
2111
2112#
2113# called on -lang
2114sub SetDocumentLanguage
2115{
2116  my $lang = shift;
2117  if (! exists($T2H_WORDS->{$lang}))
2118  {
2119    warn "$ERROR: Language specs for '$lang' do not exists. Reverting to '" . 
2120      ($T2H_LANG ? T2H_LANG : "en") . "'\n";
2121  }
2122  else
2123  {
2124    print "# using '$lang' as document language\n" if ($T2H_VERBOSE);
2125    $T2H_LANG = $lang;
2126  }
2127}
2128
2129##
2130## obsolete cmd line options
2131##
2132$T2H_OBSOLETE_OPTIONS -> {'no-section_navigation'} =
2133{
2134 type => '!',
2135 linkage => sub {$main::T2H_SECTION_NAVIGATION = 0;},
2136 verbose => 'obsolete, use -nosec_nav',
2137 noHelp => 2,
2138};
2139$T2H_OBSOLETE_OPTIONS -> {use_acc} =
2140{
2141 type => '!',
2142 linkage => \$use_acc,
2143 verbose => 'obsolete',
2144 noHelp => 2
2145};
2146$T2H_OBSOLETE_OPTIONS -> {expandinfo} =
2147{
2148 type => '!',
2149 linkage => sub {$main::T2H_EXPAND = 'info';},
2150 verbose => 'obsolete, use "-expand info" instead',
2151 noHelp => 2,
2152};
2153$T2H_OBSOLETE_OPTIONS -> {expandtex} =
2154{
2155 type => '!',
2156 linkage => sub {$main::T2H_EXPAND = 'tex';},
2157 verbose => 'obsolete, use "-expand tex" instead',
2158 noHelp => 2,
2159};
2160$T2H_OBSOLETE_OPTIONS -> {monolithic} =
2161{
2162 type => '!',
2163 linkage => sub {$main::T2H_SPLIT = '';},
2164 verbose => 'obsolete, use "-split no" instead',
2165 noHelp => 2
2166};
2167$T2H_OBSOLETE_OPTIONS -> {split_node} =
2168{
2169 type => '!',
2170 linkage => sub{$main::T2H_SPLIT = 'section';},
2171 verbose => 'obsolete, use "-split section" instead',
2172 noHelp => 2,
2173};
2174$T2H_OBSOLETE_OPTIONS -> {split_chapter} =
2175{
2176 type => '!',
2177 linkage => sub{$main::T2H_SPLIT = 'chapter';},
2178 verbose => 'obsolete, use "-split chapter" instead',
2179 noHelp => 2,
2180};
2181$T2H_OBSOLETE_OPTIONS -> {no_verbose} =
2182{
2183 type => '!',
2184 linkage => sub {$main::T2H_VERBOSE = 0;},
2185 verbose => 'obsolete, use -noverbose instead',
2186 noHelp => 2,
2187};
2188$T2H_OBSOLETE_OPTIONS -> {output_file} =
2189{
2190 type => '=s',
2191 linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';},
2192 verbose => 'obsolete, use -out_file instead',
2193 noHelp => 2
2194};
2195
2196$T2H_OBSOLETE_OPTIONS -> {section_navigation} =
2197{
2198 type => '!',
2199 linkage => \$T2H_SECTION_NAVIGATION,
2200 verbose => 'obsolete, use -sec_nav instead',
2201 noHelp => 2,
2202};
2203
2204$T2H_OBSOLETE_OPTIONS -> {verbose} =
2205{
2206 type => '!',
2207 linkage => \$T2H_VERBOSE,
2208 verbose => 'obsolete, use -Verbose instead',
2209 noHelp => 2
2210};
2211
2212# read initialzation from $sysconfdir/texi2htmlrc or $HOME/.texi2htmlrc
2213my $home = $ENV{HOME};
2214defined($home) or $home = '';
2215foreach $i ('/usr/local/etc/texi2htmlrc', "$home/.texi2htmlrc") {
2216    if (-f $i) {
2217	print "# reading initialization file from $i\n" 
2218	    if ($T2H_VERBOSE);
2219	require($i);
2220    }
2221}
2222
2223
2224#+++############################################################################
2225#                                                                              #
2226# parse command-line options
2227#                                                                              #
2228#---############################################################################
2229$T2H_USAGE_TEXT = <<EOT;
2230Usage: texi2html  [OPTIONS] TEXINFO-FILE
2231Translates Texinfo source documentation to HTML.
2232EOT
2233$T2H_FAILURE_TEXT = <<EOT;
2234Try 'texi2html -help' for usage instructions.
2235EOT
2236$options = new Getopt::MySimple;
2237
2238# some older version of GetOpt::Long don't have 
2239# Getopt::Long::Configure("pass_through")
2240eval {Getopt::Long::Configure("pass_through");};
2241$Configure_failed = $@ && <<EOT;
2242**WARNING: Parsing of obsolete command-line options could have failed. 
2243           Consider to use only documented command-line options (run
2244           'texi2html -help 2' for a complete list) or upgrade to perl 
2245           version 5.005 or higher.
2246EOT
2247
2248if (! $options->getOptions($T2H_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n"))
2249{
2250  print $Configure_failed if $Configure_failed;
2251  die $T2H_FAILURE_TEXT;
2252}
2253
2254if (@ARGV > 1)
2255{
2256  eval {Getopt::Long::Configure("no_pass_through");};
2257  if (! $options->getOptions($T2H_OBSOLETE_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n"))
2258  {
2259    print $Configure_failed if $Configure_failed;
2260    die $T2H_FAILURE_TEXT;
2261  }
2262}
2263
2264if ($T2H_CHECK) {
2265    die "Need file to check\n$T2H_FAILURE_TEXT" unless @ARGV > 0;
2266    &check;
2267    exit;
2268}
2269
2270#+++############################################################################
2271#                                                                              #
2272# evaluation of cmd line options
2273#                                                                              #
2274#---############################################################################
2275
2276if ($T2H_EXPAND eq 'info') 
2277{
2278  $to_skip{'ifinfo'} = 1;
2279  $to_skip{'end ifinfo'} = 1;
2280} 
2281elsif ($T2H_EXPAND eq 'tex')
2282{
2283  $to_skip{'iftex'} = 1;
2284  $to_skip{'end iftex'} = 1;
2285  
2286}
2287
2288$T2H_INVISIBLE_MARK = '<IMG SRC="invisible.xbm">' if $T2H_INVISIBLE_MARK eq 'xbm';
2289
2290#
2291# file name buisness
2292#
2293die "Need exactly one file to translate\n$T2H_FAILURE_TEXT" unless @ARGV == 1;
2294$docu = shift(@ARGV);
2295if ($docu =~ /.*\//) {
2296    chop($docu_dir = $&);
2297    $docu_name = $';
2298} else {
2299    $docu_dir = '.';
2300    $docu_name = $docu;
2301}
2302unshift(@T2H_INCLUDE_DIRS, $docu_dir);
2303$docu_name =~ s/\.te?x(i|info)?$//;	# basename of the document
2304$docu_name = $T2H_PREFIX if ($T2H_PREFIX);
2305
2306# subdir
2307if ($T2H_SUBDIR && ! $T2H_OUT)
2308{
2309  $T2H_SUBDIR =~ s|/*$||;
2310  unless (-d "$T2H_SUBDIR" && -w "$T2H_SUBDIR")
2311  {
2312    if ( mkdir($T2H_SUBDIR, oct(755)))
2313    {
2314      print "# created directory $T2H_SUBDIR\n" if ($T2H_VERBOSE);
2315    }
2316    else
2317    {
2318      warn "$ERROR can't create directory $T2H_SUBDIR. Put results into current directory\n";
2319      $T2H_SUBDIR = '';
2320    }
2321  }
2322}
2323
2324if ($T2H_SUBDIR && ! $T2H_OUT)
2325{
2326  $docu_rdir = "$T2H_SUBDIR/";
2327  print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE);
2328}
2329else
2330{
2331  if ($T2H_OUT && $T2H_OUT =~ m|(.*)/|)
2332  {
2333    $docu_rdir = "$1/";
2334    print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE);
2335  }
2336  else
2337  {
2338    print "# putting result files into current directory \n" if ($T2H_VERBOSE);
2339    $docu_rdir = '';
2340  }
2341}
2342
2343# extension
2344if ($T2H_SHORTEXTN)
2345{
2346  $docu_ext = "htm";
2347}
2348else
2349{
2350  $docu_ext = "html";
2351}
2352if ($T2H_TOP_FILE =~ /\..*$/)
2353{
2354  $T2H_TOP_FILE = $`.".$docu_ext";
2355}
2356
2357# result files
2358if (! $T2H_OUT && ($T2H_SPLIT =~ /section/i || $T2H_SPLIT =~ /node/i))
2359{
2360  $T2H_SPLIT = 'section';
2361}
2362elsif (! $T2H_OUT && $T2H_SPLIT =~ /chapter/i)
2363{
2364  $T2H_SPLIT = 'chapter'
2365}
2366else
2367{
2368  undef $T2H_SPLIT;
2369}
2370
2371$docu_doc = "$docu_name.$docu_ext";		# document's contents
2372$docu_doc_file = "$docu_rdir$docu_doc";
2373if ($T2H_SPLIT) 
2374{
2375  $docu_toc  = $T2H_TOC_FILE || "${docu_name}_toc.$docu_ext"; # document's table of contents
2376  $docu_stoc = "${docu_name}_ovr.$docu_ext"; # document's short toc
2377  $docu_foot = "${docu_name}_fot.$docu_ext"; # document's footnotes
2378  $docu_about = "${docu_name}_abt.$docu_ext"; # about this document
2379  $docu_top  = $T2H_TOP_FILE || $docu_doc;
2380}
2381else
2382{
2383  if ($T2H_OUT)
2384  {
2385    $docu_doc = $T2H_OUT;
2386    $docu_doc =~ s|.*/||;
2387  }
2388  $docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_top = $docu_doc;
2389}
2390
2391$docu_toc_file  = "$docu_rdir$docu_toc";
2392$docu_stoc_file = "$docu_rdir$docu_stoc";
2393$docu_foot_file = "$docu_rdir$docu_foot";
2394$docu_about_file = "$docu_rdir$docu_about";
2395$docu_top_file  = "$docu_rdir$docu_top";
2396
2397$docu_frame_file =     "$docu_rdir${docu_name}_frame.$docu_ext";
2398$docu_toc_frame_file = "$docu_rdir${docu_name}_toc_frame.$docu_ext";
2399
2400#
2401# variables
2402#
2403$value{'html'} = 1;			# predefine html (the output format)
2404$value{'texi2html'} = $THISVERSION;	# predefine texi2html (the translator)
2405# _foo: internal to track @foo
2406foreach ('_author', '_title', '_subtitle',
2407	 '_settitle', '_setfilename', '_shorttitle') {
2408    $value{$_} = '';		        # prevent -w warnings
2409}
2410%node2sec = ();				# node to section name
2411%sec2node = ();				# section to node name
2412%sec2number = ();                       # section to number
2413%number2sec = ();                       # number to section 
2414%idx2node = ();                         # index keys to node
2415%node2href = ();			# node to HREF
2416%node2next = ();			# node to next
2417%node2prev = ();			# node to prev
2418%node2up   = ();			# node to up
2419%bib2href = ();				# bibliography reference to HREF
2420%gloss2href = ();			# glossary term to HREF
2421@sections = ();				# list of sections
2422%tag2pro = ();				# protected sections
2423
2424#
2425# initial indexes
2426#
2427$bib_num = 0;
2428$foot_num = 0;
2429$gloss_num = 0;
2430$idx_num = 0;
2431$sec_num = 0;
2432$doc_num = 0;
2433$html_num = 0;
2434
2435#
2436# can I use ISO8879 characters? (HTML+)
2437#
2438if ($T2H_USE_ISO) {
2439    $things_map{'bullet'} = "&bull;";
2440    $things_map{'copyright'} = "&copy;";
2441    $things_map{'dots'} = "&hellip;";
2442    $things_map{'equiv'} = "&equiv;";
2443    $things_map{'expansion'} = "&rarr;";
2444    $things_map{'point'} = "&lowast;";
2445    $things_map{'result'} = "&rArr;";
2446}
2447
2448#
2449# read texi2html extensions (if any)
2450#
2451$extensions = 'texi2html.ext'; # extensions in working directory
2452if (-f $extensions) {
2453    print "# reading extensions from $extensions\n" if $T2H_VERBOSE;
2454    require($extensions);
2455}
2456($progdir = $0) =~ s/[^\/]+$//;
2457if ($progdir && ($progdir ne './')) {
2458    $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory
2459    if (-f $extensions) {
2460	print "# reading extensions from $extensions\n" if $T2H_VERBOSE;
2461	require($extensions);
2462    }
2463}
2464
2465
2466print "# reading from $docu\n" if $T2H_VERBOSE;
2467
2468#########################################################################
2469#
2470# latex2html stuff
2471# 
2472# latex2html conversions consist of three stages:
2473# 1) ToLatex: Put "latex" code into a latex file
2474# 2) ToHtml: Use latex2html to generate corresponding html code and images
2475# 3) FromHtml: Extract generated code and images from latex2html run
2476#
2477
2478##########################
2479# default settings
2480#
2481
2482# defaults for files and names
2483
2484sub l2h_Init 
2485{
2486  local($root) = @_;
2487  
2488  return 0 unless ($root);
2489  
2490  $l2h_name =  "${root}_l2h";
2491  
2492  $l2h_latex_file = "$docu_rdir${l2h_name}.tex";
2493  $l2h_cache_file = "${docu_rdir}l2h_cache.pm";
2494  $T2H_L2H_L2H = "latex2html" unless ($T2H_L2H_L2H);
2495  
2496  # destination dir -- generated images are put there, should be the same
2497  # as dir of enclosing html document -- 
2498  $l2h_html_file = "$docu_rdir${l2h_name}.html";
2499  $l2h_prefix = "${l2h_name}_";
2500  return 1;
2501}
2502
2503
2504##########################
2505# 
2506# First stage: Generation of Latex file
2507# Initialize with: l2h_InitToLatex
2508# Add content with: l2h_ToLatex($text) --> HTML placeholder comment
2509# Finish with: l2h_FinishToLatex
2510# 
2511
2512$l2h_latex_preample = <<EOT;
2513% This document was automatically generated by the l2h extenstion of texi2html
2514% DO NOT EDIT !!!
2515\\documentclass{article}
2516\\usepackage{html}
2517\\begin{document}
2518EOT
2519
2520$l2h_latex_closing = <<EOT;
2521\\end{document}
2522EOT
2523
2524# return used latex 1, if l2h could be initalized properly, 0 otherwise
2525sub l2h_InitToLatex
2526{
2527  %l2h_to_latex = ();
2528  unless ($T2H_L2H_SKIP)
2529  {
2530    unless (open(L2H_LATEX, ">$l2h_latex_file"))
2531    {
2532      warn "$ERROR Error l2h: Can't open latex file '$latex_file' for writing\n";
2533      return 0;
2534    }  
2535    print "# l2h: use ${l2h_latex_file} as latex file\n" if ($T2H_VERBOSE);
2536    print L2H_LATEX $l2h_latex_preample;
2537  }
2538  # open database for caching
2539  l2h_InitCache();
2540  $l2h_latex_count = 0;
2541  $l2h_to_latex_count = 0;
2542  $l2h_cached_count = 0;
2543  return  1;
2544}
2545
2546# print text (1st arg) into latex file (if not already there), return
2547# HTML commentary which can be later on replaced by the latex2html
2548# generated text
2549sub l2h_ToLatex
2550{
2551  my($text) = @_;
2552  my($count);
2553  
2554  $l2h_to_latex_count++;
2555  $text =~ s/(\s*)$//;
2556  
2557  # try whether we can cache it
2558  my $cached_text = l2h_FromCache($text);
2559  if ($cached_text)
2560  {
2561    $l2h_cached_count++;
2562    return $cached_text;
2563  }
2564  
2565  # try whether we have text already on things to do
2566  unless ($count = $l2h_to_latex{$text})
2567  {
2568    $count = $l2h_latex_count;
2569    $l2h_latex_count++;
2570    $l2h_to_latex{$text} = $count;
2571    $l2h_to_latex[$count] = $text;
2572    unless ($T2H_L2H_SKIP)
2573    {
2574      print L2H_LATEX "\\begin{rawhtml}\n";
2575      print L2H_LATEX "<!-- l2h_begin ${l2h_name} ${count} -->\n";
2576      print L2H_LATEX "\\end{rawhtml}\n";
2577      
2578      print L2H_LATEX "$text\n";
2579      
2580      print L2H_LATEX "\\begin{rawhtml}\n";
2581      print L2H_LATEX "<!-- l2h_end ${l2h_name} ${count} -->\n";
2582      print L2H_LATEX "\\end{rawhtml}\n";
2583    }
2584  }
2585  return "<!-- l2h_replace ${l2h_name} ${count} -->"; 
2586}
2587
2588# print closing into latex file and close it
2589sub l2h_FinishToLatex
2590{
2591  local ($reused);
2592  
2593  $reused = $l2h_to_latex_count - $l2h_latex_count - $l2h_cached_count;
2594  unless ($T2H_L2H_SKIP)
2595  {
2596    print L2H_LATEX $l2h_latex_closing;
2597    close(L2H_LATEX);
2598  }
2599  print "# l2h: finished to latex ($l2h_cached_count cached, $reused reused, $l2h_latex_count contents)\n" if ($T2H_VERBOSE);
2600  unless ($l2h_latex_count)
2601  {
2602    l2h_Finish();
2603    return 0;
2604  }
2605  return 1;
2606}
2607
2608###################################
2609# Second stage: Use latex2html to generate corresponding html code and images
2610#
2611# l2h_ToHtml([$l2h_latex_file, [$l2h_html_dir]]):
2612#   Call latex2html on $l2h_latex_file
2613#   Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir
2614#   Return 1, on success
2615#          0, otherwise
2616#
2617sub l2h_ToHtml
2618{
2619  local($call, $ext, $root, $dotbug);
2620  
2621  if ($T2H_L2H_SKIP)
2622  {
2623    print "# l2h: skipping latex2html run\n" if ($T2H_VERBOSE);
2624    return 1;
2625  }
2626  
2627  # Check for dot in directory where dvips will work
2628  if ($T2H_L2H_TMP)
2629  {
2630    if ($T2H_L2H_TMP =~ /\./)
2631    {
2632      warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n";
2633      $dotbug = 1;
2634    }
2635  }
2636  else
2637  {
2638    if (&getcwd =~ /\./)
2639    {
2640     warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n";
2641     $dotbug = 1;
2642   }
2643  }
2644  # fix it, if necessary and hope that it works 
2645  $T2H_L2H_TMP = "/tmp" if ($dotbug);
2646    
2647  $call = $T2H_L2H_L2H;
2648  # use init file, if specified
2649  $call = $call . " -init_file " . $init_file if ($init_file && -f $init_file);
2650  # set output dir
2651  $call .=  ($docu_rdir ? " -dir $docu_rdir" : " -no_subdir");
2652  # use l2h_tmp, if specified
2653  $call = $call . " -tmp $T2H_L2H_TMP" if ($T2H_L2H_TMP);
2654  # options we want to be sure of
2655  $call = $call ." -address 0 -info 0 -split 0 -no_navigation -no_auto_link";
2656  $call = $call ." -prefix ${l2h_prefix} $l2h_latex_file"; 
2657
2658  print "# l2h: executing '$call'\n" if ($T2H_VERBOSE);
2659  if (system($call))
2660  {
2661    warn "l2h ***Error: '${call}' did not succeed\n";
2662    return 0;
2663  }
2664  else
2665  {
2666    print "# l2h: latex2html finished successfully\n" if ($T2H_VERBOSE);
2667    return 1;
2668  }
2669}
2670
2671# this is directly pasted over from latex2html
2672sub getcwd {
2673    local($_) = `pwd`;
2674
2675    die "'pwd' failed (out of memory?)\n"
2676	unless length;
2677    chop;
2678    $_;
2679}
2680
2681
2682##########################
2683# Third stage: Extract generated contents from latex2html run
2684# Initialize with: l2h_InitFromHtml
2685#   open $l2h_html_file for reading
2686#   reads in contents into array indexed by numbers
2687#   return 1,  on success -- 0, otherwise
2688# Extract Html code with: l2h_FromHtml($text)
2689#   replaces in $text all previosuly inserted comments by generated html code
2690#   returns (possibly changed) $text
2691# Finish with: l2h_FinishFromHtml
2692#   closes $l2h_html_dir/$l2h_name.".$docu_ext" 
2693
2694sub l2h_InitFromHtml
2695{
2696  local($h_line, $h_content, $count, %l2h_img);
2697
2698  if (! open(L2H_HTML, "<${l2h_html_file}"))
2699  {
2700    print "$ERROR Error l2h: Can't open ${l2h_html_file} for reading\n";
2701    return 0;
2702  }
2703  print "# l2h: use ${l2h_html_file} as html file\n" if ($T2H_VERBOSE);
2704
2705  $l2h_html_count = 0;
2706  
2707  while ($h_line = <L2H_HTML>)
2708  {
2709    if ($h_line =~ /^<!-- l2h_begin $l2h_name ([0-9]+) -->/)
2710    {
2711      $count = $1;
2712      $h_content = "";
2713      while ($h_line = <L2H_HTML>)
2714      {
2715	if ($h_line =~ /^<!-- l2h_end $l2h_name $count -->/)
2716	{
2717	  chomp $h_content;
2718	  chomp $h_content;
2719	  $l2h_html_count++;
2720	  $h_content = l2h_ToCache($count, $h_content);
2721	  $l2h_from_html[$count] = $h_content;
2722	  $h_content = '';
2723	  last;
2724	}
2725	$h_content = $h_content.$h_line;
2726      }
2727      if ($hcontent)
2728      {
2729	print "$ERROR Warning l2h: l2h_end $l2h_name $count not found\n" 
2730	  if ($T2H_VERBOSE);
2731	close(L2H_HTML);
2732	return 0;
2733      }
2734    }
2735  }
2736  print "# l2h: Got $l2h_html_count of $l2h_latex_count html contents\n"
2737    if ($T2H_VERBOSE);
2738
2739  close(L2H_HTML);
2740  return 1;
2741}
2742
2743sub l2h_FromHtml
2744{
2745  local($text) = @_;
2746  local($done, $to_do, $count);
2747  
2748  $to_do = $text;
2749  
2750  while ($to_do =~ /([^\000]*)<!-- l2h_replace $l2h_name ([0-9]+) -->([^\000]*)/)
2751  {
2752    $to_do = $1;
2753    $count = $2;
2754    $done = $3.$done;
2755    
2756    $done = "<!-- l2h_end $l2h_name $count -->".$done
2757      if ($T2H_DEBUG & $DEBUG_L2H);
2758
2759    $done = &l2h_ExtractFromHtml($count) . $done;
2760
2761    $done = "<!-- l2h_begin $l2h_name $count -->".$done
2762      if ($T2H_DEBUG & $DEBUG_L2H);
2763  }
2764  return $to_do.$done;
2765}
2766
2767
2768sub l2h_ExtractFromHtml
2769{
2770  local($count) = @_;
2771  
2772  return $l2h_from_html[$count] if ($l2h_from_html[$count]);
2773  
2774  if ($count >= 0 && $count < $l2h_latex_count)
2775  {
2776    # now we are in trouble
2777    local($l_l2h, $_);
2778
2779    $l2h_extract_error++;
2780    print "$ERROR l2h: can't extract content $count from html\n" 
2781      if ($T2H_VERBOSE);
2782    # try simple (ordinary) substition (without l2h)
2783    $l_l2h = $T2H_L2H;
2784    $T2H_L2H = 0;
2785    $_ = $l2h_to_latex{$count};
2786    $_ = &substitute_style($_); 
2787    &unprotect_texi;
2788    $_ = "<!-- l2h: ". __LINE__ . " use texi2html -->" . $_
2789      if ($T2H_DEBUG & $DEBUG_L2H);
2790    $T2H_L2H = $l_l2h;
2791    return $_;
2792  }
2793  else
2794  {
2795    # now we have been incorrectly called
2796    $l2h_range_error++;
2797    print "$ERROR l2h: Request of $count content which is out of valide range [0,$l2h_latex_count)\n";
2798    return "<!-- l2h: ". __LINE__ . " out of range count $count -->"
2799      if ($T2H_DEBUG & $DEBUG_L2H);
2800    return "<!-- l2h: out of range count $count -->";
2801  }
2802}
2803    
2804sub l2h_FinishFromHtml
2805{
2806  if ($T2H_VERBOSE)
2807  {
2808    if ($l2h_extract_error + $l2h_range_error)
2809    {
2810      print "# l2h: finished from html ($l2h_extract_error extract and $l2h_range_error errors)\n";
2811    }
2812    else
2813    {
2814      print "# l2h: finished from html (no errors)\n";
2815    }
2816  }
2817}
2818
2819sub l2h_Finish
2820{
2821  l2h_StoreCache();
2822  if ($T2H_L2H_CLEAN)
2823  {
2824    print "# l2h: removing temporary files generated by l2h extension\n"
2825      if $T2H_VERBOSE;
2826    while (<"$docu_rdir$l2h_name"*>)
2827    {
2828      unlink $_;
2829    }
2830  }
2831  print "# l2h: Finished\n" if $T2H_VERBOSE;
2832  return 1;
2833}
2834
2835##############################
2836# stuff for l2h caching
2837#
2838
2839# I tried doing this with a dbm data base, but it did not store all
2840# keys/values. Hence, I did as latex2html does it
2841sub l2h_InitCache
2842{
2843  if (-r "$l2h_cache_file")
2844  {
2845    my $rdo = do "$l2h_cache_file";
2846    warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n")
2847      unless ($rdo);
2848  }
2849}
2850
2851sub l2h_StoreCache
2852{
2853  return unless $l2h_latex_count;
2854  
2855  my ($key, $value);
2856  open(FH, ">$l2h_cache_file") || return warn"$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n";
2857
2858  
2859  while (($key, $value) = each %l2h_cache)
2860  {
2861    # escape stuff
2862    $key =~ s|/|\\/|g;
2863    $key =~ s|\\\\/|\\/|g;
2864    # weird, a \ at the end of the key results in an error
2865    # maybe this also broke the dbm database stuff
2866    $key =~ s|\\$|\\\\|;
2867    $value =~ s/\|/\\\|/g; 
2868    $value =~ s/\\\\\|/\\\|/g; 
2869    $value =~ s|\\\\|\\\\\\\\|g;
2870    print FH "\n\$l2h_cache_key = q/$key/;\n";
2871    print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n";
2872  }
2873  print FH "1;";
2874  close(FH);
2875}
2876
2877# return cached html, if it exists for text, and if all pictures
2878# are there, as well
2879sub l2h_FromCache
2880{
2881  my $text = shift;
2882  my $cached = $l2h_cache{$text};
2883  if ($cached)
2884  {
2885    while ($cached =~ m/SRC="(.*?)"/g)
2886    {
2887      unless (-e "$docu_rdir$1")
2888      {
2889	return undef;
2890      }
2891    }
2892    return $cached;
2893  }
2894  return undef;
2895}
2896
2897# insert generated html into cache, move away images, 
2898# return transformed html
2899$maximage = 1;
2900sub l2h_ToCache
2901{
2902  my $count = shift;
2903  my $content = shift;
2904  my @images = ($content =~ /SRC="(.*?)"/g);
2905  my ($src, $dest);
2906
2907  for $src (@images)
2908  {
2909    $dest = $l2h_img{$src};
2910    unless ($dest)
2911    {
2912      my $ext;
2913      if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext)
2914      {
2915	$ext = $1;
2916      }
2917      else
2918      {
2919	warn "$ERROR: L2h image $src has invalid extension\n";
2920	next;
2921      }
2922      while (-e "$docu_rdir${docu_name}_$maximage.$ext") { $maximage++;}
2923      $dest = "${docu_name}_$maximage.$ext";
2924      system("cp -f $docu_rdir$src $docu_rdir$dest");
2925      $l2h_img{$src} = $dest;
2926      unlink "$docu_rdir$src" unless ($DEBUG & DEBUG_L2H);
2927    }
2928    $content =~ s/$src/$dest/g;
2929  }
2930  $l2h_cache{$l2h_to_latex[$count]} = $content;
2931  return $content;
2932}
2933
2934
2935#+++############################################################################
2936#                                                                              #
2937# Pass 1: read source, handle command, variable, simple substitution           #
2938#                                                                              #
2939#---############################################################################
2940
2941@lines = ();				# whole document
2942@toc_lines = ();			# table of contents
2943@stoc_lines = ();			# table of contents
2944$curlevel = 0;				# current level in TOC
2945$node = '';				# current node name
2946$node_next = '';                        # current node next name               
2947$node_prev = '';                        # current node prev name
2948$node_up = '';                          # current node up name
2949$in_table = 0;				# am I inside a table
2950$table_type = '';			# type of table ('', 'f', 'v', 'multi')
2951@tables = ();			        # nested table support
2952$in_bibliography = 0;			# am I inside a bibliography
2953$in_glossary = 0;			# am I inside a glossary
2954$in_top = 0;				# am I inside the top node
2955$has_top = 0;				# did I see a top node?
2956$has_top_command = 0;			# did I see @top for automatic pointers?
2957$in_pre = 0;				# am I inside a preformatted section
2958$in_list = 0;				# am I inside a list
2959$in_html = 0;				# am I inside an HTML section
2960$first_line = 1;		        # is it the first line
2961$dont_html = 0;				# don't protect HTML on this line
2962$deferred_ref = '';			# deferred reference for indexes
2963@html_stack = ();			# HTML elements stack
2964$html_element = '';			# current HTML element
2965&html_reset;
2966%macros = ();                           # macros
2967
2968# init l2h
2969$T2H_L2H = &l2h_Init($docu_name) if ($T2H_L2H);
2970$T2H_L2H = &l2h_InitToLatex      if ($T2H_L2H);    
2971
2972# build code for simple substitutions
2973# the maps used (%simple_map and %things_map) MUST be aware of this
2974# watch out for regexps, / and escaped characters!
2975$subst_code = '';
2976foreach (keys(%simple_map)) {
2977    ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars
2978    $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n";
2979}
2980foreach (keys(%things_map)) {
2981    $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n";
2982}
2983if ($use_acc) {
2984    # accentuated characters
2985    foreach (keys(%accent_map)) {
2986	if ($_ eq "`") {
2987	    $subst_code .= "s/$;3";
2988	} elsif ($_ eq "'") {
2989	    $subst_code .= "s/$;4";
2990	} else {
2991	    $subst_code .= "s/\\\@\\$_";
2992	}
2993	$subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n";
2994    }
2995}
2996eval("sub simple_substitutions { $subst_code }");
2997
2998&init_input;
2999INPUT_LINE: while ($_ = &next_line) {
3000    #
3001    # remove \input on the first lines only
3002    #
3003    if ($first_line) {
3004	next if /^\\input/;
3005	$first_line = 0;
3006    }
3007    # non-@ substitutions cf. texinfmt.el
3008    #
3009    # parse texinfo tags
3010    #
3011    $tag = '';
3012    $end_tag = '';
3013    if (/^\s*\@end\s+(\w+)\b/) {
3014	$end_tag = $1;
3015    } elsif (/^\s*\@(\w+)\b/) {
3016	$tag = $1;
3017    }
3018    #
3019    # handle @html / @end html
3020    #
3021    if ($in_html) {
3022	if ($end_tag eq 'html') {
3023	    $in_html = 0;
3024	} else {
3025	    $tag2pro{$in_html} .= $_;
3026	}
3027	next;
3028    } elsif ($tag eq 'html') {
3029	$in_html = $PROTECTTAG . ++$html_num;
3030	push(@lines, $in_html);
3031	next;
3032    }
3033
3034    #
3035    # try to remove inlined comments
3036    # syntax from tex-mode.el comment-start-skip
3037    #
3038    s/((^|[^\@])(\@\@)*)\@c(omment | |\{|$).*/$1/;
3039
3040# Sometimes I use @c right at the end of  a line ( to suppress the line feed )
3041#    s/((^|[^\@])(\@\@)*)\@c(omment)?$/$1/;
3042#     s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/;
3043#     s/(.*)\@c{.*?}(.*)/$1$2/;
3044#     s/(.*)\@comment{.*?}(.*)/$1$2/;
3045#     s/^(.*)\@c /$1/;
3046#     s/^(.*)\@comment /$1/;
3047
3048    #############################################################
3049    # value substitution before macro expansion, so that
3050    # it works in macro arguments			    
3051    s/\@value{($VARRE)}/$value{$1}/eg;
3052			    
3053    #############################################################
3054    # macro substitution
3055    while (/\@(\w+)/g)
3056    {
3057      if (exists($macros->{$1}))    
3058      {
3059	my $before = $`;
3060	my $name = $1;
3061	my $after = $';
3062	my @args;
3063	my $args;
3064	if ($after =~ /^\s*{(.*?[^\\])}(.*)/)  
3065	{
3066	  $args = $1;
3067	  $after = $2;
3068	}
3069	elsif (@{$macros->{$name}->{Args}} == 1)
3070	{
3071	  $args = $after;
3072	  $args =~ s/^\s*//;
3073	  $args =~ s/\s*$//;
3074	  $after = '';
3075	}
3076	$args =~ s|\\\\|\\|g;
3077	$args =~ s|\\{|{|g;
3078        $args =~ s|\\}|}|g;
3079	if (@{$macros->{$name}->{Args}} > 1)
3080	{
3081	  $args =~ s/(^|[^\\]),/$1$;/g ;
3082	  $args =~ s|\\,|,|g;
3083	  @args = split(/$;\s*/, $args) if (@{$macros->{$name}->{Args}} > 1);
3084	}
3085	else
3086	{
3087	  $args =~ s|\\,|,|g;
3088	  @args = ($args);
3089	}
3090	my $macrobody = $macros->{$name}->{Body};
3091	for ($i=0; $i<=$#args; $i++)
3092	{
3093	  $macrobody =~ s|\\$macros->{$name}->{Args}->[$i]\\|$args[$i]|g;
3094	}
3095	$macrobody =~ s|\\\\|\\|g;
3096	$_ = $before . $macrobody . $after;
3097	unshift @input_spool, map {$_ = $_."\n"} split(/\n/, $_);
3098	next INPUT_LINE;
3099      }
3100    }				#
3101			    
3102    
3103    #
3104    # try to skip the line
3105    #
3106    if ($end_tag) {
3107        $in_titlepage = 0 if $end_tag eq 'titlepage';
3108	next if $to_skip{"end $end_tag"};
3109    } elsif ($tag) {
3110      $in_titlepage = 1 if $tag eq 'titlepage';
3111      next if $to_skip{$tag};
3112      last if $tag eq 'bye';
3113    }
3114    if ($in_top) {
3115	# parsing the top node
3116	if ($tag eq 'node' || 
3117	    ($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/))
3118	{
3119	    # no more in top
3120	    $in_top = 0;
3121	    push(@lines, $TOPEND);
3122	}
3123    }
3124    unless ($in_pre) {
3125	s/``/\"/g;
3126	s/''/\"/g;
3127	s/([\w ])---([\w ])/$1--$2/g;
3128    }
3129    #
3130    # analyze the tag
3131    #
3132    if ($tag) {
3133	# skip lines
3134	&skip_until($tag), next if $tag eq 'ignore';
3135	&skip_until($tag), next if $tag eq 'ifnothtml';
3136	if ($tag eq 'ifinfo')
3137	{
3138	  &skip_until($tag), next unless $T2H_EXPAND eq 'info';
3139	}
3140	if ($tag eq 'iftex')
3141	{
3142	  &skip_until($tag), next unless $T2H_EXPAND eq 'tex';
3143	} 
3144	if ($tag eq 'tex')
3145	{
3146	  # add to latex2html file
3147	  if ($T2H_EXPAND eq 'tex' && $T2H_L2H && ! $in_pre)
3148	  {
3149	    # add space to the end -- tex(i2dvi) does this, as well 
3150	    push(@lines, &l2h_ToLatex(&string_until($tag) . " "));
3151	  }
3152	  else
3153	  {
3154	    &skip_until($tag);
3155	  }
3156	  next;
3157	}
3158	if ($tag eq 'titlepage')
3159	{
3160	  next;
3161	}
3162	# handle special tables
3163	if ($tag =~ /^(|f|v|multi)table$/) {
3164	    $table_type = $1;
3165	    $tag = 'table';
3166	}
3167	# special cases
3168	if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) {
3169	    $in_top = 1;
3170	    $has_top = 1;
3171	    $has_top_command = 1 if $tag eq 'top';
3172	    @lines = (); # ignore all lines before top (title page garbage)
3173	    next;
3174	} elsif ($tag eq 'node') {
3175	  if ($in_top)
3176	  {
3177	    $in_top = 0;
3178	    push(@lines, $TOPEND);
3179	  }
3180	  warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o;
3181	  # request of "Richard Y. Kim" <ryk@ap.com>
3182	  s/^\@node\s+//;
3183	  $_ = &protect_html($_); # if node contains '&' for instance
3184	  ($node, $node_next, $node_prev, $node_up) = split(/,/);
3185	  &normalise_node($node);
3186	  &normalise_node($node_next);
3187	  &normalise_node($node_prev);
3188	  &normalise_node($node_up);
3189	  $node =~ /\"/ ?
3190	    push @lines, &html_debug("<A NAME='$node'></A>\n", __LINE__) :
3191	    push @lines, &html_debug("<A NAME=\"$node\"></A>\n", __LINE__);
3192	  next;
3193	} elsif ($tag eq 'include') {
3194	    if (/^\@include\s+($FILERE)\s*$/o) {
3195		$file = LocateIncludeFile($1);
3196		if ($file && -e $file) {
3197		    &open($file);
3198		    print "# including $file\n" if $T2H_VERBOSE;
3199		} else {
3200		    warn "$ERROR Can't find $1, skipping";
3201		}
3202	    } else {
3203		warn "$ERROR Bad include line: $_";
3204	    }
3205	    next;
3206	} elsif ($tag eq 'ifclear') {
3207	    if (/^\@ifclear\s+($VARRE)\s*$/o) {
3208		next unless defined($value{$1});
3209		&skip_until($tag);
3210	    } else {
3211		warn "$ERROR Bad ifclear line: $_";
3212	    }
3213	    next;
3214	} elsif ($tag eq 'ifset') {
3215	    if (/^\@ifset\s+($VARRE)\s*$/o) {
3216		next if defined($value{$1});
3217		&skip_until($tag);
3218	    } else {
3219		warn "$ERROR Bad ifset line: $_";
3220	    }
3221	    next;
3222	} elsif ($tag eq 'menu') {
3223	    unless ($T2H_SHOW_MENU) {
3224		&skip_until($tag);
3225		next;
3226	    }
3227	    &html_push_if($tag);
3228	    push(@lines, &html_debug('', __LINE__));
3229	} elsif ($format_map{$tag}) {
3230	    $in_pre = 1 if $format_map{$tag} eq 'PRE';
3231	    &html_push_if($format_map{$tag});
3232	    push(@lines, &html_debug('', __LINE__));
3233	    $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ;
3234#	    push(@lines, &debug("<BLOCKQUOTE>\n", __LINE__))
3235#	      if $tag =~ /example/i;
3236	    # sunshine@sunshineco.com: <PRE>bla</PRE> looks better than
3237	    # <PRE>\nbla</PRE> (at least on NeXTstep browser
3238	    push(@lines, &debug("<$format_map{$tag}>" . 
3239				($in_pre ? '' : "\n"), __LINE__));
3240	    next;
3241	}
3242	elsif (exists $complex_format_map->{$tag})
3243	{
3244	  my $start = eval $complex_format_map->{$tag}->[0];
3245	  if ($@)
3246	  {
3247	    print "$ERROR: eval of complex_format_map->{$tag}->[0] $complex_format_map->{$tag}->[0]: $@";
3248	    $start = '<pre>'
3249	  }
3250	  $in_pre = 1 if $start =~ /<pre/;
3251	  push(@lines, html_debug($start. ($in_pre ? '' : "\n"), __LINE__));
3252	  next;
3253	} elsif ($tag eq 'table') {
3254	  # anorland@hem2.passagen.se
3255	  # if (/^\s*\@(|f|v|multi)table\s+\@(\w+)/) {
3256	     if (/^\s*\@(|f|v|multi)table\s+\@(\w+)|(\{[^\}]*\})/) {
3257		$in_table = $2;
3258		unshift(@tables, join($;, $table_type, $in_table));
3259		if ($table_type eq "multi") {
3260		    # don't use borders -- gets confused by empty cells
3261		    push(@lines, &debug("<TABLE>\n", __LINE__));
3262		    &html_push_if('TABLE');
3263		} else {
3264		    push(@lines, &debug("<DL COMPACT>\n", __LINE__));
3265		    &html_push_if('DL');
3266		}
3267		push(@lines, &html_debug('', __LINE__));
3268	    } else {
3269		warn "$ERROR Bad table line: $_";
3270	    }
3271	    next;
3272	} 
3273	elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') 
3274	{
3275	  if (/^\@$tag\s+(\w+)\s+(\w+)\s*$/) 
3276	  {
3277	    my $from = $1;
3278	    my $to = $2;
3279	    my $prefix_from = IndexName2Prefix($from);
3280	    my $prefix_to = IndexName2Prefix($to);
3281
3282	    warn("$ERROR unknown from index name $from ind syn*index line: $_"), next
3283	      unless $prefix_from;
3284	    warn("$ERROR unknown to index name $to ind syn*index line: $_"), next
3285	      unless $prefix_to;
3286
3287	    if ($tag eq 'syncodeindex')
3288	    {
3289	      $index_properties->{$prefix_to}->{'from_code'}->{$prefix_from} = 1;
3290	    }
3291	    else
3292	    {
3293	       $index_properties->{$prefix_to}->{'from'}->{$prefix_from} = 1;
3294	    }
3295	  } 
3296	  else 
3297	  {
3298	    warn "$ERROR Bad syn*index line: $_";
3299	  }
3300	  next;
3301	} 
3302	elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') 
3303	{
3304	  if (/^\@$tag\s+(\w+)\s*$/) 
3305	  {
3306	    my $name = $1;
3307	    $index_properties->{$name}->{name} = $name;
3308	    $index_properties->{$name}->{code} = 1 if $tag eq 'defcodeindex';
3309	  } 
3310	  else 
3311	  {
3312	    warn "$ERROR Bad defindex line: $_";
3313	  }
3314	  next;
3315	}
3316	elsif (/^\@printindex/)
3317	{
3318	  push (@lines, "<!--::${section}::-->$_");
3319	  next;
3320	}
3321	elsif ($tag eq 'sp') {
3322	    push(@lines, &debug("<P>\n", __LINE__));
3323	    next;
3324	} elsif ($tag eq 'center') {
3325	    push(@lines, &debug("<center>\n", __LINE__));
3326	    s/\@center//;
3327	} elsif ($tag eq 'setref') {
3328	    &protect_html; # if setref contains '&' for instance
3329	    if (/^\@$tag\s*{($NODERE)}\s*$/) {
3330		$setref = $1;
3331		$setref =~ s/\s+/ /g; # normalize
3332		$setref =~ s/ $//;
3333		$node2sec{$setref} = $name;
3334		$sec2node{$name} = $setref;
3335		$node2href{$setref} = "$docu_doc#$docid";
3336	    } else {
3337		warn "$ERROR Bad setref line: $_";
3338	    }
3339	    next;
3340	} elsif ($tag eq 'lowersections') {
3341	    local ($sec, $level);
3342	    while (($sec, $level) = each %sec2level) {
3343		$sec2level{$sec} = $level + 1;
3344	    }
3345	    next;
3346	} elsif ($tag eq 'raisesections') {
3347	    local ($sec, $level);
3348	    while (($sec, $level) = each %sec2level) {
3349		$sec2level{$sec} = $level - 1;
3350	    }
3351	    next;
3352	}
3353	elsif ($tag eq 'macro' || $tag eq 'rmacro')
3354	{
3355	  if (/^\@$tag\s*(\w+)\s*(.*)/)
3356	  {
3357	    my $name = $1;
3358	    my @args;
3359	    @args = split(/\s*,\s*/ , $1)
3360	      if ($2 =~ /^\s*{(.*)}\s*/);
3361	    
3362	    $macros->{$name}->{Args} = \@args;
3363	    $macros->{$name}->{Body} = '';
3364	    while (($_ = &next_line) && $_ !~ /\@end $tag/)
3365	    {
3366	      $macros->{$name}->{Body} .= $_;
3367	    }
3368	    die "ERROR: No closing '\@end $tag' found for macro definition of '$name'\n"
3369	      unless (/\@end $tag/);
3370	    chomp $macros->{$name}->{Body};
3371	  }
3372	  else
3373	  {
3374	    warn "$ERROR: Bad macro defintion $_"
3375	  }
3376	  next;
3377	}
3378	elsif ($tag eq 'unmacro')
3379	{
3380	  delete $macros->{$1} if (/^\@unmacro\s*(\w+)/);
3381	  next;
3382	}
3383	elsif ($tag eq 'documentlanguage')
3384	{
3385	  SetDocumentLanguage($1) if (!$T2H_LANG && /documentlanguage\s*(\w+)/);
3386	}
3387	elsif (defined($def_map{$tag})) {
3388	    if ($def_map{$tag}) {
3389		s/^\@$tag\s+//;
3390		$tag = $def_map{$tag};
3391		$_ = "\@$tag $_";
3392		$tag =~ s/\s.*//;
3393	    }
3394	} elsif (defined($user_sub{$tag})) {
3395	    s/^\@$tag\s+//;
3396	    $sub = $user_sub{$tag};
3397	    print "# user $tag = $sub, arg: $_" if $T2H_DEBUG & $DEBUG_USER;
3398	    if (defined(&$sub)) {
3399		chop($_);
3400		&$sub($_);
3401	    } else {
3402		warn "$ERROR Bad user sub for $tag: $sub\n";
3403	    }
3404	    next;
3405	  } 
3406	if (defined($def_map{$tag})) {
3407	    s/^\@$tag\s+//;
3408	    if ($tag =~ /x$/) {
3409		# extra definition line
3410		$tag = $`;
3411		$is_extra = 1;
3412	    } else {
3413		$is_extra = 0;
3414	    }
3415	    while (/\{([^\{\}]*)\}/) {
3416		# this is a {} construct
3417		($before, $contents, $after) = ($`, $1, $');
3418		# protect spaces
3419		$contents =~ s/\s+/$;9/g;
3420		# restore $_ protecting {}
3421		$_ = "$before$;7$contents$;8$after";
3422	    }
3423	    @args = split(/\s+/, &protect_html($_));
3424	    foreach (@args) {
3425		s/$;9/ /g;	# unprotect spaces
3426		s/$;7/\{/g;	# ... {
3427		s/$;8/\}/g;	# ... }
3428	    }
3429	    $type = shift(@args);
3430	    $type =~ s/^\{(.*)\}$/$1/;
3431	    print "# def ($tag): {$type} ", join(', ', @args), "\n"
3432		if $T2H_DEBUG & $DEBUG_DEF;
3433	    $type .= ':'; # it's nicer like this
3434	    my $name = shift(@args);
3435	    $name =~ s/^\{(.*)\}$/$1/;
3436	    if ($is_extra) {
3437		$_ = &debug("<DT>", __LINE__);
3438	    } else {
3439		$_ = &debug("<DL>\n<DT>", __LINE__);
3440	    }
3441	    if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') {
3442		$_ .= "<U>$type</U> <B>$name</B>";
3443		$_ .= " <I>@args</I>" if @args;
3444	    } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr'
3445		     || $tag eq 'defcv' || $tag eq 'defop') {
3446		$ftype = $name;
3447		$name = shift(@args);
3448		$name =~ s/^\{(.*)\}$/$1/;
3449		$_ .= "<U>$type</U> $ftype <B>$name</B>";
3450		$_ .= " <I>@args</I>" if @args;
3451	    } else {
3452		warn "$ERROR Unknown definition type: $tag\n";
3453		$_ .= "<U>$type</U> <B>$name</B>";
3454		$_ .= " <I>@args</I>" if @args;
3455	    }
3456 	    $_ .= &debug("\n<DD>", __LINE__);
3457	    $name = &unprotect_html($name);
3458	    if ($tag eq 'deffn' || $tag eq 'deftypefn') {
3459	      EnterIndexEntry('f', $name, $docu_doc, $section, \@lines);
3460#		unshift(@input_spool, "\@findex $name\n");
3461	    } elsif ($tag eq 'defop') {
3462	      EnterIndexEntry('f', "$name on $ftype", $docu_doc, $section, \@lines);
3463#		unshift(@input_spool, "\@findex $name on $ftype\n");
3464	    } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') {
3465	      EnterIndexEntry('v', $name, $docu_doc, $section, \@lines);
3466#		unshift(@input_spool, "\@vindex $name\n");
3467	    } else {
3468	      EnterIndexEntry('t', $name, $docu_doc, $section, \@lines);
3469#		unshift(@input_spool, "\@tindex $name\n");
3470	    }
3471	    $dont_html = 1;
3472	}
3473    } elsif ($end_tag) {
3474	if ($format_map{$end_tag}) {
3475	    $in_pre = 0 if $format_map{$end_tag} eq 'PRE';
3476	    $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ;
3477	    &html_pop_if('P');
3478	    &html_pop_if('LI');
3479	    &html_pop_if();
3480	    push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__));
3481	    push(@lines, &html_debug('', __LINE__));
3482	}
3483	elsif (exists $complex_format_map->{$end_tag})
3484	{
3485	  my $end = eval $complex_format_map->{$end_tag}->[1];
3486	  if ($@)
3487	  {
3488	    print "$ERROR: eval of complex_format_map->{$end_tag}->[1] $complex_format_map->{$end_tag}->[0]: $@";
3489	    $end = '</pre>'
3490	  }
3491	  $in_pre = 0 if $end =~ m|</pre>|;
3492	  push(@lines, html_debug($end, __LINE__));
3493	} elsif ($end_tag =~ /^(|f|v|multi)table$/) {
3494	    unless (@tables) {
3495		warn "$ERROR \@end $end_tag without \@*table\n";
3496		next;
3497	    }
3498	    &html_pop_if('P');
3499	    ($table_type, $in_table) = split($;, shift(@tables));
3500	    unless ($1 eq $table_type) {
3501		warn "$ERROR \@end $end_tag without matching \@$end_tag\n";
3502		next;
3503	    }
3504	    if ($table_type eq "multi") {
3505		push(@lines, "</TR></TABLE>\n");
3506		&html_pop_if('TR');
3507	    } else {
3508		push(@lines, "</DL>\n");
3509		&html_pop_if('DD');
3510	    }
3511	    &html_pop_if();
3512	    if (@tables) {
3513		($table_type, $in_table) = split($;, $tables[0]);
3514	    } else {
3515		$in_table = 0;
3516	    }
3517	} elsif (defined($def_map{$end_tag})) {
3518 	    push(@lines, &debug("</DL>\n", __LINE__));
3519	} elsif ($end_tag eq 'menu') {
3520	    &html_pop_if();
3521	    push(@lines, $_); # must keep it for pass 2
3522	} 
3523	next;
3524    }
3525    #############################################################
3526    # anchor insertion
3527    while (/\@anchor\s*\{(.*?)\}/)
3528    {
3529      $_ = $`.$';
3530      my $anchor = $1;
3531      $anchor = &normalise_node($anchor);
3532      push @lines, &html_debug("<A NAME=\"$anchor\"></A>\n");
3533      $node2href{$anchor} = "$docu_doc#$anchor";
3534      next INPUT_LINE if $_ =~ /^\s*$/;
3535    }
3536
3537    #############################################################
3538    # index entry generation, after value substitutions
3539    if (/^\@(\w+?)index\s+/)
3540    {
3541      EnterIndexEntry($1, $', $docu_doc, $section, \@lines);
3542      next;
3543    }
3544    #
3545    # protect texi and HTML things
3546    &protect_texi;
3547    $_ = &protect_html($_) unless $dont_html;
3548    $dont_html = 0;
3549    # substitution (unsupported things)
3550    s/^\@exdent\s+//g;
3551    s/\@noindent\s+//g;
3552    s/\@refill\s+//g;
3553    # other substitutions
3554    &simple_substitutions;
3555    s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
3556    #
3557    # analyze the tag again
3558    #
3559    if ($tag) {
3560      if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) {
3561	    if (/^\@$tag\s+(.+)$/) {
3562		$name = $1;
3563		$name = &normalise_node($name);
3564		$level = $sec2level{$tag};
3565		# check for index
3566		$first_index_chapter = $node
3567		  if ($level == 1 && !$first_index_chapter && 
3568		      $name =~ /index/i);
3569		if ($in_top && /heading/){
3570		    $T2H_HAS_TOP_HEADING = 1;
3571                    $_ = &debug("<H$level>$name</H$level>\n", __LINE__);
3572		    &html_push_if('body');
3573		    print "# top heading, section $name, level $level\n"
3574			if $T2H_DEBUG & $DEBUG_TOC;
3575		}
3576		else
3577		{
3578		  unless (/^\@\w*heading/)
3579		  {
3580		    unless (/^\@unnumbered/)
3581		    {
3582		      my $number = &update_sec_num($tag, $level);
3583		      $name = $number. ' ' . $name if $T2H_NUMBER_SECTIONS;
3584		      $sec2number{$name} = $number;
3585		      $number2sec{$number} = $name;
3586		    }
3587		    if (defined($toplevel))
3588		    {
3589		      push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND);
3590		    }
3591		    else
3592		    {
3593		      # first time we see a "section"
3594		      unless ($level == 1) 
3595		      {
3596			warn "$WARN The first section found is not of level 1: $_";
3597		      }
3598		      $toplevel = $level;
3599		    }
3600		    push(@sections, $name);
3601		    next_doc() if ($T2H_SPLIT eq 'section' ||
3602				   $T2H_SPLIT && $level == $toplevel);
3603		  }
3604		  $sec_num++;
3605		  $docid = "SEC$sec_num";
3606		  $tocid = (/^\@\w*heading/ ? undef : "TOC$sec_num");
3607		  # check biblio and glossary
3608		  $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i);
3609		  $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i);
3610		  # check node
3611		  if ($node)
3612		  {
3613		    warn "$ERROR Duplicate node found: $node\n"
3614		      if ($node2sec{$node});
3615		  }
3616		  else
3617		  {
3618		    $name .= ' ' while ($node2sec{$name});
3619		    $node = $name;
3620		  }
3621		  $name .= ' ' while ($sec2node{$name});
3622		  $section = $name; 
3623		  $node2sec{$node} = $name;
3624		  $sec2node{$name} = $node;
3625		  $node2href{$node} = "$docu_doc#$docid";
3626		  $node2next{$node} = $node_next;
3627		  $node2prev{$node} = $node_prev;
3628		  $node2up{$node} = $node_up;
3629		  print "# node $node, section $name, level $level\n"
3630		    if $T2H_DEBUG & $DEBUG_TOC;
3631
3632		  $node = '';
3633		  $node_next = '';
3634		  $node_prev = '';
3635		  $node_next = '';
3636		  if ($tocid)
3637		  {
3638		    # update TOC
3639		    while ($level > $curlevel) {
3640		      $curlevel++;
3641		      push(@toc_lines, "<UL>\n");
3642		    }
3643		    while ($level < $curlevel) {
3644		      $curlevel--;
3645		      push(@toc_lines, "</UL>\n");
3646		    }
3647		    $_ = &t2h_anchor($tocid, "$docu_doc#$docid", $name, 1);
3648		    $_ = &substitute_style($_);
3649		    push(@stoc_lines, "$_<BR>\n") if ($level == 1);
3650		    if ($T2H_NUMBER_SECTIONS)
3651		    {
3652		      push(@toc_lines, $_ . "<BR>\n")
3653		    }
3654		    else
3655		    {
3656		      push(@toc_lines, "<LI>" . $_ ."</LI>");
3657		    }
3658		  }
3659		  else
3660		  {
3661		    push(@lines, &html_debug("<A NAME=\"$docid\"></A>\n", 
3662					   __LINE__));
3663		  }
3664		  # update DOC
3665		  push(@lines, &html_debug('', __LINE__));
3666		  &html_reset;
3667		  $_ =  "<H$level> $name </H$level>\n<!--docid::${docid}::-->\n";
3668		  $_ = &debug($_, __LINE__);
3669		  push(@lines, &html_debug('', __LINE__));
3670		}
3671		# update DOC
3672		foreach $line (split(/\n+/, $_)) {
3673		    push(@lines, "$line\n");
3674		}
3675		next;
3676	    } else {
3677		warn "$ERROR Bad section line: $_";
3678	    }
3679	} else {
3680	    # track variables
3681	    $value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o;
3682	    delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o;
3683	    # store things
3684	    $value{'_shorttitle'} = Unprotect_texi($1), next if /^\@shorttitle\s+(.*)$/;
3685	    $value{'_setfilename'}   = Unprotect_texi($1), next if /^\@setfilename\s+(.*)$/;
3686	    $value{'_settitle'}      = Unprotect_texi($1), next if /^\@settitle\s+(.*)$/;
3687	    $value{'_author'}   .= Unprotect_texi($1)."\n", next if /^\@author\s+(.*)$/;
3688	    $value{'_subtitle'} .= Unprotect_texi($1)."\n", next if /^\@subtitle\s+(.*)$/;
3689	    $value{'_title'}    .= Unprotect_texi($1)."\n", next if /^\@title\s+(.*)$/;
3690
3691	    # list item
3692	    if (/^\s*\@itemx?\s+/) {
3693		$what = $';
3694		$what =~ s/\s+$//;
3695		if ($in_bibliography && $use_bibliography) {
3696		    if ($what =~ /^$BIBRE$/o) {
3697			$id = 'BIB' . ++$bib_num;
3698			$bib2href{$what} = "$docu_doc#$id";
3699			print "# found bibliography for '$what' id $id\n"
3700			    if $T2H_DEBUG & $DEBUG_BIB;
3701			$what = &t2h_anchor($id, '', $what);
3702		    }
3703		} elsif ($in_glossary && $T2H_USE_GLOSSARY) {
3704		    $id = 'GLOSS' . ++$gloss_num;
3705		    $entry = $what;
3706		    $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
3707		    $gloss2href{$entry} = "$docu_doc#$id";
3708		    print "# found glossary for '$entry' id $id\n"
3709			if $T2H_DEBUG & $DEBUG_GLOSS;
3710		    $what = &t2h_anchor($id, '', $what);
3711		}
3712		elsif ($in_table && ($table_type eq 'f' || $table_type eq 'v'))
3713		{
3714		  EnterIndexEntry($table_type, $what, $docu_doc, $section, \@lines);
3715		}
3716		&html_pop_if('P');
3717		if ($html_element eq 'DL' || $html_element eq 'DD') {
3718		    if ($things_map{$in_table} && !$what) {
3719			# special case to allow @table @bullet for instance
3720			push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__));
3721		    } else {
3722			push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__));
3723		    }
3724		    push(@lines, "<DD>");
3725		    &html_push('DD') unless $html_element eq 'DD';
3726		    if ($table_type) { # add also an index
3727			unshift(@input_spool, "\@${table_type}index $what\n");
3728		    }
3729		} elsif ($html_element eq 'TABLE') {
3730		    push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
3731		    &html_push('TR');
3732		} elsif ($html_element eq 'TR') {
3733		    push(@lines, &debug("</TR>\n", __LINE__));
3734		    push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
3735		} else {
3736		    push(@lines, &debug("<LI>$what\n", __LINE__));
3737		    &html_push('LI') unless $html_element eq 'LI';
3738		}
3739		push(@lines, &html_debug('', __LINE__));
3740		if ($deferred_ref) {
3741		    push(@lines, &debug("$deferred_ref\n", __LINE__));
3742		    $deferred_ref = '';
3743		}
3744		next;
3745	    } elsif (/^\@tab\s+(.*)$/) {
3746		push(@lines, "<TD>$1</TD>\n");
3747		next;
3748	    }
3749	}
3750    }
3751    # paragraph separator
3752    if ($_ eq "\n" && ! $in_pre) {
3753	next if $#lines >= 0 && $lines[$#lines] eq "\n";
3754	if ($html_element eq 'P') {
3755	    push (@lines, &debug("</P><P>\n", __LINE__));
3756	}
3757# 	else
3758# 	{
3759# 	  push(@lines, "<P></P>\n");
3760# 	  $_ = &debug("<P></P>\n", __LINE__);
3761# 	}
3762        elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'DD' || $html_element eq 'LI') 
3763	{
3764	  &html_push('P');
3765	  push(@lines, &debug("<P>\n", __LINE__));
3766	}
3767      }
3768    # otherwise
3769    push(@lines, $_) unless $in_titlepage;
3770    push(@lines, &debug("</center>\n", __LINE__))  if ($tag eq 'center');
3771}
3772
3773# finish TOC
3774$level = 0;
3775while ($level < $curlevel) {
3776    $curlevel--;
3777    push(@toc_lines, "</UL>\n");
3778}
3779
3780print "# end of pass 1\n" if $T2H_VERBOSE;
3781
3782SetDocumentLanguage('en') unless ($T2H_LANG);
3783#+++############################################################################
3784#                                                                              #
3785# Stuff related to Index generation                                            #
3786#                                                                              #
3787#---############################################################################
3788
3789sub EnterIndexEntry
3790{
3791  my $prefix = shift;
3792  my $key = shift;
3793  my $docu_doc = shift;
3794  my $section = shift;
3795  my $lines = shift;
3796  local $_;
3797
3798  warn "$ERROR Undefined index command: $_", next
3799    unless (exists ($index_properties->{$prefix}));
3800  $key =~ s/\s+$//;
3801  $_ = $key;
3802  &protect_texi;
3803  $key = $_;
3804  $_ = &protect_html($_);
3805  my $html_key = substitute_style($_);
3806  my $id;
3807  $key = remove_style($key);
3808  $key = remove_things($key);
3809  $_ = $key;
3810  &unprotect_texi;
3811  $key = $_;
3812  while (exists $index->{$prefix}->{$key}) {$key .= ' '};
3813  if ($lines->[$#lines] =~ /^<!--docid::(.+)::-->$/)
3814  {
3815    $id = $1;
3816  }
3817  else
3818  {
3819    $id = 'IDX' . ++$idx_num;
3820    push(@$lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre));
3821  }
3822  $index->{$prefix}->{$key}->{html_key} = $html_key;
3823  $index->{$prefix}->{$key}->{section} = $section;
3824  $index->{$prefix}->{$key}->{href} = "$docu_doc#$id";
3825  print "# found ${prefix}index  for '$key' with id $id\n"
3826    if $T2H_DEBUG & $DEBUG_INDEX;
3827}
3828
3829sub IndexName2Prefix
3830{
3831  my $name = shift;
3832  my $prefix;
3833
3834  for $prefix (keys %$index_properties)
3835  {
3836    return $prefix if ($index_properties->{$prefix}->{name} eq $name);
3837  }
3838  return undef;
3839}
3840
3841sub GetIndexEntries
3842{
3843  my $normal = shift;
3844  my $code = shift;
3845  my ($entries, $prefix, $key) = ({});
3846  
3847  for $prefix (keys %$normal)
3848  {
3849    for $key (keys %{$index->{$prefix}})
3850    {
3851      $entries->{$key} = {%{$index->{$prefix}->{$key}}};
3852    }
3853  }
3854
3855  if (defined($code))
3856  {
3857    for $prefix (keys %$code)
3858    {
3859      unless (exists $normal->{$keys})
3860      {
3861	for $key (keys %{$index->{$prefix}})
3862	{
3863	  $entries->{$key} = {%{$index->{$prefix}->{$key}}};
3864	  $entries->{$key}->{html_key} = "<CODE>$entries->{$key}->{html_key}</CODE>";
3865	}
3866      }
3867    }
3868  }
3869  return $entries;
3870}
3871
3872sub byAlpha
3873{
3874  if ($a =~ /^[A-Za-z]/)
3875  {
3876    if ($b =~ /^[A-Za-z]/)
3877    {
3878      return lc($a) cmp lc($b);
3879    }
3880    else
3881    {
3882      return 1;
3883    }
3884  }
3885  elsif ($b =~ /^[A-Za-z]/)
3886  {
3887    return -1;
3888  }
3889  else
3890  {
3891    return lc($a) cmp lc($b);
3892  } 
3893}
3894
3895sub GetIndexPages
3896{
3897  my $entries = shift;
3898  my (@Letters, $key);
3899  my ($EntriesByLetter, $Pages, $page) = ({}, [], {});
3900  my @keys = sort byAlpha keys %$entries;
3901
3902  for $key (@keys)
3903  {
3904    push @{$EntriesByLetter->{uc(substr($key,0, 1))}} , $entries->{$key};
3905  }
3906  @Letters = sort byAlpha keys %$EntriesByLetter;
3907  
3908  $T2H_SPLIT_INDEX = 0 unless ($T2H_SPLIT);
3909
3910  unless ($T2H_SPLIT_INDEX)
3911  {
3912    $page->{First} = $Letters[0];
3913    $page->{Last} = $Letters[$#Letters];
3914    $page->{Letters} = \@Letters;
3915    $page->{EntriesByLetter} = $EntriesByLetter;
3916    push @$Pages, $page;
3917    return $Pages;
3918  }
3919
3920  if ($T2H_SPLIT_INDEX =~ /^\d+$/)
3921  {
3922    my $i = 0;
3923    my ($prev_letter, $letter);
3924    $page->{First} = $Letters[0];
3925    for $letter (@Letters)
3926    {
3927      if ($i > $T2H_SPLIT_INDEX)
3928      {
3929	$page->{Last} = $prev_letter;
3930	push @$Pages, {%$page};
3931	$page->{Letters} = [];
3932	$page->{EntriesByLetter} = {};
3933	$page->{First} = $letter;
3934	$i=0;
3935      }
3936      push @{$page->{Letters}}, $letter;
3937      $page->{EntriesByLetter}->{$letter} = [@{$EntriesByLetter->{$letter}}];
3938      $i += scalar(@{$EntriesByLetter->{$letter}});
3939      $prev_letter = $letter;
3940    }
3941    $page->{Last} = $Letters[$#Letters];
3942    push @$Pages, {%$page};
3943  }
3944  return $Pages;
3945}
3946
3947sub GetIndexSummary
3948{
3949  my $first_page = shift;
3950  my $Pages = shift;
3951  my $name = shift;
3952  my ($page, $letter, $summary, $i, $l1, $l2, $l);
3953
3954  $i = 0;
3955  $summary = '<table><tr><th valign=top>Jump to: &nbsp; </th><td>';
3956  
3957  for $page ($first_page, @$Pages)
3958  {
3959    for $letter (@{$page->{Letters}})
3960    {
3961      $l = t2h_anchor('', "$page->{href}#${name}_$letter", "<b>$letter</b>", 
3962		      0, 'style="text-decoration:none"') . "\n &nbsp; \n";
3963      
3964      if ($letter =~ /^[A-Za-z]/)
3965      {
3966	$l2 .= $l;
3967      }
3968      else
3969      {
3970	$l1 .= $l;
3971      }
3972    }
3973  }
3974  $summary .= $l1 . "<BR>\n" if ($l1);
3975  $summary .= $l2 . '</td></tr></table><br>';
3976  return $summary;
3977}
3978
3979sub PrintIndexPage
3980{
3981  my $lines = shift;
3982  my $summary = shift;
3983  my $page = shift;
3984  my $name = shift;
3985
3986  push @$lines, $summary;
3987
3988  push @$lines , <<EOT;
3989<P></P>
3990<TABLE border=0>
3991<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> Section</TH></TR>
3992<TR><TD COLSPAN=3> <HR></TD></TR>
3993EOT
3994
3995  for $letter (@{$page->{Letters}})
3996  {
3997    push @$lines, "<TR><TH><A NAME=\"${name}_$letter\"></A>$letter</TH><TD></TD><TD></TD></TR>\n";
3998    for $entry (@{$page->{EntriesByLetter}->{$letter}})
3999    {
4000      push @$lines, 
4001      "<TR><TD></TD><TD valign=top>" . 
4002	t2h_anchor('', $entry->{href}, $entry->{html_key}) .
4003	  "</TD><TD valign=top>" . 
4004	    t2h_anchor('', sec_href($entry->{section}), clean_name($entry->{section})) .
4005	      "</TD></TR>\n";
4006    }
4007    push @$lines, "<TR><TD COLSPAN=3> <HR></TD></TR>\n";
4008  }
4009  push @$lines, "</TABLE><P></P>";
4010  push @$lines, $summary;
4011}
4012
4013sub PrintIndex
4014{
4015  my $lines = shift;
4016  my $name = shift;
4017  my $section = shift;
4018  $section = 'Top' unless $section;
4019  my $prefix = IndexName2Prefix($name);
4020
4021  warn ("$ERROR printindex: bad index name: $name"), return 
4022    unless $prefix;
4023
4024  if ($index_properties->{$prefix}->{code})
4025  {
4026    $index_properties->{$prefix}->{from_code}->{$prefix} = 1;
4027  }
4028  else
4029  {
4030    $index_properties->{$prefix}->{from}->{$prefix}= 1;
4031  }
4032
4033  my $Entries = GetIndexEntries($index_properties->{$prefix}->{from}, 
4034				$index_properties->{$prefix}->{from_code});
4035  return unless %$Entries;
4036
4037  if ($T2H_IDX_SUMMARY)
4038  {
4039    my $key;
4040    open(FHIDX, ">$docu_rdir$docu_name" . "_$name.idx")
4041      || die "Can't open > $docu_rdir$docu_name" . "_$name.idx for writing: $!\n";
4042    print "# writing $name index summary in $docu_rdir$docu_name" . "_$name.idx...\n" if $T2H_VERBOSE;
4043
4044    for $key (sort keys %$Entries)
4045    {
4046      print FHIDX "$key\t$Entries->{$key}->{href}\n";
4047    }
4048  }
4049
4050  my $Pages = GetIndexPages($Entries);
4051  my $page;
4052  my $first_page = shift @$Pages;
4053  my $sec_name = $section;
4054  # remove section number
4055  $sec_name =~ s/.*? // if $sec_name =~ /^([A-Z]|\d+)\./;
4056
4057  ($first_page->{href} = sec_href($section)) =~ s/\#.*$//;
4058  # Update tree structure of document
4059  if (@$Pages)
4060  {
4061    my $sec;
4062    my @after;
4063
4064    while (@sections && $sections[$#sections] ne $section)
4065    {
4066      unshift @after, pop @sections;
4067    }
4068
4069    for $page (@$Pages)
4070    {
4071      my $node = ($page->{First} ne $page->{Last} ? 
4072		  "$sec_name: $page->{First} -- $page->{Last}" :
4073		  "$sec_name: $page->{First}");
4074      push @sections, $node;
4075      $node2sec{$node} = $node;
4076      $sec2node{$node} = $node;
4077      $node2up{$node} = $section;
4078      $page->{href} = next_doc();
4079      $page->{name} = $node;
4080      $node2href{$node} = $page->{href};
4081      if ($prev_node)
4082      {
4083	$node2next{$prev_node} = $node;
4084	$node2prev{$node} = $prev_node;
4085      }
4086      $prev_node = $node;
4087    }
4088    push @sections, @after;
4089  }
4090
4091  my $summary = GetIndexSummary($first_page, $Pages, $name);
4092  PrintIndexPage($lines, $summary, $first_page, $name);
4093  for $page (@$Pages)
4094  {
4095    push @$lines, ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND);
4096    push @$lines, "<H2 ALIGN=\"Left\">$page->{name}</H2>\n";
4097    PrintIndexPage($lines, $summary, $page, $name);
4098  }
4099}
4100
4101
4102#+++############################################################################
4103#                                                                              #
4104# Pass 2/3: handle style, menu, index, cross-reference                         #
4105#                                                                              #
4106#---############################################################################
4107
4108@lines2 = ();				# whole document (2nd pass)
4109@lines3 = ();				# whole document (3rd pass)
4110$in_menu = 0;				# am I inside a menu
4111
4112while (@lines) {
4113    $_ = shift(@lines);
4114    #
4115    # special case (protected sections)
4116    #
4117    if (/^$PROTECTTAG/o) {
4118	push(@lines2, $_);
4119	next;
4120    }
4121    #
4122    # menu
4123    #
4124    if (/^\@menu\b/)
4125    {
4126      $in_menu = 1;
4127      $in_menu_listing = 1;
4128      push(@lines2, &debug("<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> \n", __LINE__));
4129      next;
4130    }
4131    if (/^\@end\s+menu\b/)
4132    {
4133      if ($in_menu_listing)
4134      {
4135	push(@lines2, &debug("</TABLE></BLOCKQUOTE>\n", __LINE__));
4136      }
4137      else
4138      {
4139	push(@lines2, &debug("</BLOCKQUOTE>\n", __LINE__));
4140      }
4141      $in_menu = 0;
4142      $in_menu_listing = 0;
4143      next;
4144    }
4145    if ($in_menu) 
4146    {
4147      my ($node, $name, $descr);
4148      if (/^\*\s+($NODERE)::/o)
4149      {
4150	$node = $1;
4151	$descr = $';
4152      }
4153      elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/)
4154      {
4155	$name = $1;
4156	$node = $2;
4157	$descr = $';
4158      }
4159      elsif (/^\*/) 
4160      {
4161	warn "$ERROR Bad menu line: $_";
4162      }
4163      else
4164      {
4165	if ($in_menu_listing)
4166	{
4167	  $in_menu_listing = 0;
4168	  push(@lines2, &debug("</TABLE>\n", __LINE__));
4169	}
4170	# should be like verbatim -- preseve spaces, etc
4171	s/ /\&nbsp;/g;
4172	$_ .= "<br>\n";
4173	push(@lines2, $_);
4174      }
4175      if ($node)
4176      {
4177	if (! $in_menu_listing)
4178	{
4179	  $in_menu_listing = 1;
4180	  push(@lines2, &debug("<TABLE BORDER=0 CELLSPACING=0>\n", __LINE__));
4181	}
4182	# look for continuation
4183	while ($lines[0] =~ /^\s+\w+/)
4184	{
4185	  $descr .= shift(@lines);
4186	}
4187	&menu_entry($node, $name, $descr);
4188      } 
4189      next;
4190    }
4191    #
4192    # printindex
4193    #
4194    PrintIndex(\@lines2, $2, $1), next
4195      if (/^<!--::(.*)::-->\@printindex\s+(\w+)/);
4196    #
4197    # simple style substitutions
4198    #
4199    $_ = &substitute_style($_);
4200    #
4201    # xref
4202    #
4203    while (/\@(x|px|info|)ref{([^{}]+)(}?)/) {
4204	# note: Texinfo may accept other characters
4205	($type, $nodes, $full) = ($1, $2, $3);
4206	($before, $after) = ($`, $');
4207	if (! $full && $after) {
4208	    warn "$ERROR Bad xref (no ending } on line): $_";
4209	    $_ = "$before$;0${type}ref\{$nodes$after";
4210	    next; # while xref
4211	}
4212	if ($type eq 'x') {
4213	    $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} ";
4214	} elsif ($type eq 'px') {
4215	    $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} ";
4216	} elsif ($type eq 'info') {
4217	    $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info";
4218	} else {
4219	    $type = '';
4220	}
4221	unless ($full) {
4222	    $next = shift(@lines);
4223	    $next = &substitute_style($next);
4224	    chop($nodes); # remove final newline
4225	    if ($next =~ /\}/) { # split on 2 lines
4226		$nodes .= " $`";
4227		$after = $';
4228	    } else {
4229		$nodes .= " $next";
4230		$next = shift(@lines);
4231		$next = &substitute_style($next);
4232		chop($nodes);
4233		if ($next =~ /\}/) { # split on 3 lines
4234		    $nodes .= " $`";
4235		    $after = $';
4236		} else {
4237		    warn "$ERROR Bad xref (no ending }): $_";
4238		    $_ = "$before$;0xref\{$nodes$after";
4239		    unshift(@lines, $next);
4240		    next; # while xref
4241		}
4242	    }
4243	}
4244	$nodes =~ s/\s+/ /g; # remove useless spaces
4245	@args = split(/\s*,\s*/, $nodes);
4246	$node = $args[0]; # the node is always the first arg
4247	$node = &normalise_node($node);
4248	$sec = $args[2] || $args[1] || $node2sec{$node};
4249	$href = $node2href{$node};
4250	if (@args == 5) { # reference to another manual
4251	    $sec = $args[2] || $node;
4252	    $man = $args[4] || $args[3];
4253	    $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after";
4254	} elsif ($type =~ /Info/) { # inforef
4255	    warn "$ERROR Wrong number of arguments: $_" unless @args == 3;
4256	    ($nn, $_, $in) = @args;
4257	    $_ = "${before}${type} file `$in', node `$nn'$after";
4258	} elsif ($sec && $href && ! $T2H_SHORT_REF) {
4259	    $_  = "${before}${type}";
4260	    $_ .= "$T2H_WORDS->{$T2H_LANG}->{'section'} " if ${type};
4261	    $_ .= &t2h_anchor('', $href, $sec) . $after;
4262	} 
4263	elsif ($href)
4264	{
4265	  $_ = "${before}${type} " . 
4266	    &t2h_anchor('', $href, $args[2] || $args[1] || $node) . 
4267	      $after;
4268	}
4269	else {
4270	    warn "$ERROR Undefined node ($node): $_";
4271	    $_ = "$before$;0xref{$nodes}$after";
4272	}
4273    }
4274
4275    # replace images
4276    s[\@image\s*{(.+?)}]
4277    {
4278     my @args = split (/\s*,\s*/, $1);
4279     my $base = $args[0];
4280     my $image = 
4281       LocateIncludeFile("$base.png") || 
4282       LocateIncludeFile("$base.jpg") ||
4283       LocateIncludeFile("$base.gif");
4284     warn "$ERROR no image file for $base: $_" unless ($image && -e $image);
4285     "<IMG SRC=\"$image\" ALT=\"$base\">";
4286     ($T2H_CENTER_IMAGE ?
4287      "<CENTER><IMG SRC=\"$image\" ALT=\"$base\"></CENTER>" :
4288      "<IMG SRC=\"$image\" ALT=\"$base\">");
4289    }eg;
4290
4291    #
4292    # try to guess bibliography references or glossary terms
4293    #
4294    unless (/^<H\d><A NAME=\"SEC\d/) {
4295	if ($use_bibliography) {
4296	    $done = '';
4297	    while (/$BIBRE/o) {
4298		($pre, $what, $post) = ($`, $&, $');
4299		$href = $bib2href{$what};
4300		if (defined($href) && $post !~ /^[^<]*<\/A>/) {
4301		    $done .= $pre . &t2h_anchor('', $href, $what);
4302		} else {
4303		    $done .= "$pre$what";
4304		}
4305		$_ = $post;
4306	    }
4307	    $_ = $done . $_;
4308	}
4309	if ($T2H_USE_GLOSSARY) {
4310	    $done = '';
4311	    while (/\b\w+\b/) {
4312		($pre, $what, $post) = ($`, $&, $');
4313		$entry = $what;
4314		$entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
4315		$href = $gloss2href{$entry};
4316		if (defined($href) && $post !~ /^[^<]*<\/A>/) {
4317		    $done .= $pre . &t2h_anchor('', $href, $what);
4318		} else {
4319		    $done .= "$pre$what";
4320		}
4321		$_ = $post;
4322	    }
4323	    $_ = $done . $_;
4324	}
4325    }
4326    # otherwise
4327    push(@lines2, $_);
4328}
4329print "# end of pass 2\n" if $T2H_VERBOSE;
4330
4331#
4332# split style substitutions
4333#
4334while (@lines2) {
4335    $_ = shift(@lines2);
4336    #
4337    # special case (protected sections)
4338    #
4339    if (/^$PROTECTTAG/o) {
4340	push(@lines3, $_);
4341	next;
4342    }
4343    #
4344    # split style substitutions
4345    #
4346    $old = '';
4347    while ($old ne $_) {
4348        $old = $_;
4349	if (/\@(\w+)\{/) {
4350	    ($before, $style, $after) = ($`, $1, $');
4351	    if (defined($style_map{$style})) {
4352		$_ = $after;
4353		$text = '';
4354		$after = '';
4355		$failed = 1;
4356		while (@lines2) {
4357		    if (/\}/) {
4358			$text .= $`;
4359			$after = $';
4360			$failed = 0;
4361			last;
4362		    } else {
4363			$text .= $_;
4364			$_ = shift(@lines2);
4365		    }
4366		}
4367		if ($failed) {
4368		    die "* Bad syntax (\@$style) after: $before\n";
4369		} else {
4370		    $text = &apply_style($style, $text);
4371		    $_ = "$before$text$after";
4372		}
4373	    }
4374	}
4375    }
4376    # otherwise
4377    push(@lines3, $_);
4378}
4379print "# end of pass 3\n" if $T2H_VERBOSE;
4380	
4381#+++############################################################################
4382#                                                                              #
4383# Pass 4: foot notes, final cleanup                                            #
4384#                                                                              #
4385#---############################################################################
4386
4387@foot_lines = ();			# footnotes
4388@doc_lines = ();			# final document
4389$end_of_para = 0;			# true if last line is <P>
4390	
4391while (@lines3) {
4392    $_ = shift(@lines3);
4393    #
4394    # special case (protected sections)
4395    #
4396    if (/^$PROTECTTAG/o) {
4397	push(@doc_lines, $_);
4398	$end_of_para = 0;
4399	next;
4400    }
4401    #
4402    # footnotes
4403    #
4404    while (/\@footnote([^\{\s]+)\{/) {
4405	($before, $d, $after) = ($`, $1, $');
4406	$_ = $after;
4407	$text = '';
4408	$after = '';
4409	$failed = 1;
4410	while (@lines3) {
4411	    if (/\}/) {
4412		$text .= $`;
4413		$after = $';
4414		$failed = 0;
4415		last;
4416	    } else {
4417		$text .= $_;
4418		$_ = shift(@lines3);
4419	    }
4420	}
4421	if ($failed) {
4422	    die "* Bad syntax (\@footnote) after: $before\n";
4423	} else {
4424	    $foot_num++;
4425	    $docid  = "DOCF$foot_num";
4426	    $footid = "FOOT$foot_num";
4427	    $foot = "($foot_num)";
4428	    push(@foot_lines, "<H3>" . &t2h_anchor($footid, "$d#$docid", $foot) . "</H3>\n");
4429	    $text = "<P>$text" unless $text =~ /^\s*<P>/;
4430	    push(@foot_lines, "$text\n");
4431	    $_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after;
4432	}
4433    }
4434    #
4435    # remove unnecessary <P>
4436    #
4437    if (/^\s*<P>\s*$/) {
4438	next if $end_of_para++;
4439    } else {
4440	$end_of_para = 0;
4441    }
4442    # otherwise
4443    push(@doc_lines, $_);
4444}
4445	
4446print "# end of pass 4\n" if $T2H_VERBOSE;
4447
4448#+++############################################################################
4449#                                                                              #
4450# Pass 5: print things                                                         #
4451#                                                                              #
4452#---############################################################################
4453
4454$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H);
4455$T2H_L2H = &l2h_ToHtml        if ($T2H_L2H);
4456$T2H_L2H = &l2h_InitFromHtml  if ($T2H_L2H);
4457
4458# fix node2up, node2prev, node2next, if desired
4459if ($has_top_command)
4460{
4461  for $section (keys %sec2number)
4462  {
4463    $node = $sec2node{$section};
4464    $node2up{$node} = Sec2UpNode($section) unless $node2up{$node};
4465    $node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node};
4466    $node2next{$node} = Sec2NextNode($section) unless $node2next{$node};
4467  }
4468}
4469
4470# prepare %T2H_THISDOC
4471$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
4472$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle};
4473$T2H_THISDOC{author} = $value{'_author'};
4474$T2H_THISDOC{subtitle} = $value{'_subtitle'};
4475$T2H_THISDOC{shorttitle} = $value{'_shorttitle'};
4476for $key (keys %T2H_THISDOC)
4477{
4478  $_ = &substitute_style($T2H_THISDOC{$key});
4479  &unprotect_texi;
4480  s/\s*$//;
4481  $T2H_THISDOC{$key} = $_;
4482}
4483
4484# if no sections, then simply print document as is
4485unless (@sections)
4486{
4487  print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE;
4488  open(FILE, "> $docu_top_file") 
4489    || die "$ERROR: Can't open $docu_top_file for writing: $!\n";
4490
4491  &$T2H_print_page_head(\*FILE);
4492  $T2H_THIS_SECTION = \@doc_lines;
4493  t2h_print_lines(\*FILE);
4494  &$T2H_print_foot_navigation(\*FILE);
4495  &$T2H_print_page_foot(\*FILE);
4496  close(FILE);
4497  goto Finish;
4498}
4499
4500# initialize $T2H_HREF, $T2H_NAME
4501%T2H_HREF = 
4502  (
4503   'First' ,   sec_href($sections[0]),
4504   'Last',     sec_href($sections[$#sections]),
4505   'About',     $docu_about. '#SEC_About',
4506  );
4507
4508# prepare TOC, OVERVIEW, TOP
4509$T2H_TOC = \@toc_lines;
4510$T2H_OVERVIEW = \@stoc_lines;
4511if ($has_top)
4512{
4513  while (1)
4514  {
4515    $_ = shift @doc_lines;
4516    last if /$TOPEND/;
4517    push @$T2H_TOP, $_;
4518  }
4519  $T2H_HREF{'Top'} = $docu_top . '#SEC_Top';
4520}
4521else
4522{
4523  $T2H_HREF{'Top'} = $T2H_HREF{First};
4524}
4525
4526$node2href{Top} = $T2H_HREF{Top};
4527$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines;
4528$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines;
4529
4530# settle on index
4531if ($T2H_INDEX_CHAPTER)
4532{
4533  $T2H_HREF{Index} = $node2href{normalise_node($T2H_INDEX_CHAPTER)};
4534  warn "$ERROR T2H_INDEX_CHAPTER '$T2H_INDEX_CHAPTER' not found\n"
4535    unless $T2H_HREF{Index};
4536}
4537if (! $T2H_HREF{Index} && $first_index_chapter)
4538{
4539  $T2H_INDEX_CHAPTER = $first_index_chapter;
4540  $T2H_HREF{Index} = $node2href{$T2H_INDEX_CHAPTER};
4541}
4542
4543print "# Using '" . clean_name($T2H_INDEX_CHAPTER) . "' as index page\n"
4544  if ($T2H_VERBOSE && $T2H_HREF{Index});
4545
4546%T2H_NAME =
4547  (
4548   'First',   clean_name($sec2node{$sections[0]}),
4549   'Last',    clean_name($sec2node{$sections[$#sections]}),
4550   'About',    $T2H_WORDS->{$T2H_LANG}->{'About_Title'},
4551   'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'},
4552   'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'},
4553   'Index' ,   clean_name($T2H_INDEX_CHAPTER),
4554   'Top',      clean_name($T2H_TOP_HEADING || $T2H_THISDOC{'title'} || $T2H_THISDOC{'shorttitle'}),
4555  );
4556
4557#############################################################################
4558# print frame and frame toc file
4559#
4560if ( $T2H_FRAMES )
4561{
4562  open(FILE, "> $docu_frame_file") 
4563    || die "$ERROR: Can't open $docu_frame_file for writing: $!\n";
4564  print "# Creating frame in $docu_frame_file ...\n" if $T2H_VERBOSE;
4565  &$T2H_print_frame(\*FILE);
4566  close(FILE);
4567
4568  open(FILE, "> $docu_toc_frame_file") 
4569    || die "$ERROR: Can't open $docu_toc_frame_file for writing: $!\n";
4570  print "# Creating toc frame in $docu_frame_file ...\n" if $T2H_VERBOSE;
4571   &$T2H_print_toc_frame(\*FILE);
4572  close(FILE);
4573}
4574
4575
4576#############################################################################
4577# print Top
4578#
4579open(FILE, "> $docu_top_file") 
4580  || die "$ERROR: Can't open $docu_top_file for writing: $!\n";
4581&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT);
4582
4583if ($has_top)
4584{
4585  print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE;
4586  $T2H_THIS_SECTION = $T2H_TOP;
4587  $T2H_HREF{This} = $T2H_HREF{Top};
4588  $T2H_NAME{This} = $T2H_NAME{Top};
4589  &$T2H_print_Top(\*FILE);
4590}
4591  
4592close(FILE) if $T2H_SPLIT;
4593
4594#############################################################################
4595# Print sections
4596#
4597$T2H_NODE{Forward} = $sec2node{$sections[0]};
4598$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]});
4599$T2H_HREF{Forward} = sec_href($sections[0]);
4600$T2H_NODE{This} = 'Top';
4601$T2H_NAME{This} = $T2H_NAME{Top};
4602$T2H_HREF{This} = $T2H_HREF{Top};
4603if ($T2H_SPLIT)
4604{
4605  print "# writing " . scalar(@sections) . 
4606    " sections in $docu_rdir$docu_name"."_[1..$doc_num]"
4607	  if $T2H_VERBOSE;
4608  $previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND);
4609  undef $FH;
4610  $doc_num = 0;
4611}
4612else
4613{
4614  print "# writing " . scalar(@sections) . " sections in $docu_top_file ..." 
4615    if $T2H_VERBOSE;
4616  $FH = \*FILE;
4617  $previous = '';
4618}
4619
4620$counter = 0;
4621# loop through sections
4622while ($section = shift(@sections)) 
4623{
4624  if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND))
4625  { 
4626    if ($FH)
4627    {
4628      #close previous page
4629      &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter';
4630      &$T2H_print_page_foot($FH);
4631      close($FH);
4632      undef $FH;
4633    }
4634  }
4635  $T2H_NAME{Back} = $T2H_NAME{This};
4636  $T2H_HREF{Back} = $T2H_HREF{This};
4637  $T2H_NODE{Back} = $T2H_NODE{This};
4638  $T2H_NAME{This} = $T2H_NAME{Forward};
4639  $T2H_HREF{This} = $T2H_HREF{Forward};
4640  $T2H_NODE{This} = $T2H_NODE{Forward};
4641  if ($sections[0])
4642  {
4643    $T2H_NODE{Forward} = $sec2node{$sections[0]};
4644    $T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward});
4645    $T2H_HREF{Forward} = sec_href($sections[0]);
4646  }
4647  else
4648  {
4649    undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward};
4650  }
4651
4652  $node = $node2up{$T2H_NODE{This}};
4653  $T2H_HREF{Up} = $node2href{$node};
4654  if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up})
4655  {
4656    $T2H_NAME{Up} = $T2H_NAME{Top};
4657    $T2H_HREF{Up} = $T2H_HREF{Top};
4658    $T2H_NODE{Up} = 'Up';
4659  }
4660  else
4661  {
4662    $T2H_NAME{Up} = &clean_name($node);
4663    $T2H_NODE{Up} = $node;
4664  }
4665
4666  $node = $T2H_NODE{This};
4667  $node = $node2prev{$node};
4668  $T2H_NAME{Prev} = &clean_name($node);
4669  $T2H_HREF{Prev} = $node2href{$node};
4670  $T2H_NODE{Prev} = $node;
4671
4672  $node = $T2H_NODE{This};
4673  if ($node2up{$node} && $node2up{$node} ne 'Top'&&
4674      ($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node}))
4675  {
4676    $node = $node2up{$node};
4677    while ($node && $node ne $node2up{$node} && ! $node2prev{$node})
4678    {
4679      $node = $node2up{$node};
4680    }
4681    $node = $node2prev{$node} 
4682      unless $node2up{$node} eq 'Top' || ! $node2up{$node};
4683  }
4684  else
4685  {
4686    $node = $node2prev{$node};
4687  }
4688  $T2H_NAME{FastBack} = &clean_name($node);
4689  $T2H_HREF{FastBack} = $node2href{$node};
4690  $T2H_NODE{FastBack} = $node;
4691  
4692  $node = $T2H_NODE{This};
4693  $node = $node2next{$node};
4694  $T2H_NAME{Next} = &clean_name($node);
4695  $T2H_HREF{Next} = $node2href{$node};
4696  $T2H_NODE{Next} = $node;
4697
4698  $node = $T2H_NODE{This};
4699  if ($node2up{$node} && $node2up{$node} ne 'Top'&& 
4700      ($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node}))
4701  {
4702    $node = $node2up{$node};
4703    while ($node && $node ne $node2up{$node} && ! $node2next{$node})
4704    {
4705      $node = $node2up{$node};
4706    }
4707  }
4708  $node = $node2next{$node};
4709  $T2H_NAME{FastForward} = &clean_name($node);
4710  $T2H_HREF{FastForward} = $node2href{$node};
4711  $T2H_NODE{FastForward} = $node;
4712
4713  if (! defined($FH))
4714  {
4715    my $file = $T2H_HREF{This};
4716    $file =~ s/\#.*$//;
4717    open(FILE, "> $docu_rdir$file") || 
4718      die "$ERROR: Can't open $docu_rdir$file for writing: $!\n";
4719    $FH = \*FILE;
4720    &$T2H_print_page_head($FH);
4721    t2h_print_label($FH);
4722    &$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter';
4723  }
4724  else
4725  {
4726    t2h_print_label($FH);
4727  }
4728
4729  $T2H_THIS_SECTION = [];
4730  while (@doc_lines) {
4731    $_ = shift(@doc_lines);
4732    last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND);
4733    push(@$T2H_THIS_SECTION, $_);
4734  }
4735  $previous = $_;
4736  &$T2H_print_section($FH);
4737
4738  if ($T2H_VERBOSE)
4739  {
4740    $counter++;
4741    print "." if $counter =~ /00$/;
4742  }
4743}
4744if ($T2H_SPLIT)
4745{
4746  &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter';
4747  &$T2H_print_page_foot($FH);
4748  close($FH);
4749}
4750print "\n" if $T2H_VERBOSE;
4751
4752#############################################################################
4753# Print ToC, Overview, Footnotes
4754#
4755undef $T2H_HREF{Prev};
4756undef $T2H_HREF{Next};
4757undef $T2H_HREF{Back};
4758undef $T2H_HREF{Forward};
4759undef $T2H_HREF{Up};
4760
4761if (@foot_lines)
4762{
4763  print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE;
4764  open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n"
4765      if $T2H_SPLIT;
4766  $T2H_HREF{This} = $docu_foot;
4767  $T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'};
4768  $T2H_THIS_SECTION = \@foot_lines;
4769  &$T2H_print_Footnotes(\*FILE);
4770  close(FILE) if $T2H_SPLIT;
4771}
4772
4773if (@toc_lines)
4774{
4775  print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE;
4776  open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n"
4777      if $T2H_SPLIT;
4778  $T2H_HREF{This} = $T2H_HREF{Contents};
4779  $T2H_NAME{This} = $T2H_NAME{Contents};
4780  $T2H_THIS_SECTION = \@toc_lines;
4781  &$T2H_print_Toc(\*FILE);
4782  close(FILE) if $T2H_SPLIT;
4783}
4784
4785if (@stoc_lines)
4786{
4787  print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE;
4788  open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n"
4789      if $T2H_SPLIT;
4790  
4791  $T2H_HREF{This} = $T2H_HREF{Overview};
4792  $T2H_NAME{This} = $T2H_NAME{Overview};
4793  $T2H_THIS_SECTION = \@stoc_lines;
4794  unshift @$T2H_THIS_SECTION, "<BLOCKQUOTE>\n";
4795  push @$T2H_THIS_SECTION, "\n</BLOCKQUOTE>\n";
4796  &$T2H_print_Overview(\*FILE);
4797  close(FILE) if $T2H_SPLIT;
4798}
4799
4800if ($about_body = &$T2H_about_body())
4801{
4802  print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE;
4803  open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n"
4804      if $T2H_SPLIT;
4805  
4806  $T2H_HREF{This} = $T2H_HREF{About};
4807  $T2H_NAME{This} = $T2H_NAME{About};
4808  $T2H_THIS_SECTION = [$about_body];
4809  &$T2H_print_About(\*FILE);
4810  close(FILE) if $T2H_SPLIT;
4811}
4812
4813unless ($T2H_SPLIT)
4814{
4815  &$T2H_print_page_foot(\*FILE);
4816  close (FILE);
4817}
4818  
4819Finish:
4820&l2h_FinishFromHtml if ($T2H_L2H);
4821&l2h_Finish if($T2H_L2H);
4822print "# that's all folks\n" if $T2H_VERBOSE;
4823
4824exit(0);
4825
4826#+++############################################################################
4827#                                                                              #
4828# Low level functions                                                          #
4829#                                                                              #
4830#---############################################################################
4831
4832sub LocateIncludeFile
4833{
4834  my $file = shift;
4835  my $dir;
4836
4837  return $file if (-e $file && -r $file);
4838  foreach $dir (@T2H_INCLUDE_DIRS)
4839  {
4840    return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file");
4841  }
4842  return undef;
4843}
4844
4845sub clean_name 
4846{
4847  local ($_);
4848  $_ = &remove_style($_[0]);
4849  &unprotect_texi;
4850  return $_;
4851}
4852
4853sub update_sec_num {
4854    local($name, $level) = @_;
4855    my $ret;
4856
4857    $level--; # here we start at 0
4858    if ($name =~ /^appendix/ || defined(@appendix_sec_num)) {
4859	# appendix style
4860	if (defined(@appendix_sec_num)) {
4861	    &incr_sec_num($level, @appendix_sec_num);
4862	} else {
4863	    @appendix_sec_num = ('A', 0, 0, 0);
4864	}
4865	$ret = join('.', @appendix_sec_num[0..$level]);
4866    } else {
4867	# normal style
4868	if (defined(@normal_sec_num)) 
4869	{
4870	  &incr_sec_num($level, @normal_sec_num);
4871	} 
4872	else 
4873	{
4874	  @normal_sec_num = (1, 0, 0, 0);
4875	}
4876	$ret = join('.', @normal_sec_num[0..$level]);
4877    }
4878    
4879    $ret .= "." if $level == 0;
4880    return $ret;
4881}
4882
4883sub incr_sec_num {
4884    local($level, $l);
4885    $level = shift(@_);
4886    $_[$level]++;
4887    foreach $l ($level+1 .. 3) {
4888	$_[$l] = 0;
4889    }
4890}
4891
4892sub Sec2UpNode
4893{
4894  my $sec = shift;
4895  my $num = $sec2number{$sec};
4896
4897  return '' unless $num;
4898  return 'Top' unless $num =~ /\.\d+/;
4899  $num =~ s/\.[^\.]*$//;
4900  $num = $num . '.' unless $num =~ /\./;
4901  return $sec2node{$number2sec{$num}};
4902}
4903
4904sub Sec2PrevNode
4905{
4906  my $sec = shift;
4907  my $num = $sec2number{$sec};
4908  my ($i, $post);
4909  
4910  if ($num =~ /(\w+)(\.$|$)/)
4911  {
4912    $num = $`;
4913    $i = $1;
4914    $post = $2;
4915    if ($i eq 'A')
4916    {
4917      $i = $normal_sec_num[0];
4918    }
4919    elsif ($i ne '1')
4920    {
4921      # unfortunately, -- operator is not magical
4922      $i = chr(ord($i) + 1);
4923    }
4924    else
4925    {
4926      return '';
4927    }
4928    return $sec2node{$number2sec{$num . $i . $post}}
4929  }
4930  return '';
4931}
4932
4933sub Sec2NextNode
4934{
4935  my $sec = shift;
4936  my $num = $sec2number{$sec};
4937  my $i;
4938
4939  if ($num =~ /(\w+)(\.$|$)/)
4940  {
4941    $num = $`;
4942    $i = $1;
4943    $post = $2;
4944    if ($post eq '.' && $i eq $normal_sec_num[0])
4945    {
4946      $i = 'A';
4947    }
4948    else
4949    {
4950      $i++;
4951    }
4952    return $sec2node{$number2sec{$num . $i . $post}}
4953  }
4954  return '';
4955}
4956
4957sub check {
4958    local($_, %seen, %context, $before, $match, $after);
4959
4960    while (<>) {
4961	if (/\@(\*|\.|\:|\@|\{|\})/) {
4962	    $seen{$&}++;
4963	    $context{$&} .= "> $_" if $T2H_VERBOSE;
4964	    $_ = "$`XX$'";
4965	    redo;
4966	}
4967	if (/\@(\w+)/) {
4968	    ($before, $match, $after) = ($`, $&, $');
4969	    if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address
4970		$seen{'e-mail address'}++;
4971		$context{'e-mail address'} .= "> $_" if $T2H_VERBOSE;
4972	    } else {
4973		$seen{$match}++;
4974		$context{$match} .= "> $_" if $T2H_VERBOSE;
4975	    }
4976	    $match =~ s/^\@/X/;
4977	    $_ = "$before$match$after";
4978	    redo;
4979	}
4980    }
4981    
4982    foreach (sort(keys(%seen))) {
4983	if ($T2H_VERBOSE) {
4984	    print "$_\n";
4985	    print $context{$_};
4986	} else {
4987	    print "$_ ($seen{$_})\n";
4988	}
4989    }
4990}
4991
4992sub open {
4993    local($name) = @_;
4994
4995    ++$fh_name;
4996    if (open($fh_name, $name)) {
4997	unshift(@fhs, $fh_name);
4998    } else {
4999	warn "$ERROR Can't read file $name: $!\n";
5000    }
5001}
5002
5003sub init_input {
5004    @fhs = ();			# hold the file handles to read
5005    @input_spool = ();		# spooled lines to read
5006    $fh_name = 'FH000';
5007    &open($docu);
5008}
5009
5010sub next_line {
5011    local($fh, $line);
5012
5013    if (@input_spool) {
5014	$line = shift(@input_spool);
5015	return($line);
5016    }
5017    while (@fhs) {
5018	$fh = $fhs[0];
5019	$line = <$fh>;
5020	return($line) if $line;
5021	close($fh);
5022	shift(@fhs);
5023    }
5024    return(undef);
5025}
5026
5027# used in pass 1, use &next_line
5028sub skip_until {
5029    local($tag) = @_;
5030    local($_);
5031
5032    while ($_ = &next_line) {
5033	return if /^\@end\s+$tag\s*$/;
5034    }
5035    die "* Failed to find '$tag' after: " . $lines[$#lines];
5036}
5037
5038# used in pass 1 for l2h use &next_line
5039sub string_until {
5040    local($tag) = @_;
5041    local($_, $string);
5042
5043    while ($_ = &next_line) {
5044	return $string if /^\@end\s+$tag\s*$/;
5045#	$_ =~ s/hbox/mbox/g;
5046	$string = $string.$_;
5047    }
5048    die "* Failed to find '$tag' after: " . $lines[$#lines];
5049}
5050
5051#
5052# HTML stacking to have a better HTML output
5053#
5054
5055sub html_reset {
5056    @html_stack = ('html');
5057    $html_element = 'body';
5058}
5059
5060sub html_push {
5061    local($what) = @_;
5062    push(@html_stack, $html_element);
5063    $html_element = $what;
5064}
5065
5066sub html_push_if {
5067    local($what) = @_;
5068    push(@html_stack, $html_element)
5069	if ($html_element && $html_element ne 'P');
5070    $html_element = $what;
5071}
5072
5073sub html_pop {
5074    $html_element = pop(@html_stack);
5075}
5076
5077sub html_pop_if {
5078    local($elt);
5079
5080    if (@_) {
5081	foreach $elt (@_) {
5082	    if ($elt eq $html_element) {
5083		$html_element = pop(@html_stack) if @html_stack;
5084		last;
5085	    }
5086	}
5087    } else {
5088	$html_element = pop(@html_stack) if @html_stack;
5089    }
5090}
5091
5092sub html_debug {
5093    local($what, $line) = @_;
5094    if ($T2H_DEBUG & $DEBUG_HTML)
5095    {
5096     $what = "\n" unless $what;
5097     return("<!-- $line @html_stack, $html_element -->$what")
5098    }	
5099    return($what);
5100}
5101
5102# to debug the output...
5103sub debug {
5104    local($what, $line) = @_;
5105    return("<!-- $line -->$what")
5106	if $T2H_DEBUG & $DEBUG_HTML;
5107    return($what);
5108}
5109
5110sub SimpleTexi2Html
5111{
5112  local $_ = $_[0];
5113  &protect_texi;
5114  &protect_html;
5115  $_ = substitute_style($_);
5116  $_[0]  = $_;
5117}
5118
5119sub normalise_node {
5120  local $_ = $_[0];
5121  s/\s+/ /g;
5122  s/ $//;
5123  s/^ //;
5124  &protect_texi;
5125  &protect_html;
5126  $_ = substitute_style($_);
5127  $_[0]  = $_;
5128}
5129
5130sub menu_entry 
5131{
5132  my ($node, $name, $descr) = @_;
5133  my ($href, $entry);
5134  
5135  &normalise_node($node);
5136  $href = $node2href{$node};
5137  if ($href) 
5138  {
5139    $descr =~ s/^\s+//;
5140    $descr =~ s/\s*$//;
5141    $descr = SimpleTexi2Html($descr);
5142    if ($T2H_NUMBER_SECTIONS && !$T2H_NODE_NAME_IN_MENU && $node2sec{$node})
5143    {
5144      $entry = $node2sec{$node};
5145      $name = '';
5146    }
5147    else
5148    {
5149      &normalise_node($name);
5150      $entry = ($name && ($name ne $node || ! $T2H_AVOID_MENU_REDUNDANCY) 
5151		? "$name : $node" : $node);
5152    }
5153
5154    if ($T2H_AVOID_MENU_REDUNDANCY && $descr)
5155    {
5156      my $clean_entry = $entry;
5157      $clean_entry =~ s/^.*? // if ($clean_entry =~ /^([A-Z]|\d+)\.[\d\.]* /);
5158      $clean_entry =~ s/[^\w]//g;
5159      my $clean_descr = $descr;
5160      $clean_descr =~ s/[^\w]//g;
5161      $descr = '' if ($clean_entry eq $clean_descr)
5162    }
5163    push(@lines2,&debug('<TR><TD ALIGN="left" VALIGN="TOP">' . 
5164			&t2h_anchor('', $href, $entry) . 
5165			'</TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">' . 
5166			$descr . 
5167			"</TD></TR>\n", __LINE__));
5168  }
5169  elsif ($node =~ /^\(.*\)\w+/)
5170  {
5171    push(@lines2,&debug('<TR><TD ALIGN="left" VALIGN="TOP">' . 
5172			$entry . 
5173			'</TD><TD ALIGN="left" VALIGN="TOP">' . $descr . 
5174			"</TD></TR>\n", __LINE__))
5175  }
5176  else
5177  {
5178    warn "$ERROR Undefined node of menu_entry ($node): $_";
5179  }
5180}
5181
5182sub do_ctrl { "^$_[0]" }
5183
5184sub do_email {
5185    local($addr, $text) = split(/,\s*/, $_[0]);
5186
5187    $text = $addr unless $text;
5188    &t2h_anchor('', "mailto:$addr", $text);
5189}
5190
5191sub do_sc 
5192{ 
5193  # l2h does this much better
5194  return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H);
5195  return "\U$_[0]\E";
5196}
5197
5198sub do_math
5199{
5200  return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H);
5201  return "<EM>".$text."</EM>";
5202}
5203
5204sub do_uref {
5205    local($url, $text, $only_text) = split(/,\s*/, $_[0]);
5206
5207    $text = $only_text if $only_text;
5208    $text = $url unless $text;
5209    &t2h_anchor('', $url, $text);
5210}
5211
5212sub do_url { &t2h_anchor('', $_[0], $_[0]) }
5213
5214sub do_acronym
5215{
5216  return '<FONT SIZE="-1">' . $_[0] . '</FONT>';
5217}
5218
5219sub do_accent
5220{
5221  return "&$_[0]acute;" if $_[1] eq 'H';
5222  return "$_[0]." if $_[1] eq 'dotaccent';
5223  return "$_[0]*" if $_[1] eq 'ringaccent';
5224  return "$_[0]".'[' if $_[1] eq 'tieaccent';
5225  return "$_[0]".'(' if $_[1] eq 'u';
5226  return "$_[0]_" if $_[1] eq 'ubaraccent';
5227  return ".$_[0]" if $_[1] eq 'udotaccent';
5228  return "$_[0]&lt;" if $_[1] eq 'v';
5229  return "&$_[0]cedil;" if $_[1] eq ',';
5230  return "$_[0]" if $_[1] eq 'dotless';
5231  return undef;
5232}
5233
5234sub apply_style {
5235    local($texi_style, $text) = @_;
5236    local($style);
5237
5238    $style = $style_map{$texi_style};
5239    if (defined($style)) { # known style
5240	if ($style =~ /^\"/) { # add quotes
5241	    $style = $';
5242	    $text = "\`$text\'";
5243	}
5244	if ($style =~ /^\&/) { # custom
5245	    $style = $';
5246	    $text = &$style($text, $texi_style);
5247	} elsif ($style) { # good style
5248	    $text = "<$style>$text</$style>";
5249	} else { # no style
5250	}
5251    } else { # unknown style
5252	$text = undef;
5253    }
5254    return($text);
5255}
5256
5257# remove Texinfo styles
5258sub remove_style {
5259    local($_) = @_;
5260    1 while(s/\@\w+{([^\{\}]+)}/$1/g);
5261    return($_);
5262}
5263
5264sub remove_things
5265{
5266  local ($_) = @_;
5267  s|\@(\w+)\{\}|$1|g;
5268  return $_;
5269}
5270
5271sub substitute_style {
5272    local($_) = @_;
5273    local($changed, $done, $style, $text);
5274
5275    &simple_substitutions;
5276    $changed = 1;
5277    while ($changed) {
5278	$changed = 0;
5279	$done = '';
5280	while (/\@(\w+){([^\{\}]+)}/ || /\@(,){([^\{\}]+)}/) {
5281	    $text = &apply_style($1, $2);
5282	    if ($text) {
5283		$_ = "$`$text$'";
5284		$changed = 1;
5285	    } else {
5286		$done .= "$`\@$1";
5287		$_ = "{$2}$'";
5288	    }
5289	}
5290        $_ = $done . $_;
5291    }
5292    return($_);
5293}
5294
5295sub t2h_anchor {
5296    local($name, $href, $text, $newline, $extra_attribs) = @_;
5297    local($result);
5298
5299    $result = "<A";
5300    $result .= " NAME=\"$name\"" if $name;
5301    if ($href)
5302    {
5303      $href =~ s|^$T2H_HREF_DIR_INSTEAD_FILE|./| 
5304	if ($T2H_HREF_DIR_INSTEAD_FILE);
5305      $result .= ($href =~ /\"/ ? " HREF='$href'"  : " HREF=\"$href\"");
5306    }
5307    $result .= " $extra_attribs" if $extra_attribs;
5308    $result .= ">$text</A>";
5309    $result .= "\n" if $newline;
5310    return($result);
5311}
5312
5313sub pretty_date {
5314    local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
5315
5316    @MoY = ('January', 'February', 'March', 'April', 'May', 'June',
5317	    'July', 'August', 'September', 'October', 'November', 'December');
5318    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
5319    $year += ($year < 70) ? 2000 : 1900;
5320    # obachman: Let's do it as the Americans do
5321    return("$MoY[$mon], $mday  $year");
5322}
5323
5324sub doc_href {
5325    local($num) = @_;
5326
5327    return("${docu_name}_$num.$docu_ext");
5328}
5329
5330sub sec_href
5331{
5332  return $node2href{$sec2node{$_[0]}};
5333}
5334
5335sub next_doc {
5336    $docu_doc = &doc_href(++$doc_num);
5337}
5338
5339sub t2h_print_lines {
5340    my ($fh, $lines) = @_;
5341    local($_);
5342    $lines = $T2H_THIS_SECTION unless $lines;
5343    my $cnt = 0;
5344    for (@$lines) 
5345    {
5346	$_ = l2h_FromHtml($_) if ($T2H_L2H);
5347	if (/^$PROTECTTAG/o) {
5348	    $_ = $tag2pro{$_};
5349	} else {
5350	    &unprotect_texi;
5351	}
5352	print $fh $_;
5353	$cnt += split(/\W*\s+\W*/);
5354    }
5355    return $cnt;
5356}
5357
5358sub protect_texi {
5359    # protect @ { } ` '
5360    s/\@\@/$;0/go;
5361    s/\@\{/$;1/go;
5362    s/\@\}/$;2/go;
5363    s/\@\`/$;3/go;
5364    s/\@\'/$;4/go;
5365}
5366
5367sub protect_html {
5368    local($what) = @_;
5369    # protect & < >
5370    $what =~ s/\&/\&\#38;/g;
5371    $what =~ s/\</\&\#60;/g;
5372    $what =~ s/\>/\&\#62;/g;
5373    # restore anything in quotes
5374    # this fixes my problem where I had:
5375    # < IMG SRC="leftarrow.gif" ALT="<--" >  but what if I wanted &#60; in my ALT text ??
5376    # maybe byte stuffing or some other technique should be used.
5377    $what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g;
5378    $what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g;
5379    $what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g;
5380    # but recognize some HTML things
5381    $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g;	      # </A>
5382    $what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g;     # <A [^&]+>
5383    $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+>
5384    return($what);
5385}
5386
5387sub unprotect_texi {
5388    s/$;0/\@/go;
5389    s/$;1/\{/go;
5390    s/$;2/\}/go;
5391    s/$;3/\`/go;
5392    s/$;4/\'/go;
5393}
5394
5395sub Unprotect_texi 
5396{
5397  local $_ = shift;
5398  &unprotect_texi;
5399  return($_);
5400}
5401
5402sub unprotect_html {
5403    local($what) = @_;
5404    $what =~ s/\&\#38;/\&/g;
5405    $what =~ s/\&\#60;/\</g;
5406    $what =~ s/\&\#62;/\>/g;
5407    return($what);
5408}
5409
5410sub t2h_print_label
5411{
5412    my $fh = shift;
5413    my $href = shift || $T2H_HREF{This};
5414    $href =~ s/.*#(.*)$/$1/;
5415    print $fh qq{<A NAME="$href"></A>\n};
5416}
5417
5418##############################################################################
5419
5420	# These next few lines are legal in both Perl and nroff.
5421
5422.00 ;			# finish .ig
5423 
5424'di			\" finish diversion--previous line must be blank
5425.nr nl 0-1		\" fake up transition to first page again
5426.nr % 0			\" start at page 1
5427'; __END__ ############# From here on it's a standard manual page ############
5428.so /usr/local/man/man1/texi2html.1
5429