#! @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 .= "" 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. "\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