diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:38:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:38:56 +0000 |
commit | 6c20c8ed2cb9ab69a1a57ccb2b9b79969a808321 (patch) | |
tree | f63ce19d57fad3ac4a15bc26dbfbfa2b834111b5 /support/texi2html | |
parent | Initial commit. (diff) | |
download | bash-6c20c8ed2cb9ab69a1a57ccb2b9b79969a808321.tar.xz bash-6c20c8ed2cb9ab69a1a57ccb2b9b79969a808321.zip |
Adding upstream version 5.2.15.upstream/5.2.15upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'support/texi2html')
-rwxr-xr-x | support/texi2html | 5428 |
1 files changed, 5428 insertions, 0 deletions
diff --git a/support/texi2html b/support/texi2html new file mode 100755 index 0000000..13b5588 --- /dev/null +++ b/support/texi2html @@ -0,0 +1,5428 @@ +#! /usr/bin/perl +'di '; +'ig 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 3 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, see <http://www.gnu.org/licenses/>. +# +#-############################################################################## + +# 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: texi2html.pl,v 1.55 2000/07/27 14:39:41 obachman Exp $ + +# 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 + +# 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'. + +# 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: texi2html.init,v 1.34 2000/07/27 14:09:02 obachman Exp $ + +###################################################################### +# 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 = ' '; +$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> </td>'; +# same as above, only for @small +$T2H_SMALL_EXAMPLE_INDENT_CELL = '<td> </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' => 'Über dieses Dokument', + 'Footnotes_Title' => 'Fuß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' => 'índice General', + 'Overview_Title' => 'Resumen del Contenido', + 'Index_Title' => 'Index', #Not sure ;-) + 'About_Title' => 'No translation available!', #No translation available! + 'Footnotes_Title' => 'Fußnoten', + 'See' => 'Véase', + 'see' => 'véase', + 'section' => 'secció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ário', + 'Overview_Title' => 'Breve Sumário', + 'Index_Title' => 'Índice', #Not sure ;-) + 'About_Title' => 'No translation available!', #No translation available! + 'Footnotes_Title' => 'No translation available!', + 'See' => 'Veja', + 'see' => 'veja', + 'section' => 'Seçã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ä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ç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', + ' ', ' ', + 'Back', ' < ', + 'FastBack', ' << ', + 'Prev', 'Prev', + 'Up', ' Up ', + 'Next', 'Next', + 'Forward', ' > ', + 'FastForward', ' >> ', + 'About', ' ? ', + 'First', ' |< ', + 'Last', ' >| ' + ); + +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 <STRONG> +<== 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', ' ', + 'Contents', ' ', + 'Overview', ' ', + 'Index', ' ', + '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', ' ', + '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: MySimple.pm,v 1.1 2000/07/03 08:44:13 obachman Exp $ + +# 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; +$DEBUG_L2H = 128; + + +$BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference +$FILERE = '[\/\w.+-]+'; # RE for a file name +$VARRE = '[^\s\{\}]+'; # RE for a variable name +$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 + +$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 +# +$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+ + " ", " ", + "\t", " ", + "-", "­", # soft hyphen + "\n", "\n", + "|", "", + 'tab', '<\/TD><TD>', + # spacing commands + ":", "", + "!", "!", + "?", "?", + ".", ".", + "-", "", + ); + +# +# texinfo "things" (@foo{}) to HTML ones +# +%things_map = ( + 'TeX', 'TeX', + 'br', '<P>', # paragraph break + 'bullet', '*', + 'copyright', '(C)', + 'dots', '<small>...<\/small>', + 'enddots', '<small>....<\/small>', + 'equiv', '==', + 'error', 'error-->', + 'expansion', '==>', + 'minus', '-', + 'point', '-!-', + 'print', '-|', + 'result', '=>', + 'today', $T2H_TODAY, + 'aa', 'å', + 'AA', 'Å', + 'ae', 'æ', + 'oe', 'œ', + 'AE', 'Æ', + 'OE', 'Œ', + 'o', 'ø', + 'O', 'Ø', + 'ss', 'ß', + 'l', '\/l', + 'L', '\/L', + 'exclamdown', '¡', + 'questiondown', '¿', + 'pounds', '£' + ); + +# +# texinfo styles (@foo{bar}) to HTML ones +# +%style_map = ( + 'acronym', '&do_acronym', + 'asis', '', + 'b', 'B', + 'cite', 'CITE', + 'code', 'CODE', + 'command', 'CODE', + 'ctrl', '&do_ctrl', # special case + 'dfn', 'EM', # DFN tag is illegal in the standard + 'dmn', '', # useless + 'email', '&do_email', # insert a clickable email address + 'emph', 'EM', + 'env', 'CODE', + 'file', '"TT', # will put quotes, cf. &apply_style + 'i', 'I', + 'kbd', 'KBD', + 'key', 'KBD', + '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 + 'uref', '&do_uref', # insert a clickable URL + 'url', '&do_url', # insert a clickable URL + 'var', 'VAR', + 'w', '', # unsupported + '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', + ); + +# +# 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}', + 'deftypeivar', 'defcv {Instance Variable}', # NEW: FIXME + 'defmethod', 'defop Method', + '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, + 'ifnotinfo', 1, + 'ifnottex', 1, + 'ifhtml', 1, + 'end ifhtml', 1, + 'end ifnotinfo', 1, + 'end ifnottex', 1, + # useless + '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, + '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, + 'paragraphindent', 1, + # unsupported formats + 'cartouche', 1, + 'end cartouche', 1, + 'group', 1, + 'end group', 1, + ); + +#+++############################################################################ +# # +# Argument parsing, initialisation # +# # +#---############################################################################ + +# +# flush stdout and stderr after every write +# +select(STDERR); +$| = 1; +select(STDOUT); +$| = 1; + + +%value = (); # hold texinfo variables, see also -D +$use_bibliography = 1; +$use_acc = 1; + +# +# 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); + } +} + + +#+++############################################################################ +# # +# 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; + ✓ + exit; +} + +#+++############################################################################ +# # +# 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; + +} + +$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; +} +unshift(@T2H_INCLUDE_DIRS, $docu_dir); +$docu_name =~ s/\.te?x(i|info)?$//; # basename of the document +$docu_name = $T2H_PREFIX if ($T2H_PREFIX); + +# 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; +} + +$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) +$value{'texi2html'} = $THISVERSION; # predefine texi2html (the translator) +# _foo: internal to track @foo +foreach ('_author', '_title', '_subtitle', + '_settitle', '_setfilename', '_shorttitle') { + $value{$_} = ''; # prevent -w warnings +} +%node2sec = (); # node to section name +%sec2node = (); # section to node name +%sec2number = (); # section to number +%number2sec = (); # number to section +%idx2node = (); # index keys to node +%node2href = (); # node to HREF +%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+) +# +if ($T2H_USE_ISO) { + $things_map{'bullet'} = "•"; + $things_map{'copyright'} = "©"; + $things_map{'dots'} = "…"; + $things_map{'equiv'} = "≡"; + $things_map{'expansion'} = "→"; + $things_map{'point'} = "∗"; + $things_map{'result'} = "⇒"; +} + +# +# read texi2html extensions (if any) +# +$extensions = 'texi2html.ext'; # extensions in working directory +if (-f $extensions) { + 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) { + print "# reading extensions from $extensions\n" if $T2H_VERBOSE; + require($extensions); + } +} + + +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 +@stoc_lines = (); # table of contents +$curlevel = 0; # current level in TOC +$node = ''; # current node name +$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 +$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 +$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; +%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/\\\@\\$_"; + } + $subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n"; + } +} +eval("sub simple_substitutions { $subst_code }"); + +&init_input; +INPUT_LINE: while ($_ = &next_line) { + # + # remove \input on the first lines only + # + if ($first_line) { + next if /^\\input/; + $first_line = 0; + } + # non-@ substitutions cf. texinfmt.el + # + # parse texinfo tags + # + $tag = ''; + $end_tag = ''; + if (/^\s*\@end\s+(\w+)\b/) { + $end_tag = $1; + } elsif (/^\s*\@(\w+)\b/) { + $tag = $1; + } + # + # handle @html / @end html + # + if ($in_html) { + if ($end_tag eq 'html') { + $in_html = 0; + } else { + $tag2pro{$in_html} .= $_; + } + next; + } elsif ($tag eq 'html') { + $in_html = $PROTECTTAG . ++$html_num; + push(@lines, $in_html); + next; + } + + # + # 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) { + $in_titlepage = 0 if $end_tag eq 'titlepage'; + next if $to_skip{"end $end_tag"}; + } elsif ($tag) { + $in_titlepage = 1 if $tag eq 'titlepage'; + next if $to_skip{$tag}; + last if $tag eq 'bye'; + } + if ($in_top) { + # parsing the top node + if ($tag eq 'node' || + ($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/)) + { + # no more in top + $in_top = 0; + push(@lines, $TOPEND); + } + } + 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'; + &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 + 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; + $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') { + if ($in_top) + { + $in_top = 0; + 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) { + $file = LocateIncludeFile($1); + if ($file && -e $file) { + &open($file); + print "# including $file\n" if $T2H_VERBOSE; + } else { + 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') { + unless ($T2H_SHOW_MENU) { + &skip_until($tag); + next; + } + &html_push_if($tag); + push(@lines, &html_debug('', __LINE__)); + } elsif ($format_map{$tag}) { + $in_pre = 1 if $format_map{$tag} eq 'PRE'; + &html_push_if($format_map{$tag}); + push(@lines, &html_debug('', __LINE__)); + $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ; +# 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; + } + 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') { + # anorland@hem2.passagen.se + # if (/^\s*\@(|f|v|multi)table\s+\@(\w+)/) { + if (/^\s*\@(|f|v|multi)table\s+\@(\w+)|(\{[^\}]*\})/) { + $in_table = $2; + unshift(@tables, join($;, $table_type, $in_table)); + if ($table_type eq "multi") { + # don't use borders -- gets confused by empty cells + push(@lines, &debug("<TABLE>\n", __LINE__)); + &html_push_if('TABLE'); + } else { + push(@lines, &debug("<DL COMPACT>\n", __LINE__)); + &html_push_if('DL'); + } + push(@lines, &html_debug('', __LINE__)); + } else { + warn "$ERROR Bad table line: $_"; + } + next; + } + 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; + } + 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; + } 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; + $sec2node{$name} = $setref; + $node2href{$setref} = "$docu_doc#$docid"; + } else { + warn "$ERROR Bad setref line: $_"; + } + next; + } elsif ($tag eq 'lowersections') { + local ($sec, $level); + while (($sec, $level) = each %sec2level) { + $sec2level{$sec} = $level + 1; + } + next; + } 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}; + 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; + } + 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" + if $T2H_DEBUG & $DEBUG_DEF; + $type .= ':'; # it's nicer like this + 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') { + EnterIndexEntry('f', $name, $docu_doc, $section, \@lines); +# unshift(@input_spool, "\@findex $name\n"); + } elsif ($tag eq 'defop') { + 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') { + EnterIndexEntry('v', $name, $docu_doc, $section, \@lines); +# unshift(@input_spool, "\@vindex $name\n"); + } else { + 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' ; + &html_pop_if('P'); + &html_pop_if('LI'); + &html_pop_if(); + push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__)); + 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__)); + } elsif ($end_tag =~ /^(|f|v|multi)table$/) { + unless (@tables) { + warn "$ERROR \@end $end_tag without \@*table\n"; + next; + } + &html_pop_if('P'); + ($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 + } + next; + } + ############################################################# + # 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) { + if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) { + if (/^\@$tag\s+(.+)$/) { + $name = $1; + $name = &normalise_node($name); + $level = $sec2level{$tag}; + # check for index + $first_index_chapter = $node + 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; + } + if (defined($toplevel)) + { + push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND); + } + else + { + # first time we see a "section" + unless ($level == 1) + { + warn "$WARN The first section found is not of level 1: $_"; + } + $toplevel = $level; + } + 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) { + $curlevel++; + push(@toc_lines, "<UL>\n"); + } + while ($level < $curlevel) { + $curlevel--; + push(@toc_lines, "</UL>\n"); + } + $_ = &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 + $value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o; + delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o; + # store things + $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 + 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" + if $T2H_DEBUG & $DEBUG_BIB; + $what = &t2h_anchor($id, '', $what); + } + } 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" + 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"); + } + } 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'; + } + push(@lines, &html_debug('', __LINE__)); + if ($deferred_ref) { + push(@lines, &debug("$deferred_ref\n", __LINE__)); + $deferred_ref = ''; + } + next; + } elsif (/^\@tab\s+(.*)$/) { + push(@lines, "<TD>$1</TD>\n"); + next; + } + } + } + # paragraph separator + if ($_ eq "\n" && ! $in_pre) { + next if $#lines >= 0 && $lines[$#lines] eq "\n"; + if ($html_element eq 'P') { + push (@lines, &debug("</P><P>\n", __LINE__)); + } +# 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 + 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"); +} + +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: </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 \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 + # + if (/^\@menu\b/) + { + $in_menu = 1; + $in_menu_listing = 1; + push(@lines2, &debug("<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> \n", __LINE__)); + next; + } + 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__)); + } + # should be like verbatim -- preseve spaces, etc + s/ /\ /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__)); + } + # look for continuation + while ($lines[0] =~ /^\s+\w+/) + { + $descr .= shift(@lines); + } + &menu_entry($node, $name, $descr); + } + next; + } + # + # printindex + # + PrintIndex(\@lines2, $2, $1), next + if (/^<!--::(.*)::-->\@printindex\s+(\w+)/); + # + # simple style substitutions + # + $_ = &substitute_style($_); + # + # xref + # + 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') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} "; + } elsif ($type eq 'px') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} "; + } elsif ($type eq 'info') { + $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 + $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]; + $_ = "${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"; + } 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"; + } + } + + # 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>/) { + $done .= $pre . &t2h_anchor('', $href, $what); + } else { + $done .= "$pre$what"; + } + $_ = $post; + } + $_ = $done . $_; + } + 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>/) { + $done .= $pre . &t2h_anchor('', $href, $what); + } else { + $done .= "$pre$what"; + } + $_ = $post; + } + $_ = $done . $_; + } + } + # otherwise + push(@lines2, $_); +} +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, $_); +} +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> + +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)"; + push(@foot_lines, "<H3>" . &t2h_anchor($footid, "$d#$docid", $foot) . "</H3>\n"); + $text = "<P>$text" unless $text =~ /^\s*<P>/; + push(@foot_lines, "$text\n"); + $_ = $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, $_); +} + +print "# end of pass 4\n" if $T2H_VERBOSE; + +#+++############################################################################ +# # +# Pass 5: print things # +# # +#---############################################################################ + +$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} = $_; +} + +# 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"; + + &$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 +# +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); +} + + +############################################################################# +# print Top +# +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 +# +$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; + } + } + $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}; + } + $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; +} + +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 # +# # +#---############################################################################ + +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) = @_; + my $ret; + + $level--; # here we start at 0 + 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); + } + $ret = join('.', @appendix_sec_num[0..$level]); + } else { + # normal style + if (defined(@normal_sec_num)) + { + &incr_sec_num($level, @normal_sec_num); + } + else + { + @normal_sec_num = (1, 0, 0, 0); + } + $ret = join('.', @normal_sec_num[0..$level]); + } + + $ret .= "." if $level == 0; + return $ret; +} + +sub incr_sec_num { + local($level, $l); + $level = shift(@_); + $_[$level]++; + foreach $l ($level+1 .. 3) { + $_[$l] = 0; + } +} + +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{$&}++; + $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'}++; + $context{'e-mail address'} .= "> $_" if $T2H_VERBOSE; + } else { + $seen{$match}++; + $context{$match} .= "> $_" if $T2H_VERBOSE; + } + $match =~ s/^\@/X/; + $_ = "$before$match$after"; + redo; + } + } + + foreach (sort(keys(%seen))) { + 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]; +} + +# 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) = @_; + 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") + if $T2H_DEBUG & $DEBUG_HTML; + return($what); +} + +sub SimpleTexi2Html +{ + local $_ = $_[0]; + &protect_texi; + &protect_html; + $_ = substitute_style($_); + $_[0] = $_; +} + +sub normalise_node { + local $_ = $_[0]; + s/\s+/ /g; + s/ $//; + s/^ //; + &protect_texi; + &protect_html; + $_ = substitute_style($_); + $_[0] = $_; +} + +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); + } + + 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) + } + push(@lines2,&debug('<TR><TD ALIGN="left" VALIGN="TOP">' . + &t2h_anchor('', $href, $entry) . + '</TD><TD> </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]" } + +sub do_email { + local($addr, $text) = split(/,\s*/, $_[0]); + + $text = $addr unless $text; + &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"; +} + +sub do_math +{ + return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H); + return "<EM>".$text."</EM>"; +} + +sub do_uref { + local($url, $text, $only_text) = split(/,\s*/, $_[0]); + + $text = $only_text if $only_text; + $text = $url unless $text; + &t2h_anchor('', $url, $text); +} + +sub do_url { &t2h_anchor('', $_[0], $_[0]) } + +sub do_acronym +{ + return '<FONT SIZE="-1">' . $_[0] . '</FONT>'; +} + +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]<" if $_[1] eq 'v'; + return "&$_[0]cedil;" if $_[1] eq ','; + return "$_[0]" if $_[1] eq 'dotless'; + return undef; +} + +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 = $'; + $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($_) = @_; + 1 while(s/\@\w+{([^\{\}]+)}/$1/g); + return($_); +} + +sub remove_things +{ + local ($_) = @_; + s|\@(\w+)\{\}|$1|g; + return $_; +} + +sub substitute_style { + local($_) = @_; + local($changed, $done, $style, $text); + + &simple_substitutions; + $changed = 1; + while ($changed) { + $changed = 0; + $done = ''; + while (/\@(\w+){([^\{\}]+)}/ || /\@(,){([^\{\}]+)}/) { + $text = &apply_style($1, $2); + if ($text) { + $_ = "$`$text$'"; + $changed = 1; + } else { + $done .= "$`\@$1"; + $_ = "{$2}$'"; + } + } + $_ = $done . $_; + } + return($_); +} + +sub t2h_anchor { + local($name, $href, $text, $newline, $extra_attribs) = @_; + local($result); + + $result = "<A"; + $result .= " NAME=\"$name\"" if $name; + 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); + + @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; + # obachman: Let's do it as the Americans do + return("$MoY[$mon], $mday $year"); +} + +sub doc_href { + local($num) = @_; + + return("${docu_name}_$num.$docu_ext"); +} + +sub sec_href +{ + return $node2href{$sec2node{$_[0]}}; +} + +sub next_doc { + $docu_doc = &doc_href(++$doc_num); +} + +sub t2h_print_lines { + my ($fh, $lines) = @_; + local($_); + $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 $_; + $cnt += split(/\W*\s+\W*/); + } + 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; + # restore anything in quotes + # this fixes my problem where I had: + # < IMG SRC="leftarrow.gif" ALT="<--" > but what if I wanted < 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; +} + +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); +} + +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 ############ +.so /usr/local/man/man1/texi2html.1 |