source: git/doc/texi2html @ fddf1c

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