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