binutils-gdb/readline/doc/texi2html

5430 lines
138 KiB
Plaintext
Raw Normal View History

2002-12-09 06:31:39 +08:00
#! /usr/bin/perl
'di ';
'ig 00 ';
#+##############################################################################
2002-12-09 06:31:39 +08:00
#
# texi2html: Program to transform Texinfo documents to HTML
#
# Copyright (C) 1999, 2000 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#-##############################################################################
2002-12-09 06:31:39 +08:00
# This requires perl version 5 or higher
require 5.0;
#++##############################################################################
#
# NOTE FOR DEBUGGING THIS SCRIPT:
# You can run 'perl texi2html.pl' directly, provided you have
# the environment variable T2H_HOME set to the directory containing
# the texi2html.init file
#
#--##############################################################################
# CVS version:
# $Id$
# Homepage:
$T2H_HOMEPAGE = <<EOT;
http://www.mathematik.uni-kl.de/~obachman/Texi2html
EOT
# Authors:
$T2H_AUTHORS = <<EOT;
Written by: Lionel Cons <Lionel.Cons\@cern.ch> (original author)
Karl Berry <karl\@freefriends.org>
Olaf Bachmann <obachman\@mathematik.uni-kl.de>
and many others.
Maintained by: Olaf Bachmann <obachman\@mathematik.uni-kl.de>
Send bugs and suggestions to <texi2html\@mathematik.uni-kl.de>
EOT
2002-12-09 06:31:39 +08:00
# Version: set in configure.in
$THISVERSION = '1.64';
$THISPROG = "texi2html $THISVERSION"; # program name and version
# The man page for this program is included at the end of this file and can be
# viewed using the command 'nroff -man texi2html'.
2002-12-09 06:31:39 +08:00
# Identity:
$T2H_TODAY = &pretty_date; # like "20 September 1993"
# the eval prevents this from breaking on system which do not have
# a proper getpwuid implemented
eval { ($T2H_USER = (getpwuid ($<))[6]) =~ s/,.*//;}; # Who am i
#+++############################################################################
# #
# Initialization #
# Pasted content of File $(srcdir)/texi2html.init: Default initializations #
# #
#---############################################################################
# leave this within comments, and keep the require statement
# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init
# exists.
#
# -*-perl-*-
######################################################################
# File: texi2html.init
#
# Sets default values for command-line arguments and for various customizable
# procedures
#
# A copy of this file is pasted into the beginning of texi2html by
# 'make texi2html'
#
# Copy this file and make changes to it, if you like.
# Afterwards, either, load it with command-line option -init_file <your_init_file>
#
# $Id$
######################################################################
# stuff which can also be set by command-line options
#
#
# Note: values set here, overwrite values set by the command-line
# options before -init_file and might still be overwritten by
# command-line arguments following the -init_file option
#
# T2H_OPTIONS is a hash whose keys are the (long) names of valid
# command-line options and whose values are a hash with the following keys:
# type ==> one of !|=i|:i|=s|:s (see GetOpt::Long for more info)
# linkage ==> ref to scalar, array, or subroutine (see GetOpt::Long for more info)
# verbose ==> short description of option (displayed by -h)
# noHelp ==> if 1 -> for "not so important options": only print description on -h 1
# 2 -> for obsolete options: only print description on -h 2
$T2H_DEBUG = 0;
$T2H_OPTIONS -> {debug} =
{
type => '=i',
linkage => \$main::T2H_DEBUG,
verbose => 'output HTML with debuging information',
};
$T2H_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">';
$T2H_OPTIONS -> {doctype} =
{
type => '=s',
linkage => \$main::T2H_DOCTYPE,
verbose => 'document type which is output in header of HTML files',
noHelp => 1
};
$T2H_CHECK = 0;
$T2H_OPTIONS -> {check} =
{
type => '!',
linkage => \$main::T2H_CHECK,
verbose => 'if set, only check files and output all things that may be Texinfo commands',
noHelp => 1
};
# -expand
# if set to "tex" (or, "info") expand @iftex and @tex (or, @ifinfo) sections
# else, neither expand @iftex, @tex, nor @ifinfo sections
$T2H_EXPAND = "info";
$T2H_OPTIONS -> {expand} =
{
type => '=s',
linkage => \$T2H_EXPAND,
verbose => 'Expand info|tex|none section of texinfo source',
};
# - glossary
#if set, uses section named `Footnotes' for glossary
$T2H_USE_GLOSSARY = 0;
T2H_OPTIONS -> {glossary} =
{
type => '!',
linkage => \$T2H_USE_GLOSSARY,
verbose => "if set, uses section named `Footnotes' for glossary",
noHelp => 1,
};
# -invisible
# $T2H_INVISIBLE_MARK is the text used to create invisible destination
# anchors for index links (you can for instance use the invisible.xbm
# file shipped with this program). This is a workaround for a known
# bug of many WWW browsers, including netscape.
# For me, it works fine without it -- on the contrary: if there, it
# inserts space between headers and start of text (obachman 3/99)
$T2H_INVISIBLE_MARK = '';
# $T2H_INVISIBLE_MARK = '&#160;';
$T2H_OPTIONS -> {invisible} =
{
type => '=s',
linkage => \$T2H_INVISIBLE_MARK,
verbose => 'use text in invisble anchot',
noHelp => 1,
};
# -iso
# if set, ISO8879 characters are used for special symbols (like copyright, etc)
$T2H_USE_ISO = 0;
$T2H_OPTIONS -> {iso} =
{
type => 'iso',
linkage => \$T2H_USE_ISO,
verbose => 'if set, ISO8879 characters are used for special symbols (like copyright, etc)',
noHelp => 1,
};
# -I
# list directories where @include files are searched for (besides the
# directory of the doc file) additional '-I' args add to this list
@T2H_INCLUDE_DIRS = (".");
$T2H_OPTIONS -> {I} =
{
type => '=s',
linkage => \@T2H_INCLUDE_DIRS,
verbose => 'append $s to the @include search path',
};
# -top_file
# uses file of this name for top-level file
# extension is manipulated appropriately, if necessary.
# If empty, <basename of document>.html is used
# Typically, you would set this to "index.html".
$T2H_TOP_FILE = '';
$T2H_OPTIONS -> {top_file} =
{
type => '=s',
linkage => \$T2H_TOP_FILE,
verbose => 'use $s as top file, instead of <docname>.html',
};
# -toc_file
# uses file of this name for table of contents file
# extension is manipulated appropriately, if necessary.
# If empty, <basename of document>_toc.html is used
$T2H_TOC_FILE = '';
$T2H_OPTIONS -> {toc_file} =
{
type => '=s',
linkage => \$T2H_TOC_FILE,
verbose => 'use $s as ToC file, instead of <docname>_toc.html',
};
# -frames
# if set, output two additional files which use HTML 4.0 "frames".
$T2H_FRAMES = 0;
$T2H_OPTIONS -> {frames} =
{
type => '!',
linkage => \$T2H_FRAMES,
verbose => 'output files which use HTML 4.0 frames (experimental)',
noHelp => 1,
};
# -menu | -nomenu
# if set, show the Texinfo menus
$T2H_SHOW_MENU = 1;
$T2H_OPTIONS -> {menu} =
{
type => '!',
linkage => \$T2H_SHOW_MENU,
verbose => 'ouput Texinfo menus',
};
# -number | -nonumber
# if set, number sections and show section names and numbers in references
# and menus
$T2H_NUMBER_SECTIONS = 1;
$T2H_OPTIONS -> {number} =
{
type => '!',
linkage => \$T2H_NUMBER_SECTIONS,
verbose => 'use numbered sections'
};
# if set, and T2H_NUMBER_SECTIONS is set, then use node names in menu
# entries, instead of section names
$T2H_NODE_NAME_IN_MENU = 0;
# if set and menu entry equals menu descr, then do not print menu descr.
# Likewise, if node name equals entry name, do not print entry name.
$T2H_AVOID_MENU_REDUNDANCY = 1;
# -split section|chapter|none
# if set to 'section' (resp. 'chapter') create one html file per (sub)section
# (resp. chapter) and separate pages for Top, ToC, Overview, Index,
# Glossary, About.
# otherwise, create monolithic html file which contains whole document
#$T2H_SPLIT = 'section';
$T2H_SPLIT = '';
$T2H_OPTIONS -> {split} =
{
type => '=s',
linkage => \$T2H_SPLIT,
verbose => 'split document on section|chapter else no splitting',
};
# -section_navigation|-no-section_navigation
# if set, then navigation panels are printed at the beginning of each section
# and, possibly at the end (depending on whether or not there were more than
# $T2H_WORDS_IN_PAGE words on page
# This is most useful if you do not want to have section navigation
# on -split chapter
$T2H_SECTION_NAVIGATION = 1;
$T2H_OPTIONS -> {sec_nav} =
{
type => '!',
linkage => \$T2H_SECTION_NAVIGATION,
verbose => 'output navigation panels for each section',
};
# -subdir
# if set put result files in this directory
# if not set result files are put into current directory
#$T2H_SUBDIR = 'html';
$T2H_SUBDIR = '';
$T2H_OPTIONS -> {subdir} =
{
type => '=s',
linkage => \$T2H_SUBDIR,
verbose => 'put HTML files in directory $s, instead of $cwd',
};
# -short_extn
# If this is set all HTML file will have extension ".htm" instead of
# ".html". This is helpful when shipping the document to PC systems.
$T2H_SHORTEXTN = 0;
$T2H_OPTIONS -> {short_ext} =
{
type => '!',
linkage => \$T2H_SHORTEXTN,
verbose => 'use "htm" extension for output HTML files',
};
# -prefix
# Set the output file prefix, prepended to all .html, .gif and .pl files.
# By default, this is the basename of the document
$T2H_PREFIX = '';
$T2H_OPTIONS -> {prefix} =
{
type => '=s',
linkage => \$T2H_PREFIX,
verbose => 'use as prefix for output files, instead of <docname>',
};
# -o filename
# If set, generate monolithic document output html into $filename
$T2H_OUT = '';
$T2H_OPTIONS -> {out_file} =
{
type => '=s',
linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';},
verbose => 'if set, all HTML output goes into file $s',
};
# -short_ref
#if set cross-references are given without section numbers
$T2H_SHORT_REF = '';
$T2H_OPTIONS -> {short_ref} =
{
type => '!',
linkage => \$T2H_SHORT_REF,
verbose => 'if set, references are without section numbers',
};
# -idx_sum
# if value is set, then for each @prinindex $what
# $docu_name_$what.idx is created which contains lines of the form
# $key\t$ref sorted alphabetically (case matters)
$T2H_IDX_SUMMARY = 0;
$T2H_OPTIONS -> {idx_sum} =
{
type => '!',
linkage => \$T2H_IDX_SUMMARY,
verbose => 'if set, also output index summary',
noHelp => 1,
};
# -verbose
# if set, chatter about what we are doing
$T2H_VERBOSE = '';
$T2H_OPTIONS -> {Verbose} =
{
type => '!',
linkage => \$T2H_VERBOSE,
verbose => 'print progress info to stdout',
};
# -lang
# For page titles use $T2H_WORDS->{$T2H_LANG}->{...} as title.
# To add a new language, supply list of titles (see $T2H_WORDS below).
# and use ISO 639 language codes (see e.g. perl module Locale-Codes-1.02
# for definitions)
# Default's to 'en' if not set or no @documentlanguage is specified
$T2H_LANG = '';
$T2H_OPTIONS -> {lang} =
{
type => '=s',
linkage => sub {SetDocumentLanguage($_[1])},
verbose => 'use $s as document language (ISO 639 encoding)',
};
# -l2h
# if set, uses latex2html for generation of math content
$T2H_L2H = '';
$T2H_OPTIONS -> {l2h} =
{
type => '!',
linkage => \$T2H_L2H,
verbose => 'if set, uses latex2html for @math and @tex',
};
######################
# The following options are only relevant if $T2H_L2H is set
#
# -l2h_l2h
# name/location of latex2html progam
$T2H_L2H_L2H = "latex2html";
$T2H_OPTIONS -> {l2h_l2h} =
{
type => '=s',
linkage => \$T2H_L2H_L2H,
verbose => 'program to use for latex2html translation',
noHelp => 1,
};
# -l2h_skip
# if set, skips actual call to latex2html tries to reuse previously generated
# content, instead
$T2H_L2H_SKIP = '';
$T2H_OPTIONS -> {l2h_skip} =
{
type => '!',
linkage => \$T2H_L2H_SKIP,
verbose => 'if set, tries to reuse previously latex2html output',
noHelp => 1,
};
# -l2h_tmp
# if set, l2h uses this directory for temporarary files. The path
# leading to this directory may not contain a dot (i.e., a "."),
# otherwise, l2h will fail
$T2H_L2H_TMP = '';
$T2H_OPTIONS -> {l2h_tmp} =
{
type => '=s',
linkage => \$T2H_L2H_TMP,
verbose => 'if set, uses $s as temporary latex2html directory',
noHelp => 1,
};
# if set, cleans intermediate files (they all have the prefix $doc_l2h_)
# of l2h
$T2H_L2H_CLEAN = 1;
$T2H_OPTIONS -> {l2h_clean} =
{
type => '!',
linkage => \$T2H_L2H_CLEAN,
verbose => 'if set, do not keep intermediate latex2html files for later reuse',
noHelp => 1,
};
$T2H_OPTIONS -> {D} =
{
type => '=s',
linkage => sub {$main::value{@_[1]} = 1;},
verbose => 'equivalent to Texinfo "@set $s 1"',
noHelp => 1,
};
$T2H_OPTIONS -> {init_file} =
{
type => '=s',
linkage => \&LoadInitFile,
verbose => 'load init file $s'
};
##############################################################################
#
# The following can only be set in the init file
#
##############################################################################
# if set, center @image by default
# otherwise, do not center by default
$T2H_CENTER_IMAGE = 1;
# used as identation for block enclosing command @example, etc
# If not empty, must be enclosed in <td></td>
$T2H_EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';
# same as above, only for @small
$T2H_SMALL_EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';
# font size for @small
$T2H_SMALL_FONT_SIZE = '-1';
# if non-empty, and no @..heading appeared in Top node, then
# use this as header for top node/section, otherwise use value of
# @settitle or @shorttitle (in that order)
$T2H_TOP_HEADING = '';
# if set, use this chapter for 'Index' button, else
# use first chapter whose name matches 'index' (case insensitive)
$T2H_INDEX_CHAPTER = '';
# if set and $T2H_SPLIT is set, then split index pages at the next letter
# after they have more than that many entries
$T2H_SPLIT_INDEX = 100;
# if set (e.g., to index.html) replace hrefs to this file
# (i.e., to index.html) by ./
$T2H_HREF_DIR_INSTEAD_FILE = '';
########################################################################
# Language dependencies:
# To add a new language extend T2H_WORDS hash and create $T2H_<...>_WORDS hash
# To redefine one word, simply do:
# $T2H_WORDS->{<language>}->{<word>} = 'whatever' in your personal init file.
#
$T2H_WORDS_EN =
{
# titles of pages
'ToC_Title' => 'Table of Contents',
'Overview_Title' => 'Short Table of Contents',
'Index_Title' => 'Index',
'About_Title' => 'About this document',
'Footnotes_Title' => 'Footnotes',
'See' => 'See',
'see' => 'see',
'section' => 'section',
# If necessary, we could extend this as follows:
# # text for buttons
# 'Top_Button' => 'Top',
# 'ToC_Button' => 'Contents',
# 'Overview_Button' => 'Overview',
# 'Index_button' => 'Index',
# 'Back_Button' => 'Back',
# 'FastBack_Button' => 'FastBack',
# 'Prev_Button' => 'Prev',
# 'Up_Button' => 'Up',
# 'Next_Button' => 'Next',
# 'Forward_Button' =>'Forward',
# 'FastWorward_Button' => 'FastForward',
# 'First_Button' => 'First',
# 'Last_Button' => 'Last',
# 'About_Button' => 'About'
};
$T2H_WORD_DE =
{
'ToC_Title' => 'Inhaltsverzeichniss',
'Overview_Title' => 'Kurzes Inhaltsverzeichniss',
'Index_Title' => 'Index',
'About_Title' => '&Uuml;ber dieses Dokument',
'Footnotes_Title' => 'Fu&szlig;noten',
'See' => 'Siehe',
'see' => 'siehe',
'section' => 'Abschnitt',
};
$T2H_WORD_NL =
{
'ToC_Title' => 'Inhoudsopgave',
'Overview_Title' => 'Korte inhoudsopgave',
'Index_Title' => 'Index', #Not sure ;-)
'About_Title' => 'No translation available!', #No translation available!
'Footnotes_Title' => 'No translation available!', #No translation available!
'See' => 'Zie',
'see' => 'zie',
'section' => 'sectie',
};
$T2H_WORD_ES =
{
'ToC_Title' => '&iacute;ndice General',
'Overview_Title' => 'Resumen del Contenido',
'Index_Title' => 'Index', #Not sure ;-)
'About_Title' => 'No translation available!', #No translation available!
'Footnotes_Title' => 'Fu&szlig;noten',
'See' => 'V&eacute;ase',
'see' => 'v&eacute;ase',
'section' => 'secci&oacute;n',
};
$T2H_WORD_NO =
{
'ToC_Title' => 'Innholdsfortegnelse',
'Overview_Title' => 'Kort innholdsfortegnelse',
'Index_Title' => 'Indeks', #Not sure ;-)
'About_Title' => 'No translation available!', #No translation available!
'Footnotes_Title' => 'No translation available!',
'See' => 'Se',
'see' => 'se',
'section' => 'avsnitt',
};
$T2H_WORD_PT =
{
'ToC_Title' => 'Sum&aacute;rio',
'Overview_Title' => 'Breve Sum&aacute;rio',
'Index_Title' => '&Iacute;ndice', #Not sure ;-)
'About_Title' => 'No translation available!', #No translation available!
'Footnotes_Title' => 'No translation available!',
'See' => 'Veja',
'see' => 'veja',
'section' => 'Se&ccedil;&atilde;o',
};
$T2H_WORDS =
{
'en' => $T2H_WORDS_EN,
'de' => $T2H_WORDS_DE,
'nl' => $T2H_WORDS_NL,
'es' => $T2H_WORDS_ES,
'no' => $T2H_WORDS_NO,
'pt' => $T2H_WORDS_PT
};
@MONTH_NAMES_EN =
(
'January', 'February', 'March', 'April', 'May',
'June', 'July', 'August', 'September', 'October',
'November', 'December'
);
@MONTH_NAMES_DE =
(
'Januar', 'Februar', 'M&auml;rz', 'April', 'Mai',
'Juni', 'Juli', 'August', 'September', 'Oktober',
'November', 'Dezember'
);
@MONTH_NAMES_NL =
(
'Januari', 'Februari', 'Maart', 'April', 'Mei',
'Juni', 'Juli', 'Augustus', 'September', 'Oktober',
'November', 'December'
);
@MONTH_NAMES_ES =
(
'enero', 'febrero', 'marzo', 'abril', 'mayo',
'junio', 'julio', 'agosto', 'septiembre', 'octubre',
'noviembre', 'diciembre'
);
@MONTH_NAMES_NO =
(
'januar', 'februar', 'mars', 'april', 'mai',
'juni', 'juli', 'august', 'september', 'oktober',
'november', 'desember'
);
@MONTH_NAMES_PT =
(
'Janeiro', 'Fevereiro', 'Mar&ccedil;o', 'Abril', 'Maio',
'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro',
'Novembro', 'Dezembro'
);
$MONTH_NAMES =
{
'en' => \@MONTH_NAMES_EN,
'de' => \@MONTH_NAMES_DE,
'es' => \@MONTH_NAMES_ES,
'nl' => \@MONTH_NAMES_NL,
'no' => \@MONTH_NAMES_NO,
'pt' => \@MONTH_NAMES_PT
};
########################################################################
# Control of Page layout:
# You can make changes of the Page layout at two levels:
# 1.) For small changes, it is often enough to change the value of
# some global string/hash/array variables
# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines,
# give them another name, and assign them to the respective
# $T2H_<fnc> variable.
# As a general interface, the hashes T2H_HREF, T2H_NAME, T2H_NODE hold
# href, html-name, node-name of
# This -- current section (resp. html page)
# Top -- top page ($T2H_TOP_FILE)
# Contents -- Table of contents
# Overview -- Short table of contents
# Index -- Index page
# About -- page which explain "navigation buttons"
# First -- first node
# Last -- last node
#
# Whether or not the following hash values are set, depends on the context
# (all values are w.r.t. 'This' section)
# Next -- next node of texinfo
# Prev -- previous node of texinfo
# Up -- up node of texinfo
# Forward -- next node in reading order
# Back -- previous node in reading order
# FastForward -- if leave node, up and next, else next node
# FastBackward-- if leave node, up and prev, else prev node
#
# Furthermore, the following global variabels are set:
# $T2H_THISDOC{title} -- title as set by @setttile
# $T2H_THISDOC{fulltitle} -- full title as set by @title...
# $T2H_THISDOC{subtitle} -- subtitle as set by @subtitle
# $T2H_THISDOC{author} -- author as set by @author
#
# and pointer to arrays of lines which need to be printed by t2h_print_lines
# $T2H_OVERVIEW -- lines of short table of contents
# $T2H_TOC -- lines of table of contents
# $T2H_TOP -- lines of Top texinfo node
# $T2H_THIS_SECTION -- lines of 'This' section
#
# There are the following subs which control the layout:
#
$T2H_print_section = \&T2H_DEFAULT_print_section;
$T2H_print_Top_header = \&T2H_DEFAULT_print_Top_header;
$T2H_print_Top_footer = \&T2H_DEFAULT_print_Top_footer;
$T2H_print_Top = \&T2H_DEFAULT_print_Top;
$T2H_print_Toc = \&T2H_DEFAULT_print_Toc;
$T2H_print_Overview = \&T2H_DEFAULT_print_Overview;
$T2H_print_Footnotes = \&T2H_DEFAULT_print_Footnotes;
$T2H_print_About = \&T2H_DEFAULT_print_About;
$T2H_print_misc_header = \&T2H_DEFAULT_print_misc_header;
$T2H_print_misc_footer = \&T2H_DEFAULT_print_misc_footer;
$T2H_print_misc = \&T2H_DEFAULT_print_misc;
$T2H_print_chapter_header = \&T2H_DEFAULT_print_chapter_header;
$T2H_print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer;
$T2H_print_page_head = \&T2H_DEFAULT_print_page_head;
$T2H_print_page_foot = \&T2H_DEFAULT_print_page_foot;
$T2H_print_head_navigation = \&T2H_DEFAULT_print_head_navigation;
$T2H_print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation;
$T2H_button_icon_img = \&T2H_DEFAULT_button_icon_img;
$T2H_print_navigation = \&T2H_DEFAULT_print_navigation;
$T2H_about_body = \&T2H_DEFAULT_about_body;
$T2H_print_frame = \&T2H_DEFAULT_print_frame;
$T2H_print_toc_frame = \&T2H_DEFAULT_print_toc_frame;
########################################################################
# Layout for html for every sections
#
sub T2H_DEFAULT_print_section
{
my $fh = shift;
local $T2H_BUTTONS = \@T2H_SECTION_BUTTONS;
&$T2H_print_head_navigation($fh) if $T2H_SECTION_NAVIGATION;
my $nw = t2h_print_lines($fh);
if ($T2H_SPLIT eq 'section' && $T2H_SECTION_NAVIGATION)
{
&$T2H_print_foot_navigation($fh, $nw);
}
else
{
print $fh '<HR SIZE="6">' . "\n";
}
}
###################################################################
# Layout of top-page I recommend that you use @ifnothtml, @ifhtml,
# @html within the Top texinfo node to specify content of top-level
# page.
#
# If you enclose everything in @ifnothtml, then title, subtitle,
# author and overview is printed
# T2H_HREF of Next, Prev, Up, Forward, Back are not defined
# if $T2H_SPLIT then Top page is in its own html file
sub T2H_DEFAULT_print_Top_header
{
&$T2H_print_page_head(@_) if $T2H_SPLIT;
t2h_print_label(@_); # this needs to be called, otherwise no label set
&$T2H_print_head_navigation(@_);
}
sub T2H_DEFAULT_print_Top_footer
{
&$T2H_print_foot_navigation(@_);
&$T2H_print_page_foot(@_) if $T2H_SPLIT;
}
sub T2H_DEFAULT_print_Top
{
my $fh = shift;
# for redefining navigation buttons use:
# local $T2H_BUTTONS = [...];
# as it is, 'Top', 'Contents', 'Index', 'About' are printed
local $T2H_BUTTONS = \@T2H_MISC_BUTTONS;
&$T2H_print_Top_header($fh);
if ($T2H_THIS_SECTION)
{
# if top-level node has content, then print it with extra header
print $fh "<H1>$T2H_NAME{Top}</H1>"
unless ($T2H_HAS_TOP_HEADING);
t2h_print_lines($fh, $T2H_THIS_SECTION)
}
else
{
# top-level node is fully enclosed in @ifnothtml
# print fulltitle, subtitle, author, Overview
print $fh
"<CENTER>\n<H1>" .
join("</H1>\n<H1>", split(/\n/, $T2H_THISDOC{fulltitle})) .
"</H1>\n";
print $fh "<H2>$T2H_THISDOC{subtitle}</H2>\n" if $T2H_THISDOC{subtitle};
print $fh "$T2H_THISDOC{author}\n" if $T2H_THISDOC{author};
print $fh <<EOT;
</CENTER>
<HR>
<P></P>
<H2> Overview: </H2>
<BLOCKQUOTE>
EOT
t2h_print_lines($fh, $T2H_OVERVIEW);
print $fh "</BLOCKQUOTE>\n";
}
&$T2H_print_Top_footer($fh);
}
###################################################################
# Layout of Toc, Overview, and Footnotes pages
# By default, we use "normal" layout
# T2H_HREF of Next, Prev, Up, Forward, Back, etc are not defined
# use: local $T2H_BUTTONS = [...] to redefine navigation buttons
sub T2H_DEFAULT_print_Toc
{
return &$T2H_print_misc(@_);
}
sub T2H_DEFAULT_print_Overview
{
return &$T2H_print_misc(@_);
}
sub T2H_DEFAULT_print_Footnotes
{
return &$T2H_print_misc(@_);
}
sub T2H_DEFAULT_print_About
{
return &$T2H_print_misc(@_);
}
sub T2H_DEFAULT_print_misc_header
{
&$T2H_print_page_head(@_) if $T2H_SPLIT;
# this needs to be called, otherwise, no labels are set
t2h_print_label(@_);
&$T2H_print_head_navigation(@_);
}
sub T2H_DEFAULT_print_misc_footer
{
&$T2H_print_foot_navigation(@_);
&$T2H_print_page_foot(@_) if $T2H_SPLIT;
}
sub T2H_DEFAULT_print_misc
{
my $fh = shift;
local $T2H_BUTTONS = \@T2H_MISC_BUTTONS;
&$T2H_print_misc_header($fh);
print $fh "<H1>$T2H_NAME{This}</H1>\n";
t2h_print_lines($fh);
&$T2H_print_misc_footer($fh);
}
###################################################################
# chapter_header and chapter_footer are only called if
# T2H_SPLIT eq 'chapter'
# chapter_header: after print_page_header, before print_section
# chapter_footer: after print_section of last section, before print_page_footer
#
# If you want to get rid of navigation stuff after each section,
# redefine print_section such that it does not call print_navigation,
# and put print_navigation into print_chapter_header
@T2H_CHAPTER_BUTTONS =
(
'FastBack', 'FastForward', ' ',
' ', ' ', ' ', ' ',
'Top', 'Contents', 'Index', 'About',
);
sub T2H_DEFAULT_print_chapter_header
{
# nothing to do there, by default
if (! $T2H_SECTION_NAVIGATION)
{
my $fh = shift;
local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS;
&$T2H_print_navigation($fh);
print $fh "\n<HR SIZE=2>\n";
}
}
sub T2H_DEFAULT_print_chapter_footer
{
local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS;
&$T2H_print_navigation(@_);
}
###################################################################
$T2H_TODAY = &pretty_date; # like "20 September 1993"
sub pretty_date {
local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
$year += ($year < 70) ? 2000 : 1900;
# obachman: Let's do it as the Americans do
return($MONTH_NAMES->{$T2H_LANG}[$mon] . ", " . $mday . " " . $year);
}
###################################################################
# Layout of standard header and footer
#
# Set the default body text, inserted between <BODY ... >
###$T2H_BODYTEXT = 'LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"';
$T2H_BODYTEXT = 'LANG="' . $T2H_LANG . '" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"';
# text inserted after <BODY ...>
$T2H_AFTER_BODY_OPEN = '';
#text inserted before </BODY>
$T2H_PRE_BODY_CLOSE = '';
# this is used in footer
$T2H_ADDRESS = "by <I>$T2H_USER</I> " if $T2H_USER;
$T2H_ADDRESS .= "on <I>$T2H_TODAY</I>";
# this is added inside <HEAD></HEAD> after <TITLE> and some META NAME stuff
# can be used for <style> <script>, <meta> tags
$T2H_EXTRA_HEAD = '';
sub T2H_DEFAULT_print_page_head
{
my $fh = shift;
my $longtitle = "$T2H_THISDOC{title}: $T2H_NAME{This}";
print $fh <<EOT;
<HTML>
$T2H_DOCTYPE
<!-- Created on $T2H_TODAY by $THISPROG -->
<!--
$T2H_AUTHORS
-->
<HEAD>
<TITLE>$longtitle</TITLE>
<META NAME="description" CONTENT="$longtitle">
<META NAME="keywords" CONTENT="$longtitle">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META NAME="Generator" CONTENT="$THISPROG">
$T2H_EXTRA_HEAD
</HEAD>
<BODY $T2H_BODYTEXT>
$T2H_AFTER_BODY_OPEN
EOT
}
sub T2H_DEFAULT_print_page_foot
{
my $fh = shift;
print $fh <<EOT;
<BR>
<FONT SIZE="-1">
This document was generated
$T2H_ADDRESS
using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A>
$T2H_PRE_BODY_CLOSE
</BODY>
</HTML>
EOT
}
###################################################################
# Layout of navigation panel
# if this is set, then a vertical navigation panel is used
$T2H_VERTICAL_HEAD_NAVIGATION = 0;
sub T2H_DEFAULT_print_head_navigation
{
my $fh = shift;
if ($T2H_VERTICAL_HEAD_NAVIGATION)
{
print $fh <<EOT;
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
<TR VALIGN="TOP">
<TD ALIGN="LEFT">
EOT
}
&$T2H_print_navigation($fh, $T2H_VERTICAL_HEAD_NAVIGATION);
if ($T2H_VERTICAL_HEAD_NAVIGATION)
{
print $fh <<EOT;
</TD>
<TD ALIGN="LEFT">
EOT
}
elsif ($T2H_SPLIT eq 'section')
{
print $fh "<HR SIZE=1>\n";
}
}
# Specifies the minimum page length required before a navigation panel
# is placed at the bottom of a page (the default is that of latex2html)
# T2H_THIS_WORDS_IN_PAGE holds number of words of current page
$T2H_WORDS_IN_PAGE = 300;
sub T2H_DEFAULT_print_foot_navigation
{
my $fh = shift;
my $nwords = shift;
if ($T2H_VERTICAL_HEAD_NAVIGATION)
{
print $fh <<EOT;
</TD>
</TR>
</TABLE>
EOT
}
print $fh "<HR SIZE=1>\n";
&$T2H_print_navigation($fh) if ($nwords >= $T2H_WORDS_IN_PAGE)
}
######################################################################
# navigation panel
#
# specify in this array which "buttons" should appear in which order
# in the navigation panel for sections; use ' ' for empty buttons (space)
@T2H_SECTION_BUTTONS =
(
'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward',
' ', ' ', ' ', ' ',
'Top', 'Contents', 'Index', 'About',
);
# buttons for misc stuff
@T2H_MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About');
# insert here name of icon images for buttons
# Icons are used, if $T2H_ICONS and resp. value are set
%T2H_ACTIVE_ICONS =
(
'Top', '',
'Contents', '',
'Overview', '',
'Index', '',
'Back', '',
'FastBack', '',
'Prev', '',
'Up', '',
'Next', '',
'Forward', '',
'FastForward', '',
'About' , '',
'First', '',
'Last', '',
' ', ''
);
# insert here name of icon images for these, if button is inactive
%T2H_PASSIVE_ICONS =
(
'Top', '',
'Contents', '',
'Overview', '',
'Index', '',
'Back', '',
'FastBack', '',
'Prev', '',
'Up', '',
'Next', '',
'Forward', '',
'FastForward', '',
'About', '',
'First', '',
'Last', '',
);
# how to create IMG tag
sub T2H_DEFAULT_button_icon_img
{
my $button = shift;
my $icon = shift;
my $name = shift;
return qq{<IMG SRC="$icon" BORDER="0" ALT="$button: $name" ALIGN="MIDDLE">};
}
# Names of text as alternative for icons
%T2H_NAVIGATION_TEXT =
(
'Top', 'Top',
'Contents', 'Contents',
'Overview', 'Overview',
'Index', 'Index',
' ', ' &nbsp; ',
'Back', ' &lt; ',
'FastBack', ' &lt;&lt; ',
'Prev', 'Prev',
'Up', ' Up ',
'Next', 'Next',
'Forward', ' &gt; ',
'FastForward', ' &gt;&gt; ',
'About', ' ? ',
'First', ' |&lt; ',
'Last', ' &gt;| '
);
sub T2H_DEFAULT_print_navigation
{
my $fh = shift;
my $vertical = shift;
my $spacing = 1;
print $fh "<TABLE CELLPADDING=$spacing CELLSPACING=$spacing BORDER=0>\n";
print $fh "<TR>" unless $vertical;
for $button (@$T2H_BUTTONS)
{
print $fh qq{<TR VALIGN="TOP" ALIGN="LEFT">\n} if $vertical;
print $fh qq{<TD VALIGN="MIDDLE" ALIGN="LEFT">};
if (ref($button) eq 'CODE')
{
&$button($fh, $vertical);
}
elsif ($button eq ' ')
{ # handle space button
print $fh
$T2H_ICONS && $T2H_ACTIVE_ICONS{' '} ?
&$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{' '}) :
$T2H_NAVIGATION_TEXT{' '};
next;
}
elsif ($T2H_HREF{$button})
{ # button is active
print $fh
$T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? # use icon ?
t2h_anchor('', $T2H_HREF{$button}, # yes
&$T2H_button_icon_img($button,
$T2H_ACTIVE_ICONS{$button},
$T2H_NAME{$button}))
: # use text
"[" .
t2h_anchor('', $T2H_HREF{$button}, $T2H_NAVIGATION_TEXT{$button}) .
"]";
}
else
{ # button is passive
print $fh
$T2H_ICONS && $T2H_PASSIVE_ICONS{$button} ?
&$T2H_button_icon_img($button,
$T2H_PASSIVE_ICONS{$button},
$T2H_NAME{$button}) :
"[" . $T2H_NAVIGATION_TEXT{$button} . "]";
}
print $fh "</TD>\n";
print $fh "</TR>\n" if $vertical;
}
print $fh "</TR>" unless $vertical;
print $fh "</TABLE>\n";
}
######################################################################
# Frames: this is from "Richard Y. Kim" <ryk@coho.net>
# Should be improved to be more conforming to other _print* functions
sub T2H_DEFAULT_print_frame
{
my $fh = shift;
print $fh <<EOT;
<HTML>
<HEAD><TITLE>$T2H_THISDOC{title}</TITLE></HEAD>
<FRAMESET cols="140,*">
<FRAME name=toc src="$docu_toc_frame_file">
<FRAME name=main src="$docu_doc">
</FRAMESET>
</HTML>
EOT
}
sub T2H_DEFAULT_print_toc_frame
{
my $fh = shift;
&$T2H_print_page_head($fh);
print $fh <<EOT;
<H2>Content</H2>
EOT
print $fh map {s/HREF=/target=\"main\" HREF=/; $_;} @stoc_lines;
print $fh "</BODY></HTML>\n";
}
######################################################################
# About page
#
# T2H_PRE_ABOUT might be a function
$T2H_PRE_ABOUT = <<EOT;
This document was generated $T2H_ADDRESS
using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A>
<P></P>
EOT
$T2H_AFTER_ABOUT = '';
sub T2H_DEFAULT_about_body
{
my $about;
if (ref($T2H_PRE_ABOUT) eq 'CODE')
{
$about = &$T2H_PRE_ABOUT();
}
else
{
$about = $T2H_PRE_ABOUT;
}
$about .= <<EOT;
The buttons in the navigation panels have the following meaning:
<P></P>
<table border = "1">
<TR>
<TH> Button </TH>
<TH> Name </TH>
<TH> Go to </TH>
<TH> From 1.2.3 go to</TH>
</TR>
EOT
for $button (@T2H_SECTION_BUTTONS)
{
next if $button eq ' ' || ref($button) eq 'CODE';
$about .= <<EOT;
<TR>
<TD ALIGN="CENTER">
EOT
$about .=
($T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ?
&$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{$button}) :
" [" . $T2H_NAVIGATION_TEXT{$button} . "] ");
$about .= <<EOT;
</TD>
<TD ALIGN="CENTER">
$button
</TD>
<TD>
$T2H_BUTTONS_GOTO{$button}
</TD>
<TD>
$T2H_BUTTONS_EXAMPLE{$button}
</TD>
</TR>
EOT
}
$about .= <<EOT;
</TABLE>
<P></P>
where the <STRONG> Example </STRONG> assumes that the current position
is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of
the following structure:
<UL>
<LI> 1. Section One </LI>
<UL>
<LI>1.1 Subsection One-One</LI>
<UL>
<LI> ... </LI>
</UL>
<LI>1.2 Subsection One-Two</LI>
<UL>
<LI>1.2.1 Subsubsection One-Two-One
</LI><LI>1.2.2 Subsubsection One-Two-Two
</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
&lt;== Current Position </STRONG>
</LI><LI>1.2.4 Subsubsection One-Two-Four
</LI></UL>
<LI>1.3 Subsection One-Three</LI>
<UL>
<LI> ... </LI>
</UL>
<LI>1.4 Subsection One-Four</LI>
</UL>
</UL>
$T2H_AFTER_ABOUT
EOT
return $about;
}
%T2H_BUTTONS_GOTO =
(
'Top', 'cover (top) of document',
'Contents', 'table of contents',
'Overview', 'short table of contents',
'Index', 'concept index',
'Back', 'previous section in reading order',
'FastBack', 'previous or up-and-previous section ',
'Prev', 'previous section same level',
'Up', 'up section',
'Next', 'next section same level',
'Forward', 'next section in reading order',
'FastForward', 'next or up-and-next section',
'About' , 'this page',
'First', 'first section in reading order',
'Last', 'last section in reading order',
);
%T2H_BUTTONS_EXAMPLE =
(
'Top', ' &nbsp; ',
'Contents', ' &nbsp; ',
'Overview', ' &nbsp; ',
'Index', ' &nbsp; ',
'Back', '1.2.2',
'FastBack', '1.1',
'Prev', '1.2.2',
'Up', '1.2',
'Next', '1.2.4',
'Forward', '1.2.4',
'FastForward', '1.3',
'About', ' &nbsp; ',
'First', '1.',
'Last', '1.2.4',
);
######################################################################
# from here on, its l2h init stuff
#
## initialization for latex2html as for Singular manual generation
## obachman 3/99
#
# Options controlling Titles, File-Names, Tracing and Sectioning
#
$TITLE = '';
$SHORTEXTN = 0;
$LONG_TITLES = 0;
$DESTDIR = ''; # should be overwritten by cmd-line argument
$NO_SUBDIR = 0;# should be overwritten by cmd-line argument
$PREFIX = ''; # should be overwritten by cmd-line argument
$AUTO_PREFIX = 0; # this is needed, so that prefix settings are used
$AUTO_LINK = 0;
$SPLIT = 0;
$MAX_LINK_DEPTH = 0;
$TMP = ''; # should be overwritten by cmd-line argument
$DEBUG = 0;
$VERBOSE = 1;
#
# Options controlling Extensions and Special Features
#
$HTML_VERSION = "3.2";
$TEXDEFS = 1; # we absolutely need that
$EXTERNAL_FILE = '';
$SCALABLE_FONTS = 1;
$NO_SIMPLE_MATH = 1;
$LOCAL_ICONS = 1;
$SHORT_INDEX = 0;
$NO_FOOTNODE = 1;
$ADDRESS = '';
$INFO = '';
#
# Switches controlling Image Generation
#
$ASCII_MODE = 0;
$NOLATEX = 0;
$EXTERNAL_IMAGES = 0;
$PS_IMAGES = 0;
$NO_IMAGES = 0;
$IMAGES_ONLY = 0;
$REUSE = 2;
$ANTI_ALIAS = 1;
$ANTI_ALIAS_TEXT = 1;
#
#Switches controlling Navigation Panels
#
$NO_NAVIGATION = 1;
$ADDRESS = '';
$INFO = 0; # 0 = do not make a "About this document..." section
#
#Switches for Linking to other documents
#
# actuall -- we don't care
$MAX_SPLIT_DEPTH = 0; # Stop making separate files at this depth
$MAX_LINK_DEPTH = 0; # Stop showing child nodes at this depth
$NOLATEX = 0; # 1 = do not pass unknown environments to Latex
$EXTERNAL_IMAGES = 0; # 1 = leave the images outside the document
$ASCII_MODE = 0; # 1 = do not use any icons or internal images
# 1 = use links to external postscript images rather than inlined bitmap
# images.
$PS_IMAGES = 0;
$SHOW_SECTION_NUMBERS = 0;
### Other global variables ###############################################
$CHILDLINE = "";
# This is the line width measured in pixels and it is used to right justify
# equations and equation arrays;
$LINE_WIDTH = 500;
# Used in conjunction with AUTO_NAVIGATION
$WORDS_IN_PAGE = 300;
# Affects ONLY the way accents are processed
$default_language = 'english';
# The value of this variable determines how many words to use in each
# title that is added to the navigation panel (see below)
#
$WORDS_IN_NAVIGATION_PANEL_TITLES = 0;
# This number will determine the size of the equations, special characters,
# and anything which will be converted into an inlined image
# *except* "image generating environments" such as "figure", "table"
# or "minipage".
# Effective values are those greater than 0.
# Sensible values are between 0.1 - 4.
$MATH_SCALE_FACTOR = 1.5;
# This number will determine the size of
# image generating environments such as "figure", "table" or "minipage".
# Effective values are those greater than 0.
# Sensible values are between 0.1 - 4.
$FIGURE_SCALE_FACTOR = 1.6;
# If both of the following two variables are set then the "Up" button
# of the navigation panel in the first node/page of a converted document
# will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set
# to some text which describes this external link.
$EXTERNAL_UP_LINK = "";
$EXTERNAL_UP_TITLE = "";
# If this is set then the resulting HTML will look marginally better if viewed
# with Netscape.
$NETSCAPE_HTML = 1;
# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0"
# Paper sizes has no effect other than in the time it takes to create inlined
# images and in whether large images can be created at all ie
# - larger paper sizes *MAY* help with large image problems
# - smaller paper sizes are quicker to handle
$PAPERSIZE = "a4";
# Replace "english" with another language in order to tell LaTeX2HTML that you
# want some generated section titles (eg "Table of Contents" or "References")
# to appear in a different language. Currently only "english" and "french"
# is supported but it is very easy to add your own. See the example in the
# file "latex2html.config"
$TITLES_LANGUAGE = "english";
1; # This must be the last non-comment line
# End File texi2html.init
######################################################################
require "$ENV{T2H_HOME}/texi2html.init"
if ($0 =~ /\.pl$/ &&
-e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init");
#+++############################################################################
# #
# Initialization #
# Pasted content of File $(srcdir)/MySimple.pm: Command-line processing #
# #
#---############################################################################
# leave this within comments, and keep the require statement
# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init
# exists.
#
package Getopt::MySimple;
# Name:
# Getopt::MySimple.
#
# Documentation:
# POD-style (incomplete) documentation is in file MySimple.pod
#
# Tabs:
# 4 spaces || die.
#
# Author:
# Ron Savage rpsavage@ozemail.com.au.
# 1.00 19-Aug-97 Initial version.
# 1.10 13-Oct-97 Add arrays of switches (eg '=s@').
# 1.20 3-Dec-97 Add 'Help' on a per-switch basis.
# 1.30 11-Dec-97 Change 'Help' to 'verbose'. Make all hash keys lowercase.
# 1.40 10-Nov-98 Change width of help report. Restructure tests.
# 1-Jul-00 Modifications for Texi2html
# --------------------------------------------------------------------------
# Locally modified by obachman (Display type instead of env, order by cmp)
# $Id$
# use strict;
# no strict 'refs';
use vars qw(@EXPORT @EXPORT_OK @ISA);
use vars qw($fieldWidth $opt $VERSION);
use Exporter();
use Getopt::Long;
@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw($opt); # An alias for $self -> {'opt'}.
# --------------------------------------------------------------------------
$fieldWidth = 20;
$VERSION = '1.41';
# --------------------------------------------------------------------------
sub byOrder
{
my($self) = @_;
return uc($a) cmp (uc($b));
}
# --------------------------------------------------------------------------
sub dumpOptions
{
my($self) = @_;
print 'Option', ' ' x ($fieldWidth - length('Option') ), "Value\n";
for (sort byOrder keys(%{$self -> {'opt'} }) )
{
print "-$_", ' ' x ($fieldWidth - (1 + length) ), "${$self->{'opt'} }{$_}\n";
}
print "\n";
} # End of dumpOptions.
# --------------------------------------------------------------------------
# Return:
# 0 -> Error.
# 1 -> Ok.
sub getOptions
{
push(@_, 0) if ($#_ == 2); # Default for $ignoreCase is 0.
push(@_, 1) if ($#_ == 3); # Default for $helpThenExit is 1.
my($self, $default, $helpText, $versionText,
$helpThenExit, $versionThenExit, $ignoreCase) = @_;
$helpThenExit = 1 unless (defined($helpThenExit));
$versionThenExit = 1 unless (defined($versionThenExit));
$ignoreCase = 0 unless (defined($ignoreCase));
$self -> {'default'} = $default;
$self -> {'helpText'} = $helpText;
$self -> {'versionText'} = $versionText;
$Getopt::Long::ignorecase = $ignoreCase;
unless (defined($self -> {'default'}{'help'}))
{
$self -> {'default'}{'help'} =
{
type => ':i',
default => '',
linkage => sub {$self->helpOptions($_[1]); exit (0) if $helpThenExit;},
verbose => "print help and exit"
};
}
unless (defined($self -> {'default'}{'version'}))
{
$self -> {'default'}{'version'} =
{
type => '',
default => '',
linkage => sub {print $self->{'versionText'}; exit (0) if versionTheExit;},
verbose => "print version and exit"
};
}
for (keys(%{$self -> {'default'} }) )
{
my $type = ${$self -> {'default'} }{$_}{'type'};
push(@{$self -> {'type'} }, "$_$type");
$self->{'opt'}->{$_} = ${$self -> {'default'} }{$_}{'linkage'}
if ${$self -> {'default'} }{$_}{'linkage'};
}
my($result) = &GetOptions($self -> {'opt'}, @{$self -> {'type'} });
return $result unless $result;
for (keys(%{$self -> {'default'} }) )
{
if (! defined(${$self -> {'opt'} }{$_})) #{
{
${$self -> {'opt'} }{$_} = ${$self -> {'default'} }{$_}{'default'};
}
}
$result;
} # End of getOptions.
# --------------------------------------------------------------------------
sub helpOptions
{
my($self) = shift;
my($noHelp) = shift;
$noHelp = 0 unless $noHelp;
my($optwidth, $typewidth, $defaultwidth, $maxlinewidth, $valind, $valwidth)
= (10, 5, 9, 78, 4, 11);
print "$self->{'helpText'}" if ($self -> {'helpText'});
print ' Option', ' ' x ($optwidth - length('Option') -1 ),
'Type', ' ' x ($typewidth - length('Type') + 1),
'Default', ' ' x ($defaultwidth - length('Default') ),
"Description\n";
for (sort byOrder keys(%{$self -> {'default'} }) )
{
my($line, $help, $option, $val);
$option = $_;
next if ${$self->{'default'} }{$_}{'noHelp'} && ${$self->{'default'} }{$_}{'noHelp'} > $noHelp;
$line = " -$_ " . ' ' x ($optwidth - (2 + length) ) .
"${$self->{'default'} }{$_}{'type'} ".
' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) ));
$val = ${$self->{'default'} }{$_}{'linkage'};
if ($val)
{
if (ref($val) eq 'SCALAR')
{
$val = $$val;
}
else
{
$val = '';
}
}
else
{
$val = ${$self->{'default'} }{$_}{'default'};
}
$line .= "$val ";
$line .= ' ' x ($optwidth + $typewidth + $defaultwidth + 1 - length($line));
if (defined(${$self -> {'default'} }{$_}{'verbose'}) &&
${$self -> {'default'} }{$_}{'verbose'} ne '')
{
$help = "${$self->{'default'} }{$_}{'verbose'}";
}
else
{
$help = ' ';
}
if ((length("$line") + length($help)) < $maxlinewidth)
{
print $line , $help, "\n";
}
else
{
print $line, "\n", ' ' x $valind, $help, "\n";
}
for $val (sort byOrder keys(%{${$self->{'default'}}{$option}{'values'}}))
{
print ' ' x ($valind + 2);
print $val, ' ', ' ' x ($valwidth - length($val) - 2);
print ${$self->{'default'}}{$option}{'values'}{$val}, "\n";
}
}
print <<EOT;
Note: 'Options' may be abbreviated. 'Type' specifications mean:
<none>| ! no argument: variable is set to 1 on -foo (or, to 0 on -nofoo)
=s | :s mandatory (or, optional) string argument
=i | :i mandatory (or, optional) integer argument
EOT
} # End of helpOptions.
#-------------------------------------------------------------------
sub new
{
my($class) = @_;
my($self) = {};
$self -> {'default'} = {};
$self -> {'helpText'} = '';
$self -> {'opt'} = {};
$opt = $self -> {'opt'}; # An alias for $self -> {'opt'}.
$self -> {'type'} = ();
return bless $self, $class;
} # End of new.
# --------------------------------------------------------------------------
1;
# End MySimple.pm
require "$ENV{T2H_HOME}/MySimple.pm"
if ($0 =~ /\.pl$/ &&
-e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init");
package main;
#+++############################################################################
# #
# Constants #
# #
#---############################################################################
$DEBUG_TOC = 1;
$DEBUG_INDEX = 2;
$DEBUG_BIB = 4;
$DEBUG_GLOSS = 8;
$DEBUG_DEF = 16;
$DEBUG_HTML = 32;
$DEBUG_USER = 64;
2002-12-09 06:31:39 +08:00
$DEBUG_L2H = 128;
1999-08-03 07:48:02 +08:00
$BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference
$FILERE = '[\/\w.+-]+'; # RE for a file name
$VARRE = '[^\s\{\}]+'; # RE for a variable name
2002-12-09 06:31:39 +08:00
$NODERE = '[^,:]+'; # RE for a node name
$NODESRE = '[^:]+'; # RE for a list of node names
$ERROR = "***"; # prefix for errors
$WARN = "**"; # prefix for warnings
# program home page
$PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections
2002-12-09 06:31:39 +08:00
$CHAPTEREND = "<!-- End chapter -->\n"; # to know where a chpater ends
$SECTIONEND = "<!-- End section -->\n"; # to know where section ends
$TOPEND = "<!-- End top -->\n"; # to know where top ends
#
# pre-defined indices
#
2002-12-09 06:31:39 +08:00
$index_properties =
{
'c' => { name => 'cp'},
'f' => { name => 'fn', code => 1},
'v' => { name => 'vr', code => 1},
'k' => { name => 'ky', code => 1},
'p' => { name => 'pg', code => 1},
't' => { name => 'tp', code => 1}
};
%predefined_index = (
'cp', 'c',
'fn', 'f',
'vr', 'v',
'ky', 'k',
'pg', 'p',
'tp', 't',
);
#
# valid indices
#
%valid_index = (
'c', 1,
'f', 1,
'v', 1,
'k', 1,
'p', 1,
't', 1,
);
#
# texinfo section names to level
#
%sec2level = (
'top', 0,
'chapter', 1,
'unnumbered', 1,
'majorheading', 1,
'chapheading', 1,
'appendix', 1,
'section', 2,
'unnumberedsec', 2,
'heading', 2,
'appendixsec', 2,
'appendixsection', 2,
'subsection', 3,
'unnumberedsubsec', 3,
'subheading', 3,
'appendixsubsec', 3,
'subsubsection', 4,
'unnumberedsubsubsec', 4,
'subsubheading', 4,
'appendixsubsubsec', 4,
);
#
# accent map, TeX command to ISO name
#
%accent_map = (
'"', 'uml',
'~', 'tilde',
'^', 'circ',
'`', 'grave',
'\'', 'acute',
);
#
# texinfo "simple things" (@foo) to HTML ones
#
%simple_map = (
# cf. makeinfo.c
"*", "<BR>", # HTML+
" ", " ",
2002-12-09 06:31:39 +08:00
"\t", " ",
"-", "&#173;", # soft hyphen
"\n", "\n",
"|", "",
2002-12-09 06:31:39 +08:00
'tab', '<\/TD><TD>',
# spacing commands
":", "",
"!", "!",
"?", "?",
".", ".",
1999-08-03 07:48:02 +08:00
"-", "",
);
#
# texinfo "things" (@foo{}) to HTML ones
#
%things_map = (
'TeX', 'TeX',
'br', '<P>', # paragraph break
'bullet', '*',
'copyright', '(C)',
2002-12-09 06:31:39 +08:00
'dots', '<small>...<\/small>',
'enddots', '<small>....<\/small>',
'equiv', '==',
'error', 'error-->',
'expansion', '==>',
'minus', '-',
'point', '-!-',
'print', '-|',
'result', '=>',
2002-12-09 06:31:39 +08:00
'today', $T2H_TODAY,
'aa', '&aring;',
'AA', '&Aring;',
'ae', '&aelig;',
'oe', '&#156;',
'AE', '&AElig;',
'OE', '&#140;',
'o', '&oslash;',
'O', '&Oslash;',
'ss', '&szlig;',
'l', '\/l',
'L', '\/L',
'exclamdown', '&iexcl;',
'questiondown', '&iquest;',
'pounds', '&pound;'
);
#
# texinfo styles (@foo{bar}) to HTML ones
#
%style_map = (
2002-12-09 06:31:39 +08:00
'acronym', '&do_acronym',
'asis', '',
'b', 'B',
'cite', 'CITE',
'code', 'CODE',
2002-12-09 06:31:39 +08:00
'command', 'CODE',
'ctrl', '&do_ctrl', # special case
1999-08-03 07:48:02 +08:00
'dfn', 'EM', # DFN tag is illegal in the standard
'dmn', '', # useless
1999-08-03 07:48:02 +08:00
'email', '&do_email', # insert a clickable email address
'emph', 'EM',
2002-12-09 06:31:39 +08:00
'env', 'CODE',
'file', '"TT', # will put quotes, cf. &apply_style
'i', 'I',
'kbd', 'KBD',
'key', 'KBD',
2002-12-09 06:31:39 +08:00
'math', '&do_math',
'option', '"SAMP', # will put quotes, cf. &apply_style
'r', '', # unsupported
'samp', '"SAMP', # will put quotes, cf. &apply_style
'sc', '&do_sc', # special case
'strong', 'STRONG',
't', 'TT',
'titlefont', '', # useless
1999-08-03 07:48:02 +08:00
'uref', '&do_uref', # insert a clickable URL
'url', '&do_url', # insert a clickable URL
'var', 'VAR',
'w', '', # unsupported
2002-12-09 06:31:39 +08:00
'H', '&do_accent',
'dotaccent', '&do_accent',
'ringaccent','&do_accent',
'tieaccent', '&do_accent',
'u','&do_accent',
'ubaraccent','&do_accent',
'udotaccent','&do_accent',
'v', '&do_accent',
',', '&do_accent',
'dotless', '&do_accent'
);
#
# texinfo format (@foo/@end foo) to HTML ones
#
%format_map = (
'quotation', 'BLOCKQUOTE',
# lists
'itemize', 'UL',
'enumerate', 'OL',
# poorly supported
'flushleft', 'PRE',
'flushright', 'PRE',
);
2002-12-09 06:31:39 +08:00
#
# an eval of these $complex_format_map->{what}->[0] yields beginning
# an eval of these $complex_format_map->{what}->[1] yieleds end
$complex_format_map =
{
example =>
[
q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td class=example><pre>"},
q{'</pre></td></tr></table>'}
],
smallexample =>
[
q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td class=smallexample><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre>"},
q{'</FONT></pre></td></tr></table>'}
],
display =>
[
q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td class=display><pre " . 'style="font-family: serif">'},
q{'</pre></td></tr></table>'}
],
smalldisplay =>
[
q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td class=smalldisplay><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre " . 'style="font-family: serif">'},
q{'</pre></FONT></td></tr></table>'}
]
};
$complex_format_map->{lisp} = $complex_format_map->{example};
$complex_format_map->{smalllisp} = $complex_format_map->{smallexample};
$complex_format_map->{format} = $complex_format_map->{display};
$complex_format_map->{smallformat} = $complex_format_map->{smalldisplay};
#
# texinfo definition shortcuts to real ones
#
%def_map = (
# basic commands
'deffn', 0,
'defvr', 0,
'deftypefn', 0,
'deftypevr', 0,
'defcv', 0,
'defop', 0,
'deftp', 0,
# basic x commands
'deffnx', 0,
'defvrx', 0,
'deftypefnx', 0,
'deftypevrx', 0,
'defcvx', 0,
'defopx', 0,
'deftpx', 0,
# shortcuts
'defun', 'deffn Function',
'defmac', 'deffn Macro',
'defspec', 'deffn {Special Form}',
'defvar', 'defvr Variable',
'defopt', 'defvr {User Option}',
'deftypefun', 'deftypefn Function',
'deftypevar', 'deftypevr Variable',
'defivar', 'defcv {Instance Variable}',
2002-12-09 06:31:39 +08:00
'deftypeivar', 'defcv {Instance Variable}', # NEW: FIXME
'defmethod', 'defop Method',
2002-12-09 06:31:39 +08:00
'deftypemethod', 'defop Method', # NEW:FIXME
# x shortcuts
'defunx', 'deffnx Function',
'defmacx', 'deffnx Macro',
'defspecx', 'deffnx {Special Form}',
'defvarx', 'defvrx Variable',
'defoptx', 'defvrx {User Option}',
'deftypefunx', 'deftypefnx Function',
'deftypevarx', 'deftypevrx Variable',
'defivarx', 'defcvx {Instance Variable}',
'defmethodx', 'defopx Method',
);
#
# things to skip
#
%to_skip = (
# comments
'c', 1,
'comment', 1,
2002-12-09 06:31:39 +08:00
'ifnotinfo', 1,
'ifnottex', 1,
'ifhtml', 1,
'end ifhtml', 1,
'end ifnotinfo', 1,
'end ifnottex', 1,
# useless
2002-12-09 06:31:39 +08:00
'detailmenu', 1,
'direntry', 1,
'contents', 1,
'shortcontents', 1,
'summarycontents', 1,
'footnotestyle', 1,
'end ifclear', 1,
'end ifset', 1,
'titlepage', 1,
'end titlepage', 1,
# unsupported commands (formatting)
'afourpaper', 1,
'cropmarks', 1,
'finalout', 1,
'headings', 1,
2002-12-09 06:31:39 +08:00
'sp', 1,
'need', 1,
'page', 1,
'setchapternewpage', 1,
'everyheading', 1,
'everyfooting', 1,
'evenheading', 1,
'evenfooting', 1,
'oddheading', 1,
'oddfooting', 1,
'smallbook', 1,
'vskip', 1,
'filbreak', 1,
1999-08-03 07:48:02 +08:00
'paragraphindent', 1,
# unsupported formats
'cartouche', 1,
'end cartouche', 1,
'group', 1,
'end group', 1,
);
#+++############################################################################
# #
# Argument parsing, initialisation #
# #
#---############################################################################
2002-12-09 06:31:39 +08:00
#
# flush stdout and stderr after every write
#
select(STDERR);
$| = 1;
select(STDOUT);
$| = 1;
1999-08-03 07:48:02 +08:00
2002-12-09 06:31:39 +08:00
%value = (); # hold texinfo variables, see also -D
$use_bibliography = 1;
2002-12-09 06:31:39 +08:00
$use_acc = 1;
2002-12-09 06:31:39 +08:00
#
# called on -init-file
sub LoadInitFile
{
my $init_file = shift;
# second argument is value of options
$init_file = shift;
if (-f $init_file)
{
print "# reading initialization file from $init_file\n"
if ($T2H_VERBOSE);
require($init_file);
}
else
{
print "$ERROR Error: can't read init file $int_file\n";
$init_file = '';
}
}
#
# called on -lang
sub SetDocumentLanguage
{
my $lang = shift;
if (! exists($T2H_WORDS->{$lang}))
{
warn "$ERROR: Language specs for '$lang' do not exists. Reverting to '" .
($T2H_LANG ? T2H_LANG : "en") . "'\n";
}
else
{
print "# using '$lang' as document language\n" if ($T2H_VERBOSE);
$T2H_LANG = $lang;
}
}
##
## obsolete cmd line options
##
$T2H_OBSOLETE_OPTIONS -> {'no-section_navigation'} =
{
type => '!',
linkage => sub {$main::T2H_SECTION_NAVIGATION = 0;},
verbose => 'obsolete, use -nosec_nav',
noHelp => 2,
};
$T2H_OBSOLETE_OPTIONS -> {use_acc} =
{
type => '!',
linkage => \$use_acc,
verbose => 'obsolete',
noHelp => 2
};
$T2H_OBSOLETE_OPTIONS -> {expandinfo} =
{
type => '!',
linkage => sub {$main::T2H_EXPAND = 'info';},
verbose => 'obsolete, use "-expand info" instead',
noHelp => 2,
};
$T2H_OBSOLETE_OPTIONS -> {expandtex} =
{
type => '!',
linkage => sub {$main::T2H_EXPAND = 'tex';},
verbose => 'obsolete, use "-expand tex" instead',
noHelp => 2,
};
$T2H_OBSOLETE_OPTIONS -> {monolithic} =
{
type => '!',
linkage => sub {$main::T2H_SPLIT = '';},
verbose => 'obsolete, use "-split no" instead',
noHelp => 2
};
$T2H_OBSOLETE_OPTIONS -> {split_node} =
{
type => '!',
linkage => sub{$main::T2H_SPLIT = 'section';},
verbose => 'obsolete, use "-split section" instead',
noHelp => 2,
};
$T2H_OBSOLETE_OPTIONS -> {split_chapter} =
{
type => '!',
linkage => sub{$main::T2H_SPLIT = 'chapter';},
verbose => 'obsolete, use "-split chapter" instead',
noHelp => 2,
};
$T2H_OBSOLETE_OPTIONS -> {no_verbose} =
{
type => '!',
linkage => sub {$main::T2H_VERBOSE = 0;},
verbose => 'obsolete, use -noverbose instead',
noHelp => 2,
};
$T2H_OBSOLETE_OPTIONS -> {output_file} =
{
type => '=s',
linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';},
verbose => 'obsolete, use -out_file instead',
noHelp => 2
};
$T2H_OBSOLETE_OPTIONS -> {section_navigation} =
{
type => '!',
linkage => \$T2H_SECTION_NAVIGATION,
verbose => 'obsolete, use -sec_nav instead',
noHelp => 2,
};
$T2H_OBSOLETE_OPTIONS -> {verbose} =
{
type => '!',
linkage => \$T2H_VERBOSE,
verbose => 'obsolete, use -Verbose instead',
noHelp => 2
};
# read initialzation from $sysconfdir/texi2htmlrc or $HOME/.texi2htmlrc
my $home = $ENV{HOME};
defined($home) or $home = '';
foreach $i ('/usr/local/etc/texi2htmlrc', "$home/.texi2htmlrc") {
if (-f $i) {
print "# reading initialization file from $i\n"
if ($T2H_VERBOSE);
require($i);
}
}
2002-12-09 06:31:39 +08:00
#+++############################################################################
# #
# parse command-line options
# #
#---############################################################################
$T2H_USAGE_TEXT = <<EOT;
Usage: texi2html [OPTIONS] TEXINFO-FILE
Translates Texinfo source documentation to HTML.
EOT
$T2H_FAILURE_TEXT = <<EOT;
Try 'texi2html -help' for usage instructions.
EOT
$options = new Getopt::MySimple;
# some older version of GetOpt::Long don't have
# Getopt::Long::Configure("pass_through")
eval {Getopt::Long::Configure("pass_through");};
$Configure_failed = $@ && <<EOT;
**WARNING: Parsing of obsolete command-line options could have failed.
Consider to use only documented command-line options (run
'texi2html -help 2' for a complete list) or upgrade to perl
version 5.005 or higher.
EOT
if (! $options->getOptions($T2H_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n"))
{
print $Configure_failed if $Configure_failed;
die $T2H_FAILURE_TEXT;
}
if (@ARGV > 1)
{
eval {Getopt::Long::Configure("no_pass_through");};
if (! $options->getOptions($T2H_OBSOLETE_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n"))
{
print $Configure_failed if $Configure_failed;
die $T2H_FAILURE_TEXT;
}
}
if ($T2H_CHECK) {
die "Need file to check\n$T2H_FAILURE_TEXT" unless @ARGV > 0;
&check;
exit;
}
2002-12-09 06:31:39 +08:00
#+++############################################################################
# #
# evaluation of cmd line options
# #
#---############################################################################
if ($T2H_EXPAND eq 'info')
{
$to_skip{'ifinfo'} = 1;
$to_skip{'end ifinfo'} = 1;
}
elsif ($T2H_EXPAND eq 'tex')
{
$to_skip{'iftex'} = 1;
$to_skip{'end iftex'} = 1;
}
2002-12-09 06:31:39 +08:00
$T2H_INVISIBLE_MARK = '<IMG SRC="invisible.xbm">' if $T2H_INVISIBLE_MARK eq 'xbm';
#
# file name buisness
#
die "Need exactly one file to translate\n$T2H_FAILURE_TEXT" unless @ARGV == 1;
$docu = shift(@ARGV);
if ($docu =~ /.*\//) {
chop($docu_dir = $&);
$docu_name = $';
} else {
$docu_dir = '.';
$docu_name = $docu;
}
2002-12-09 06:31:39 +08:00
unshift(@T2H_INCLUDE_DIRS, $docu_dir);
$docu_name =~ s/\.te?x(i|info)?$//; # basename of the document
2002-12-09 06:31:39 +08:00
$docu_name = $T2H_PREFIX if ($T2H_PREFIX);
2002-12-09 06:31:39 +08:00
# subdir
if ($T2H_SUBDIR && ! $T2H_OUT)
{
$T2H_SUBDIR =~ s|/*$||;
unless (-d "$T2H_SUBDIR" && -w "$T2H_SUBDIR")
{
if ( mkdir($T2H_SUBDIR, oct(755)))
{
print "# created directory $T2H_SUBDIR\n" if ($T2H_VERBOSE);
}
else
{
warn "$ERROR can't create directory $T2H_SUBDIR. Put results into current directory\n";
$T2H_SUBDIR = '';
}
}
}
if ($T2H_SUBDIR && ! $T2H_OUT)
{
$docu_rdir = "$T2H_SUBDIR/";
print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE);
}
else
{
if ($T2H_OUT && $T2H_OUT =~ m|(.*)/|)
{
$docu_rdir = "$1/";
print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE);
}
else
{
print "# putting result files into current directory \n" if ($T2H_VERBOSE);
$docu_rdir = '';
}
}
# extension
if ($T2H_SHORTEXTN)
{
$docu_ext = "htm";
}
else
{
$docu_ext = "html";
}
if ($T2H_TOP_FILE =~ /\..*$/)
{
$T2H_TOP_FILE = $`.".$docu_ext";
}
# result files
if (! $T2H_OUT && ($T2H_SPLIT =~ /section/i || $T2H_SPLIT =~ /node/i))
{
$T2H_SPLIT = 'section';
}
elsif (! $T2H_OUT && $T2H_SPLIT =~ /chapter/i)
{
$T2H_SPLIT = 'chapter'
}
else
{
undef $T2H_SPLIT;
}
$docu_doc = "$docu_name.$docu_ext"; # document's contents
$docu_doc_file = "$docu_rdir$docu_doc";
if ($T2H_SPLIT)
{
$docu_toc = $T2H_TOC_FILE || "${docu_name}_toc.$docu_ext"; # document's table of contents
$docu_stoc = "${docu_name}_ovr.$docu_ext"; # document's short toc
$docu_foot = "${docu_name}_fot.$docu_ext"; # document's footnotes
$docu_about = "${docu_name}_abt.$docu_ext"; # about this document
$docu_top = $T2H_TOP_FILE || $docu_doc;
}
else
{
if ($T2H_OUT)
{
$docu_doc = $T2H_OUT;
$docu_doc =~ s|.*/||;
}
$docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_top = $docu_doc;
}
2002-12-09 06:31:39 +08:00
$docu_toc_file = "$docu_rdir$docu_toc";
$docu_stoc_file = "$docu_rdir$docu_stoc";
$docu_foot_file = "$docu_rdir$docu_foot";
$docu_about_file = "$docu_rdir$docu_about";
$docu_top_file = "$docu_rdir$docu_top";
$docu_frame_file = "$docu_rdir${docu_name}_frame.$docu_ext";
$docu_toc_frame_file = "$docu_rdir${docu_name}_toc_frame.$docu_ext";
#
# variables
#
$value{'html'} = 1; # predefine html (the output format)
2002-12-09 06:31:39 +08:00
$value{'texi2html'} = $THISVERSION; # predefine texi2html (the translator)
# _foo: internal to track @foo
foreach ('_author', '_title', '_subtitle',
2002-12-09 06:31:39 +08:00
'_settitle', '_setfilename', '_shorttitle') {
$value{$_} = ''; # prevent -w warnings
}
%node2sec = (); # node to section name
2002-12-09 06:31:39 +08:00
%sec2node = (); # section to node name
%sec2number = (); # section to number
%number2sec = (); # number to section
%idx2node = (); # index keys to node
%node2href = (); # node to HREF
2002-12-09 06:31:39 +08:00
%node2next = (); # node to next
%node2prev = (); # node to prev
%node2up = (); # node to up
%bib2href = (); # bibliography reference to HREF
%gloss2href = (); # glossary term to HREF
@sections = (); # list of sections
%tag2pro = (); # protected sections
#
# initial indexes
#
$bib_num = 0;
$foot_num = 0;
$gloss_num = 0;
$idx_num = 0;
$sec_num = 0;
$doc_num = 0;
$html_num = 0;
#
# can I use ISO8879 characters? (HTML+)
#
2002-12-09 06:31:39 +08:00
if ($T2H_USE_ISO) {
$things_map{'bullet'} = "&bull;";
$things_map{'copyright'} = "&copy;";
$things_map{'dots'} = "&hellip;";
$things_map{'equiv'} = "&equiv;";
$things_map{'expansion'} = "&rarr;";
$things_map{'point'} = "&lowast;";
$things_map{'result'} = "&rArr;";
}
#
# read texi2html extensions (if any)
#
$extensions = 'texi2html.ext'; # extensions in working directory
if (-f $extensions) {
2002-12-09 06:31:39 +08:00
print "# reading extensions from $extensions\n" if $T2H_VERBOSE;
require($extensions);
}
($progdir = $0) =~ s/[^\/]+$//;
if ($progdir && ($progdir ne './')) {
$extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory
if (-f $extensions) {
2002-12-09 06:31:39 +08:00
print "# reading extensions from $extensions\n" if $T2H_VERBOSE;
require($extensions);
}
}
2002-12-09 06:31:39 +08:00
print "# reading from $docu\n" if $T2H_VERBOSE;
#########################################################################
#
# latex2html stuff
#
# latex2html conversions consist of three stages:
# 1) ToLatex: Put "latex" code into a latex file
# 2) ToHtml: Use latex2html to generate corresponding html code and images
# 3) FromHtml: Extract generated code and images from latex2html run
#
##########################
# default settings
#
# defaults for files and names
sub l2h_Init
{
local($root) = @_;
return 0 unless ($root);
$l2h_name = "${root}_l2h";
$l2h_latex_file = "$docu_rdir${l2h_name}.tex";
$l2h_cache_file = "${docu_rdir}l2h_cache.pm";
$T2H_L2H_L2H = "latex2html" unless ($T2H_L2H_L2H);
# destination dir -- generated images are put there, should be the same
# as dir of enclosing html document --
$l2h_html_file = "$docu_rdir${l2h_name}.html";
$l2h_prefix = "${l2h_name}_";
return 1;
}
##########################
#
# First stage: Generation of Latex file
# Initialize with: l2h_InitToLatex
# Add content with: l2h_ToLatex($text) --> HTML placeholder comment
# Finish with: l2h_FinishToLatex
#
$l2h_latex_preample = <<EOT;
% This document was automatically generated by the l2h extenstion of texi2html
% DO NOT EDIT !!!
\\documentclass{article}
\\usepackage{html}
\\begin{document}
EOT
$l2h_latex_closing = <<EOT;
\\end{document}
EOT
# return used latex 1, if l2h could be initalized properly, 0 otherwise
sub l2h_InitToLatex
{
%l2h_to_latex = ();
unless ($T2H_L2H_SKIP)
{
unless (open(L2H_LATEX, ">$l2h_latex_file"))
{
warn "$ERROR Error l2h: Can't open latex file '$latex_file' for writing\n";
return 0;
}
print "# l2h: use ${l2h_latex_file} as latex file\n" if ($T2H_VERBOSE);
print L2H_LATEX $l2h_latex_preample;
}
# open database for caching
l2h_InitCache();
$l2h_latex_count = 0;
$l2h_to_latex_count = 0;
$l2h_cached_count = 0;
return 1;
}
# print text (1st arg) into latex file (if not already there), return
# HTML commentary which can be later on replaced by the latex2html
# generated text
sub l2h_ToLatex
{
my($text) = @_;
my($count);
$l2h_to_latex_count++;
$text =~ s/(\s*)$//;
# try whether we can cache it
my $cached_text = l2h_FromCache($text);
if ($cached_text)
{
$l2h_cached_count++;
return $cached_text;
}
# try whether we have text already on things to do
unless ($count = $l2h_to_latex{$text})
{
$count = $l2h_latex_count;
$l2h_latex_count++;
$l2h_to_latex{$text} = $count;
$l2h_to_latex[$count] = $text;
unless ($T2H_L2H_SKIP)
{
print L2H_LATEX "\\begin{rawhtml}\n";
print L2H_LATEX "<!-- l2h_begin ${l2h_name} ${count} -->\n";
print L2H_LATEX "\\end{rawhtml}\n";
print L2H_LATEX "$text\n";
print L2H_LATEX "\\begin{rawhtml}\n";
print L2H_LATEX "<!-- l2h_end ${l2h_name} ${count} -->\n";
print L2H_LATEX "\\end{rawhtml}\n";
}
}
return "<!-- l2h_replace ${l2h_name} ${count} -->";
}
# print closing into latex file and close it
sub l2h_FinishToLatex
{
local ($reused);
$reused = $l2h_to_latex_count - $l2h_latex_count - $l2h_cached_count;
unless ($T2H_L2H_SKIP)
{
print L2H_LATEX $l2h_latex_closing;
close(L2H_LATEX);
}
print "# l2h: finished to latex ($l2h_cached_count cached, $reused reused, $l2h_latex_count contents)\n" if ($T2H_VERBOSE);
unless ($l2h_latex_count)
{
l2h_Finish();
return 0;
}
return 1;
}
###################################
# Second stage: Use latex2html to generate corresponding html code and images
#
# l2h_ToHtml([$l2h_latex_file, [$l2h_html_dir]]):
# Call latex2html on $l2h_latex_file
# Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir
# Return 1, on success
# 0, otherwise
#
sub l2h_ToHtml
{
local($call, $ext, $root, $dotbug);
if ($T2H_L2H_SKIP)
{
print "# l2h: skipping latex2html run\n" if ($T2H_VERBOSE);
return 1;
}
# Check for dot in directory where dvips will work
if ($T2H_L2H_TMP)
{
if ($T2H_L2H_TMP =~ /\./)
{
warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n";
$dotbug = 1;
}
}
else
{
if (&getcwd =~ /\./)
{
warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n";
$dotbug = 1;
}
}
# fix it, if necessary and hope that it works
$T2H_L2H_TMP = "/tmp" if ($dotbug);
$call = $T2H_L2H_L2H;
# use init file, if specified
$call = $call . " -init_file " . $init_file if ($init_file && -f $init_file);
# set output dir
$call .= ($docu_rdir ? " -dir $docu_rdir" : " -no_subdir");
# use l2h_tmp, if specified
$call = $call . " -tmp $T2H_L2H_TMP" if ($T2H_L2H_TMP);
# options we want to be sure of
$call = $call ." -address 0 -info 0 -split 0 -no_navigation -no_auto_link";
$call = $call ." -prefix ${l2h_prefix} $l2h_latex_file";
print "# l2h: executing '$call'\n" if ($T2H_VERBOSE);
if (system($call))
{
warn "l2h ***Error: '${call}' did not succeed\n";
return 0;
}
else
{
print "# l2h: latex2html finished successfully\n" if ($T2H_VERBOSE);
return 1;
}
}
# this is directly pasted over from latex2html
sub getcwd {
local($_) = `pwd`;
die "'pwd' failed (out of memory?)\n"
unless length;
chop;
$_;
}
##########################
# Third stage: Extract generated contents from latex2html run
# Initialize with: l2h_InitFromHtml
# open $l2h_html_file for reading
# reads in contents into array indexed by numbers
# return 1, on success -- 0, otherwise
# Extract Html code with: l2h_FromHtml($text)
# replaces in $text all previosuly inserted comments by generated html code
# returns (possibly changed) $text
# Finish with: l2h_FinishFromHtml
# closes $l2h_html_dir/$l2h_name.".$docu_ext"
sub l2h_InitFromHtml
{
local($h_line, $h_content, $count, %l2h_img);
if (! open(L2H_HTML, "<${l2h_html_file}"))
{
print "$ERROR Error l2h: Can't open ${l2h_html_file} for reading\n";
return 0;
}
print "# l2h: use ${l2h_html_file} as html file\n" if ($T2H_VERBOSE);
$l2h_html_count = 0;
while ($h_line = <L2H_HTML>)
{
if ($h_line =~ /^<!-- l2h_begin $l2h_name ([0-9]+) -->/)
{
$count = $1;
$h_content = "";
while ($h_line = <L2H_HTML>)
{
if ($h_line =~ /^<!-- l2h_end $l2h_name $count -->/)
{
chomp $h_content;
chomp $h_content;
$l2h_html_count++;
$h_content = l2h_ToCache($count, $h_content);
$l2h_from_html[$count] = $h_content;
$h_content = '';
last;
}
$h_content = $h_content.$h_line;
}
if ($hcontent)
{
print "$ERROR Warning l2h: l2h_end $l2h_name $count not found\n"
if ($T2H_VERBOSE);
close(L2H_HTML);
return 0;
}
}
}
print "# l2h: Got $l2h_html_count of $l2h_latex_count html contents\n"
if ($T2H_VERBOSE);
close(L2H_HTML);
return 1;
}
sub l2h_FromHtml
{
local($text) = @_;
local($done, $to_do, $count);
$to_do = $text;
while ($to_do =~ /([^\000]*)<!-- l2h_replace $l2h_name ([0-9]+) -->([^\000]*)/)
{
$to_do = $1;
$count = $2;
$done = $3.$done;
$done = "<!-- l2h_end $l2h_name $count -->".$done
if ($T2H_DEBUG & $DEBUG_L2H);
$done = &l2h_ExtractFromHtml($count) . $done;
$done = "<!-- l2h_begin $l2h_name $count -->".$done
if ($T2H_DEBUG & $DEBUG_L2H);
}
return $to_do.$done;
}
sub l2h_ExtractFromHtml
{
local($count) = @_;
return $l2h_from_html[$count] if ($l2h_from_html[$count]);
if ($count >= 0 && $count < $l2h_latex_count)
{
# now we are in trouble
local($l_l2h, $_);
$l2h_extract_error++;
print "$ERROR l2h: can't extract content $count from html\n"
if ($T2H_VERBOSE);
# try simple (ordinary) substition (without l2h)
$l_l2h = $T2H_L2H;
$T2H_L2H = 0;
$_ = $l2h_to_latex{$count};
$_ = &substitute_style($_);
&unprotect_texi;
$_ = "<!-- l2h: ". __LINE__ . " use texi2html -->" . $_
if ($T2H_DEBUG & $DEBUG_L2H);
$T2H_L2H = $l_l2h;
return $_;
}
else
{
# now we have been incorrectly called
$l2h_range_error++;
print "$ERROR l2h: Request of $count content which is out of valide range [0,$l2h_latex_count)\n";
return "<!-- l2h: ". __LINE__ . " out of range count $count -->"
if ($T2H_DEBUG & $DEBUG_L2H);
return "<!-- l2h: out of range count $count -->";
}
}
sub l2h_FinishFromHtml
{
if ($T2H_VERBOSE)
{
if ($l2h_extract_error + $l2h_range_error)
{
print "# l2h: finished from html ($l2h_extract_error extract and $l2h_range_error errors)\n";
}
else
{
print "# l2h: finished from html (no errors)\n";
}
}
}
sub l2h_Finish
{
l2h_StoreCache();
if ($T2H_L2H_CLEAN)
{
print "# l2h: removing temporary files generated by l2h extension\n"
if $T2H_VERBOSE;
while (<"$docu_rdir$l2h_name"*>)
{
unlink $_;
}
}
print "# l2h: Finished\n" if $T2H_VERBOSE;
return 1;
}
##############################
# stuff for l2h caching
#
# I tried doing this with a dbm data base, but it did not store all
# keys/values. Hence, I did as latex2html does it
sub l2h_InitCache
{
if (-r "$l2h_cache_file")
{
my $rdo = do "$l2h_cache_file";
warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n")
unless ($rdo);
}
}
sub l2h_StoreCache
{
return unless $l2h_latex_count;
my ($key, $value);
open(FH, ">$l2h_cache_file") || return warn"$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n";
while (($key, $value) = each %l2h_cache)
{
# escape stuff
$key =~ s|/|\\/|g;
$key =~ s|\\\\/|\\/|g;
# weird, a \ at the end of the key results in an error
# maybe this also broke the dbm database stuff
$key =~ s|\\$|\\\\|;
$value =~ s/\|/\\\|/g;
$value =~ s/\\\\\|/\\\|/g;
$value =~ s|\\\\|\\\\\\\\|g;
print FH "\n\$l2h_cache_key = q/$key/;\n";
print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n";
}
print FH "1;";
close(FH);
}
# return cached html, if it exists for text, and if all pictures
# are there, as well
sub l2h_FromCache
{
my $text = shift;
my $cached = $l2h_cache{$text};
if ($cached)
{
while ($cached =~ m/SRC="(.*?)"/g)
{
unless (-e "$docu_rdir$1")
{
return undef;
}
}
return $cached;
}
return undef;
}
# insert generated html into cache, move away images,
# return transformed html
$maximage = 1;
sub l2h_ToCache
{
my $count = shift;
my $content = shift;
my @images = ($content =~ /SRC="(.*?)"/g);
my ($src, $dest);
for $src (@images)
{
$dest = $l2h_img{$src};
unless ($dest)
{
my $ext;
if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext)
{
$ext = $1;
}
else
{
warn "$ERROR: L2h image $src has invalid extension\n";
next;
}
while (-e "$docu_rdir${docu_name}_$maximage.$ext") { $maximage++;}
$dest = "${docu_name}_$maximage.$ext";
system("cp -f $docu_rdir$src $docu_rdir$dest");
$l2h_img{$src} = $dest;
unlink "$docu_rdir$src" unless ($DEBUG & DEBUG_L2H);
}
$content =~ s/$src/$dest/g;
}
$l2h_cache{$l2h_to_latex[$count]} = $content;
return $content;
}
#+++############################################################################
# #
# Pass 1: read source, handle command, variable, simple substitution #
# #
#---############################################################################
@lines = (); # whole document
@toc_lines = (); # table of contents
2002-12-09 06:31:39 +08:00
@stoc_lines = (); # table of contents
$curlevel = 0; # current level in TOC
$node = ''; # current node name
2002-12-09 06:31:39 +08:00
$node_next = ''; # current node next name
$node_prev = ''; # current node prev name
$node_up = ''; # current node up name
$in_table = 0; # am I inside a table
1999-08-03 07:48:02 +08:00
$table_type = ''; # type of table ('', 'f', 'v', 'multi')
@tables = (); # nested table support
$in_bibliography = 0; # am I inside a bibliography
$in_glossary = 0; # am I inside a glossary
$in_top = 0; # am I inside the top node
2002-12-09 06:31:39 +08:00
$has_top = 0; # did I see a top node?
$has_top_command = 0; # did I see @top for automatic pointers?
$in_pre = 0; # am I inside a preformatted section
$in_list = 0; # am I inside a list
$in_html = 0; # am I inside an HTML section
$first_line = 1; # is it the first line
$dont_html = 0; # don't protect HTML on this line
$deferred_ref = ''; # deferred reference for indexes
@html_stack = (); # HTML elements stack
$html_element = ''; # current HTML element
&html_reset;
2002-12-09 06:31:39 +08:00
%macros = (); # macros
# init l2h
$T2H_L2H = &l2h_Init($docu_name) if ($T2H_L2H);
$T2H_L2H = &l2h_InitToLatex if ($T2H_L2H);
# build code for simple substitutions
# the maps used (%simple_map and %things_map) MUST be aware of this
# watch out for regexps, / and escaped characters!
$subst_code = '';
foreach (keys(%simple_map)) {
($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars
$subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n";
}
foreach (keys(%things_map)) {
$subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n";
}
if ($use_acc) {
# accentuated characters
foreach (keys(%accent_map)) {
if ($_ eq "`") {
$subst_code .= "s/$;3";
} elsif ($_ eq "'") {
$subst_code .= "s/$;4";
} else {
$subst_code .= "s/\\\@\\$_";
}
2002-12-09 06:31:39 +08:00
$subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n";
}
}
eval("sub simple_substitutions { $subst_code }");
&init_input;
2002-12-09 06:31:39 +08:00
INPUT_LINE: while ($_ = &next_line) {
#
# remove \input on the first lines only
#
if ($first_line) {
next if /^\\input/;
$first_line = 0;
}
2002-12-09 06:31:39 +08:00
# non-@ substitutions cf. texinfmt.el
#
# parse texinfo tags
#
$tag = '';
$end_tag = '';
2002-12-09 06:31:39 +08:00
if (/^\s*\@end\s+(\w+)\b/) {
$end_tag = $1;
2002-12-09 06:31:39 +08:00
} elsif (/^\s*\@(\w+)\b/) {
$tag = $1;
}
#
2002-12-09 06:31:39 +08:00
# handle @html / @end html
#
if ($in_html) {
2002-12-09 06:31:39 +08:00
if ($end_tag eq 'html') {
$in_html = 0;
} else {
$tag2pro{$in_html} .= $_;
}
next;
2002-12-09 06:31:39 +08:00
} elsif ($tag eq 'html') {
$in_html = $PROTECTTAG . ++$html_num;
push(@lines, $in_html);
next;
}
2002-12-09 06:31:39 +08:00
#
# try to remove inlined comments
# syntax from tex-mode.el comment-start-skip
#
s/((^|[^\@])(\@\@)*)\@c(omment | |\{|$).*/$1/;
# Sometimes I use @c right at the end of a line ( to suppress the line feed )
# s/((^|[^\@])(\@\@)*)\@c(omment)?$/$1/;
# s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/;
# s/(.*)\@c{.*?}(.*)/$1$2/;
# s/(.*)\@comment{.*?}(.*)/$1$2/;
# s/^(.*)\@c /$1/;
# s/^(.*)\@comment /$1/;
#############################################################
# value substitution before macro expansion, so that
# it works in macro arguments
s/\@value{($VARRE)}/$value{$1}/eg;
#############################################################
# macro substitution
while (/\@(\w+)/g)
{
if (exists($macros->{$1}))
{
my $before = $`;
my $name = $1;
my $after = $';
my @args;
my $args;
if ($after =~ /^\s*{(.*?[^\\])}(.*)/)
{
$args = $1;
$after = $2;
}
elsif (@{$macros->{$name}->{Args}} == 1)
{
$args = $after;
$args =~ s/^\s*//;
$args =~ s/\s*$//;
$after = '';
}
$args =~ s|\\\\|\\|g;
$args =~ s|\\{|{|g;
$args =~ s|\\}|}|g;
if (@{$macros->{$name}->{Args}} > 1)
{
$args =~ s/(^|[^\\]),/$1$;/g ;
$args =~ s|\\,|,|g;
@args = split(/$;\s*/, $args) if (@{$macros->{$name}->{Args}} > 1);
}
else
{
$args =~ s|\\,|,|g;
@args = ($args);
}
my $macrobody = $macros->{$name}->{Body};
for ($i=0; $i<=$#args; $i++)
{
$macrobody =~ s|\\$macros->{$name}->{Args}->[$i]\\|$args[$i]|g;
}
$macrobody =~ s|\\\\|\\|g;
$_ = $before . $macrobody . $after;
unshift @input_spool, map {$_ = $_."\n"} split(/\n/, $_);
next INPUT_LINE;
}
} #
#
# try to skip the line
#
if ($end_tag) {
2002-12-09 06:31:39 +08:00
$in_titlepage = 0 if $end_tag eq 'titlepage';
next if $to_skip{"end $end_tag"};
} elsif ($tag) {
2002-12-09 06:31:39 +08:00
$in_titlepage = 1 if $tag eq 'titlepage';
next if $to_skip{$tag};
last if $tag eq 'bye';
}
if ($in_top) {
# parsing the top node
2002-12-09 06:31:39 +08:00
if ($tag eq 'node' ||
($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/))
{
# no more in top
$in_top = 0;
2002-12-09 06:31:39 +08:00
push(@lines, $TOPEND);
}
}
1999-08-03 07:48:02 +08:00
unless ($in_pre) {
s/``/\"/g;
s/''/\"/g;
s/([\w ])---([\w ])/$1--$2/g;
}
#
# analyze the tag
#
if ($tag) {
# skip lines
&skip_until($tag), next if $tag eq 'ignore';
2002-12-09 06:31:39 +08:00
&skip_until($tag), next if $tag eq 'ifnothtml';
if ($tag eq 'ifinfo')
{
&skip_until($tag), next unless $T2H_EXPAND eq 'info';
}
if ($tag eq 'iftex')
{
&skip_until($tag), next unless $T2H_EXPAND eq 'tex';
}
if ($tag eq 'tex')
{
# add to latex2html file
if ($T2H_EXPAND eq 'tex' && $T2H_L2H && ! $in_pre)
{
# add space to the end -- tex(i2dvi) does this, as well
push(@lines, &l2h_ToLatex(&string_until($tag) . " "));
}
else
{
&skip_until($tag);
}
next;
}
if ($tag eq 'titlepage')
{
next;
}
# handle special tables
1999-08-03 07:48:02 +08:00
if ($tag =~ /^(|f|v|multi)table$/) {
$table_type = $1;
$tag = 'table';
}
# special cases
if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) {
$in_top = 1;
2002-12-09 06:31:39 +08:00
$has_top = 1;
$has_top_command = 1 if $tag eq 'top';
@lines = (); # ignore all lines before top (title page garbage)
next;
} elsif ($tag eq 'node') {
2002-12-09 06:31:39 +08:00
if ($in_top)
{
$in_top = 0;
2002-12-09 06:31:39 +08:00
push(@lines, $TOPEND);
}
warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o;
# request of "Richard Y. Kim" <ryk@ap.com>
s/^\@node\s+//;
$_ = &protect_html($_); # if node contains '&' for instance
($node, $node_next, $node_prev, $node_up) = split(/,/);
&normalise_node($node);
&normalise_node($node_next);
&normalise_node($node_prev);
&normalise_node($node_up);
$node =~ /\"/ ?
push @lines, &html_debug("<A NAME='$node'></A>\n", __LINE__) :
push @lines, &html_debug("<A NAME=\"$node\"></A>\n", __LINE__);
next;
} elsif ($tag eq 'include') {
if (/^\@include\s+($FILERE)\s*$/o) {
2002-12-09 06:31:39 +08:00
$file = LocateIncludeFile($1);
if ($file && -e $file) {
&open($file);
2002-12-09 06:31:39 +08:00
print "# including $file\n" if $T2H_VERBOSE;
} else {
2002-12-09 06:31:39 +08:00
warn "$ERROR Can't find $1, skipping";
}
} else {
warn "$ERROR Bad include line: $_";
}
next;
} elsif ($tag eq 'ifclear') {
if (/^\@ifclear\s+($VARRE)\s*$/o) {
next unless defined($value{$1});
&skip_until($tag);
} else {
warn "$ERROR Bad ifclear line: $_";
}
next;
} elsif ($tag eq 'ifset') {
if (/^\@ifset\s+($VARRE)\s*$/o) {
next if defined($value{$1});
&skip_until($tag);
} else {
warn "$ERROR Bad ifset line: $_";
}
next;
} elsif ($tag eq 'menu') {
2002-12-09 06:31:39 +08:00
unless ($T2H_SHOW_MENU) {
&skip_until($tag);
next;
}
&html_push_if($tag);
2002-12-09 06:31:39 +08:00
push(@lines, &html_debug('', __LINE__));
} elsif ($format_map{$tag}) {
$in_pre = 1 if $format_map{$tag} eq 'PRE';
&html_push_if($format_map{$tag});
2002-12-09 06:31:39 +08:00
push(@lines, &html_debug('', __LINE__));
$in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ;
2002-12-09 06:31:39 +08:00
# push(@lines, &debug("<BLOCKQUOTE>\n", __LINE__))
# if $tag =~ /example/i;
# sunshine@sunshineco.com: <PRE>bla</PRE> looks better than
# <PRE>\nbla</PRE> (at least on NeXTstep browser
push(@lines, &debug("<$format_map{$tag}>" .
($in_pre ? '' : "\n"), __LINE__));
next;
2002-12-09 06:31:39 +08:00
}
elsif (exists $complex_format_map->{$tag})
{
my $start = eval $complex_format_map->{$tag}->[0];
if ($@)
{
print "$ERROR: eval of complex_format_map->{$tag}->[0] $complex_format_map->{$tag}->[0]: $@";
$start = '<pre>'
}
$in_pre = 1 if $start =~ /<pre/;
push(@lines, html_debug($start. ($in_pre ? '' : "\n"), __LINE__));
next;
} elsif ($tag eq 'table') {
2002-12-09 06:31:39 +08:00
# anorland@hem2.passagen.se
# if (/^\s*\@(|f|v|multi)table\s+\@(\w+)/) {
if (/^\s*\@(|f|v|multi)table\s+\@(\w+)|(\{[^\}]*\})/) {
1999-08-03 07:48:02 +08:00
$in_table = $2;
unshift(@tables, join($;, $table_type, $in_table));
1999-08-03 07:48:02 +08:00
if ($table_type eq "multi") {
2002-12-09 06:31:39 +08:00
# don't use borders -- gets confused by empty cells
push(@lines, &debug("<TABLE>\n", __LINE__));
1999-08-03 07:48:02 +08:00
&html_push_if('TABLE');
} else {
push(@lines, &debug("<DL COMPACT>\n", __LINE__));
&html_push_if('DL');
}
2002-12-09 06:31:39 +08:00
push(@lines, &html_debug('', __LINE__));
} else {
warn "$ERROR Bad table line: $_";
}
next;
2002-12-09 06:31:39 +08:00
}
elsif ($tag eq 'synindex' || $tag eq 'syncodeindex')
{
if (/^\@$tag\s+(\w+)\s+(\w+)\s*$/)
{
my $from = $1;
my $to = $2;
my $prefix_from = IndexName2Prefix($from);
my $prefix_to = IndexName2Prefix($to);
warn("$ERROR unknown from index name $from ind syn*index line: $_"), next
unless $prefix_from;
warn("$ERROR unknown to index name $to ind syn*index line: $_"), next
unless $prefix_to;
if ($tag eq 'syncodeindex')
{
$index_properties->{$prefix_to}->{'from_code'}->{$prefix_from} = 1;
}
2002-12-09 06:31:39 +08:00
else
{
$index_properties->{$prefix_to}->{'from'}->{$prefix_from} = 1;
}
}
else
{
warn "$ERROR Bad syn*index line: $_";
}
next;
}
elsif ($tag eq 'defindex' || $tag eq 'defcodeindex')
{
if (/^\@$tag\s+(\w+)\s*$/)
{
my $name = $1;
$index_properties->{$name}->{name} = $name;
$index_properties->{$name}->{code} = 1 if $tag eq 'defcodeindex';
}
else
{
warn "$ERROR Bad defindex line: $_";
}
next;
}
elsif (/^\@printindex/)
{
push (@lines, "<!--::${section}::-->$_");
next;
}
elsif ($tag eq 'sp') {
push(@lines, &debug("<P>\n", __LINE__));
next;
2002-12-09 06:31:39 +08:00
} elsif ($tag eq 'center') {
push(@lines, &debug("<center>\n", __LINE__));
s/\@center//;
} elsif ($tag eq 'setref') {
&protect_html; # if setref contains '&' for instance
if (/^\@$tag\s*{($NODERE)}\s*$/) {
$setref = $1;
$setref =~ s/\s+/ /g; # normalize
$setref =~ s/ $//;
$node2sec{$setref} = $name;
2002-12-09 06:31:39 +08:00
$sec2node{$name} = $setref;
$node2href{$setref} = "$docu_doc#$docid";
} else {
warn "$ERROR Bad setref line: $_";
}
next;
2002-12-09 06:31:39 +08:00
} elsif ($tag eq 'lowersections') {
local ($sec, $level);
while (($sec, $level) = each %sec2level) {
$sec2level{$sec} = $level + 1;
}
next;
2002-12-09 06:31:39 +08:00
} elsif ($tag eq 'raisesections') {
local ($sec, $level);
while (($sec, $level) = each %sec2level) {
$sec2level{$sec} = $level - 1;
}
next;
}
elsif ($tag eq 'macro' || $tag eq 'rmacro')
{
if (/^\@$tag\s*(\w+)\s*(.*)/)
{
my $name = $1;
my @args;
@args = split(/\s*,\s*/ , $1)
if ($2 =~ /^\s*{(.*)}\s*/);
$macros->{$name}->{Args} = \@args;
$macros->{$name}->{Body} = '';
while (($_ = &next_line) && $_ !~ /\@end $tag/)
{
$macros->{$name}->{Body} .= $_;
}
die "ERROR: No closing '\@end $tag' found for macro definition of '$name'\n"
unless (/\@end $tag/);
chomp $macros->{$name}->{Body};
}
else
{
warn "$ERROR: Bad macro defintion $_"
}
next;
}
elsif ($tag eq 'unmacro')
{
delete $macros->{$1} if (/^\@unmacro\s*(\w+)/);
next;
}
elsif ($tag eq 'documentlanguage')
{
SetDocumentLanguage($1) if (!$T2H_LANG && /documentlanguage\s*(\w+)/);
}
elsif (defined($def_map{$tag})) {
if ($def_map{$tag}) {
s/^\@$tag\s+//;
$tag = $def_map{$tag};
$_ = "\@$tag $_";
$tag =~ s/\s.*//;
}
} elsif (defined($user_sub{$tag})) {
s/^\@$tag\s+//;
$sub = $user_sub{$tag};
2002-12-09 06:31:39 +08:00
print "# user $tag = $sub, arg: $_" if $T2H_DEBUG & $DEBUG_USER;
if (defined(&$sub)) {
chop($_);
&$sub($_);
} else {
warn "$ERROR Bad user sub for $tag: $sub\n";
}
next;
2002-12-09 06:31:39 +08:00
}
if (defined($def_map{$tag})) {
s/^\@$tag\s+//;
if ($tag =~ /x$/) {
# extra definition line
$tag = $`;
$is_extra = 1;
} else {
$is_extra = 0;
}
while (/\{([^\{\}]*)\}/) {
# this is a {} construct
($before, $contents, $after) = ($`, $1, $');
# protect spaces
$contents =~ s/\s+/$;9/g;
# restore $_ protecting {}
$_ = "$before$;7$contents$;8$after";
}
@args = split(/\s+/, &protect_html($_));
foreach (@args) {
s/$;9/ /g; # unprotect spaces
s/$;7/\{/g; # ... {
s/$;8/\}/g; # ... }
}
$type = shift(@args);
$type =~ s/^\{(.*)\}$/$1/;
print "# def ($tag): {$type} ", join(', ', @args), "\n"
2002-12-09 06:31:39 +08:00
if $T2H_DEBUG & $DEBUG_DEF;
$type .= ':'; # it's nicer like this
2002-12-09 06:31:39 +08:00
my $name = shift(@args);
$name =~ s/^\{(.*)\}$/$1/;
if ($is_extra) {
$_ = &debug("<DT>", __LINE__);
} else {
$_ = &debug("<DL>\n<DT>", __LINE__);
}
if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') {
$_ .= "<U>$type</U> <B>$name</B>";
$_ .= " <I>@args</I>" if @args;
} elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr'
|| $tag eq 'defcv' || $tag eq 'defop') {
$ftype = $name;
$name = shift(@args);
$name =~ s/^\{(.*)\}$/$1/;
$_ .= "<U>$type</U> $ftype <B>$name</B>";
$_ .= " <I>@args</I>" if @args;
} else {
warn "$ERROR Unknown definition type: $tag\n";
$_ .= "<U>$type</U> <B>$name</B>";
$_ .= " <I>@args</I>" if @args;
}
$_ .= &debug("\n<DD>", __LINE__);
$name = &unprotect_html($name);
if ($tag eq 'deffn' || $tag eq 'deftypefn') {
2002-12-09 06:31:39 +08:00
EnterIndexEntry('f', $name, $docu_doc, $section, \@lines);
# unshift(@input_spool, "\@findex $name\n");
} elsif ($tag eq 'defop') {
2002-12-09 06:31:39 +08:00
EnterIndexEntry('f', "$name on $ftype", $docu_doc, $section, \@lines);
# unshift(@input_spool, "\@findex $name on $ftype\n");
} elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') {
2002-12-09 06:31:39 +08:00
EnterIndexEntry('v', $name, $docu_doc, $section, \@lines);
# unshift(@input_spool, "\@vindex $name\n");
} else {
2002-12-09 06:31:39 +08:00
EnterIndexEntry('t', $name, $docu_doc, $section, \@lines);
# unshift(@input_spool, "\@tindex $name\n");
}
$dont_html = 1;
}
} elsif ($end_tag) {
if ($format_map{$end_tag}) {
$in_pre = 0 if $format_map{$end_tag} eq 'PRE';
$in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ;
2002-12-09 06:31:39 +08:00
&html_pop_if('P');
&html_pop_if('LI');
&html_pop_if();
push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__));
2002-12-09 06:31:39 +08:00
push(@lines, &html_debug('', __LINE__));
}
elsif (exists $complex_format_map->{$end_tag})
{
my $end = eval $complex_format_map->{$end_tag}->[1];
if ($@)
{
print "$ERROR: eval of complex_format_map->{$end_tag}->[1] $complex_format_map->{$end_tag}->[0]: $@";
$end = '</pre>'
}
$in_pre = 0 if $end =~ m|</pre>|;
push(@lines, html_debug($end, __LINE__));
1999-08-03 07:48:02 +08:00
} elsif ($end_tag =~ /^(|f|v|multi)table$/) {
unless (@tables) {
warn "$ERROR \@end $end_tag without \@*table\n";
next;
}
2002-12-09 06:31:39 +08:00
&html_pop_if('P');
1999-08-03 07:48:02 +08:00
($table_type, $in_table) = split($;, shift(@tables));
unless ($1 eq $table_type) {
warn "$ERROR \@end $end_tag without matching \@$end_tag\n";
next;
}
if ($table_type eq "multi") {
push(@lines, "</TR></TABLE>\n");
&html_pop_if('TR');
} else {
push(@lines, "</DL>\n");
&html_pop_if('DD');
}
&html_pop_if();
if (@tables) {
($table_type, $in_table) = split($;, $tables[0]);
} else {
$in_table = 0;
}
} elsif (defined($def_map{$end_tag})) {
push(@lines, &debug("</DL>\n", __LINE__));
} elsif ($end_tag eq 'menu') {
&html_pop_if();
push(@lines, $_); # must keep it for pass 2
2002-12-09 06:31:39 +08:00
}
next;
}
2002-12-09 06:31:39 +08:00
#############################################################
# anchor insertion
while (/\@anchor\s*\{(.*?)\}/)
{
$_ = $`.$';
my $anchor = $1;
$anchor = &normalise_node($anchor);
push @lines, &html_debug("<A NAME=\"$anchor\"></A>\n");
$node2href{$anchor} = "$docu_doc#$anchor";
next INPUT_LINE if $_ =~ /^\s*$/;
}
#############################################################
# index entry generation, after value substitutions
if (/^\@(\w+?)index\s+/)
{
EnterIndexEntry($1, $', $docu_doc, $section, \@lines);
next;
}
#
# protect texi and HTML things
&protect_texi;
$_ = &protect_html($_) unless $dont_html;
$dont_html = 0;
# substitution (unsupported things)
s/^\@exdent\s+//g;
s/\@noindent\s+//g;
s/\@refill\s+//g;
# other substitutions
&simple_substitutions;
s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4
#
# analyze the tag again
#
if ($tag) {
2002-12-09 06:31:39 +08:00
if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) {
if (/^\@$tag\s+(.+)$/) {
$name = $1;
2002-12-09 06:31:39 +08:00
$name = &normalise_node($name);
$level = $sec2level{$tag};
2002-12-09 06:31:39 +08:00
# check for index
$first_index_chapter = $name
if ($level == 1 && !$first_index_chapter &&
$name =~ /index/i);
if ($in_top && /heading/){
$T2H_HAS_TOP_HEADING = 1;
$_ = &debug("<H$level>$name</H$level>\n", __LINE__);
&html_push_if('body');
print "# top heading, section $name, level $level\n"
if $T2H_DEBUG & $DEBUG_TOC;
}
else
{
unless (/^\@\w*heading/)
{
unless (/^\@unnumbered/)
{
my $number = &update_sec_num($tag, $level);
$name = $number. ' ' . $name if $T2H_NUMBER_SECTIONS;
$sec2number{$name} = $number;
$number2sec{$number} = $name;
}
2002-12-09 06:31:39 +08:00
if (defined($toplevel))
{
push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND);
}
2002-12-09 06:31:39 +08:00
else
{
# first time we see a "section"
unless ($level == 1)
{
warn "$WARN The first section found is not of level 1: $_";
}
$toplevel = $level;
}
2002-12-09 06:31:39 +08:00
push(@sections, $name);
next_doc() if ($T2H_SPLIT eq 'section' ||
$T2H_SPLIT && $level == $toplevel);
}
$sec_num++;
$docid = "SEC$sec_num";
$tocid = (/^\@\w*heading/ ? undef : "TOC$sec_num");
# check biblio and glossary
$in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i);
$in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i);
# check node
if ($node)
{
warn "$ERROR Duplicate node found: $node\n"
if ($node2sec{$node});
}
else
{
$name .= ' ' while ($node2sec{$name});
$node = $name;
}
$name .= ' ' while ($sec2node{$name});
$section = $name;
$node2sec{$node} = $name;
$sec2node{$name} = $node;
$node2href{$node} = "$docu_doc#$docid";
$node2next{$node} = $node_next;
$node2prev{$node} = $node_prev;
$node2up{$node} = $node_up;
print "# node $node, section $name, level $level\n"
if $T2H_DEBUG & $DEBUG_TOC;
$node = '';
$node_next = '';
$node_prev = '';
$node_next = '';
if ($tocid)
{
# update TOC
while ($level > $curlevel) {
2002-12-09 06:31:39 +08:00
$curlevel++;
push(@toc_lines, "<UL>\n");
}
while ($level < $curlevel) {
2002-12-09 06:31:39 +08:00
$curlevel--;
push(@toc_lines, "</UL>\n");
}
2002-12-09 06:31:39 +08:00
$_ = &t2h_anchor($tocid, "$docu_doc#$docid", $name, 1);
$_ = &substitute_style($_);
push(@stoc_lines, "$_<BR>\n") if ($level == 1);
if ($T2H_NUMBER_SECTIONS)
{
push(@toc_lines, $_ . "<BR>\n")
}
else
{
push(@toc_lines, "<LI>" . $_ ."</LI>");
}
}
else
{
push(@lines, &html_debug("<A NAME=\"$docid\"></A>\n",
__LINE__));
}
# update DOC
push(@lines, &html_debug('', __LINE__));
&html_reset;
$_ = "<H$level> $name </H$level>\n<!--docid::${docid}::-->\n";
$_ = &debug($_, __LINE__);
push(@lines, &html_debug('', __LINE__));
}
# update DOC
foreach $line (split(/\n+/, $_)) {
push(@lines, "$line\n");
}
next;
} else {
warn "$ERROR Bad section line: $_";
}
} else {
# track variables
2002-12-09 06:31:39 +08:00
$value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o;
delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o;
# store things
2002-12-09 06:31:39 +08:00
$value{'_shorttitle'} = Unprotect_texi($1), next if /^\@shorttitle\s+(.*)$/;
$value{'_setfilename'} = Unprotect_texi($1), next if /^\@setfilename\s+(.*)$/;
$value{'_settitle'} = Unprotect_texi($1), next if /^\@settitle\s+(.*)$/;
$value{'_author'} .= Unprotect_texi($1)."\n", next if /^\@author\s+(.*)$/;
$value{'_subtitle'} .= Unprotect_texi($1)."\n", next if /^\@subtitle\s+(.*)$/;
$value{'_title'} .= Unprotect_texi($1)."\n", next if /^\@title\s+(.*)$/;
# list item
2002-12-09 06:31:39 +08:00
if (/^\s*\@itemx?\s+/) {
$what = $';
$what =~ s/\s+$//;
if ($in_bibliography && $use_bibliography) {
if ($what =~ /^$BIBRE$/o) {
$id = 'BIB' . ++$bib_num;
$bib2href{$what} = "$docu_doc#$id";
print "# found bibliography for '$what' id $id\n"
2002-12-09 06:31:39 +08:00
if $T2H_DEBUG & $DEBUG_BIB;
$what = &t2h_anchor($id, '', $what);
}
2002-12-09 06:31:39 +08:00
} elsif ($in_glossary && $T2H_USE_GLOSSARY) {
$id = 'GLOSS' . ++$gloss_num;
$entry = $what;
$entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
$gloss2href{$entry} = "$docu_doc#$id";
print "# found glossary for '$entry' id $id\n"
2002-12-09 06:31:39 +08:00
if $T2H_DEBUG & $DEBUG_GLOSS;
$what = &t2h_anchor($id, '', $what);
}
elsif ($in_table && ($table_type eq 'f' || $table_type eq 'v'))
{
EnterIndexEntry($table_type, $what, $docu_doc, $section, \@lines);
}
&html_pop_if('P');
if ($html_element eq 'DL' || $html_element eq 'DD') {
if ($things_map{$in_table} && !$what) {
# special case to allow @table @bullet for instance
push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__));
} else {
push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__));
}
push(@lines, "<DD>");
&html_push('DD') unless $html_element eq 'DD';
if ($table_type) { # add also an index
unshift(@input_spool, "\@${table_type}index $what\n");
}
1999-08-03 07:48:02 +08:00
} elsif ($html_element eq 'TABLE') {
push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
&html_push('TR');
} elsif ($html_element eq 'TR') {
push(@lines, &debug("</TR>\n", __LINE__));
push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__));
} else {
push(@lines, &debug("<LI>$what\n", __LINE__));
&html_push('LI') unless $html_element eq 'LI';
}
2002-12-09 06:31:39 +08:00
push(@lines, &html_debug('', __LINE__));
if ($deferred_ref) {
push(@lines, &debug("$deferred_ref\n", __LINE__));
$deferred_ref = '';
}
next;
1999-08-03 07:48:02 +08:00
} elsif (/^\@tab\s+(.*)$/) {
push(@lines, "<TD>$1</TD>\n");
next;
}
}
}
# paragraph separator
2002-12-09 06:31:39 +08:00
if ($_ eq "\n" && ! $in_pre) {
next if $#lines >= 0 && $lines[$#lines] eq "\n";
if ($html_element eq 'P') {
2002-12-09 06:31:39 +08:00
push (@lines, &debug("</P><P>\n", __LINE__));
}
2002-12-09 06:31:39 +08:00
# else
# {
# push(@lines, "<P></P>\n");
# $_ = &debug("<P></P>\n", __LINE__);
# }
elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'DD' || $html_element eq 'LI')
{
&html_push('P');
push(@lines, &debug("<P>\n", __LINE__));
}
}
# otherwise
2002-12-09 06:31:39 +08:00
push(@lines, $_) unless $in_titlepage;
push(@lines, &debug("</center>\n", __LINE__)) if ($tag eq 'center');
}
# finish TOC
$level = 0;
while ($level < $curlevel) {
$curlevel--;
push(@toc_lines, "</UL>\n");
}
2002-12-09 06:31:39 +08:00
print "# end of pass 1\n" if $T2H_VERBOSE;
SetDocumentLanguage('en') unless ($T2H_LANG);
#+++############################################################################
# #
# Stuff related to Index generation #
# #
#---############################################################################
sub EnterIndexEntry
{
my $prefix = shift;
my $key = shift;
my $docu_doc = shift;
my $section = shift;
my $lines = shift;
local $_;
warn "$ERROR Undefined index command: $_", next
unless (exists ($index_properties->{$prefix}));
$key =~ s/\s+$//;
$_ = $key;
&protect_texi;
$key = $_;
$_ = &protect_html($_);
my $html_key = substitute_style($_);
my $id;
$key = remove_style($key);
$key = remove_things($key);
$_ = $key;
&unprotect_texi;
$key = $_;
while (exists $index->{$prefix}->{$key}) {$key .= ' '};
if ($lines->[$#lines] =~ /^<!--docid::(.+)::-->$/)
{
$id = $1;
}
else
{
$id = 'IDX' . ++$idx_num;
push(@$lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre));
}
$index->{$prefix}->{$key}->{html_key} = $html_key;
$index->{$prefix}->{$key}->{section} = $section;
$index->{$prefix}->{$key}->{href} = "$docu_doc#$id";
print "# found ${prefix}index for '$key' with id $id\n"
if $T2H_DEBUG & $DEBUG_INDEX;
}
sub IndexName2Prefix
{
my $name = shift;
my $prefix;
for $prefix (keys %$index_properties)
{
return $prefix if ($index_properties->{$prefix}->{name} eq $name);
}
return undef;
}
sub GetIndexEntries
{
my $normal = shift;
my $code = shift;
my ($entries, $prefix, $key) = ({});
for $prefix (keys %$normal)
{
for $key (keys %{$index->{$prefix}})
{
$entries->{$key} = {%{$index->{$prefix}->{$key}}};
}
}
if (defined($code))
{
for $prefix (keys %$code)
{
unless (exists $normal->{$keys})
{
for $key (keys %{$index->{$prefix}})
{
$entries->{$key} = {%{$index->{$prefix}->{$key}}};
$entries->{$key}->{html_key} = "<CODE>$entries->{$key}->{html_key}</CODE>";
}
}
}
}
return $entries;
}
sub byAlpha
{
if ($a =~ /^[A-Za-z]/)
{
if ($b =~ /^[A-Za-z]/)
{
return lc($a) cmp lc($b);
}
else
{
return 1;
}
}
elsif ($b =~ /^[A-Za-z]/)
{
return -1;
}
else
{
return lc($a) cmp lc($b);
}
}
sub GetIndexPages
{
my $entries = shift;
my (@Letters, $key);
my ($EntriesByLetter, $Pages, $page) = ({}, [], {});
my @keys = sort byAlpha keys %$entries;
for $key (@keys)
{
push @{$EntriesByLetter->{uc(substr($key,0, 1))}} , $entries->{$key};
}
@Letters = sort byAlpha keys %$EntriesByLetter;
$T2H_SPLIT_INDEX = 0 unless ($T2H_SPLIT);
unless ($T2H_SPLIT_INDEX)
{
$page->{First} = $Letters[0];
$page->{Last} = $Letters[$#Letters];
$page->{Letters} = \@Letters;
$page->{EntriesByLetter} = $EntriesByLetter;
push @$Pages, $page;
return $Pages;
}
if ($T2H_SPLIT_INDEX =~ /^\d+$/)
{
my $i = 0;
my ($prev_letter, $letter);
$page->{First} = $Letters[0];
for $letter (@Letters)
{
if ($i > $T2H_SPLIT_INDEX)
{
$page->{Last} = $prev_letter;
push @$Pages, {%$page};
$page->{Letters} = [];
$page->{EntriesByLetter} = {};
$page->{First} = $letter;
$i=0;
}
push @{$page->{Letters}}, $letter;
$page->{EntriesByLetter}->{$letter} = [@{$EntriesByLetter->{$letter}}];
$i += scalar(@{$EntriesByLetter->{$letter}});
$prev_letter = $letter;
}
$page->{Last} = $Letters[$#Letters];
push @$Pages, {%$page};
}
return $Pages;
}
sub GetIndexSummary
{
my $first_page = shift;
my $Pages = shift;
my $name = shift;
my ($page, $letter, $summary, $i, $l1, $l2, $l);
$i = 0;
$summary = '<table><tr><th valign=top>Jump to: &nbsp; </th><td>';
for $page ($first_page, @$Pages)
{
for $letter (@{$page->{Letters}})
{
$l = t2h_anchor('', "$page->{href}#${name}_$letter", "<b>$letter</b>",
0, 'style="text-decoration:none"') . "\n &nbsp; \n";
if ($letter =~ /^[A-Za-z]/)
{
$l2 .= $l;
}
else
{
$l1 .= $l;
}
}
}
$summary .= $l1 . "<BR>\n" if ($l1);
$summary .= $l2 . '</td></tr></table><br>';
return $summary;
}
sub PrintIndexPage
{
my $lines = shift;
my $summary = shift;
my $page = shift;
my $name = shift;
push @$lines, $summary;
push @$lines , <<EOT;
<P></P>
<TABLE border=0>
<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> Section</TH></TR>
<TR><TD COLSPAN=3> <HR></TD></TR>
EOT
for $letter (@{$page->{Letters}})
{
push @$lines, "<TR><TH><A NAME=\"${name}_$letter\"></A>$letter</TH><TD></TD><TD></TD></TR>\n";
for $entry (@{$page->{EntriesByLetter}->{$letter}})
{
push @$lines,
"<TR><TD></TD><TD valign=top>" .
t2h_anchor('', $entry->{href}, $entry->{html_key}) .
"</TD><TD valign=top>" .
t2h_anchor('', sec_href($entry->{section}), clean_name($entry->{section})) .
"</TD></TR>\n";
}
push @$lines, "<TR><TD COLSPAN=3> <HR></TD></TR>\n";
}
push @$lines, "</TABLE><P></P>";
push @$lines, $summary;
}
sub PrintIndex
{
my $lines = shift;
my $name = shift;
my $section = shift;
$section = 'Top' unless $section;
my $prefix = IndexName2Prefix($name);
warn ("$ERROR printindex: bad index name: $name"), return
unless $prefix;
if ($index_properties->{$prefix}->{code})
{
$index_properties->{$prefix}->{from_code}->{$prefix} = 1;
}
else
{
$index_properties->{$prefix}->{from}->{$prefix}= 1;
}
my $Entries = GetIndexEntries($index_properties->{$prefix}->{from},
$index_properties->{$prefix}->{from_code});
return unless %$Entries;
if ($T2H_IDX_SUMMARY)
{
my $key;
open(FHIDX, ">$docu_rdir$docu_name" . "_$name.idx")
|| die "Can't open > $docu_rdir$docu_name" . "_$name.idx for writing: $!\n";
print "# writing $name index summary in $docu_rdir$docu_name" . "_$name.idx...\n" if $T2H_VERBOSE;
for $key (sort keys %$Entries)
{
print FHIDX "$key\t$Entries->{$key}->{href}\n";
}
}
my $Pages = GetIndexPages($Entries);
my $page;
my $first_page = shift @$Pages;
my $sec_name = $section;
# remove section number
$sec_name =~ s/.*? // if $sec_name =~ /^([A-Z]|\d+)\./;
($first_page->{href} = sec_href($section)) =~ s/\#.*$//;
# Update tree structure of document
if (@$Pages)
{
my $sec;
my @after;
while (@sections && $sections[$#sections] ne $section)
{
unshift @after, pop @sections;
}
for $page (@$Pages)
{
my $node = ($page->{First} ne $page->{Last} ?
"$sec_name: $page->{First} -- $page->{Last}" :
"$sec_name: $page->{First}");
push @sections, $node;
$node2sec{$node} = $node;
$sec2node{$node} = $node;
$node2up{$node} = $section;
$page->{href} = next_doc();
$page->{name} = $node;
$node2href{$node} = $page->{href};
if ($prev_node)
{
$node2next{$prev_node} = $node;
$node2prev{$node} = $prev_node;
}
$prev_node = $node;
}
push @sections, @after;
}
my $summary = GetIndexSummary($first_page, $Pages, $name);
PrintIndexPage($lines, $summary, $first_page, $name);
for $page (@$Pages)
{
push @$lines, ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND);
push @$lines, "<H2 ALIGN=\"Left\">$page->{name}</H2>\n";
PrintIndexPage($lines, $summary, $page, $name);
}
}
#+++############################################################################
# #
# Pass 2/3: handle style, menu, index, cross-reference #
# #
#---############################################################################
@lines2 = (); # whole document (2nd pass)
@lines3 = (); # whole document (3rd pass)
$in_menu = 0; # am I inside a menu
while (@lines) {
$_ = shift(@lines);
#
# special case (protected sections)
#
if (/^$PROTECTTAG/o) {
push(@lines2, $_);
next;
}
#
# menu
#
2002-12-09 06:31:39 +08:00
if (/^\@menu\b/)
{
$in_menu = 1;
$in_menu_listing = 1;
push(@lines2, &debug("<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> \n", __LINE__));
next;
}
2002-12-09 06:31:39 +08:00
if (/^\@end\s+menu\b/)
{
if ($in_menu_listing)
{
push(@lines2, &debug("</TABLE></BLOCKQUOTE>\n", __LINE__));
}
else
{
push(@lines2, &debug("</BLOCKQUOTE>\n", __LINE__));
}
$in_menu = 0;
$in_menu_listing = 0;
next;
}
if ($in_menu)
{
my ($node, $name, $descr);
if (/^\*\s+($NODERE)::/o)
{
$node = $1;
$descr = $';
}
elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/)
{
$name = $1;
$node = $2;
$descr = $';
}
elsif (/^\*/)
{
warn "$ERROR Bad menu line: $_";
}
else
{
if ($in_menu_listing)
{
$in_menu_listing = 0;
push(@lines2, &debug("</TABLE>\n", __LINE__));
}
2002-12-09 06:31:39 +08:00
# should be like verbatim -- preseve spaces, etc
s/ /\&nbsp;/g;
$_ .= "<br>\n";
push(@lines2, $_);
}
if ($node)
{
if (! $in_menu_listing)
{
$in_menu_listing = 1;
push(@lines2, &debug("<TABLE BORDER=0 CELLSPACING=0>\n", __LINE__));
1999-08-03 07:48:02 +08:00
}
2002-12-09 06:31:39 +08:00
# look for continuation
while ($lines[0] =~ /^\s+\w+/)
{
$descr .= shift(@lines);
}
2002-12-09 06:31:39 +08:00
&menu_entry($node, $name, $descr);
}
next;
}
#
2002-12-09 06:31:39 +08:00
# printindex
#
PrintIndex(\@lines2, $2, $1), next
if (/^<!--::(.*)::-->\@printindex\s+(\w+)/);
#
# simple style substitutions
#
$_ = &substitute_style($_);
#
# xref
#
2002-12-09 06:31:39 +08:00
while (/\@(x|px|info|)ref{([^{}]+)(}?)/) {
# note: Texinfo may accept other characters
($type, $nodes, $full) = ($1, $2, $3);
($before, $after) = ($`, $');
if (! $full && $after) {
warn "$ERROR Bad xref (no ending } on line): $_";
$_ = "$before$;0${type}ref\{$nodes$after";
next; # while xref
}
if ($type eq 'x') {
2002-12-09 06:31:39 +08:00
$type = "$T2H_WORDS->{$T2H_LANG}->{'See'} ";
} elsif ($type eq 'px') {
2002-12-09 06:31:39 +08:00
$type = "$T2H_WORDS->{$T2H_LANG}->{'see'} ";
} elsif ($type eq 'info') {
2002-12-09 06:31:39 +08:00
$type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info";
} else {
$type = '';
}
unless ($full) {
$next = shift(@lines);
$next = &substitute_style($next);
chop($nodes); # remove final newline
if ($next =~ /\}/) { # split on 2 lines
$nodes .= " $`";
$after = $';
} else {
$nodes .= " $next";
$next = shift(@lines);
$next = &substitute_style($next);
chop($nodes);
if ($next =~ /\}/) { # split on 3 lines
$nodes .= " $`";
$after = $';
} else {
warn "$ERROR Bad xref (no ending }): $_";
$_ = "$before$;0xref\{$nodes$after";
unshift(@lines, $next);
next; # while xref
}
}
}
$nodes =~ s/\s+/ /g; # remove useless spaces
@args = split(/\s*,\s*/, $nodes);
$node = $args[0]; # the node is always the first arg
2002-12-09 06:31:39 +08:00
$node = &normalise_node($node);
$sec = $args[2] || $args[1] || $node2sec{$node};
$href = $node2href{$node};
if (@args == 5) { # reference to another manual
$sec = $args[2] || $node;
$man = $args[4] || $args[3];
2002-12-09 06:31:39 +08:00
$_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after";
} elsif ($type =~ /Info/) { # inforef
warn "$ERROR Wrong number of arguments: $_" unless @args == 3;
($nn, $_, $in) = @args;
$_ = "${before}${type} file `$in', node `$nn'$after";
2002-12-09 06:31:39 +08:00
} elsif ($sec && $href && ! $T2H_SHORT_REF) {
$_ = "${before}${type}";
$_ .= "$T2H_WORDS->{$T2H_LANG}->{'section'} " if ${type};
$_ .= &t2h_anchor('', $href, $sec) . $after;
}
elsif ($href)
{
$_ = "${before}${type} " .
&t2h_anchor('', $href, $args[2] || $args[1] || $node) .
$after;
}
else {
warn "$ERROR Undefined node ($node): $_";
$_ = "$before$;0xref{$nodes}$after";
}
}
2002-12-09 06:31:39 +08:00
# replace images
s[\@image\s*{(.+?)}]
{
my @args = split (/\s*,\s*/, $1);
my $base = $args[0];
my $image =
LocateIncludeFile("$base.png") ||
LocateIncludeFile("$base.jpg") ||
LocateIncludeFile("$base.gif");
warn "$ERROR no image file for $base: $_" unless ($image && -e $image);
"<IMG SRC=\"$image\" ALT=\"$base\">";
($T2H_CENTER_IMAGE ?
"<CENTER><IMG SRC=\"$image\" ALT=\"$base\"></CENTER>" :
"<IMG SRC=\"$image\" ALT=\"$base\">");
}eg;
#
# try to guess bibliography references or glossary terms
#
unless (/^<H\d><A NAME=\"SEC\d/) {
if ($use_bibliography) {
$done = '';
while (/$BIBRE/o) {
($pre, $what, $post) = ($`, $&, $');
$href = $bib2href{$what};
if (defined($href) && $post !~ /^[^<]*<\/A>/) {
2002-12-09 06:31:39 +08:00
$done .= $pre . &t2h_anchor('', $href, $what);
} else {
$done .= "$pre$what";
}
$_ = $post;
}
$_ = $done . $_;
}
2002-12-09 06:31:39 +08:00
if ($T2H_USE_GLOSSARY) {
$done = '';
while (/\b\w+\b/) {
($pre, $what, $post) = ($`, $&, $');
$entry = $what;
$entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/;
$href = $gloss2href{$entry};
if (defined($href) && $post !~ /^[^<]*<\/A>/) {
2002-12-09 06:31:39 +08:00
$done .= $pre . &t2h_anchor('', $href, $what);
} else {
$done .= "$pre$what";
}
$_ = $post;
}
$_ = $done . $_;
}
}
# otherwise
push(@lines2, $_);
}
2002-12-09 06:31:39 +08:00
print "# end of pass 2\n" if $T2H_VERBOSE;
#
# split style substitutions
#
while (@lines2) {
$_ = shift(@lines2);
#
# special case (protected sections)
#
if (/^$PROTECTTAG/o) {
push(@lines3, $_);
next;
}
#
# split style substitutions
#
$old = '';
while ($old ne $_) {
$old = $_;
if (/\@(\w+)\{/) {
($before, $style, $after) = ($`, $1, $');
if (defined($style_map{$style})) {
$_ = $after;
$text = '';
$after = '';
$failed = 1;
while (@lines2) {
if (/\}/) {
$text .= $`;
$after = $';
$failed = 0;
last;
} else {
$text .= $_;
$_ = shift(@lines2);
}
}
if ($failed) {
die "* Bad syntax (\@$style) after: $before\n";
} else {
$text = &apply_style($style, $text);
$_ = "$before$text$after";
}
}
}
}
# otherwise
push(@lines3, $_);
}
2002-12-09 06:31:39 +08:00
print "# end of pass 3\n" if $T2H_VERBOSE;
#+++############################################################################
# #
# Pass 4: foot notes, final cleanup #
# #
#---############################################################################
@foot_lines = (); # footnotes
@doc_lines = (); # final document
$end_of_para = 0; # true if last line is <P>
2002-12-09 06:31:39 +08:00
while (@lines3) {
$_ = shift(@lines3);
#
# special case (protected sections)
#
if (/^$PROTECTTAG/o) {
push(@doc_lines, $_);
$end_of_para = 0;
next;
}
#
# footnotes
#
while (/\@footnote([^\{\s]+)\{/) {
($before, $d, $after) = ($`, $1, $');
$_ = $after;
$text = '';
$after = '';
$failed = 1;
while (@lines3) {
if (/\}/) {
$text .= $`;
$after = $';
$failed = 0;
last;
} else {
$text .= $_;
$_ = shift(@lines3);
}
}
if ($failed) {
die "* Bad syntax (\@footnote) after: $before\n";
} else {
$foot_num++;
$docid = "DOCF$foot_num";
$footid = "FOOT$foot_num";
$foot = "($foot_num)";
2002-12-09 06:31:39 +08:00
push(@foot_lines, "<H3>" . &t2h_anchor($footid, "$d#$docid", $foot) . "</H3>\n");
$text = "<P>$text" unless $text =~ /^\s*<P>/;
push(@foot_lines, "$text\n");
2002-12-09 06:31:39 +08:00
$_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after;
}
}
#
# remove unnecessary <P>
#
if (/^\s*<P>\s*$/) {
next if $end_of_para++;
} else {
$end_of_para = 0;
}
# otherwise
push(@doc_lines, $_);
}
2002-12-09 06:31:39 +08:00
print "# end of pass 4\n" if $T2H_VERBOSE;
#+++############################################################################
# #
# Pass 5: print things #
# #
#---############################################################################
2002-12-09 06:31:39 +08:00
$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H);
$T2H_L2H = &l2h_ToHtml if ($T2H_L2H);
$T2H_L2H = &l2h_InitFromHtml if ($T2H_L2H);
# fix node2up, node2prev, node2next, if desired
if ($has_top_command)
{
for $section (keys %sec2number)
{
$node = $sec2node{$section};
$node2up{$node} = Sec2UpNode($section) unless $node2up{$node};
$node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node};
$node2next{$node} = Sec2NextNode($section) unless $node2next{$node};
}
}
# prepare %T2H_THISDOC
$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document";
$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle};
$T2H_THISDOC{author} = $value{'_author'};
$T2H_THISDOC{subtitle} = $value{'_subtitle'};
$T2H_THISDOC{shorttitle} = $value{'_shorttitle'};
for $key (keys %T2H_THISDOC)
{
$_ = &substitute_style($T2H_THISDOC{$key});
&unprotect_texi;
s/\s*$//;
$T2H_THISDOC{$key} = $_;
}
2002-12-09 06:31:39 +08:00
# if no sections, then simply print document as is
unless (@sections)
{
print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE;
open(FILE, "> $docu_top_file")
|| die "$ERROR: Can't open $docu_top_file for writing: $!\n";
2002-12-09 06:31:39 +08:00
&$T2H_print_page_head(\*FILE);
$T2H_THIS_SECTION = \@doc_lines;
t2h_print_lines(\*FILE);
&$T2H_print_foot_navigation(\*FILE);
&$T2H_print_page_foot(\*FILE);
close(FILE);
goto Finish;
}
# initialize $T2H_HREF, $T2H_NAME
%T2H_HREF =
(
'First' , sec_href($sections[0]),
'Last', sec_href($sections[$#sections]),
'About', $docu_about. '#SEC_About',
);
# prepare TOC, OVERVIEW, TOP
$T2H_TOC = \@toc_lines;
$T2H_OVERVIEW = \@stoc_lines;
if ($has_top)
{
while (1)
{
$_ = shift @doc_lines;
last if /$TOPEND/;
push @$T2H_TOP, $_;
}
$T2H_HREF{'Top'} = $docu_top . '#SEC_Top';
}
else
{
$T2H_HREF{'Top'} = $T2H_HREF{First};
}
$node2href{Top} = $T2H_HREF{Top};
$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines;
$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines;
# settle on index
if ($T2H_INDEX_CHAPTER)
{
$T2H_HREF{Index} = $node2href{normalise_node($T2H_INDEX_CHAPTER)};
warn "$ERROR T2H_INDEX_CHAPTER '$T2H_INDEX_CHAPTER' not found\n"
unless $T2H_HREF{Index};
}
if (! $T2H_HREF{Index} && $first_index_chapter)
{
$T2H_INDEX_CHAPTER = $first_index_chapter;
$T2H_HREF{Index} = $node2href{$T2H_INDEX_CHAPTER};
}
print "# Using '" . clean_name($T2H_INDEX_CHAPTER) . "' as index page\n"
if ($T2H_VERBOSE && $T2H_HREF{Index});
%T2H_NAME =
(
'First', clean_name($sec2node{$sections[0]}),
'Last', clean_name($sec2node{$sections[$#sections]}),
'About', $T2H_WORDS->{$T2H_LANG}->{'About_Title'},
'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'},
'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'},
'Index' , clean_name($T2H_INDEX_CHAPTER),
'Top', clean_name($T2H_TOP_HEADING || $T2H_THISDOC{'title'} || $T2H_THISDOC{'shorttitle'}),
);
#############################################################################
# print frame and frame toc file
#
2002-12-09 06:31:39 +08:00
if ( $T2H_FRAMES )
{
open(FILE, "> $docu_frame_file")
|| die "$ERROR: Can't open $docu_frame_file for writing: $!\n";
print "# Creating frame in $docu_frame_file ...\n" if $T2H_VERBOSE;
&$T2H_print_frame(\*FILE);
close(FILE);
open(FILE, "> $docu_toc_frame_file")
|| die "$ERROR: Can't open $docu_toc_frame_file for writing: $!\n";
print "# Creating toc frame in $docu_frame_file ...\n" if $T2H_VERBOSE;
&$T2H_print_toc_frame(\*FILE);
close(FILE);
}
2002-12-09 06:31:39 +08:00
#############################################################################
# print Top
#
2002-12-09 06:31:39 +08:00
open(FILE, "> $docu_top_file")
|| die "$ERROR: Can't open $docu_top_file for writing: $!\n";
&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT);
if ($has_top)
{
print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE;
$T2H_THIS_SECTION = $T2H_TOP;
$T2H_HREF{This} = $T2H_HREF{Top};
$T2H_NAME{This} = $T2H_NAME{Top};
&$T2H_print_Top(\*FILE);
}
close(FILE) if $T2H_SPLIT;
#############################################################################
# Print sections
#
2002-12-09 06:31:39 +08:00
$T2H_NODE{Forward} = $sec2node{$sections[0]};
$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]});
$T2H_HREF{Forward} = sec_href($sections[0]);
$T2H_NODE{This} = 'Top';
$T2H_NAME{This} = $T2H_NAME{Top};
$T2H_HREF{This} = $T2H_HREF{Top};
if ($T2H_SPLIT)
{
print "# writing " . scalar(@sections) .
" sections in $docu_rdir$docu_name"."_[1..$doc_num]"
if $T2H_VERBOSE;
$previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND);
undef $FH;
$doc_num = 0;
}
else
{
print "# writing " . scalar(@sections) . " sections in $docu_top_file ..."
if $T2H_VERBOSE;
$FH = \*FILE;
$previous = '';
}
$counter = 0;
# loop through sections
while ($section = shift(@sections))
{
if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND))
{
if ($FH)
{
#close previous page
&$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter';
&$T2H_print_page_foot($FH);
close($FH);
undef $FH;
}
2002-12-09 06:31:39 +08:00
}
$T2H_NAME{Back} = $T2H_NAME{This};
$T2H_HREF{Back} = $T2H_HREF{This};
$T2H_NODE{Back} = $T2H_NODE{This};
$T2H_NAME{This} = $T2H_NAME{Forward};
$T2H_HREF{This} = $T2H_HREF{Forward};
$T2H_NODE{This} = $T2H_NODE{Forward};
if ($sections[0])
{
$T2H_NODE{Forward} = $sec2node{$sections[0]};
$T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward});
$T2H_HREF{Forward} = sec_href($sections[0]);
}
else
{
undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward};
}
$node = $node2up{$T2H_NODE{This}};
$T2H_HREF{Up} = $node2href{$node};
if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up})
{
$T2H_NAME{Up} = $T2H_NAME{Top};
$T2H_HREF{Up} = $T2H_HREF{Top};
$T2H_NODE{Up} = 'Up';
}
else
{
$T2H_NAME{Up} = &clean_name($node);
$T2H_NODE{Up} = $node;
}
$node = $T2H_NODE{This};
$node = $node2prev{$node};
$T2H_NAME{Prev} = &clean_name($node);
$T2H_HREF{Prev} = $node2href{$node};
$T2H_NODE{Prev} = $node;
$node = $T2H_NODE{This};
if ($node2up{$node} && $node2up{$node} ne 'Top'&&
($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node}))
{
$node = $node2up{$node};
while ($node && $node ne $node2up{$node} && ! $node2prev{$node})
{
$node = $node2up{$node};
}
2002-12-09 06:31:39 +08:00
$node = $node2prev{$node}
unless $node2up{$node} eq 'Top' || ! $node2up{$node};
}
else
{
$node = $node2prev{$node};
}
$T2H_NAME{FastBack} = &clean_name($node);
$T2H_HREF{FastBack} = $node2href{$node};
$T2H_NODE{FastBack} = $node;
$node = $T2H_NODE{This};
$node = $node2next{$node};
$T2H_NAME{Next} = &clean_name($node);
$T2H_HREF{Next} = $node2href{$node};
$T2H_NODE{Next} = $node;
$node = $T2H_NODE{This};
if ($node2up{$node} && $node2up{$node} ne 'Top'&&
($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node}))
{
$node = $node2up{$node};
while ($node && $node ne $node2up{$node} && ! $node2next{$node})
{
$node = $node2up{$node};
}
}
$node = $node2next{$node};
$T2H_NAME{FastForward} = &clean_name($node);
$T2H_HREF{FastForward} = $node2href{$node};
$T2H_NODE{FastForward} = $node;
if (! defined($FH))
{
my $file = $T2H_HREF{This};
$file =~ s/\#.*$//;
open(FILE, "> $docu_rdir$file") ||
die "$ERROR: Can't open $docu_rdir$file for writing: $!\n";
$FH = \*FILE;
&$T2H_print_page_head($FH);
t2h_print_label($FH);
&$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter';
}
else
{
t2h_print_label($FH);
}
$T2H_THIS_SECTION = [];
while (@doc_lines) {
$_ = shift(@doc_lines);
last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND);
push(@$T2H_THIS_SECTION, $_);
}
$previous = $_;
&$T2H_print_section($FH);
if ($T2H_VERBOSE)
{
$counter++;
print "." if $counter =~ /00$/;
}
}
if ($T2H_SPLIT)
{
&$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter';
&$T2H_print_page_foot($FH);
close($FH);
}
print "\n" if $T2H_VERBOSE;
#############################################################################
# Print ToC, Overview, Footnotes
#
undef $T2H_HREF{Prev};
undef $T2H_HREF{Next};
undef $T2H_HREF{Back};
undef $T2H_HREF{Forward};
undef $T2H_HREF{Up};
if (@foot_lines)
{
print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE;
open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n"
if $T2H_SPLIT;
$T2H_HREF{This} = $docu_foot;
$T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'};
$T2H_THIS_SECTION = \@foot_lines;
&$T2H_print_Footnotes(\*FILE);
close(FILE) if $T2H_SPLIT;
}
if (@toc_lines)
{
print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE;
open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n"
if $T2H_SPLIT;
$T2H_HREF{This} = $T2H_HREF{Contents};
$T2H_NAME{This} = $T2H_NAME{Contents};
$T2H_THIS_SECTION = \@toc_lines;
&$T2H_print_Toc(\*FILE);
close(FILE) if $T2H_SPLIT;
}
if (@stoc_lines)
{
print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE;
open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n"
if $T2H_SPLIT;
$T2H_HREF{This} = $T2H_HREF{Overview};
$T2H_NAME{This} = $T2H_NAME{Overview};
$T2H_THIS_SECTION = \@stoc_lines;
unshift @$T2H_THIS_SECTION, "<BLOCKQUOTE>\n";
push @$T2H_THIS_SECTION, "\n</BLOCKQUOTE>\n";
&$T2H_print_Overview(\*FILE);
close(FILE) if $T2H_SPLIT;
}
if ($about_body = &$T2H_about_body())
{
print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE;
open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n"
if $T2H_SPLIT;
$T2H_HREF{This} = $T2H_HREF{About};
$T2H_NAME{This} = $T2H_NAME{About};
$T2H_THIS_SECTION = [$about_body];
&$T2H_print_About(\*FILE);
close(FILE) if $T2H_SPLIT;
}
2002-12-09 06:31:39 +08:00
unless ($T2H_SPLIT)
{
&$T2H_print_page_foot(\*FILE);
close (FILE);
}
Finish:
&l2h_FinishFromHtml if ($T2H_L2H);
&l2h_Finish if($T2H_L2H);
print "# that's all folks\n" if $T2H_VERBOSE;
exit(0);
#+++############################################################################
# #
# Low level functions #
# #
#---############################################################################
2002-12-09 06:31:39 +08:00
sub LocateIncludeFile
{
my $file = shift;
my $dir;
return $file if (-e $file && -r $file);
foreach $dir (@T2H_INCLUDE_DIRS)
{
return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file");
}
return undef;
}
sub clean_name
{
local ($_);
$_ = &remove_style($_[0]);
&unprotect_texi;
return $_;
}
sub update_sec_num {
local($name, $level) = @_;
2002-12-09 06:31:39 +08:00
my $ret;
$level--; # here we start at 0
2002-12-09 06:31:39 +08:00
if ($name =~ /^appendix/ || defined(@appendix_sec_num)) {
# appendix style
if (defined(@appendix_sec_num)) {
&incr_sec_num($level, @appendix_sec_num);
} else {
@appendix_sec_num = ('A', 0, 0, 0);
}
2002-12-09 06:31:39 +08:00
$ret = join('.', @appendix_sec_num[0..$level]);
} else {
# normal style
2002-12-09 06:31:39 +08:00
if (defined(@normal_sec_num))
{
&incr_sec_num($level, @normal_sec_num);
}
else
{
@normal_sec_num = (1, 0, 0, 0);
}
2002-12-09 06:31:39 +08:00
$ret = join('.', @normal_sec_num[0..$level]);
}
2002-12-09 06:31:39 +08:00
$ret .= "." if $level == 0;
return $ret;
}
sub incr_sec_num {
local($level, $l);
$level = shift(@_);
$_[$level]++;
foreach $l ($level+1 .. 3) {
$_[$l] = 0;
}
}
2002-12-09 06:31:39 +08:00
sub Sec2UpNode
{
my $sec = shift;
my $num = $sec2number{$sec};
return '' unless $num;
return 'Top' unless $num =~ /\.\d+/;
$num =~ s/\.[^\.]*$//;
$num = $num . '.' unless $num =~ /\./;
return $sec2node{$number2sec{$num}};
}
sub Sec2PrevNode
{
my $sec = shift;
my $num = $sec2number{$sec};
my ($i, $post);
if ($num =~ /(\w+)(\.$|$)/)
{
$num = $`;
$i = $1;
$post = $2;
if ($i eq 'A')
{
$i = $normal_sec_num[0];
}
elsif ($i ne '1')
{
# unfortunately, -- operator is not magical
$i = chr(ord($i) + 1);
}
else
{
return '';
}
return $sec2node{$number2sec{$num . $i . $post}}
}
return '';
}
sub Sec2NextNode
{
my $sec = shift;
my $num = $sec2number{$sec};
my $i;
if ($num =~ /(\w+)(\.$|$)/)
{
$num = $`;
$i = $1;
$post = $2;
if ($post eq '.' && $i eq $normal_sec_num[0])
{
$i = 'A';
}
else
{
$i++;
}
return $sec2node{$number2sec{$num . $i . $post}}
}
return '';
}
sub check {
local($_, %seen, %context, $before, $match, $after);
while (<>) {
if (/\@(\*|\.|\:|\@|\{|\})/) {
$seen{$&}++;
2002-12-09 06:31:39 +08:00
$context{$&} .= "> $_" if $T2H_VERBOSE;
$_ = "$`XX$'";
redo;
}
if (/\@(\w+)/) {
($before, $match, $after) = ($`, $&, $');
if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address
$seen{'e-mail address'}++;
2002-12-09 06:31:39 +08:00
$context{'e-mail address'} .= "> $_" if $T2H_VERBOSE;
} else {
$seen{$match}++;
2002-12-09 06:31:39 +08:00
$context{$match} .= "> $_" if $T2H_VERBOSE;
}
$match =~ s/^\@/X/;
$_ = "$before$match$after";
redo;
}
}
foreach (sort(keys(%seen))) {
2002-12-09 06:31:39 +08:00
if ($T2H_VERBOSE) {
print "$_\n";
print $context{$_};
} else {
print "$_ ($seen{$_})\n";
}
}
}
sub open {
local($name) = @_;
++$fh_name;
if (open($fh_name, $name)) {
unshift(@fhs, $fh_name);
} else {
warn "$ERROR Can't read file $name: $!\n";
}
}
sub init_input {
@fhs = (); # hold the file handles to read
@input_spool = (); # spooled lines to read
$fh_name = 'FH000';
&open($docu);
}
sub next_line {
local($fh, $line);
if (@input_spool) {
$line = shift(@input_spool);
return($line);
}
while (@fhs) {
$fh = $fhs[0];
$line = <$fh>;
return($line) if $line;
close($fh);
shift(@fhs);
}
return(undef);
}
# used in pass 1, use &next_line
sub skip_until {
local($tag) = @_;
local($_);
while ($_ = &next_line) {
return if /^\@end\s+$tag\s*$/;
}
die "* Failed to find '$tag' after: " . $lines[$#lines];
}
2002-12-09 06:31:39 +08:00
# used in pass 1 for l2h use &next_line
sub string_until {
local($tag) = @_;
local($_, $string);
while ($_ = &next_line) {
return $string if /^\@end\s+$tag\s*$/;
# $_ =~ s/hbox/mbox/g;
$string = $string.$_;
}
die "* Failed to find '$tag' after: " . $lines[$#lines];
}
#
# HTML stacking to have a better HTML output
#
sub html_reset {
@html_stack = ('html');
$html_element = 'body';
}
sub html_push {
local($what) = @_;
push(@html_stack, $html_element);
$html_element = $what;
}
sub html_push_if {
local($what) = @_;
push(@html_stack, $html_element)
if ($html_element && $html_element ne 'P');
$html_element = $what;
}
sub html_pop {
$html_element = pop(@html_stack);
}
sub html_pop_if {
local($elt);
if (@_) {
foreach $elt (@_) {
if ($elt eq $html_element) {
$html_element = pop(@html_stack) if @html_stack;
last;
}
}
} else {
$html_element = pop(@html_stack) if @html_stack;
}
}
sub html_debug {
local($what, $line) = @_;
2002-12-09 06:31:39 +08:00
if ($T2H_DEBUG & $DEBUG_HTML)
{
$what = "\n" unless $what;
return("<!-- $line @html_stack, $html_element -->$what")
}
return($what);
}
# to debug the output...
sub debug {
local($what, $line) = @_;
return("<!-- $line -->$what")
2002-12-09 06:31:39 +08:00
if $T2H_DEBUG & $DEBUG_HTML;
return($what);
}
2002-12-09 06:31:39 +08:00
sub SimpleTexi2Html
{
local $_ = $_[0];
&protect_texi;
&protect_html;
$_ = substitute_style($_);
$_[0] = $_;
}
sub normalise_node {
2002-12-09 06:31:39 +08:00
local $_ = $_[0];
s/\s+/ /g;
s/ $//;
s/^ //;
&protect_texi;
&protect_html;
$_ = substitute_style($_);
$_[0] = $_;
}
2002-12-09 06:31:39 +08:00
sub menu_entry
{
my ($node, $name, $descr) = @_;
my ($href, $entry);
&normalise_node($node);
$href = $node2href{$node};
if ($href)
{
$descr =~ s/^\s+//;
$descr =~ s/\s*$//;
$descr = SimpleTexi2Html($descr);
if ($T2H_NUMBER_SECTIONS && !$T2H_NODE_NAME_IN_MENU && $node2sec{$node})
{
$entry = $node2sec{$node};
$name = '';
}
else
{
&normalise_node($name);
$entry = ($name && ($name ne $node || ! $T2H_AVOID_MENU_REDUNDANCY)
? "$name : $node" : $node);
}
2002-12-09 06:31:39 +08:00
if ($T2H_AVOID_MENU_REDUNDANCY && $descr)
{
my $clean_entry = $entry;
$clean_entry =~ s/^.*? // if ($clean_entry =~ /^([A-Z]|\d+)\.[\d\.]* /);
$clean_entry =~ s/[^\w]//g;
my $clean_descr = $descr;
$clean_descr =~ s/[^\w]//g;
$descr = '' if ($clean_entry eq $clean_descr)
}
2002-12-09 06:31:39 +08:00
push(@lines2,&debug('<TR><TD ALIGN="left" VALIGN="TOP">' .
&t2h_anchor('', $href, $entry) .
'</TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">' .
$descr .
"</TD></TR>\n", __LINE__));
}
elsif ($node =~ /^\(.*\)\w+/)
{
push(@lines2,&debug('<TR><TD ALIGN="left" VALIGN="TOP">' .
$entry .
'</TD><TD ALIGN="left" VALIGN="TOP">' . $descr .
"</TD></TR>\n", __LINE__))
}
else
{
warn "$ERROR Undefined node of menu_entry ($node): $_";
}
}
sub do_ctrl { "^$_[0]" }
1999-08-03 07:48:02 +08:00
sub do_email {
local($addr, $text) = split(/,\s*/, $_[0]);
$text = $addr unless $text;
2002-12-09 06:31:39 +08:00
&t2h_anchor('', "mailto:$addr", $text);
}
sub do_sc
{
# l2h does this much better
return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H);
return "\U$_[0]\E";
1999-08-03 07:48:02 +08:00
}
2002-12-09 06:31:39 +08:00
sub do_math
{
return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H);
return "<EM>".$text."</EM>";
}
1999-08-03 07:48:02 +08:00
sub do_uref {
2002-12-09 06:31:39 +08:00
local($url, $text, $only_text) = split(/,\s*/, $_[0]);
1999-08-03 07:48:02 +08:00
2002-12-09 06:31:39 +08:00
$text = $only_text if $only_text;
1999-08-03 07:48:02 +08:00
$text = $url unless $text;
2002-12-09 06:31:39 +08:00
&t2h_anchor('', $url, $text);
}
sub do_url { &t2h_anchor('', $_[0], $_[0]) }
sub do_acronym
{
return '<FONT SIZE="-1">' . $_[0] . '</FONT>';
1999-08-03 07:48:02 +08:00
}
2002-12-09 06:31:39 +08:00
sub do_accent
{
return "&$_[0]acute;" if $_[1] eq 'H';
return "$_[0]." if $_[1] eq 'dotaccent';
return "$_[0]*" if $_[1] eq 'ringaccent';
return "$_[0]".'[' if $_[1] eq 'tieaccent';
return "$_[0]".'(' if $_[1] eq 'u';
return "$_[0]_" if $_[1] eq 'ubaraccent';
return ".$_[0]" if $_[1] eq 'udotaccent';
return "$_[0]&lt;" if $_[1] eq 'v';
return "&$_[0]cedil;" if $_[1] eq ',';
return "$_[0]" if $_[1] eq 'dotless';
return undef;
}
1999-08-03 07:48:02 +08:00
sub apply_style {
local($texi_style, $text) = @_;
local($style);
$style = $style_map{$texi_style};
if (defined($style)) { # known style
if ($style =~ /^\"/) { # add quotes
$style = $';
$text = "\`$text\'";
}
if ($style =~ /^\&/) { # custom
$style = $';
2002-12-09 06:31:39 +08:00
$text = &$style($text, $texi_style);
} elsif ($style) { # good style
$text = "<$style>$text</$style>";
} else { # no style
}
} else { # unknown style
$text = undef;
}
return($text);
}
# remove Texinfo styles
sub remove_style {
local($_) = @_;
2002-12-09 06:31:39 +08:00
1 while(s/\@\w+{([^\{\}]+)}/$1/g);
return($_);
}
2002-12-09 06:31:39 +08:00
sub remove_things
{
local ($_) = @_;
s|\@(\w+)\{\}|$1|g;
return $_;
}
sub substitute_style {
local($_) = @_;
local($changed, $done, $style, $text);
2002-12-09 06:31:39 +08:00
&simple_substitutions;
$changed = 1;
while ($changed) {
$changed = 0;
$done = '';
2002-12-09 06:31:39 +08:00
while (/\@(\w+){([^\{\}]+)}/ || /\@(,){([^\{\}]+)}/) {
$text = &apply_style($1, $2);
if ($text) {
$_ = "$`$text$'";
$changed = 1;
} else {
$done .= "$`\@$1";
$_ = "{$2}$'";
}
}
$_ = $done . $_;
}
return($_);
}
2002-12-09 06:31:39 +08:00
sub t2h_anchor {
local($name, $href, $text, $newline, $extra_attribs) = @_;
local($result);
$result = "<A";
$result .= " NAME=\"$name\"" if $name;
2002-12-09 06:31:39 +08:00
if ($href)
{
$href =~ s|^$T2H_HREF_DIR_INSTEAD_FILE|./|
if ($T2H_HREF_DIR_INSTEAD_FILE);
$result .= ($href =~ /\"/ ? " HREF='$href'" : " HREF=\"$href\"");
}
$result .= " $extra_attribs" if $extra_attribs;
$result .= ">$text</A>";
$result .= "\n" if $newline;
return($result);
}
sub pretty_date {
local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
2002-12-09 06:31:39 +08:00
@MoY = ('January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December');
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
$year += ($year < 70) ? 2000 : 1900;
2002-12-09 06:31:39 +08:00
# obachman: Let's do it as the Americans do
return("$MoY[$mon], $mday $year");
}
2002-12-09 06:31:39 +08:00
sub doc_href {
local($num) = @_;
2002-12-09 06:31:39 +08:00
return("${docu_name}_$num.$docu_ext");
}
sub sec_href
{
return $node2href{$sec2node{$_[0]}};
}
sub next_doc {
2002-12-09 06:31:39 +08:00
$docu_doc = &doc_href(++$doc_num);
}
2002-12-09 06:31:39 +08:00
sub t2h_print_lines {
my ($fh, $lines) = @_;
local($_);
2002-12-09 06:31:39 +08:00
$lines = $T2H_THIS_SECTION unless $lines;
my $cnt = 0;
for (@$lines)
{
$_ = l2h_FromHtml($_) if ($T2H_L2H);
if (/^$PROTECTTAG/o) {
$_ = $tag2pro{$_};
} else {
&unprotect_texi;
}
print $fh $_;
2002-12-09 06:31:39 +08:00
$cnt += split(/\W*\s+\W*/);
}
2002-12-09 06:31:39 +08:00
return $cnt;
}
sub protect_texi {
# protect @ { } ` '
s/\@\@/$;0/go;
s/\@\{/$;1/go;
s/\@\}/$;2/go;
s/\@\`/$;3/go;
s/\@\'/$;4/go;
}
sub protect_html {
local($what) = @_;
# protect & < >
$what =~ s/\&/\&\#38;/g;
$what =~ s/\</\&\#60;/g;
$what =~ s/\>/\&\#62;/g;
2002-12-09 06:31:39 +08:00
# restore anything in quotes
# this fixes my problem where I had:
# < IMG SRC="leftarrow.gif" ALT="<--" > but what if I wanted &#60; in my ALT text ??
# maybe byte stuffing or some other technique should be used.
$what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g;
$what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g;
$what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g;
# but recognize some HTML things
$what =~ s/\&\#60;\/A\&\#62;/<\/A>/g; # </A>
$what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g; # <A [^&]+>
$what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+>
return($what);
}
sub unprotect_texi {
s/$;0/\@/go;
s/$;1/\{/go;
s/$;2/\}/go;
s/$;3/\`/go;
s/$;4/\'/go;
}
2002-12-09 06:31:39 +08:00
sub Unprotect_texi
{
local $_ = shift;
&unprotect_texi;
return($_);
}
sub unprotect_html {
local($what) = @_;
$what =~ s/\&\#38;/\&/g;
$what =~ s/\&\#60;/\</g;
$what =~ s/\&\#62;/\>/g;
return($what);
}
2002-12-09 06:31:39 +08:00
sub t2h_print_label
{
my $fh = shift;
my $href = shift || $T2H_HREF{This};
$href =~ s/.*#(.*)$/$1/;
print $fh qq{<A NAME="$href"></A>\n};
}
##############################################################################
# These next few lines are legal in both Perl and nroff.
.00 ; # finish .ig
'di \" finish diversion--previous line must be blank
.nr nl 0-1 \" fake up transition to first page again
.nr % 0 \" start at page 1
'; __END__ ############# From here on it's a standard manual page ############
2002-12-09 06:31:39 +08:00
.so /usr/local/man/man1/texi2html.1