source: git/doc/texi2html

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