#! @PERL@ --
# perl
'di ';
'ig 00 ';
#+##############################################################################
#
# texi2html: Parse and transform Texinfo documents
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
# 2009, 2010, 2011 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 .
#
#
# Some error messages come from texinfo (makeinfo), so copyright holder
# is the FSF or the individual who wrote them. All come from before the
# switch of texinfo to GPLv3+.
#
# Originally written by Lionel Cons.
#
#-##############################################################################
# The man page for this program is included at the end of this file and can be
# viewed using the command 'nroff -man texi2html'.
# for POSIX::setlocale and File::Spec
require 5.00405;
# Perl pragma to restrict unsafe constructs
use strict;
# used in case of tests, to revert to "C" locale.
use POSIX qw(setlocale LC_ALL LC_CTYPE);
# used to obtain the name of the current working directory
use Cwd;
# Used to find the parent directory of this script.
use File::Basename;
# used to find a relative path back to the current working directory
use File::Spec;
# to determine the path separator and null file
use Config;
#use encoding::warnings;
# for translations
#use encoding 'utf8';
#use utf8;
#
# According to
# larry.jones@sdrc.com (Larry Jones)
# this pragma is not present in perl5.004_02:
#
# Perl pragma to control optional warnings
# use warnings;
# determine the path separators
my $path_separator = $Config{'path_sep'};
$path_separator = ':' if (!defined($path_separator));
my $quoted_path_separator = quotemeta($path_separator);
#++##########################################################################
#
# NOTE FOR DEBUGGING THIS SCRIPT:
# You can run 'perl -x texi2html.pl' directly, provided you have the script
# in the same directory with, or the environment variable T2H_HOME set to
# the directory containing, the texi2html.pm, T2h_i18n.pm, translations.pl,
# l2h.init, & T2h_l2h.pm files. Ditto makeinfo.pl, if you make it a
# symlink to texi2html.pl.
#
#--##########################################################################
my $T2H_HOME = defined $ENV{T2H_HOME} ? $ENV{T2H_HOME} : dirname $0;
if ($0 =~ /\.pl$/)
{
# Issue a warning in debugging mode if $T2H_HOME is set but isn't
# accessible.
if (!-e $T2H_HOME)
{ warn "T2H_HOME ($T2H_HOME) does not exist."; }
elsif (!-d $T2H_HOME)
{ warn "T2H_HOME ($T2H_HOME) is not a directory."; }
elsif (!-x $T2H_HOME)
{ warn "T2H_HOME ($T2H_HOME) is not accessible."; }
}
# CVS version:
# $Id: texi2html.pl 5307 2013-08-12 18:41:40Z pertusus $
# Homepage:
my $T2H_HOMEPAGE = "http://www.gnu.org/software/texinfo/";
# Version: set in configure.in
my $THISVERSION = '@PACKAGE_VERSION@';
my $THISPROG = '@PACKAGE_NAME@';
my $THISPROG_THISVERSION = "$THISPROG $THISVERSION"; # program name and version
#+++########################################################################
# #
# Paths and file names #
# #
#---########################################################################
# set by configure, prefix for the sysconfdir and so on
my $prefix = '@prefix@';
my $datarootdir;# = '@datarootdir@';
my $sysconfdir;
my $pkgdatadir;
my $datadir;
# We need to eval as $prefix has to be expanded. However when we haven't
# run configure @sysconfdir will be expanded as an array, thus we verify
# whether configure was run or not
if ('@sysconfdir@' ne '@' . 'sysconfdir@')
{
$sysconfdir = eval '"@sysconfdir@"';
}
else
{
$sysconfdir = "/usr/local/etc";
}
if ('@datarootdir@' ne '@' . 'datarootdir@')
{
$datarootdir = eval '"@datarootdir@"';
}
else
{
$datarootdir = "/usr/local/share";
}
if ('@datadir@' ne '@' . 'datadir@')
{
$pkgdatadir = eval '"@datadir@/@PACKAGE@"';
$datadir = eval '"@datadir@"';
}
else
{
$pkgdatadir = "/usr/local/share/texi2html";
$datadir = "/usr/local/share";
}
my $target_prefix = "t_h";
#+++########################################################################
# #
# Constants #
# #
#---########################################################################
my $DEBUG_MENU = 1;
my $DEBUG_INDEX = 2;
my $DEBUG_TEXI = 4;
my $DEBUG_MACROS = 8;
my $DEBUG_FORMATS = 16;
my $DEBUG_ELEMENTS = 32;
my $DEBUG_USER = 64;
my $DEBUG_L2H = 128;
my $VARRE = '[\w\-]+'; # RE for a variable name
my $MAX_LEVEL = 4;
my $MIN_LEVEL = 1;
# all settable variables that are reset between every pass
# FIXME is it really right?
# Yes, for documentlanguage, clickstyle, allowcodebreaks.
# Maybe not for frenchspacing?
my @document_settable_at_commands =
('everyheading', 'everyfooting', 'evenheading',
'evenfooting', 'oddheading', 'oddfooting', 'headings',
'allowcodebreaks', 'frenchspacing', 'exampleindent',
'firstparagraphindent', 'paragraphindent', 'clickstyle',
'documentlanguage');
# those are not reset such that they are available between passes.
my @document_global_at_commands = ('contents', 'shortcontents',
'setcontentsaftertitlepage', 'setshortcontentsaftertitlepage',
'footnotestyle', 'novalidate', 'kbdinputstyle', 'documentencoding',
'setfilename', 'today', 'documentdescription',
# the following are not set to anything in the default
# case, and currently not used anywhere
'everyheadingmarks','everyfootingmarks',
'evenheadingmarks','oddheadingmarks','evenfootingmarks','oddfootingmarks',
'fonttextsize', 'pagesizes', 'setchapternewpage'
);
my @command_line_settables = ('FILLCOLUMN', 'SPLIT', 'SPLIT_SIZE',
'HEADERS',
'MACRO_EXPAND', 'NUMBER_SECTIONS',
'NUMBER_FOOTNOTES', 'NODE_FILES',
'NO_WARN', 'VERBOSE',
'TRANSLITERATE_FILE_NAMES', 'ERROR_LIMIT', 'ENABLE_ENCODING',
'FORCE', 'INTERNAL_LINKS', 'OUTFILE', 'SUBDIR', 'OUT',
'BATCH', 'SILENT'
);
# FIXME TOP_HEADING_AT_BEGINNING seems to be a no-op
my @variable_settables = (
'DEBUG', 'FRAMES', 'FRAMESET_DOCTYPE', 'DOCTYPE', 'TEST', 'DUMP_TEXI',
'TOP_FILE', 'TOC_FILE', 'SHOW_MENU', 'USE_NODES', 'TOC_LINKS', 'SHORTEXTN',
'PREFIX', 'SHORT_REF', 'IDX_SUMMARY', 'DEF_TABLE', 'L2H', 'MONOLITHIC',
'L2H_L2H', 'L2H_SKIP', 'L2H_TMP', 'L2H_FILE', 'L2H_CLEAN',
'L2H_HTML_VERSION', 'IGNORE_PREAMBLE_TEXT', 'EXTERNAL_DIR', 'USE_ISO',
'SPLIT_INDEX', 'IN_ENCODING', 'USE_NLS',
'VERTICAL_HEAD_NAVIGATION', 'INLINE_CONTENTS', 'NODE_FILE_EXTENSION',
'NO_CSS', 'INLINE_CSS_STYLE', 'USE_SECTIONS', 'USE_TITLEPAGE_FOR_TITLE',
'SIMPLE_MENU', 'EXTENSION', 'INLINE_INSERTCOPYING', 'USE_NUMERIC_ENTITY',
'I18N_PERL_HASH', 'ENABLE_ENCODING_USE_ENTITY', 'ICONS', 'USE_UNICODE',
'USE_UNIDECODE', 'DATE_IN_HEADER', 'OPEN_QUOTE_SYMBOL',
'CLOSE_QUOTE_SYMBOL', 'TOP_NODE_UP', 'TOP_NODE_FILE',
'TOP_NODE_FILE_TARGET', 'SHOW_TITLE', 'WORDS_IN_PAGE',
'HEADER_IN_TABLE', 'USE_ACCESSKEY', 'USE_REL_REV', 'USE_LINKS',
'OVERVIEW_LINK_TO_TOC', 'AVOID_MENU_REDUNDANCY', 'NODE_NAME_IN_MENU',
'NODE_NAME_IN_INDEX', 'USE_SETFILENAME', 'USE_SETFILENAME_EXTENSION',
'COMPLEX_FORMAT_IN_TABLE',
'USE_UP_FOR_ADJACENT_NODES', 'TOP_HEADING_AT_BEGINNING',
'SEPARATE_DESCRIPTION', 'IGNORE_BEFORE_SETFILENAME',
'COMPLETE_IMAGE_PATHS', 'USE_NODE_TARGET', 'NEW_CROSSREF_STYLE',
'PROGRAM_NAME_IN_FOOTER', 'NODE_FILENAMES', 'DEFAULT_ENCODING',
'OUT_ENCODING', 'ENCODING_NAME', 'EXTERNAL_CROSSREF_SPLIT', 'BODYTEXT',
'CSS_LINES', 'RENAMED_NODES_REDIRECTIONS', 'RENAMED_NODES_FILE',
'TEXI2DVI', 'DO_ABOUT');
foreach my $var (@document_settable_at_commands, @command_line_settables,
@document_global_at_commands, @variable_settables)
{
$Texi2HTML::GLOBAL{'variable_levels'}->{$var} = 10;
}
#+++########################################################################
# #
# Command name and default format #
# #
#---########################################################################
my $real_command_name = $0;
$real_command_name =~ s/.*\///;
$real_command_name =~ s/\.pl$//;
my %command_format = (
'texi2html' => 'html',
'makeinfo' => 'info',
'texi2any' => 'raw-text',
);
# Config files
my $i18n_dir = 'i18n'; # name of the directory containing the per language files
my $conf_file_name = 'Config' ;
my $texinfo_htmlxref = 'htmlxref.cnf';
# directories for texinfo configuration files
my @language_config_dirs = ('./.texinfo');
push @language_config_dirs, "$ENV{'HOME'}/.texinfo" if (defined($ENV{'HOME'}));
push @language_config_dirs, "$sysconfdir/texinfo" if (defined($sysconfdir));
push @language_config_dirs, "$datadir/texinfo" if (defined($datadir));
my @texinfo_config_dirs = ('.', @language_config_dirs);
my @program_config_dirs;
my @program_init_dirs;
# program name dependent initializations: config directories and default
# format.
sub set_config_init_dirs_output($)
{
my $program_name = shift;
if (!defined($command_format{$program_name}))
{
# user can make any link to set $0, or use --program with an unknown name.
# In that case the default is to use texi2any
$program_name = 'texi2any';
}
my $default_output_format = $command_format{$program_name};
# directories for config files
@program_config_dirs = ('.', "./.$program_name");
push @program_config_dirs, "$ENV{'HOME'}/.$program_name" if (defined($ENV{'HOME'}));
push @program_config_dirs, "$sysconfdir/$program_name" if (defined($sysconfdir));
push @program_config_dirs, "$datadir/$program_name" if (defined($datadir));
# directories for init files
@program_init_dirs = @program_config_dirs;
# common directories for all command names
foreach my $texinfo_config_dir (@language_config_dirs)
{
push @program_init_dirs, "${texinfo_config_dir}/init";
}
$Texi2HTML::Config::DEFAULT_OUTPUT_FORMAT = $default_output_format;
$Texi2HTML::Config::COMMAND_NAME = $program_name;
Texi2HTML::Config::t2h_default_load_format($default_output_format, 0);
}
#+++###########################################################################
# #
# Initialization #
# Some declarations, some functions that are GPL and therefore cannot be in #
# texi2html.pm, some functions that are not to be customized. #
# Pasted content of File $(srcdir)/texi2html.pm: Default initializations #
# #
#---###########################################################################
{
package Texi2HTML::Config;
use Config;
# customization options variables
use vars qw(
@EXPAND
@INCLUDE_DIRS
@PREPEND_DIRS
@CONF_DIRS
@CSS_FILES
@CSS_REFS
$DEFAULT_OUTPUT_FORMAT
$OUTPUT_FORMAT
$COMMAND_NAME
@COMMANDS
);
# customization variables
use vars qw(
$CAPTION_STYLE
$MENU_PRE_STYLE
$MENU_PRE_COMPLEX_FORMAT
$EXAMPLE_INDENT_CELL
$SMALL_EXAMPLE_INDENT_CELL
$SMALL_FONT_SIZE
$SMALL_RULE
$DEFAULT_RULE
$MIDDLE_RULE
$BIG_RULE
$TOP_HEADING
$INDEX_CHAPTER
$AFTER_BODY_OPEN
$PRE_BODY_CLOSE
$EXTRA_HEAD
$UNNUMBERED_SYMBOL_IN_MENU
$MENU_SYMBOL
$MENU_ENTRY_COLON
$INDEX_ENTRY_COLON
$NO_NUMBER_FOOTNOTE_SYMBOL
$NO_BULLET_LIST_STYLE
$NO_BULLET_LIST_ATTRIBUTE
$NO_BULLET_LIST_CLASS
$STDIN_DOCU_NAME
$STDOUT_DOCU_NAME
$BEFORE_OVERVIEW
$AFTER_OVERVIEW
$BEFORE_TOC_LINES
$AFTER_TOC_LINES
%ACTIVE_ICONS
%NAVIGATION_TEXT
%PASSIVE_ICONS
%BUTTONS_NAME
%BUTTONS_GOTO
%BUTTONS_EXAMPLE
%BUTTONS_ACCESSKEY
%BUTTONS_REL
%BUTTONS_TEXT
@T2H_FORMAT_EXPAND
@CHAPTER_BUTTONS
@MISC_BUTTONS
@SECTION_BUTTONS
@SECTION_FOOTER_BUTTONS
@NODE_FOOTER_BUTTONS
@TOP_BUTTONS
@LINKS_BUTTONS
@IMAGE_EXTENSIONS
@INPUT_FILE_SUFFIXES
@TEXI2DVI_ARGUMENTS
);
# I18n
use vars qw(
$I
$LANGUAGES
);
# customizable subroutines references
use vars qw(
$print_section
$one_section
$end_section
$print_Top_header
$print_Top_footer
$print_Top
$print_Toc
$print_Overview
$print_Footnotes
$print_About
$print_misc_header
$print_misc_footer
$print_misc
$print_section_header
$print_section_footer
$print_chapter_header
$print_chapter_footer
$print_element_header
$print_page_head
$print_page_foot
$print_head_navigation
$print_foot_navigation
$print_title
$button_icon_img
$button_formatting
$print_navigation
$about_body
$print_frame
$print_toc_frame
$toc_body
$contents
$internal_links
$shortcontents
$titlepage
$insertcopying
$css_lines
$print_redirection_page
$translate_names
$init_out
$finish_out
$node_file_name
$element_file_name
$node_target_name
$element_target_name
$placed_target_file_name
$inline_contents
$program_string
$preserve_misc_command
$misc_command_line
$misc_command_line_texi
$protect_text
$anchor
$anchor_label
$element_label
$misc_element_label
$def_item
$def
$menu
$menu_command
$menu_link
$menu_description
$menu_comment
$simple_menu_link
$ref_beginning
$info_ref
$book_ref
$external_href
$external_ref
$internal_ref
$table_item
$table_line
$row
$cell
$list_item
$comment
$def_line
$def_line_no_texi
$heading_no_texi
$raw
$raw_no_texi
$heading
$element_heading
$heading_text
$heading_text_preformatted
$paragraph
$preformatted
$empty_preformatted
$foot_line_and_ref
$foot_section
$image
$image_files
$index_entry_label
$index_entry
$index_entry_command
$index_letter
$print_index
$printindex
$index_summary
$summary_letter
$complex_format
$cartouche
$sp
$definition_category
$definition_index_entry
$table_list
$copying_comment
$documentdescription
$index_summary_file_entry
$index_summary_file_end
$index_summary_file_begin
$style
$line_command
$format
$normal_text
$empty_line
$unknown
$unknown_style
$float
$caption_shortcaption
$caption_shortcaption_command
$listoffloats
$listoffloats_entry
$listoffloats_caption
$listoffloats_float_style
$listoffloats_style
$acronym_like
$quotation
$quotation_prepend_text
$paragraph_style_command
$heading_texi
$index_element_heading_texi
$format_list_item_texi
$begin_format_texi
$begin_style_texi
$begin_paragraph_texi
$tab_item_texi
$footnote_texi
$colon_command
$simple_command
$thing_command
$begin_special_region
$end_special_region
$PRE_ABOUT
$AFTER_ABOUT
);
# hash which entries might be redefined by the user
use vars qw(
$complex_format_map
%complex_format_map
%accent_map
%def_map
%format_map
%simple_map
%simple_map_pre
%simple_map_texi
%simple_map_math
%style_map
%style_map_pre
%style_map_math
%style_map_texi
%simple_format_simple_map_texi
%simple_format_style_map_texi
%simple_format_texi_map
%line_command_map
%command_type
%paragraph_style
%stop_paragraph_command
%format_code_style
%region_formats_kept
%texi_formats_map
%things_map
%pre_map
%math_map
%texi_map
%sorting_things_map
%unicode_map
%unicode_diacritical
%transliterate_map
%transliterate_accent_map
%no_transliterate_map
%ascii_character_map
%default_simple_map
%default_things_map
%default_texi_map
%default_style_map
%default_style_map_pre
%default_style_map_texi
%default_simple_format_style_map_texi
%numeric_entity_map
%perl_charset_to_html
%misc_pages_targets
%misc_command
%no_paragraph_commands
%css_map
%format_in_paragraph
%special_list_commands
%accent_letters
%unicode_accents
%special_accents
%inter_item_commands
$def_always_delimiters
$def_in_type_delimiters
$def_argument_separator_delimiters
$warn_var_character_quoted
%colon_command_punctuation_characters
$punctuation_characters
$after_punctuation_characters
@command_handler_setup
@command_handler_init
@command_handler_names
@command_handler_process
@command_handler_output
@command_handler_finish
%command_handler
%special_style
%null_device_file
%language_codes
%region_codes
%deprecated_commands
%output_format_names
%canonical_texinfo_encodings
@text_substitutions_normal
@text_substitutions_texi
@text_substitutions_simple_format
@text_substitutions_pre
%htmlxref_entries
%renamed_nodes
%texi2dvi_formats
);
# deprecated
use vars qw(
$address
%iso_symbols
%simple_map_pre_math
%simple_map_texi_math
);
# subject to change
use vars qw(
%makeinfo_encoding_to_map
%makeinfo_unicode_to_eight_bit
%eight_bit_to_unicode
%t2h_encoding_aliases
);
# FIXME i18n ?
%output_format_names = (
'info' => 'Info',
'html' => 'HTML',
'docbook' => 'Docbook XML',
'xml' => 'Texinfo XML',
'plaintext' => 'plain text',
'raw-text' => 'raw text',
'dvi' => 'DVI',
'pdf' => 'Pdf',
'ps' => 'Postscript'
);
sub load($)
{
my $file = shift;
# If required like other init files, the functions would be redefined
# and the format dependent stuff wouldn't be loaded. Having the
# formats loaded could be worked around, for example there could be
# a variable that, and if the variable is defined a function reference
# should be called right after the require. There is no real
# workaround for having the function redefined, though.
foreach my $output_format (keys(%output_format_names))
{
if ($file =~ /\/$output_format\.pm$/)
{
t2h_default_load_format($output_format, 1);
return 1;
}
}
eval { require($file) ;};
if ($@ ne '')
{
print STDERR "error loading $file: $@\n";
return 0;
}
return 1;
}
# var: variable name
# value: value to set. May be undef.
# level: priority level. If undef, it means reusing the current level
# not_global: if set the change should only concern the current document
sub set_variable($$$;$)
{
my $var = shift;
my $value = shift;
my $level = shift;
my $not_global = shift;
$not_global = 0 if (!$not_global);
my $ref_level = $Texi2HTML::GLOBAL{'variable_levels'}->{$var};
if (!defined($ref_level))
{
# issue with Locale::Messages::dpgettext not already defined
#main::msg_warn(sprintf('Unknown variable %s', $var));
warn (sprintf('Unknown variable %s', $var));
return 0;
}
#print STDERR "$var(".(main::var_to_str($level))."): ".main::var_to_str($value)." not_global $not_global\n";
if (!defined($level) or $level <= $ref_level)
{
$Texi2HTML::THISDOC{'variable_levels'}->{$var} = $level if (defined($level));
if ($not_global)
{
$Texi2HTML::THISDOC{'variables'}->{$var} = $value;
}
else
{
$Texi2HTML::GLOBAL{'variables'}->{$var} = $value;
$Texi2HTML::GLOBAL{'variable_levels'}->{$var} = $level if (defined($level));
}
return 1;
}
return 0;
}
# var: variable name
# level: priority level. If undef, it means reusing the current level
# not_global: only for the current document
sub unset_variable($$;$)
{
my $var = shift;
my $level = shift;
my $not_global = shift;
$not_global = 0 if (!$not_global);
my $ref_level = $Texi2HTML::GLOBAL{'variable_levels'}->{$var};
if (!defined($ref_level))
{
# issue with Locale::Messages::dpgettext not already defined
#main::msg_warn(sprintf('Unknown variable %s', $var));
warn (sprintf('Unknown variable %s', $var));
return 0;
}
#print STDERR "$var(".(main::var_to_str($level))."): ".main::var_to_str($value)." not_global $not_global\n";
if (!defined($level) or $level <= $ref_level)
{
$Texi2HTML::THISDOC{'variable_levels'}->{$var} = $level if (defined($level));
if ($not_global)
{
delete($Texi2HTML::THISDOC{'variables'}->{$var});
}
else
{
delete($Texi2HTML::GLOBAL{'variables'}->{$var});
$Texi2HTML::GLOBAL{'variable_levels'}->{$var} = $level if (defined($level));
}
return 1;
}
return 0;
}
sub set_from_init_file ($$)
{
my $var = shift;
my $value = shift;
my $level = 3;
return set_variable($var, $value, $level);
}
sub set_default ($$)
{
my $var = shift;
my $value = shift;
my $level = 7;
return set_variable($var, $value, $level);
}
sub set_from_document($$)
{
my $var = shift;
my $value = shift;
my $level = 5;
return set_variable($var, $value, $level, 1);
}
sub get_conf($)
{
my $name = shift;
if (defined($Texi2HTML::GLOBAL{'variable_levels'}->{$name}))
{ # notice the exists, and not defined. Such that undef is a
# value like any other possible value.
if (exists($Texi2HTML::THISDOC{'variables'}->{$name}))
{
return $Texi2HTML::THISDOC{'variables'}->{$name};
}
else
{ # may be undef
return $Texi2HTML::GLOBAL{'variables'}->{$name};
}
}
else
{ # no i18n since it may not be set up already (?)
warn (sprintf('get_conf: Unknown variable %s', $name));
return undef;
}
}
# manage expanded sections
sub set_expansion($$)
{
my $region = shift;
my $set = shift;
$set = 1 if (!defined($set));
if ($set)
{
push (@EXPAND, $region) unless (grep {$_ eq $region} @EXPAND);
}
else
{
@EXPAND = grep {$_ ne $region} @EXPAND;
@T2H_FORMAT_EXPAND = grep {$_ ne $region} @T2H_FORMAT_EXPAND;
}
}
# needed in this namespace for translations
$I = \&Texi2HTML::I18n::get_string;
sub gdt($;$$)
{
return &main::gdt(@_);
}
sub __($)
{
return &main::__(@_);
}
sub __p($$)
{
return &main::__p(@_);
}
sub N__($)
{
return $_[0];
}
#
# Function refs covered by the GPL as part of the texi2html.pl original
# code. As such they cannot appear in texi2html.pm which is public
# domain (at least the things coded by me, and, if I'm not wrong also the
# things coded by Olaf -- Pat).
#
sub HTML_DEFAULT_shortcontents($$)
{
my $elements_list = shift;
my $stoc_file = shift;
return unless (get_conf('shortcontents') or get_conf('FRAMES'));
my $ul_class = '';
$ul_class = $NO_BULLET_LIST_CLASS if (get_conf('NUMBER_SECTIONS'));
my @result = ();
foreach my $element (@$elements_list)
{
next if ($element->{'tag'} eq 'top' or $element->{'toc_level'} != 1);
my $dest_for_stoc = $element->{'file'};
my $dest_target_for_stoc = $element->{'target'};
if (get_conf('OVERVIEW_LINK_TO_TOC'))
{
$dest_for_stoc = $Texi2HTML::THISDOC{'toc_file'};
$dest_target_for_stoc = $element->{'tocid'};
}
$dest_for_stoc = '' if ($dest_for_stoc eq $stoc_file);
my $text = $element->{'text'};
my $stoc_entry = "
" . &$anchor ($element->{'stocid'}, "$dest_for_stoc#$dest_target_for_stoc",$text);
push(@result, $stoc_entry. "\n");
}
if (@result)
{
unshift @result, html_default_attribute_class('ul', $ul_class) .">\n";
push @result, "\n";
unshift @result, $BEFORE_OVERVIEW;
push @result, $AFTER_OVERVIEW;
}
return \@result;
}
sub HTML_DEFAULT_contents($$)
{
my $elements_list = shift;
my $toc_file = shift;
return unless (get_conf('contents'));
my $current_level = 0;
my $ul_class = '';
$ul_class = $NO_BULLET_LIST_CLASS if (get_conf('NUMBER_SECTIONS'));
my @result = ();
foreach my $element (@$elements_list)
{
next if ($element->{'tag'} eq 'top');
my $ind = ' ' x $current_level;
my $level = $element->{'toc_level'};
print STDERR "Bug no toc_level for ($element) $element->{'texi'}\n" if (!defined ($level));
if ($level > $current_level)
{
while ($level > $current_level)
{
$current_level++;
my $ln = "\n$ind".html_default_attribute_class('ul', $ul_class).">\n";
$ind = ' ' x $current_level;
push(@result, $ln);
}
}
elsif ($level < $current_level)
{
while ($level < $current_level)
{
$current_level--;
$ind = ' ' x $current_level;
my $line = "\n$ind";
$line .= "" if ($level == $current_level);
push(@result, "$line\n");
}
}
else
{
push(@result, "\n");
}
my $dest_for_toc = $element->{'file'};
my $dest_for_stoc = $element->{'file'};
my $dest_target_for_stoc = $element->{'target'};
$dest_for_toc = '' if ($dest_for_toc eq $toc_file);
my $text = $element->{'text'};
my $toc_entry = "" . &$anchor ($element->{'tocid'}, "$dest_for_toc#$element->{'target'}",$text);
push (@result, $ind . $toc_entry);
}
while (0 < $current_level)
{
$current_level--;
my $ind = ' ' x $current_level;
push(@result, "\n$ind\n");
}
if (@result)
{
unshift @result, $BEFORE_TOC_LINES;
push @result, $AFTER_TOC_LINES;
}
return \@result;
}
#$toc_body = \&T2H_GPL_toc_body;
#$style = \&T2H_GPL_style;
#$format = \&T2H_GPL_format;
#$printindex = \&t2h_GPL_default_printindex;
#$summary_letter = \&t2h_default_summary_letter;
sub T2H_GPL_style($$$$$$$$$$)
{ # known style
my $style = shift;
my $command = shift;
my $text = shift;
my $args = shift;
my $no_close = shift;
my $no_open = shift;
my $line_nr = shift;
my $state = shift;
my $style_stack = shift;
my $kept_line_nrs = shift;
my $do_quotes = 0;
my $use_attribute = 0;
my $use_begin_end = 0;
my $inline_attribute = 0;
if (ref($style) eq 'HASH')
{
#print STDERR "GPL_STYLE $command ($style)\n";
#print STDERR " @$args\n";
if (ref($style->{'args'}) ne 'ARRAY')
{
print STDERR "BUG: args not an array for command `$command'\n";
}
$do_quotes = $style->{'quote'};
if (defined($style->{'function'}))
{
$text = &{$style->{'function'}}($command, $args, $style_stack, $state, $line_nr, $kept_line_nrs);
}
elsif (@{$style->{'args'}} == 1)
{
if (defined($style->{'inline_attribute'}))
{
$style = $style->{'inline_attribute'};
$use_attribute = 1;
$inline_attribute = 1;
}
elsif (defined($style->{'attribute'}))
{
$style = $style->{'attribute'};
$use_attribute = 1;
}
#$text = $args->[0];
}
}
else
{
if ($style =~ s/^\"//)
{ # add quotes
$do_quotes = 1;
}
if ($style =~ s/^\&//)
{ # custom
$style = 'Texi2HTML::Config::' . $style;
eval "\$text = &$style(\$text, \$command, \$style_stack)";
}
elsif ($style ne '')
{
$use_attribute = 1;
}
else
{ # no style
}
}
if ($use_attribute)
{
my ($attribute_text, $class);
($style, $class, $attribute_text) = html_default_parse_attribute ($style);
$text = html_default_attribute_class($style, $class) . "$attribute_text>" . "$text" if (!$no_open or $inline_attribute);
$text .= "$style>" if (!$no_close or $inline_attribute);
if ($do_quotes)
{
$text = get_conf('OPEN_QUOTE_SYMBOL') . "$text" if (!$no_open);
$text .= get_conf('CLOSE_QUOTE_SYMBOL') if (!$no_close);
}
}
if (ref($style) eq 'HASH')
{
if (defined($style->{'begin'}) and !$no_open)
{
$text = $style->{'begin'} . $text;
}
if (defined($style->{'end'}) and !$no_close)
{
$text = $text . $style->{'end'};
}
if (defined($style->{'inline_begin'}))
{
$text = $style->{'inline_begin'} . $text;
}
if (defined($style->{'inline_end'}))
{
$text = $text . $style->{'inline_end'};
}
}
if ($do_quotes and !$use_attribute)
{
$text = get_conf('OPEN_QUOTE_SYMBOL') . "$text" if (!$no_open);
$text .= get_conf('CLOSE_QUOTE_SYMBOL') if (!$no_close);
}
return $text;
}
sub T2H_GPL_format($$$)
{
my $tag = shift;
my $element = shift;
my $text = shift;
return '' if (!defined($element) or ($text !~ /\S/));
return $text if ($element eq '');
my $attribute_text = '';
if ($element =~ /^(\w+)(\s+.*)/)
{
$element = $1;
$attribute_text = $2;
}
return "<${element}$attribute_text>\n" . $text. "$element>\n";
}
# for each index holds the letters split as determined by SPLIT_INDEX.
my %t2h_default_index_letters_array;
# equivalent of doc_nr, but with files (and hence numbers) added when
# a split index leads to an additional element and a file is created.
my $t2h_default_file_number;
# this is an increasing number to construct the id for each newly
# created index element.
my $t2h_default_index_id_nr;
# this holds the file name associated with an element file, such
# as to follow the splitting coming from the main program, and also use
# the newly generated files.
my %t2h_default_seen_files;
# holds the elements and indices that are split to easily set the
# directions after they are done in the main program.
my $t2h_default_element_split_printindices;
# construct a hash of index names holding the letter grouped how they will
# be split.
sub t2h_default_init_split_indices()
{
push @command_handler_process, \&t2h_default_index_rearrange_directions;
%t2h_default_index_letters_array = ();
%t2h_default_seen_files = ();
$t2h_default_element_split_printindices = undef;
$t2h_default_index_id_nr = 0;
$t2h_default_file_number = 0;
foreach my $index_name(keys %{$Texi2HTML::THISDOC{'index_letters_array'}})
{
my $entries_count = 0;
my @letters = ();
foreach my $letter_entry (@{$Texi2HTML::THISDOC{'index_letters_array'}->{$index_name}})
{
push @letters, $letter_entry;
$entries_count += scalar(@{$letter_entry->{'entries'}});
# Don't split if document is not split
if (get_conf('SPLIT') and get_conf('SPLIT_INDEX') and $entries_count >= get_conf('SPLIT_INDEX'))
{
push @{$t2h_default_index_letters_array{$index_name}}, [ @letters ];
@letters = ();
$entries_count = 0;
}
}
push @{$t2h_default_index_letters_array{$index_name}}, [ @letters ] if (scalar(@letters));
}
}
sub t2h_default_associate_index_element($$$$)
{
my $element = shift;
my $is_top = shift;
my $docu_name = shift;
my $use_node_file = shift;
my $default_element_file = $element->{'file'};
# redo the file naming -- the doc_nr part -- in case new elements were
# inserted upon index split. But respect the default splitting to keep
# the elements that are associated with the same file in the same file,
# or the added file.
if (!$use_node_file or $t2h_default_seen_files{$default_element_file})
{
my $file;
if ($t2h_default_seen_files{$default_element_file})
{
$file = $t2h_default_seen_files{$default_element_file};
}
else
{
if ($is_top eq 'top')
{ # this is the element_top, so we keep docu_top as associated file.
# this, in fact, is not necessary since the element_top is never
# associated with another element, but who knows.
$t2h_default_seen_files{$default_element_file} = $default_element_file;
}
else
{
$file = "${docu_name}_$t2h_default_file_number";
$file .= '.' . get_conf('EXTENSION') if
(defined(get_conf('EXTENSION')));
$t2h_default_seen_files{$default_element_file} = $file;
}
$t2h_default_file_number++;
}
$element->{'file'} = $file if (defined($file));
}
my $level = $element->{'level'};
# Even if, without USE_SECTION, output can be split at chapter or
# section we don't split indices accordingly. We don't want to add
# more cases where users want split indices, this was a very difficult
# to maintain feature from the beginning.
#$level = $element->{'with_section'}->{'level'} if (!defined($level) and
# defined($element->{'with_section'}));
# if the element is not the level of splitting, then we don't split.
# also if 'top' is set we don't split since the formatting is different
# in that case and the result would be quite unpredictable.
return if ($element->{'top'} or ((get_conf('SPLIT') ne 'node')
and (!defined($level) or $level > $Texi2HTML::THISDOC{'split_level'})));
#print STDERR "Doing printindices for $element $element->{'texi'}, file $element->{'file'} (@{$element->{'place'}})\n";
# iterate over the @places of the element, which includes associated nodes,
# associated elements, anchors, footnotes, floats, index entries,
# printindices (including the element command itself, be it a @node or
# a sectioning @-command).
# during the iteration, split printindices that needs it, and reassociate
# other placed elements with files and elements.
my $current_element = $element;
my @places = @{$element->{'place'}};
@{$element->{'place'}} = ();
foreach my $place (@places)
{
my ($printindex, $printindex_to_split, $index_name);
# determines if the placed thing is a printindex to be split
if ($place->{'command'} and $place->{'command'} eq 'printindex')
{
$printindex = $place;
$index_name = $printindex->{'name'};
# ! empty index
if (exists($t2h_default_index_letters_array{$index_name}) and
# split index
scalar(@{$t2h_default_index_letters_array{$index_name}} > 1)
# the condition defined($printindex->{'associated_element'} implies
# that we don't split printindex before first element, otherwise
# there will be a need to begin document without a first element
# which would be annoying.
and defined($printindex->{'associated_element'}))
{
$printindex_to_split = 1;
}
}
# this is a non split printindex or any other placed thing.
if (!$printindex_to_split)
{
push @{$current_element->{'place'}}, $place;
# don't remodify the original element file, it was set right at the
# beginning of the function.
$place->{'file'} = $current_element->{'file'} if ($place ne $element);
# the 'element_ref' has to be reset. Otherwise, $place->{'element_ref'}
# will appear as a new element and trigger closing the file and
# opening a new one.
$place->{'element_ref'} = $current_element if ($place->{'element_ref'} and $current_element ne $element);
# this resets the element associated with a printindex.
if ($place->{'associated_element'} and $current_element ne $element)
{
$place->{'associated_element'} = $current_element;
}
next;
}
# now split the index
my @letter_groups = ();
my @letters_split = @{$t2h_default_index_letters_array{$index_name}};
foreach my $letters_split (@letters_split)
{
push @letter_groups, {'letters' => [@$letters_split]};
}
$letter_groups[0]->{'element'} = $current_element;
# besides preparing the new elements corresponding with split indices,
# they are recorded for later directions rearrangements in
# t2h_default_index_rearrange_directions.
# this weird construct is there because the element used as a key is
# converted to a string by perl, losing its meaning as a reference,
# the reference must be recorded explicitly
$t2h_default_element_split_printindices->{$element}->{'element'} = $element;
push @{$t2h_default_element_split_printindices->{$element}->{'printindices'}}, $printindex;
#print STDERR "Setting $element, $element->{'texi'}, $printindex $printindex->{'name'} as a split element\n";
foreach my $split_group (@letter_groups)
{
my $first_letter = $split_group->{'letters'}->[0]->{'letter'};
my $last_letter = $split_group->{'letters'}->[-1]->{'letter'};
if (!$split_group->{'element'})
{ # this is not the first letters group, which is already associated
# with an element, a new element is done.
# construct new element name
my $letters_heading;
if ($last_letter ne $first_letter)
{
$letters_heading = &$normal_text("$first_letter -- $last_letter");
}
else
{
$letters_heading = &$normal_text("$first_letter");
}
my ($name, $simple);
my $texi = "ADDED ELEMENT $element->{'texi'}: $letters_heading";
if (!defined($element->{'text'}))
{
my $element_heading_texi = &$heading_texi($element->{'tag'}, $element->{'texi'}, $element->{'number'});
my $index_heading_texi = &$index_element_heading_texi(
$element_heading_texi,
$element->{'tag'},
$element->{'texi'},
$element->{'number'},
$first_letter, $last_letter);
$name = main::substitute_line($index_heading_texi, sprintf(__p("\@sectioning_command index page","\@%s index page"), $element->{'tag'}));
$simple = main::simple_format(undef,undef,"simple_format \@$element->{'tag'} index page", $index_heading_texi);
}
else
{ # should never happen, at this point 'text' is always undefined.
$name = "$element->{'text'}: $letters_heading";
$simple = "$element->{'simple_format'}: $letters_heading";
}
#file and id
my $relative_file = $Texi2HTML::THISDOC{'file_base_name'} . '_' . $t2h_default_file_number;
$t2h_default_file_number++;
$relative_file .= '.' . get_conf('EXTENSION') if
(defined(get_conf('EXTENSION')));
my $id = "index_split-$t2h_default_index_id_nr";
$t2h_default_index_id_nr++;
my $new_element = { 'file' => $relative_file, 'id' => $id, 'target' => $id, 'text' => $name, 'texi' => $texi, 'seen' => 1, 'simple_format' => $simple };
# to avoid crashing when there is a filename collision.
main::add_file($new_element->{'file'});
$split_group->{'element'} = $new_element;
$current_element = $new_element;
#print STDERR "Added file $new_element->{'file'} ($new_element, $new_element->{'id'}) for $new_element->{'texi'} ($first_letter:$last_letter)\n";
}
else
{ # this is the first index split, it is still associated with the element
#print STDERR "No file added for ($first_letter:$last_letter)\n";
}
}
$t2h_default_seen_files{$default_element_file} = $current_element->{'file'};
$printindex->{'split_groups'} = \@letter_groups;
#print STDERR "$index_name processed for $element, $element->{'texi'} (@{$printindex->{'split_groups'}})\n";
}
}
# set directions for added elements now that they are done in the
# main program for all the other elements.
sub t2h_default_index_rearrange_directions()
{
return if (!defined($t2h_default_element_split_printindices));
foreach my $element_string (keys(%$t2h_default_element_split_printindices))
{
my $element = $t2h_default_element_split_printindices->{$element_string}->{'element'};
my $current_element = $element;
#print STDERR " E Processing $element_string,$current_element $current_element->{'texi'}\n";
foreach my $printindex (@{$t2h_default_element_split_printindices->{$element_string}->{'printindices'}})
{
#print STDERR " I Processing $printindex $printindex->{'name'} (@{$printindex->{'split_groups'}})\n";
foreach my $split_group (@{$printindex->{'split_groups'}})
{
my $first_letter = $split_group->{'letters'}->[0]->{'letter'};
my $last_letter = $split_group->{'letters'}->[-1]->{'letter'};
my $new_element = $split_group->{'element'};
next if ($current_element eq $new_element);
#print STDERR " G Processing ($first_letter:$last_letter) in $element->{'texi'}, index $printindex->{'name'}: $new_element->{'texi'}\n";
$new_element->{'This'} = $new_element;
if ($current_element->{'Forward'})
{
$current_element->{'Forward'}->{'Back'} = $new_element;
$new_element->{'Forward'} = $current_element->{'Forward'};
}
$current_element->{'Forward'} = $new_element;
$new_element->{'Back'} = $current_element;
if ($current_element->{'NodeForward'})
{
#print STDERR "F: C($current_element): $current_element->{'texi'}, N($new_element): $new_element->{'texi'} -- C->F: $current_element->{'NodeForward'}->{'texi'}\n";
$new_element->{'NodeForward'} = $current_element->{'NodeForward'};
$current_element->{'NodeForward'} = $new_element;
$new_element->{'NodeBack'} = $current_element;
}
foreach my $key ('FastForward', 'FastBack', 'Up', 'tag_level', 'tag',
'level', 'node')
{
$new_element->{$key} = $element->{$key} if (defined($element->{$key}));
}
$new_element->{'this'} = $new_element;
$new_element->{'element_ref'} = $new_element;
$current_element = $new_element;
}
}
}
}
# not needed to initialize it for a document, since it is reset
# in index_summary
my $t2h_symbol_indices = 0;
# format a letter appearing in a summary for an index. The letter links to
# the place where the index elements beginning with this letter are (called
# a letter entry).
#
# arguments:
# letter
# file where the target letter entry is
# identifier for the target letter entry
sub html_default_summary_letter($$$$$$$)
{
my $letter = shift;
my $file = shift;
my $default_identifier = shift;
my $index_element_id = shift;
my $number = shift;
my $index_element = shift;
my $index_name = shift;
return '' if ($letter =~ /^\s*$/);
my $is_symbol = $letter !~ /^[A-Za-z]/;
my $identifier = $default_identifier;
if (get_conf('NEW_CROSSREF_STYLE'))
{
if ($is_symbol)
{
$t2h_symbol_indices++;
$identifier = $index_element_id . "_${index_name}_symbol-$t2h_symbol_indices";
}
else
{
$identifier = $index_element_id . "_${index_name}_letter-${letter}";
}
}
my $result = &$anchor('', $file . '#' . $identifier, '' . &$protect_text($letter) . '', 'class="summary-letter"');
return $result unless (get_conf('NEW_CROSSREF_STYLE'));
return ($result, $identifier, $is_symbol);
}
# this replaces do_index_page
# args should be:
# index_name
# printindex
sub t2h_GPL_default_printindex($$)
{
my $index_name = shift;
my $printindex = shift;
# could be cross verified with argument
my $identifier_index_nr = 0;
my @split_letters;
if (defined($printindex->{'split_groups'}) and scalar(@{$printindex->{'split_groups'}}))
{
@split_letters = @{$printindex->{'split_groups'}};
}
elsif (defined($Texi2HTML::THISDOC{'index_letters_array'}->{$index_name}) and scalar(@{$Texi2HTML::THISDOC{'index_letters_array'}->{$index_name}}))
{
my $element = $printindex->{'associated_element'};
# this happens for printindex before the first element.
if (!defined($element))
{
$element = {'file' => '', 'id' => "$printindex->{'region'}_printindex"};
}
elsif (defined($element->{'element_ref'}))
{
$element = $element->{'element_ref'};
}
@split_letters = ({ 'letters' => $Texi2HTML::THISDOC{'index_letters_array'}->{$index_name}, 'element' => $element});
}
else
{
return '';
}
foreach my $split_group (@split_letters)
{
#do summmary
my @non_alpha = ();
my @alpha = ();
#print STDERR "$index_name @{$split_group->{'letters'}}\n";
# letter_id could be done once for all instead of for each split_group
# and outside of t2h_default_summary_letter (or t2h_default_summary_letter
# could be simplified and inlined
my %letter_id;
foreach my $summary_split_group (@split_letters)
{
foreach my $letter_entry (@{$summary_split_group->{'letters'}})
{
my $letter = $letter_entry->{'letter'};
my $dest_file = '';
####################################### debug
if (!defined($summary_split_group->{'element'}))
{
main::msg_debug ("index $index_name, letter $letter, element for summary_split_group $summary_split_group not defined");
}
elsif (!defined($summary_split_group->{'element'}->{'id'}))
{
main::msg_debug ("index $index_name, letter $letter, element $summary_split_group->{'element'} `$summary_split_group->{'element'}->{'texi'}', id undef");
}
####################################### end debug
$dest_file = $summary_split_group->{'element'}->{'file'}
if ($summary_split_group ne $split_group);
my $index_element_id = $summary_split_group->{'element'}->{'id'};
my $default_identifier = $index_element_id . "_$identifier_index_nr";
#print STDERR "$split_group $summary_split_group $summary_split_group->{'element'} $summary_split_group->{'element'}->{'id'} $identifier_index_nr $index_element_id $default_identifier\n";
$identifier_index_nr++;
my ($result, $identifier, $is_symbol) =
&$summary_letter($letter, $dest_file, $default_identifier, $index_element_id, '', '', $index_name);
$identifier = $default_identifier if (!defined($identifier));
$letter_id{$letter} = $identifier;
$is_symbol = $letter !~ /^[A-Za-z]/ if (!defined($is_symbol));
if ($result ne '')
{
if ($is_symbol)
{
push @non_alpha, $result;
}
else
{
push @alpha, $result;
}
}
}
}
my $summary = &$index_summary(\@alpha, \@non_alpha);
# reset symbols numbering
$t2h_symbol_indices = 0;
my $letters_text = '';
foreach my $letter_entry (@{$split_group->{'letters'}})
{
my $letter = $letter_entry->{'letter'};
my $entries_text = '';
foreach my $index_entry_ref (@{$letter_entry->{'entries'}})
{
my ($text_href, $entry_file, $element_file, $entry_target,
$entry_element_target, $formatted_entry, $element_href,
$entry_element_text, $in_region_not_in_output)
= main::get_index_entry_infos($index_entry_ref, $split_group->{'element'});
$entries_text .= &$index_entry ($text_href, $formatted_entry, $element_href, $entry_element_text, $entry_file, $element_file, $entry_target, $entry_element_target, $in_region_not_in_output, $index_entry_ref);
}
$letters_text .= &$index_letter ($letter, $letter_id{$letter}, $entries_text)
}
my $index_text = &$print_index($letters_text, $index_name);
$split_group->{'text'} = $summary . $index_text . $summary;
# print STDERR " ---> $index_name @{$split_group->{'letters'}}
# * elt: $split_group->{'element'}->{'id'}, $split_group->{'element'}->{'file'}, $split_group->{'element'}->{'name'}
# * directions: B: $split_group->{'element'}->{'Back'}->{'name'}, F: $split_group->{'element'}->{'Forward'}->{'name'}, FB: $split_group->{'element'}->{'FastBack'}->{'name'}, FF: $split_group->{'element'}->{'FastForward'}->{'name'}
# * text
#
#$split_group->{'text'}
#
#";
}
my $current_page = shift @split_letters;
if (!scalar(@split_letters))
{
return $current_page->{'text'};
}
while (1)
{
# print the index letters
push @{$Texi2HTML::THIS_SECTION}, $current_page->{'text'};
$current_page = shift @split_letters;
last if (!defined($current_page));
# there is no need to begin first element if not already done, since
# the index is not split if not already in an element.
# end the previous element
main::finish_element ($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT, $Texi2HTML::THIS_ELEMENT->{'Forward'}, 0);
# do the new element beginning
$Texi2HTML::THIS_ELEMENT = $current_page->{'element'};
my $new_element = $Texi2HTML::THIS_ELEMENT;
main::unref_file($new_element->{'file'});
main::do_element_directions($new_element);
my $do_page_head = main::open_out_file($new_element->{'file'});
if ($do_page_head)
{
&$print_page_head($Texi2HTML::THISDOC{'FH'});
&$print_chapter_header($Texi2HTML::THISDOC{'FH'}, $new_element) if get_conf('SPLIT') eq 'chapter';
&$print_section_header($Texi2HTML::THISDOC{'FH'}, $new_element) if get_conf('SPLIT') eq 'section';
}
# almost nothing of this is used in the default html output
@{$Texi2HTML::THIS_SECTION} = &$element_heading($new_element, $new_element->{'tag'}, $new_element->{'texi'},
$new_element->{'text'}, 0, 0, $new_element->{'this'}, 1, 0, 0, "\@$new_element->{'tag'} $new_element->{'texi'}",
$new_element->{'id'}, $new_element);
}
return '';
}
# leave this within comments, and keep the require statement
# This way, you can directly run texi2html.pl,
# if $T2H_HOME/documentlanguages.pl exists.
#
# @T2H_DOCUMENT_LANGUAGES@
require "$T2H_HOME/documentlanguages.pl"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/documentlanguages.pl" && -r "$T2H_HOME/documentlanguages.pl");
# leave this within comments, and keep the require statement
# This way, you can directly run texi2html.pl, if
# $T2H_HOME/texi2html.pm exists.
# @INIT@
require "$T2H_HOME/texi2html.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/texi2html.pm" && -r "$T2H_HOME/texi2html.pm");
# @INIT_HTML@
require "$T2H_HOME/formats/html.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/formats/html.pm" && -r "$T2H_HOME/formats/html.pm");
# @INIT_INFO@
require "$T2H_HOME/formats/info.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/formats/info.pm" && -r "$T2H_HOME/formats/info.pm");
# @INIT_DOCBOOK@
require "$T2H_HOME/formats/docbook.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/formats/docbook.pm" && -r "$T2H_HOME/formats/docbook.pm");
# @INIT_XML@
require "$T2H_HOME/formats/xml.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/formats/xml.pm" && -r "$T2H_HOME/formats/xml.pm");
# @INIT_PLAINTEXT@
require "$T2H_HOME/formats/plaintext.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/formats/plaintext.pm" && -r "$T2H_HOME/formats/plaintext.pm");
my $translation_file = 'translations.pl'; # file containing all the translations
my $T2H_OBSOLETE_STRINGS;
# leave this within comments, and keep the require statement
# This way, you can directly run texi2html.pl,
# if $T2H_HOME/translations.pl exists.
#
# @T2H_TRANSLATIONS_FILE@
require "$T2H_HOME/$translation_file"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/$translation_file" && -r "$T2H_HOME/$translation_file");
# these are unlikely to be used by users, as they are essentially
# used to follow the html external refs specification in texinfo
sub t2h_cross_manual_normal_text($$$$$$$;$)
{
my $text = shift;
my $in_raw_text = shift;
my $in_preformatted = shift;
my $in_code =shift;
my $in_math = shift;
my $in_simple =shift;
my $style_stack = shift;
my $state = shift;
$text = uc($text) if (in_small_caps($style_stack));
return $text if (get_conf('USE_UNICODE'));
return t2h_no_unicode_cross_manual_normal_text($text, 0);
}
sub t2h_cross_manual_normal_text_transliterate($$$$$$$;$)
{
my $text = shift;
my $in_raw_text = shift;
my $in_preformatted = shift;
my $in_code =shift;
my $in_math = shift;
my $in_simple =shift;
my $style_stack = shift;
my $state = shift;
$text = uc($text) if (in_small_caps($style_stack));
return $text if (get_conf('USE_UNICODE'));
return t2h_no_unicode_cross_manual_normal_text($text, 1);
}
sub t2h_no_unicode_cross_manual_normal_text($$)
{
# if there is no unicode support, we do all the transformations here
my $text = shift;
my $transliterate = shift;
my $result = '';
my $encoding = get_conf('documentencoding');
if (defined($encoding) and exists($t2h_encoding_aliases{$encoding}))
{
$encoding = $t2h_encoding_aliases{$encoding};
}
while ($text ne '')
{
if ($text =~ s/^([A-Za-z0-9]+)//o)
{
$result .= $1;
}
elsif ($text =~ s/^ //o)
{
$result .= '-';
}
elsif ($text =~ s/^(.)//o)
{
if (exists($ascii_character_map{$1}))
{
$result .= '_' . lc($ascii_character_map{$1});
}
else
{
my $character = $1;
my $charcode = uc(sprintf("%02x",ord($1)));
my $done = 0;
if (defined($encoding) and exists($eight_bit_to_unicode{$encoding})
and exists($eight_bit_to_unicode{$encoding}->{$charcode}))
{
$done = 1;
my $unicode_point = $eight_bit_to_unicode{$encoding}->{$charcode};
if (!$transliterate)
{
$result .= '_' . lc($unicode_point);
}
elsif (exists($transliterate_map{$unicode_point}))
{
$result .= $transliterate_map{$unicode_point};
}
elsif (exists($unicode_diacritical{$unicode_point}))
{
$result .= '';
}
else
{
$done = 0;
}
}
if (!$done)
{ # wild guess that work for latin1, and thus, should fail
$result .= '_' . '00' . lc($charcode);
}
}
}
else
{
msg_debug("Bug: unknown character in cross ref (likely in infinite loop)");
msg_debug("Text: !!$text!!");
sleep 1;
}
}
return $result;
}
sub t2h_nounicode_cross_manual_accent($$$)
{
my $accent = shift;
my $args = shift;
my $style_stack = shift;
my $text = $args->[0];
if ($accent eq 'dotless')
{
if (($text eq 'i') and (!defined($style_stack->[-1]) or (!defined($unicode_accents{$style_stack->[-1]})) or ($style_stack->[-1] eq 'tieaccent')))
{
return "_0131";
}
#return "\x{}" if ($text eq 'j'); # not found !
return $text;
}
return '_' . lc($unicode_accents{$accent}->{$text})
if (defined($unicode_accents{$accent}->{$text}));
return ($text . '_' . lc($unicode_diacritical{$accent}))
if (defined($unicode_diacritical{$accent}));
return ascii_accents($text, $accent);
}
sub t2h_transliterate_cross_manual_accent($$)
{
my $accent = shift;
my $args = shift;
my $text = $args->[0];
if (exists($unicode_accents{$accent}->{$text}) and
exists ($transliterate_map{$unicode_accents{$accent}->{$text}}))
{
return $transliterate_map{$unicode_accents{$accent}->{$text}};
}
return $text;
}
} # end package Texi2HTML::Config
# set the defaults based on real command name
set_config_init_dirs_output($real_command_name);
use vars qw(
%value
%alias
);
# variables which might be redefined by the user but aren't likely to be
# they seem to be in the main namespace
use vars qw(
%index_names
%index_prefix_to_name
%predefined_index
%valid_index
%reference_sec2level
%code_style_map
%forbidden_index_name
);
# Some global variables are set in the script, and used in the subroutines
# they are in the Texi2HTML namespace, thus prefixed with Texi2HTML::.
# see texi2html.pm for details.
#+++############################################################################
# #
# 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 $T2H_HOME/MySimple.pm
# exists.
# @MYSIMPLE@
require "$T2H_HOME/MySimple.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/MySimple.pm" && -r "$T2H_HOME/MySimple.pm");
#+++########################################################################
# #
# Pasted content of File $(srcdir)/T2h_i18n.pm: Internationalisation #
# #
#---########################################################################
# leave this within comments, and keep the require statement
# This way, you can directly run texi2html.pl, if $T2H_HOME/T2h_i18n.pm
# exists.
{
# @T2H_I18N@
require "$T2H_HOME/T2h_i18n.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/T2h_i18n.pm" && -r "$T2H_HOME/T2h_i18n.pm");
}
#########################################################################
#
# latex2html code
#
#---######################################################################
{
# leave this within comments, and keep the require statement
# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/T2h_l2h.pm
# exists.
# @T2H_L2H@
require "$T2H_HOME/T2h_l2h.pm"
if ($0 =~ /\.pl$/ &&
-e "$T2H_HOME/T2h_l2h.pm" && -r "$T2H_HOME/T2h_l2h.pm");
}
{
package Texi2HTML::LaTeX2HTML::Config;
# latex2html variables
# These variables are not used. They are here for information only, and
# an example of config file for latex2html file is included.
my $ADDRESS;
my $ANTI_ALIAS;
my $ANTI_ALIAS_TEXT;
my $ASCII_MODE;
my $AUTO_LINK;
my $AUTO_PREFIX;
my $CHILDLINE;
my $DEBUG;
my $DESTDIR;
my $DVIPS = 'dvips';
my $ERROR;
my $EXTERNAL_FILE;
my $EXTERNAL_IMAGES;
my $EXTERNAL_UP_LINK;
my $EXTERNAL_UP_TITLE;
my $FIGURE_SCALE_FACTOR;
my $HTML_VERSION;
my $IMAGES_ONLY;
my $INFO;
my $LINE_WIDTH;
my $LOCAL_ICONS;
my $LONG_TITLES;
my $MATH_SCALE_FACTOR;
my $MAX_LINK_DEPTH;
my $MAX_SPLIT_DEPTH;
my $NETSCAPE_HTML;
my $NOLATEX;
my $NO_FOOTNODE;
my $NO_IMAGES;
my $NO_NAVIGATION;
my $NO_SIMPLE_MATH;
my $NO_SUBDIR;
my $PAPERSIZE;
my $PREFIX;
my $PS_IMAGES;
my $REUSE;
my $SCALABLE_FONTS;
my $SHORTEXTN;
my $SHORT_INDEX;
my $SHOW_SECTION_NUMBERS;
my $SPLIT;
my $TEXDEFS;
my $TITLE;
my $TITLES_LANGUAGE;
my $TMP;
my $VERBOSE;
my $WORDS_IN_NAVIGATION_PANEL_TITLES;
my $WORDS_IN_PAGE;
# @T2H_L2H_INIT@
}
package main;
# functions related with configuration variables.
sub get_conf($)
{
my $var = shift;
return Texi2HTML::Config::get_conf($var);
}
sub set_from_cmdline($$)
{
my $var = shift;
my $value = shift;
my $level = 1;
return Texi2HTML::Config::set_variable($var, $value, $level);
}
sub global_override($$)
{
my $var = shift;
my $value = shift;
return Texi2HTML::Config::set_variable($var, $value, undef);
}
sub document_override($$)
{
my $var = shift;
my $value = shift;
return Texi2HTML::Config::set_variable($var, $value, undef, 1);
}
sub set_from_document($$)
{
my $var = shift;
my $value = shift;
my $level = 5;
return Texi2HTML::Config::set_variable($var, $value, $level, 1);
}
sub unset_from_document($)
{
my $var = shift;
my $level = 5;
return Texi2HTML::Config::unset_variable($var, $level, 1);
}
# prepare the gettext-like framework. To be noted that Locales::TextDomain
# canot be used, since it cannot be used dynamically through a reuires.
# Fortunately, Locales::TextDomain is a thin layer above Locales::Messages.
Texi2HTML::Config::set_default('USE_NLS', ('@USE_NLS@' eq 'yes' or $0 =~ /\.pl$/));
my $strings_textdomain = '@PACKAGE@' . '_document';
$strings_textdomain = 'texi2html_document' if ($strings_textdomain eq '@'.'PACKAGE@' . '_document');
my $messages_textdomain = '@PACKAGE@';
$messages_textdomain = 'texi2html' if ($messages_textdomain eq '@'.'PACKAGE@');
#my $messages_textdomain = 'texinfo';
if (get_conf('USE_NLS'))
{
if ($0 =~ /\.pl$/)
{ # use in-source libintl when testing
unshift @INC, "$T2H_HOME/lib/libintl-perl/lib";
}
elsif ($ENV{T2H_SOURCE_LIBINTL})
{
unshift @INC, $ENV{T2H_SOURCE_LIBINTL};
}
elsif ('@USE_EXTERNAL_LIBINTL@' ne 'yes')
{
unshift @INC, "$pkgdatadir/lib/libintl-perl/lib";
}
else
{
eval {
require Locale::Messages;
};
if ($@)
{
unshift @INC, "$pkgdatadir/lib/libintl-perl/lib";
}
}
# gettext-like translations
#require Locale::TextDomain;
require Locale::Messages;
# we want a reliable way to switch locale, so we don't use the system
# gettext.
Locale::Messages->select_package ('gettext_pp');
if ($0 =~ /\.pl$/)
{
# in case of out of source build, the locales directory should
# be two levels below. $T2H_HOME is in srcdir.
foreach my $locales_dir ("$T2H_HOME/locales", "../../locales")
{
if (-d $locales_dir)
{
Locale::Messages::bindtextdomain ($strings_textdomain, $locales_dir);
last;
}
}
}
else
{ # match where gettext installs
Locale::Messages::bindtextdomain ($strings_textdomain, "$datadir/locale");
}
# simply bind error messages to the installation directory.
# Messages should be untranslated for tests.
Locale::Messages::bindtextdomain ($messages_textdomain, "$datadir/locale");
}
sub __($)
{
my $msgid = shift;
return Locale::Messages::dgettext($messages_textdomain, $msgid);
}
sub __p($$)
{
my $context = shift;
my $msgid = shift;
return Locale::Messages::dpgettext($messages_textdomain, $context, $msgid);
}
sub N__($)
{
return $_[0];
}
#
# flush stdout and stderr after every write
#
select(STDERR);
$| = 1;
select(STDOUT);
$| = 1;
my $I = \&Texi2HTML::I18n::get_string;
########################################################################
#
# Global variable initialization
#
########################################################################
#
# pre-defined indices
#
%index_prefix_to_name = ();
%index_names =
(
'cp' => {'cp' => 0,'c' => 0},
'fn' => {'fn' => 1, 'f' => 1},
'vr' => {'vr' => 1, 'v' => 1},
'ky' => {'ky' => 1, 'k' => 1},
'pg' => {'pg' => 1, 'p' => 1},
'tp' => {'tp' => 1, 't' => 1}
);
foreach my $name(keys(%index_names))
{
foreach my $prefix (keys %{$index_names{$name}})
{
$forbidden_index_name{$prefix} = 1;
$index_prefix_to_name{$prefix} = $name;
}
}
foreach my $other_forbidden_index_name ('info','ps','pdf','htm',
'log','aux','dvi','texi','txi','texinfo','tex','bib')
{
$forbidden_index_name{$other_forbidden_index_name} = 1;
}
# commands with ---, -- '' and `` preserved
# usefull with the old interface
%code_style_map = (
'code' => 1,
'command' => 1,
'env' => 1,
'file' => 1,
'kbd' => 1,
'option' => 1,
'samp' => 1,
'verb' => 1,
);
my @element_directions = ('Up', 'Forward', 'Back', 'Next', 'Prev',
'SectionNext', 'SectionPrev', 'SectionUp', 'FastForward', 'FastBack',
'This', 'NodeUp', 'NodePrev', 'NodeNext', 'NodeForward', 'NodeBack',
'NextFile', 'PrevFile', 'ToplevelNext', 'ToplevelPrev');
$::simple_map_ref = \%Texi2HTML::Config::simple_map;
$::simple_map_math_ref = \%Texi2HTML::Config::simple_map_math;
#$::simple_map_pre_ref = \%Texi2HTML::Config::simple_map_pre;
$::simple_map_texi_ref = \%Texi2HTML::Config::simple_map_texi;
$::style_map_ref = \%Texi2HTML::Config::style_map;
$::style_map_pre_ref = \%Texi2HTML::Config::style_map_pre;
$::style_map_math_ref = \%Texi2HTML::Config::style_map_math;
$::style_map_texi_ref = \%Texi2HTML::Config::style_map_texi;
$::things_map_ref = \%Texi2HTML::Config::things_map;
$::pre_map_ref = \%Texi2HTML::Config::pre_map;
$::texi_map_ref = \%Texi2HTML::Config::texi_map;
#print STDERR "MAPS: $::simple_map_ref $::simple_map_pre_ref $::simple_map_texi_ref $::style_map_ref $::style_map_pre_ref $::style_map_texi_ref $::things_map_ref $::pre_map_ref $::texi_map_ref\n";
# delete from hash if we are using the new interface
foreach my $code (keys(%code_style_map))
{
delete ($code_style_map{$code})
if (ref($::style_map_ref->{$code}) eq 'HASH');
}
# no paragraph in these commands
my %no_paragraph_macro = (
'xref' => 1,
'ref' => 1,
'pxref' => 1,
'inforef' => 1,
'anchor' => 1,
);
#
# texinfo section names to level
#
my %reference_sec2level = (
'top', 0,
'chapter', 1,
'unnumbered', 1,
'chapheading', 1,
'appendix', 1,
'section', 2,
'unnumberedsec', 2,
'heading', 2,
'appendixsec', 2,
'subsection', 3,
'unnumberedsubsec', 3,
'subheading', 3,
'appendixsubsec', 3,
'subsubsection', 4,
'unnumberedsubsubsec', 4,
'subsubheading', 4,
'appendixsubsubsec', 4,
);
# the reverse mapping. There is an entry for each sectioning command.
# The value is a ref on an array containing at each index the corresponding
# sectioning command name.
my %level2sec;
{
my $sections = [ ];
my $appendices = [ ];
my $unnumbered = [ ];
my $headings = [ ];
foreach my $command (keys (%reference_sec2level))
{
if ($command =~ /^appendix/)
{
$level2sec{$command} = $appendices;
}
elsif ($command =~ /^unnumbered/ or $command eq 'top')
{
$level2sec{$command} = $unnumbered;
}
elsif ($command =~ /section$/ or $command eq 'chapter')
{
$level2sec{$command} = $sections;
}
else
{
$level2sec{$command} = $headings;
}
$level2sec{$command}->[$reference_sec2level{$command}] = $command;
}
}
# out of the main hierarchy
$reference_sec2level{'part'} = 0;
# this are synonyms
$reference_sec2level{'appendixsection'} = 2;
# sec2level{'majorheading'} is also 1 and not 0
$reference_sec2level{'majorheading'} = 1;
$reference_sec2level{'chapheading'} = 1;
$reference_sec2level{'centerchap'} = 1;
sub stop_paragraph_command($)
{
my $command = shift;
return 1 if ($Texi2HTML::Config::stop_paragraph_command{$command} or defined($reference_sec2level{$command}));
}
sub set_no_line_macro($$)
{
my $macro = shift;
my $value = shift;
$Texi2HTML::Config::no_paragraph_commands{$macro} = $value
unless defined($Texi2HTML::Config::no_paragraph_commands{$macro});
}
# those macros aren't considered as beginning a paragraph
foreach my $no_line_macro ('alias', 'macro', 'unmacro', 'rmacro',
'titlefont', 'include', 'copying', 'end copying', 'tab', 'item',
'itemx', '*', 'float', 'end float', 'caption', 'shortcaption', 'cindex',
'image')
{
set_no_line_macro($no_line_macro, 1);
}
# holds all the @-commands that should be at the beginning of a line
my %begin_line_command = ();
foreach my $command ('node', 'end')
{
$begin_line_command{$command} = $command;
}
foreach my $key (keys(%Texi2HTML::Config::misc_command), keys(%reference_sec2level))
{
set_no_line_macro($key, 1);
$begin_line_command{$key} = $key;
}
foreach my $misc_not_begin_line('comment', 'c', 'sp', 'refill', 'noindent', 'indent')
{
delete $begin_line_command{$misc_not_begin_line};
}
# a hash associating a format @thing / @end thing with the type of the format
# 'complex_format' 'simple_format' 'deff' 'list' 'menu' 'paragraph_format'
my %format_type = ();
foreach my $simple_format (keys(%Texi2HTML::Config::format_map))
{
$format_type{$simple_format} = 'simple_format';
}
foreach my $paragraph_style (keys(%Texi2HTML::Config::paragraph_style))
{
$format_type{$paragraph_style} = 'paragraph_format';
}
# FIXME $complex_format_map obsoleted in nov 2009
foreach my $complex_format (keys(%$Texi2HTML::Config::complex_format_map),
keys(%Texi2HTML::Config::complex_format_map))
{
$format_type{$complex_format} = 'complex_format';
}
foreach my $table (('table', 'ftable', 'vtable'))
{
$format_type{$table} = 'table';
}
$format_type{'multitable'} = 'multitable';
foreach my $def_format (keys(%Texi2HTML::Config::def_map))
{
$format_type{$def_format} = 'deff';
}
$format_type{'itemize'} = 'list';
$format_type{'enumerate'} = 'list';
$format_type{'menu'} = 'menu';
$format_type{'detailmenu'} = 'menu';
$format_type{'direntry'} = 'menu';
$format_type{'cartouche'} = 'cartouche';
$format_type{'float'} = 'float';
$format_type{'quotation'} = 'quotation';
$format_type{'smallquotation'} = 'quotation';
$format_type{'group'} = 'group';
my @special_regions = ('titlepage', 'copying', 'documentdescription');
foreach my $region (@special_regions)
{
$format_type{$region} = 'region';
}
foreach my $key (keys(%format_type))
{
set_no_line_macro($key, 1);
set_no_line_macro("end $key", 1);
}
foreach my $macro (keys(%Texi2HTML::Config::format_in_paragraph))
{
set_no_line_macro($macro, 1);
set_no_line_macro("end $macro", 1);
}
foreach my $format (keys(%format_type))
{
$begin_line_command{$format} = $format_type{$format};
}
# fake format at the bottom of the stack
$format_type{'noformat'} = '';
# fake formats are formats used internally within other formats
# we associate them with a real format, for the error messages
my %fake_format = (
'line' => 'table',
'term' => 'table',
'item' => 'list or table',
'row' => 'multitable row',
'cell' => 'multitable cell',
'deff_item' => 'definition command',
'menu_comment' => 'menu',
'menu_description' => 'menu',
);
foreach my $key (keys(%fake_format))
{
$format_type{$key} = 'fake';
}
# raw formats which are expanded especially
my @raw_regions = ('html', 'tex', 'xml', 'docbook');
foreach my $format (keys(%Texi2HTML::Config::texi_formats_map), @raw_regions)
{
$begin_line_command{$format} = $format;
}
foreach my $format (keys(%Texi2HTML::Config::texi_formats_map))
{
push @raw_regions, $format if ($Texi2HTML::Config::texi_formats_map{$format} eq 'raw');
}
# The css formats are associated with complex format commands, and associated
# with the 'pre_style' key
# FIXME $complex_format_map obsoleted in nov 2009
foreach my $complex_format (keys(%$Texi2HTML::Config::complex_format_map))
{
next if (defined($Texi2HTML::Config::complex_format_map->{$complex_format}->{'pre_style'}));
$Texi2HTML::Config::complex_format_map->{$complex_format}->{'pre_style'} = '';
$Texi2HTML::Config::complex_format_map->{$complex_format}->{'pre_style'} = $Texi2HTML::Config::css_map{"pre.$complex_format"} if (exists($Texi2HTML::Config::css_map{"pre.$complex_format"}));
}
# The css formats are associated with complex format commands, and associated
# with the 'pre_style' key
foreach my $complex_format (keys(%Texi2HTML::Config::complex_format_map))
{
next if (defined($Texi2HTML::Config::complex_format_map{$complex_format}->{'pre_style'}));
$Texi2HTML::Config::complex_format_map{$complex_format}->{'pre_style'} = '';
$Texi2HTML::Config::complex_format_map{$complex_format}->{'pre_style'} = $Texi2HTML::Config::css_map{"pre.$complex_format"} if (exists($Texi2HTML::Config::css_map{"pre.$complex_format"}));
}
#+++############################################################################
# #
# Argument parsing, initialisation #
# #
#---############################################################################
# shorthand for get_conf('VERBOSE')
my $T2H_VERBOSE;
my $T2H_DEBUG;
#
# %value hold texinfo variables, see also -D, -U, @set and @clear.
# we predefine html (the output format) and texi2html (the translator)
# it is initialized with %value_initial at the beginning of the
# document parsing and filled and emptied as @set and @clear are
# encountered
# FIXME remove html
my %value_initial =
(
# 'html' => 1,
'texi2html' => $THISVERSION,
);
sub line_warn($$);
sub document_warn($);
sub file_line_warn($$;$);
sub cmdline_warn ($);
my $T2H_FAILURE_TEXT = sprintf(__("Try `%s --help' for more information.\n"), $real_command_name);
#print STDERR "" . gdt('test i18n: \' , \a \\ %% %{unknown}a %known % %{known} \\', { 'known' => 'a known string', 'no' => 'nope'}); exit 0;
sub add_to_texi2dvi_args($;$)
{
my $option = shift;
my $value = shift;
#print STDERR "$option $value\n";
push @Texi2HTML::Config::TEXI2DVI_ARGUMENTS, $option;
push @Texi2HTML::Config::TEXI2DVI_ARGUMENTS, $value if (defined($value));
}
# file: file name to locate. It can be a file path.
# directories: a reference on a array containing a list of directories to
# search the file in.
# all_files: if true collect all the files with that name, otherwise stop
# at first match.
sub locate_init_file($$$)
{
my $file = shift;
my $directories = shift;
my $all_files = shift;
if ($file =~ /^\//)
{
return $file if (-e $file and -r $file);
}
else
{
my @files;
foreach my $dir (@$directories)
{
next unless (-d "$dir");
if ($all_files)
{
push (@files, "$dir/$file") if (-e "$dir/$file" and -r "$dir/$file");
}
else
{
return "$dir/$file" if (-e "$dir/$file" and -r "$dir/$file");
}
}
return @files if ($all_files);
}
return undef;
}
# called on -init-file
sub load_init_file
{
# First argument is option
shift;
# second argument is value of options
my $init_file = shift;
my $file = locate_init_file($init_file, [ @Texi2HTML::Config::CONF_DIRS, @program_init_dirs ], 0);
if ($file)
{
print STDERR "# reading initialization file from $file\n"
if ($T2H_VERBOSE);
# require the file in the Texi2HTML::Config namespace
return (Texi2HTML::Config::load($file));
}
else
{
document_error ("Can't read init file $init_file");
return 0;
}
}
sub set_date($)
{
my $language = shift;
if (!get_conf('TEST'))
{
print STDERR "# Setting date in $language\n" if ($T2H_DEBUG);
set_from_document('today', Texi2HTML::I18n::pretty_date($language)); # like "20 September 1993";
}
else
{
set_from_document('today', 'a sunny day');
}
$::things_map_ref->{'today'} = get_conf('today');
$::pre_map_ref->{'today'} = get_conf('today');
$::texi_map_ref->{'today'} = get_conf('today');
}
sub warn_unknown_language($;$)
{
my $lang = shift;
my $line_nr = shift;
my $lang_code = $lang;
my $region_code;
if ($lang =~ /^([a-z]+)_([A-Z]+)/)
{
$lang_code = $1;
$region_code = $2;
}
if (! $Texi2HTML::Config::language_codes{$lang_code})
{
msg_warn(sprintf(__("%s is not a valid language code"), $lang_code), $line_nr);
}
if (defined($region_code) and ! $Texi2HTML::Config::region_codes{$region_code})
{
msg_warn(sprintf(__("%s is not a valid region code"), $region_code), $line_nr);
}
}
# Called on --document-language, at the beginning of each pass and
# when a @documentlanguage appears
sub set_document_language ($;$)
{
my $lang = shift;
my $line_nr = shift;
# Always succeed if using a gettext-like environment
if (!get_conf('I18N_PERL_HASH'))
{
set_date($lang);
return 1;
}
# old framework code
my @langs = ($lang);
my $main_lang;
if ($lang =~ /^([a-z]+)_([A-Z]+)/)
{
$main_lang = $1;
push @langs, $main_lang;
}
my @files = locate_init_file("$i18n_dir/$lang.thl", \@program_config_dirs, 1);
if (! scalar(@files) and defined($main_lang))
{
@files = locate_init_file("$i18n_dir/$main_lang.thl", \@program_config_dirs, 1);
}
foreach my $file (@files)
{
Texi2HTML::Config::load($file);
}
foreach my $language (@langs)
{
if (Texi2HTML::I18n::set_language($language))
{
print STDERR "# using '$language' as document language\n" if ($T2H_VERBOSE);
set_date($language);
return 1;
}
}
return 0;
}
# manage footnote style
sub set_footnote_style($$;$)
{
my $value = shift;
my $from_command_line = shift;
my $line_nr = shift;
my $command = 'footnotestyle';
if ($value eq 'end' or $value eq 'separate')
{
if ($from_command_line)
{
set_from_cmdline($command, $value);
}
else
{
set_from_document($command, $value);
}
}
elsif ($from_command_line)
{
die sprintf(__("%s: --footnote-style arg must be `separate' or `end', not `%s'.\n"), $real_command_name, $value);
# the T2H_FAILURE_TEXT is output by getOption, seems to catch die
}
else
{
line_error (sprintf(__("\@%s arg must be `separate' or `end', not `%s'"), $command, $value), $line_nr);
}
}
sub set_output($;$)
{
my $output = shift;
my $from_command_line = shift;
my $var = 'OUTFILE';
if ($output =~ m:/$: or -d $output)
{
$var = 'SUBDIR';
}
if ($from_command_line)
{
set_from_cmdline($var, $output);
set_from_cmdline('OUT', $output);
add_to_texi2dvi_args('-o', $output);
}
else
{
set_default($var, $output);
if (set_default('OUT', $output))
{
add_to_texi2dvi_args('-o', $output);
}
}
}
# used both for command line and @-command argument checking
sub set_paragraphindent($$;$$)
{
my $value = shift;
my $from_command_line = shift;
my $line_nr = shift;
my $pass = shift;
my $command = 'paragraphindent';
if ($value =~ /^([0-9]+)$/ or $value eq 'none' or $value eq 'asis')
{
if ($from_command_line)
{
set_from_cmdline($command, $value)
}
else
{
set_from_document($command, $value)
}
}
elsif ($from_command_line)
{
die sprintf(__("%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n"), $real_command_name, $value);
}
elsif ($pass == 1)
{
line_error (sprintf(__("\@paragraphindent arg must be numeric/`none'/`asis', not `%s'"), $value), $line_nr);
}
}
# find the encoding alias.
# with encoding support (USE_UNICODE), may return undef if no alias was found.
# The $line_nr argument should only be set when called from misc_command_texi
# for @documentencoding, and so the error message should only be echoed at
# that time.
sub encoding_alias($;$$)
{
my $encoding = shift;
my $line_nr = shift;
my $context_string = shift;
return undef if (!defined($encoding) or $encoding eq '');
if (get_conf('USE_UNICODE'))
{
my $result_encoding = Encode::resolve_alias($encoding);
if (! $result_encoding)
{
line_warn(sprintf(__("unrecognized encoding name `%s'"), $encoding), $line_nr);
return undef;
}
if (defined($Texi2HTML::Config::t2h_encoding_aliases{$result_encoding}))
{
$result_encoding = $Texi2HTML::Config::t2h_encoding_aliases{$result_encoding};
}
print STDERR "# Using encoding $result_encoding\n" if ($T2H_VERBOSE);
return $result_encoding;
}
else
{
if (exists($Texi2HTML::Config::t2h_encoding_aliases{$encoding}))
{
$encoding = $Texi2HTML::Config::t2h_encoding_aliases{$encoding};
return $encoding;
}
line_warn(sprintf(__("Encoding %s certainly poorly supported"), $encoding), $line_nr);
return $encoding;
}
}
# libintl converts between encodings but doesn't decode them into the
# perl internal format.
sub encode_i18n_string($$)
{
my $string = shift;
my $encoding = shift;
if ($encoding ne 'us-ascii' and get_conf('USE_UNICODE')
and Encode::resolve_alias($encoding))
{
return Encode::decode($encoding, $string);
}
return $string;
}
sub gdt($;$$)
{
my $message = shift;
my $context = shift;
my $state = shift;
# FIXME this should be done only once, for @documentencoding
my $encoding;
my $input_encoding = get_conf('documentencoding');
if (defined($input_encoding))
{
$encoding = lc($input_encoding);
}
if (defined($encoding) and $encoding ne '' and exists($Texi2HTML::Config::t2h_encoding_aliases{$encoding}))
{
$encoding = $Texi2HTML::Config::t2h_encoding_aliases{$encoding};
}
$encoding = 'us-ascii' if (!defined($encoding) or $encoding eq '');
return &$I($message, $context, $state) if (get_conf('I18N_PERL_HASH'));
# if set, use substitute_text instead of substitute_line
my $allow_paragraph = $state->{'allow_paragraph'};
# if duplicate is passed, it means that we are in the text and so should
# use the main state
if (defined($state) and $state->{'duplicate'} and defined($Texi2HTML::THISDOC{'state'}))
{
$state = main::duplicate_formatting_state($Texi2HTML::THISDOC{'state'});
}
my $result;
# taken from libintl perl, copyright Guido. sub __expand. Overall not
# enough code taken form Guido right now to be copyrightable.
my $re = join '|', map { quotemeta $_ } keys %$context if (defined($context) and ref($context));
if (get_conf('USE_NLS'))
{
my $saved_LANGUAGE = $ENV{'LANGUAGE'};
Locale::Messages::textdomain($strings_textdomain);
Locale::Messages::bind_textdomain_codeset($strings_textdomain, $encoding) if ($encoding ne 'us-ascii');
Locale::Messages::bind_textdomain_filter($strings_textdomain, \&encode_i18n_string, $encoding);
my $lang = get_conf('documentlanguage');
my @langs = ($lang);
if ($lang =~ /^([a-z]+)_([A-Z]+)/)
{
my $main_lang = $1;
my $region_code = $2;
push @langs, $main_lang;
}
my $locales = '';
foreach my $language (@langs)
{
$locales .= "$language.$encoding:";
#$locales .= "$language:";
# always try us-ascii, the charset should always be a subset of
# all charset, and should resort to @-commands if needed for non
# ascii characters
if ($encoding ne 'us-ascii')
{
$locales .= "$language.us-ascii:";
}
}
$locales =~ s/:$//;
#print STDERR "$locales\n";
Locale::Messages::nl_putenv("LANGUAGE=$locales");
if (!defined($context) or ref($context))
{
$result = Locale::Messages::gettext($message);
}
else
{
$result = Locale::Messages::pgettext($context, $message);
}
Locale::Messages::textdomain($messages_textdomain);
# old perl complains 'Use of uninitialized value in scalar assignment'
if (!defined($saved_LANGUAGE))
{
delete ($ENV{'LANGUAGE'});
}
else
{
$ENV{'LANGUAGE'} = $saved_LANGUAGE;
}
}
# now perform the argument substitutions
if ($state->{'keep_texi'})
{
# next line taken from libintl perl, copyright Guido. sub __expand
$result =~ s/\{($re)\}/defined $context->{$1} ? $context->{$1} : "{$1}"/ge if (defined($re));
return $result;
}
if (defined($re))
{
# next line taken from libintl perl, copyright Guido. sub __expand
$result =~ s/\{($re)\}/\@internal_translation_open_brace\{\}$1\@internal_translation_close_brace\{\}/g;
foreach my $map (\%Texi2HTML::Config::things_map, \%Texi2HTML::Config::pre_map, \%Texi2HTML::Config::texi_map, \%Texi2HTML::Config::simple_format_texi_map)
{
$map->{'internal_translation_open_brace'} = '{';
$map->{'internal_translation_close_brace'} = '}';
}
}
if ($allow_paragraph)
{
delete $state->{'allow_paragraph'};
$result = substitute_text ($state, undef, __("translation"), ($result));
}
else
{
$result = substitute_line ($result, __("translation"), $state);
}
if (defined($re))
{
$result =~ s/\{($re)\}/defined $context->{$1} ? $context->{$1} : "{$1}"/ge;
foreach my $map (\%Texi2HTML::Config::things_map, \%Texi2HTML::Config::pre_map, \%Texi2HTML::Config::texi_map, \%Texi2HTML::Config::simple_format_texi_map)
{
delete $map->{'internal_translation_open_brace'};
delete $map->{'internal_translation_close_brace'};
}
}
return $result;
}
sub unicode_to_protected($)
{
my $text = shift;
my $result = '';
while ($text ne '')
{
if ($text =~ s/^([A-Za-z0-9]+)//o)
{
$result .= $1;
}
elsif ($text =~ s/^ //o)
{
$result .= '-';
}
elsif ($text =~ s/^(.)//o)
{
my $char = $1;
if (exists($Texi2HTML::Config::ascii_character_map{$char}))
{
$result .= '_' . lc($Texi2HTML::Config::ascii_character_map{$char});
}
else
{
if (ord($char) <= hex(0xFFFF))
{
$result .= '_' . lc(sprintf("%04x",ord($char)));
}
else
{
$result .= '__' . lc(sprintf("%06x",ord($char)));
}
}
}
else
{
print STDERR "Bug: unknown character in a cross ref (likely in infinite loop)\n";
print STDERR "Text: !!$text!!\n";
sleep 1;
}
}
return $result;
}
sub unicode_to_transliterate($)
{
my $text = shift;
if (chomp($text))
{
print STDERR "Strange: end of line to transliterate: $text\n";
}
my $result = '';
while ($text ne '')
{
if ($text =~ s/^([A-Za-z0-9 ]+)//o)
{
$result .= $1;
}
elsif ($text =~ s/^(.)//o)
{
my $char = $1;
if (exists($Texi2HTML::Config::ascii_character_map{$char}))
{
$result .= $char;
}
elsif (ord($char) <= hex(0xFFFF) and exists($Texi2HTML::Config::transliterate_map{uc(sprintf("%04x",ord($char)))}))
{
$result .= $Texi2HTML::Config::transliterate_map{uc(sprintf("%04x",ord($char)))};
}
elsif (ord($char) <= hex(0xFFFF) and exists($Texi2HTML::Config::unicode_diacritical{uc(sprintf("%04x",ord($char)))}))
{
$result .= '';
}
# in this case, we want to avoid calling unidecode, as we are sure
# that there is no useful transliteration of the unicode character
# instead we want to keep it as is.
# This is the case, for example, for @exclamdown, is corresponds
# with x00a1, but unidecode transliterates it to a !, we want
# to avoid that and keep x00a1.
elsif (ord($char) <= hex(0xFFFF) and exists($Texi2HTML::Config::no_transliterate_map{uc(sprintf("%04x",ord($char)))}))
{
$result .= $char;
}
else
{
if (get_conf('USE_UNIDECODE'))
{
$result .= unidecode($char);
}
else
{
$result .= $char;
}
}
}
else
{
print STDERR "Bug: unknown character in cross ref transliteration (likely in infinite loop)\n";
print STDERR "Text: !!$text!!\n";
sleep 1;
}
}
return $result;
}
# 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
my $T2H_OPTIONS;
$T2H_OPTIONS -> {'macro-expand|E'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('MACRO_EXPAND', $_[1]); add_to_texi2dvi_args('-E'); },
'verbose' => 'output macro expanded source in ',
};
$T2H_OPTIONS -> {'ifhtml'} =
{
'type' => '!',
'linkage' => sub { Texi2HTML::Config::set_expansion('html', $_[1]); },
'verbose' => "expand ifhtml and html sections",
};
$T2H_OPTIONS -> {'ifinfo'} =
{
'type' => '!',
'linkage' => sub { Texi2HTML::Config::set_expansion('info', $_[1]); },
'verbose' => "expand ifinfo",
};
$T2H_OPTIONS -> {'ifxml'} =
{
'type' => '!',
'linkage' => sub { Texi2HTML::Config::set_expansion('xml', $_[1]); },
'verbose' => "expand ifxml and xml sections",
};
$T2H_OPTIONS -> {'ifdocbook'} =
{
'type' => '!',
'linkage' => sub { Texi2HTML::Config::set_expansion('docbook', $_[1]); },
'verbose' => "expand ifdocbook and docbook sections",
};
$T2H_OPTIONS -> {'iftex'} =
{
'type' => '!',
'linkage' => sub { Texi2HTML::Config::set_expansion('tex', $_[1]); },
'verbose' => "expand iftex and tex sections",
};
$T2H_OPTIONS -> {'ifplaintext'} =
{
'type' => '!',
'linkage' => sub { Texi2HTML::Config::set_expansion('plaintext', $_[1]); },
'verbose' => "expand ifplaintext sections",
};
$T2H_OPTIONS -> {'I'} =
{
'type' => '=s',
'linkage' => sub { add_to_texi2dvi_args('-'.$_[0], $_[1]); push @Texi2HTML::Config::INCLUDE_DIRS, $_[1] },
'verbose' => 'append $s to the @include search path',
};
$T2H_OPTIONS -> {'conf-dir'} =
{
'type' => '=s',
'linkage' => \@Texi2HTML::Config::CONF_DIRS,
'verbose' => 'append $s to the init file directories',
};
$T2H_OPTIONS -> {'P'} =
{
'type' => '=s',
'linkage' => sub {unshift (@Texi2HTML::Config::PREPEND_DIRS, $_[1]);},
'verbose' => 'prepend $s to the @include search path',
};
$T2H_OPTIONS -> {'number-sections'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('NUMBER_SECTIONS', $_[1]);},
'verbose' => 'output chapter and sectioning numbers.',
};
$T2H_OPTIONS -> {'number-footnotes'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('NUMBER_FOOTNOTES', $_[1]);},
'verbose' => 'output footnote numbers.',
};
$T2H_OPTIONS -> {'node-files'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('NODE_FILES', $_[1]);},
'verbose' => 'produce one file per node for cross references'
};
$T2H_OPTIONS -> {'footnote-style|s'} =
{
'type' => '=s',
'linkage' => sub {set_footnote_style ($_[1], 1);},
'verbose' => 'output footnotes separate|end',
};
$T2H_OPTIONS -> {'split'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('SPLIT', $_[1])},
'verbose' => 'split document on section|chapter|node else no splitting',
};
$T2H_OPTIONS -> {'no-split'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('SPLIT', ''); set_from_cmdline('SPLIT_SIZE', undef);},
'verbose' => 'no splitting of document',
'noHelp' => 1,
};
$T2H_OPTIONS -> {'headers'} =
{
'type' => '!',
'linkage' => sub {
set_from_cmdline('HEADERS', $_[1]);
set_from_cmdline('SHOW_MENU', $_[1]);
Texi2HTML::Config::t2h_default_load_format('plaintext', 1)
if (!$_[1] and defined($Texi2HTML::Config::OUTPUT_FORMAT) and $Texi2HTML::Config::OUTPUT_FORMAT eq 'info');
},
'verbose' => 'output navigation headers for each section',
};
$T2H_OPTIONS -> {'output|out|o'} =
{
'type' => '=s',
'linkage' => sub {set_output($_[1], 1);},
'verbose' => 'output goes to $s (directory if split)',
};
$T2H_OPTIONS -> {'no-validate|no-pointer-validate'} =
{
'type' => '',
'linkage' => sub {set_from_cmdline('novalidate',$_[1])},
'verbose' => 'suppress node cross-reference validation',
};
$T2H_OPTIONS -> {'no-warn'} =
{
'type' => '',
'linkage' => sub {set_from_cmdline('NO_WARN', $_[1]);},
'verbose' => 'suppress warnings (but not errors).'
};
$T2H_OPTIONS -> {'verbose'} = 0;
$T2H_OPTIONS -> {'verbose|v'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('VERBOSE', $_[1]); add_to_texi2dvi_args('--verbose'); },
'verbose' => 'print progress info to stdout',
};
$T2H_OPTIONS -> {'document-language'} =
{
'type' => '=s',
'linkage' => sub {
warn_unknown_language ($_[1]);
set_from_cmdline('documentlanguage', $_[1])
},
'verbose' => 'use $s as document language',
};
$T2H_OPTIONS -> {'D'} =
{
'type' => '=s',
'linkage' => sub {$value_initial{$_[1]} = 1;},
'verbose' => 'equivalent to Texinfo "@set $s 1"',
'noHelp' => 1,
};
$T2H_OPTIONS -> {'U'} =
{
'type' => '=s',
'linkage' => sub {delete $value_initial{$_[1]};},
'verbose' => 'equivalent to Texinfo "@clear $s"',
'noHelp' => 1,
};
$T2H_OPTIONS -> {'init-file'} =
{
'type' => '=s',
'linkage' => \&load_init_file,
'verbose' => 'load init file $s'
};
$T2H_OPTIONS -> {'set-init-variable'} =
{
'type' => '=s',
'linkage' => sub { my $var_val = $_[1];
if ($var_val =~ s/^(\w+)\s*=?\s*//)
{
my $var = $1;
my $value = $var_val;
if ($value =~ /^undef$/i)
{
$value = undef;
}
set_from_cmdline ($var, $value);
}
},
'verbose' => 'set an init file variable to a value'
};
$T2H_OPTIONS -> {'css-include'} =
{
'type' => '=s',
'linkage' => \@Texi2HTML::Config::CSS_FILES,
'verbose' => 'use css file $s'
};
$T2H_OPTIONS -> {'css-ref'} =
{
'type' => '=s',
'linkage' => \@Texi2HTML::Config::CSS_REFS,
'verbose' => 'generate reference to the CSS URL $s'
};
$T2H_OPTIONS -> {'transliterate-file-names'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('TRANSLITERATE_FILE_NAMES', $_[1]);},
'verbose' => 'produce file names in ASCII transliteration',
};
$T2H_OPTIONS -> {'error-limit|e'} =
{
'type' => '=i',
'linkage' => sub {set_from_cmdline('ERROR_LIMIT', $_[1]);},
'verbose' => 'quit after NUM errors (default '.get_conf('ERROR_LIMIT').').',
};
$T2H_OPTIONS -> {'split-size'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('SPLIT_SIZE', $_[1])},
'verbose' => 'split Info files at size s (default '.get_conf('SPLIT_SIZE').').',
};
$T2H_OPTIONS -> {'paragraph-indent|p'} =
{
'type' => '=s',
'linkage' => sub {set_paragraphindent($_[1], 1);},
'verbose' => "indent Info paragraphs by VAL spaces (default ".get_conf('paragraphindent').").
If VAL is `none', do not indent; if VAL is
`asis', preserve existing indentation.",
};
$T2H_OPTIONS -> {'fill-column|f'} =
{
'type' => '=i',
'linkage' => sub {set_from_cmdline('FILLCOLUMN',$_[1]);},
'verbose' => "break Info lines at NUM characters (default ".get_conf('FILLCOLUMN').")",
};
$T2H_OPTIONS -> {'enable-encoding'} =
{
'type' => '',
'linkage' => sub {set_from_cmdline('ENABLE_ENCODING', $_[1]);},
'verbose' => 'override --disable-encoding (default in Info).',
};
$T2H_OPTIONS -> {'disable-encoding'} =
{
'type' => '',
'linkage' => sub {set_from_cmdline('ENABLE_ENCODING', 0);},
'verbose' => 'do not output accented and special characters
in Info output based on @documentencoding.',
};
$T2H_OPTIONS -> {'internal-links'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('INTERNAL_LINKS', $_[1]);},
'verbose' => 'produce list of internal links in FILE.'
};
$T2H_OPTIONS -> {'force|F'} =
{ 'type' => '!',
'linkage' => sub {set_from_cmdline('FORCE', $_[1]);},
'verbose' => 'preserve output even if errors.'
};
$T2H_OPTIONS -> {'commands-in-node-names'} =
{
'type' => '!',
'verbose' => 'Always set',
'noHelp' => 1
};
$T2H_OPTIONS -> {'output-indent'} =
{
'type' => '=i',
'verbose' => 'This option used to indent XML, it is ignored',
'noHelp' => 1
};
$T2H_OPTIONS -> {'program'} =
{
'type' => '=s',
'linkage' => sub {set_config_init_dirs_output($_[1]);},
'verbose' => 'Call as $s, setting corresponding defaults'
};
$T2H_OPTIONS -> {'reference-limit' } =
{
'type' => '=i',
'verbose' => 'Does nothing, retained for backward compatibility',
'noHelp' => 2
};
#$T2H_OPTIONS -> {'command'} =
#{
# 'type' => '=s',
# 'linkage' => \@Texi2HTML::Config::COMMANDS,
# 'verbose' => 'insert CMD in copy of input file'
#};
$T2H_OPTIONS -> {'Xopt'} =
{
'type' => '=s',
'linkage' => \@Texi2HTML::Config::TEXI2DVI_ARGUMENTS,
'verbose' => 'pass argument to the dvi/pdf converter.',
};
$T2H_OPTIONS -> {'batch'} =
{
'type' => '',
'linkage' => sub {set_from_cmdline('BATCH', $_[1]); add_to_texi2dvi_args('--'.$_[0]);},
'noHelp' => 2
};
$T2H_OPTIONS -> {'silent|quiet'} =
{
'type' => '',
'linkage' => sub {set_from_cmdline('SILENT', $_[1]); add_to_texi2dvi_args('--'.$_[0]);},
'noHelp' => 2
};
my $call_texi2dvi = 0;
foreach my $output_format (keys(%Texi2HTML::Config::output_format_names))
{
next if (defined($Texi2HTML::Config::DEFAULT_OUTPUT_FORMAT) and $output_format eq $Texi2HTML::Config::DEFAULT_OUTPUT_FORMAT);
my $linkage;
if ($Texi2HTML::Config::texi2dvi_formats{$output_format})
{
$linkage = sub {add_to_texi2dvi_args('--'.$_[0]); $call_texi2dvi = 1;
Texi2HTML::Config::t2h_default_load_format($_[0], 1);};
}
else
{
$linkage = sub {Texi2HTML::Config::t2h_default_load_format($_[0], 1);};
}
$T2H_OPTIONS -> {$output_format} =
{
'type' => '',
'linkage' => $linkage,
'verbose' => "output $Texi2HTML::Config::output_format_names{$output_format} rather than $Texi2HTML::Config::output_format_names{$Texi2HTML::Config::DEFAULT_OUTPUT_FORMAT}.",
}
};
$T2H_OPTIONS -> {$Texi2HTML::Config::DEFAULT_OUTPUT_FORMAT} =
{
'type' => '',
'linkage' => sub {Texi2HTML::Config::t2h_default_load_format($_[0], 1);},
'verbose' => "output default format.",
'noHelp' => 2
};
$T2H_OPTIONS -> {'debug'} =
{
'type' => '=i',
'linkage' => sub {set_from_cmdline('DEBUG', $_[1]), add_to_texi2dvi_args('--'.$_[0]); },
'verbose' => 'output debuging information',
'noHelp' => 1,
};
##
## obsolete cmd line options
##
my $T2H_OBSOLETE_OPTIONS;
$T2H_OBSOLETE_OPTIONS -> {'subdir'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('SUBDIR', $_[1]);},
'verbose' => 'put files in directory $s, not $cwd',
'noHelp' => 1,
};
# actually a noop, since it is not used anywhere
$T2H_OBSOLETE_OPTIONS -> {'invisible'} =
{
'type' => '=s',
'verbose' => 'Not used',
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {'toc-links'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('TOC_LINKS', $_[1]);},
'verbose' => 'create links from headings to toc entries',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'short-ext'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('SHORTEXTN', $_[1]);},
'verbose' => 'use "htm" extension for output HTML files',
'noHelp' => 1,
};
# FIXME this is not that helpful as a message, as reported by
# Jens Schleusener one could imagine that absolute paths are
# accepted.
$T2H_OBSOLETE_OPTIONS -> {'prefix'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('PREFIX', $_[1]);},
'verbose' => 'use as prefix for output files, instead of ',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'short-ref'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('SHORT_REF', $_[1]);},
'verbose' => 'if set, references are without section numbers',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'idx-sum'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('IDX_SUMMARY', $_[1]);},
'verbose' => 'if set, also output index summary',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'def-table'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('DEF_TABLE', $_[1]);},
'verbose' => 'if set, \@def.. are converted using tables.',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'ignore-preamble-text'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('IGNORE_PREAMBLE_TEXT', $_[1]);},
'verbose' => 'if set, ignore the text before @node and sectioning commands',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'html-xref-prefix'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('EXTERNAL_DIR', $_[1]);},
'verbose' => '$s is the base dir for external manual references',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'l2h'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('L2H', $_[1]);},
'verbose' => 'if set, uses latex2html for @math and @tex',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'l2h-l2h'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('L2H_L2H', $_[1]);},
'verbose' => 'program to use for latex2html translation',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'l2h-skip'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('L2H_SKIP', $_[1]);},
'verbose' => 'if set, tries to reuse previously latex2html output',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'l2h-tmp'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('L2H_TMP', $_[1]);},
'verbose' => 'if set, uses $s as temporary latex2html directory',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'l2h-file'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('L2H_FILE', $_[1]);},
'verbose' => 'if set, uses $s as latex2html init file',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'l2h-clean'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('L2H_CLEAN', $_[1]);},
'verbose' => 'if set, do not keep intermediate latex2html files for later reuse',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'use-nodes'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('USE_NODES', $_[1]);},
'verbose' => 'use nodes for sectioning',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'monolithic'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('MONOLITHIC', $_[1]);},
'verbose' => 'output only one file including ToC, About...',
'noHelp' => 1
};
$T2H_OBSOLETE_OPTIONS -> {'top-file'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('TOP_FILE', $_[1]);},
'verbose' => 'use $s as top file, instead of .html',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'toc-file'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('TOC_FILE', $_[1]);},
'verbose' => 'use $s as ToC file, instead of _toc.html',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'frames'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('FRAMES', $_[1])},
'verbose' => 'output files which use HTML 4.0 frames (experimental)',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'menu'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('SHOW_MENU', $_[1]);},
'verbose' => 'output Texinfo menus',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'iso'} =
{
'type' => 'iso',
'linkage' => sub {Texi2HTML::Config::t2h_default_set_iso_symbols ($_[1], 1);},
'verbose' => 'if set, entities are used for special symbols (like copyright, etc...) and quotes',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'doctype'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('DOCTYPE', $_[1]);},
'verbose' => 'document type which is output in header of HTML files',
'noHelp' => 1
};
$T2H_OBSOLETE_OPTIONS -> {'frameset-doctype'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('FRAMESET_DOCTYPE', $_[1]);},
'verbose' => 'document type for HTML frameset documents',
'noHelp' => 1
};
$T2H_OBSOLETE_OPTIONS -> {'test'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('TEST', $_[1]);},
'verbose' => 'use predefined information to avoid differences with reference files',
'noHelp' => 1
};
$T2H_OBSOLETE_OPTIONS -> {'dump-texi'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('DUMP_TEXI', $_[1]);},
'verbose' => 'dump the output of first pass into a file with extension passfirst and exit',
'noHelp' => 1
};
$T2H_OBSOLETE_OPTIONS -> {'expand'} =
{
'type' => '=s',
'linkage' => sub {Texi2HTML::Config::set_expansion($_[1], 1);},
'verbose' => 'Expand section of texinfo source',
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'no-expand'} =
{
'type' => '=s',
'linkage' => sub {Texi2HTML::Config::set_expansion ($_[1], 0);},
'verbose' => 'Don\'t expand the given section of texinfo source',
};
$T2H_OBSOLETE_OPTIONS -> {'noexpand'} =
{
'type' => '=s',
'linkage' => $T2H_OBSOLETE_OPTIONS->{'no-expand'}->{'linkage'},
'verbose' => $T2H_OBSOLETE_OPTIONS->{'no-expand'}->{'verbose'},
'noHelp' => 1,
};
$T2H_OBSOLETE_OPTIONS -> {'out-file'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('OUTFILE', $_[1]); set_from_cmdline('SPLIT', '');},
'verbose' => 'if set, all HTML output goes into file $s, obsoleted by "-output" with different semantics',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {'lang'} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('documentlanguage', $_[1])},
'verbose' => 'obsolete, use "--document-language" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {'separated-footnotes'} =
{
'type' => '!',
'linkage' => sub {my $style = 'separate'; $style = 'end' if !$_[1]; set_footnote_style ($style, 1);},
'verbose' => 'obsolete, use "--footnote-style" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {'Verbose'} =
{
'type' => '!',
linkage=> sub {set_from_cmdline('VERBOSE', $_[1]);},
'verbose' => 'obsolete, use "--verbose" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {init_file} =
{
'type' => '=s',
'linkage' => \&load_init_file,
'verbose' => 'obsolete, use "-init-file" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {l2h_clean} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('L2H_CLEAN', $_[1]);},
'verbose' => 'obsolete, use "-l2h-clean" instead',
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {l2h_l2h} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('L2H_L2H', $_[1]);},
'verbose' => 'obsolete, use "-l2h-l2h" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {l2h_skip} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('L2H_SKIP', $_[1]);},
'verbose' => 'obsolete, use "-l2h-skip" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {l2h_tmp} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('L2H_TMP', $_[1]);},
'verbose' => 'obsolete, use "-l2h-tmp" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {out_file} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('OUTFILE', $_[1]); set_from_cmdline('SPLIT', '');},
'verbose' => 'obsolete, use "-out-file" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {short_ref} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('SHORT_REF', $_[1]);},
'verbose' => 'obsolete, use "-short-ref" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {idx_sum} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('IDX_SUMMARY', $_[1]);},
'verbose' => 'obsolete, use "-idx-sum" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {def_table} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('DEF_TABLE', $_[1]);},
'verbose' => 'obsolete, use "-def-table" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {short_ext} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('SHORTEXTN', $_[1]);},
'verbose' => 'obsolete, use "-short-ext" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {sec_nav} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('HEADERS', $_[1]);},
'verbose' => 'obsolete, use "-headers" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {'sec-nav'} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('HEADERS', $_[1]);},
'verbose' => 'obsolete, use "--header" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {top_file} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('TOP_FILE', $_[1]);},
'verbose' => 'obsolete, use "-top-file" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {toc_file} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('TOC_FILE', $_[1]);},
'verbose' => 'obsolete, use "-toc-file" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {glossary} =
{
'type' => '!',
'verbose' => "this does nothing",
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {check} =
{
'type' => '!',
'linkage' => sub {exit 0;},
'verbose' => "exit without doing anything",
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {dump_texi} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('DUMP_TEXI', $_[1]);},
'verbose' => 'obsolete, use "-dump-texi" instead',
'noHelp' => 1
};
$T2H_OBSOLETE_OPTIONS -> {frameset_doctype} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('FRAMESET_DOCTYPE', $_[1]);},
'verbose' => 'obsolete, use "-frameset-doctype" instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {use_acc} =
{
'type' => '!',
'verbose' => 'obsolete, set to true unconditionnaly',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {expandinfo} =
{
'type' => '!',
'linkage' => sub {push @Texi2HTML::Config::EXPAND, 'info';},
'verbose' => 'obsolete, use "--ifinfo" instead',
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {expandtex} =
{
'type' => '!',
'linkage' => sub {push @Texi2HTML::Config::EXPAND, 'tex';},
'verbose' => 'obsolete, use "--iftex" instead',
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {split_node} =
{
'type' => '!',
'linkage' => sub{set_from_cmdline('SPLIT', 'section');},
'verbose' => 'obsolete, use "-split section" instead',
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {split_chapter} =
{
'type' => '!',
'linkage' => sub{set_from_cmdline('SPLIT', 'chapter');},
'verbose' => 'obsolete, use "-split chapter" instead',
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {no_verbose} =
{
'type' => '!',
'linkage' => sub{set_from_cmdline('VERBOSE', 0);},
'verbose' => 'obsolete, use -noverbose instead',
'noHelp' => 2,
};
$T2H_OBSOLETE_OPTIONS -> {output_file} =
{
'type' => '=s',
'linkage' => sub {set_from_cmdline('OUTFILE', $_[1]); set_from_cmdline('SPLIT','');},
'verbose' => 'obsolete, use --out-file instead',
'noHelp' => 2
};
$T2H_OBSOLETE_OPTIONS -> {section_navigation} =
{
'type' => '!',
'linkage' => sub {set_from_cmdline('HEADERS', $_[1]);},
'verbose' => 'obsolete, use --sec-nav instead',
'noHelp' => 2,
};
# read initialzation from $sysconfdir/texi2htmlrc or $HOME/.texi2htmlrc
# (this is obsolete). Obsoleted in 1.68 (March 20 2004).
my @rc_files = ();
push @rc_files, "$sysconfdir/texi2htmlrc" if defined($sysconfdir);
push @rc_files, "$ENV{'HOME'}/.texi2htmlrc" if (defined($ENV{'HOME'}));
foreach my $i (@rc_files)
{
if (-e $i and -r $i)
{
print STDERR "# reading initialization file from $i\n"
if ($T2H_VERBOSE);
print STDERR "Reading config from $i is obsolete, use texi2html/$conf_file_name instead\n";
Texi2HTML::Config::load($i);
}
}
# read initialization files
foreach my $file (locate_init_file($conf_file_name, [ reverse(@program_config_dirs) ], 1))
{
print STDERR "# reading initialization file from $file\n" if ($T2H_VERBOSE);
Texi2HTML::Config::load($file);
}
#+++############################################################################
# #
# parse command-line options
# #
#---############################################################################
# options known by makeinfo (+version, help and if*)
#my @makeinfo_options = ('error-limit', 'document-language',
#'force', 'help', 'no-validate', 'no-warn', 'verbose', 'docbook', 'html',
#'xml', 'plaintext', 'macro-expand', 'headers', 'no-split',
#'number-sections', 'output', 'disable-encoding', 'enable-encoding',
#'fill-column', 'footnote-style', 'paragraph-indent', 'split-size',
#'css-include', 'css-ref', 'internal-links', 'transliterate-file-names',
#'output-indent', 'number-footnotes', 'D', 'I', 'P', 'U');
# always used, even though they are not in makeinfo in C.
# split is in makeinfo in C, as --no-split.
# 'conf-dir', 'init-file' options have to be taken into account for proper
# functionning.
#my @basic_options = ('conf-dir', 'init-file',
#'split', 'program', 'set-init-variable');
# --command=CMD insert CMD in copy of input file
my $makeinfo_help =
sprintf(__("Usage: %s [OPTION]... TEXINFO-FILE...\n"), $real_command_name)
."\n".
__("Translate Texinfo source documentation to various other formats, by default
Info files suitable for reading online with Emacs or standalone GNU Info.\n")
."\n";
$makeinfo_help .= sprintf(__("General options:
--error-limit=NUM quit after NUM errors (default %d).
--document-language=STR locale to use in translating Texinfo keywords
for the output document (default C).
--force preserve output even if errors.
--help display this help and exit.
--no-validate suppress node cross-reference validation.
--no-warn suppress warnings (but not errors).
--conf-dir=DIR search also for initialization files in DIR.
--init-file=FILE load FILE to modify the default behaviour.
--set-init-variable VAR=VAL set configuration variable VAR to VAL.
-v, --verbose explain what is being done.
--version display version information and exit.\n"), get_conf('ERROR_LIMIT'))
."\n";
$makeinfo_help .= __("Output format selection (default is to produce Info):
--docbook output Docbook XML rather than Info.
--html output HTML rather than Info.
--xml output Texinfo XML rather than Info.
--plaintext output plain text rather than Info.\n")
."\n";
$makeinfo_help .= __("General output options:
-E, --macro-expand=FILE output macro-expanded source to FILE,
ignoring any \@setfilename.
--no-headers suppress node separators, Node: lines, and menus
from Info output (thus producing plain text)
or from HTML (thus producing shorter output);
also, write to standard output by default if
producing Info.
--split=SPLIT split at SPLIT, where SPLIT may be chapter,
section or node if output supports splitting.
--no-split suppress the splitting of Info or HTML output,
generate only one output file.
--number-sections output chapter and sectioning numbers.
-o, --output=FILE output to FILE (or directory if split).
If not split and FILE is a directory, put the
resulting files in FILE.\n")
."\n";
$makeinfo_help .= sprintf(__("Options for Info and plain text:
--disable-encoding do not output accented and special characters
in Info output based on \@documentencoding.
--enable-encoding override --disable-encoding (default).
--fill-column=NUM break Info lines at NUM characters (default %d).
--footnote-style=STYLE output footnotes in Info according to STYLE:
`separate' to put them in their own node;
`end' to put them at the end of the node, in
which they are defined (this is the default).
--paragraph-indent=VAL indent Info paragraphs by VAL spaces (default %d).
If VAL is `none', do not indent; if VAL is
`asis', preserve existing indentation.
--split-size=NUM split Info files at size NUM (default %d).\n"),
get_conf('FILLCOLUMN'), get_conf('paragraphindent'), get_conf('SPLIT_SIZE'))
."\n";
$makeinfo_help .= __("Options for HTML:
--css-include=FILE include FILE in HTML