1#!@HAVE_PERL@
2'di ';
3'ig 00 ';
4#+##############################################################################
5#
6# texi2html: Program to transform Texinfo documents to HTML
7#
8#    Copyright (C) 1999, 2000  Free Software Foundation, Inc.
9#
10#    This program is free software; you can redistribute it and/or modify
11#    it under the terms of the GNU General Public License as published by
12#    the Free Software Foundation; either version 2 of the License, or
13#    (at your option) any later version.
14#
15#    This program is distributed in the hope that it will be useful,
16#    but WITHOUT ANY WARRANTY; without even the implied warranty of
17#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18#    GNU General Public License for more details.
19#
20#    You should have received a copy of the GNU General Public License
21#    along with this program; if not, write to the Free Software
22#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23#
24#-##############################################################################
25
26# This requires perl version 5 or higher
27require 5.0;
28
29#++##############################################################################
30#
31# NOTE FOR DEBUGGING THIS SCRIPT:
32# You can run 'perl texi2html.pl' directly, provided you have
33# the environment variable T2H_HOME set to the directory containing
34# the texi2html.init file
35#
36#--##############################################################################
37
38# CVS version:
39# $Id: texi2html.in,v 1.2 2000/04/08 12:20:05 danny Exp $
40
41# Homepage:
42$T2H_HOMEPAGE = <<EOT;
43http://www.mathematik.uni-kl.de/~obachman/Texi2html
44EOT
45
46# Authors:
47$T2H_AUTHORS = <<EOT;
48Written by: Lionel Cons <Lionel.Cons\@cern.ch> (original author)
49            Karl Berry  <karl\@freefriends.org>
50            Olaf Bachmann <obachman\@mathematik.uni-kl.de>
51            and many others.
52Maintained by: Olaf Bachmann <obachman\@mathematik.uni-kl.de>
53Send bugs and suggestions to <texi2html\@mathematik.uni-kl.de>
54EOT
55
56# Version: set in configure.in
57$THISVERSION = '1.61';
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                              #
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.inig
79# exists
80
81#
82# -*-perl-*-
83######################################################################
84# File: texi2html.init
85#
86# Sets default values for command-line arguments and for various customizable
87# procedures
88#
89# A copy of this file is pasted into the beginning of texi2html by
90# 'make texi2html'
91#
92# Copy this file and make changes to it, if you like.
93# Afterwards, either, load it with command-line option -init_file <your_init_file>
94#
95# $Id: texi2html.in,v 1.2 2000/04/08 12:20:05 danny Exp $
96
97######################################################################
98# stuff which can also be set by command-line options
99#
100#
101# Note: values set here, overwrite values set by the command-line
102# options before -init_file and might still be overwritten by
103# command-line arguments following the -init_file option
104#
105
106# -debug
107# debugging: 0 -- no debugging, other values: see beginning of texi2html
108$T2H_DEBUG = 0;
109
110# -doctype
111# document type which is specified in header of html files
112$T2H_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">';
113
114# -check
115# if set, only check files and give the list of all things that may be
116# Texinfo commands
117$T2H_CHECK = 0;
118
119# -expand
120# if set to "tex" (or, "info") expand @iftex and @tex (or, @ifinfo) sections
121# else, neither expand @iftex, @tex, nor @ifinfo sections
122$T2H_EXPAND = "info";
123
124# - glossary
125#if set, uses section named `Footnotes' for glossary
126$T2H_USE_GLOSSARY = 0;
127
128# -invisible
129# if set, use $T2H_INVISIBLE_MARK to create invisible destination
130# anchors for index links (you can for instance use the invisible.xbm
131# file shipped with this program). This is a workaround for a known
132# bug of many WWW browsers, including netscape.
133# For me, it works fine without it -- on the contrary: if there, it
134# inserts space between headers and start of text (obachman 3/99)
135$T2H_INVISIBLE_MARK = '';
136# $T2H_INVISIBLE_MARK = '&#160;';
137
138# -iso
139# if set, ISO8879 characters are used for special symbols (like copyright, etc)
140$T2H_USE_ISO = 0;
141
142# -I
143# list directories where @include files are searched for (besides the
144# directory of the doc file) additional '-I' args add to this list
145@T2H_INCLUDE_DIRS = (".");
146
147# -top_file
148# uses file of this name for top-level file
149# extension is manipulated appropriately, if nessecary
150$T2H_TOP_FILE = "index.html";
151
152# -menu
153# if set, show the Texinfo menus
154$T2H_SHOW_MENU = 1;
155
156# -number
157# if set, number sections, show sections ins menu
158$T2H_NUMBER_SECTIONS = 1;
159
160# -split section|chapter|none
161# if set to 'section' (resp. 'chapter') create one html file per (sub)section
162# (resp. chapter) and separate pages for Top, ToC, Overview, Index,
163# Glossary, About.
164# otherwise, create monolithic html file which contains whole document
165#$T2H_SPLIT = 'section';
166$T2H_SPLIT = undef;
167
168# -section_navigation|-no-section_navigation
169# if set, then navigation panels are printed at the beginning of each section
170# and, possibly at the end (depending on whether or not there were more than
171# $T2H_WORDS_IN_PAGE  words on page
172# This is most useful if yopu do not want to have section navigation
173# on -split chapter
174$T2H_SECTION_NAVIGATION = 1;
175
176# -subdir
177# if set put result files in this directory
178# if not set result files are put into current directory
179#$T2H_SUBDIR = 'html';
180$T2H_SUBDIR = undef;
181
182# -short_extn
183# If this is set all HTML file will have extension ".htm" instead of
184# ".html". This is helpful when shipping the document to PC systems.
185$T2H_SHORTEXTN = 0;
186
187# -prefix
188# Set the output file prefix, prepended to all .html, .gif and .pl files.
189# By default, this is the basename of the document
190$T2H_PREFIX = '';
191
192# -o filename
193# If set, generate monolithic document output html into $filename
194$T2H_OUT = '';
195
196# -short_ref
197#if set cross-references are given without section numbers
198$T2H_SHORT_REF = 0;
199
200# -idx_sum
201# if value matches argument of @printindex, (say, $what) then file
202# $docu_name_$what.idx is created which contains lines of the form
203# $key\t$ref
204# sorted alphabetically with lines where $key
205$T2H_IDX_SUMMARY = '';
206
207# -verbose
208# if set, chatter about what we are doing
209$T2H_VERBOSE = 0;
210
211# -lang
212# For page titles use $T2H_WORDS->{$T2H_LANG}->{...} as title.
213# To add a new language, supply list of titles (see $T2H_WORDS below).
214$T2H_LANG = 'english';
215
216# -l2h
217# if set, uses latex2html for generation of math content
218$T2H_L2H = 0;
219
220######################
221# The following options are only relevant if $T2H_L2H is set
222#
223# -l2h_l2h
224# name/location of latex2html progam
225$T2H_L2H_L2H = "latex2html";
226
227# -l2h_skip
228# if set, skips actual call to latex2htm tries to reuse previously generated
229# content, instead
230$T2H_L2H_SKIP = 0;
231
232# -l2h_tmp
233# if set, l2h uses this directory for temporarary files. The path
234# leading to this directory may not contain a dot (i.e., a "."),
235# otherwise, l2h will fail
236$T2H_L2H_TMP = '';
237
238# -l2h_keep
239# if set, keeps intermediate files (they all have the prefix $doc_l2h_)
240# of l2h for later reuse
241$T2H_L2H_KEEP = 1;
242
243##############################################################################
244#
245# The following can only be set in the init file
246#
247##############################################################################
248
249# if set, center @image by default
250# otherwise, do not center by default
251$T2H_CENTER_IMAGE = 1;
252
253# used as identation for block enclosing command @example, etc
254# If not empty, must be enclosed in <td></td>
255$T2H_EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';
256# same as abov, only for @small
257$T2H_SMALL_EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';
258# font size for @small
259$T2H_SMALL_FONT_SIZE = '-1';
260
261
262########################################################################
263# Language dependencies:
264# To add a new language extend T2H_WORDS hash and create $T2H_<...>_WORDS hash
265# To redefine one word, simply do:
266# $T2H_WORDS->{<language>}->{<word>} = 'whatever' in your personal init file.
267#
268$T2H_ENGLISH_WORDS =
269{
270 # titles  of pages
271 'ToC_Title' => 'Table of Contents',
272 'Overview_Title' => 'Short Table of Contents',
273 'Index_Title' => 'Index',
274 'About_Title' => 'About this document',
275 'Footnotes_Title' => 'Footnotes',
276 'See' => 'See',
277 'see' => 'see',
278 'section' => 'section',
279# If necessary, we could extend this as follows:
280#  # text for buttons
281#  'Top_Button' => 'Top',
282#  'ToC_Button' => 'Contents',
283#  'Overview_Button' => 'Overview',
284#  'Index_button' => 'Index',
285#  'Back_Button' => 'Back',
286#  'FastBack_Button' => 'FastBack',
287#  'Prev_Button' => 'Prev',
288#  'Up_Button' => 'Up',
289#  'Next_Button' => 'Next',
290#  'Forward_Button' =>'Forward',
291#  'FastWorward_Button' => 'FastForward',
292#  'First_Button' => 'First',
293#  'Last_Button' => 'Last',
294#  'About_Button' => 'About'
295};
296
297$T2H_GERMAN_WORDS =
298{
299 'ToC_Title' => 'Inhaltsverzeichniss',
300 'Overview_Title' => 'Kurzes Inhaltsverzeichniss',
301 'Index_Title' => 'Index',
302 'About_Title' => '&Uuml;ber dieses Dokument',
303 'Footnotes_Title' => 'Fu&szlig;noten',
304 'See' => 'Siehe',
305 'see' => 'siehe',
306 'section' => 'Abschnitt',
307};
308
309$T2H_WORDS =
310{
311 'english' => $T2H_ENGLISH_WORDS,
312 'german' => $T2H_GERMAN_WORDS
313};
314
315########################################################################
316# Control of Page layout:
317# You can make changes of the Page layout at two levels:
318# 1.) For small changes, it is often enough to change the value of
319#     some global string/hash/array variables
320# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines,
321#     give them another name, and assign them to the respective
322#     $T2H_<fnc> variable.
323
324# As a general interface, the hashes T2H_HREF, T2H_NAME, T2H_NODE hold
325# href, html-name, node-name of
326# This     -- current section (resp. html page)
327# Top      -- top page ($T2H_TOP_FILE)
328# Contents -- Table of contents
329# Overview -- Short table of contents
330# Index    -- Index page
331# About    -- page which explain "navigation buttons"
332# First    -- first node
333# Last     -- last node
334#
335# Whether or not the following hash values are set, depends on the context
336# (all values are w.r.t. 'This' section)
337# Next        -- next node of texinfo
338# Prev        -- previous node of texinfo
339# Up          -- up node of texinfo
340# Forward     -- next node in reading order
341# Back        -- previous node in reading order
342# FastForward -- if leave node, up and next, else next node
343# FastBackward-- if leave node, up and prev, else prev node
344#
345# Furthermore, the following global variabels are set:
346# $T2H_THISDOC{title}     -- title as set by @setttile
347# $T2H_THISDOC{fulltitle} -- full title as set by @title...
348# $T2H_THISDOC{subtitle}  -- subtitle as set by @subtitle
349# $T2H_THISDOC{author}    -- author as set by @author
350#
351# and pointer to arrays of lines which need to be printed by t2h_print_lines
352# $T2H_OVERVIEW      -- lines of short table of contents
353# $T2H_TOC           -- lines of table of contents
354# $T2H_TOP           -- lines of Top texinfo node
355# $T2H_THIS_SECTION  -- lines of 'This' section
356
357#
358# There are the following subs which control the layout:
359#
360$T2H_print_section            = \&T2H_DEFAULT_print_section;
361$T2H_print_Top_header         = \&T2H_DEFAULT_print_Top_header;
362$T2H_print_Top_footer	      = \&T2H_DEFAULT_print_Top_footer;
363$T2H_print_Top		      = \&T2H_DEFAULT_print_Top;
364$T2H_print_Toc		      = \&T2H_DEFAULT_print_Toc;
365$T2H_print_Overview	      = \&T2H_DEFAULT_print_Overview;
366$T2H_print_Footnotes	      = \&T2H_DEFAULT_print_Footnotes;
367$T2H_print_About	      = \&T2H_DEFAULT_print_About;
368$T2H_print_misc_header	      = \&T2H_DEFAULT_print_misc_header;
369$T2H_print_misc_footer	      = \&T2H_DEFAULT_print_misc_footer;
370$T2H_print_misc		      = \&T2H_DEFAULT_print_misc;
371$T2H_print_chapter_header     = \&T2H_DEFAULT_print_chapter_header;
372$T2H_print_chapter_footer     = \&T2H_DEFAULT_print_chapter_footer;
373$T2H_print_page_head	      = \&T2H_DEFAULT_print_page_head;
374$T2H_print_page_foot	      = \&T2H_DEFAULT_print_page_foot;
375$T2H_print_head_navigation    = \&T2H_DEFAULT_print_head_navigation;
376$T2H_print_foot_navigation    = \&T2H_DEFAULT_print_foot_navigation;
377$T2H_button_icon_img	      = \&T2H_DEFAULT_button_icon_img;
378$T2H_print_navigation	      = \&T2H_DEFAULT_print_navigation;
379$T2H_about_body		      = \&T2H_DEFAULT_about_body;
380
381########################################################################
382# Layout for html for every sections
383#
384sub T2H_DEFAULT_print_section
385{
386  my $fh = shift;
387  local $T2H_BUTTONS = \@T2H_SECTION_BUTTONS;
388  &$T2H_print_head_navigation($fh) if $T2H_SECTION_NAVIGATION;
389  my $nw = t2h_print_lines($fh);
390  if ($T2H_SPLIT eq 'section' && $T2H_SECTION_NAVIGATION)
391  {
392    &$T2H_print_foot_navigation($fh, $nw);
393  }
394  else
395  {
396    print $fh '<HR SIZE="6">' . "\n";
397  }
398}
399
400###################################################################
401# Layout of top-page I recommend that you use @ifnothtml, @ifhtml,
402# @html within the Top texinfo node to specify content of top-level
403# page.
404#
405# If you enclose everything in @ifnothtml, then title, subtitle,
406# author and overview is printed
407# T2H_HREF of Next, Prev, Up, Forward, Back are not defined
408# if $T2H_SPLIT then Top page is in its own html file
409sub T2H_DEFAULT_print_Top_header
410{
411  &$T2H_print_page_head(@_) if $T2H_SPLIT;
412  t2h_print_label(@_); # this needs to be called, otherwise no label set
413  &$T2H_print_head_navigation(@_);
414}
415sub T2H_DEFAULT_print_Top_footer
416{
417  &$T2H_print_foot_navigation(@_);
418  &$T2H_print_page_foot(@_) if $T2H_SPLIT;
419}
420sub T2H_DEFAULT_print_Top
421{
422  my $fh = shift;
423
424  # for redefining navigation buttons use:
425  # local $T2H_BUTTONS = [...];
426  # as it is, 'Top', 'Contents', 'Index', 'About' are printed
427  local $T2H_BUTTONS = \@T2H_MISC_BUTTONS;
428  &$T2H_print_Top_header($fh);
429  if ($T2H_THIS_SECTION)
430  {
431    # if top-level node has content, then print it
432    t2h_print_lines($fh, $T2H_THIS_SECTION)
433  }
434  else
435  {
436    # top-level node is fully enclosed in @ifnothtml
437    # print fulltitle, subtitle, author, Overview
438    print $fh
439      "<CENTER>\n<H1>" .
440      join("</H1>\n<H1>", split(/\n/,  $T2H_THISDOC{fulltitle})) .
441      "</H1>\n";
442    print $fh "<H2>$T2H_THISDOC{subtitle}</H2>\n" if $T2H_THISDOC{subtitle};
443    print $fh "$T2H_THISDOC{author}\n" if $T2H_THISDOC{author};
444    print $fh <<EOT;
445</CENTER>
446<HR>
447<P></P>  
448<H2> Overview: </H2>
449<BLOCKQUOTE>  
450EOT
451    t2h_print_lines($fh, $T2H_OVERVIEW);
452    print $fh "</BLOCKQUOTE>\n";
453  }
454  &$T2H_print_Top_footer($fh);
455}
456
457###################################################################
458# Layout of Toc, Overview, and Footnotes pages
459# By default, we use "normal" layout
460# T2H_HREF of Next, Prev, Up, Forward, Back, etc are not defined
461# use: local $T2H_BUTTONS = [...] to redefine navigation buttons
462sub T2H_DEFAULT_print_Toc
463{
464  return &$T2H_print_misc(@_);
465}
466sub T2H_DEFAULT_print_Overview
467{
468  return &$T2H_print_misc(@_);
469}
470sub T2H_DEFAULT_print_Footnotes
471{
472  return &$T2H_print_misc(@_);
473}
474sub T2H_DEFAULT_print_About
475{
476  return &$T2H_print_misc(@_);
477}
478
479sub T2H_DEFAULT_print_misc_header
480{
481  &$T2H_print_page_head(@_) if $T2H_SPLIT;
482  # this needs to be called, otherwise, no labels are set
483  t2h_print_label(@_);
484  &$T2H_print_head_navigation(@_);
485}
486sub T2H_DEFAULT_print_misc_footer
487{
488  &$T2H_print_foot_navigation(@_);
489  &$T2H_print_page_foot(@_) if $T2H_SPLIT;
490}
491sub T2H_DEFAULT_print_misc
492{
493  my $fh = shift;
494  local $T2H_BUTTONS = \@T2H_MISC_BUTTONS;
495  &$T2H_print_misc_header($fh);
496  print $fh "<H1>$T2H_NAME{This}</H1>\n";
497  t2h_print_lines($fh);
498  &$T2H_print_misc_footer($fh);
499}
500
501###################################################################
502# chapter_header and chapter_footer are only called if
503# T2H_SPLIT eq 'chapter'
504# chapter_header: after print_page_header, before print_section
505# chapter_footer: after print_section of last section, before print_page_footer
506#
507# If you want to get rid of navigation stuff after each section,
508# redefine print_section such that it does not call print_navigation,
509# and put print_navigation into print_chapter_header
510@T2H_CHAPTER_BUTTONS =
511  (
512   'FastBack', 'FastForward', ' ',
513   ' ', ' ', ' ', ' ',
514   'Top', 'Contents', 'Index', 'About',
515  );
516
517sub T2H_DEFAULT_print_chapter_header
518{
519  # nothing to do there, by default
520  if (! $T2H_SECTION_NAVIGATION)
521  {
522    my $fh = shift;
523    local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS;
524    &$T2H_print_navigation($fh);
525    print $fh "\n<HR SIZE=2>\n";
526  }
527}
528
529sub T2H_DEFAULT_print_chapter_footer
530{
531  local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS;
532  &$T2H_print_navigation(@_);
533}
534###################################################################
535# Layout of standard header and footer
536#
537
538# Set the default body text, inserted between <BODY ... >
539$T2H_BODYTEXT = 'LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"';
540# text inserted after <BODY ...>
541$T2H_AFTER_BODY_OPEN = '';
542#text inserted before </BODY>
543$T2H_PRE_BODY_CLOSE = '';
544# this is used in footer
545$T2H_ADDRESS = "by <I>$T2H_USER</I> " if $T2H_USER;
546$T2H_ADDRESS .= "on <I>$T2H_TODAY</I>";
547# this is added inside <HEAD></HEAD> after <TITLE> and some META NAME stuff
548# can be used for <style> <script>, <meta> tags
549$T2H_EXTRA_HEAD = '';
550
551sub T2H_DEFAULT_print_page_head
552{
553  my $fh = shift;
554  my $longtitle = "$T2H_THISDOC{title}: $T2H_NAME{This}";
555  print $fh <<EOT;
556$T2H_DOCTYPE
557<!-- Created on $T2H_TODAY by $THISPROG -->
558<!-- 
559$T2H_AUTHORS 
560-->
561<HTML>
562<HEAD>
563<TITLE>$longtitle</TITLE>
564
565<META NAME="description" CONTENT="$longtitle">
566<META NAME="keywords" CONTENT="$longtitle">
567<META NAME="resource-type" CONTENT="document">
568<META NAME="distribution" CONTENT="global">
569<META NAME="Generator" CONTENT="$THISPROG">
570$T2H_EXTRA_HEAD
571</HEAD>
572
573<BODY $T2H_BODYTEXT>
574$T2H_AFTER_BODY_OPEN
575EOT
576}
577
578sub T2H_DEFAULT_print_page_foot
579{
580  my $fh = shift;
581  print $fh <<EOT;
582<BR>  
583<FONT SIZE="-1">
584This document was generated
585$T2H_ADDRESS
586using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A>
587$T2H_PRE_BODY_CLOSE
588</BODY>
589</HTML>
590EOT
591}
592
593###################################################################
594# Layout of navigation panel
595
596# if this is set, then a vertical navigation panel is used
597$T2H_VERTICAL_HEAD_NAVIGATION = 0;
598sub T2H_DEFAULT_print_head_navigation
599{
600  my $fh = shift;
601  if ($T2H_VERTICAL_HEAD_NAVIGATION)
602  {
603    print $fh <<EOT;
604<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
605<TR VALIGN="TOP">
606<TD ALIGN="LEFT">
607EOT
608  }
609  &$T2H_print_navigation($fh, $T2H_VERTICAL_HEAD_NAVIGATION);
610  if ($T2H_VERTICAL_HEAD_NAVIGATION)
611  {
612    print $fh <<EOT;
613</TD>
614<TD ALIGN="LEFT">
615EOT
616  }
617  elsif ($T2H_SPLIT eq 'section')
618  {
619    print $fh "<HR SIZE=1>\n";
620  }
621}
622
623# Specifies the minimum page length required before a navigation panel
624# is placed at the bottom of a page (the default is that of latex2html)
625# T2H_THIS_WORDS_IN_PAGE holds number of words of current page
626$T2H_WORDS_IN_PAGE = 300;
627sub T2H_DEFAULT_print_foot_navigation
628{
629  my $fh = shift;
630  my $nwords = shift;
631  if ($T2H_VERTICAL_HEAD_NAVIGATION)
632  {
633    print $fh <<EOT;
634</TD>
635</TR>
636</TABLE>
637EOT
638  }
639  print $fh "<HR SIZE=1>\n";
640  &$T2H_print_navigation($fh) if ($nwords >= $T2H_WORDS_IN_PAGE)
641}
642
643######################################################################
644# navigation panel
645#
646# specify in this array which "buttons" should appear in which order
647# in the navigation panel for sections; use ' ' for empty buttons (space)
648@T2H_SECTION_BUTTONS =
649  (
650   'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward',
651   ' ', ' ', ' ', ' ',
652   'Top', 'Contents', 'Index', 'About',
653  );
654
655# buttons for misc stuff
656@T2H_MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About');
657
658# insert here name of icon images for buttons
659# Icons are used, if $T2H_ICONS and resp. value are set
660%T2H_ACTIVE_ICONS =
661  (
662   'Top',      '',
663   'Contents', '',
664   'Overview', '',
665   'Index',    '',
666   'Back',     '',
667   'FastBack', '',
668   'Prev',     '',
669   'Up',       '',
670   'Next',     '',
671   'Forward',  '',
672   'FastForward', '',
673   'About' ,    '',
674   'First',    '',
675   'Last',     '',
676   ' ',        ''
677  );
678
679# insert here name of icon images for these, if button is inactive
680%T2H_PASSIVE_ICONS =
681  (
682   'Top',      '',
683   'Contents', '',
684   'Overview', '',
685   'Index',    '',
686   'Back',     '',
687   'FastBack', '',
688   'Prev',     '',
689   'Up',       '',
690   'Next',     '',
691   'Forward',  '',
692   'FastForward', '',
693   'About',     '',
694   'First',    '',
695   'Last',     '',
696  );
697
698# how to create IMG tag
699sub T2H_DEFAULT_button_icon_img
700{
701  my $button = shift;
702  my $icon = shift;
703  my $name = shift;
704  return qq{<IMG SRC="$icon" BORDER="0" ALT="$button: $name" ALIGN="MIDDLE">};
705}
706
707# Names of text as alternative for icons
708%T2H_NAVIGATION_TEXT =
709  (
710   'Top',      'Top',
711   'Contents', 'Contents',
712   'Overview', 'Overview',
713   'Index',    'Index',
714   ' ',        ' &nbsp; ',
715   'Back',     ' &lt; ',
716   'FastBack', ' &lt;&lt; ',
717   'Prev',     'Prev',
718   'Up',       ' Up ',
719   'Next',     'Next',
720   'Forward',  ' &gt; ',
721   'FastForward',  ' &gt;&gt; ',
722   'About',     ' ? ',
723   'First',    ' |&lt; ',
724   'Last',     ' &gt;| '
725  );
726
727sub T2H_DEFAULT_print_navigation
728{
729  my $fh = shift;
730  my $vertical = shift;
731  my $spacing = 1;
732  print $fh "<TABLE CELLPADDING=$spacing CELLSPACING=$spacing BORDER=0>\n";
733
734  print $fh "<TR>" unless $vertical;
735  for $button (@$T2H_BUTTONS)
736  {
737    print $fh qq{<TR VALIGN="TOP" ALIGN="LEFT">\n} if $vertical;
738    print $fh qq{<TD VALIGN="MIDDLE" ALIGN="LEFT">};
739
740    if (ref($button) eq 'CODE')
741    {
742      &$button($fh, $vertical);
743    }
744    elsif ($button eq ' ')
745    { # handle space button
746      print $fh
747	$T2H_ICONS && $T2H_ACTIVE_ICONS{' '} ?
748	 &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{' '}) :
749	 $T2H_NAVIGATION_TEXT{' '};
750      next;
751    }
752    elsif ($T2H_HREF{$button})
753    { # button is active
754      print $fh
755	 $T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? # use icon ?
756	   t2h_anchor('', $T2H_HREF{$button},  # yes
757		    &$T2H_button_icon_img($button,
758					$T2H_ACTIVE_ICONS{$button},
759					$T2H_NAME{$button}))
760	 : # use text
761	 "[" .
762	 t2h_anchor('', $T2H_HREF{$button}, $T2H_NAVIGATION_TEXT{$button}) .
763	 "]";
764    }
765    else
766    { # button is passive
767      print $fh
768	$T2H_ICONS && $T2H_PASSIVE_ICONS{$button} ?
769	 &$T2H_button_icon_img($button,
770			       $T2H_PASSIVE_ICONS{$button},
771			       $T2H_NAME{$button}) :
772
773	 "[" . $T2H_NAVIGATION_TEXT{$button} . "]";
774    }
775    print $fh "</TD>\n";
776    print $fh "</TR>\n" if $vertical;
777  }
778  print $fh "</TR>" unless $vertical;
779  print $fh "</TABLE>\n";
780}
781
782######################################################################
783# About page
784#
785
786# T2H_PRE_ABOUT might be a function
787$T2H_PRE_ABOUT = <<EOT;
788This document was generated $T2H_ADDRESS
789using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A>
790<P></P>  
791EOT
792$T2H_AFTER_ABOUT = '';
793
794sub T2H_DEFAULT_about_body
795{
796  my $about;
797  if (ref($T2H_PRE_ABOUT) eq 'CODE')
798  {
799    $about = &$T2H_PRE_ABOUT();
800  }
801  else
802  {
803    $about = $T2H_PRE_ABOUT;
804  }
805  $about .= <<EOT;
806The buttons in the navigation panels have the following meaning:
807<P></P>
808<table border = "1">
809<TR>
810<TH> Button </TH>
811<TH> Name </TH>
812<TH> Go to </TH>
813<TH> From 1.2.3 go to</TH>
814</TR>
815EOT
816
817  for $button (@T2H_SECTION_BUTTONS)
818  {
819    next if $button eq ' ' || ref($button) eq 'CODE';
820    $about .= <<EOT;
821<TR>
822<TD ALIGN="CENTER">
823EOT
824    $about .=
825      ($T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ?
826       &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{$button}) :
827       " [" . $T2H_NAVIGATION_TEXT{$button} . "] ");
828    $about .= <<EOT;
829</TD>
830<TD ALIGN="CENTER">
831$button
832</TD>
833<TD>
834$T2H_BUTTONS_GOTO{$button}
835</TD>
836<TD>
837$T2H_BUTTONS_EXAMPLE{$button}
838</TD>
839</TR>
840EOT
841  }
842
843  $about .= <<EOT;
844</TABLE>
845<P></P>
846where the <STRONG> Example </STRONG> assumes that the current position 
847is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 
848the following structure:
849<UL>
850<LI> 1. Section One  </LI>
851<UL>
852<LI>1.1 Subsection One-One</LI>
853<UL>
854<LI> ... </LI>
855</UL>
856<LI>1.2 Subsection One-Two</LI>
857<UL>
858<LI>1.2.1 Subsubsection One-Two-One
859</LI><LI>1.2.2 Subsubsection One-Two-Two
860</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
861&lt;== Current Position </STRONG>
862</LI><LI>1.2.4 Subsubsection One-Two-Four
863</LI></UL>
864<LI>1.3 Subsection One-Three</LI>
865<UL>
866<LI> ... </LI>
867</UL>
868<LI>1.4 Subsection One-Four</LI>
869</UL>
870</UL>
871$T2H_AFTER_ABOUT
872EOT
873  return $about;
874}
875
876
877%T2H_BUTTONS_GOTO =
878  (
879   'Top',      'cover (top) of document',
880   'Contents', 'table of contents',
881   'Overview', 'short table of contents',
882   'Index',    'concept index',
883   'Back',     'previous section in reading order',
884   'FastBack', 'previous or up-and-previous section ',
885   'Prev',     'previous section same level',
886   'Up',       'up section',
887   'Next',     'next section same level',
888   'Forward',  'next section in reading order',
889   'FastForward', 'next or up-and-next section',
890   'About' ,    'this page',
891   'First',    'first section in reading order',
892   'Last',     'last section in reading order',
893  );
894
895%T2H_BUTTONS_EXAMPLE =
896(
897   'Top',      ' &nbsp; ',
898   'Contents', ' &nbsp; ',
899   'Overview', ' &nbsp; ',
900   'Index',    ' &nbsp; ',
901   'Back',     '1.2.2',
902   'FastBack', '1.1',
903   'Prev',     '1.2.2',
904   'Up',       '1.2',
905   'Next',     '1.2.4',
906   'Forward',  '1.2.4',
907   'FastForward', '1.3',
908   'About',     ' &nbsp; ',
909   'First',    '1.',
910   'Last',     '1.2.4',
911);
912
913
914######################################################################
915# from here on, its l2h init stuff
916#
917
918## initialization for latex2html as for Singular manual generation
919## obachman 3/99
920
921#
922# Options controlling Titles, File-Names, Tracing and Sectioning
923#
924$TITLE = '';
925
926$SHORTEXTN = 0;
927
928$LONG_TITLES = 0;
929
930$DESTDIR = ''; # should be overwritten by cmd-line argument
931
932$NO_SUBDIR = 0;# should be overwritten by cmd-line argument
933
934$PREFIX = '';  # should be overwritten by cmd-line argument
935
936$AUTO_PREFIX = 0; # this is needed, so that prefix settings are used
937
938$AUTO_LINK = 0;
939
940$SPLIT = 0;
941
942$MAX_LINK_DEPTH = 0;
943
944$TMP = ''; # should be overwritten by cmd-line argument
945
946$DEBUG = 0;
947
948$VERBOSE = 1;
949
950#
951# Options controlling Extensions and Special Features
952#
953$HTML_VERSION = "3.2";
954
955$TEXDEFS = 1; # we absolutely need that
956
957$EXTERNAL_FILE = '';
958
959$SCALABLE_FONTS = 1;
960
961$NO_SIMPLE_MATH = 1;
962
963$LOCAL_ICONS = 1;
964
965$SHORT_INDEX = 0;
966
967$NO_FOOTNODE = 1;
968
969$ADDRESS = '';
970
971$INFO = '';
972
973#
974# Switches controlling Image Generation
975#
976$ASCII_MODE = 0;
977
978$NOLATEX = 0;
979
980$EXTERNAL_IMAGES = 0;
981
982$PS_IMAGES = 0;
983
984$NO_IMAGES = 0;
985
986$IMAGES_ONLY = 0;
987
988$REUSE = 2;
989
990$ANTI_ALIAS = 1;
991
992$ANTI_ALIAS_TEXT = 1;
993
994#
995#Switches controlling Navigation Panels
996#
997$NO_NAVIGATION = 1;
998$ADDRESS = '';
999$INFO = 0;              # 0 = do not make a "About this document..." section
1000
1001#
1002#Switches for Linking to other documents
1003#
1004# actuall -- we don't care
1005
1006$MAX_SPLIT_DEPTH = 0;	# Stop making separate files at this depth
1007
1008$MAX_LINK_DEPTH = 0;    # Stop showing child nodes at this depth
1009
1010$NOLATEX = 0;           # 1 = do not pass unknown environments to Latex
1011
1012$EXTERNAL_IMAGES = 0;   # 1 = leave the images outside the document
1013
1014$ASCII_MODE = 0;        # 1 = do not use any icons or internal images
1015
1016# 1 =  use links to external postscript images rather than inlined bitmap
1017# images.
1018$PS_IMAGES = 0;
1019$SHOW_SECTION_NUMBERS = 0;
1020
1021### Other global variables ###############################################
1022$CHILDLINE = "";
1023
1024# This is the line width measured in pixels and it is used to right justify
1025# equations and equation arrays;
1026$LINE_WIDTH = 500;
1027
1028# Used in conjunction with AUTO_NAVIGATION
1029$WORDS_IN_PAGE = 300;
1030
1031# Affects ONLY the way accents are processed
1032$default_language = 'english';
1033
1034# The value of this variable determines how many words to use in each
1035# title that is added to the navigation panel (see below)
1036#
1037$WORDS_IN_NAVIGATION_PANEL_TITLES = 0;
1038
1039# This number will determine the size of the equations, special characters,
1040# and anything which will be converted into an inlined image
1041# *except* "image generating environments" such as "figure", "table"
1042# or "minipage".
1043# Effective values are those greater than 0.
1044# Sensible values are between 0.1 - 4.
1045$MATH_SCALE_FACTOR = 1.5;
1046
1047# This number will determine the size of
1048# image generating environments such as "figure", "table" or "minipage".
1049# Effective values are those greater than 0.
1050# Sensible values are between 0.1 - 4.
1051$FIGURE_SCALE_FACTOR = 1.6;
1052
1053
1054#  If both of the following two variables are set then the "Up" button
1055#  of the navigation panel in the first node/page of a converted document
1056#  will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set
1057#  to some text which describes this external link.
1058$EXTERNAL_UP_LINK = "";
1059$EXTERNAL_UP_TITLE = "";
1060
1061# If this is set then the resulting HTML will look marginally better if viewed
1062# with Netscape.
1063$NETSCAPE_HTML = 1;
1064
1065# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0"
1066# Paper sizes has no effect other than in the time it takes to create inlined
1067# images and in whether large images can be created at all ie
1068#  - larger paper sizes *MAY* help with large image problems
1069#  - smaller paper sizes are quicker to handle
1070$PAPERSIZE = "a4";
1071
1072# Replace "english" with another language in order to tell LaTeX2HTML that you
1073# want some generated section titles (eg "Table of Contents" or "References")
1074# to appear in a different language. Currently only "english" and "french"
1075# is supported but it is very easy to add your own. See the example in the
1076# file "latex2html.config"
1077$TITLES_LANGUAGE = "english";
1078
10791;	# This must be the last non-comment line
1080
1081# End File texi2html.init
1082######################################################################
1083
1084require "$ENV{T2H_HOME}/texi2html.init"
1085  if ($0 =~ /\.pl$/ &&
1086      -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init");
1087
1088#+++############################################################################
1089#                                                                              #
1090# Constants                                                                    #
1091#                                                                              #
1092#---############################################################################
1093
1094$DEBUG_TOC   =  1;
1095$DEBUG_INDEX =  2;
1096$DEBUG_BIB   =  4;
1097$DEBUG_GLOSS =  8;
1098$DEBUG_DEF   = 16;
1099$DEBUG_HTML  = 32;
1100$DEBUG_USER  = 64;
1101$DEBUG_L2H   = 128;
1102
1103
1104$BIBRE = '\[[\w\/-]+\]';		# RE for a bibliography reference
1105$FILERE = '[\/\w.+-]+';			# RE for a file name
1106$VARRE = '[^\s\{\}]+';			# RE for a variable name
1107$NODERE = '[^,:]+';		        # RE for a node name
1108$NODESRE = '[^:]+';		        # RE for a list of node names
1109
1110$ERROR = "***";			        # prefix for errors
1111$WARN  = "**";                          # prefix for warnings
1112
1113                                        # program home page
1114$PROTECTTAG = "_ThisIsProtected_";	# tag to recognize protected sections
1115
1116$CHAPTEREND = "<!-- End chapter -->\n"; # to know where a chpater ends
1117$SECTIONEND = "<!-- End section -->\n"; # to know where section ends
1118$TOPEND     = "<!-- End top     -->\n"; # to know where top ends
1119
1120
1121
1122#
1123# pre-defined indices
1124#
1125%predefined_index = (
1126		    'cp', 'c',
1127		    'fn', 'f',
1128		    'vr', 'v',
1129		    'ky', 'k',
1130		    'pg', 'p',
1131		    'tp', 't',
1132	            );
1133
1134#
1135# valid indices
1136#
1137%valid_index = (
1138		    'c', 1,
1139		    'f', 1,
1140		    'v', 1,
1141		    'k', 1,
1142		    'p', 1,
1143		    't', 1,
1144		);
1145
1146#
1147# texinfo section names to level
1148#
1149%sec2level = (
1150	      'top', 0,
1151	      'chapter', 1,
1152	      'unnumbered', 1,
1153	      'majorheading', 1,
1154	      'chapheading', 1,
1155	      'appendix', 1,
1156	      'section', 2,
1157	      'unnumberedsec', 2,
1158	      'heading', 2,
1159	      'appendixsec', 2,
1160	      'appendixsection', 2,
1161	      'subsection', 3,
1162	      'unnumberedsubsec', 3,
1163	      'subheading', 3,
1164	      'appendixsubsec', 3,
1165	      'subsubsection', 4,
1166	      'unnumberedsubsubsec', 4,
1167	      'subsubheading', 4,
1168	      'appendixsubsubsec', 4,
1169	      );
1170
1171#
1172# accent map, TeX command to ISO name
1173#
1174%accent_map = (
1175	       '"',  'uml',
1176	       '~',  'tilde',
1177	       '^',  'circ',
1178	       '`',  'grave',
1179	       '\'', 'acute',
1180	       );
1181
1182#
1183# texinfo "simple things" (@foo) to HTML ones
1184#
1185%simple_map = (
1186	       # cf. makeinfo.c
1187	       "*", "<BR>",		# HTML+
1188	       " ", " ",
1189	       "\t", " ",
1190  	       "-", "&#173;",	# soft hyphen
1191	       "\n", "\n",
1192	       "|", "",
1193	       'tab', '<\/TD><TD>',
1194	       # spacing commands
1195	       ":", "",
1196	       "!", "!",
1197	       "?", "?",
1198	       ".", ".",
1199	       "-", "",
1200	       );
1201
1202#
1203# texinfo "things" (@foo{}) to HTML ones
1204#
1205%things_map = (
1206	       'TeX', 'TeX',
1207	       'br', '<P>',		# paragraph break
1208	       'bullet', '*',
1209	       'copyright', '(C)',
1210	       'dots', '<small>...<\/small>',
1211	       'enddots', '<small>....<\/small>',
1212	       'equiv', '==',
1213	       'error', 'error-->',
1214	       'expansion', '==>',
1215	       'minus', '-',
1216	       'point', '-!-',
1217	       'print', '-|',
1218	       'result', '=>',
1219	       'today', $T2H_TODAY,
1220	       'aa', '&aring;',
1221	       'AA', '&Aring;',
1222	       'ae', '&aelig;',
1223	       'oe', '&#156;',
1224	       'AE', '&AElig;',
1225	       'OE', '&#140;',
1226	       'o',  '&oslash;',
1227	       'O',  '&Oslash;',
1228	       'ss', '&szlig;',
1229	       'l', '\/l',
1230	       'L', '\/L',
1231	       'exclamdown', '&iexcl;',
1232	       'questiondown', '&iquest;',
1233	       'pounds', '&pound;'
1234	       );
1235
1236#
1237# texinfo styles (@foo{bar}) to HTML ones
1238#
1239%style_map = (
1240	      'acronym', '&do_acronym',
1241	      'asis', '',
1242	      'b', 'B',
1243	      'cite', 'CITE',
1244	      'code', 'CODE',
1245	      'command', 'CODE',
1246	      'ctrl', '&do_ctrl',	# special case
1247	      'dfn', 'EM',		# DFN tag is illegal in the standard
1248	      'dmn', '',		# useless
1249	      'email', '&do_email',     # insert a clickable email address
1250	      'emph', 'EM',
1251	      'env', 'CODE',
1252	      'file', '"TT',		# will put quotes, cf. &apply_style
1253	      'i', 'I',
1254	      'kbd', 'KBD',
1255	      'key', 'KBD',
1256	      'math', '&do_math',
1257	      'option', '"SAMP',        # will put quotes, cf. &apply_style
1258	      'r', '',			# unsupported
1259	      'samp', '"SAMP',		# will put quotes, cf. &apply_style
1260	      'sc', '&do_sc',		# special case
1261	      'strong', 'STRONG',
1262	      't', 'TT',
1263	      'titlefont', '',		# useless
1264	      'uref', '&do_uref',       # insert a clickable URL
1265	      'url', '&do_url',         # insert a clickable URL
1266	      'var', 'VAR',
1267	      'w', '',			# unsupported
1268	      'H', '&do_accent',
1269	      'dotaccent', '&do_accent',
1270	      'ringaccent','&do_accent',
1271	      'tieaccent', '&do_accent',
1272	      'u','&do_accent',
1273	      'ubaraccent','&do_accent',
1274	      'udotaccent','&do_accent',
1275	      'v', '&do_accent',
1276	      ',', '&do_accent',
1277	      'dotless', '&do_accent'
1278	      );
1279
1280#
1281# texinfo format (@foo/@end foo) to HTML ones
1282#
1283%format_map = (
1284	       'quotation', 'BLOCKQUOTE',
1285	       # lists
1286	       'itemize', 'UL',
1287	       'enumerate', 'OL',
1288	       # poorly supported
1289	       'flushleft', 'PRE',
1290	       'flushright', 'PRE',
1291	       );
1292
1293#
1294# an eval of these $complex_format_map->{what}->[0] yields beginning
1295# an eval of these $complex_format_map->{what}->[1] yieleds end
1296$complex_format_map =
1297{
1298 example =>
1299 [
1300  q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td><pre>"},
1301  q{'</pre></td></tr></table>'}
1302 ],
1303 smallexample =>
1304 [
1305  q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre>"},
1306  q{'</FONT></pre></td></tr></table>'}
1307 ],
1308 display =>
1309 [
1310  q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td><pre " . 'style="font-family: serif">'},
1311  q{'</pre></td></tr></table>'}
1312 ],
1313 smalldisplay =>
1314 [
1315  q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre " . 'style="font-family: serif">'},
1316  q{'</pre></FONT></td></tr></table>'}
1317 ]
1318};
1319
1320$complex_format_map->{lisp} = $complex_format_map->{example};
1321$complex_format_map->{smalllisp} = $complex_format_map->{smallexample};
1322$complex_format_map->{format} = $complex_format_map->{display};
1323$complex_format_map->{smallformat} = $complex_format_map->{smalldisplay};
1324
1325#
1326# texinfo definition shortcuts to real ones
1327#
1328%def_map = (
1329	    # basic commands
1330	    'deffn', 0,
1331	    'defvr', 0,
1332	    'deftypefn', 0,
1333	    'deftypevr', 0,
1334	    'defcv', 0,
1335	    'defop', 0,
1336	    'deftp', 0,
1337	    # basic x commands
1338	    'deffnx', 0,
1339	    'defvrx', 0,
1340	    'deftypefnx', 0,
1341	    'deftypevrx', 0,
1342	    'defcvx', 0,
1343	    'defopx', 0,
1344	    'deftpx', 0,
1345	    # shortcuts
1346	    'defun', 'deffn Function',
1347	    'defmac', 'deffn Macro',
1348	    'defspec', 'deffn {Special Form}',
1349	    'defvar', 'defvr Variable',
1350	    'defopt', 'defvr {User Option}',
1351	    'deftypefun', 'deftypefn Function',
1352	    'deftypevar', 'deftypevr Variable',
1353	    'defivar', 'defcv {Instance Variable}',
1354	    'defmethod', 'defop Method',
1355	    # x shortcuts
1356	    'defunx', 'deffnx Function',
1357	    'defmacx', 'deffnx Macro',
1358	    'defspecx', 'deffnx {Special Form}',
1359	    'defvarx', 'defvrx Variable',
1360	    'defoptx', 'defvrx {User Option}',
1361	    'deftypefunx', 'deftypefnx Function',
1362	    'deftypevarx', 'deftypevrx Variable',
1363	    'defivarx', 'defcvx {Instance Variable}',
1364	    'defmethodx', 'defopx Method',
1365	    );
1366
1367#
1368# things to skip
1369#
1370%to_skip = (
1371	    # comments
1372	    'c', 1,
1373	    'comment', 1,
1374            'ifnotinfo', 1,
1375            'ifnottex', 1,
1376	    'ifhtml', 1,
1377	    'end ifhtml', 1,
1378            'end ifnotinfo', 1,
1379            'end ifnottex', 1,
1380	    # useless
1381	    'detailmenu', 1,
1382            'direntry', 1,
1383	    'contents', 1,
1384	    'shortcontents', 1,
1385	    'summarycontents', 1,
1386	    'footnotestyle', 1,
1387	    'end ifclear', 1,
1388	    'end ifset', 1,
1389	    'titlepage', 1,
1390	    'end titlepage', 1,
1391	    # unsupported commands (formatting)
1392	    'afourpaper', 1,
1393	    'cropmarks', 1,
1394	    'finalout', 1,
1395	    'headings', 1,
1396            'sp', 1,
1397	    'need', 1,
1398	    'page', 1,
1399	    'setchapternewpage', 1,
1400	    'everyheading', 1,
1401	    'everyfooting', 1,
1402	    'evenheading', 1,
1403	    'evenfooting', 1,
1404	    'oddheading', 1,
1405	    'oddfooting', 1,
1406	    'smallbook', 1,
1407	    'vskip', 1,
1408	    'filbreak', 1,
1409	    'paragraphindent', 1,
1410	    # unsupported formats
1411	    'cartouche', 1,
1412	    'end cartouche', 1,
1413	    'group', 1,
1414	    'end group', 1,
1415	    );
1416
1417#+++############################################################################
1418#                                                                              #
1419# Argument parsing, initialisation                                             #
1420#                                                                              #
1421#---############################################################################
1422
1423#
1424# flush stdout and stderr after every write
1425#
1426select(STDERR);
1427$| = 1;
1428select(STDOUT);
1429$| = 1;
1430
1431%value = ();				# hold texinfo variables, see also -D
1432
1433$use_bibliography = 1;
1434$use_acc = 1;
1435$usage = <<EOT;
1436This is $THISPROG
1437To convert a Texinfo file to HMTL: $0 [options] file
1438 where options can be:
1439  -expand [info,tex]     : expand info/tex sections
1440  -glossary              : handle a glossary
1441  -invisible <name>      : use <name> as an invisible anchor
1442  -D<name>               : define <name> as if with \@set
1443  -I <dir>               : search also for files in <dir>
1444  -init_file <file>      : use <file> for texi2html and latex2html initialization 
1445  -index_file <file>     : use <file> as index file
1446  -menu                  : handle menus
1447  -monolithic            : cancels out -split option
1448  -l2h                   : use latex2html for \@math, \@tex, and \@sc 
1449  -l2h_latex2html <prog> : use <prog> as latex2html program 
1450                           (default: 'latex2html')
1451  -l2h_tmp <dir>         : use <dir> as temp dir for latex2html
1452  -l2h_clean             : remove temporary files generated by l2h extension
1453  -l2h_skip              : skip latex2html run (needs temporary files)
1454  -number                : number sections
1455  -o file                : output into monlithic <file>
1456  -section_navigation    : use navigation panel for section
1457  -no-section_navigation : do not use navigation panel for sections
1458  -split section|chapter : split on section or chapter
1459  -split_{node|chapter}  : split on section or chapter
1460  -short_ref             : cross references without section numbers
1461  -subdir dir            : put HTML files into subdir <dir>
1462                           (default 'html')
1463  -usage, --help         : display these usage instructions and exit immediately
1464  -verbose               : verbose output
1465  -version, --version    : display version number and exit immediately
1466To check converted files: $0 -check [-verbose] files
1467EOT
1468# Not currently usaged
1469#  -sidx                  : index jump label to top of section
1470
1471my $home = $ENV{HOME};
1472defined($home) or $home = '';
1473foreach $i ('/usr/local/etc/texi2htmlrc', "$home/.texi2htmlrc") {
1474    if (-f $i) {
1475	print "# reading initialization file from $i\n"
1476	    if ($T2H_VERBOSE);
1477	require($i);
1478    }
1479}
1480
1481while (@ARGV && $ARGV[0] =~ /^-/) {
1482    $_ = shift(@ARGV);
1483    if (/^-acc$/)            { $use_acc = 1; next; }
1484    if (/^-D(.+)?$/)         { $value{$1 || shift(@ARGV)} = 1; next; }
1485    if (/^-d(?:ebug)?(\d+)?$/) { $T2H_DEBUG = $1 || shift(@ARGV); next; }
1486    if (/^-doctype$/)        { $T2H_DOCTYPE = shift(@ARGV); next; }
1487    if (/^-c(?:heck)?$/)       { $T2H_CHECK = 1; next; }
1488    if (/^-e(?:xpand)?$/)      { $T2H_EXPAND = shift(@ARGV); next; }
1489    if (/^-g(?:lossary)?$/)    { $T2H_USE_GLOSSARY = 1; next; }
1490    if (/^-id(?:x_sum)?$/)     { $T2H_IDX_SUMMARY = shift(@ARGV); next; }
1491    if (/^-i(?:nvisible)?$/)   { $T2H_INVISIBLE_MARK = shift(@ARGV); next; }
1492    if (/^-I(.+)?$/)         { push(@T2H_INCLUDE_DIRS, $1 || shift(@ARGV)); next; }
1493    if (/^-iso$/)            { $T2H_USE_ISO = 1; next; }
1494    if (/^-init_file$/)
1495    {
1496      $init_file = shift(@ARGV);
1497      if (-f $init_file)
1498      {
1499	print "# reading initialization file from $init_file\n"
1500	  if ($T2H_VERBOSE);
1501	require($init_file);
1502      }
1503      else
1504      {
1505	print "$ERROR Error: can't read init file $int_file\n";
1506	$init_file = '';
1507      }
1508      next;
1509    }
1510    if (/^-l(ang)?$/)        { $T2H_LANG = shift(@ARGV); next;}
1511    if (/^-l2h$/)            { $T2H_L2H     = 1;            next; }
1512    if (/^-l2h_l2h$/)        { $T2H_L2H_L2H = shift(@ARGV); next; }
1513    if (/^-l2h_skip$/)       { $T2H_L2H_SKIP= 1;            next; }
1514    if (/^-l2h_tmp$/)        { $T2H_L2H_TMP = shift(@ARGV); next; }
1515    if (/^-l2h_clean$/)      { $T2H_L2H_CLEAN= 1;            next; }
1516    if (/^-m(?:enu)?$/)        { $T2H_SHOW_MENU = 1; next; }
1517    if (/^-nu(?:mber)?$/)      { $T2H_NUMBER_SECTIONS = 1; next; }
1518    if (/^-o(?:ut_file)?$/)    { $T2H_OUT = shift (@ARGV);
1519                               undef $T2H_SPLIT; next;}
1520    if (/^-p(?:refix)?$/)      { $T2H_PREFIX = shift(@ARGV); next; }
1521    if (/^-su(?:bdir)?$/)      { $T2H_SUBDIR = shift(@ARGV); next; }
1522    if (/^-short_e(?:xtn)?$/)  { $T2H_SHORTEXTN = 1; next; }
1523    if (/^-short_r(?:ef)?$/)   { $T2H_SHORT_REF = 1; next; }
1524    # The following is because we want to remain compatible with
1525    # texi2html versions 1.5x and earlier while also allowing
1526    # `-s(plit)? (n(ode)?|c(hapter)?)' which 1.60beta used.  It's
1527    # important to remain compatible with 1.5x because many build
1528    # scripts use its syntax.  If anything, the 1.60beta syntax could
1529    # be dropped.
1530    if (/^-mono(?:lith(?:ic)?)?$/) { $T2H_SPLIT = undef; next; }
1531    if (/^-s(?:plit)?(_?)(n(?:ode)?|c(?:hapter)?)?$/) {
1532	if ($2 =~ /^n/) {
1533	    # 1.5x syntax.
1534	    $T2H_SPLIT = 'node';
1535	} elsif (("$1$2" eq '') && ($ARGV[0] =~ /^(?:no|none|node|section|chapter)$/i)) {
1536	    # 1.60beta syntax.
1537	    $T2H_SPLIT = shift(@ARGV);
1538	} else {
1539	    # 1.5x syntax.
1540	    $T2H_SPLIT = 'chapter';
1541	}
1542	next;
1543    }
1544    if (/^-t(?:op_file)?$/)    { $T2H_TOP_FILE = shift (@ARGV); next;}
1545    if (/^-v(?:erbose)?$/)     { $T2H_VERBOSE = 1; next; }
1546    if (/^-no_v(?:erbose)?$/)  { $T2H_VERBOSE = 0; next; }
1547    if (/^-section_navigation$/)  { $T2H_SECTION_NAVIGATION = 1; next; }
1548    if (/^-no-section_navigation$/)  { undef $T2H_SECTION_NAVIGATION; next; }
1549    if (/^--?vers(?:ion)?$/)   { print "$THISPROG\n"; exit;}
1550    if (/^-(?:usage|-help)/)   { print "$usage"; exit; }
1551    die "Unknown option: $_\n$usage";
1552}
1553if ($T2H_CHECK) {
1554    die "Need file to check\n$usage" unless @ARGV > 0;
1555    &check;
1556    exit;
1557}
1558
1559if ($T2H_EXPAND eq 'info')
1560{
1561  $to_skip{'ifinfo'} = 1;
1562  $to_skip{'end ifinfo'} = 1;
1563}
1564elsif ($T2H_EXPAND eq 'tex')
1565{
1566  $to_skip{'iftex'} = 1;
1567  $to_skip{'end iftex'} = 1;
1568
1569}
1570
1571$T2H_INVISIBLE_MARK = '<IMG SRC="invisible.xbm">' if $T2H_INVISIBLE_MARK eq 'xbm';
1572
1573#
1574# file name buisness
1575#
1576die "Need exactly one file to translate\n$usage" unless @ARGV == 1;
1577$docu = shift(@ARGV);
1578if ($docu =~ /.*\//) {
1579    chop($docu_dir = $&);
1580    $docu_name = $';
1581} else {
1582    $docu_dir = '.';
1583    $docu_name = $docu;
1584}
1585unshift(@T2H_INCLUDE_DIRS, $docu_dir);
1586$docu_name =~ s/\.te?x(i|info)?$//;	# basename of the document
1587$docu_name = $T2H_PREFIX if ($T2H_PREFIX);
1588
1589# subdir
1590if ($T2H_SUBDIR && ! $T2H_OUT)
1591{
1592  $T2H_SUBDIR =~ s|/*$||;
1593  unless (-d "$T2H_SUBDIR" && -w "$T2H_SUBDIR")
1594  {
1595    if ( mkdir($T2H_SUBDIR, oct(755)))
1596    {
1597      print "# created directory $T2H_SUBDIR\n" if ($T2H_VERBOSE);
1598    }
1599    else
1600    {
1601      warn "$ERROR can't create directory $T2H_SUBDIR. Put results into current directory\n";
1602      $T2H_SUBDIR = '';
1603    }
1604  }
1605}
1606
1607if ($T2H_SUBDIR && ! $T2H_OUT)
1608{
1609  $docu_rdir = "$T2H_SUBDIR/";
1610  print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE);
1611}
1612else
1613{
1614  if ($T2H_OUT && $T2H_OUT =~ m|(.*)/|)
1615  {
1616    $docu_rdir = "$1/";
1617    print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE);
1618  }
1619  else
1620  {
1621    print "# putting result files into current directory \n" if ($T2H_VERBOSE);
1622    $docu_rdir = '';
1623  }
1624}
1625
1626# extension
1627if ($T2H_SHORTEXTN)
1628{
1629  $docu_ext = "htm";
1630}
1631else
1632{
1633  $docu_ext = "html";
1634}
1635if ($T2H_TOP_FILE =~ /\..*$/)
1636{
1637  $T2H_TOP_FILE = $`.".$docu_ext";
1638}
1639else
1640{
1641  $T2H_TOP_FILE .= ".$docu_ext";
1642}
1643
1644# result files
1645if (! $T2H_OUT && ($T2H_SPLIT =~ /section/i || $T2H_SPLIT =~ /node/i))
1646{
1647  $T2H_SPLIT = 'section';
1648}
1649elsif (! $T2H_OUT && $T2H_SPLIT =~ /chapter/i)
1650{
1651  $T2H_SPLIT = 'chapter'
1652}
1653else
1654{
1655  undef $T2H_SPLIT;
1656}
1657
1658$docu_doc = "$docu_name.$docu_ext";		# document's contents
1659$docu_doc_file = "$docu_rdir$docu_doc";
1660if ($T2H_SPLIT)
1661{
1662  $docu_toc  = "${docu_name}_toc.$docu_ext"; # document's table of contents
1663  $docu_stoc = "${docu_name}_ovr.$docu_ext"; # document's short toc
1664  $docu_foot = "${docu_name}_fot.$docu_ext"; # document's footnotes
1665  $docu_about = "${docu_name}_abt.$docu_ext"; # about this document
1666  $docu_top  = $T2H_TOP_FILE;
1667}
1668else
1669{
1670  if ($T2H_OUT)
1671  {
1672    $docu_doc = $T2H_OUT;
1673    $docu_doc =~ s|.*/||;
1674  }
1675  $docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_top = $docu_doc;
1676}
1677
1678$docu_toc_file  = "$docu_rdir$docu_toc";
1679$docu_stoc_file = "$docu_rdir$docu_stoc";
1680$docu_foot_file = "$docu_rdir$docu_foot";
1681$docu_about_file = "$docu_rdir$docu_about";
1682$docu_top_file  = "$docu_rdir$docu_top";
1683
1684#
1685# variables
1686#
1687$value{'html'} = 1;			# predefine html (the output format)
1688$value{'texi2html'} = $THISVERSION;	# predefine texi2html (the translator)
1689# _foo: internal to track @foo
1690foreach ('_author', '_title', '_subtitle',
1691	 '_settitle', '_setfilename') {
1692    $value{$_} = '';		        # prevent -w warnings
1693}
1694%node2sec = ();				# node to section name
1695%sec2node = ();				# section to node name
1696%sec2number = ();                       # section to number
1697%number2sec = ();                       # number to section
1698%idx2node = ();                         # index keys to node
1699%node2href = ();			# node to HREF
1700%node2next = ();			# node to next
1701%node2prev = ();			# node to prev
1702%node2up   = ();			# node to up
1703%bib2href = ();				# bibliography reference to HREF
1704%gloss2href = ();			# glossary term to HREF
1705@sections = ();				# list of sections
1706%tag2pro = ();				# protected sections
1707
1708#
1709# initial indexes
1710#
1711$bib_num = 0;
1712$foot_num = 0;
1713$gloss_num = 0;
1714$idx_num = 0;
1715$sec_num = 0;
1716$doc_num = 0;
1717$html_num = 0;
1718
1719#
1720# can I use ISO8879 characters? (HTML+)
1721#
1722if ($T2H_USE_ISO) {
1723    $things_map{'bullet'} = "&bull;";
1724    $things_map{'copyright'} = "&copy;";
1725    $things_map{'dots'} = "&hellip;";
1726    $things_map{'equiv'} = "&equiv;";
1727    $things_map{'expansion'} = "&rarr;";
1728    $things_map{'point'} = "&lowast;";
1729    $things_map{'result'} = "&rArr;";
1730}
1731
1732#
1733# read texi2html extensions (if any)
1734#
1735$extensions = 'texi2html.ext'; # extensions in working directory
1736if (-f $extensions) {
1737    print "# reading extensions from $extensions\n" if $T2H_VERBOSE;
1738    require($extensions);
1739}
1740($progdir = $0) =~ s/[^\/]+$//;
1741if ($progdir && ($progdir ne './')) {
1742    $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory
1743    if (-f $extensions) {
1744	print "# reading extensions from $extensions\n" if $T2H_VERBOSE;
1745	require($extensions);
1746    }
1747}
1748
1749
1750#
1751# Check Language
1752#
1753if (! exists $T2H_WORDS->{$T2H_LANG})
1754{
1755  warn "$ERROR: Language specs for '$T2H_LANG' do not exists. Reverting to 'english'\n";
1756  $T2H_LANG = 'english'
1757}
1758print "# reading from $docu\n" if $T2H_VERBOSE;
1759
1760#########################################################################
1761#
1762# latex2html stuff
1763#
1764# latex2html conversions consist of three stages:
1765# 1) ToLatex: Put "latex" code into a latex file
1766# 2) ToHtml: Use latex2html to generate corresponding html code and images
1767# 3) FromHtml: Extract generated code and images from latex2html run
1768#
1769
1770##########################
1771# default settings
1772#
1773
1774# defaults for files and names
1775
1776sub l2h_Init
1777{
1778  local($root) = @_;
1779
1780  return 0 unless ($root);
1781
1782  $l2h_name =  "${root}_l2h";
1783
1784  $l2h_latex_file = "$docu_rdir${l2h_name}.tex";
1785  $l2h_cache_file = "${docu_rdir}l2h_cache.pm";
1786  $T2H_L2H_L2H = "latex2html" unless ($T2H_L2H_L2H);
1787
1788  # destination dir -- generated images are put there, should be the same
1789  # as dir of enclosing html document --
1790  $l2h_html_file = "$docu_rdir${l2h_name}.html";
1791  $l2h_prefix = "${l2h_name}_";
1792  return 1;
1793}
1794
1795
1796##########################
1797#
1798# First stage: Generation of Latex file
1799# Initialize with: l2h_InitToLatex
1800# Add content with: l2h_ToLatex($text) --> HTML placeholder comment
1801# Finish with: l2h_FinishToLatex
1802#
1803
1804$l2h_latex_preample = <<EOT;
1805% This document was automatically generated by the l2h extenstion of texi2html
1806% DO NOT EDIT !!!
1807\\documentclass{article}
1808\\usepackage{html}
1809\\begin{document}
1810EOT
1811
1812$l2h_latex_closing = <<EOT;
1813\\end{document}
1814EOT
1815
1816# return used latex 1, if l2h could be initalized properly, 0 otherwise
1817sub l2h_InitToLatex
1818{
1819  %l2h_to_latex = ();
1820  unless ($T2H_L2H_SKIP)
1821  {
1822    unless (open(L2H_LATEX, ">$l2h_latex_file"))
1823    {
1824      warn "$ERROR Error l2h: Can't open latex file '$latex_file' for writing\n";
1825      return 0;
1826    }
1827    print "# l2h: use ${l2h_latex_file} as latex file\n" if ($T2H_VERBOSE);
1828    print L2H_LATEX $l2h_latex_preample;
1829  }
1830  # open database for caching
1831  l2h_InitCache();
1832  $l2h_latex_count = 0;
1833  $l2h_to_latex_count = 0;
1834  $l2h_cached_count = 0;
1835  return  1;
1836}
1837
1838# print text (1st arg) into latex file (if not already there), return
1839# HTML commentary which can be later on replaced by the latex2html
1840# generated text
1841sub l2h_ToLatex
1842{
1843  my($text) = @_;
1844  my($count);
1845
1846  $l2h_to_latex_count++;
1847  $text =~ s/(\s*)$//;
1848
1849  # try whether we can cache it
1850  my $cached_text = l2h_FromCache($text);
1851  if ($cached_text)
1852  {
1853    $l2h_cached_count++;
1854    return $cached_text;
1855  }
1856
1857  # try whether we have text already on things to do
1858  unless ($count = $l2h_to_latex{$text})
1859  {
1860    $count = $l2h_latex_count;
1861    $l2h_latex_count++;
1862    $l2h_to_latex{$text} = $count;
1863    $l2h_to_latex[$count] = $text;
1864    unless ($T2H_L2H_SKIP)
1865    {
1866      print L2H_LATEX "\\begin{rawhtml}\n";
1867      print L2H_LATEX "<!-- l2h_begin ${l2h_name} ${count} -->\n";
1868      print L2H_LATEX "\\end{rawhtml}\n";
1869
1870      print L2H_LATEX "$text\n";
1871
1872      print L2H_LATEX "\\begin{rawhtml}\n";
1873      print L2H_LATEX "<!-- l2h_end ${l2h_name} ${count} -->\n";
1874      print L2H_LATEX "\\end{rawhtml}\n";
1875    }
1876  }
1877  return "<!-- l2h_replace ${l2h_name} ${count} -->";
1878}
1879
1880# print closing into latex file and close it
1881sub l2h_FinishToLatex
1882{
1883  local ($reused);
1884
1885  $reused = $l2h_to_latex_count - $l2h_latex_count - $l2h_cached_count;
1886  unless ($T2H_L2H_SKIP)
1887  {
1888    print L2H_LATEX $l2h_latex_closing;
1889    close(L2H_LATEX);
1890  }
1891  print "# l2h: finished to latex ($l2h_cached_count cached, $reused reused, $l2h_latex_count contents)\n" if ($T2H_VERBOSE);
1892  unless ($l2h_latex_count)
1893  {
1894    l2h_Finish();
1895    return 0;
1896  }
1897  return 1;
1898}
1899
1900###################################
1901# Second stage: Use latex2html to generate corresponding html code and images
1902#
1903# l2h_ToHtml([$l2h_latex_file, [$l2h_html_dir]]):
1904#   Call latex2html on $l2h_latex_file
1905#   Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir
1906#   Return 1, on success
1907#          0, otherwise
1908#
1909sub l2h_ToHtml
1910{
1911  local($call, $ext, $root, $dotbug);
1912
1913  if ($T2H_L2H_SKIP)
1914  {
1915    print "# l2h: skipping latex2html run\n" if ($T2H_VERBOSE);
1916    return 1;
1917  }
1918
1919  # Check for dot in directory where dvips will work
1920  if ($T2H_L2H_TMP)
1921  {
1922    if ($T2H_L2H_TMP =~ /\./)
1923    {
1924      warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n";
1925      $dotbug = 1;
1926    }
1927  }
1928  else
1929  {
1930    if (&getcwd =~ /\./)
1931    {
1932     warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n";
1933     $dotbug = 1;
1934   }
1935  }
1936  # fix it, if necessary and hope that it works
1937  $T2H_L2H_TMP = "/tmp" if ($dotbug);
1938
1939  $call = $T2H_L2H_L2H;
1940  # use init file, if specified
1941  $call = $call . " -init_file " . $init_file if ($init_file && -f $init_file);
1942  # set output dir
1943  $call .=  ($docu_rdir ? " -dir $docu_rdir" : " -no_subdir");
1944  # use l2h_tmp, if specified
1945  $call = $call . " -tmp $T2H_L2H_TMP" if ($T2H_L2H_TMP);
1946  # options we want to be sure of
1947  $call = $call ." -address 0 -info 0 -split 0 -no_navigation -no_auto_link";
1948  $call = $call ." -prefix ${l2h_prefix} $l2h_latex_file";
1949
1950  print "# l2h: executing '$call'\n" if ($T2H_VERBOSE);
1951  if (system($call))
1952  {
1953    warn "l2h ***Error: '${call}' did not succeed\n";
1954    return 0;
1955  }
1956  else
1957  {
1958    print "# l2h: latex2html finished successfully\n" if ($T2H_VERBOSE);
1959    return 1;
1960  }
1961}
1962
1963# this is directly pasted over from latex2html
1964sub getcwd {
1965    local($_) = `pwd`;
1966
1967    die "'pwd' failed (out of memory?)\n"
1968	unless length;
1969    chop;
1970    $_;
1971}
1972
1973
1974##########################
1975# Third stage: Extract generated contents from latex2html run
1976# Initialize with: l2h_InitFromHtml
1977#   open $l2h_html_file for reading
1978#   reads in contents into array indexed by numbers
1979#   return 1,  on success -- 0, otherwise
1980# Extract Html code with: l2h_FromHtml($text)
1981#   replaces in $text all previosuly inserted comments by generated html code
1982#   returns (possibly changed) $text
1983# Finish with: l2h_FinishFromHtml
1984#   closes $l2h_html_dir/$l2h_name.".$docu_ext"
1985
1986sub l2h_InitFromHtml
1987{
1988  local($h_line, $h_content, $count, %l2h_img);
1989
1990  if (! open(L2H_HTML, "<${l2h_html_file}"))
1991  {
1992    print "$ERROR Error l2h: Can't open ${l2h_html_file} for reading\n";
1993    return 0;
1994  }
1995  print "# l2h: use ${l2h_html_file} as html file\n" if ($T2H_VERBOSE);
1996
1997  $l2h_html_count = 0;
1998
1999  while ($h_line = <L2H_HTML>)
2000  {
2001    if ($h_line =~ /^<!-- l2h_begin $l2h_name ([0-9]+) -->/)
2002    {
2003      $count = $1;
2004      $h_content = "";
2005      while ($h_line = <L2H_HTML>)
2006      {
2007	if ($h_line =~ /^<!-- l2h_end $l2h_name $count -->/)
2008	{
2009	  chomp $h_content;
2010	  chomp $h_content;
2011	  $l2h_html_count++;
2012	  $h_content = l2h_ToCache($count, $h_content);
2013	  $l2h_from_html[$count] = $h_content;
2014	  $h_content = '';
2015	  last;
2016	}
2017	$h_content = $h_content.$h_line;
2018      }
2019      if ($hcontent)
2020      {
2021	print "$ERROR Warning l2h: l2h_end $l2h_name $count not found\n"
2022	  if ($T2H_VERBOSE);
2023	close(L2H_HTML);
2024	return 0;
2025      }
2026    }
2027  }
2028  print "# l2h: Got $l2h_html_count of $l2h_latex_count html contents\n"
2029    if ($T2H_VERBOSE);
2030
2031  close(L2H_HTML);
2032  return 1;
2033}
2034
2035sub l2h_FromHtml
2036{
2037  local($text) = @_;
2038  local($done, $to_do, $count);
2039
2040  $to_do = $text;
2041
2042  while ($to_do =~ /([^\000]*)<!-- l2h_replace $l2h_name ([0-9]+) -->([^\000]*)/)
2043  {
2044    $to_do = $1;
2045    $count = $2;
2046    $done = $3.$done;
2047
2048    $done = "<!-- l2h_end $l2h_name $count -->".$done
2049      if ($T2H_DEBUG & $DEBUG_L2H);
2050
2051    $done = &l2h_ExtractFromHtml($count) . $done;
2052
2053    $done = "<!-- l2h_begin $l2h_name $count -->".$done
2054      if ($T2H_DEBUG & $DEBUG_L2H);
2055  }
2056  return $to_do.$done;
2057}
2058
2059
2060sub l2h_ExtractFromHtml
2061{
2062  local($count) = @_;
2063
2064  return $l2h_from_html[$count] if ($l2h_from_html[$count]);
2065
2066  if ($count >= 0 && $count < $l2h_latex_count)
2067  {
2068    # now we are in trouble
2069    local($l_l2h, $_);
2070
2071    $l2h_extract_error++;
2072    print "$ERROR l2h: can't extract content $count from html\n"
2073      if ($T2H_VERBOSE);
2074    # try simple (ordinary) substition (without l2h)
2075    $l_l2h = $T2H_L2H;
2076    $T2H_L2H = 0;
2077    $_ = $l2h_to_latex{$count};
2078    $_ = &substitute_style($_);
2079    &unprotect_texi;
2080    $_ = "<!-- l2h: ". __LINE__ . " use texi2html -->" . $_
2081      if ($T2H_DEBUG & $DEBUG_L2H);
2082    $T2H_L2H = $l_l2h;
2083    return $_;
2084  }
2085  else
2086  {
2087    # now we have been incorrectly called
2088    $l2h_range_error++;
2089    print "$ERROR l2h: Request of $count content which is out of valide range [0,$l2h_latex_count)\n";
2090    return "<!-- l2h: ". __LINE__ . " out of range count $count -->"
2091      if ($T2H_DEBUG & $DEBUG_L2H);
2092    return "<!-- l2h: out of range count $count -->";
2093  }
2094}
2095
2096sub l2h_FinishFromHtml
2097{
2098  if ($T2H_VERBOSE)
2099  {
2100    if ($l2h_extract_error + $l2h_range_error)
2101    {
2102      print "# l2h: finished from html ($l2h_extract_error extract and $l2h_range_error errors)\n";
2103    }
2104    else
2105    {
2106      print "# l2h: finished from html (no errors)\n";
2107    }
2108  }
2109}
2110
2111sub l2h_Finish
2112{
2113  l2h_StoreCache();
2114  if ($T2H_L2H_CLEAN)
2115  {
2116    print "# l2h: removing temporary files generated by l2h extension\n"
2117      if $T2H_VERBOSE;
2118    while (<"$docu_rdir$l2h_name"*>)
2119    {
2120      unlink $_;
2121    }
2122  }
2123  print "# l2h: Finished\n" if $T2H_VERBOSE;
2124  return 1;
2125}
2126
2127##############################
2128# stuff for l2h caching
2129#
2130
2131# I tried doing this with a dbm data base, but it did not store all
2132# keys/values. Hence, I did as latex2html does it
2133sub l2h_InitCache
2134{
2135  if (-r "$l2h_cache_file")
2136  {
2137    my $rdo = do "$l2h_cache_file";
2138    warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n")
2139      unless ($rdo);
2140  }
2141}
2142
2143sub l2h_StoreCache
2144{
2145  return unless $l2h_latex_count;
2146
2147  my ($key, $value);
2148  open(FH, ">$l2h_cache_file") || return warn"$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n";
2149
2150
2151  while (($key, $value) = each %l2h_cache)
2152  {
2153    # escape stuff
2154    $key =~ s|/|\\/|g;
2155    $key =~ s|\\\\/|\\/|g;
2156    # weird, a \ at the end of the key results in an error
2157    # maybe this also broke the dbm database stuff
2158    $key =~ s|\\$|\\\\|;
2159    $value =~ s/\|/\\\|/g;
2160    $value =~ s/\\\\\|/\\\|/g;
2161    $value =~ s|\\\\|\\\\\\\\|g;
2162    print FH "\n\$l2h_cache_key = q/$key/;\n";
2163    print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n";
2164  }
2165  print FH "1;";
2166  close(FH);
2167}
2168
2169# return cached html, if it exists for text, and if all pictures
2170# are there, as well
2171sub l2h_FromCache
2172{
2173  my $text = shift;
2174  my $cached = $l2h_cache{$text};
2175  if ($cached)
2176  {
2177    while ($cached =~ m/SRC="(.*?)"/g)
2178    {
2179      unless (-e "$docu_rdir$1")
2180      {
2181	return undef;
2182      }
2183    }
2184    return $cached;
2185  }
2186  return undef;
2187}
2188
2189# insert generated html into cache, move away images,
2190# return transformed html
2191$maximage = 1;
2192sub l2h_ToCache
2193{
2194  my $count = shift;
2195  my $content = shift;
2196  my @images = ($content =~ /SRC="(.*?)"/g);
2197  my ($src, $dest);
2198
2199  for $src (@images)
2200  {
2201    $dest = $l2h_img{$src};
2202    unless ($dest)
2203    {
2204      my $ext;
2205      if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext)
2206      {
2207	$ext = $1;
2208      }
2209      else
2210      {
2211	warn "$ERROR: L2h image $src has invalid extension\n";
2212	next;
2213      }
2214      while (-e "$docu_rdir${docu_name}_$maximage.$ext") { $maximage++;}
2215      $dest = "${docu_name}_$maximage.$ext";
2216      system("cp -f $docu_rdir$src $docu_rdir$dest");
2217      $l2h_img{$src} = $dest;
2218      unlink "$docu_rdir$src" unless ($DEBUG & DEBUG_L2H);
2219    }
2220    $content =~ s/$src/$dest/g;
2221  }
2222  $l2h_cache{$l2h_to_latex[$count]} = $content;
2223  return $content;
2224}
2225
2226
2227#+++############################################################################
2228#                                                                              #
2229# Pass 1: read source, handle command, variable, simple substitution           #
2230#                                                                              #
2231#---############################################################################
2232
2233@lines = ();				# whole document
2234@toc_lines = ();			# table of contents
2235@stoc_lines = ();			# table of contents
2236$curlevel = 0;				# current level in TOC
2237$node = '';				# current node name
2238$node_next = '';                        # current node next name
2239$node_prev = '';                        # current node prev name
2240$node_up = '';                          # current node up name
2241$in_table = 0;				# am I inside a table
2242$table_type = '';			# type of table ('', 'f', 'v', 'multi')
2243@tables = ();			        # nested table support
2244$in_bibliography = 0;			# am I inside a bibliography
2245$in_glossary = 0;			# am I inside a glossary
2246$in_top = 0;				# am I inside the top node
2247$has_top = 0;				# did I see a top node?
2248$has_top_command = 0;                   # did I see @top for automatic pointers?
2249$in_pre = 0;				# am I inside a preformatted section
2250$in_list = 0;				# am I inside a list
2251$in_html = 0;				# am I inside an HTML section
2252$first_line = 1;		        # is it the first line
2253$dont_html = 0;				# don't protect HTML on this line
2254$deferred_ref = '';			# deferred reference for indexes
2255@html_stack = ();			# HTML elements stack
2256$html_element = '';			# current HTML element
2257&html_reset;
2258%macros = ();                           # macros
2259
2260# init l2h
2261$T2H_L2H = &l2h_Init($docu_name) if ($T2H_L2H);
2262$T2H_L2H = &l2h_InitToLatex      if ($T2H_L2H);
2263
2264# build code for simple substitutions
2265# the maps used (%simple_map and %things_map) MUST be aware of this
2266# watch out for regexps, / and escaped characters!
2267$subst_code = '';
2268foreach (keys(%simple_map)) {
2269    ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars
2270    $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n";
2271}
2272foreach (keys(%things_map)) {
2273    $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n";
2274}
2275if ($use_acc) {
2276    # accentuated characters
2277    foreach (keys(%accent_map)) {
2278	if ($_ eq "`") {
2279	    $subst_code .= "s/$;3";
2280	} elsif ($_ eq "'") {
2281	    $subst_code .= "s/$;4";
2282	} else {
2283	    $subst_code .= "s/\\\@\\$_";
2284	}
2285	$subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n";
2286    }
2287}
2288eval("sub simple_substitutions { $subst_code }");
2289
2290&init_input;
2291INPUT_LINE: while ($_ = &next_line) {
2292    #
2293    # remove \input on the first lines only
2294    #
2295    if ($first_line) {
2296	next if /^\\input/;
2297	$first_line = 0;
2298    }
2299    # non-@ substitutions cf. texinfmt.el
2300    #
2301    # parse texinfo tags
2302    #
2303    $tag = '';
2304    $end_tag = '';
2305    if (/^\s*\@end\s+(\w+)\b/) {
2306	$end_tag = $1;
2307    } elsif (/^\s*\@(\w+)\b/) {
2308	$tag = $1;
2309    }
2310    #
2311    # handle @html / @end html
2312    #
2313    if ($in_html) {
2314	if ($end_tag eq 'html') {
2315	    $in_html = 0;
2316	} else {
2317	    $tag2pro{$in_html} .= $_;
2318	}
2319	next;
2320    } elsif ($tag eq 'html') {
2321	$in_html = $PROTECTTAG . ++$html_num;
2322	push(@lines, $in_html);
2323	next;
2324    }
2325
2326    #
2327    # try to remove inlined comments
2328    # syntax from tex-mode.el comment-start-skip
2329    #
2330    s/((^|[^\@])(\@\@)*)\@c(omment | |\{|$).*/$1/;
2331
2332# Sometimes I use @c right at the end of  a line ( to suppress the line feed )
2333#    s/((^|[^\@])(\@\@)*)\@c(omment)?$/$1/;
2334#     s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/;
2335#     s/(.*)\@c{.*?}(.*)/$1$2/;
2336#     s/(.*)\@comment{.*?}(.*)/$1$2/;
2337#     s/^(.*)\@c /$1/;
2338#     s/^(.*)\@comment /$1/;
2339
2340    #############################################################
2341    # macro substitution
2342    while (/\@(\w+)/g)
2343    {
2344      if (exists($macros->{$1}))
2345      {
2346	my $before = $`;
2347	my $name = $1;
2348	my $after = $';
2349	my @args;
2350	if ($after =~ /^\s*{(.*?)}(.*)/)
2351	{
2352	  @args = split(/\s*,\s*/, $1);
2353	  $after = $2;
2354	}
2355	my $macrobody = $macros->{$name}->{Body};
2356	for ($i=0; $i<=$#args; $i++)
2357	{
2358	  $macrobody =~ s|\\$macros->{$name}->{Args}->[$i]\\|$args[$i]|g;
2359	}
2360	$macrobody =~ s|\\\\|\\|g;
2361	$_ = $before . $macrobody . $after;
2362	unshift @input_spool, map {$_ = $_."\n"} split(/\n/, $_);
2363	next INPUT_LINE;
2364      }
2365    }				#
2366
2367
2368    #
2369    # try to skip the line
2370    #
2371    if ($end_tag) {
2372	next if $to_skip{"end $end_tag"};
2373    } elsif ($tag) {
2374	next if $to_skip{$tag};
2375	last if $tag eq 'bye';
2376    }
2377    if ($in_top) {
2378	# parsing the top node
2379	if ($tag eq 'node' || $tag eq 'include' ||
2380	    ($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/))
2381	{
2382	    # no more in top
2383	    $in_top = 0;
2384	    push(@lines, $TOPEND);
2385	}
2386    }
2387    unless ($in_pre) {
2388	s/``/\"/g;
2389	s/''/\"/g;
2390	s/([\w ])---([\w ])/$1--$2/g;
2391    }
2392    #
2393    # analyze the tag
2394    #
2395    if ($tag) {
2396	# skip lines
2397	&skip_until($tag), next if $tag eq 'ignore';
2398	&skip_until($tag), next if $tag eq 'ifnothtml';
2399	if ($tag eq 'ifinfo')
2400	{
2401	  &skip_until($tag), next unless $T2H_EXPAND eq 'info';
2402	}
2403	if ($tag eq 'iftex')
2404	{
2405	  &skip_until($tag), next unless $T2H_EXPAND eq 'tex';
2406	}
2407	if ($tag eq 'tex')
2408	{
2409	  # add to latex2html file
2410	  if ($T2H_EXPAND eq 'tex' && $T2H_L2H && ! $in_pre)
2411	  {
2412	    # add space to the end -- tex(i2dvi) does this, as well
2413	    push(@lines, &l2h_ToLatex(&string_until($tag) . " "));
2414	  }
2415	  else
2416	  {
2417	    &skip_until($tag);
2418	  }
2419	  next;
2420	}
2421	# handle special tables
2422	if ($tag =~ /^(|f|v|multi)table$/) {
2423	    $table_type = $1;
2424	    $tag = 'table';
2425	}
2426	# special cases
2427	if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) {
2428	    $in_top = 1;
2429	    $has_top = 1;
2430	    $has_top_command = 1 if $tag eq 'top';
2431	    @lines = (); # ignore all lines before top (title page garbage)
2432	    next;
2433	} elsif ($tag eq 'node') {
2434	  if ($in_top)
2435	  {
2436	    $in_top = 0;
2437	    push(@lines, $TOPEND);
2438	  }
2439	  warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o;
2440	  $_ = &protect_html($_); # if node contains '&' for instance
2441	  s/^\@node\s+//;
2442	  ($node, $node_next, $node_prev, $node_up) = split(/,/);
2443	  &normalise_node($node);
2444	  &normalise_node($node_next);
2445	  &normalise_node($node_prev);
2446	  &normalise_node($node_up);
2447	  next;
2448	} elsif ($tag eq 'include') {
2449	    if (/^\@include\s+($FILERE)\s*$/o) {
2450		$file = LocateIncludeFile($1);
2451		if ($file && -e $file) {
2452		    &open($file);
2453		    print "# including $file\n" if $T2H_VERBOSE;
2454		} else {
2455		    warn "$ERROR Can't find $file, skipping";
2456		}
2457	    } else {
2458		warn "$ERROR Bad include line: $_";
2459	    }
2460	    next;
2461	} elsif ($tag eq 'ifclear') {
2462	    if (/^\@ifclear\s+($VARRE)\s*$/o) {
2463		next unless defined($value{$1});
2464		&skip_until($tag);
2465	    } else {
2466		warn "$ERROR Bad ifclear line: $_";
2467	    }
2468	    next;
2469	} elsif ($tag eq 'ifset') {
2470	    if (/^\@ifset\s+($VARRE)\s*$/o) {
2471		next if defined($value{$1});
2472		&skip_until($tag);
2473	    } else {
2474		warn "$ERROR Bad ifset line: $_";
2475	    }
2476	    next;
2477	} elsif ($tag eq 'menu') {
2478	    unless ($T2H_SHOW_MENU) {
2479		&skip_until($tag);
2480		next;
2481	    }
2482	    &html_push_if($tag);
2483	    push(@lines, &html_debug('', __LINE__));
2484	} elsif ($format_map{$tag}) {
2485	    $in_pre = 1 if $format_map{$tag} eq 'PRE';
2486	    &html_push_if($format_map{$tag});
2487	    push(@lines, &html_debug('', __LINE__));
2488	    $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ;
2489#	    push(@lines, &debug("<BLOCKQUOTE>\n", __LINE__))
2490#	      if $tag =~ /example/i;
2491	    # sunshine@sunshineco.com: <PRE>bla</PRE> looks better than
2492	    # <PRE>\nbla</PRE> (at least on NeXTstep browser
2493	    push(@lines, &debug("<$format_map{$tag}>" .
2494				($in_pre ? '' : "\n"), __LINE__));
2495	    next;
2496	}
2497	elsif (exists $complex_format_map->{$tag})
2498	{
2499	  my $start = eval $complex_format_map->{$tag}->[0];
2500	  if ($@)
2501	  {
2502	    print "$ERROR: eval of complex_format_map->{$tag}->[0] $complex_format_map->{$tag}->[0]: $@";
2503	    $start = '<pre>'
2504	  }
2505	  $in_pre = 1 if $start =~ /<pre/;
2506	  push(@lines, html_debug($start. ($in_pre ? '' : "\n"), __LINE__));
2507	  next;
2508	} elsif ($tag eq 'table') {
2509	  # anorland@hem2.passagen.se
2510	  # if (/^\s*\@(|f|v|multi)table\s+\@(\w+)/) {
2511	     if (/^\s*\@(|f|v|multi)table\s+\@(\w+)|(\{[^\}]*\})/) {
2512		$in_table = $2;
2513		unshift(@tables, join($;, $table_type, $in_table));
2514		if ($table_type eq "multi") {
2515		    # don't use borders -- gets confused by empty cells
2516		    push(@lines, &debug("<TABLE>\n", __LINE__));
2517		    &html_push_if('TABLE');
2518		} else {
2519		    push(@lines, &debug("<DL COMPACT>\n", __LINE__));
2520		    &html_push_if('DL');
2521		}
2522		push(@lines, &html_debug('', __LINE__));
2523	    } else {
2524		warn "$ERROR Bad table line: $_";
2525	    }
2526	    next;
2527	} elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') {
2528	    if (/^\@$tag\s+(\w)\w\s+(\w)\w\s*$/) {
2529		eval("*${1}index = *${2}index");
2530	    } else {
2531		warn "$ERROR Bad syn*index line: $_";
2532	    }
2533	    next;
2534	} elsif ($tag eq 'sp') {
2535	    push(@lines, &debug("<P>\n", __LINE__));
2536	    next;
2537	} elsif ($tag eq 'center') {
2538	    push(@lines, &debug("<center>\n", __LINE__));
2539	    s/\@center//;
2540	} elsif ($tag eq 'setref') {
2541	    &protect_html; # if setref contains '&' for instance
2542	    if (/^\@$tag\s*{($NODERE)}\s*$/) {
2543		$setref = $1;
2544		$setref =~ s/\s+/ /g; # normalize
2545		$setref =~ s/ $//;
2546		$node2sec{$setref} = $name;
2547		$sec2node{$name} = $setref;
2548		$node2href{$setref} = "$docu_doc#$docid";
2549	    } else {
2550		warn "$ERROR Bad setref line: $_";
2551	    }
2552	    next;
2553	} elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') {
2554	    if (/^\@$tag\s+(\w\w)\s*$/) {
2555		$valid_index{$1} = 1;
2556	    } else {
2557		warn "$ERROR Bad defindex line: $_";
2558	    }
2559	    next;
2560	} elsif ($tag eq 'lowersections') {
2561	    local ($sec, $level);
2562	    while (($sec, $level) = each %sec2level) {
2563		$sec2level{$sec} = $level + 1;
2564	    }
2565	    next;
2566	} elsif ($tag eq 'raisesections') {
2567	    local ($sec, $level);
2568	    while (($sec, $level) = each %sec2level) {
2569		$sec2level{$sec} = $level - 1;
2570	    }
2571	    next;
2572	}
2573	elsif ($tag eq 'macro' || $tag eq 'rmacro')
2574	{
2575	  if (/^\@$tag\s*(\w+)\s*(.*)/)
2576	  {
2577	    my $name = $1;
2578	    my @args;
2579	    @args = split(/\s*,\s*/ , $1)
2580	      if ($2 =~ /^\s*{(.*)}\s*/);
2581
2582	    $macros->{$name}->{Args} = \@args;
2583	    $macros->{$name}->{Body} = '';
2584	    while (($_ = &next_line) !~ /\@end $tag/)
2585	    {
2586	      $macros->{$name}->{Body} .= $_;
2587	    }
2588	    chomp $macros->{$name}->{Body};
2589	  }
2590	  else
2591	  {
2592	    warn "$ERROR: Bad macro defintion $_"
2593	  }
2594	  next;
2595	}
2596	elsif ($tag eq 'unmacro')
2597	{
2598	  delete $macros->{$1} if (/^\@unmacro\s*(\w+)/);
2599	}
2600	elsif (defined($def_map{$tag})) {
2601	    if ($def_map{$tag}) {
2602		s/^\@$tag\s+//;
2603		$tag = $def_map{$tag};
2604		$_ = "\@$tag $_";
2605		$tag =~ s/\s.*//;
2606	    }
2607	} elsif (defined($user_sub{$tag})) {
2608	    s/^\@$tag\s+//;
2609	    $sub = $user_sub{$tag};
2610	    print "# user $tag = $sub, arg: $_" if $T2H_DEBUG & $DEBUG_USER;
2611	    if (defined(&$sub)) {
2612		chop($_);
2613		&$sub($_);
2614	    } else {
2615		warn "$ERROR Bad user sub for $tag: $sub\n";
2616	    }
2617	    next;
2618	  }
2619	if (defined($def_map{$tag})) {
2620	    s/^\@$tag\s+//;
2621	    if ($tag =~ /x$/) {
2622		# extra definition line
2623		$tag = $`;
2624		$is_extra = 1;
2625	    } else {
2626		$is_extra = 0;
2627	    }
2628	    while (/\{([^\{\}]*)\}/) {
2629		# this is a {} construct
2630		($before, $contents, $after) = ($`, $1, $');
2631		# protect spaces
2632		$contents =~ s/\s+/$;9/g;
2633		# restore $_ protecting {}
2634		$_ = "$before$;7$contents$;8$after";
2635	    }
2636	    @args = split(/\s+/, &protect_html($_));
2637	    foreach (@args) {
2638		s/$;9/ /g;	# unprotect spaces
2639		s/$;7/\{/g;	# ... {
2640		s/$;8/\}/g;	# ... }
2641	    }
2642	    $type = shift(@args);
2643	    $type =~ s/^\{(.*)\}$/$1/;
2644	    print "# def ($tag): {$type} ", join(', ', @args), "\n"
2645		if $T2H_DEBUG & $DEBUG_DEF;
2646	    $type .= ':'; # it's nicer like this
2647	    my $name = shift(@args);
2648	    $name =~ s/^\{(.*)\}$/$1/;
2649	    if ($is_extra) {
2650		$_ = &debug("<DT>", __LINE__);
2651	    } else {
2652		$_ = &debug("<DL>\n<DT>", __LINE__);
2653	    }
2654	    if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') {
2655		$_ .= "<U>$type</U> <B>$name</B>";
2656		$_ .= " <I>@args</I>" if @args;
2657	    } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr'
2658		     || $tag eq 'defcv' || $tag eq 'defop') {
2659		$ftype = $name;
2660		$name = shift(@args);
2661		$name =~ s/^\{(.*)\}$/$1/;
2662		$_ .= "<U>$type</U> $ftype <B>$name</B>";
2663		$_ .= " <I>@args</I>" if @args;
2664	    } else {
2665		warn "$ERROR Unknown definition type: $tag\n";
2666		$_ .= "<U>$type</U> <B>$name</B>";
2667		$_ .= " <I>@args</I>" if @args;
2668	    }
2669 	    $_ .= &debug("\n<DD>", __LINE__);
2670	    $name = &unprotect_html($name);
2671	    if ($tag eq 'deffn' || $tag eq 'deftypefn') {
2672		unshift(@input_spool, "\@findex $name\n");
2673	    } elsif ($tag eq 'defop') {
2674		unshift(@input_spool, "\@findex $name on $ftype\n");
2675	    } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') {
2676		unshift(@input_spool, "\@vindex $name\n");
2677	    } else {
2678		unshift(@input_spool, "\@tindex $name\n");
2679	    }
2680	    $dont_html = 1;
2681	}
2682    } elsif ($end_tag) {
2683	if ($format_map{$end_tag}) {
2684	    $in_pre = 0 if $format_map{$end_tag} eq 'PRE';
2685	    $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ;
2686	    &html_pop_if('LI', 'P');
2687	    &html_pop_if();
2688	    push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__));
2689	    push(@lines, &html_debug('', __LINE__));
2690	}
2691	elsif (exists $complex_format_map->{$end_tag})
2692	{
2693	  my $end = eval $complex_format_map->{$end_tag}->[1];
2694	  if ($@)
2695	  {
2696	    print "$ERROR: eval of complex_format_map->{$end_tag}->[1] $complex_format_map->{$end_tag}->[0]: $@";
2697	    $end = '</pre>'
2698	  }
2699	  $in_pre = 0 if $end =~ m|</pre>|;
2700	  push(@lines, html_debug($end, __LINE__));
2701	} elsif ($end_tag =~ /^(|f|v|multi)table$/) {
2702	    unless (@tables) {
2703		warn "$ERROR \@end $end_tag without \@*table\n";
2704		next;
2705	    }
2706	    ($table_type, $in_table) = split($;, shift(@tables));
2707	    unless ($1 eq $table_type) {
2708		warn "$ERROR \@end $end_tag without matching \@$end_tag\n";
2709		next;
2710	    }
2711	    if ($table_type eq "multi") {
2712		push(@lines, "</TR></TABLE>\n");
2713		&html_pop_if('TR');
2714	    } else {
2715		push(@lines, "</DL>\n");
2716		&html_pop_if('DD');
2717	    }
2718	    &html_pop_if();
2719	    if (@tables) {
2720		($table_type, $in_table) = split($;, $tables[0]);
2721	    } else {
2722		$in_table = 0;
2723	    }
2724	} elsif (defined($def_map{$end_tag})) {
2725 	    push(@lines, &debug("</DL>\n", __LINE__));
2726	} elsif ($end_tag eq 'menu') {
2727	    &html_pop_if();
2728	    push(@lines, $_); # must keep it for pass 2
2729	}
2730	next;
2731    }
2732    #############################################################
2733    # anchor insertion
2734    while (/\@anchor\s*\{(.*?)\}/)
2735    {
2736      $_ = $`.$';
2737      my $anchor = $1;
2738      $anchor = &normalise_node($anchor);
2739      push @lines, &html_debug("<A NAME=\"$anchor\"></A>\n");
2740      $node2href{$anchor} = "$docu_doc#$anchor";
2741      next INPUT_LINE if $_ = /^\s*$/;
2742    }
2743
2744    #
2745    # protect texi and HTML things
2746    &protect_texi;
2747    $_ = &protect_html($_) unless $dont_html;
2748    $dont_html = 0;
2749    # substitution (unsupported things)
2750    s/^\@exdent\s+//g;
2751    s/\@noindent\s+//g;
2752    s/\@refill\s+//g;
2753    # other substitutions
2754    &simple_substitutions;
2755    s/\@value\{($VARRE)\}/$value{$1}/eg;
2756    s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
2757    #
2758    # analyze the tag again
2759    #
2760    if ($tag) {
2761      if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) {
2762	    if (/^\@$tag\s+(.+)$/) {
2763		$name = $1;
2764		$name = &normalise_node($name);
2765		$level = $sec2level{$tag};
2766		if ($tag =~ /heading$/ || $in_top){
2767		    push(@lines, &html_debug('', __LINE__));
2768                    $_ = &debug("<H$level>$name</H$level>\n", __LINE__);
2769		    &html_push_if('body');
2770		    print "# heading, section $name, level $level\n"
2771			if $T2H_DEBUG & $DEBUG_TOC;
2772		}
2773# this `else' seems to cause problems if there is a chapheading section and
2774# -split node is used.  In this case, the split gets forgotten.
2775		else
2776		{
2777		  $node = $name unless $node;
2778		  unless (/^unnumbered/)
2779		  {
2780		    my $number = &update_sec_num($tag, $level);
2781		    $name = $number. ' ' . $name if $T2H_NUMBER_SECTIONS;
2782		    $sec2number{$name} = $number;
2783		    $number2sec{$number} = $name;
2784		  }
2785		  if (defined($toplevel))
2786		  {
2787		    push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND);
2788		  }
2789		  else
2790		  {
2791		    # first time we see a "section"
2792		    unless ($level == 1)
2793		    {
2794		      warn "$WARN The first section found is not of level 1: $_";
2795		    }
2796		    $toplevel = $level;
2797		  }
2798		  push(@sections, $name);
2799		  next_doc() if ($T2H_SPLIT eq 'section' ||
2800				 $T2H_SPLIT && $level == $toplevel);
2801		  $sec_num++;
2802		  $docid = "SEC$sec_num";
2803		  $tocid = "TOC$sec_num";
2804		  # check biblio and glossary
2805		  $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i);
2806		  $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i);
2807		  # check node
2808		  if ($node2sec{$node}) {
2809		    warn "$ERROR Duplicate node found: $node\n";
2810		  } else {
2811		    $section = $name;
2812		    $node2sec{$node} = $name;
2813		    warn "$ERROR Duplicate section found: $name\n"
2814		      if ($sec2node{$name});
2815		    $sec2node{$name} = $node;
2816		    $node2href{$node} = "$docu_doc#$docid";
2817		    $node2next{$node} = $node_next;
2818		    $node2prev{$node} = $node_prev;
2819		    $node2up{$node} = $node_up;
2820		    print "# node $node, section $name, level $level\n"
2821		      if $T2H_DEBUG & $DEBUG_TOC;
2822		  }
2823		  $node = '';
2824		  $node_next = '';
2825		  $node_prev = '';
2826		  $node_next = '';
2827		  # update TOC
2828		  while ($level > $curlevel) {
2829		    $curlevel++;
2830		    push(@toc_lines, "<UL>\n");
2831		  }
2832		  while ($level < $curlevel) {
2833		    $curlevel--;
2834		    push(@toc_lines, "</UL>\n");
2835		  }
2836		  $_ = &t2h_anchor($tocid, "$docu_doc#$docid", $name, 1);
2837		  $_ = &substitute_style($_);
2838		  push(@stoc_lines, "$_<BR>\n") if ($level == 1);
2839		  push(@toc_lines, "<LI>" . $_ ."</LI>");
2840		  # update DOC
2841		  push(@lines, &html_debug('', __LINE__));
2842		  &html_reset;
2843		  #		    $_ =  "<H$level>".&t2h_anchor($docid, '', $name)."</H$level>\n";
2844		  $_ =  "<H$level> $name </H$level>\n<!--docid::${docid}::-->\n";
2845
2846		  $_ = &debug($_, __LINE__);
2847		  push(@lines, &html_debug('', __LINE__));
2848		}
2849		# update DOC
2850		foreach $line (split(/\n+/, $_)) {
2851		    push(@lines, "$line\n");
2852		}
2853		next;
2854	    } else {
2855		warn "$ERROR Bad section line: $_";
2856	    }
2857	} else {
2858	    # track variables
2859	    $value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o;
2860	    delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o;
2861	    # store things
2862	    $value{'_setfilename'}   = Unprotect_texi($1), next if /^\@setfilename\s+(.*)$/;
2863	    $value{'_settitle'}      = Unprotect_texi($1), next if /^\@settitle\s+(.*)$/;
2864	    $value{'_author'}   .= Unprotect_texi($1)."\n", next if /^\@author\s+(.*)$/;
2865	    $value{'_subtitle'} .= Unprotect_texi($1)."\n", next if /^\@subtitle\s+(.*)$/;
2866	    $value{'_title'}    .= Unprotect_texi($1)."\n", next if /^\@title\s+(.*)$/;
2867	    # index
2868	    if (/^\@(..?)index\s+/) {
2869		unless ($valid_index{$1}) {
2870		    warn "$ERROR Undefined index command: $_";
2871		    next;
2872		}
2873		$index = $1 . 'index';
2874		$what = &substitute_style($');
2875		$what =~ s/\s+$//;
2876		# check whether last pushed line was header
2877		if ($lines[$#lines] =~ /^<!--docid::(.+)::-->$/)
2878		{
2879		  $id = $1;
2880		}
2881		else
2882		{
2883		  $id = 'IDX' . ++$idx_num;
2884		}
2885		print "# found $index for '$what' id $id\n"
2886		    if $T2H_DEBUG & $DEBUG_INDEX;
2887		eval(<<EOC);
2888		if (defined(\$$index\{\$what\})) {
2889		    \$$index\{\$what\} .= "$;$;$docu_doc#$id$;$section";
2890		} else {
2891		    \$$index\{\$what\} = "$docu_doc#$id$;$section";
2892		}
2893EOC
2894
2895		#
2896		# dirty hack to see if I can put an invisible anchor...
2897		#
2898		if ($id =~ /^IDX/)
2899		{
2900		  if ($html_element eq 'DL' ||
2901		      $html_element eq 'UL' ||
2902		      $html_element eq 'OL' )
2903		  {
2904		    $deferred_ref .= &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre) . " ";
2905		  }
2906		  elsif ($html_element eq 'body')
2907		  {
2908		    push(@lines, &debug("<P>\n", __LINE__));
2909                    push(@lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre));
2910		    &html_push('P');
2911		  }
2912		  else
2913		  {
2914                    push(@lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre));
2915		  }
2916		}
2917		next;
2918	    }
2919	    # list item
2920	    if (/^\s*\@itemx?\s+/) {
2921		$what = $';
2922		$what =~ s/\s+$//;
2923		if ($in_bibliography && $use_bibliography) {
2924		    if ($what =~ /^$BIBRE$/o) {
2925			$id = 'BIB' . ++$bib_num;
2926			$bib2href{$what} = "$docu_doc#$id";
2927			print "# found bibliography for '$what' id $id\n"
2928			    if $T2H_DEBUG & $DEBUG_BIB;
2929			$what = &t2h_anchor($id, '', $what);
2930		    }
2931		} elsif ($in_glossary && $T2H_USE_GLOSSARY) {
2932		    $id = 'GLOSS' . ++$gloss_num;
2933		    $entry = $what;
2934		    $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
2935		    $gloss2href{$entry} = "$docu_doc#$id";
2936		    print "# found glossary for '$entry' id $id\n"
2937			if $T2H_DEBUG & $DEBUG_GLOSS;
2938		    $what = &t2h_anchor($id, '', $what);
2939		}
2940		&html_pop_if('P');
2941		if ($html_element eq 'DL' || $html_element eq 'DD') {
2942		    if ($things_map{$in_table} && !$what) {
2943			# special case to allow @table @bullet for instance
2944			push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__));
2945		    } else {
2946			push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__));
2947		    }
2948		    push(@lines, "<DD>");
2949		    &html_push('DD') unless $html_element eq 'DD';
2950		    if ($table_type) { # add also an index
2951			unshift(@input_spool, "\@${table_type}index $what\n");
2952		    }
2953		} elsif ($html_element eq 'TABLE') {
2954		    push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
2955		    &html_push('TR');
2956		} elsif ($html_element eq 'TR') {
2957		    push(@lines, &debug("</TR>\n", __LINE__));
2958		    push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
2959		} else {
2960		    push(@lines, &debug("<LI>$what\n", __LINE__));
2961		    &html_push('LI') unless $html_element eq 'LI';
2962		}
2963		push(@lines, &html_debug('', __LINE__));
2964		if ($deferred_ref) {
2965		    push(@lines, &debug("$deferred_ref\n", __LINE__));
2966		    $deferred_ref = '';
2967		}
2968		next;
2969	    } elsif (/^\@tab\s+(.*)$/) {
2970		push(@lines, "<TD>$1</TD>\n");
2971		next;
2972	    }
2973	}
2974    }
2975    # paragraph separator
2976    if ($_ eq "\n") {
2977	next if $#lines >= 0 && $lines[$#lines] eq "\n";
2978	if ($html_element eq 'P') {
2979	    push (@lines, &debug("</P><P>\n", __LINE__));
2980	}
2981# 	else
2982# 	{
2983# 	  push(@lines, "<P></P>\n");
2984# 	  $_ = &debug("<P></P>\n", __LINE__);
2985# 	}
2986        elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'DD' || $html_element eq 'LI')
2987	{
2988	  &html_push('P');
2989	  push(@lines, &debug("<P>\n", __LINE__));
2990	}
2991      }
2992    # otherwise
2993    push(@lines, $_);
2994
2995    push(@lines, &debug("</center>\n", __LINE__))  if ($tag eq 'center');
2996}
2997
2998# finish TOC
2999$level = 0;
3000while ($level < $curlevel) {
3001    $curlevel--;
3002    push(@toc_lines, "</UL>\n");
3003}
3004
3005print "# end of pass 1\n" if $T2H_VERBOSE;
3006
3007#+++############################################################################
3008#                                                                              #
3009# Pass 2/3: handle style, menu, index, cross-reference                         #
3010#                                                                              #
3011#---############################################################################
3012
3013@lines2 = ();				# whole document (2nd pass)
3014@lines3 = ();				# whole document (3rd pass)
3015$in_menu = 0;				# am I inside a menu
3016
3017while (@lines) {
3018    $_ = shift(@lines);
3019    #
3020    # special case (protected sections)
3021    #
3022    if (/^$PROTECTTAG/o) {
3023	push(@lines2, $_);
3024	next;
3025    }
3026    #
3027    # menu
3028    #
3029    if (/^\@menu\b/)
3030    {
3031      $in_menu = 1;
3032      $in_menu_listing = 1;
3033      $T2H_NUMBER_SECTIONS ?
3034	push(@lines2, &debug("<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> \n", __LINE__)) :
3035	  push(@lines2, &debug("<UL>\n", __LINE__));
3036      next;
3037    }
3038    if (/^\@end\s+menu\b/)
3039    {
3040      $in_menu = 0;
3041      $T2H_NUMBER_SECTIONS ?
3042	push(@lines2, &debug("</TABLE></BLOCKQUOTE>\n", __LINE__)) :
3043	  push(@lines2, &debug("</UL>\n", __LINE__));
3044      next;
3045    }
3046    if ($in_menu) {
3047	if (/^\*\s+($NODERE)::/o) {
3048	  if (! $in_menu_listing)
3049	  {
3050	    $in_menu_listing = 1;
3051	     $T2H_NUMBER_SECTIONS ?
3052	       push(@lines2, &debug("<TABLE BORDER=0 CELLSPACING=0>\n", __LINE__)) :
3053		 push(@lines2, &debug("<UL>\n", __LINE__));
3054	  }
3055	    $descr = $';
3056	    chop($descr);
3057	    &menu_entry($1, $1, $descr);
3058	} elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) {
3059	  if (! $in_menu_listing)
3060	  {
3061	    $in_menu_listing = 1;
3062	     $T2H_NUMBER_SECTIONS ?
3063	       push(@lines2, &debug("<TABLE BORDER=0 CELLSPACING=0>\n", __LINE__)) :
3064		 push(@lines2, &debug("<UL>\n", __LINE__));
3065	  }
3066	    $descr = $';
3067	    chop($descr);
3068	    &menu_entry($1, $2, $descr);
3069	} elsif (/^\*/) {
3070	    warn "$ERROR Bad menu line: $_";
3071	} else { # description continued?
3072	  if ($in_menu_listing)
3073	  {
3074	    $in_menu_listing = 0;
3075	    $T2H_NUMBER_SECTIONS ?
3076	      push(@lines2, &debug("</TABLE>\n", __LINE__)) :
3077		push(@lines2, &debug("</UL>\n", __LINE__));
3078	  }
3079	  # should be like verbatim -- preseve spaces, etc
3080	  s/ /\&nbsp;/g;
3081	  $_ .= "<br>\n";
3082	  push(@lines2, $_);
3083	}
3084	next;
3085    }
3086    #
3087    # printindex
3088    #
3089    # obachman: replace ^\@printindex by \@printindex, otherwise
3090    # generation in debug mode fails
3091    if (/\@printindex\s+(\w\w)\b/) {
3092	local($index, *ary, @keys, $key, $letter, $last_letter, @refs, $fhidx);
3093	if ($predefined_index{$1}) {
3094	    $index = $predefined_index{$1} . 'index';
3095	} else {
3096	    $index = $1 . 'index';
3097	}
3098	# check for index summary
3099	$letter = $1;
3100	if ($letter =~ /$T2H_IDX_SUMMARY/)
3101	{
3102	  open(FHIDX, "> $docu_rdir$docu_name" . "_$letter.idx")
3103	    || die "Can't open > $docu_rdir$docu_name" . "_$letter.idx for writing: $!\n";
3104	  $fhidx = \*FHIDX;
3105	  print "# writing index summary in $docu_rdir$docu_name" . "_$letter.idx..." if $T2H_VERBOSE;
3106	}
3107	eval("*ary = *$index");
3108	@keys = keys(%ary);
3109	foreach $key (@keys) {
3110	    $_ = $key;
3111	    1 while s/<(\w+)>\`(.*)\'<\/\1>/$2/; # remove HTML tags with quotes
3112	    1 while s/<(\w+)>(.*)<\/\1>/$2/;     # remove HTML tags
3113	    $_ = &unprotect_html($_);
3114	    &unprotect_texi;
3115	    tr/A-Z/a-z/; # lowercase
3116	    $key2alpha{$key} = $_;
3117	    print "# index $key sorted as $_\n"
3118		if $key ne $_ && $T2H_DEBUG & $DEBUG_INDEX;
3119	}
3120	push(@lines2, "<H3>Jump to:</H3>\n");
3121	$last_letter = undef;
3122	foreach $key (sort byalpha @keys) {
3123	    $letter = substr($key2alpha{$key}, 0, 1);
3124	    $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;;
3125	    if (!defined($last_letter) || $letter ne $last_letter) {
3126		push(@lines2, " &nbsp; \n") if defined($last_letter);
3127		push(@lines2, "<BR>\n") if ($letter eq 'a');
3128		push(@lines2, "<A HREF=\"#$index\_$letter\">" . &protect_html(uc($letter)) . "</A>\n");
3129		$last_letter = $letter;
3130	    }
3131	}
3132	push(@lines2, "<P></P><P></P>\n");
3133	push(@lines2, "<TABLE border=0>\n");
3134	push(@lines2, "<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> $T2H_WORDS->{$T2H_LANG}->{'section'}</TH></TR>\n");
3135	$last_letter = undef;
3136	foreach $key (sort byalpha @keys) {
3137	    $letter = substr($key2alpha{$key}, 0, 1);
3138	    $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;;
3139	    if (!defined($last_letter) || $letter ne $last_letter) {
3140	        push (@lines2, "<TR><TD COLSPAN=3> <HR></TD></TR>\n");
3141		push(@lines2, "<TR><TH><A NAME=\"$index\_$letter\">" . &protect_html(uc($letter)) . "</A>\n");
3142		push(@lines2, "</TH><TD></TD><TD></TD></TR>\n");
3143		$last_letter = $letter;
3144	    }
3145	    foreach (split(/$;$;/, $ary{$key})) {
3146	        my ($idx, $section) = split(/$;/, $_);
3147		push(@lines2,
3148		     "<TR><TD></TD><TD>" .
3149		     &t2h_anchor('', $idx, $key, 0) .
3150		     "</TD><TD>" .
3151		     &t2h_anchor('', &sec_href($section), $section, 0) .
3152		     "</TD></TR>\n");
3153
3154	    }
3155	    if ($fhidx)
3156	    {
3157	      ($letter) = split(/$;/, $ary{$key});
3158	      $key = unprotect_html($key);
3159	      print $fhidx "$key\t$letter\n";
3160	    }
3161	}
3162	if ($fhidx)
3163	{
3164	  print "\n" if $T2H_VERBOSE;
3165	  close($fhidx);
3166	}
3167	push (@lines2, "</TABLE>\n");
3168	next;
3169    }
3170    #
3171    # simple style substitutions
3172    #
3173    $_ = &substitute_style($_);
3174    #
3175    # xref
3176    #
3177    while (/\@(x|px|info|)ref\{([^{}]+)(\}?)/) {
3178	# note: Texinfo may accept other characters
3179	($type, $nodes, $full) = ($1, $2, $3);
3180	($before, $after) = ($`, $');
3181	if (! $full && $after) {
3182	    warn "$ERROR Bad xref (no ending } on line): $_";
3183	    $_ = "$before$;0${type}ref\{$nodes$after";
3184	    next; # while xref
3185	}
3186	if ($type eq 'x') {
3187	    $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} ";
3188	} elsif ($type eq 'px') {
3189	    $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} ";
3190	} elsif ($type eq 'info') {
3191	    $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info";
3192	} else {
3193	    $type = '';
3194	}
3195	unless ($full) {
3196	    $next = shift(@lines);
3197	    $next = &substitute_style($next);
3198	    chop($nodes); # remove final newline
3199	    if ($next =~ /\}/) { # split on 2 lines
3200		$nodes .= " $`";
3201		$after = $';
3202	    } else {
3203		$nodes .= " $next";
3204		$next = shift(@lines);
3205		$next = &substitute_style($next);
3206		chop($nodes);
3207		if ($next =~ /\}/) { # split on 3 lines
3208		    $nodes .= " $`";
3209		    $after = $';
3210		} else {
3211		    warn "$ERROR Bad xref (no ending }): $_";
3212		    $_ = "$before$;0xref\{$nodes$after";
3213		    unshift(@lines, $next);
3214		    next; # while xref
3215		}
3216	    }
3217	}
3218	$nodes =~ s/\s+/ /g; # remove useless spaces
3219	@args = split(/\s*,\s*/, $nodes);
3220	$node = $args[0]; # the node is always the first arg
3221	$node = &normalise_node($node);
3222	$sec = $node2sec{$node};
3223	$href = $node2href{$node};
3224	if (@args == 5) { # reference to another manual
3225	    $sec = $args[2] || $node;
3226	    $man = $args[4] || $args[3];
3227	    $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after";
3228	} elsif ($type =~ /Info/) { # inforef
3229	    warn "$ERROR Wrong number of arguments: $_" unless @args == 3;
3230	    ($nn, $_, $in) = @args;
3231	    $_ = "${before}${type} file `$in', node `$nn'$after";
3232	} elsif ($sec && $href && ! $T2H_SHORT_REF) {
3233	    $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} " .
3234	      &t2h_anchor('', $href, $sec) . $after;
3235	}
3236	elsif ($href)
3237	{
3238	  $_ = "${before}${type} " . &t2h_anchor('', $href, $node) . $after;
3239	}
3240	else {
3241	    warn "$ERROR Undefined node ($node): $_";
3242	    $_ = "$before$;0xref{$nodes}$after";
3243	}
3244    }
3245
3246    # replace images
3247    s[\@image\s*{(.+?)}]
3248    {
3249     my @args = split (/\s*,\s*/, $1);
3250     my $base = $args[0];
3251     my $image =
3252       LocateIncludeFile("$base.png") ||
3253       LocateIncludeFile("$base.jpg") ||
3254       LocateIncludeFile("$base.gif");
3255     warn "$ERROR no image file for $base: $_" unless ($image && -e $image);
3256     "<IMG SRC=\"$image\" ALT=\"$base\">";
3257     ($T2H_CENTER_IMAGE ?
3258      "<CENTER><IMG SRC=\"$image\" ALT=\"$base\"></CENTER>" :
3259      "<IMG SRC=\"$image\" ALT=\"$base\">");
3260    }eg;
3261
3262    #
3263    # try to guess bibliography references or glossary terms
3264    #
3265    unless (/^<H\d><A NAME=\"SEC\d/) {
3266	if ($use_bibliography) {
3267	    $done = '';
3268	    while (/$BIBRE/o) {
3269		($pre, $what, $post) = ($`, $&, $');
3270		$href = $bib2href{$what};
3271		if (defined($href) && $post !~ /^[^<]*<\/A>/) {
3272		    $done .= $pre . &t2h_anchor('', $href, $what);
3273		} else {
3274		    $done .= "$pre$what";
3275		}
3276		$_ = $post;
3277	    }
3278	    $_ = $done . $_;
3279	}
3280	if ($T2H_USE_GLOSSARY) {
3281	    $done = '';
3282	    while (/\b\w+\b/) {
3283		($pre, $what, $post) = ($`, $&, $');
3284		$entry = $what;
3285		$entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
3286		$href = $gloss2href{$entry};
3287		if (defined($href) && $post !~ /^[^<]*<\/A>/) {
3288		    $done .= $pre . &t2h_anchor('', $href, $what);
3289		} else {
3290		    $done .= "$pre$what";
3291		}
3292		$_ = $post;
3293	    }
3294	    $_ = $done . $_;
3295	}
3296    }
3297    # otherwise
3298    push(@lines2, $_);
3299}
3300print "# end of pass 2\n" if $T2H_VERBOSE;
3301
3302#
3303# split style substitutions
3304#
3305while (@lines2) {
3306    $_ = shift(@lines2);
3307    #
3308    # special case (protected sections)
3309    #
3310    if (/^$PROTECTTAG/o) {
3311	push(@lines3, $_);
3312	next;
3313    }
3314    #
3315    # split style substitutions
3316    #
3317    $old = '';
3318    while ($old ne $_) {
3319        $old = $_;
3320	if (/\@(\w+)\{/) {
3321	    ($before, $style, $after) = ($`, $1, $');
3322	    if (defined($style_map{$style})) {
3323		$_ = $after;
3324		$text = '';
3325		$after = '';
3326		$failed = 1;
3327		while (@lines2) {
3328		    if (/\}/) {
3329			$text .= $`;
3330			$after = $';
3331			$failed = 0;
3332			last;
3333		    } else {
3334			$text .= $_;
3335			$_ = shift(@lines2);
3336		    }
3337		}
3338		if ($failed) {
3339		    die "* Bad syntax (\@$style) after: $before\n";
3340		} else {
3341		    $text = &apply_style($style, $text);
3342		    $_ = "$before$text$after";
3343		}
3344	    }
3345	}
3346    }
3347    # otherwise
3348    push(@lines3, $_);
3349}
3350print "# end of pass 3\n" if $T2H_VERBOSE;
3351
3352#+++############################################################################
3353#                                                                              #
3354# Pass 4: foot notes, final cleanup                                            #
3355#                                                                              #
3356#---############################################################################
3357
3358@foot_lines = ();			# footnotes
3359@doc_lines = ();			# final document
3360$end_of_para = 0;			# true if last line is <P>
3361
3362while (@lines3) {
3363    $_ = shift(@lines3);
3364    #
3365    # special case (protected sections)
3366    #
3367    if (/^$PROTECTTAG/o) {
3368	push(@doc_lines, $_);
3369	$end_of_para = 0;
3370	next;
3371    }
3372    #
3373    # footnotes
3374    #
3375    while (/\@footnote([^\{\s]+)\{/) {
3376	($before, $d, $after) = ($`, $1, $');
3377	$_ = $after;
3378	$text = '';
3379	$after = '';
3380	$failed = 1;
3381	while (@lines3) {
3382	    if (/\}/) {
3383		$text .= $`;
3384		$after = $';
3385		$failed = 0;
3386		last;
3387	    } else {
3388		$text .= $_;
3389		$_ = shift(@lines3);
3390	    }
3391	}
3392	if ($failed) {
3393	    die "* Bad syntax (\@footnote) after: $before\n";
3394	} else {
3395	    $foot_num++;
3396	    $docid  = "DOCF$foot_num";
3397	    $footid = "FOOT$foot_num";
3398	    $foot = "($foot_num)";
3399	    push(@foot_lines, "<H3>" . &t2h_anchor($footid, "$d#$docid", $foot) . "</H3>\n");
3400	    $text = "<P>$text" unless $text =~ /^\s*<P>/;
3401	    push(@foot_lines, "$text\n");
3402	    $_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after;
3403	}
3404    }
3405    #
3406    # remove unnecessary <P>
3407    #
3408    if (/^\s*<P>\s*$/) {
3409	next if $end_of_para++;
3410    } else {
3411	$end_of_para = 0;
3412    }
3413    # otherwise
3414    push(@doc_lines, $_);
3415}
3416
3417print "# end of pass 4\n" if $T2H_VERBOSE;
3418
3419#+++############################################################################
3420#                                                                              #
3421# Pass 5: print things                                                         #
3422#                                                                              #
3423#---############################################################################
3424
3425$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H);
3426$T2H_L2H = &l2h_ToHtml        if ($T2H_L2H);
3427$T2H_L2H = &l2h_InitFromHtml  if ($T2H_L2H);
3428
3429# fix node2up, node2prev, node2next, if desired
3430if ($has_top_command)
3431{
3432  for $section (keys %sec2number)
3433  {
3434    $node = $sec2node{$section};
3435    $node2up{$node} = Sec2UpNode($section) unless $node2up{$node};
3436    $node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node};
3437    $node2next{$node} = Sec2NextNode($section) unless $node2next{$node};
3438  }
3439}
3440
3441# prepare %T2H_THISDOC
3442$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
3443$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle};
3444$T2H_THISDOC{author} = $value{'_author'};
3445$T2H_THISDOC{subtitle} = $value{'_subtitle'};
3446for $key (keys %T2H_THISDOC)
3447{
3448  $_ = &substitute_style($T2H_THISDOC{$key});
3449  &unprotect_texi;
3450  s/\s*$//;
3451  $T2H_THISDOC{$key} = $_;
3452}
3453
3454# if no sections, then simply print docuemnt as is
3455unless (@sections)
3456{
3457  print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE;
3458  open(FILE, "> $docu_top_file")
3459    || die "$ERROR: Can't open $docu_top_file for writing: $!\n";
3460
3461  &$T2H_print_page_head(\*FILE);
3462  $T2H_THIS_SECTION = \@doc_lines;
3463  t2h_print_lines(\*FILE);
3464  &$T2H_print_foot_navigation(\*FILE);
3465  &$T2H_print_page_foot(\*FILE);
3466  close(FILE);
3467  goto Finish;
3468}
3469
3470# initialize $T2H_HREF, $T2H_NAME
3471%T2H_HREF =
3472  (
3473   'First' ,   sec_href($sections[0]),
3474   'Last',     sec_href($sections[$#sections]),
3475   'About',     $docu_about. '#SEC_About',
3476  );
3477
3478# prepare TOC, OVERVIEW, TOP
3479$T2H_TOC = \@toc_lines;
3480$T2H_OVERVIEW = \@stoc_lines;
3481if ($has_top)
3482{
3483  while (1)
3484  {
3485    $_ = shift @doc_lines;
3486    last if /$TOPEND/;
3487    push @$T2H_TOP, $_;
3488  }
3489  $T2H_HREF{'Top'} = $docu_top . '#SEC_Top';
3490}
3491else
3492{
3493  $T2H_HREF{'Top'} = $T2H_HREF{First};
3494}
3495
3496$node2href{Top} = $T2H_HREF{Top};
3497$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines;
3498$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines;
3499$T2H_HREF{Index} = $node2href{'Index'};
3500
3501%T2H_NAME =
3502  (
3503   'First',   clean_name($sec2node{$sections[0]}),
3504   'Last',    clean_name($sec2node{$sections[$#sections]}),
3505   'About',    $T2H_WORDS->{$T2H_LANG}->{'About_Title'},
3506   'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'},
3507   'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'},
3508   'Index' ,   '',
3509   'Top',      ''
3510  );
3511
3512#############################################################################
3513# print Top
3514#
3515open(FILE, "> $docu_top_file")
3516  || die "$ERROR: Can't open $docu_top_file for writing: $!\n";
3517&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT);
3518
3519if ($has_top)
3520{
3521  print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE;
3522  $T2H_THIS_SECTION = $T2H_TOP;
3523  $T2H_HREF{This} = $T2H_HREF{Top};
3524  $T2H_NAME{This} = $T2H_NAME{Top};
3525  &$T2H_print_Top(\*FILE);
3526}
3527
3528close(FILE) if $T2H_SPLIT;
3529
3530#############################################################################
3531# Print sections
3532#
3533$T2H_NODE{Forward} = $sec2node{$sections[0]};
3534$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]});
3535$T2H_HREF{Forward} = sec_href($sections[0]);
3536$T2H_NODE{This} = 'Top';
3537$T2H_NAME{This} = $T2H_NAME{Top};
3538$T2H_HREF{This} = $T2H_HREF{Top};
3539if ($T2H_SPLIT)
3540{
3541  print "# writing " . scalar(@sections) .
3542    " sections in $docu_rdir$docu_name"."_[1.." .
3543      ($T2H_SPLIT eq 'section' ? scalar(@sections) : scalar(@$T2H_OVERVIEW) ) .
3544	"]"
3545	  if $T2H_VERBOSE;
3546  $previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND);
3547  undef $FH;
3548  $doc_num = 0;
3549}
3550else
3551{
3552  print "# writing " . scalar(@sections) . " sections in $docu_top_file ..."
3553    if $T2H_VERBOSE;
3554  $FH = \*FILE;
3555  $previous = '';
3556}
3557
3558$counter = 0;
3559# loop through sections
3560while ($section = shift(@sections))
3561{
3562  if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND))
3563  { # open new page
3564    if ($FH)
3565    {
3566      #close previous page
3567      &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter';
3568      &$T2H_print_page_foot($FH);
3569      close($FH);
3570      undef $FH;
3571    }
3572    &next_doc;
3573  }
3574  $T2H_NAME{Back} = $T2H_NAME{This};
3575  $T2H_HREF{Back} = $T2H_HREF{This};
3576  $T2H_NODE{Back} = $T2H_NODE{This};
3577  $T2H_NAME{This} = $T2H_NAME{Forward};
3578  $T2H_HREF{This} = $T2H_HREF{Forward};
3579  $T2H_NODE{This} = $T2H_NODE{Forward};
3580  if ($sections[0])
3581  {
3582    $T2H_NODE{Forward} = $sec2node{$sections[0]};
3583    $T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward});
3584    $T2H_HREF{Forward} = sec_href($sections[0]);
3585  }
3586  else
3587  {
3588    undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward};
3589  }
3590
3591  $node = $node2up{$T2H_NODE{This}};
3592  $T2H_HREF{Up} = $node2href{$node};
3593  if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up})
3594  {
3595    $T2H_NAME{Up} = $T2H_NAME{Top};
3596    $T2H_HREF{Up} = $T2H_HREF{Top};
3597    $T2H_NODE{Up} = 'Up';
3598  }
3599  else
3600  {
3601    $T2H_NAME{Up} = &clean_name($node);
3602    $T2H_NODE{Up} = $node;
3603  }
3604
3605  $node = $T2H_NODE{This};
3606  $node = $node2prev{$node};
3607  $T2H_NAME{Prev} = &clean_name($node);
3608  $T2H_HREF{Prev} = $node2href{$node};
3609  $T2H_NODE{Prev} = $node;
3610
3611  $node = $T2H_NODE{This};
3612  if ($node2up{$node} && $node2up{$node} ne 'Top'&&
3613      ($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node}))
3614  {
3615    $node = $node2up{$node};
3616    while ($node && $node ne $node2up{$node} && ! $node2prev{$node})
3617    {
3618      $node = $node2up{$node};
3619    }
3620    $node = $node2prev{$node}
3621      unless $node2up{$node} eq 'Top' || ! $node2up{$node};
3622  }
3623  else
3624  {
3625    $node = $node2prev{$node};
3626  }
3627  $T2H_NAME{FastBack} = &clean_name($node);
3628  $T2H_HREF{FastBack} = $node2href{$node};
3629  $T2H_NODE{FastBack} = $node;
3630
3631  $node = $T2H_NODE{This};
3632  $node = $node2next{$node};
3633  $T2H_NAME{Next} = &clean_name($node);
3634  $T2H_HREF{Next} = $node2href{$node};
3635  $T2H_NODE{Next} = $node;
3636
3637  $node = $T2H_NODE{This};
3638  if ($node2up{$node} && $node2up{$node} ne 'Top'&&
3639      ($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node}))
3640  {
3641    $node = $node2up{$node};
3642    while ($node && $node ne $node2up{$node} && ! $node2next{$node})
3643    {
3644      $node = $node2up{$node};
3645    }
3646  }
3647  $node = $node2next{$node};
3648  $T2H_NAME{FastForward} = &clean_name($node);
3649  $T2H_HREF{FastForward} = $node2href{$node};
3650  $T2H_NODE{FastForward} = $node;
3651
3652  if (! defined($FH))
3653  {
3654    open(FILE, "> $docu_rdir$docu_doc") ||
3655      die "$ERROR: Can't open $docu_rdir$docu_doc for writing: $!\n";
3656    $FH = \*FILE;
3657    &$T2H_print_page_head($FH);
3658    t2h_print_label($FH);
3659    &$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter';
3660  }
3661  else
3662  {
3663    t2h_print_label($FH);
3664  }
3665
3666  $T2H_THIS_SECTION = [];
3667  while (@doc_lines) {
3668    $_ = shift(@doc_lines);
3669    last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND);
3670    push(@$T2H_THIS_SECTION, $_);
3671  }
3672  $previous = $_;
3673  &$T2H_print_section($FH);
3674
3675  if ($T2H_VERBOSE)
3676  {
3677    $counter++;
3678    print "." if $counter =~ /00$/;
3679  }
3680}
3681if ($T2H_SPLIT)
3682{
3683  &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter';
3684  &$T2H_print_page_foot($FH);
3685  close($FH);
3686}
3687print "\n" if $T2H_VERBOSE;
3688
3689#############################################################################
3690# Print ToC, Overview, Footnotes
3691#
3692undef $T2H_HREF{Prev};
3693undef $T2H_HREF{Next};
3694undef $T2H_HREF{Back};
3695undef $T2H_HREF{Forward};
3696undef $T2H_HREF{Up};
3697
3698if (@foot_lines)
3699{
3700  print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE;
3701  open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n"
3702      if $T2H_SPLIT;
3703  $T2H_HREF{This} = $docu_foot;
3704  $T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'};
3705  $T2H_THIS_SECTION = \@foot_lines;
3706  &$T2H_print_Footnotes(\*FILE);
3707  close(FILE) if $T2H_SPLIT;
3708}
3709
3710if (@toc_lines)
3711{
3712  print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE;
3713  open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n"
3714      if $T2H_SPLIT;
3715  $T2H_HREF{This} = $T2H_HREF{Contents};
3716  $T2H_NAME{This} = $T2H_NAME{Contents};
3717  $T2H_THIS_SECTION = \@toc_lines;
3718  &$T2H_print_Toc(\*FILE);
3719  close(FILE) if $T2H_SPLIT;
3720}
3721
3722if (@stoc_lines)
3723{
3724  print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE;
3725  open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n"
3726      if $T2H_SPLIT;
3727
3728  $T2H_HREF{This} = $T2H_HREF{Overview};
3729  $T2H_NAME{This} = $T2H_NAME{Overview};
3730  $T2H_THIS_SECTION = \@stoc_lines;
3731  &$T2H_print_Overview(\*FILE);
3732  close(FILE) if $T2H_SPLIT;
3733}
3734
3735if ($about_body = &$T2H_about_body())
3736{
3737  print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE;
3738  open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n"
3739      if $T2H_SPLIT;
3740
3741  $T2H_HREF{This} = $T2H_HREF{About};
3742  $T2H_NAME{This} = $T2H_NAME{About};
3743  $T2H_THIS_SECTION = [$about_body];
3744  &$T2H_print_About(\*FILE);
3745  close(FILE) if $T2H_SPLIT;
3746}
3747
3748unless ($T2H_SPLIT)
3749{
3750  &$T2H_print_page_foot(\*FILE);
3751  close (FILE);
3752}
3753
3754Finish:
3755&l2h_FinishFromHtml if ($T2H_L2H);
3756&l2h_Finish if($T2H_L2H);
3757print "# that's all folks\n" if $T2H_VERBOSE;
3758
3759exit(0);
3760
3761#+++############################################################################
3762#                                                                              #
3763# Low level functions                                                          #
3764#                                                                              #
3765#---############################################################################
3766
3767sub LocateIncludeFile
3768{
3769  my $file = shift;
3770  my $dir;
3771
3772  return $file if (-e $file && -r $file);
3773  foreach $dir (@T2H_INCLUDE_DIRS)
3774  {
3775    return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file");
3776  }
3777  return undef;
3778}
3779
3780sub clean_name
3781{
3782  local ($_);
3783  $_ = &remove_style($_[0]);
3784  &unprotect_texi;
3785  return $_;
3786}
3787
3788sub update_sec_num {
3789    local($name, $level) = @_;
3790    my $ret;
3791
3792    $level--; # here we start at 0
3793    if ($name =~ /^appendix/ || @appendix_sec_num) {
3794	# appendix style
3795	if (@appendix_sec_num) {
3796	    &incr_sec_num($level, @appendix_sec_num);
3797	} else {
3798	    @appendix_sec_num = ('A', 0, 0, 0);
3799	}
3800	$ret = join('.', @appendix_sec_num[0..$level]);
3801    } else {
3802	# normal style
3803	if (@normal_sec_num)
3804	{
3805	  &incr_sec_num($level, @normal_sec_num);
3806	}
3807	else
3808	{
3809	  @normal_sec_num = (1, 0, 0, 0);
3810	}
3811	$ret = join('.', @normal_sec_num[0..$level]);
3812    }
3813
3814    $ret .= "." if $level == 0;
3815    return $ret;
3816}
3817
3818sub incr_sec_num {
3819    local($level, $l);
3820    $level = shift(@_);
3821    $_[$level]++;
3822    foreach $l ($level+1 .. 3) {
3823	$_[$l] = 0;
3824    }
3825}
3826
3827sub Sec2UpNode
3828{
3829  my $sec = shift;
3830  my $num = $sec2number{$sec};
3831
3832  return '' unless $num;
3833  return 'Top' unless $num =~ /\.\d+/;
3834  $num =~ s/\.[^\.]*$//;
3835  $num = $num . '.' unless $num =~ /\./;
3836  return $sec2node{$number2sec{$num}};
3837}
3838
3839sub Sec2PrevNode
3840{
3841  my $sec = shift;
3842  my $num = $sec2number{$sec};
3843  my ($i, $post);
3844
3845  if ($num =~ /(\w+)(\.$|$)/)
3846  {
3847    $num = $`;
3848    $i = $1;
3849    $post = $2;
3850    if ($i eq 'A')
3851    {
3852      $i = $normal_sec_num[0];
3853    }
3854    elsif ($i ne '1')
3855    {
3856      $i--;
3857    }
3858    else
3859    {
3860      return '';
3861    }
3862    return $sec2node{$number2sec{$num . $i . $post}}
3863  }
3864  return '';
3865}
3866
3867sub Sec2NextNode
3868{
3869  my $sec = shift;
3870  my $num = $sec2number{$sec};
3871  my $i;
3872
3873  if ($num =~ /(\w+)(\.$|$)/)
3874  {
3875    $num = $`;
3876    $i = $1;
3877    $post = $2;
3878    if ($post eq '.' && $i eq $normal_sec_num[0])
3879    {
3880      $i = 'A';
3881    }
3882    else
3883    {
3884      $i++;
3885    }
3886    return $sec2node{$number2sec{$num . $i . $post}}
3887  }
3888  return '';
3889}
3890
3891sub check {
3892    local($_, %seen, %context, $before, $match, $after);
3893
3894    while (<>) {
3895	if (/\@(\*|\.|\:|\@|\{|\})/) {
3896	    $seen{$&}++;
3897	    $context{$&} .= "> $_" if $T2H_VERBOSE;
3898	    $_ = "$`XX$'";
3899	    redo;
3900	}
3901	if (/\@(\w+)/) {
3902	    ($before, $match, $after) = ($`, $&, $');
3903	    if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address
3904		$seen{'e-mail address'}++;
3905		$context{'e-mail address'} .= "> $_" if $T2H_VERBOSE;
3906	    } else {
3907		$seen{$match}++;
3908		$context{$match} .= "> $_" if $T2H_VERBOSE;
3909	    }
3910	    $match =~ s/^\@/X/;
3911	    $_ = "$before$match$after";
3912	    redo;
3913	}
3914    }
3915
3916    foreach (sort(keys(%seen))) {
3917	if ($T2H_VERBOSE) {
3918	    print "$_\n";
3919	    print $context{$_};
3920	} else {
3921	    print "$_ ($seen{$_})\n";
3922	}
3923    }
3924}
3925
3926sub open {
3927    local($name) = @_;
3928
3929    ++$fh_name;
3930    if (open($fh_name, $name)) {
3931	unshift(@fhs, $fh_name);
3932    } else {
3933	warn "$ERROR Can't read file $name: $!\n";
3934    }
3935}
3936
3937sub init_input {
3938    @fhs = ();			# hold the file handles to read
3939    @input_spool = ();		# spooled lines to read
3940    $fh_name = 'FH000';
3941    &open($docu);
3942}
3943
3944sub next_line {
3945    local($fh, $line);
3946
3947    if (@input_spool) {
3948	$line = shift(@input_spool);
3949	return($line);
3950    }
3951    while (@fhs) {
3952	$fh = $fhs[0];
3953	$line = <$fh>;
3954	return($line) if $line;
3955	close($fh);
3956	shift(@fhs);
3957    }
3958    return(undef);
3959}
3960
3961# used in pass 1, use &next_line
3962sub skip_until {
3963    local($tag) = @_;
3964    local($_);
3965
3966    while ($_ = &next_line) {
3967	return if /^\@end\s+$tag\s*$/;
3968    }
3969    die "* Failed to find '$tag' after: " . $lines[$#lines];
3970}
3971
3972# used in pass 1 for l2h use &next_line
3973sub string_until {
3974    local($tag) = @_;
3975    local($_, $string);
3976
3977    while ($_ = &next_line) {
3978	return $string if /^\@end\s+$tag\s*$/;
3979#	$_ =~ s/hbox/mbox/g;
3980	$string = $string.$_;
3981    }
3982    die "* Failed to find '$tag' after: " . $lines[$#lines];
3983}
3984
3985#
3986# HTML stacking to have a better HTML output
3987#
3988
3989sub html_reset {
3990    @html_stack = ('html');
3991    $html_element = 'body';
3992}
3993
3994sub html_push {
3995    local($what) = @_;
3996    push(@html_stack, $html_element);
3997    $html_element = $what;
3998}
3999
4000sub html_push_if {
4001    local($what) = @_;
4002    push(@html_stack, $html_element)
4003	if ($html_element && $html_element ne 'P');
4004    $html_element = $what;
4005}
4006
4007sub html_pop {
4008    $html_element = pop(@html_stack);
4009}
4010
4011sub html_pop_if {
4012    local($elt);
4013
4014    if (@_) {
4015	foreach $elt (@_) {
4016	    if ($elt eq $html_element) {
4017		$html_element = pop(@html_stack) if @html_stack;
4018		last;
4019	    }
4020	}
4021    } else {
4022	$html_element = pop(@html_stack) if @html_stack;
4023    }
4024}
4025
4026sub html_debug {
4027    local($what, $line) = @_;
4028    if ($T2H_DEBUG & $DEBUG_HTML)
4029    {
4030     $what = "\n" unless $what;
4031     return("<!-- $line @html_stack, $html_element -->$what")
4032    }
4033    return($what);
4034}
4035
4036# to debug the output...
4037sub debug {
4038    local($what, $line) = @_;
4039    return("<!-- $line -->$what")
4040	if $T2H_DEBUG & $DEBUG_HTML;
4041    return($what);
4042}
4043
4044sub normalise_node {
4045  local $_ = $_[0];
4046  s/\s+/ /g;
4047  s/ $//;
4048  s/^ //;
4049  &protect_texi;
4050  &protect_html;
4051  $_ = substitute_style($_);
4052  $_[0]  = $_;
4053}
4054
4055sub menu_entry {
4056    local($entry, $node, $descr) = @_;
4057    local($href);
4058
4059    &normalise_node($node);
4060    $href = $node2href{$node};
4061    if ($href) {
4062	$descr =~ s/^\s+//;
4063	if ($T2H_NUMBER_SECTIONS)
4064	{
4065	  $entry = $node2sec{$entry} if ! $descr && $node2sec{$entry};
4066	  push(@lines2,
4067	       '<TR><TD ALIGN="left">' .
4068	       &t2h_anchor('', $href, $entry) .
4069	       '</TD><TD ALIGN="left">' . $descr . "</TD><TR>\n");
4070	}
4071	else
4072	{
4073	  push(@lines2, "<LI>" . &t2h_anchor('', $href, $entry) . ": $descr\n");
4074	}
4075    } else {
4076	warn "$ERROR Undefined node ($node): $_";
4077    }
4078}
4079
4080sub do_ctrl { "^$_[0]" }
4081
4082sub do_email {
4083    local($addr, $text) = split(/,\s*/, $_[0]);
4084
4085    $text = $addr unless $text;
4086    &t2h_anchor('', "mailto:$addr", $text);
4087}
4088
4089sub do_sc
4090{
4091  # l2h does this much better
4092  return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H);
4093  return "\U$_[0]\E";
4094}
4095
4096sub do_math
4097{
4098  return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H);
4099  return "<EM>".$text."</EM>";
4100}
4101
4102sub do_uref {
4103    local($url, $text, $only_text) = split(/,\s*/, $_[0]);
4104
4105    $text = $only_text if $only_text;
4106    $text = $url unless $text;
4107    &t2h_anchor('', $url, $text);
4108}
4109
4110sub do_url { &t2h_anchor('', $_[0], $_[0]) }
4111
4112sub do_acronym
4113{
4114  return '<FONT SIZE="-1">' . $_[0] . '</FONT>';
4115}
4116
4117sub do_accent
4118{
4119  return "&$_[0]acute;" if $_[1] eq 'H';
4120  return "$_[0]." if $_[1] eq 'dotaccent';
4121  return "$_[0]*" if $_[1] eq 'ringaccent';
4122  return "$_[0]".'[' if $_[1] eq 'tieaccent';
4123  return "$_[0]".'(' if $_[1] eq 'u';
4124  return "$_[0]_" if $_[1] eq 'ubaraccent';
4125  return ".$_[0]" if $_[1] eq 'udotaccent';
4126  return "$_[0]&lt;" if $_[1] eq 'v';
4127  return "$_[0]," if $_[1] eq ',';
4128  return "$_[0]" if $_[1] eq 'dotless';
4129  return undef;
4130}
4131
4132sub apply_style {
4133    local($texi_style, $text) = @_;
4134    local($style);
4135
4136    $style = $style_map{$texi_style};
4137    if (defined($style)) { # known style
4138	if ($style =~ /^\"/) { # add quotes
4139	    $style = $';
4140	    $text = "\`$text\'";
4141	}
4142	if ($style =~ /^\&/) { # custom
4143	    $style = $';
4144	    $text = &$style($text, $texi_style);
4145	} elsif ($style) { # good style
4146	    $text = "<$style>$text</$style>";
4147	} else { # no style
4148	}
4149    } else { # unknown style
4150	$text = undef;
4151    }
4152    return($text);
4153}
4154
4155# remove Texinfo styles
4156sub remove_style {
4157    local($_) = @_;
4158    s/\@\w+{([^\{\}]+)}/$1/g;
4159    return($_);
4160}
4161
4162sub substitute_style {
4163    local($_) = @_;
4164    local($changed, $done, $style, $text);
4165
4166    &simple_substitutions;
4167    $changed = 1;
4168    while ($changed) {
4169	$changed = 0;
4170	$done = '';
4171	while (/\@(\w+)\{([^\{\}]+)\}/ || /\@(,)\{([^\{\}]+)\}/) {
4172	    $text = &apply_style($1, $2);
4173	    if ($text) {
4174		$_ = "$`$text$'";
4175		$changed = 1;
4176	    } else {
4177		$done .= "$`\@$1";
4178		$_ = "{$2}$'";
4179	    }
4180	}
4181        $_ = $done . $_;
4182    }
4183    return($_);
4184}
4185
4186sub t2h_anchor {
4187    local($name, $href, $text, $newline) = @_;
4188    local($result);
4189
4190    $result = "<A";
4191    $result .= " NAME=\"$name\"" if $name;
4192    $result .= " HREF=\"$href\"" if $href;
4193    $result .= ">$text</A>";
4194    $result .= "\n" if $newline;
4195    return($result);
4196}
4197
4198sub pretty_date {
4199    local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
4200
4201    @MoY = ('January', 'February', 'March', 'April', 'May', 'June',
4202	    'July', 'August', 'September', 'October', 'November', 'December');
4203    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
4204    $year += ($year < 70) ? 2000 : 1900;
4205    # obachman: Let's do it as the Americans do
4206    return("$MoY[$mon], $mday  $year");
4207}
4208
4209sub doc_href {
4210    local($num) = @_;
4211
4212    return("${docu_name}_$num.$docu_ext");
4213}
4214
4215sub sec_href
4216{
4217  return $node2href{$sec2node{$_[0]}};
4218}
4219
4220sub next_doc {
4221    $docu_doc = &doc_href(++$doc_num);
4222}
4223
4224sub t2h_print_lines {
4225    my ($fh, $lines) = @_;
4226    local($_);
4227    $lines = $T2H_THIS_SECTION unless $lines;
4228    my $cnt = 0;
4229    for (@$lines)
4230    {
4231	$_ = l2h_FromHtml($_) if ($T2H_L2H);
4232	if (/^$PROTECTTAG/o) {
4233	    $_ = $tag2pro{$_};
4234	} else {
4235	    &unprotect_texi;
4236	}
4237	print $fh $_;
4238	$cnt += split(/\W*\s+\W*/);
4239    }
4240    return $cnt;
4241}
4242
4243sub protect_texi {
4244    # protect @ { } ` '
4245    s/\@\@/$;0/go;
4246    s/\@\{/$;1/go;
4247    s/\@\}/$;2/go;
4248    s/\@\`/$;3/go;
4249    s/\@\'/$;4/go;
4250}
4251
4252sub protect_html {
4253    local($what) = @_;
4254    # protect & < >
4255    $what =~ s/\&/\&\#38;/g;
4256    $what =~ s/\</\&\#60;/g;
4257    $what =~ s/\>/\&\#62;/g;
4258    # restore anything in quotes
4259    # this fixes my problem where I had:
4260    # < IMG SRC="leftarrow.gif" ALT="<--" >  but what if I wanted &#60; in my ALT text ??
4261    # maybe byte stuffing or some other technique should be used.
4262    $what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g;
4263    $what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g;
4264    $what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g;
4265    # but recognize some HTML things
4266    $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g;	      # </A>
4267    $what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g;     # <A [^&]+>
4268    $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+>
4269    return($what);
4270}
4271
4272sub unprotect_texi {
4273    s/$;0/\@/go;
4274    s/$;1/\{/go;
4275    s/$;2/\}/go;
4276    s/$;3/\`/go;
4277    s/$;4/\'/go;
4278}
4279
4280sub Unprotect_texi
4281{
4282  local $_ = shift;
4283  &unprotect_texi;
4284  return($_);
4285}
4286
4287sub unprotect_html {
4288    local($what) = @_;
4289    $what =~ s/\&\#38;/\&/g;
4290    $what =~ s/\&\#60;/\</g;
4291    $what =~ s/\&\#62;/\>/g;
4292    return($what);
4293}
4294
4295sub byalpha {
4296    $key2alpha{$a} cmp $key2alpha{$b};
4297}
4298
4299sub t2h_print_label
4300{
4301    my $fh = shift;
4302    my $href = shift || $T2H_HREF{This};
4303    $href =~ s/.*#(.*)$/$1/;
4304    print $fh qq{<A NAME="$href"></A>\n};
4305}
4306
4307##############################################################################
4308
4309	# These next few lines are legal in both Perl and nroff.
4310
4311.00 ;			# finish .ig
4312
4313'di			\" finish diversion--previous line must be blank
4314.nr nl 0-1		\" fake up transition to first page again
4315.nr % 0			\" start at page 1
4316'; __END__ ############# From here on it's a standard manual page ############
4317.so /usr/local/man/man1/texi2html.1
4318