=================================================================== RCS file: /home/cvs/OpenXM/src/asir-doc/Attic/texi2html,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -r1.2 -r1.3 --- OpenXM/src/asir-doc/Attic/texi2html 2009/02/22 04:59:56 1.2 +++ OpenXM/src/asir-doc/Attic/texi2html 2017/03/28 23:22:20 1.3 @@ -1,2131 +1,44671 @@ -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' - if 0; +#! /usr/local/bin/perl -- +# perl 'di '; 'ig 00 '; +# texi2html: generated by addformats.sh from texi2html.temp and formats/html.init formats/info.init formats/docbook.init formats/xml.init formats/plaintext.init +# texi2html.temp: generated by buildt2h.sh from texi2html_configured.pl and MySimple.pm T2h_i18n.pm texi2html.init translations.pl examples/l2h.init T2h_l2h.pm documentlanguages.pl #+############################################################################## -# # -# File: texi2html # -# # -# Description: Program to transform most Texinfo documents to HTML # -# # +# +# texi2html: Program to transform Texinfo documents to HTML +# +# Copyright (C) 1999-2010 Patrice Dumas , +# Derek Price , +# Adrian Aichner , +# & others. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA +# +# 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+. +# #-############################################################################## - -# From @(#)texi2html 1.52 01/05/98 Written (mainly) by Lionel Cons, Lionel.Cons@cern.ch -# $Id: texi2html,v 1.2 2009/02/22 04:59:56 takayama Exp $ -# This version of texi2html is currently maintained at -# ftp://ftp.cs.umb.edu/pub/tex/texi2html by kb@cs.umb.edu. - # The man page for this program is included at the end of this file and can be # viewed using the command 'nroff -man texi2html'. -# Please read the copyright at the end of the man page. -#+++############################################################################ -# # -# Constants # -# # -#---############################################################################ +# 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; -$DEBUG_TOC = 1; -$DEBUG_INDEX = 2; -$DEBUG_BIB = 4; -$DEBUG_GLOSS = 8; -$DEBUG_DEF = 16; -$DEBUG_HTML = 32; -$DEBUG_USER = 64; +#use encoding::warnings; +# for translations +#use encoding 'utf8'; +#use utf8; -$BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference -$FILERE = '[\/\w.+-]+'; # RE for a file name -$VARRE = '[^\s\{\}]+'; # RE for a variable name -$NODERE = '[^@{}:\'`",]+'; # RE for a node name -$NODESRE = '[^@{}:\'`"]+'; # RE for a list of node names -$XREFRE = '[^@{}]+'; # RE for a xref (should use NODERE) +# +# 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; -$ERROR = "***"; # prefix for errors and warnings -$THISVERSION = "1.56k"; -$THISPROG = "texi2html $THISVERSION"; # program name and version -$HOMEPAGE = "http://wwwinfo.cern.ch/dis/texi2html/"; # program home page -$TODAY = &pretty_date; # like "20 September 1993" -$SPLITTAG = "\n"; # tag to know where to split -$PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections -$html2_doctype = ''; +# determine the path separators +my $path_separator = $Config{'path_sep'}; +$path_separator = ':' if (!defined($path_separator)); +my $quoted_path_separator = quotemeta($path_separator); +#++########################################################################## # -# language dependent constants +# 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.init, T2h_i18n.pm, translations.pl, +# l2h.init, & T2h_l2h.pm files. Ditto makeinfo.pl, if you make it a +# symlink to texi2html.pl. # -#$LDC_SEE = 'see'; -#$LDC_SECTION = 'section'; -#$LDC_IN = 'in'; -#$LDC_TOC = 'Table of Contents'; -#$LDC_GOTO = 'Go to the'; -#$LDC_FOOT = 'Footnotes'; -# TODO: @def* shortcuts +#--########################################################################## +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,v 1.3 2017/03/28 23:22:20 takayama Exp $ + +# FIXME. Change for texinfo, and also simplify. + +# Homepage: +my $T2H_HOMEPAGE = "http://www.nongnu.org/texi2html/"; + +# Authors (appears in comments): +my $T2H_AUTHORS = < (original author) + Karl Berry + Olaf Bachmann + and many others. +Maintained by: Many creative people. +Send bugs and suggestions to +EOT + +# Version: set in configure.in +my $THISVERSION = '5.0'; +my $THISPROG = "texi2html $THISVERSION"; # program name and version + +#+++######################################################################## +# # +# Paths and file names # +# # +#---######################################################################## + +# set by configure, prefix for the sysconfdir and so on +my $prefix = '/usr/local'; +my $datarootdir;# = '${prefix}/share'; +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 ('${prefix}/etc' ne '@' . 'sysconfdir@') +{ + $sysconfdir = eval '"${prefix}/etc"'; +} +else +{ + $sysconfdir = "/usr/local/etc"; +} + +if ('${prefix}/share' ne '@' . 'datarootdir@') +{ + $datarootdir = eval '"${prefix}/share"'; +} +else +{ + $datarootdir = "/usr/local/share"; +} + +if ('${datarootdir}' ne '@' . 'datadir@') +{ + $pkgdatadir = eval '"${datarootdir}/texi2html"'; + $datadir = eval '"${datarootdir}"'; +} +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; + +#+++######################################################################## +# # +# 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 @texinfo_config_dirs = ('./.texinfo'); +push @texinfo_config_dirs, "$ENV{'HOME'}/.texinfo" if (defined($ENV{'HOME'})); +push @texinfo_config_dirs, "$sysconfdir/texinfo" if (defined($sysconfdir)); +push @texinfo_config_dirs, "$datadir/texinfo" if (defined($datadir)); + +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 = ('./'); + 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 (@texinfo_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.init, some functions that are not to be customized. # +# Pasted content of File $(srcdir)/texi2html.init: Default initializations # +# # +#---########################################################################### +{ +package Texi2HTML::Config; + +use Config; + +# customization options variables + +use vars qw( +$DEBUG +$PREFIX +$VERBOSE +$SUBDIR +$IDX_SUMMARY +$SPLIT +$SPLIT_SIZE +$SHORT_REF +@EXPAND +$TOP +$DOCTYPE +$FRAMESET_DOCTYPE +$ERROR_LIMIT +$CHECK +$TEST +$DUMP_TEXI +$MACRO_EXPAND +$CAPTION_STYLE +$USE_ISO +$TOP_FILE +$TOC_FILE +$FRAMES +$SHOW_MENU +$SHOW_TITLE +$NUMBER_SECTIONS +$NUMBER_FOOTNOTES +$USE_NODES +$USE_SECTIONS +$USE_NODE_TARGET +$USE_UNICODE +$USE_UNIDECODE +$TRANSLITERATE_FILE_NAMES +$NODE_FILES +$NODE_FILENAMES +$NODE_NAME_IN_MENU +$NODE_NAME_IN_INDEX +$AVOID_MENU_REDUNDANCY +$HEADERS +$NO_WARN +$FORCE +$MONOLITHIC +$SHORTEXTN +$EXTENSION +$OUT +$NOVALIDATE +$DEF_TABLE +$DOCUMENTLANGUAGE +$CONTENTS +$SHORTCONTENTS +$FOOTNOTESTYLE +$FILLCOLUMN +$SETCONTENTSAFTERTITLEPAGE +$SETSHORTCONTENTSAFTERTITLEPAGE +$KBDINPUTSTYLE +$FRENCHSPACING +$ALLOWCODEBREAKS +$SETFILENAME +$TOC_LINKS +$L2H +$L2H_L2H +$L2H_SKIP +$L2H_TMP +$L2H_CLEAN +$L2H_FILE +$L2H_HTML_VERSION +$EXTERNAL_DIR +@INCLUDE_DIRS +@PREPEND_DIRS +@CONF_DIRS +$IGNORE_PREAMBLE_TEXT +@CSS_FILES +@CSS_REFS +$INLINE_CONTENTS +$INLINE_INSERTCOPYING +$PARAGRAPHINDENT +$FIRSTPARAGRAPHINDENT +$ENABLE_ENCODING +$INTERNAL_LINKS +$DEFAULT_OUTPUT_FORMAT +$OUTPUT_FORMAT +$COMMAND_NAME +@COMMANDS +); + +# customization variables +use vars qw( +$ENCODING_NAME +$DOCUMENT_ENCODING +$OUT_ENCODING +$IN_ENCODING +$DEFAULT_ENCODING +$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 +$SPLIT_INDEX +$USE_MENU_DIRECTIONS +$USE_UP_FOR_ADJACENT_NODES +$AFTER_BODY_OPEN +$PRE_BODY_CLOSE +$EXTRA_HEAD +$VERTICAL_HEAD_NAVIGATION +$WORDS_IN_PAGE +$ICONS +$UNNUMBERED_SYMBOL_IN_MENU +$SIMPLE_MENU +$MENU_SYMBOL +$MENU_ENTRY_COLON +$INDEX_ENTRY_COLON +$USE_ACCESSKEY +$USE_REL_REV +$USE_LINKS +$OPEN_QUOTE_SYMBOL +$CLOSE_QUOTE_SYMBOL +$NO_NUMBER_FOOTNOTE_SYMBOL +$NO_BULLET_LIST_STYLE +$NO_BULLET_LIST_ATTRIBUTE +$NO_BULLET_LIST_CLASS +$TOP_NODE_FILE +$TOP_NODE_FILE_TARGET +$TOP_NODE_UP +$NODE_FILE_EXTENSION +$STDIN_DOCU_NAME +$STDOUT_DOCU_NAME +$BEFORE_OVERVIEW +$AFTER_OVERVIEW +$BEFORE_TOC_LINES +$AFTER_TOC_LINES +$NEW_CROSSREF_STYLE +$TOP_HEADING_AT_BEGINNING +$USE_NUMERIC_ENTITY +$USE_SETFILENAME +$USE_SETFILENAME_EXTENSION +$SEPARATE_DESCRIPTION +$IGNORE_BEFORE_SETFILENAME +$OVERVIEW_LINK_TO_TOC +$COMPLETE_IMAGE_PATHS +$DATE +%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 +$ENABLE_ENCODING_USE_ENTITY +$PROGRAM_NAME_IN_FOOTER +$HEADER_IN_TABLE +$DATE_IN_HEADER +$COMPLEX_FORMAT_IN_TABLE +$USE_TITLEPAGE_FOR_TITLE +$INLINE_CSS_STYLE +$NO_CSS +$I18N_PERL_HASH +$USE_NLS +); + +# customization variables which may be guessed in the script +#our $ADDRESS; +use vars qw( +$BODYTEXT +$CSS_LINES +$DOCUMENT_DESCRIPTION +$EXTERNAL_CROSSREF_SPLIT +); + +# 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 +%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 +); + +# deprecated +use vars qw( +$address +%iso_symbols +%simple_map_pre_math +%simple_map_texi_math +$ENCODING +$CENTER_IMAGE +$HREF_DIR_INSTEAD_FILE +$EXPAND +$USE_GLOSSARY +$INVISIBLE_MARK +); + +# 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', +); + +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\.init$/) + { + t2h_default_load_format($output_format, 1); + return 1; + } + } + eval { require($file) ;}; + if ($@ ne '') + { + print STDERR "error loading $file: $@\n"; + return 0; + } + return 1; +} + + +sub set_conf($$;$) +{ + my $name = shift; + my $value = shift; + my $not_global = shift; + + unless ($not_global) + { + if (defined($value)) + { + $Texi2HTML::GLOBAL{$name} = $value; + } + else + { + delete $Texi2HTML::GLOBAL{$name}; + } + return 1; + } + return 0 if (defined($Texi2HTML::GLOBAL{$name})); + if (defined($value)) + { + $Texi2HTML::THISDOC{$name} = $value; + } + else + { + delete $Texi2HTML::THISDOC{$name}; + } + return 1; +} + +my %config_map = ( + 'paragraphindent' => \$PARAGRAPHINDENT, + 'firstparagraphindent' => \$FIRSTPARAGRAPHINDENT, + 'footnotestyle' => \$FOOTNOTESTYLE, + 'fillcolumn' => \$FILLCOLUMN, + 'documentlanguage' => \$DOCUMENTLANGUAGE, + 'novalidate' => \$NOVALIDATE, + 'SPLIT' => \$SPLIT, + 'SPLIT_SIZE' => \$SPLIT_SIZE, + 'contents' => \$CONTENTS, + 'shortcontents' => \$SHORTCONTENTS, + 'doctype' => \$DOCTYPE, + 'headers' => \$HEADERS, + 'DOCUMENT_ENCODING' => \$DOCUMENT_ENCODING, + 'IN_ENCODING' => \$IN_ENCODING, + 'setcontentsaftertitlepage' => \$SETCONTENTSAFTERTITLEPAGE, + 'setshortcontentsaftertitlepage' => \$SETSHORTCONTENTSAFTERTITLEPAGE, + 'kbdinputstyle' => \$KBDINPUTSTYLE, + 'frenchspacing' => \$FRENCHSPACING, + 'allowcodebreaks' => \$ALLOWCODEBREAKS, + 'setfilename' => \$SETFILENAME, + 'use_nls' => \$USE_NLS, +); + +sub get_conf($) +{ + my $name = shift; + return $Texi2HTML::THISDOC{$name} if (defined($Texi2HTML::THISDOC{$name})); + return $Texi2HTML::GLOBAL{$name} if (defined($Texi2HTML::GLOBAL{$name})); + return ${$config_map{$name}} if (defined($config_map{$name})); + # there is no default value for many @-commmands, like headings.... + #print STDERR "Unknown conf string: $name\n"; +} + +# 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]; +} + # -# pre-defined indices +# Function refs covered by the GPL as part of the texi2html.pl original +# code. As such they cannot appear in texi2html.init which is public +# domain (at least the things coded by me, and, if I'm not wrong also the +# things coded by Olaf -- Pat). # -%predefined_index = ( - 'cp', 'c', - 'fn', 'f', - 'vr', 'v', - 'ky', 'k', - 'pg', 'p', - 'tp', 't', - ); +sub HTML_DEFAULT_shortcontents($$) +{ + my $elements_list = shift; + my $stoc_file = shift; + return unless (Texi2HTML::Config::get_conf('shortcontents') or $FRAMES); + my $ul_class = ''; + $ul_class = $NO_BULLET_LIST_CLASS if ($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 ($Texi2HTML::Config::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 (Texi2HTML::Config::get_conf('contents')); + + my $current_level = 0; + my $ul_class = ''; + $ul_class = $NO_BULLET_LIST_CLASS if ($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 = $OPEN_QUOTE_SYMBOL . "$text" if (!$no_open); + $text .= $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 = $OPEN_QUOTE_SYMBOL . "$text" if (!$no_open); + $text .= $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 $SPLIT_INDEX and $entries_count >= $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 .= '.' . $Texi2HTML::THISDOC{'extension'} if + (defined($Texi2HTML::THISDOC{'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("\@sectionning_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 .= '.' . $Texi2HTML::THISDOC{'extension'} if + (defined($Texi2HTML::THISDOC{'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->{'Following'}) + { +#print STDERR "F: C($current_element): $current_element->{'texi'}, N($new_element): $new_element->{'texi'} -- C->F: $current_element->{'Following'}->{'texi'}\n"; + $new_element->{'Following'} = $current_element->{'Following'}; + $current_element->{'Following'} = $new_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). # -# valid indices +# 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 ($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 ($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 # -%valid_index = ( - 'c', 1, - 'f', 1, - 'v', 1, - 'k', 1, - 'p', 1, - 't', 1, - ); +#$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 Texi2HTML::Config::get_conf('SPLIT') eq 'chapter'; + &$print_section_header($Texi2HTML::THISDOC{'FH'}, $new_element) if Texi2HTML::Config::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. # -# texinfo section names to level +# @T2H_DOCUMENT_LANGUAGES@ +%language_codes = ( +'aa' => 1, +'ab' => 1, +'ae' => 1, +'af' => 1, +'ak' => 1, +'am' => 1, +'an' => 1, +'ar' => 1, +'as' => 1, +'av' => 1, +'ay' => 1, +'az' => 1, +'ba' => 1, +'be' => 1, +'bg' => 1, +'bh' => 1, +'bi' => 1, +'bm' => 1, +'bn' => 1, +'bo' => 1, +'br' => 1, +'ca' => 1, +'ce' => 1, +'ch' => 1, +'co' => 1, +'cr' => 1, +'cs' => 1, +'cu' => 1, +'cv' => 1, +'cy' => 1, +'da' => 1, +'de' => 1, +'dv' => 1, +'dz' => 1, +'ee' => 1, +'el' => 1, +'en' => 1, +'eo' => 1, +'es' => 1, +'et' => 1, +'eu' => 1, +'fa' => 1, +'ff' => 1, +'fi' => 1, +'fj' => 1, +'fo' => 1, +'fr' => 1, +'fy' => 1, +'ga' => 1, +'gd' => 1, +'gl' => 1, +'gn' => 1, +'gu' => 1, +'gv' => 1, +'ha' => 1, +'he' => 1, +'hi' => 1, +'ho' => 1, +'ht' => 1, +'hu' => 1, +'hy' => 1, +'hz' => 1, +'ia' => 1, +'ie' => 1, +'ig' => 1, +'ii' => 1, +'ik' => 1, +'io' => 1, +'is' => 1, +'it' => 1, +'iu' => 1, +'iw' => 1, +'ja' => 1, +'ji' => 1, +'jv' => 1, +'jw' => 1, +'ka' => 1, +'kg' => 1, +'ki' => 1, +'kj' => 1, +'kk' => 1, +'kl' => 1, +'km' => 1, +'kn' => 1, +'ko' => 1, +'kr' => 1, +'ks' => 1, +'ku' => 1, +'kv' => 1, +'kw' => 1, +'ky' => 1, +'la' => 1, +'lb' => 1, +'lg' => 1, +'li' => 1, +'ln' => 1, +'lo' => 1, +'lt' => 1, +'lu' => 1, +'lv' => 1, +'mg' => 1, +'mh' => 1, +'mi' => 1, +'mk' => 1, +'ml' => 1, +'mn' => 1, +'mo' => 1, +'mr' => 1, +'ms' => 1, +'mt' => 1, +'my' => 1, +'na' => 1, +'nd' => 1, +'ne' => 1, +'ng' => 1, +'nl' => 1, +'no' => 1, +'nr' => 1, +'nv' => 1, +'ny' => 1, +'oc' => 1, +'oj' => 1, +'om' => 1, +'or' => 1, +'os' => 1, +'pa' => 1, +'pi' => 1, +'pl' => 1, +'ps' => 1, +'pt' => 1, +'qu' => 1, +'rm' => 1, +'rn' => 1, +'ro' => 1, +'ru' => 1, +'rw' => 1, +'sa' => 1, +'sc' => 1, +'sd' => 1, +'se' => 1, +'sg' => 1, +'sh' => 1, +'si' => 1, +'sk' => 1, +'sl' => 1, +'sm' => 1, +'sn' => 1, +'so' => 1, +'sq' => 1, +'ss' => 1, +'st' => 1, +'su' => 1, +'sv' => 1, +'sw' => 1, +'ta' => 1, +'te' => 1, +'tg' => 1, +'th' => 1, +'ti' => 1, +'tk' => 1, +'tl' => 1, +'tn' => 1, +'to' => 1, +'tr' => 1, +'ts' => 1, +'tt' => 1, +'ty' => 1, +'ug' => 1, +'uk' => 1, +'ur' => 1, +'uz' => 1, +'ve' => 1, +'vi' => 1, +'vo' => 1, +'wa' => 1, +'wo' => 1, +'xh' => 1, +'yi' => 1, +'yo' => 1, +'za' => 1, +'zh' => 1, +'zu' => 1, +'aaa' => 1, +'aab' => 1, +'aac' => 1, +'aad' => 1, +'aaf' => 1, +'aag' => 1, +'aah' => 1, +'aai' => 1, +'aak' => 1, +'aal' => 1, +'aam' => 1, +'aan' => 1, +'aap' => 1, +'aaq' => 1, +'aas' => 1, +'aau' => 1, +'aav' => 1, +'aaw' => 1, +'aax' => 1, +'aaz' => 1, +'aba' => 1, +'abb' => 1, +'abc' => 1, +'abd' => 1, +'abe' => 1, +'abf' => 1, +'abg' => 1, +'abi' => 1, +'abj' => 1, +'abl' => 1, +'abm' => 1, +'abn' => 1, +'abo' => 1, +'abp' => 1, +'abq' => 1, +'abr' => 1, +'abs' => 1, +'abt' => 1, +'abu' => 1, +'abw' => 1, +'abx' => 1, +'aby' => 1, +'abz' => 1, +'aca' => 1, +'acb' => 1, +'acd' => 1, +'ace' => 1, +'acf' => 1, +'ach' => 1, +'aci' => 1, +'ack' => 1, +'acl' => 1, +'acn' => 1, +'acp' => 1, +'acr' => 1, +'acs' => 1, +'act' => 1, +'acu' => 1, +'acv' => 1, +'acz' => 1, +'ada' => 1, +'adb' => 1, +'add' => 1, +'ade' => 1, +'adg' => 1, +'adh' => 1, +'adi' => 1, +'adj' => 1, +'adl' => 1, +'adn' => 1, +'ado' => 1, +'adp' => 1, +'adq' => 1, +'adr' => 1, +'ads' => 1, +'adt' => 1, +'adu' => 1, +'adw' => 1, +'adx' => 1, +'ady' => 1, +'adz' => 1, +'aea' => 1, +'aed' => 1, +'aee' => 1, +'aek' => 1, +'ael' => 1, +'aem' => 1, +'aen' => 1, +'aeq' => 1, +'aer' => 1, +'aes' => 1, +'aeu' => 1, +'aew' => 1, +'aey' => 1, +'aez' => 1, +'afa' => 1, +'afd' => 1, +'afe' => 1, +'afg' => 1, +'afh' => 1, +'afi' => 1, +'afk' => 1, +'afn' => 1, +'afo' => 1, +'afp' => 1, +'afs' => 1, +'aft' => 1, +'afu' => 1, +'afz' => 1, +'aga' => 1, +'agb' => 1, +'agc' => 1, +'agd' => 1, +'age' => 1, +'agf' => 1, +'agg' => 1, +'agh' => 1, +'agi' => 1, +'agj' => 1, +'agk' => 1, +'agl' => 1, +'agm' => 1, +'agn' => 1, +'ago' => 1, +'agp' => 1, +'agq' => 1, +'agr' => 1, +'ags' => 1, +'agt' => 1, +'agu' => 1, +'agv' => 1, +'agw' => 1, +'agx' => 1, +'agy' => 1, +'agz' => 1, +'aha' => 1, +'ahb' => 1, +'ahg' => 1, +'ahh' => 1, +'ahi' => 1, +'ahk' => 1, +'ahl' => 1, +'ahm' => 1, +'ahn' => 1, +'aho' => 1, +'ahp' => 1, +'ahr' => 1, +'ahs' => 1, +'aht' => 1, +'aia' => 1, +'aib' => 1, +'aic' => 1, +'aid' => 1, +'aie' => 1, +'aif' => 1, +'aig' => 1, +'aih' => 1, +'aij' => 1, +'aik' => 1, +'ail' => 1, +'aim' => 1, +'ain' => 1, +'aio' => 1, +'aip' => 1, +'aiq' => 1, +'air' => 1, +'ais' => 1, +'ait' => 1, +'aiw' => 1, +'aix' => 1, +'aiy' => 1, +'aja' => 1, +'ajg' => 1, +'aji' => 1, +'ajw' => 1, +'ajz' => 1, +'akb' => 1, +'akc' => 1, +'akd' => 1, +'ake' => 1, +'akf' => 1, +'akg' => 1, +'akh' => 1, +'aki' => 1, +'akj' => 1, +'akk' => 1, +'akl' => 1, +'akm' => 1, +'ako' => 1, +'akp' => 1, +'akq' => 1, +'akr' => 1, +'aks' => 1, +'akt' => 1, +'aku' => 1, +'akv' => 1, +'akw' => 1, +'akx' => 1, +'aky' => 1, +'akz' => 1, +'ala' => 1, +'alc' => 1, +'ald' => 1, +'ale' => 1, +'alf' => 1, +'alg' => 1, +'alh' => 1, +'ali' => 1, +'alj' => 1, +'alk' => 1, +'all' => 1, +'alm' => 1, +'alo' => 1, +'alp' => 1, +'alq' => 1, +'alr' => 1, +'alt' => 1, +'alu' => 1, +'alv' => 1, +'alw' => 1, +'alx' => 1, +'aly' => 1, +'alz' => 1, +'ama' => 1, +'amb' => 1, +'amc' => 1, +'ame' => 1, +'amf' => 1, +'amg' => 1, +'ami' => 1, +'amj' => 1, +'amk' => 1, +'aml' => 1, +'amm' => 1, +'amn' => 1, +'amo' => 1, +'amp' => 1, +'amq' => 1, +'amr' => 1, +'ams' => 1, +'amt' => 1, +'amu' => 1, +'amv' => 1, +'amw' => 1, +'amx' => 1, +'amy' => 1, +'amz' => 1, +'ana' => 1, +'anb' => 1, +'anc' => 1, +'and' => 1, +'ane' => 1, +'anf' => 1, +'ang' => 1, +'anh' => 1, +'ani' => 1, +'anj' => 1, +'ank' => 1, +'anl' => 1, +'anm' => 1, +'ann' => 1, +'ano' => 1, +'anp' => 1, +'anq' => 1, +'anr' => 1, +'ans' => 1, +'ant' => 1, +'anu' => 1, +'anv' => 1, +'anw' => 1, +'anx' => 1, +'any' => 1, +'anz' => 1, +'aoa' => 1, +'aob' => 1, +'aoc' => 1, +'aod' => 1, +'aoe' => 1, +'aof' => 1, +'aog' => 1, +'aoh' => 1, +'aoi' => 1, +'aoj' => 1, +'aok' => 1, +'aol' => 1, +'aom' => 1, +'aon' => 1, +'aor' => 1, +'aos' => 1, +'aot' => 1, +'aox' => 1, +'aoz' => 1, +'apa' => 1, +'apb' => 1, +'ape' => 1, +'apg' => 1, +'aph' => 1, +'api' => 1, +'apj' => 1, +'apk' => 1, +'apl' => 1, +'apm' => 1, +'apn' => 1, +'apo' => 1, +'app' => 1, +'apq' => 1, +'apr' => 1, +'aps' => 1, +'apt' => 1, +'apu' => 1, +'apv' => 1, +'apw' => 1, +'apx' => 1, +'apy' => 1, +'apz' => 1, +'aqa' => 1, +'aqc' => 1, +'aqg' => 1, +'aql' => 1, +'aqm' => 1, +'aqn' => 1, +'aqp' => 1, +'aqr' => 1, +'arc' => 1, +'ard' => 1, +'are' => 1, +'arh' => 1, +'ari' => 1, +'arj' => 1, +'ark' => 1, +'arl' => 1, +'arn' => 1, +'aro' => 1, +'arp' => 1, +'arr' => 1, +'art' => 1, +'aru' => 1, +'arv' => 1, +'arw' => 1, +'arx' => 1, +'asa' => 1, +'asb' => 1, +'asc' => 1, +'asd' => 1, +'ase' => 1, +'asf' => 1, +'asg' => 1, +'ash' => 1, +'asi' => 1, +'asj' => 1, +'ask' => 1, +'asl' => 1, +'asn' => 1, +'aso' => 1, +'asp' => 1, +'asq' => 1, +'asr' => 1, +'ass' => 1, +'ast' => 1, +'asu' => 1, +'asv' => 1, +'asw' => 1, +'asx' => 1, +'asy' => 1, +'asz' => 1, +'ata' => 1, +'atb' => 1, +'atc' => 1, +'atd' => 1, +'ate' => 1, +'atg' => 1, +'ath' => 1, +'ati' => 1, +'atj' => 1, +'atk' => 1, +'atl' => 1, +'atm' => 1, +'atn' => 1, +'ato' => 1, +'atp' => 1, +'atq' => 1, +'atr' => 1, +'ats' => 1, +'att' => 1, +'atu' => 1, +'atv' => 1, +'atw' => 1, +'atx' => 1, +'aty' => 1, +'atz' => 1, +'aua' => 1, +'aub' => 1, +'auc' => 1, +'aud' => 1, +'aue' => 1, +'auf' => 1, +'aug' => 1, +'auh' => 1, +'aui' => 1, +'auj' => 1, +'auk' => 1, +'aul' => 1, +'aum' => 1, +'aun' => 1, +'auo' => 1, +'aup' => 1, +'auq' => 1, +'aur' => 1, +'aus' => 1, +'aut' => 1, +'auu' => 1, +'auw' => 1, +'aux' => 1, +'auy' => 1, +'avb' => 1, +'avd' => 1, +'avi' => 1, +'avk' => 1, +'avn' => 1, +'avo' => 1, +'avs' => 1, +'avt' => 1, +'avu' => 1, +'avv' => 1, +'awa' => 1, +'awb' => 1, +'awc' => 1, +'awd' => 1, +'awe' => 1, +'awh' => 1, +'awi' => 1, +'awk' => 1, +'awm' => 1, +'awn' => 1, +'awo' => 1, +'awr' => 1, +'aws' => 1, +'awt' => 1, +'awu' => 1, +'awv' => 1, +'aww' => 1, +'awx' => 1, +'awy' => 1, +'axb' => 1, +'axg' => 1, +'axk' => 1, +'axm' => 1, +'axx' => 1, +'aya' => 1, +'ayb' => 1, +'ayd' => 1, +'aye' => 1, +'ayg' => 1, +'ayi' => 1, +'ayk' => 1, +'ayo' => 1, +'ayq' => 1, +'ays' => 1, +'ayt' => 1, +'ayu' => 1, +'ayx' => 1, +'ayy' => 1, +'ayz' => 1, +'aza' => 1, +'azc' => 1, +'azg' => 1, +'azm' => 1, +'azo' => 1, +'azt' => 1, +'azz' => 1, +'baa' => 1, +'bab' => 1, +'bac' => 1, +'bad' => 1, +'bae' => 1, +'baf' => 1, +'bag' => 1, +'bah' => 1, +'bai' => 1, +'baj' => 1, +'bal' => 1, +'ban' => 1, +'bao' => 1, +'bap' => 1, +'bar' => 1, +'bas' => 1, +'bat' => 1, +'bau' => 1, +'bav' => 1, +'baw' => 1, +'bax' => 1, +'bay' => 1, +'baz' => 1, +'bba' => 1, +'bbb' => 1, +'bbc' => 1, +'bbd' => 1, +'bbe' => 1, +'bbf' => 1, +'bbg' => 1, +'bbh' => 1, +'bbi' => 1, +'bbj' => 1, +'bbk' => 1, +'bbl' => 1, +'bbm' => 1, +'bbn' => 1, +'bbo' => 1, +'bbp' => 1, +'bbq' => 1, +'bbr' => 1, +'bbs' => 1, +'bbt' => 1, +'bbu' => 1, +'bbv' => 1, +'bbw' => 1, +'bbx' => 1, +'bby' => 1, +'bca' => 1, +'bcb' => 1, +'bcd' => 1, +'bce' => 1, +'bcf' => 1, +'bcg' => 1, +'bch' => 1, +'bci' => 1, +'bcj' => 1, +'bck' => 1, +'bcm' => 1, +'bcn' => 1, +'bco' => 1, +'bcp' => 1, +'bcq' => 1, +'bcr' => 1, +'bcs' => 1, +'bct' => 1, +'bcu' => 1, +'bcv' => 1, +'bcw' => 1, +'bcy' => 1, +'bcz' => 1, +'bda' => 1, +'bdb' => 1, +'bdc' => 1, +'bdd' => 1, +'bde' => 1, +'bdg' => 1, +'bdh' => 1, +'bdi' => 1, +'bdj' => 1, +'bdk' => 1, +'bdl' => 1, +'bdm' => 1, +'bdn' => 1, +'bdo' => 1, +'bdp' => 1, +'bdq' => 1, +'bdr' => 1, +'bds' => 1, +'bdu' => 1, +'bdv' => 1, +'bdw' => 1, +'bdx' => 1, +'bdy' => 1, +'bdz' => 1, +'bea' => 1, +'beb' => 1, +'bec' => 1, +'bed' => 1, +'bee' => 1, +'bef' => 1, +'beg' => 1, +'beh' => 1, +'bei' => 1, +'bej' => 1, +'bek' => 1, +'bem' => 1, +'beo' => 1, +'bep' => 1, +'beq' => 1, +'ber' => 1, +'bes' => 1, +'bet' => 1, +'beu' => 1, +'bev' => 1, +'bew' => 1, +'bex' => 1, +'bey' => 1, +'bez' => 1, +'bfa' => 1, +'bfb' => 1, +'bfc' => 1, +'bfd' => 1, +'bfe' => 1, +'bff' => 1, +'bfg' => 1, +'bfh' => 1, +'bfi' => 1, +'bfj' => 1, +'bfk' => 1, +'bfl' => 1, +'bfm' => 1, +'bfn' => 1, +'bfo' => 1, +'bfp' => 1, +'bfq' => 1, +'bfr' => 1, +'bfs' => 1, +'bft' => 1, +'bfu' => 1, +'bfw' => 1, +'bfy' => 1, +'bfz' => 1, +'bga' => 1, +'bgb' => 1, +'bgc' => 1, +'bgd' => 1, +'bge' => 1, +'bgf' => 1, +'bgg' => 1, +'bgi' => 1, +'bgj' => 1, +'bgk' => 1, +'bgl' => 1, +'bgm' => 1, +'bgo' => 1, +'bgr' => 1, +'bgs' => 1, +'bgt' => 1, +'bgu' => 1, +'bgv' => 1, +'bgw' => 1, +'bgx' => 1, +'bgy' => 1, +'bgz' => 1, +'bha' => 1, +'bhb' => 1, +'bhc' => 1, +'bhd' => 1, +'bhe' => 1, +'bhf' => 1, +'bhg' => 1, +'bhh' => 1, +'bhi' => 1, +'bhj' => 1, +'bhl' => 1, +'bhm' => 1, +'bhn' => 1, +'bho' => 1, +'bhp' => 1, +'bhq' => 1, +'bhs' => 1, +'bht' => 1, +'bhu' => 1, +'bhv' => 1, +'bhw' => 1, +'bhx' => 1, +'bhy' => 1, +'bhz' => 1, +'bia' => 1, +'bib' => 1, +'bic' => 1, +'bid' => 1, +'bie' => 1, +'bif' => 1, +'big' => 1, +'bij' => 1, +'bik' => 1, +'bil' => 1, +'bim' => 1, +'bin' => 1, +'bio' => 1, +'bip' => 1, +'biq' => 1, +'bir' => 1, +'bit' => 1, +'biu' => 1, +'biv' => 1, +'biw' => 1, +'bix' => 1, +'biy' => 1, +'biz' => 1, +'bja' => 1, +'bjb' => 1, +'bjc' => 1, +'bjd' => 1, +'bje' => 1, +'bjf' => 1, +'bjg' => 1, +'bjh' => 1, +'bji' => 1, +'bjj' => 1, +'bjk' => 1, +'bjl' => 1, +'bjm' => 1, +'bjo' => 1, +'bjr' => 1, +'bjs' => 1, +'bjt' => 1, +'bju' => 1, +'bjv' => 1, +'bjw' => 1, +'bjx' => 1, +'bjy' => 1, +'bjz' => 1, +'bka' => 1, +'bkb' => 1, +'bkc' => 1, +'bkd' => 1, +'bkf' => 1, +'bkg' => 1, +'bkh' => 1, +'bki' => 1, +'bkj' => 1, +'bkk' => 1, +'bkl' => 1, +'bkm' => 1, +'bkn' => 1, +'bko' => 1, +'bkp' => 1, +'bkq' => 1, +'bkr' => 1, +'bks' => 1, +'bkt' => 1, +'bku' => 1, +'bkv' => 1, +'bkw' => 1, +'bkx' => 1, +'bky' => 1, +'bkz' => 1, +'bla' => 1, +'blb' => 1, +'blc' => 1, +'bld' => 1, +'ble' => 1, +'blf' => 1, +'blg' => 1, +'blh' => 1, +'bli' => 1, +'blj' => 1, +'blk' => 1, +'bll' => 1, +'blm' => 1, +'blo' => 1, +'blp' => 1, +'blq' => 1, +'blr' => 1, +'bls' => 1, +'blt' => 1, +'blv' => 1, +'blw' => 1, +'blx' => 1, +'bly' => 1, +'blz' => 1, +'bma' => 1, +'bmb' => 1, +'bmc' => 1, +'bmd' => 1, +'bme' => 1, +'bmf' => 1, +'bmg' => 1, +'bmh' => 1, +'bmi' => 1, +'bmj' => 1, +'bmk' => 1, +'bml' => 1, +'bmn' => 1, +'bmo' => 1, +'bmp' => 1, +'bmq' => 1, +'bmr' => 1, +'bms' => 1, +'bmt' => 1, +'bmu' => 1, +'bmv' => 1, +'bmw' => 1, +'bmx' => 1, +'bmy' => 1, +'bmz' => 1, +'bna' => 1, +'bnb' => 1, +'bnc' => 1, +'bnd' => 1, +'bne' => 1, +'bnf' => 1, +'bng' => 1, +'bni' => 1, +'bnj' => 1, +'bnk' => 1, +'bnl' => 1, +'bnm' => 1, +'bnn' => 1, +'bno' => 1, +'bnp' => 1, +'bnq' => 1, +'bnr' => 1, +'bns' => 1, +'bnt' => 1, +'bnu' => 1, +'bnv' => 1, +'bnw' => 1, +'bnx' => 1, +'bny' => 1, +'bnz' => 1, +'boa' => 1, +'bob' => 1, +'boe' => 1, +'bof' => 1, +'bog' => 1, +'boh' => 1, +'boi' => 1, +'boj' => 1, +'bok' => 1, +'bol' => 1, +'bom' => 1, +'bon' => 1, +'boo' => 1, +'bop' => 1, +'boq' => 1, +'bor' => 1, +'bot' => 1, +'bou' => 1, +'bov' => 1, +'bow' => 1, +'box' => 1, +'boy' => 1, +'boz' => 1, +'bpa' => 1, +'bpb' => 1, +'bpd' => 1, +'bpg' => 1, +'bph' => 1, +'bpi' => 1, +'bpj' => 1, +'bpk' => 1, +'bpl' => 1, +'bpm' => 1, +'bpn' => 1, +'bpo' => 1, +'bpp' => 1, +'bpq' => 1, +'bpr' => 1, +'bps' => 1, +'bpt' => 1, +'bpu' => 1, +'bpv' => 1, +'bpw' => 1, +'bpx' => 1, +'bpy' => 1, +'bpz' => 1, +'bqa' => 1, +'bqb' => 1, +'bqc' => 1, +'bqd' => 1, +'bqf' => 1, +'bqg' => 1, +'bqh' => 1, +'bqi' => 1, +'bqj' => 1, +'bqk' => 1, +'bql' => 1, +'bqm' => 1, +'bqn' => 1, +'bqo' => 1, +'bqp' => 1, +'bqq' => 1, +'bqr' => 1, +'bqs' => 1, +'bqt' => 1, +'bqu' => 1, +'bqv' => 1, +'bqw' => 1, +'bqx' => 1, +'bqy' => 1, +'bqz' => 1, +'bra' => 1, +'brb' => 1, +'brc' => 1, +'brd' => 1, +'brf' => 1, +'brg' => 1, +'brh' => 1, +'bri' => 1, +'brj' => 1, +'brk' => 1, +'brl' => 1, +'brm' => 1, +'brn' => 1, +'bro' => 1, +'brp' => 1, +'brq' => 1, +'brr' => 1, +'brs' => 1, +'brt' => 1, +'bru' => 1, +'brv' => 1, +'brw' => 1, +'brx' => 1, +'bry' => 1, +'brz' => 1, +'bsa' => 1, +'bsb' => 1, +'bsc' => 1, +'bse' => 1, +'bsf' => 1, +'bsg' => 1, +'bsh' => 1, +'bsi' => 1, +'bsj' => 1, +'bsk' => 1, +'bsl' => 1, +'bsm' => 1, +'bsn' => 1, +'bso' => 1, +'bsp' => 1, +'bsq' => 1, +'bsr' => 1, +'bss' => 1, +'bst' => 1, +'bsu' => 1, +'bsv' => 1, +'bsw' => 1, +'bsx' => 1, +'bsy' => 1, +'bta' => 1, +'btb' => 1, +'btc' => 1, +'btd' => 1, +'bte' => 1, +'btf' => 1, +'btg' => 1, +'bth' => 1, +'bti' => 1, +'btk' => 1, +'btl' => 1, +'btm' => 1, +'btn' => 1, +'btp' => 1, +'btq' => 1, +'btr' => 1, +'bts' => 1, +'btt' => 1, +'btu' => 1, +'btv' => 1, +'btw' => 1, +'btx' => 1, +'bty' => 1, +'btz' => 1, +'bua' => 1, +'bub' => 1, +'buc' => 1, +'bud' => 1, +'bue' => 1, +'buf' => 1, +'bug' => 1, +'buh' => 1, +'bui' => 1, +'buj' => 1, +'buk' => 1, +'bum' => 1, +'bun' => 1, +'buo' => 1, +'bup' => 1, +'buq' => 1, +'bus' => 1, +'but' => 1, +'buu' => 1, +'buv' => 1, +'buw' => 1, +'bux' => 1, +'buy' => 1, +'buz' => 1, +'bva' => 1, +'bvb' => 1, +'bvc' => 1, +'bvd' => 1, +'bvf' => 1, +'bvg' => 1, +'bvh' => 1, +'bvi' => 1, +'bvj' => 1, +'bvk' => 1, +'bvl' => 1, +'bvm' => 1, +'bvn' => 1, +'bvo' => 1, +'bvq' => 1, +'bvr' => 1, +'bvt' => 1, +'bvv' => 1, +'bvw' => 1, +'bvx' => 1, +'bvz' => 1, +'bwa' => 1, +'bwb' => 1, +'bwc' => 1, +'bwd' => 1, +'bwe' => 1, +'bwf' => 1, +'bwg' => 1, +'bwh' => 1, +'bwi' => 1, +'bwj' => 1, +'bwk' => 1, +'bwl' => 1, +'bwm' => 1, +'bwn' => 1, +'bwo' => 1, +'bwp' => 1, +'bwq' => 1, +'bwr' => 1, +'bws' => 1, +'bwt' => 1, +'bwu' => 1, +'bww' => 1, +'bwx' => 1, +'bwy' => 1, +'bwz' => 1, +'bxa' => 1, +'bxb' => 1, +'bxc' => 1, +'bxd' => 1, +'bxe' => 1, +'bxf' => 1, +'bxg' => 1, +'bxh' => 1, +'bxi' => 1, +'bxj' => 1, +'bxl' => 1, +'bxn' => 1, +'bxo' => 1, +'bxp' => 1, +'bxq' => 1, +'bxs' => 1, +'bxv' => 1, +'bxw' => 1, +'bxx' => 1, +'bxz' => 1, +'bya' => 1, +'byb' => 1, +'byc' => 1, +'byd' => 1, +'bye' => 1, +'byf' => 1, +'byg' => 1, +'byh' => 1, +'byi' => 1, +'byj' => 1, +'byk' => 1, +'byl' => 1, +'bym' => 1, +'byn' => 1, +'byo' => 1, +'byp' => 1, +'byq' => 1, +'byr' => 1, +'bys' => 1, +'byt' => 1, +'byv' => 1, +'byw' => 1, +'byx' => 1, +'byy' => 1, +'byz' => 1, +'bza' => 1, +'bzb' => 1, +'bzd' => 1, +'bze' => 1, +'bzf' => 1, +'bzg' => 1, +'bzh' => 1, +'bzi' => 1, +'bzj' => 1, +'bzk' => 1, +'bzl' => 1, +'bzm' => 1, +'bzn' => 1, +'bzo' => 1, +'bzp' => 1, +'bzq' => 1, +'bzr' => 1, +'bzs' => 1, +'bzt' => 1, +'bzu' => 1, +'bzv' => 1, +'bzw' => 1, +'bzx' => 1, +'bzy' => 1, +'bzz' => 1, +'caa' => 1, +'cab' => 1, +'cac' => 1, +'cad' => 1, +'cae' => 1, +'caf' => 1, +'cag' => 1, +'cah' => 1, +'cai' => 1, +'caj' => 1, +'cak' => 1, +'cal' => 1, +'cam' => 1, +'can' => 1, +'cao' => 1, +'cap' => 1, +'caq' => 1, +'car' => 1, +'cas' => 1, +'cau' => 1, +'cav' => 1, +'caw' => 1, +'cax' => 1, +'cay' => 1, +'caz' => 1, +'cba' => 1, +'cbb' => 1, +'cbc' => 1, +'cbd' => 1, +'cbe' => 1, +'cbg' => 1, +'cbh' => 1, +'cbi' => 1, +'cbj' => 1, +'cbk' => 1, +'cbl' => 1, +'cbn' => 1, +'cbo' => 1, +'cbr' => 1, +'cbs' => 1, +'cbt' => 1, +'cbu' => 1, +'cbv' => 1, +'cby' => 1, +'cca' => 1, +'ccc' => 1, +'ccd' => 1, +'cce' => 1, +'ccg' => 1, +'cch' => 1, +'ccj' => 1, +'ccl' => 1, +'ccm' => 1, +'ccn' => 1, +'cco' => 1, +'ccp' => 1, +'ccq' => 1, +'ccr' => 1, +'ccs' => 1, +'cda' => 1, +'cdc' => 1, +'cdd' => 1, +'cde' => 1, +'cdf' => 1, +'cdg' => 1, +'cdh' => 1, +'cdi' => 1, +'cdj' => 1, +'cdm' => 1, +'cdn' => 1, +'cdr' => 1, +'cds' => 1, +'cdy' => 1, +'cdz' => 1, +'cea' => 1, +'ceb' => 1, +'ceg' => 1, +'cel' => 1, +'cen' => 1, +'cet' => 1, +'cfa' => 1, +'cfd' => 1, +'cfg' => 1, +'cfm' => 1, +'cga' => 1, +'cgc' => 1, +'cgg' => 1, +'cgk' => 1, +'chb' => 1, +'chc' => 1, +'chd' => 1, +'chf' => 1, +'chg' => 1, +'chh' => 1, +'chj' => 1, +'chk' => 1, +'chl' => 1, +'chm' => 1, +'chn' => 1, +'cho' => 1, +'chp' => 1, +'chq' => 1, +'chr' => 1, +'cht' => 1, +'chw' => 1, +'chx' => 1, +'chy' => 1, +'chz' => 1, +'cia' => 1, +'cib' => 1, +'cic' => 1, +'cid' => 1, +'cie' => 1, +'cih' => 1, +'cik' => 1, +'cim' => 1, +'cin' => 1, +'cip' => 1, +'cir' => 1, +'ciy' => 1, +'cja' => 1, +'cje' => 1, +'cjh' => 1, +'cji' => 1, +'cjk' => 1, +'cjm' => 1, +'cjn' => 1, +'cjo' => 1, +'cjp' => 1, +'cjr' => 1, +'cjs' => 1, +'cjv' => 1, +'cka' => 1, +'ckh' => 1, +'ckl' => 1, +'cko' => 1, +'ckq' => 1, +'ckr' => 1, +'cks' => 1, +'ckt' => 1, +'cku' => 1, +'ckv' => 1, +'ckx' => 1, +'cky' => 1, +'ckz' => 1, +'cla' => 1, +'clc' => 1, +'cle' => 1, +'clh' => 1, +'cli' => 1, +'clk' => 1, +'cll' => 1, +'clm' => 1, +'clo' => 1, +'clu' => 1, +'clw' => 1, +'cly' => 1, +'cma' => 1, +'cmc' => 1, +'cme' => 1, +'cmg' => 1, +'cmi' => 1, +'cmk' => 1, +'cml' => 1, +'cmm' => 1, +'cmo' => 1, +'cmr' => 1, +'cms' => 1, +'cmt' => 1, +'cna' => 1, +'cnb' => 1, +'cnc' => 1, +'cng' => 1, +'cnh' => 1, +'cni' => 1, +'cnk' => 1, +'cnl' => 1, +'cno' => 1, +'cns' => 1, +'cnt' => 1, +'cnu' => 1, +'cnw' => 1, +'cnx' => 1, +'cob' => 1, +'coc' => 1, +'cod' => 1, +'coe' => 1, +'cof' => 1, +'cog' => 1, +'coh' => 1, +'coj' => 1, +'cok' => 1, +'col' => 1, +'com' => 1, +'con' => 1, +'coo' => 1, +'cop' => 1, +'coq' => 1, +'cot' => 1, +'cou' => 1, +'cov' => 1, +'cow' => 1, +'cox' => 1, +'coy' => 1, +'coz' => 1, +'cpa' => 1, +'cpb' => 1, +'cpc' => 1, +'cpe' => 1, +'cpf' => 1, +'cpg' => 1, +'cpi' => 1, +'cpn' => 1, +'cpp' => 1, +'cps' => 1, +'cpu' => 1, +'cpy' => 1, +'cra' => 1, +'crb' => 1, +'crc' => 1, +'crd' => 1, +'crf' => 1, +'crg' => 1, +'crh' => 1, +'cri' => 1, +'crn' => 1, +'cro' => 1, +'crp' => 1, +'crq' => 1, +'crr' => 1, +'crs' => 1, +'crt' => 1, +'crv' => 1, +'crw' => 1, +'crx' => 1, +'cry' => 1, +'crz' => 1, +'csa' => 1, +'csb' => 1, +'csc' => 1, +'csd' => 1, +'cse' => 1, +'csf' => 1, +'csg' => 1, +'csh' => 1, +'csi' => 1, +'csk' => 1, +'csl' => 1, +'csm' => 1, +'csn' => 1, +'cso' => 1, +'csq' => 1, +'csr' => 1, +'css' => 1, +'cst' => 1, +'csu' => 1, +'csy' => 1, +'csz' => 1, +'cta' => 1, +'ctc' => 1, +'ctd' => 1, +'cte' => 1, +'ctg' => 1, +'ctl' => 1, +'ctm' => 1, +'ctn' => 1, +'cto' => 1, +'ctp' => 1, +'ctt' => 1, +'ctu' => 1, +'ctz' => 1, +'cua' => 1, +'cub' => 1, +'cuc' => 1, +'cug' => 1, +'cuh' => 1, +'cui' => 1, +'cuj' => 1, +'cuk' => 1, +'cul' => 1, +'cum' => 1, +'cuo' => 1, +'cup' => 1, +'cuq' => 1, +'cur' => 1, +'cus' => 1, +'cut' => 1, +'cuu' => 1, +'cuv' => 1, +'cuw' => 1, +'cux' => 1, +'cvg' => 1, +'cvn' => 1, +'cwa' => 1, +'cwb' => 1, +'cwe' => 1, +'cwg' => 1, +'cwt' => 1, +'cya' => 1, +'cyb' => 1, +'cyo' => 1, +'czk' => 1, +'czn' => 1, +'czt' => 1, +'daa' => 1, +'dac' => 1, +'dad' => 1, +'dae' => 1, +'daf' => 1, +'dag' => 1, +'dah' => 1, +'dai' => 1, +'daj' => 1, +'dak' => 1, +'dal' => 1, +'dam' => 1, +'dao' => 1, +'dap' => 1, +'daq' => 1, +'dar' => 1, +'das' => 1, +'dau' => 1, +'dav' => 1, +'daw' => 1, +'dax' => 1, +'day' => 1, +'daz' => 1, +'dba' => 1, +'dbb' => 1, +'dbd' => 1, +'dbe' => 1, +'dbf' => 1, +'dbg' => 1, +'dbi' => 1, +'dbj' => 1, +'dbl' => 1, +'dbm' => 1, +'dbn' => 1, +'dbo' => 1, +'dbp' => 1, +'dbq' => 1, +'dbr' => 1, +'dbu' => 1, +'dbv' => 1, +'dby' => 1, +'dcc' => 1, +'dcr' => 1, +'ddd' => 1, +'dde' => 1, +'ddg' => 1, +'ddi' => 1, +'ddj' => 1, +'ddn' => 1, +'ddo' => 1, +'dds' => 1, +'ddw' => 1, +'dec' => 1, +'ded' => 1, +'dee' => 1, +'def' => 1, +'deg' => 1, +'deh' => 1, +'dei' => 1, +'dek' => 1, +'del' => 1, +'dem' => 1, +'den' => 1, +'dep' => 1, +'deq' => 1, +'der' => 1, +'des' => 1, +'dev' => 1, +'dez' => 1, +'dga' => 1, +'dgb' => 1, +'dgc' => 1, +'dgd' => 1, +'dge' => 1, +'dgg' => 1, +'dgh' => 1, +'dgi' => 1, +'dgk' => 1, +'dgn' => 1, +'dgr' => 1, +'dgs' => 1, +'dgu' => 1, +'dgx' => 1, +'dgz' => 1, +'dha' => 1, +'dhg' => 1, +'dhi' => 1, +'dhl' => 1, +'dhm' => 1, +'dhn' => 1, +'dho' => 1, +'dhr' => 1, +'dhs' => 1, +'dhu' => 1, +'dhv' => 1, +'dhw' => 1, +'dia' => 1, +'dic' => 1, +'did' => 1, +'dif' => 1, +'dig' => 1, +'dih' => 1, +'dii' => 1, +'dij' => 1, +'dil' => 1, +'dim' => 1, +'din' => 1, +'dio' => 1, +'dir' => 1, +'dis' => 1, +'dit' => 1, +'diu' => 1, +'dix' => 1, +'diy' => 1, +'diz' => 1, +'djb' => 1, +'djc' => 1, +'djd' => 1, +'dje' => 1, +'djf' => 1, +'dji' => 1, +'djj' => 1, +'djk' => 1, +'djl' => 1, +'djm' => 1, +'djn' => 1, +'djo' => 1, +'djr' => 1, +'dju' => 1, +'djw' => 1, +'dka' => 1, +'dkk' => 1, +'dkl' => 1, +'dkr' => 1, +'dkx' => 1, +'dlg' => 1, +'dlm' => 1, +'dln' => 1, +'dma' => 1, +'dmc' => 1, +'dme' => 1, +'dmg' => 1, +'dmk' => 1, +'dml' => 1, +'dmm' => 1, +'dmn' => 1, +'dmo' => 1, +'dmr' => 1, +'dms' => 1, +'dmu' => 1, +'dmv' => 1, +'dmx' => 1, +'dmy' => 1, +'dna' => 1, +'dnd' => 1, +'dne' => 1, +'dng' => 1, +'dni' => 1, +'dnk' => 1, +'dnn' => 1, +'dnr' => 1, +'dnt' => 1, +'dnu' => 1, +'dnw' => 1, +'dny' => 1, +'doa' => 1, +'dob' => 1, +'doc' => 1, +'doe' => 1, +'dof' => 1, +'doh' => 1, +'doi' => 1, +'dok' => 1, +'dol' => 1, +'don' => 1, +'doo' => 1, +'dop' => 1, +'doq' => 1, +'dor' => 1, +'dos' => 1, +'dot' => 1, +'dov' => 1, +'dow' => 1, +'dox' => 1, +'doy' => 1, +'doz' => 1, +'dpp' => 1, +'dra' => 1, +'drb' => 1, +'drd' => 1, +'dre' => 1, +'drg' => 1, +'drh' => 1, +'dri' => 1, +'drl' => 1, +'drn' => 1, +'dro' => 1, +'drq' => 1, +'drr' => 1, +'drs' => 1, +'drt' => 1, +'dru' => 1, +'drw' => 1, +'dry' => 1, +'dsb' => 1, +'dse' => 1, +'dsh' => 1, +'dsi' => 1, +'dsl' => 1, +'dsn' => 1, +'dso' => 1, +'dsq' => 1, +'dta' => 1, +'dtb' => 1, +'dti' => 1, +'dtk' => 1, +'dtm' => 1, +'dtp' => 1, +'dtr' => 1, +'dts' => 1, +'dtt' => 1, +'dtu' => 1, +'dua' => 1, +'dub' => 1, +'duc' => 1, +'dud' => 1, +'due' => 1, +'duf' => 1, +'dug' => 1, +'duh' => 1, +'dui' => 1, +'duj' => 1, +'duk' => 1, +'dul' => 1, +'dum' => 1, +'dun' => 1, +'duo' => 1, +'duq' => 1, +'dur' => 1, +'dus' => 1, +'duu' => 1, +'duv' => 1, +'duw' => 1, +'dux' => 1, +'duy' => 1, +'duz' => 1, +'dva' => 1, +'dwa' => 1, +'dwl' => 1, +'dwr' => 1, +'dws' => 1, +'dww' => 1, +'dya' => 1, +'dyb' => 1, +'dyd' => 1, +'dyg' => 1, +'dyi' => 1, +'dym' => 1, +'dyn' => 1, +'dyo' => 1, +'dyu' => 1, +'dyy' => 1, +'dza' => 1, +'dzd' => 1, +'dzg' => 1, +'dzl' => 1, +'dzn' => 1, +'ebg' => 1, +'ebo' => 1, +'ebr' => 1, +'ebu' => 1, +'ecr' => 1, +'ecs' => 1, +'ecy' => 1, +'eee' => 1, +'efa' => 1, +'efe' => 1, +'efi' => 1, +'ega' => 1, +'egl' => 1, +'ego' => 1, +'egx' => 1, +'egy' => 1, +'ehu' => 1, +'eip' => 1, +'eit' => 1, +'eiv' => 1, +'eja' => 1, +'eka' => 1, +'eke' => 1, +'ekg' => 1, +'eki' => 1, +'ekl' => 1, +'ekm' => 1, +'eko' => 1, +'ekp' => 1, +'ekr' => 1, +'eky' => 1, +'ele' => 1, +'elh' => 1, +'eli' => 1, +'elk' => 1, +'elm' => 1, +'elo' => 1, +'elp' => 1, +'elu' => 1, +'elx' => 1, +'ema' => 1, +'emb' => 1, +'eme' => 1, +'emg' => 1, +'emi' => 1, +'emm' => 1, +'emn' => 1, +'emo' => 1, +'emp' => 1, +'ems' => 1, +'emu' => 1, +'emw' => 1, +'emy' => 1, +'ena' => 1, +'enc' => 1, +'end' => 1, +'enf' => 1, +'enh' => 1, +'enm' => 1, +'enn' => 1, +'eno' => 1, +'enq' => 1, +'enr' => 1, +'enu' => 1, +'env' => 1, +'enw' => 1, +'eot' => 1, +'epi' => 1, +'era' => 1, +'erg' => 1, +'erh' => 1, +'eri' => 1, +'erk' => 1, +'ero' => 1, +'err' => 1, +'ers' => 1, +'ert' => 1, +'erw' => 1, +'ese' => 1, +'esh' => 1, +'esl' => 1, +'esm' => 1, +'esn' => 1, +'eso' => 1, +'esq' => 1, +'ess' => 1, +'esu' => 1, +'esx' => 1, +'etb' => 1, +'etc' => 1, +'eth' => 1, +'etn' => 1, +'eto' => 1, +'etr' => 1, +'ets' => 1, +'ett' => 1, +'etu' => 1, +'etx' => 1, +'etz' => 1, +'euq' => 1, +'eve' => 1, +'evh' => 1, +'evn' => 1, +'ewo' => 1, +'ext' => 1, +'eya' => 1, +'eze' => 1, +'faa' => 1, +'fab' => 1, +'fad' => 1, +'faf' => 1, +'fag' => 1, +'fah' => 1, +'fai' => 1, +'faj' => 1, +'fak' => 1, +'fal' => 1, +'fam' => 1, +'fan' => 1, +'fap' => 1, +'far' => 1, +'fau' => 1, +'fax' => 1, +'fay' => 1, +'faz' => 1, +'fcs' => 1, +'fer' => 1, +'ffi' => 1, +'fgr' => 1, +'fia' => 1, +'fie' => 1, +'fil' => 1, +'fip' => 1, +'fir' => 1, +'fit' => 1, +'fiu' => 1, +'fiw' => 1, +'fkv' => 1, +'fla' => 1, +'flh' => 1, +'fli' => 1, +'fll' => 1, +'fln' => 1, +'flr' => 1, +'fly' => 1, +'fmp' => 1, +'fmu' => 1, +'fng' => 1, +'fni' => 1, +'fod' => 1, +'foi' => 1, +'fom' => 1, +'fon' => 1, +'for' => 1, +'fos' => 1, +'fox' => 1, +'fpe' => 1, +'fqs' => 1, +'frc' => 1, +'frd' => 1, +'frk' => 1, +'frm' => 1, +'fro' => 1, +'frp' => 1, +'frq' => 1, +'frr' => 1, +'frs' => 1, +'frt' => 1, +'fse' => 1, +'fsl' => 1, +'fss' => 1, +'fud' => 1, +'fuj' => 1, +'fum' => 1, +'fun' => 1, +'fur' => 1, +'fut' => 1, +'fuu' => 1, +'fuy' => 1, +'fvr' => 1, +'fwa' => 1, +'fwe' => 1, +'gaa' => 1, +'gab' => 1, +'gad' => 1, +'gae' => 1, +'gaf' => 1, +'gag' => 1, +'gah' => 1, +'gai' => 1, +'gaj' => 1, +'gak' => 1, +'gal' => 1, +'gam' => 1, +'gao' => 1, +'gap' => 1, +'gaq' => 1, +'gar' => 1, +'gas' => 1, +'gat' => 1, +'gau' => 1, +'gav' => 1, +'gaw' => 1, +'gay' => 1, +'gba' => 1, +'gbb' => 1, +'gbc' => 1, +'gbd' => 1, +'gbe' => 1, +'gbf' => 1, +'gbg' => 1, +'gbh' => 1, +'gbi' => 1, +'gbj' => 1, +'gbk' => 1, +'gbl' => 1, +'gbm' => 1, +'gbn' => 1, +'gbr' => 1, +'gbs' => 1, +'gbu' => 1, +'gbv' => 1, +'gbx' => 1, +'gby' => 1, +'gbz' => 1, +'gcc' => 1, +'gcd' => 1, +'gce' => 1, +'gcf' => 1, +'gcl' => 1, +'gcn' => 1, +'gcr' => 1, +'gct' => 1, +'gdb' => 1, +'gdc' => 1, +'gdd' => 1, +'gde' => 1, +'gdf' => 1, +'gdg' => 1, +'gdh' => 1, +'gdi' => 1, +'gdj' => 1, +'gdk' => 1, +'gdl' => 1, +'gdm' => 1, +'gdn' => 1, +'gdo' => 1, +'gdq' => 1, +'gdr' => 1, +'gdu' => 1, +'gdx' => 1, +'gea' => 1, +'geb' => 1, +'ged' => 1, +'geg' => 1, +'geh' => 1, +'gei' => 1, +'gej' => 1, +'gek' => 1, +'gel' => 1, +'gem' => 1, +'geq' => 1, +'ges' => 1, +'gew' => 1, +'gex' => 1, +'gey' => 1, +'gez' => 1, +'gfk' => 1, +'gft' => 1, +'gga' => 1, +'ggb' => 1, +'ggd' => 1, +'gge' => 1, +'ggg' => 1, +'ggk' => 1, +'ggl' => 1, +'ggn' => 1, +'ggr' => 1, +'ggt' => 1, +'ggu' => 1, +'ggw' => 1, +'gha' => 1, +'ghc' => 1, +'ghe' => 1, +'ghh' => 1, +'ghk' => 1, +'ghl' => 1, +'ghn' => 1, +'gho' => 1, +'ghr' => 1, +'ghs' => 1, +'ght' => 1, +'gia' => 1, +'gib' => 1, +'gic' => 1, +'gid' => 1, +'gig' => 1, +'gil' => 1, +'gim' => 1, +'gin' => 1, +'gio' => 1, +'gip' => 1, +'giq' => 1, +'gir' => 1, +'gis' => 1, +'git' => 1, +'giw' => 1, +'gix' => 1, +'giy' => 1, +'giz' => 1, +'gji' => 1, +'gjk' => 1, +'gjn' => 1, +'gka' => 1, +'gke' => 1, +'gkn' => 1, +'glc' => 1, +'gld' => 1, +'glh' => 1, +'gli' => 1, +'glj' => 1, +'glk' => 1, +'glo' => 1, +'glr' => 1, +'glu' => 1, +'glw' => 1, +'gly' => 1, +'gma' => 1, +'gmb' => 1, +'gmd' => 1, +'gme' => 1, +'gmh' => 1, +'gml' => 1, +'gmn' => 1, +'gmq' => 1, +'gmu' => 1, +'gmv' => 1, +'gmw' => 1, +'gmx' => 1, +'gmy' => 1, +'gna' => 1, +'gnb' => 1, +'gnc' => 1, +'gnd' => 1, +'gne' => 1, +'gng' => 1, +'gnh' => 1, +'gni' => 1, +'gnk' => 1, +'gnl' => 1, +'gnm' => 1, +'gnn' => 1, +'gnq' => 1, +'gnr' => 1, +'gnt' => 1, +'gnu' => 1, +'gnz' => 1, +'goa' => 1, +'gob' => 1, +'goc' => 1, +'god' => 1, +'goe' => 1, +'gof' => 1, +'gog' => 1, +'goh' => 1, +'goi' => 1, +'goj' => 1, +'gok' => 1, +'gol' => 1, +'gon' => 1, +'goo' => 1, +'gop' => 1, +'goq' => 1, +'gor' => 1, +'gos' => 1, +'got' => 1, +'gou' => 1, +'gow' => 1, +'gox' => 1, +'goy' => 1, +'goz' => 1, +'gpa' => 1, +'gpn' => 1, +'gqa' => 1, +'gqi' => 1, +'gqn' => 1, +'gqr' => 1, +'gra' => 1, +'grb' => 1, +'grc' => 1, +'grd' => 1, +'grg' => 1, +'grh' => 1, +'gri' => 1, +'grk' => 1, +'grm' => 1, +'gro' => 1, +'grq' => 1, +'grr' => 1, +'grs' => 1, +'grt' => 1, +'gru' => 1, +'grw' => 1, +'grx' => 1, +'grz' => 1, +'gse' => 1, +'gsg' => 1, +'gsl' => 1, +'gsm' => 1, +'gsn' => 1, +'gsp' => 1, +'gss' => 1, +'gsw' => 1, +'gta' => 1, +'gti' => 1, +'gua' => 1, +'gub' => 1, +'guc' => 1, +'gud' => 1, +'gue' => 1, +'guf' => 1, +'guh' => 1, +'guk' => 1, +'gul' => 1, +'gum' => 1, +'guo' => 1, +'gup' => 1, +'guq' => 1, +'gur' => 1, +'gus' => 1, +'gut' => 1, +'guu' => 1, +'guv' => 1, +'guw' => 1, +'gux' => 1, +'guz' => 1, +'gva' => 1, +'gvc' => 1, +'gve' => 1, +'gvf' => 1, +'gvj' => 1, +'gvl' => 1, +'gvm' => 1, +'gvn' => 1, +'gvo' => 1, +'gvp' => 1, +'gvr' => 1, +'gvs' => 1, +'gvy' => 1, +'gwa' => 1, +'gwb' => 1, +'gwc' => 1, +'gwd' => 1, +'gwe' => 1, +'gwf' => 1, +'gwg' => 1, +'gwi' => 1, +'gwj' => 1, +'gwn' => 1, +'gwr' => 1, +'gwt' => 1, +'gwu' => 1, +'gww' => 1, +'gwx' => 1, +'gxx' => 1, +'gyb' => 1, +'gyd' => 1, +'gye' => 1, +'gyf' => 1, +'gyg' => 1, +'gyi' => 1, +'gyl' => 1, +'gym' => 1, +'gyn' => 1, +'gyr' => 1, +'gyy' => 1, +'gza' => 1, +'gzi' => 1, +'gzn' => 1, +'haa' => 1, +'hab' => 1, +'hac' => 1, +'had' => 1, +'haf' => 1, +'hag' => 1, +'hah' => 1, +'hai' => 1, +'haj' => 1, +'hal' => 1, +'ham' => 1, +'han' => 1, +'hao' => 1, +'hap' => 1, +'haq' => 1, +'har' => 1, +'has' => 1, +'hav' => 1, +'haw' => 1, +'hay' => 1, +'haz' => 1, +'hba' => 1, +'hbb' => 1, +'hbn' => 1, +'hbo' => 1, +'hbu' => 1, +'hca' => 1, +'hch' => 1, +'hds' => 1, +'hdy' => 1, +'hed' => 1, +'heg' => 1, +'heh' => 1, +'hei' => 1, +'hem' => 1, +'hgm' => 1, +'hgw' => 1, +'hhi' => 1, +'hhr' => 1, +'hhy' => 1, +'hia' => 1, +'hib' => 1, +'hid' => 1, +'hif' => 1, +'hig' => 1, +'hih' => 1, +'hii' => 1, +'hij' => 1, +'hik' => 1, +'hil' => 1, +'him' => 1, +'hio' => 1, +'hir' => 1, +'hit' => 1, +'hiw' => 1, +'hix' => 1, +'hka' => 1, +'hke' => 1, +'hkk' => 1, +'hks' => 1, +'hla' => 1, +'hlb' => 1, +'hld' => 1, +'hle' => 1, +'hlt' => 1, +'hlu' => 1, +'hmb' => 1, +'hmf' => 1, +'hmk' => 1, +'hmn' => 1, +'hmr' => 1, +'hmt' => 1, +'hmu' => 1, +'hmv' => 1, +'hmx' => 1, +'hmz' => 1, +'hna' => 1, +'hne' => 1, +'hnh' => 1, +'hni' => 1, +'hnn' => 1, +'hns' => 1, +'hnu' => 1, +'hoa' => 1, +'hob' => 1, +'hoc' => 1, +'hod' => 1, +'hoe' => 1, +'hoh' => 1, +'hoi' => 1, +'hok' => 1, +'hol' => 1, +'hom' => 1, +'hoo' => 1, +'hop' => 1, +'hor' => 1, +'hos' => 1, +'hot' => 1, +'hov' => 1, +'how' => 1, +'hoy' => 1, +'hoz' => 1, +'hpo' => 1, +'hps' => 1, +'hra' => 1, +'hre' => 1, +'hrk' => 1, +'hro' => 1, +'hrr' => 1, +'hrt' => 1, +'hru' => 1, +'hrx' => 1, +'hrz' => 1, +'hsb' => 1, +'hsh' => 1, +'hsl' => 1, +'hss' => 1, +'hti' => 1, +'hto' => 1, +'hts' => 1, +'htu' => 1, +'htx' => 1, +'hub' => 1, +'huc' => 1, +'hud' => 1, +'hue' => 1, +'huf' => 1, +'hug' => 1, +'huh' => 1, +'hui' => 1, +'huk' => 1, +'hul' => 1, +'hum' => 1, +'huo' => 1, +'hup' => 1, +'huq' => 1, +'hur' => 1, +'hus' => 1, +'hut' => 1, +'huu' => 1, +'huv' => 1, +'huw' => 1, +'hux' => 1, +'huy' => 1, +'huz' => 1, +'hvc' => 1, +'hve' => 1, +'hvk' => 1, +'hvn' => 1, +'hvv' => 1, +'hwa' => 1, +'hwc' => 1, +'hwo' => 1, +'hya' => 1, +'hyx' => 1, +'iai' => 1, +'ian' => 1, +'iap' => 1, +'iar' => 1, +'iba' => 1, +'ibb' => 1, +'ibd' => 1, +'ibe' => 1, +'ibg' => 1, +'ibi' => 1, +'ibl' => 1, +'ibm' => 1, +'ibn' => 1, +'ibr' => 1, +'ibu' => 1, +'iby' => 1, +'ica' => 1, +'ich' => 1, +'icl' => 1, +'icr' => 1, +'idb' => 1, +'idc' => 1, +'idd' => 1, +'ide' => 1, +'idi' => 1, +'idr' => 1, +'ids' => 1, +'idt' => 1, +'idu' => 1, +'ifa' => 1, +'ifb' => 1, +'ife' => 1, +'iff' => 1, +'ifk' => 1, +'ifm' => 1, +'ifu' => 1, +'ify' => 1, +'igb' => 1, +'ige' => 1, +'igg' => 1, +'igl' => 1, +'igm' => 1, +'ign' => 1, +'igo' => 1, +'igs' => 1, +'igw' => 1, +'ihb' => 1, +'ihi' => 1, +'ihp' => 1, +'iir' => 1, +'ijc' => 1, +'ije' => 1, +'ijj' => 1, +'ijn' => 1, +'ijo' => 1, +'ijs' => 1, +'iki' => 1, +'ikk' => 1, +'ikl' => 1, +'iko' => 1, +'ikp' => 1, +'ikv' => 1, +'ikw' => 1, +'ikx' => 1, +'ikz' => 1, +'ila' => 1, +'ilb' => 1, +'ilg' => 1, +'ili' => 1, +'ilk' => 1, +'ill' => 1, +'ilo' => 1, +'ils' => 1, +'ilu' => 1, +'ilv' => 1, +'ilw' => 1, +'ima' => 1, +'ime' => 1, +'imi' => 1, +'iml' => 1, +'imn' => 1, +'imo' => 1, +'imr' => 1, +'ims' => 1, +'imy' => 1, +'inb' => 1, +'inc' => 1, +'ine' => 1, +'ing' => 1, +'inh' => 1, +'inj' => 1, +'inl' => 1, +'inm' => 1, +'inn' => 1, +'ino' => 1, +'inp' => 1, +'ins' => 1, +'int' => 1, +'inz' => 1, +'ior' => 1, +'iou' => 1, +'iow' => 1, +'ipi' => 1, +'ipo' => 1, +'iqu' => 1, +'ira' => 1, +'ire' => 1, +'irh' => 1, +'iri' => 1, +'irk' => 1, +'irn' => 1, +'iro' => 1, +'irr' => 1, +'iru' => 1, +'irx' => 1, +'iry' => 1, +'isa' => 1, +'isc' => 1, +'isd' => 1, +'ise' => 1, +'isg' => 1, +'ish' => 1, +'isi' => 1, +'ism' => 1, +'isn' => 1, +'iso' => 1, +'isr' => 1, +'ist' => 1, +'isu' => 1, +'itb' => 1, +'itc' => 1, +'ite' => 1, +'iti' => 1, +'itk' => 1, +'itl' => 1, +'itm' => 1, +'ito' => 1, +'itr' => 1, +'its' => 1, +'itt' => 1, +'itv' => 1, +'itw' => 1, +'itx' => 1, +'ity' => 1, +'itz' => 1, +'ium' => 1, +'ivb' => 1, +'ivv' => 1, +'iwk' => 1, +'iwm' => 1, +'iwo' => 1, +'iws' => 1, +'ixc' => 1, +'ixl' => 1, +'iya' => 1, +'iyo' => 1, +'iyx' => 1, +'izh' => 1, +'izi' => 1, +'izr' => 1, +'jaa' => 1, +'jab' => 1, +'jac' => 1, +'jad' => 1, +'jae' => 1, +'jaf' => 1, +'jah' => 1, +'jaj' => 1, +'jal' => 1, +'jam' => 1, +'jao' => 1, +'jaq' => 1, +'jar' => 1, +'jas' => 1, +'jau' => 1, +'jay' => 1, +'jaz' => 1, +'jbe' => 1, +'jbj' => 1, +'jbn' => 1, +'jbo' => 1, +'jbr' => 1, +'jbt' => 1, +'jbu' => 1, +'jcs' => 1, +'jct' => 1, +'jda' => 1, +'jdg' => 1, +'jdt' => 1, +'jeb' => 1, +'jee' => 1, +'jeg' => 1, +'jeh' => 1, +'jei' => 1, +'jek' => 1, +'jel' => 1, +'jen' => 1, +'jer' => 1, +'jet' => 1, +'jeu' => 1, +'jgb' => 1, +'jge' => 1, +'jgo' => 1, +'jhi' => 1, +'jhs' => 1, +'jia' => 1, +'jib' => 1, +'jic' => 1, +'jid' => 1, +'jie' => 1, +'jig' => 1, +'jih' => 1, +'jii' => 1, +'jil' => 1, +'jim' => 1, +'jio' => 1, +'jiq' => 1, +'jit' => 1, +'jiu' => 1, +'jiv' => 1, +'jiy' => 1, +'jko' => 1, +'jku' => 1, +'jle' => 1, +'jma' => 1, +'jmb' => 1, +'jmc' => 1, +'jmd' => 1, +'jmi' => 1, +'jml' => 1, +'jmn' => 1, +'jmr' => 1, +'jms' => 1, +'jmx' => 1, +'jna' => 1, +'jnd' => 1, +'jng' => 1, +'jni' => 1, +'jnj' => 1, +'jnl' => 1, +'jns' => 1, +'job' => 1, +'jod' => 1, +'jor' => 1, +'jos' => 1, +'jow' => 1, +'jpa' => 1, +'jpr' => 1, +'jpx' => 1, +'jqr' => 1, +'jra' => 1, +'jrb' => 1, +'jrr' => 1, +'jrt' => 1, +'jru' => 1, +'jsl' => 1, +'jua' => 1, +'jub' => 1, +'juc' => 1, +'jud' => 1, +'juh' => 1, +'juk' => 1, +'jul' => 1, +'jum' => 1, +'jun' => 1, +'juo' => 1, +'jup' => 1, +'jur' => 1, +'jus' => 1, +'jut' => 1, +'juu' => 1, +'juw' => 1, +'juy' => 1, +'jvd' => 1, +'jvn' => 1, +'jwi' => 1, +'jya' => 1, +'jyy' => 1, +'kaa' => 1, +'kab' => 1, +'kac' => 1, +'kad' => 1, +'kae' => 1, +'kaf' => 1, +'kag' => 1, +'kah' => 1, +'kai' => 1, +'kaj' => 1, +'kak' => 1, +'kam' => 1, +'kao' => 1, +'kap' => 1, +'kaq' => 1, +'kar' => 1, +'kav' => 1, +'kaw' => 1, +'kax' => 1, +'kay' => 1, +'kba' => 1, +'kbb' => 1, +'kbc' => 1, +'kbd' => 1, +'kbe' => 1, +'kbf' => 1, +'kbg' => 1, +'kbh' => 1, +'kbi' => 1, +'kbj' => 1, +'kbk' => 1, +'kbl' => 1, +'kbm' => 1, +'kbn' => 1, +'kbo' => 1, +'kbp' => 1, +'kbq' => 1, +'kbr' => 1, +'kbs' => 1, +'kbt' => 1, +'kbu' => 1, +'kbv' => 1, +'kbw' => 1, +'kbx' => 1, +'kbz' => 1, +'kca' => 1, +'kcb' => 1, +'kcc' => 1, +'kcd' => 1, +'kce' => 1, +'kcf' => 1, +'kcg' => 1, +'kch' => 1, +'kci' => 1, +'kcj' => 1, +'kck' => 1, +'kcl' => 1, +'kcm' => 1, +'kcn' => 1, +'kco' => 1, +'kcp' => 1, +'kcq' => 1, +'kcr' => 1, +'kcs' => 1, +'kct' => 1, +'kcu' => 1, +'kcv' => 1, +'kcw' => 1, +'kcx' => 1, +'kcy' => 1, +'kcz' => 1, +'kda' => 1, +'kdc' => 1, +'kdd' => 1, +'kde' => 1, +'kdf' => 1, +'kdg' => 1, +'kdh' => 1, +'kdi' => 1, +'kdj' => 1, +'kdk' => 1, +'kdl' => 1, +'kdm' => 1, +'kdn' => 1, +'kdo' => 1, +'kdp' => 1, +'kdq' => 1, +'kdr' => 1, +'kdt' => 1, +'kdu' => 1, +'kdv' => 1, +'kdw' => 1, +'kdx' => 1, +'kdy' => 1, +'kdz' => 1, +'kea' => 1, +'keb' => 1, +'kec' => 1, +'ked' => 1, +'kee' => 1, +'kef' => 1, +'keg' => 1, +'keh' => 1, +'kei' => 1, +'kej' => 1, +'kek' => 1, +'kel' => 1, +'kem' => 1, +'ken' => 1, +'keo' => 1, +'kep' => 1, +'keq' => 1, +'ker' => 1, +'kes' => 1, +'ket' => 1, +'keu' => 1, +'kev' => 1, +'kew' => 1, +'kex' => 1, +'key' => 1, +'kez' => 1, +'kfa' => 1, +'kfb' => 1, +'kfc' => 1, +'kfd' => 1, +'kfe' => 1, +'kff' => 1, +'kfg' => 1, +'kfh' => 1, +'kfi' => 1, +'kfj' => 1, +'kfk' => 1, +'kfl' => 1, +'kfm' => 1, +'kfn' => 1, +'kfo' => 1, +'kfp' => 1, +'kfq' => 1, +'kfr' => 1, +'kfs' => 1, +'kft' => 1, +'kfu' => 1, +'kfv' => 1, +'kfw' => 1, +'kfx' => 1, +'kfy' => 1, +'kfz' => 1, +'kga' => 1, +'kgb' => 1, +'kgc' => 1, +'kgd' => 1, +'kge' => 1, +'kgf' => 1, +'kgg' => 1, +'kgh' => 1, +'kgi' => 1, +'kgj' => 1, +'kgk' => 1, +'kgl' => 1, +'kgm' => 1, +'kgn' => 1, +'kgo' => 1, +'kgp' => 1, +'kgq' => 1, +'kgr' => 1, +'kgs' => 1, +'kgt' => 1, +'kgu' => 1, +'kgv' => 1, +'kgw' => 1, +'kgx' => 1, +'kgy' => 1, +'kha' => 1, +'khb' => 1, +'khc' => 1, +'khd' => 1, +'khe' => 1, +'khf' => 1, +'khg' => 1, +'khh' => 1, +'khi' => 1, +'khj' => 1, +'khl' => 1, +'khn' => 1, +'kho' => 1, +'khp' => 1, +'khq' => 1, +'khr' => 1, +'khs' => 1, +'kht' => 1, +'khu' => 1, +'khv' => 1, +'khw' => 1, +'khx' => 1, +'khy' => 1, +'khz' => 1, +'kia' => 1, +'kib' => 1, +'kic' => 1, +'kid' => 1, +'kie' => 1, +'kif' => 1, +'kig' => 1, +'kih' => 1, +'kii' => 1, +'kij' => 1, +'kil' => 1, +'kim' => 1, +'kio' => 1, +'kip' => 1, +'kiq' => 1, +'kis' => 1, +'kit' => 1, +'kiv' => 1, +'kiw' => 1, +'kix' => 1, +'kiy' => 1, +'kiz' => 1, +'kja' => 1, +'kjb' => 1, +'kjc' => 1, +'kjd' => 1, +'kje' => 1, +'kjf' => 1, +'kjg' => 1, +'kjh' => 1, +'kji' => 1, +'kjj' => 1, +'kjk' => 1, +'kjl' => 1, +'kjm' => 1, +'kjn' => 1, +'kjo' => 1, +'kjp' => 1, +'kjq' => 1, +'kjr' => 1, +'kjs' => 1, +'kjt' => 1, +'kju' => 1, +'kjx' => 1, +'kjy' => 1, +'kjz' => 1, +'kka' => 1, +'kkb' => 1, +'kkc' => 1, +'kkd' => 1, +'kke' => 1, +'kkf' => 1, +'kkg' => 1, +'kkh' => 1, +'kki' => 1, +'kkj' => 1, +'kkk' => 1, +'kkl' => 1, +'kkm' => 1, +'kkn' => 1, +'kko' => 1, +'kkp' => 1, +'kkq' => 1, +'kkr' => 1, +'kks' => 1, +'kkt' => 1, +'kku' => 1, +'kkv' => 1, +'kkw' => 1, +'kkx' => 1, +'kky' => 1, +'kkz' => 1, +'kla' => 1, +'klb' => 1, +'klc' => 1, +'kld' => 1, +'kle' => 1, +'klf' => 1, +'klg' => 1, +'klh' => 1, +'kli' => 1, +'klj' => 1, +'klk' => 1, +'kll' => 1, +'klm' => 1, +'kln' => 1, +'klo' => 1, +'klp' => 1, +'klq' => 1, +'klr' => 1, +'kls' => 1, +'klt' => 1, +'klu' => 1, +'klv' => 1, +'klw' => 1, +'klx' => 1, +'kly' => 1, +'klz' => 1, +'kma' => 1, +'kmb' => 1, +'kmc' => 1, +'kmd' => 1, +'kme' => 1, +'kmf' => 1, +'kmg' => 1, +'kmh' => 1, +'kmi' => 1, +'kmj' => 1, +'kmk' => 1, +'kml' => 1, +'kmm' => 1, +'kmn' => 1, +'kmo' => 1, +'kmp' => 1, +'kmq' => 1, +'kms' => 1, +'kmt' => 1, +'kmu' => 1, +'kmv' => 1, +'kmw' => 1, +'kmx' => 1, +'kmy' => 1, +'kmz' => 1, +'kna' => 1, +'knb' => 1, +'knd' => 1, +'kne' => 1, +'knf' => 1, +'kni' => 1, +'knj' => 1, +'knk' => 1, +'knl' => 1, +'knm' => 1, +'kno' => 1, +'knp' => 1, +'knq' => 1, +'knr' => 1, +'kns' => 1, +'knt' => 1, +'knu' => 1, +'knv' => 1, +'knw' => 1, +'knx' => 1, +'kny' => 1, +'knz' => 1, +'koa' => 1, +'koc' => 1, +'kod' => 1, +'koe' => 1, +'kof' => 1, +'kog' => 1, +'koh' => 1, +'koj' => 1, +'kok' => 1, +'kol' => 1, +'koo' => 1, +'kop' => 1, +'koq' => 1, +'kos' => 1, +'kot' => 1, +'kou' => 1, +'kov' => 1, +'kow' => 1, +'kox' => 1, +'koy' => 1, +'koz' => 1, +'kpa' => 1, +'kpb' => 1, +'kpc' => 1, +'kpd' => 1, +'kpe' => 1, +'kpf' => 1, +'kpg' => 1, +'kph' => 1, +'kpi' => 1, +'kpj' => 1, +'kpk' => 1, +'kpl' => 1, +'kpm' => 1, +'kpn' => 1, +'kpo' => 1, +'kpp' => 1, +'kpq' => 1, +'kpr' => 1, +'kps' => 1, +'kpt' => 1, +'kpu' => 1, +'kpw' => 1, +'kpx' => 1, +'kpy' => 1, +'kpz' => 1, +'kqa' => 1, +'kqb' => 1, +'kqc' => 1, +'kqd' => 1, +'kqe' => 1, +'kqf' => 1, +'kqg' => 1, +'kqh' => 1, +'kqi' => 1, +'kqj' => 1, +'kqk' => 1, +'kql' => 1, +'kqm' => 1, +'kqn' => 1, +'kqo' => 1, +'kqp' => 1, +'kqq' => 1, +'kqr' => 1, +'kqs' => 1, +'kqt' => 1, +'kqu' => 1, +'kqv' => 1, +'kqw' => 1, +'kqx' => 1, +'kqy' => 1, +'kqz' => 1, +'kra' => 1, +'krb' => 1, +'krc' => 1, +'krd' => 1, +'kre' => 1, +'krf' => 1, +'krh' => 1, +'kri' => 1, +'krj' => 1, +'krk' => 1, +'krl' => 1, +'krm' => 1, +'krn' => 1, +'kro' => 1, +'krp' => 1, +'krr' => 1, +'krs' => 1, +'kru' => 1, +'krv' => 1, +'krw' => 1, +'krx' => 1, +'kry' => 1, +'krz' => 1, +'ksa' => 1, +'ksb' => 1, +'ksc' => 1, +'ksd' => 1, +'kse' => 1, +'ksf' => 1, +'ksg' => 1, +'ksh' => 1, +'ksi' => 1, +'ksj' => 1, +'ksk' => 1, +'ksl' => 1, +'ksm' => 1, +'ksn' => 1, +'kso' => 1, +'ksp' => 1, +'ksq' => 1, +'ksr' => 1, +'kss' => 1, +'kst' => 1, +'ksu' => 1, +'ksv' => 1, +'ksw' => 1, +'ksx' => 1, +'ksy' => 1, +'ksz' => 1, +'kta' => 1, +'ktb' => 1, +'ktc' => 1, +'ktd' => 1, +'kte' => 1, +'ktf' => 1, +'ktg' => 1, +'kth' => 1, +'kti' => 1, +'ktj' => 1, +'ktk' => 1, +'ktl' => 1, +'ktm' => 1, +'ktn' => 1, +'kto' => 1, +'ktp' => 1, +'ktq' => 1, +'ktr' => 1, +'kts' => 1, +'ktt' => 1, +'ktu' => 1, +'ktv' => 1, +'ktw' => 1, +'ktx' => 1, +'kty' => 1, +'ktz' => 1, +'kub' => 1, +'kuc' => 1, +'kud' => 1, +'kue' => 1, +'kuf' => 1, +'kug' => 1, +'kuh' => 1, +'kui' => 1, +'kuj' => 1, +'kuk' => 1, +'kul' => 1, +'kum' => 1, +'kun' => 1, +'kuo' => 1, +'kup' => 1, +'kuq' => 1, +'kus' => 1, +'kut' => 1, +'kuu' => 1, +'kuv' => 1, +'kuw' => 1, +'kux' => 1, +'kuy' => 1, +'kuz' => 1, +'kva' => 1, +'kvc' => 1, +'kvd' => 1, +'kve' => 1, +'kvf' => 1, +'kvg' => 1, +'kvh' => 1, +'kvi' => 1, +'kvj' => 1, +'kvk' => 1, +'kvl' => 1, +'kvm' => 1, +'kvn' => 1, +'kvo' => 1, +'kvp' => 1, +'kvq' => 1, +'kvs' => 1, +'kvt' => 1, +'kvu' => 1, +'kvv' => 1, +'kvw' => 1, +'kvx' => 1, +'kvy' => 1, +'kvz' => 1, +'kwa' => 1, +'kwb' => 1, +'kwc' => 1, +'kwd' => 1, +'kwe' => 1, +'kwf' => 1, +'kwg' => 1, +'kwh' => 1, +'kwi' => 1, +'kwj' => 1, +'kwk' => 1, +'kwl' => 1, +'kwm' => 1, +'kwn' => 1, +'kwo' => 1, +'kwp' => 1, +'kwq' => 1, +'kwr' => 1, +'kws' => 1, +'kwt' => 1, +'kwu' => 1, +'kwv' => 1, +'kww' => 1, +'kwx' => 1, +'kwz' => 1, +'kxa' => 1, +'kxb' => 1, +'kxc' => 1, +'kxe' => 1, +'kxf' => 1, +'kxh' => 1, +'kxi' => 1, +'kxj' => 1, +'kxk' => 1, +'kxl' => 1, +'kxm' => 1, +'kxn' => 1, +'kxo' => 1, +'kxp' => 1, +'kxq' => 1, +'kxr' => 1, +'kxs' => 1, +'kxt' => 1, +'kxu' => 1, +'kxv' => 1, +'kxw' => 1, +'kxx' => 1, +'kxy' => 1, +'kxz' => 1, +'kya' => 1, +'kyb' => 1, +'kyc' => 1, +'kyd' => 1, +'kye' => 1, +'kyf' => 1, +'kyg' => 1, +'kyh' => 1, +'kyi' => 1, +'kyj' => 1, +'kyk' => 1, +'kyl' => 1, +'kym' => 1, +'kyn' => 1, +'kyo' => 1, +'kyp' => 1, +'kyq' => 1, +'kyr' => 1, +'kys' => 1, +'kyt' => 1, +'kyu' => 1, +'kyv' => 1, +'kyw' => 1, +'kyx' => 1, +'kyy' => 1, +'kyz' => 1, +'kza' => 1, +'kzb' => 1, +'kzc' => 1, +'kzd' => 1, +'kze' => 1, +'kzf' => 1, +'kzg' => 1, +'kzh' => 1, +'kzi' => 1, +'kzj' => 1, +'kzk' => 1, +'kzl' => 1, +'kzm' => 1, +'kzn' => 1, +'kzo' => 1, +'kzp' => 1, +'kzq' => 1, +'kzr' => 1, +'kzs' => 1, +'kzt' => 1, +'kzu' => 1, +'kzv' => 1, +'kzw' => 1, +'kzx' => 1, +'kzy' => 1, +'kzz' => 1, +'laa' => 1, +'lab' => 1, +'lac' => 1, +'lad' => 1, +'lae' => 1, +'laf' => 1, +'lag' => 1, +'lah' => 1, +'lai' => 1, +'laj' => 1, +'lak' => 1, +'lal' => 1, +'lam' => 1, +'lan' => 1, +'lap' => 1, +'laq' => 1, +'lar' => 1, +'las' => 1, +'lau' => 1, +'law' => 1, +'lax' => 1, +'lay' => 1, +'laz' => 1, +'lba' => 1, +'lbb' => 1, +'lbc' => 1, +'lbe' => 1, +'lbf' => 1, +'lbg' => 1, +'lbi' => 1, +'lbj' => 1, +'lbm' => 1, +'lbn' => 1, +'lbo' => 1, +'lbq' => 1, +'lbr' => 1, +'lbs' => 1, +'lbt' => 1, +'lbu' => 1, +'lbv' => 1, +'lbw' => 1, +'lbx' => 1, +'lby' => 1, +'lbz' => 1, +'lcc' => 1, +'lcd' => 1, +'lch' => 1, +'lcl' => 1, +'lcm' => 1, +'lcp' => 1, +'lcq' => 1, +'lcs' => 1, +'ldb' => 1, +'ldd' => 1, +'ldg' => 1, +'ldh' => 1, +'ldj' => 1, +'ldk' => 1, +'ldl' => 1, +'ldm' => 1, +'ldn' => 1, +'ldo' => 1, +'ldp' => 1, +'ldq' => 1, +'lea' => 1, +'leb' => 1, +'lec' => 1, +'led' => 1, +'lee' => 1, +'lef' => 1, +'leg' => 1, +'leh' => 1, +'lei' => 1, +'lej' => 1, +'lek' => 1, +'lel' => 1, +'lem' => 1, +'len' => 1, +'leo' => 1, +'lep' => 1, +'leq' => 1, +'ler' => 1, +'les' => 1, +'let' => 1, +'leu' => 1, +'lev' => 1, +'lew' => 1, +'lex' => 1, +'ley' => 1, +'lez' => 1, +'lfa' => 1, +'lfn' => 1, +'lga' => 1, +'lgb' => 1, +'lgg' => 1, +'lgh' => 1, +'lgi' => 1, +'lgk' => 1, +'lgl' => 1, +'lgm' => 1, +'lgn' => 1, +'lgq' => 1, +'lgr' => 1, +'lgt' => 1, +'lgu' => 1, +'lgz' => 1, +'lha' => 1, +'lhh' => 1, +'lhi' => 1, +'lhl' => 1, +'lhm' => 1, +'lhn' => 1, +'lhp' => 1, +'lhs' => 1, +'lht' => 1, +'lhu' => 1, +'lia' => 1, +'lib' => 1, +'lic' => 1, +'lid' => 1, +'lie' => 1, +'lif' => 1, +'lig' => 1, +'lih' => 1, +'lii' => 1, +'lij' => 1, +'lik' => 1, +'lil' => 1, +'lio' => 1, +'lip' => 1, +'liq' => 1, +'lir' => 1, +'lis' => 1, +'liu' => 1, +'liv' => 1, +'lix' => 1, +'liy' => 1, +'liz' => 1, +'lje' => 1, +'lji' => 1, +'ljl' => 1, +'ljp' => 1, +'lka' => 1, +'lkc' => 1, +'lkd' => 1, +'lke' => 1, +'lkh' => 1, +'lki' => 1, +'lkj' => 1, +'lkl' => 1, +'lkn' => 1, +'lkr' => 1, +'lkt' => 1, +'lky' => 1, +'lla' => 1, +'llb' => 1, +'llc' => 1, +'lld' => 1, +'lle' => 1, +'llf' => 1, +'llg' => 1, +'llh' => 1, +'lli' => 1, +'llk' => 1, +'lll' => 1, +'llm' => 1, +'lln' => 1, +'llo' => 1, +'llp' => 1, +'llq' => 1, +'lls' => 1, +'llu' => 1, +'llx' => 1, +'lma' => 1, +'lmb' => 1, +'lmc' => 1, +'lmd' => 1, +'lme' => 1, +'lmf' => 1, +'lmg' => 1, +'lmh' => 1, +'lmi' => 1, +'lmj' => 1, +'lmk' => 1, +'lml' => 1, +'lmm' => 1, +'lmn' => 1, +'lmo' => 1, +'lmp' => 1, +'lmq' => 1, +'lmr' => 1, +'lmu' => 1, +'lmv' => 1, +'lmw' => 1, +'lmx' => 1, +'lmy' => 1, +'lmz' => 1, +'lna' => 1, +'lnb' => 1, +'lnd' => 1, +'lng' => 1, +'lnh' => 1, +'lni' => 1, +'lnj' => 1, +'lnl' => 1, +'lnm' => 1, +'lnn' => 1, +'lno' => 1, +'lns' => 1, +'lnu' => 1, +'lnz' => 1, +'loa' => 1, +'lob' => 1, +'loc' => 1, +'loe' => 1, +'lof' => 1, +'log' => 1, +'loh' => 1, +'loi' => 1, +'loj' => 1, +'lok' => 1, +'lol' => 1, +'lom' => 1, +'lon' => 1, +'loo' => 1, +'lop' => 1, +'loq' => 1, +'lor' => 1, +'los' => 1, +'lot' => 1, +'lou' => 1, +'lov' => 1, +'low' => 1, +'lox' => 1, +'loy' => 1, +'loz' => 1, +'lpa' => 1, +'lpe' => 1, +'lpn' => 1, +'lpo' => 1, +'lpx' => 1, +'lra' => 1, +'lrc' => 1, +'lre' => 1, +'lrg' => 1, +'lrk' => 1, +'lrl' => 1, +'lrn' => 1, +'lro' => 1, +'lrr' => 1, +'lrt' => 1, +'lrv' => 1, +'lrz' => 1, +'lsa' => 1, +'lsd' => 1, +'lse' => 1, +'lsg' => 1, +'lsh' => 1, +'lsi' => 1, +'lsl' => 1, +'lso' => 1, +'lsp' => 1, +'lsr' => 1, +'lss' => 1, +'lst' => 1, +'ltc' => 1, +'lti' => 1, +'ltn' => 1, +'ltu' => 1, +'lua' => 1, +'luc' => 1, +'lud' => 1, +'lue' => 1, +'luf' => 1, +'lui' => 1, +'luj' => 1, +'luk' => 1, +'lul' => 1, +'lum' => 1, +'lun' => 1, +'luo' => 1, +'lup' => 1, +'luq' => 1, +'lur' => 1, +'lus' => 1, +'lut' => 1, +'luu' => 1, +'luv' => 1, +'luw' => 1, +'luy' => 1, +'luz' => 1, +'lva' => 1, +'lvk' => 1, +'lvu' => 1, +'lwa' => 1, +'lwe' => 1, +'lwh' => 1, +'lwl' => 1, +'lwm' => 1, +'lwo' => 1, +'lwt' => 1, +'lww' => 1, +'lya' => 1, +'lyg' => 1, +'lyn' => 1, +'lzl' => 1, +'lzn' => 1, +'lzz' => 1, +'maa' => 1, +'mab' => 1, +'mad' => 1, +'mae' => 1, +'maf' => 1, +'mag' => 1, +'mai' => 1, +'maj' => 1, +'mak' => 1, +'mam' => 1, +'man' => 1, +'map' => 1, +'maq' => 1, +'mas' => 1, +'mat' => 1, +'mau' => 1, +'mav' => 1, +'maw' => 1, +'maz' => 1, +'mba' => 1, +'mbb' => 1, +'mbc' => 1, +'mbd' => 1, +'mbe' => 1, +'mbf' => 1, +'mbh' => 1, +'mbi' => 1, +'mbj' => 1, +'mbk' => 1, +'mbl' => 1, +'mbm' => 1, +'mbn' => 1, +'mbo' => 1, +'mbp' => 1, +'mbq' => 1, +'mbr' => 1, +'mbs' => 1, +'mbt' => 1, +'mbu' => 1, +'mbv' => 1, +'mbw' => 1, +'mbx' => 1, +'mby' => 1, +'mbz' => 1, +'mca' => 1, +'mcb' => 1, +'mcc' => 1, +'mcd' => 1, +'mce' => 1, +'mcf' => 1, +'mcg' => 1, +'mch' => 1, +'mci' => 1, +'mcj' => 1, +'mck' => 1, +'mcl' => 1, +'mcm' => 1, +'mcn' => 1, +'mco' => 1, +'mcp' => 1, +'mcq' => 1, +'mcr' => 1, +'mcs' => 1, +'mct' => 1, +'mcu' => 1, +'mcv' => 1, +'mcw' => 1, +'mcx' => 1, +'mcy' => 1, +'mcz' => 1, +'mda' => 1, +'mdb' => 1, +'mdc' => 1, +'mdd' => 1, +'mde' => 1, +'mdf' => 1, +'mdg' => 1, +'mdh' => 1, +'mdi' => 1, +'mdj' => 1, +'mdk' => 1, +'mdl' => 1, +'mdm' => 1, +'mdn' => 1, +'mdp' => 1, +'mdq' => 1, +'mdr' => 1, +'mds' => 1, +'mdt' => 1, +'mdu' => 1, +'mdv' => 1, +'mdw' => 1, +'mdx' => 1, +'mdy' => 1, +'mdz' => 1, +'mea' => 1, +'meb' => 1, +'mec' => 1, +'med' => 1, +'mee' => 1, +'mef' => 1, +'meg' => 1, +'meh' => 1, +'mei' => 1, +'mej' => 1, +'mek' => 1, +'mel' => 1, +'mem' => 1, +'men' => 1, +'mep' => 1, +'meq' => 1, +'mer' => 1, +'mes' => 1, +'met' => 1, +'meu' => 1, +'mev' => 1, +'mew' => 1, +'mey' => 1, +'mez' => 1, +'mfc' => 1, +'mfd' => 1, +'mfe' => 1, +'mff' => 1, +'mfg' => 1, +'mfh' => 1, +'mfi' => 1, +'mfj' => 1, +'mfk' => 1, +'mfl' => 1, +'mfm' => 1, +'mfn' => 1, +'mfo' => 1, +'mfp' => 1, +'mfq' => 1, +'mfr' => 1, +'mfs' => 1, +'mft' => 1, +'mfu' => 1, +'mfv' => 1, +'mfw' => 1, +'mfx' => 1, +'mfy' => 1, +'mfz' => 1, +'mga' => 1, +'mgb' => 1, +'mgc' => 1, +'mgd' => 1, +'mge' => 1, +'mgf' => 1, +'mgg' => 1, +'mgh' => 1, +'mgi' => 1, +'mgj' => 1, +'mgk' => 1, +'mgl' => 1, +'mgm' => 1, +'mgn' => 1, +'mgo' => 1, +'mgp' => 1, +'mgq' => 1, +'mgr' => 1, +'mgs' => 1, +'mgt' => 1, +'mgu' => 1, +'mgv' => 1, +'mgw' => 1, +'mgx' => 1, +'mgy' => 1, +'mgz' => 1, +'mha' => 1, +'mhb' => 1, +'mhc' => 1, +'mhd' => 1, +'mhe' => 1, +'mhf' => 1, +'mhg' => 1, +'mhh' => 1, +'mhi' => 1, +'mhj' => 1, +'mhk' => 1, +'mhl' => 1, +'mhm' => 1, +'mhn' => 1, +'mho' => 1, +'mhp' => 1, +'mhq' => 1, +'mhs' => 1, +'mht' => 1, +'mhu' => 1, +'mhw' => 1, +'mhx' => 1, +'mhy' => 1, +'mhz' => 1, +'mia' => 1, +'mib' => 1, +'mic' => 1, +'mid' => 1, +'mie' => 1, +'mif' => 1, +'mig' => 1, +'mih' => 1, +'mii' => 1, +'mij' => 1, +'mik' => 1, +'mil' => 1, +'mim' => 1, +'mio' => 1, +'mip' => 1, +'miq' => 1, +'mir' => 1, +'mit' => 1, +'miu' => 1, +'miw' => 1, +'mix' => 1, +'miy' => 1, +'miz' => 1, +'mja' => 1, +'mjc' => 1, +'mjd' => 1, +'mje' => 1, +'mjg' => 1, +'mjh' => 1, +'mji' => 1, +'mjj' => 1, +'mjk' => 1, +'mjl' => 1, +'mjm' => 1, +'mjn' => 1, +'mjo' => 1, +'mjp' => 1, +'mjq' => 1, +'mjr' => 1, +'mjs' => 1, +'mjt' => 1, +'mju' => 1, +'mjv' => 1, +'mjw' => 1, +'mjx' => 1, +'mjy' => 1, +'mjz' => 1, +'mka' => 1, +'mkb' => 1, +'mkc' => 1, +'mke' => 1, +'mkf' => 1, +'mkg' => 1, +'mkh' => 1, +'mki' => 1, +'mkj' => 1, +'mkk' => 1, +'mkl' => 1, +'mkm' => 1, +'mkn' => 1, +'mko' => 1, +'mkp' => 1, +'mkq' => 1, +'mkr' => 1, +'mks' => 1, +'mkt' => 1, +'mkv' => 1, +'mkw' => 1, +'mkx' => 1, +'mky' => 1, +'mkz' => 1, +'mla' => 1, +'mlb' => 1, +'mlc' => 1, +'mld' => 1, +'mle' => 1, +'mlf' => 1, +'mlh' => 1, +'mli' => 1, +'mlj' => 1, +'mlk' => 1, +'mll' => 1, +'mlm' => 1, +'mln' => 1, +'mlo' => 1, +'mlp' => 1, +'mlr' => 1, +'mls' => 1, +'mlu' => 1, +'mlv' => 1, +'mlw' => 1, +'mlx' => 1, +'mlz' => 1, +'mma' => 1, +'mmb' => 1, +'mmc' => 1, +'mmd' => 1, +'mme' => 1, +'mmf' => 1, +'mmg' => 1, +'mmh' => 1, +'mmi' => 1, +'mmj' => 1, +'mmk' => 1, +'mml' => 1, +'mmm' => 1, +'mmn' => 1, +'mmo' => 1, +'mmp' => 1, +'mmq' => 1, +'mmt' => 1, +'mmu' => 1, +'mmv' => 1, +'mmw' => 1, +'mmx' => 1, +'mmy' => 1, +'mmz' => 1, +'mna' => 1, +'mnb' => 1, +'mnc' => 1, +'mnd' => 1, +'mne' => 1, +'mnf' => 1, +'mng' => 1, +'mnh' => 1, +'mni' => 1, +'mnj' => 1, +'mnl' => 1, +'mnm' => 1, +'mnn' => 1, +'mno' => 1, +'mnq' => 1, +'mnr' => 1, +'mns' => 1, +'mnt' => 1, +'mnu' => 1, +'mnv' => 1, +'mnw' => 1, +'mnx' => 1, +'mny' => 1, +'mnz' => 1, +'moa' => 1, +'moc' => 1, +'mod' => 1, +'moe' => 1, +'mof' => 1, +'mog' => 1, +'moh' => 1, +'moi' => 1, +'moj' => 1, +'mok' => 1, +'mom' => 1, +'moo' => 1, +'mop' => 1, +'moq' => 1, +'mor' => 1, +'mos' => 1, +'mot' => 1, +'mou' => 1, +'mov' => 1, +'mow' => 1, +'mox' => 1, +'moy' => 1, +'moz' => 1, +'mpa' => 1, +'mpb' => 1, +'mpc' => 1, +'mpd' => 1, +'mpe' => 1, +'mpg' => 1, +'mph' => 1, +'mpi' => 1, +'mpj' => 1, +'mpk' => 1, +'mpl' => 1, +'mpm' => 1, +'mpn' => 1, +'mpo' => 1, +'mpp' => 1, +'mpq' => 1, +'mpr' => 1, +'mps' => 1, +'mpt' => 1, +'mpu' => 1, +'mpv' => 1, +'mpw' => 1, +'mpx' => 1, +'mpy' => 1, +'mpz' => 1, +'mqa' => 1, +'mqb' => 1, +'mqc' => 1, +'mqe' => 1, +'mqf' => 1, +'mqh' => 1, +'mqi' => 1, +'mqj' => 1, +'mqk' => 1, +'mql' => 1, +'mqm' => 1, +'mqn' => 1, +'mqo' => 1, +'mqp' => 1, +'mqq' => 1, +'mqr' => 1, +'mqs' => 1, +'mqt' => 1, +'mqu' => 1, +'mqv' => 1, +'mqw' => 1, +'mqx' => 1, +'mqy' => 1, +'mqz' => 1, +'mra' => 1, +'mrb' => 1, +'mrc' => 1, +'mrd' => 1, +'mre' => 1, +'mrf' => 1, +'mrg' => 1, +'mrh' => 1, +'mrk' => 1, +'mrl' => 1, +'mrm' => 1, +'mrn' => 1, +'mro' => 1, +'mrp' => 1, +'mrq' => 1, +'mrr' => 1, +'mrs' => 1, +'mrt' => 1, +'mru' => 1, +'mrv' => 1, +'mrw' => 1, +'mrx' => 1, +'mry' => 1, +'mrz' => 1, +'msb' => 1, +'msd' => 1, +'mse' => 1, +'msf' => 1, +'msg' => 1, +'msj' => 1, +'msk' => 1, +'msl' => 1, +'msm' => 1, +'msn' => 1, +'mso' => 1, +'msp' => 1, +'msq' => 1, +'msr' => 1, +'mss' => 1, +'mst' => 1, +'msu' => 1, +'msv' => 1, +'msw' => 1, +'msx' => 1, +'msy' => 1, +'msz' => 1, +'mta' => 1, +'mtb' => 1, +'mtc' => 1, +'mtd' => 1, +'mte' => 1, +'mtf' => 1, +'mtg' => 1, +'mth' => 1, +'mti' => 1, +'mtj' => 1, +'mtk' => 1, +'mtl' => 1, +'mtm' => 1, +'mtn' => 1, +'mto' => 1, +'mtp' => 1, +'mtq' => 1, +'mts' => 1, +'mtt' => 1, +'mtu' => 1, +'mtv' => 1, +'mtw' => 1, +'mtx' => 1, +'mty' => 1, +'mua' => 1, +'mub' => 1, +'muc' => 1, +'mud' => 1, +'mue' => 1, +'mug' => 1, +'muh' => 1, +'muj' => 1, +'muk' => 1, +'mum' => 1, +'mun' => 1, +'muo' => 1, +'mur' => 1, +'mus' => 1, +'mut' => 1, +'muu' => 1, +'muv' => 1, +'mux' => 1, +'muy' => 1, +'muz' => 1, +'mva' => 1, +'mvb' => 1, +'mvd' => 1, +'mvg' => 1, +'mvh' => 1, +'mvi' => 1, +'mvk' => 1, +'mvl' => 1, +'mvm' => 1, +'mvn' => 1, +'mvo' => 1, +'mvp' => 1, +'mvq' => 1, +'mvr' => 1, +'mvs' => 1, +'mvt' => 1, +'mvu' => 1, +'mvv' => 1, +'mvw' => 1, +'mvx' => 1, +'mvy' => 1, +'mvz' => 1, +'mwa' => 1, +'mwb' => 1, +'mwc' => 1, +'mwd' => 1, +'mwe' => 1, +'mwf' => 1, +'mwg' => 1, +'mwh' => 1, +'mwi' => 1, +'mwj' => 1, +'mwl' => 1, +'mwm' => 1, +'mwn' => 1, +'mwo' => 1, +'mwp' => 1, +'mwq' => 1, +'mwr' => 1, +'mws' => 1, +'mwt' => 1, +'mwu' => 1, +'mwv' => 1, +'mwx' => 1, +'mwy' => 1, +'mwz' => 1, +'mxa' => 1, +'mxb' => 1, +'mxc' => 1, +'mxd' => 1, +'mxe' => 1, +'mxf' => 1, +'mxg' => 1, +'mxh' => 1, +'mxi' => 1, +'mxj' => 1, +'mxk' => 1, +'mxl' => 1, +'mxm' => 1, +'mxn' => 1, +'mxo' => 1, +'mxp' => 1, +'mxq' => 1, +'mxr' => 1, +'mxs' => 1, +'mxt' => 1, +'mxu' => 1, +'mxv' => 1, +'mxw' => 1, +'mxx' => 1, +'mxy' => 1, +'mxz' => 1, +'myb' => 1, +'myc' => 1, +'myd' => 1, +'mye' => 1, +'myf' => 1, +'myg' => 1, +'myh' => 1, +'myi' => 1, +'myj' => 1, +'myk' => 1, +'myl' => 1, +'mym' => 1, +'myn' => 1, +'myo' => 1, +'myp' => 1, +'myr' => 1, +'mys' => 1, +'myt' => 1, +'myu' => 1, +'myv' => 1, +'myw' => 1, +'myx' => 1, +'myy' => 1, +'myz' => 1, +'mza' => 1, +'mzb' => 1, +'mzc' => 1, +'mzd' => 1, +'mze' => 1, +'mzg' => 1, +'mzh' => 1, +'mzi' => 1, +'mzj' => 1, +'mzk' => 1, +'mzl' => 1, +'mzm' => 1, +'mzn' => 1, +'mzo' => 1, +'mzp' => 1, +'mzq' => 1, +'mzr' => 1, +'mzs' => 1, +'mzt' => 1, +'mzu' => 1, +'mzv' => 1, +'mzw' => 1, +'mzx' => 1, +'mzy' => 1, +'mzz' => 1, +'naa' => 1, +'nab' => 1, +'nac' => 1, +'nad' => 1, +'nae' => 1, +'naf' => 1, +'nag' => 1, +'nah' => 1, +'nai' => 1, +'naj' => 1, +'nak' => 1, +'nal' => 1, +'nam' => 1, +'nao' => 1, +'nap' => 1, +'naq' => 1, +'nar' => 1, +'nas' => 1, +'nat' => 1, +'naw' => 1, +'nax' => 1, +'nay' => 1, +'naz' => 1, +'nba' => 1, +'nbb' => 1, +'nbc' => 1, +'nbd' => 1, +'nbe' => 1, +'nbf' => 1, +'nbg' => 1, +'nbh' => 1, +'nbi' => 1, +'nbj' => 1, +'nbk' => 1, +'nbm' => 1, +'nbn' => 1, +'nbo' => 1, +'nbp' => 1, +'nbq' => 1, +'nbr' => 1, +'nbs' => 1, +'nbt' => 1, +'nbu' => 1, +'nbv' => 1, +'nbw' => 1, +'nbx' => 1, +'nby' => 1, +'nca' => 1, +'ncb' => 1, +'ncc' => 1, +'ncd' => 1, +'nce' => 1, +'ncf' => 1, +'ncg' => 1, +'nch' => 1, +'nci' => 1, +'ncj' => 1, +'nck' => 1, +'ncl' => 1, +'ncm' => 1, +'ncn' => 1, +'nco' => 1, +'ncp' => 1, +'ncr' => 1, +'ncs' => 1, +'nct' => 1, +'ncu' => 1, +'ncx' => 1, +'ncz' => 1, +'nda' => 1, +'ndb' => 1, +'ndc' => 1, +'ndd' => 1, +'ndf' => 1, +'ndg' => 1, +'ndh' => 1, +'ndi' => 1, +'ndj' => 1, +'ndk' => 1, +'ndl' => 1, +'ndm' => 1, +'ndn' => 1, +'ndp' => 1, +'ndq' => 1, +'ndr' => 1, +'nds' => 1, +'ndt' => 1, +'ndu' => 1, +'ndv' => 1, +'ndw' => 1, +'ndx' => 1, +'ndy' => 1, +'ndz' => 1, +'nea' => 1, +'neb' => 1, +'nec' => 1, +'ned' => 1, +'nee' => 1, +'nef' => 1, +'neg' => 1, +'neh' => 1, +'nei' => 1, +'nej' => 1, +'nek' => 1, +'nem' => 1, +'nen' => 1, +'neo' => 1, +'neq' => 1, +'ner' => 1, +'nes' => 1, +'net' => 1, +'nev' => 1, +'new' => 1, +'nex' => 1, +'ney' => 1, +'nez' => 1, +'nfa' => 1, +'nfd' => 1, +'nfl' => 1, +'nfr' => 1, +'nfu' => 1, +'nga' => 1, +'ngb' => 1, +'ngc' => 1, +'ngd' => 1, +'nge' => 1, +'ngf' => 1, +'ngg' => 1, +'ngh' => 1, +'ngi' => 1, +'ngj' => 1, +'ngk' => 1, +'ngl' => 1, +'ngm' => 1, +'ngn' => 1, +'ngo' => 1, +'ngp' => 1, +'ngq' => 1, +'ngr' => 1, +'ngs' => 1, +'ngt' => 1, +'ngu' => 1, +'ngv' => 1, +'ngw' => 1, +'ngx' => 1, +'ngy' => 1, +'ngz' => 1, +'nha' => 1, +'nhb' => 1, +'nhc' => 1, +'nhe' => 1, +'nhf' => 1, +'nhg' => 1, +'nhh' => 1, +'nhi' => 1, +'nhk' => 1, +'nhm' => 1, +'nhn' => 1, +'nho' => 1, +'nhp' => 1, +'nhq' => 1, +'nhr' => 1, +'nht' => 1, +'nhu' => 1, +'nhv' => 1, +'nhw' => 1, +'nhx' => 1, +'nhy' => 1, +'nhz' => 1, +'nia' => 1, +'nib' => 1, +'nic' => 1, +'nid' => 1, +'nie' => 1, +'nif' => 1, +'nig' => 1, +'nih' => 1, +'nii' => 1, +'nij' => 1, +'nik' => 1, +'nil' => 1, +'nim' => 1, +'nin' => 1, +'nio' => 1, +'nir' => 1, +'nis' => 1, +'nit' => 1, +'niu' => 1, +'niv' => 1, +'niw' => 1, +'nix' => 1, +'niy' => 1, +'niz' => 1, +'nja' => 1, +'njb' => 1, +'njd' => 1, +'njh' => 1, +'nji' => 1, +'njj' => 1, +'njl' => 1, +'njm' => 1, +'njn' => 1, +'njo' => 1, +'njr' => 1, +'njs' => 1, +'njt' => 1, +'nju' => 1, +'njx' => 1, +'njy' => 1, +'nka' => 1, +'nkb' => 1, +'nkc' => 1, +'nkd' => 1, +'nke' => 1, +'nkf' => 1, +'nkg' => 1, +'nkh' => 1, +'nki' => 1, +'nkj' => 1, +'nkk' => 1, +'nkm' => 1, +'nkn' => 1, +'nko' => 1, +'nkp' => 1, +'nkr' => 1, +'nks' => 1, +'nkt' => 1, +'nku' => 1, +'nkv' => 1, +'nkw' => 1, +'nkx' => 1, +'nkz' => 1, +'nla' => 1, +'nlc' => 1, +'nlg' => 1, +'nli' => 1, +'nlj' => 1, +'nlk' => 1, +'nll' => 1, +'nln' => 1, +'nlo' => 1, +'nlr' => 1, +'nlu' => 1, +'nlv' => 1, +'nlx' => 1, +'nly' => 1, +'nlz' => 1, +'nma' => 1, +'nmb' => 1, +'nmc' => 1, +'nmd' => 1, +'nme' => 1, +'nmf' => 1, +'nmg' => 1, +'nmh' => 1, +'nmi' => 1, +'nmj' => 1, +'nmk' => 1, +'nml' => 1, +'nmm' => 1, +'nmn' => 1, +'nmo' => 1, +'nmp' => 1, +'nmq' => 1, +'nmr' => 1, +'nms' => 1, +'nmt' => 1, +'nmu' => 1, +'nmv' => 1, +'nmw' => 1, +'nmx' => 1, +'nmy' => 1, +'nmz' => 1, +'nna' => 1, +'nnb' => 1, +'nnc' => 1, +'nnd' => 1, +'nne' => 1, +'nnf' => 1, +'nng' => 1, +'nnh' => 1, +'nni' => 1, +'nnj' => 1, +'nnk' => 1, +'nnl' => 1, +'nnm' => 1, +'nnn' => 1, +'nnp' => 1, +'nnq' => 1, +'nnr' => 1, +'nns' => 1, +'nnt' => 1, +'nnu' => 1, +'nnv' => 1, +'nnw' => 1, +'nnx' => 1, +'nny' => 1, +'nnz' => 1, +'noa' => 1, +'noc' => 1, +'nod' => 1, +'noe' => 1, +'nof' => 1, +'nog' => 1, +'noh' => 1, +'noi' => 1, +'nok' => 1, +'nom' => 1, +'non' => 1, +'noo' => 1, +'nop' => 1, +'noq' => 1, +'nos' => 1, +'not' => 1, +'nou' => 1, +'nov' => 1, +'now' => 1, +'noy' => 1, +'noz' => 1, +'npa' => 1, +'npb' => 1, +'nph' => 1, +'npl' => 1, +'npn' => 1, +'npo' => 1, +'nps' => 1, +'npu' => 1, +'npy' => 1, +'nqg' => 1, +'nqk' => 1, +'nqm' => 1, +'nqn' => 1, +'nqo' => 1, +'nra' => 1, +'nrb' => 1, +'nrc' => 1, +'nre' => 1, +'nrg' => 1, +'nri' => 1, +'nrl' => 1, +'nrm' => 1, +'nrn' => 1, +'nrp' => 1, +'nrr' => 1, +'nrt' => 1, +'nrx' => 1, +'nrz' => 1, +'nsa' => 1, +'nsc' => 1, +'nsd' => 1, +'nse' => 1, +'nsg' => 1, +'nsh' => 1, +'nsi' => 1, +'nsk' => 1, +'nsl' => 1, +'nsm' => 1, +'nsn' => 1, +'nso' => 1, +'nsp' => 1, +'nsq' => 1, +'nsr' => 1, +'nss' => 1, +'nst' => 1, +'nsu' => 1, +'nsv' => 1, +'nsw' => 1, +'nsx' => 1, +'nsy' => 1, +'nsz' => 1, +'nte' => 1, +'nti' => 1, +'ntj' => 1, +'ntk' => 1, +'ntm' => 1, +'nto' => 1, +'ntp' => 1, +'ntr' => 1, +'nts' => 1, +'ntu' => 1, +'ntw' => 1, +'nty' => 1, +'ntz' => 1, +'nua' => 1, +'nub' => 1, +'nuc' => 1, +'nud' => 1, +'nue' => 1, +'nuf' => 1, +'nug' => 1, +'nuh' => 1, +'nui' => 1, +'nuj' => 1, +'nul' => 1, +'num' => 1, +'nun' => 1, +'nuo' => 1, +'nup' => 1, +'nuq' => 1, +'nur' => 1, +'nus' => 1, +'nut' => 1, +'nuu' => 1, +'nuv' => 1, +'nuw' => 1, +'nux' => 1, +'nuy' => 1, +'nuz' => 1, +'nvh' => 1, +'nvm' => 1, +'nwa' => 1, +'nwb' => 1, +'nwc' => 1, +'nwe' => 1, +'nwi' => 1, +'nwm' => 1, +'nwr' => 1, +'nwx' => 1, +'nwy' => 1, +'nxa' => 1, +'nxd' => 1, +'nxe' => 1, +'nxg' => 1, +'nxi' => 1, +'nxl' => 1, +'nxm' => 1, +'nxn' => 1, +'nxr' => 1, +'nxu' => 1, +'nxx' => 1, +'nyb' => 1, +'nyc' => 1, +'nye' => 1, +'nyf' => 1, +'nyg' => 1, +'nyh' => 1, +'nyi' => 1, +'nyj' => 1, +'nyk' => 1, +'nyl' => 1, +'nym' => 1, +'nyn' => 1, +'nyo' => 1, +'nyp' => 1, +'nyq' => 1, +'nyr' => 1, +'nys' => 1, +'nyt' => 1, +'nyu' => 1, +'nyv' => 1, +'nyw' => 1, +'nyx' => 1, +'nyy' => 1, +'nza' => 1, +'nzb' => 1, +'nzi' => 1, +'nzk' => 1, +'nzm' => 1, +'nzs' => 1, +'nzu' => 1, +'nzy' => 1, +'oaa' => 1, +'oac' => 1, +'oar' => 1, +'oav' => 1, +'obi' => 1, +'obl' => 1, +'obm' => 1, +'obo' => 1, +'obr' => 1, +'obt' => 1, +'obu' => 1, +'oca' => 1, +'och' => 1, +'oco' => 1, +'ocu' => 1, +'oda' => 1, +'odk' => 1, +'odt' => 1, +'odu' => 1, +'ofo' => 1, +'ofs' => 1, +'ofu' => 1, +'ogb' => 1, +'ogc' => 1, +'oge' => 1, +'ogg' => 1, +'ogo' => 1, +'ogu' => 1, +'oht' => 1, +'ohu' => 1, +'oia' => 1, +'oin' => 1, +'ojp' => 1, +'ojv' => 1, +'oka' => 1, +'okb' => 1, +'okd' => 1, +'oke' => 1, +'okh' => 1, +'okj' => 1, +'okk' => 1, +'okl' => 1, +'okm' => 1, +'okn' => 1, +'oko' => 1, +'okr' => 1, +'oks' => 1, +'oku' => 1, +'okv' => 1, +'okx' => 1, +'ola' => 1, +'old' => 1, +'ole' => 1, +'olm' => 1, +'olo' => 1, +'olr' => 1, +'oma' => 1, +'omb' => 1, +'omc' => 1, +'ome' => 1, +'omg' => 1, +'omi' => 1, +'omk' => 1, +'oml' => 1, +'omn' => 1, +'omo' => 1, +'omp' => 1, +'omq' => 1, +'omr' => 1, +'omt' => 1, +'omu' => 1, +'omv' => 1, +'omw' => 1, +'omx' => 1, +'ona' => 1, +'onb' => 1, +'one' => 1, +'ong' => 1, +'oni' => 1, +'onj' => 1, +'onk' => 1, +'onn' => 1, +'ono' => 1, +'onp' => 1, +'onr' => 1, +'ons' => 1, +'ont' => 1, +'onu' => 1, +'onw' => 1, +'onx' => 1, +'ood' => 1, +'oog' => 1, +'oon' => 1, +'oor' => 1, +'oos' => 1, +'opa' => 1, +'opk' => 1, +'opm' => 1, +'opo' => 1, +'opt' => 1, +'opy' => 1, +'ora' => 1, +'ore' => 1, +'org' => 1, +'orh' => 1, +'oro' => 1, +'orr' => 1, +'ort' => 1, +'oru' => 1, +'orv' => 1, +'orw' => 1, +'orx' => 1, +'orz' => 1, +'osa' => 1, +'osc' => 1, +'osi' => 1, +'oso' => 1, +'osp' => 1, +'ost' => 1, +'osu' => 1, +'osx' => 1, +'ota' => 1, +'otb' => 1, +'otd' => 1, +'ote' => 1, +'oti' => 1, +'otk' => 1, +'otl' => 1, +'otm' => 1, +'otn' => 1, +'oto' => 1, +'otq' => 1, +'otr' => 1, +'ots' => 1, +'ott' => 1, +'otu' => 1, +'otx' => 1, +'oty' => 1, +'otz' => 1, +'oua' => 1, +'oub' => 1, +'oue' => 1, +'oui' => 1, +'oum' => 1, +'oun' => 1, +'owi' => 1, +'owl' => 1, +'oyb' => 1, +'oyd' => 1, +'oym' => 1, +'oyy' => 1, +'ozm' => 1, +'paa' => 1, +'pab' => 1, +'pac' => 1, +'pad' => 1, +'pae' => 1, +'paf' => 1, +'pag' => 1, +'pah' => 1, +'pai' => 1, +'pak' => 1, +'pal' => 1, +'pam' => 1, +'pao' => 1, +'pap' => 1, +'paq' => 1, +'par' => 1, +'pas' => 1, +'pat' => 1, +'pau' => 1, +'pav' => 1, +'paw' => 1, +'pax' => 1, +'pay' => 1, +'paz' => 1, +'pbb' => 1, +'pbc' => 1, +'pbe' => 1, +'pbf' => 1, +'pbg' => 1, +'pbh' => 1, +'pbi' => 1, +'pbl' => 1, +'pbn' => 1, +'pbo' => 1, +'pbp' => 1, +'pbr' => 1, +'pbs' => 1, +'pbv' => 1, +'pby' => 1, +'pbz' => 1, +'pca' => 1, +'pcb' => 1, +'pcc' => 1, +'pcd' => 1, +'pce' => 1, +'pcf' => 1, +'pcg' => 1, +'pch' => 1, +'pci' => 1, +'pcj' => 1, +'pck' => 1, +'pcl' => 1, +'pcm' => 1, +'pcn' => 1, +'pcp' => 1, +'pcr' => 1, +'pcw' => 1, +'pda' => 1, +'pdc' => 1, +'pdi' => 1, +'pdn' => 1, +'pdo' => 1, +'pdt' => 1, +'pdu' => 1, +'pea' => 1, +'peb' => 1, +'ped' => 1, +'pee' => 1, +'pef' => 1, +'peg' => 1, +'peh' => 1, +'pei' => 1, +'pej' => 1, +'pek' => 1, +'pem' => 1, +'peo' => 1, +'pep' => 1, +'peq' => 1, +'pev' => 1, +'pex' => 1, +'pey' => 1, +'pez' => 1, +'pfa' => 1, +'pfe' => 1, +'pfl' => 1, +'pgg' => 1, +'pgi' => 1, +'pgk' => 1, +'pgn' => 1, +'pgs' => 1, +'pgu' => 1, +'pgy' => 1, +'pha' => 1, +'phd' => 1, +'phg' => 1, +'phh' => 1, +'phi' => 1, +'phk' => 1, +'phl' => 1, +'phm' => 1, +'phn' => 1, +'pho' => 1, +'phq' => 1, +'pht' => 1, +'phu' => 1, +'phv' => 1, +'phw' => 1, +'pia' => 1, +'pib' => 1, +'pic' => 1, +'pid' => 1, +'pie' => 1, +'pif' => 1, +'pig' => 1, +'pih' => 1, +'pii' => 1, +'pij' => 1, +'pil' => 1, +'pim' => 1, +'pin' => 1, +'pio' => 1, +'pip' => 1, +'pir' => 1, +'pis' => 1, +'pit' => 1, +'piu' => 1, +'piv' => 1, +'piw' => 1, +'pix' => 1, +'piy' => 1, +'piz' => 1, +'pjt' => 1, +'pka' => 1, +'pkb' => 1, +'pkc' => 1, +'pkg' => 1, +'pkh' => 1, +'pkn' => 1, +'pkp' => 1, +'pkr' => 1, +'pks' => 1, +'pkt' => 1, +'pku' => 1, +'pla' => 1, +'plb' => 1, +'plc' => 1, +'pld' => 1, +'ple' => 1, +'plf' => 1, +'plg' => 1, +'plh' => 1, +'plj' => 1, +'plk' => 1, +'pll' => 1, +'pln' => 1, +'plo' => 1, +'plp' => 1, +'plq' => 1, +'plr' => 1, +'pls' => 1, +'plu' => 1, +'plv' => 1, +'plw' => 1, +'ply' => 1, +'plz' => 1, +'pma' => 1, +'pmb' => 1, +'pmc' => 1, +'pme' => 1, +'pmf' => 1, +'pmh' => 1, +'pmi' => 1, +'pmj' => 1, +'pmk' => 1, +'pml' => 1, +'pmm' => 1, +'pmn' => 1, +'pmo' => 1, +'pmq' => 1, +'pmr' => 1, +'pms' => 1, +'pmt' => 1, +'pmw' => 1, +'pmx' => 1, +'pmy' => 1, +'pmz' => 1, +'pna' => 1, +'pnc' => 1, +'pne' => 1, +'png' => 1, +'pnh' => 1, +'pni' => 1, +'pnm' => 1, +'pnn' => 1, +'pno' => 1, +'pnp' => 1, +'pnq' => 1, +'pnr' => 1, +'pns' => 1, +'pnt' => 1, +'pnu' => 1, +'pnv' => 1, +'pnw' => 1, +'pnx' => 1, +'pny' => 1, +'pnz' => 1, +'poc' => 1, +'pod' => 1, +'poe' => 1, +'pof' => 1, +'pog' => 1, +'poh' => 1, +'poi' => 1, +'pok' => 1, +'pom' => 1, +'pon' => 1, +'poo' => 1, +'pop' => 1, +'poq' => 1, +'pos' => 1, +'pot' => 1, +'pov' => 1, +'pow' => 1, +'pox' => 1, +'poy' => 1, +'poz' => 1, +'ppa' => 1, +'ppe' => 1, +'ppi' => 1, +'ppk' => 1, +'ppl' => 1, +'ppm' => 1, +'ppn' => 1, +'ppo' => 1, +'ppp' => 1, +'ppq' => 1, +'ppr' => 1, +'pps' => 1, +'ppt' => 1, +'ppu' => 1, +'pqa' => 1, +'pqe' => 1, +'pqm' => 1, +'pqw' => 1, +'pra' => 1, +'prb' => 1, +'prc' => 1, +'prd' => 1, +'pre' => 1, +'prg' => 1, +'prh' => 1, +'pri' => 1, +'prk' => 1, +'prl' => 1, +'prm' => 1, +'prn' => 1, +'pro' => 1, +'prp' => 1, +'prq' => 1, +'prr' => 1, +'prt' => 1, +'pru' => 1, +'prw' => 1, +'prx' => 1, +'pry' => 1, +'prz' => 1, +'psa' => 1, +'psc' => 1, +'psd' => 1, +'psg' => 1, +'psh' => 1, +'psi' => 1, +'psl' => 1, +'psm' => 1, +'psn' => 1, +'pso' => 1, +'psp' => 1, +'psq' => 1, +'psr' => 1, +'pss' => 1, +'psu' => 1, +'psw' => 1, +'psy' => 1, +'pta' => 1, +'pth' => 1, +'pti' => 1, +'ptn' => 1, +'pto' => 1, +'ptp' => 1, +'ptr' => 1, +'ptt' => 1, +'ptu' => 1, +'ptv' => 1, +'ptw' => 1, +'pty' => 1, +'pua' => 1, +'pub' => 1, +'puc' => 1, +'pud' => 1, +'pue' => 1, +'puf' => 1, +'pug' => 1, +'pui' => 1, +'puj' => 1, +'puk' => 1, +'pum' => 1, +'puo' => 1, +'pup' => 1, +'puq' => 1, +'pur' => 1, +'put' => 1, +'puu' => 1, +'puw' => 1, +'pux' => 1, +'puy' => 1, +'puz' => 1, +'pwa' => 1, +'pwb' => 1, +'pwg' => 1, +'pwm' => 1, +'pwn' => 1, +'pwo' => 1, +'pwr' => 1, +'pww' => 1, +'pxm' => 1, +'pye' => 1, +'pym' => 1, +'pyn' => 1, +'pyu' => 1, +'pyx' => 1, +'pyy' => 1, +'pzn' => 1, +'qua' => 1, +'quc' => 1, +'qui' => 1, +'qum' => 1, +'qun' => 1, +'quq' => 1, +'quv' => 1, +'qvy' => 1, +'qwe' => 1, +'qwm' => 1, +'qwt' => 1, +'qxq' => 1, +'qxs' => 1, +'qya' => 1, +'qyp' => 1, +'raa' => 1, +'rab' => 1, +'rac' => 1, +'rad' => 1, +'raf' => 1, +'rah' => 1, +'rai' => 1, +'raj' => 1, +'rak' => 1, +'ral' => 1, +'ram' => 1, +'ran' => 1, +'rao' => 1, +'rap' => 1, +'raq' => 1, +'rar' => 1, +'ras' => 1, +'rat' => 1, +'rau' => 1, +'rav' => 1, +'raw' => 1, +'rax' => 1, +'ray' => 1, +'raz' => 1, +'rbb' => 1, +'rcf' => 1, +'rdb' => 1, +'rea' => 1, +'reb' => 1, +'ree' => 1, +'reg' => 1, +'rei' => 1, +'rej' => 1, +'rel' => 1, +'rem' => 1, +'ren' => 1, +'rer' => 1, +'res' => 1, +'ret' => 1, +'rey' => 1, +'rga' => 1, +'rge' => 1, +'rgk' => 1, +'rgn' => 1, +'rgr' => 1, +'rgs' => 1, +'rgu' => 1, +'rhg' => 1, +'rhp' => 1, +'ria' => 1, +'rie' => 1, +'rif' => 1, +'ril' => 1, +'rim' => 1, +'rin' => 1, +'rir' => 1, +'rit' => 1, +'riu' => 1, +'rjg' => 1, +'rji' => 1, +'rjs' => 1, +'rka' => 1, +'rkb' => 1, +'rkh' => 1, +'rki' => 1, +'rkm' => 1, +'rkt' => 1, +'rma' => 1, +'rmb' => 1, +'rmd' => 1, +'rme' => 1, +'rmg' => 1, +'rmh' => 1, +'rmi' => 1, +'rmk' => 1, +'rmm' => 1, +'rmp' => 1, +'rmr' => 1, +'rms' => 1, +'rmt' => 1, +'rmu' => 1, +'rmv' => 1, +'rmx' => 1, +'rmz' => 1, +'rna' => 1, +'rnd' => 1, +'rng' => 1, +'rnl' => 1, +'rnn' => 1, +'rnp' => 1, +'rnw' => 1, +'roa' => 1, +'rob' => 1, +'roc' => 1, +'rod' => 1, +'roe' => 1, +'rof' => 1, +'rog' => 1, +'rol' => 1, +'rom' => 1, +'roo' => 1, +'rop' => 1, +'ror' => 1, +'rou' => 1, +'row' => 1, +'rpn' => 1, +'rpt' => 1, +'rri' => 1, +'rro' => 1, +'rsb' => 1, +'rsi' => 1, +'rsl' => 1, +'rth' => 1, +'rtm' => 1, +'rtw' => 1, +'rub' => 1, +'ruc' => 1, +'rue' => 1, +'ruf' => 1, +'rug' => 1, +'ruh' => 1, +'rui' => 1, +'ruk' => 1, +'ruo' => 1, +'rup' => 1, +'ruq' => 1, +'rut' => 1, +'ruu' => 1, +'ruy' => 1, +'ruz' => 1, +'rwa' => 1, +'rwk' => 1, +'rwm' => 1, +'rwo' => 1, +'ryn' => 1, +'rys' => 1, +'ryu' => 1, +'saa' => 1, +'sab' => 1, +'sac' => 1, +'sad' => 1, +'sae' => 1, +'saf' => 1, +'sah' => 1, +'sai' => 1, +'saj' => 1, +'sak' => 1, +'sal' => 1, +'sam' => 1, +'sao' => 1, +'sap' => 1, +'saq' => 1, +'sar' => 1, +'sas' => 1, +'sat' => 1, +'sau' => 1, +'sav' => 1, +'saw' => 1, +'sax' => 1, +'say' => 1, +'saz' => 1, +'sba' => 1, +'sbb' => 1, +'sbc' => 1, +'sbd' => 1, +'sbe' => 1, +'sbf' => 1, +'sbg' => 1, +'sbh' => 1, +'sbi' => 1, +'sbj' => 1, +'sbk' => 1, +'sbl' => 1, +'sbm' => 1, +'sbn' => 1, +'sbo' => 1, +'sbp' => 1, +'sbq' => 1, +'sbr' => 1, +'sbs' => 1, +'sbt' => 1, +'sbu' => 1, +'sbv' => 1, +'sbw' => 1, +'sbx' => 1, +'sby' => 1, +'sbz' => 1, +'sca' => 1, +'scb' => 1, +'sce' => 1, +'scf' => 1, +'scg' => 1, +'sch' => 1, +'sci' => 1, +'sck' => 1, +'scl' => 1, +'scn' => 1, +'sco' => 1, +'scp' => 1, +'scq' => 1, +'scu' => 1, +'scv' => 1, +'scw' => 1, +'scx' => 1, +'sda' => 1, +'sdb' => 1, +'sde' => 1, +'sdf' => 1, +'sdg' => 1, +'sdj' => 1, +'sdk' => 1, +'sdl' => 1, +'sdm' => 1, +'sdo' => 1, +'sdp' => 1, +'sdr' => 1, +'sds' => 1, +'sdt' => 1, +'sdu' => 1, +'sdv' => 1, +'sdx' => 1, +'sdz' => 1, +'sea' => 1, +'seb' => 1, +'sec' => 1, +'sed' => 1, +'see' => 1, +'sef' => 1, +'seg' => 1, +'seh' => 1, +'sei' => 1, +'sej' => 1, +'sek' => 1, +'sel' => 1, +'sem' => 1, +'sen' => 1, +'seo' => 1, +'sep' => 1, +'seq' => 1, +'ser' => 1, +'ses' => 1, +'set' => 1, +'seu' => 1, +'sev' => 1, +'sew' => 1, +'sey' => 1, +'sez' => 1, +'sfb' => 1, +'sfs' => 1, +'sfw' => 1, +'sga' => 1, +'sgb' => 1, +'sge' => 1, +'sgg' => 1, +'sgh' => 1, +'sgi' => 1, +'sgk' => 1, +'sgl' => 1, +'sgm' => 1, +'sgn' => 1, +'sgo' => 1, +'sgp' => 1, +'sgr' => 1, +'sgt' => 1, +'sgu' => 1, +'sgw' => 1, +'sgx' => 1, +'sgz' => 1, +'sha' => 1, +'shb' => 1, +'shc' => 1, +'she' => 1, +'shg' => 1, +'shh' => 1, +'shi' => 1, +'shj' => 1, +'shk' => 1, +'shl' => 1, +'shm' => 1, +'shn' => 1, +'sho' => 1, +'shp' => 1, +'shq' => 1, +'shr' => 1, +'shs' => 1, +'sht' => 1, +'shv' => 1, +'shw' => 1, +'shx' => 1, +'shy' => 1, +'shz' => 1, +'sia' => 1, +'sib' => 1, +'sid' => 1, +'sie' => 1, +'sif' => 1, +'sig' => 1, +'sih' => 1, +'sii' => 1, +'sij' => 1, +'sik' => 1, +'sil' => 1, +'sim' => 1, +'sio' => 1, +'sip' => 1, +'siq' => 1, +'sir' => 1, +'sis' => 1, +'sit' => 1, +'siu' => 1, +'siv' => 1, +'siw' => 1, +'six' => 1, +'siy' => 1, +'siz' => 1, +'sja' => 1, +'sjb' => 1, +'sjd' => 1, +'sje' => 1, +'sjg' => 1, +'sjk' => 1, +'sjl' => 1, +'sjm' => 1, +'sjn' => 1, +'sjo' => 1, +'sjp' => 1, +'sjr' => 1, +'sjs' => 1, +'sjt' => 1, +'sju' => 1, +'sjw' => 1, +'ska' => 1, +'skb' => 1, +'skc' => 1, +'skd' => 1, +'ske' => 1, +'skf' => 1, +'skh' => 1, +'ski' => 1, +'skj' => 1, +'skk' => 1, +'skm' => 1, +'skn' => 1, +'sko' => 1, +'skp' => 1, +'skq' => 1, +'sks' => 1, +'skt' => 1, +'sku' => 1, +'skv' => 1, +'skw' => 1, +'skx' => 1, +'sky' => 1, +'skz' => 1, +'sla' => 1, +'slc' => 1, +'sld' => 1, +'sle' => 1, +'slf' => 1, +'slg' => 1, +'slh' => 1, +'sli' => 1, +'slj' => 1, +'sll' => 1, +'slm' => 1, +'sln' => 1, +'slp' => 1, +'slq' => 1, +'slr' => 1, +'sls' => 1, +'slt' => 1, +'slu' => 1, +'slw' => 1, +'slx' => 1, +'sly' => 1, +'slz' => 1, +'sma' => 1, +'smb' => 1, +'smc' => 1, +'smd' => 1, +'smf' => 1, +'smg' => 1, +'smh' => 1, +'smi' => 1, +'smj' => 1, +'smk' => 1, +'sml' => 1, +'smm' => 1, +'smn' => 1, +'smp' => 1, +'smq' => 1, +'smr' => 1, +'sms' => 1, +'smt' => 1, +'smu' => 1, +'smv' => 1, +'smw' => 1, +'smx' => 1, +'smy' => 1, +'smz' => 1, +'snb' => 1, +'snc' => 1, +'sne' => 1, +'snf' => 1, +'sng' => 1, +'snh' => 1, +'sni' => 1, +'snj' => 1, +'snk' => 1, +'snl' => 1, +'snm' => 1, +'snn' => 1, +'sno' => 1, +'snp' => 1, +'snq' => 1, +'snr' => 1, +'sns' => 1, +'snu' => 1, +'snv' => 1, +'snw' => 1, +'snx' => 1, +'sny' => 1, +'snz' => 1, +'soa' => 1, +'sob' => 1, +'soc' => 1, +'sod' => 1, +'soe' => 1, +'sog' => 1, +'soh' => 1, +'soi' => 1, +'soj' => 1, +'sok' => 1, +'sol' => 1, +'son' => 1, +'soo' => 1, +'sop' => 1, +'soq' => 1, +'sor' => 1, +'sos' => 1, +'sou' => 1, +'sov' => 1, +'sow' => 1, +'sox' => 1, +'soy' => 1, +'soz' => 1, +'spb' => 1, +'spc' => 1, +'spd' => 1, +'spe' => 1, +'spg' => 1, +'spi' => 1, +'spk' => 1, +'spl' => 1, +'spm' => 1, +'spo' => 1, +'spp' => 1, +'spq' => 1, +'spr' => 1, +'sps' => 1, +'spt' => 1, +'spu' => 1, +'spx' => 1, +'sqa' => 1, +'sqh' => 1, +'sqj' => 1, +'sqm' => 1, +'sqn' => 1, +'sqo' => 1, +'sqq' => 1, +'sqr' => 1, +'sqs' => 1, +'sqt' => 1, +'squ' => 1, +'sra' => 1, +'srb' => 1, +'sre' => 1, +'srf' => 1, +'srg' => 1, +'srh' => 1, +'sri' => 1, +'srk' => 1, +'srl' => 1, +'srm' => 1, +'srn' => 1, +'srq' => 1, +'srr' => 1, +'srs' => 1, +'srt' => 1, +'sru' => 1, +'srv' => 1, +'srw' => 1, +'srx' => 1, +'sry' => 1, +'srz' => 1, +'ssa' => 1, +'ssb' => 1, +'ssc' => 1, +'ssd' => 1, +'sse' => 1, +'ssf' => 1, +'ssg' => 1, +'ssi' => 1, +'ssj' => 1, +'ssk' => 1, +'ssl' => 1, +'ssm' => 1, +'ssn' => 1, +'sso' => 1, +'ssp' => 1, +'ssq' => 1, +'ssr' => 1, +'sss' => 1, +'sst' => 1, +'ssu' => 1, +'ssv' => 1, +'ssx' => 1, +'ssy' => 1, +'ssz' => 1, +'sta' => 1, +'stb' => 1, +'std' => 1, +'ste' => 1, +'stf' => 1, +'stg' => 1, +'sth' => 1, +'sti' => 1, +'stj' => 1, +'stk' => 1, +'stl' => 1, +'stm' => 1, +'stn' => 1, +'sto' => 1, +'stp' => 1, +'stq' => 1, +'str' => 1, +'sts' => 1, +'stt' => 1, +'stu' => 1, +'stv' => 1, +'stw' => 1, +'sua' => 1, +'sub' => 1, +'suc' => 1, +'sue' => 1, +'sug' => 1, +'sui' => 1, +'suj' => 1, +'suk' => 1, +'sul' => 1, +'sum' => 1, +'suq' => 1, +'sur' => 1, +'sus' => 1, +'sut' => 1, +'suv' => 1, +'suw' => 1, +'sux' => 1, +'suy' => 1, +'suz' => 1, +'sva' => 1, +'svb' => 1, +'svc' => 1, +'sve' => 1, +'svk' => 1, +'svr' => 1, +'svs' => 1, +'svx' => 1, +'swb' => 1, +'swf' => 1, +'swg' => 1, +'swi' => 1, +'swj' => 1, +'swk' => 1, +'swl' => 1, +'swm' => 1, +'swn' => 1, +'swo' => 1, +'swp' => 1, +'swq' => 1, +'swr' => 1, +'sws' => 1, +'swt' => 1, +'swu' => 1, +'sww' => 1, +'swx' => 1, +'swy' => 1, +'sxb' => 1, +'sxc' => 1, +'sxe' => 1, +'sxg' => 1, +'sxk' => 1, +'sxl' => 1, +'sxm' => 1, +'sxn' => 1, +'sxo' => 1, +'sxr' => 1, +'sxs' => 1, +'sxu' => 1, +'sxw' => 1, +'sya' => 1, +'syb' => 1, +'syc' => 1, +'syd' => 1, +'syi' => 1, +'syk' => 1, +'syl' => 1, +'sym' => 1, +'syn' => 1, +'syo' => 1, +'syr' => 1, +'sys' => 1, +'syw' => 1, +'syy' => 1, +'sza' => 1, +'szb' => 1, +'szc' => 1, +'szd' => 1, +'sze' => 1, +'szg' => 1, +'szl' => 1, +'szn' => 1, +'szp' => 1, +'szv' => 1, +'szw' => 1, +'taa' => 1, +'tab' => 1, +'tac' => 1, +'tad' => 1, +'tae' => 1, +'taf' => 1, +'tag' => 1, +'tai' => 1, +'taj' => 1, +'tak' => 1, +'tal' => 1, +'tan' => 1, +'tao' => 1, +'tap' => 1, +'tar' => 1, +'tas' => 1, +'tau' => 1, +'tav' => 1, +'taw' => 1, +'tax' => 1, +'tay' => 1, +'taz' => 1, +'tba' => 1, +'tbb' => 1, +'tbc' => 1, +'tbd' => 1, +'tbe' => 1, +'tbf' => 1, +'tbg' => 1, +'tbh' => 1, +'tbi' => 1, +'tbj' => 1, +'tbk' => 1, +'tbl' => 1, +'tbm' => 1, +'tbn' => 1, +'tbo' => 1, +'tbp' => 1, +'tbq' => 1, +'tbr' => 1, +'tbs' => 1, +'tbt' => 1, +'tbu' => 1, +'tbv' => 1, +'tbw' => 1, +'tbx' => 1, +'tby' => 1, +'tbz' => 1, +'tca' => 1, +'tcb' => 1, +'tcc' => 1, +'tcd' => 1, +'tce' => 1, +'tcf' => 1, +'tcg' => 1, +'tch' => 1, +'tci' => 1, +'tck' => 1, +'tcl' => 1, +'tcm' => 1, +'tcn' => 1, +'tco' => 1, +'tcp' => 1, +'tcq' => 1, +'tcs' => 1, +'tct' => 1, +'tcu' => 1, +'tcw' => 1, +'tcx' => 1, +'tcy' => 1, +'tcz' => 1, +'tda' => 1, +'tdb' => 1, +'tdc' => 1, +'tdd' => 1, +'tdf' => 1, +'tdg' => 1, +'tdh' => 1, +'tdi' => 1, +'tdj' => 1, +'tdk' => 1, +'tdl' => 1, +'tdn' => 1, +'tdo' => 1, +'tdq' => 1, +'tdr' => 1, +'tds' => 1, +'tdt' => 1, +'tdu' => 1, +'tdv' => 1, +'tdy' => 1, +'tea' => 1, +'teb' => 1, +'ted' => 1, +'tee' => 1, +'tef' => 1, +'teg' => 1, +'teh' => 1, +'tei' => 1, +'tek' => 1, +'tem' => 1, +'ten' => 1, +'teo' => 1, +'tep' => 1, +'teq' => 1, +'ter' => 1, +'tes' => 1, +'tet' => 1, +'teu' => 1, +'tev' => 1, +'tew' => 1, +'tex' => 1, +'tey' => 1, +'tfi' => 1, +'tfn' => 1, +'tfo' => 1, +'tfr' => 1, +'tft' => 1, +'tga' => 1, +'tgb' => 1, +'tgc' => 1, +'tgd' => 1, +'tge' => 1, +'tgf' => 1, +'tgg' => 1, +'tgh' => 1, +'tgi' => 1, +'tgo' => 1, +'tgp' => 1, +'tgq' => 1, +'tgr' => 1, +'tgs' => 1, +'tgt' => 1, +'tgu' => 1, +'tgv' => 1, +'tgw' => 1, +'tgx' => 1, +'tgy' => 1, +'thc' => 1, +'thd' => 1, +'the' => 1, +'thf' => 1, +'thh' => 1, +'thi' => 1, +'thk' => 1, +'thl' => 1, +'thm' => 1, +'thn' => 1, +'thp' => 1, +'thq' => 1, +'thr' => 1, +'ths' => 1, +'tht' => 1, +'thu' => 1, +'thw' => 1, +'thx' => 1, +'thy' => 1, +'tia' => 1, +'tic' => 1, +'tid' => 1, +'tie' => 1, +'tif' => 1, +'tig' => 1, +'tih' => 1, +'tii' => 1, +'tij' => 1, +'tik' => 1, +'til' => 1, +'tim' => 1, +'tin' => 1, +'tio' => 1, +'tip' => 1, +'tiq' => 1, +'tis' => 1, +'tit' => 1, +'tiu' => 1, +'tiv' => 1, +'tiw' => 1, +'tix' => 1, +'tiy' => 1, +'tiz' => 1, +'tja' => 1, +'tjg' => 1, +'tji' => 1, +'tjm' => 1, +'tjn' => 1, +'tjo' => 1, +'tjs' => 1, +'tju' => 1, +'tka' => 1, +'tkb' => 1, +'tkd' => 1, +'tke' => 1, +'tkf' => 1, +'tkk' => 1, +'tkl' => 1, +'tkm' => 1, +'tkn' => 1, +'tkp' => 1, +'tkq' => 1, +'tkr' => 1, +'tks' => 1, +'tkt' => 1, +'tku' => 1, +'tkw' => 1, +'tkx' => 1, +'tkz' => 1, +'tla' => 1, +'tlb' => 1, +'tlc' => 1, +'tld' => 1, +'tlf' => 1, +'tlg' => 1, +'tlh' => 1, +'tli' => 1, +'tlj' => 1, +'tlk' => 1, +'tll' => 1, +'tlm' => 1, +'tln' => 1, +'tlo' => 1, +'tlp' => 1, +'tlq' => 1, +'tlr' => 1, +'tls' => 1, +'tlt' => 1, +'tlu' => 1, +'tlv' => 1, +'tlw' => 1, +'tlx' => 1, +'tly' => 1, +'tma' => 1, +'tmb' => 1, +'tmc' => 1, +'tmd' => 1, +'tme' => 1, +'tmf' => 1, +'tmg' => 1, +'tmh' => 1, +'tmi' => 1, +'tmj' => 1, +'tmk' => 1, +'tml' => 1, +'tmm' => 1, +'tmn' => 1, +'tmo' => 1, +'tmp' => 1, +'tmq' => 1, +'tmr' => 1, +'tms' => 1, +'tmt' => 1, +'tmu' => 1, +'tmv' => 1, +'tmy' => 1, +'tmz' => 1, +'tna' => 1, +'tnb' => 1, +'tnc' => 1, +'tnd' => 1, +'tne' => 1, +'tnf' => 1, +'tng' => 1, +'tnh' => 1, +'tni' => 1, +'tnk' => 1, +'tnl' => 1, +'tnm' => 1, +'tnn' => 1, +'tno' => 1, +'tnp' => 1, +'tnq' => 1, +'tnr' => 1, +'tns' => 1, +'tnt' => 1, +'tnu' => 1, +'tnv' => 1, +'tnw' => 1, +'tnx' => 1, +'tny' => 1, +'tnz' => 1, +'tob' => 1, +'toc' => 1, +'tod' => 1, +'toe' => 1, +'tof' => 1, +'tog' => 1, +'toh' => 1, +'toi' => 1, +'toj' => 1, +'tol' => 1, +'tom' => 1, +'too' => 1, +'top' => 1, +'toq' => 1, +'tor' => 1, +'tos' => 1, +'tou' => 1, +'tov' => 1, +'tow' => 1, +'tox' => 1, +'toy' => 1, +'toz' => 1, +'tpa' => 1, +'tpc' => 1, +'tpe' => 1, +'tpf' => 1, +'tpg' => 1, +'tpi' => 1, +'tpj' => 1, +'tpk' => 1, +'tpl' => 1, +'tpm' => 1, +'tpn' => 1, +'tpo' => 1, +'tpp' => 1, +'tpq' => 1, +'tpr' => 1, +'tpt' => 1, +'tpu' => 1, +'tpv' => 1, +'tpw' => 1, +'tpx' => 1, +'tpy' => 1, +'tpz' => 1, +'tqb' => 1, +'tql' => 1, +'tqm' => 1, +'tqn' => 1, +'tqo' => 1, +'tqp' => 1, +'tqq' => 1, +'tqr' => 1, +'tqt' => 1, +'tqu' => 1, +'tqw' => 1, +'tra' => 1, +'trb' => 1, +'trc' => 1, +'trd' => 1, +'tre' => 1, +'trf' => 1, +'trg' => 1, +'trh' => 1, +'tri' => 1, +'trj' => 1, +'trk' => 1, +'trl' => 1, +'trm' => 1, +'trn' => 1, +'tro' => 1, +'trp' => 1, +'trq' => 1, +'trr' => 1, +'trs' => 1, +'trt' => 1, +'tru' => 1, +'trv' => 1, +'trw' => 1, +'trx' => 1, +'try' => 1, +'trz' => 1, +'tsa' => 1, +'tsb' => 1, +'tsc' => 1, +'tsd' => 1, +'tse' => 1, +'tsf' => 1, +'tsg' => 1, +'tsh' => 1, +'tsi' => 1, +'tsj' => 1, +'tsk' => 1, +'tsl' => 1, +'tsm' => 1, +'tsp' => 1, +'tsq' => 1, +'tsr' => 1, +'tss' => 1, +'tsu' => 1, +'tsv' => 1, +'tsw' => 1, +'tsx' => 1, +'tsy' => 1, +'tsz' => 1, +'tta' => 1, +'ttb' => 1, +'ttc' => 1, +'ttd' => 1, +'tte' => 1, +'ttf' => 1, +'ttg' => 1, +'tth' => 1, +'tti' => 1, +'ttj' => 1, +'ttk' => 1, +'ttl' => 1, +'ttm' => 1, +'ttn' => 1, +'tto' => 1, +'ttp' => 1, +'ttr' => 1, +'tts' => 1, +'ttt' => 1, +'ttu' => 1, +'ttv' => 1, +'ttw' => 1, +'tty' => 1, +'ttz' => 1, +'tua' => 1, +'tub' => 1, +'tuc' => 1, +'tud' => 1, +'tue' => 1, +'tuf' => 1, +'tug' => 1, +'tuh' => 1, +'tui' => 1, +'tuj' => 1, +'tul' => 1, +'tum' => 1, +'tun' => 1, +'tuo' => 1, +'tup' => 1, +'tuq' => 1, +'tus' => 1, +'tut' => 1, +'tuu' => 1, +'tuv' => 1, +'tuw' => 1, +'tux' => 1, +'tuz' => 1, +'tva' => 1, +'tvd' => 1, +'tve' => 1, +'tvk' => 1, +'tvl' => 1, +'tvm' => 1, +'tvn' => 1, +'tvo' => 1, +'tvs' => 1, +'tvt' => 1, +'tvw' => 1, +'tvy' => 1, +'twa' => 1, +'twb' => 1, +'twc' => 1, +'twd' => 1, +'twe' => 1, +'twf' => 1, +'twg' => 1, +'twh' => 1, +'twl' => 1, +'twm' => 1, +'twn' => 1, +'two' => 1, +'twp' => 1, +'twq' => 1, +'twr' => 1, +'twt' => 1, +'twu' => 1, +'tww' => 1, +'twx' => 1, +'twy' => 1, +'txa' => 1, +'txb' => 1, +'txc' => 1, +'txe' => 1, +'txg' => 1, +'txh' => 1, +'txi' => 1, +'txm' => 1, +'txn' => 1, +'txo' => 1, +'txq' => 1, +'txr' => 1, +'txs' => 1, +'txt' => 1, +'txu' => 1, +'txx' => 1, +'tya' => 1, +'tye' => 1, +'tyh' => 1, +'tyi' => 1, +'tyj' => 1, +'tyl' => 1, +'tyn' => 1, +'typ' => 1, +'tyr' => 1, +'tys' => 1, +'tyt' => 1, +'tyu' => 1, +'tyv' => 1, +'tyx' => 1, +'tyz' => 1, +'tza' => 1, +'tzh' => 1, +'tzj' => 1, +'tzm' => 1, +'tzn' => 1, +'tzo' => 1, +'tzx' => 1, +'uam' => 1, +'uan' => 1, +'uar' => 1, +'uba' => 1, +'ubi' => 1, +'ubr' => 1, +'ubu' => 1, +'uby' => 1, +'uda' => 1, +'ude' => 1, +'udg' => 1, +'udi' => 1, +'udj' => 1, +'udl' => 1, +'udm' => 1, +'udu' => 1, +'ues' => 1, +'ufi' => 1, +'uga' => 1, +'ugb' => 1, +'uge' => 1, +'ugn' => 1, +'ugo' => 1, +'ugy' => 1, +'uha' => 1, +'uhn' => 1, +'uis' => 1, +'uiv' => 1, +'uji' => 1, +'uka' => 1, +'ukg' => 1, +'ukh' => 1, +'ukl' => 1, +'ukp' => 1, +'ukq' => 1, +'uks' => 1, +'uku' => 1, +'ukw' => 1, +'ula' => 1, +'ulb' => 1, +'ulc' => 1, +'ulf' => 1, +'uli' => 1, +'ulk' => 1, +'ull' => 1, +'ulm' => 1, +'uln' => 1, +'ulu' => 1, +'uma' => 1, +'umb' => 1, +'umc' => 1, +'umd' => 1, +'umg' => 1, +'umi' => 1, +'umm' => 1, +'umn' => 1, +'umo' => 1, +'ump' => 1, +'umr' => 1, +'ums' => 1, +'una' => 1, +'une' => 1, +'ung' => 1, +'unk' => 1, +'unp' => 1, +'unr' => 1, +'unx' => 1, +'unz' => 1, +'uok' => 1, +'upi' => 1, +'upv' => 1, +'ura' => 1, +'urb' => 1, +'urc' => 1, +'ure' => 1, +'urf' => 1, +'urg' => 1, +'urh' => 1, +'uri' => 1, +'urj' => 1, +'url' => 1, +'urm' => 1, +'urn' => 1, +'uro' => 1, +'urp' => 1, +'urr' => 1, +'urt' => 1, +'uru' => 1, +'urv' => 1, +'urw' => 1, +'urx' => 1, +'ury' => 1, +'urz' => 1, +'usa' => 1, +'ush' => 1, +'usi' => 1, +'usk' => 1, +'usp' => 1, +'usu' => 1, +'uta' => 1, +'ute' => 1, +'utp' => 1, +'utr' => 1, +'utu' => 1, +'uum' => 1, +'uun' => 1, +'uur' => 1, +'uuu' => 1, +'uve' => 1, +'uvh' => 1, +'uvl' => 1, +'uwa' => 1, +'uya' => 1, +'vaa' => 1, +'vae' => 1, +'vaf' => 1, +'vag' => 1, +'vah' => 1, +'vai' => 1, +'vaj' => 1, +'val' => 1, +'vam' => 1, +'van' => 1, +'vao' => 1, +'vap' => 1, +'var' => 1, +'vas' => 1, +'vau' => 1, +'vav' => 1, +'vay' => 1, +'vbb' => 1, +'vec' => 1, +'ved' => 1, +'vel' => 1, +'vem' => 1, +'veo' => 1, +'vep' => 1, +'ver' => 1, +'vgr' => 1, +'vgt' => 1, +'vic' => 1, +'vid' => 1, +'vif' => 1, +'vig' => 1, +'vil' => 1, +'vin' => 1, +'vis' => 1, +'vit' => 1, +'viv' => 1, +'vka' => 1, +'vki' => 1, +'vkj' => 1, +'vkl' => 1, +'vkm' => 1, +'vko' => 1, +'vkp' => 1, +'vku' => 1, +'vlp' => 1, +'vls' => 1, +'vma' => 1, +'vmb' => 1, +'vmc' => 1, +'vmd' => 1, +'vme' => 1, +'vmf' => 1, +'vmg' => 1, +'vmh' => 1, +'vmi' => 1, +'vmj' => 1, +'vmk' => 1, +'vml' => 1, +'vmm' => 1, +'vmp' => 1, +'vmq' => 1, +'vmr' => 1, +'vms' => 1, +'vmu' => 1, +'vmv' => 1, +'vmw' => 1, +'vmx' => 1, +'vmy' => 1, +'vmz' => 1, +'vnk' => 1, +'vnm' => 1, +'vnp' => 1, +'vor' => 1, +'vot' => 1, +'vra' => 1, +'vrs' => 1, +'vrt' => 1, +'vsi' => 1, +'vsl' => 1, +'vsv' => 1, +'vto' => 1, +'vum' => 1, +'vun' => 1, +'vut' => 1, +'vwa' => 1, +'waa' => 1, +'wab' => 1, +'wac' => 1, +'wad' => 1, +'wae' => 1, +'waf' => 1, +'wag' => 1, +'wah' => 1, +'wai' => 1, +'waj' => 1, +'wak' => 1, +'wal' => 1, +'wam' => 1, +'wan' => 1, +'wao' => 1, +'wap' => 1, +'waq' => 1, +'war' => 1, +'was' => 1, +'wat' => 1, +'wau' => 1, +'wav' => 1, +'waw' => 1, +'wax' => 1, +'way' => 1, +'waz' => 1, +'wba' => 1, +'wbb' => 1, +'wbe' => 1, +'wbf' => 1, +'wbh' => 1, +'wbi' => 1, +'wbj' => 1, +'wbk' => 1, +'wbl' => 1, +'wbm' => 1, +'wbp' => 1, +'wbq' => 1, +'wbt' => 1, +'wbv' => 1, +'wbw' => 1, +'wca' => 1, +'wci' => 1, +'wdd' => 1, +'wdg' => 1, +'wdj' => 1, +'wdu' => 1, +'wea' => 1, +'wec' => 1, +'wed' => 1, +'weh' => 1, +'wei' => 1, +'wem' => 1, +'wen' => 1, +'weo' => 1, +'wep' => 1, +'wer' => 1, +'wes' => 1, +'wet' => 1, +'weu' => 1, +'wew' => 1, +'wfg' => 1, +'wga' => 1, +'wgg' => 1, +'wgi' => 1, +'wgo' => 1, +'wgw' => 1, +'wgy' => 1, +'wha' => 1, +'whg' => 1, +'whk' => 1, +'whu' => 1, +'wib' => 1, +'wic' => 1, +'wie' => 1, +'wif' => 1, +'wig' => 1, +'wih' => 1, +'wii' => 1, +'wij' => 1, +'wik' => 1, +'wil' => 1, +'wim' => 1, +'win' => 1, +'wir' => 1, +'wit' => 1, +'wiu' => 1, +'wiv' => 1, +'wiw' => 1, +'wiy' => 1, +'wja' => 1, +'wji' => 1, +'wka' => 1, +'wkb' => 1, +'wkd' => 1, +'wkl' => 1, +'wku' => 1, +'wkw' => 1, +'wla' => 1, +'wlc' => 1, +'wle' => 1, +'wlg' => 1, +'wli' => 1, +'wlk' => 1, +'wll' => 1, +'wlm' => 1, +'wlo' => 1, +'wlr' => 1, +'wls' => 1, +'wlu' => 1, +'wlv' => 1, +'wlw' => 1, +'wlx' => 1, +'wly' => 1, +'wma' => 1, +'wmb' => 1, +'wmc' => 1, +'wmd' => 1, +'wme' => 1, +'wmh' => 1, +'wmi' => 1, +'wmm' => 1, +'wmn' => 1, +'wmo' => 1, +'wms' => 1, +'wmt' => 1, +'wmw' => 1, +'wmx' => 1, +'wnb' => 1, +'wnc' => 1, +'wnd' => 1, +'wne' => 1, +'wng' => 1, +'wni' => 1, +'wnk' => 1, +'wnm' => 1, +'wno' => 1, +'wnp' => 1, +'wnu' => 1, +'woa' => 1, +'wob' => 1, +'woc' => 1, +'wod' => 1, +'woe' => 1, +'wof' => 1, +'wog' => 1, +'woi' => 1, +'wok' => 1, +'wom' => 1, +'won' => 1, +'woo' => 1, +'wor' => 1, +'wos' => 1, +'wow' => 1, +'woy' => 1, +'wpc' => 1, +'wra' => 1, +'wrb' => 1, +'wrd' => 1, +'wrg' => 1, +'wrh' => 1, +'wri' => 1, +'wrl' => 1, +'wrm' => 1, +'wrn' => 1, +'wrp' => 1, +'wrr' => 1, +'wrs' => 1, +'wru' => 1, +'wrv' => 1, +'wrw' => 1, +'wrx' => 1, +'wrz' => 1, +'wsa' => 1, +'wsi' => 1, +'wsk' => 1, +'wsr' => 1, +'wss' => 1, +'wsu' => 1, +'wsv' => 1, +'wtf' => 1, +'wti' => 1, +'wtk' => 1, +'wtm' => 1, +'wtw' => 1, +'wua' => 1, +'wub' => 1, +'wud' => 1, +'wuh' => 1, +'wul' => 1, +'wum' => 1, +'wun' => 1, +'wur' => 1, +'wut' => 1, +'wuv' => 1, +'wux' => 1, +'wuy' => 1, +'wwa' => 1, +'wwo' => 1, +'wwr' => 1, +'www' => 1, +'wxa' => 1, +'wya' => 1, +'wyb' => 1, +'wym' => 1, +'wyr' => 1, +'wyy' => 1, +'xaa' => 1, +'xab' => 1, +'xac' => 1, +'xad' => 1, +'xae' => 1, +'xag' => 1, +'xai' => 1, +'xal' => 1, +'xam' => 1, +'xan' => 1, +'xao' => 1, +'xap' => 1, +'xaq' => 1, +'xar' => 1, +'xas' => 1, +'xat' => 1, +'xau' => 1, +'xav' => 1, +'xaw' => 1, +'xay' => 1, +'xba' => 1, +'xbc' => 1, +'xbi' => 1, +'xbm' => 1, +'xbo' => 1, +'xbr' => 1, +'xbw' => 1, +'xbx' => 1, +'xcb' => 1, +'xcc' => 1, +'xce' => 1, +'xcg' => 1, +'xch' => 1, +'xcl' => 1, +'xcm' => 1, +'xcn' => 1, +'xco' => 1, +'xcr' => 1, +'xct' => 1, +'xcu' => 1, +'xcv' => 1, +'xcw' => 1, +'xcy' => 1, +'xdc' => 1, +'xdm' => 1, +'xdy' => 1, +'xeb' => 1, +'xed' => 1, +'xeg' => 1, +'xel' => 1, +'xem' => 1, +'xep' => 1, +'xer' => 1, +'xes' => 1, +'xet' => 1, +'xeu' => 1, +'xfa' => 1, +'xga' => 1, +'xgf' => 1, +'xgl' => 1, +'xgn' => 1, +'xgr' => 1, +'xha' => 1, +'xhc' => 1, +'xhd' => 1, +'xhr' => 1, +'xht' => 1, +'xhu' => 1, +'xhv' => 1, +'xia' => 1, +'xib' => 1, +'xii' => 1, +'xil' => 1, +'xin' => 1, +'xip' => 1, +'xir' => 1, +'xiv' => 1, +'xiy' => 1, +'xka' => 1, +'xkb' => 1, +'xkc' => 1, +'xkd' => 1, +'xke' => 1, +'xkf' => 1, +'xkg' => 1, +'xkh' => 1, +'xki' => 1, +'xkj' => 1, +'xkk' => 1, +'xkl' => 1, +'xkn' => 1, +'xko' => 1, +'xkp' => 1, +'xkq' => 1, +'xkr' => 1, +'xks' => 1, +'xkt' => 1, +'xku' => 1, +'xkv' => 1, +'xkw' => 1, +'xkx' => 1, +'xky' => 1, +'xkz' => 1, +'xla' => 1, +'xlb' => 1, +'xlc' => 1, +'xld' => 1, +'xle' => 1, +'xlg' => 1, +'xli' => 1, +'xln' => 1, +'xlo' => 1, +'xlp' => 1, +'xls' => 1, +'xlu' => 1, +'xly' => 1, +'xma' => 1, +'xmb' => 1, +'xmc' => 1, +'xmd' => 1, +'xme' => 1, +'xmf' => 1, +'xmg' => 1, +'xmh' => 1, +'xmj' => 1, +'xmk' => 1, +'xml' => 1, +'xmn' => 1, +'xmo' => 1, +'xmp' => 1, +'xmq' => 1, +'xmr' => 1, +'xms' => 1, +'xmt' => 1, +'xmu' => 1, +'xmx' => 1, +'xmy' => 1, +'xmz' => 1, +'xna' => 1, +'xnb' => 1, +'xnd' => 1, +'xng' => 1, +'xnh' => 1, +'xnn' => 1, +'xno' => 1, +'xns' => 1, +'xoc' => 1, +'xod' => 1, +'xog' => 1, +'xoi' => 1, +'xok' => 1, +'xom' => 1, +'xon' => 1, +'xoo' => 1, +'xop' => 1, +'xor' => 1, +'xow' => 1, +'xpc' => 1, +'xpg' => 1, +'xpi' => 1, +'xpk' => 1, +'xpm' => 1, +'xpn' => 1, +'xpo' => 1, +'xpp' => 1, +'xpr' => 1, +'xps' => 1, +'xpu' => 1, +'xpy' => 1, +'xqa' => 1, +'xqt' => 1, +'xra' => 1, +'xrb' => 1, +'xre' => 1, +'xri' => 1, +'xrm' => 1, +'xrn' => 1, +'xrr' => 1, +'xrt' => 1, +'xru' => 1, +'xrw' => 1, +'xsa' => 1, +'xsb' => 1, +'xsc' => 1, +'xsd' => 1, +'xse' => 1, +'xsh' => 1, +'xsi' => 1, +'xsj' => 1, +'xsm' => 1, +'xsn' => 1, +'xso' => 1, +'xsp' => 1, +'xsq' => 1, +'xsr' => 1, +'xss' => 1, +'xsu' => 1, +'xsv' => 1, +'xsy' => 1, +'xta' => 1, +'xtb' => 1, +'xtc' => 1, +'xtd' => 1, +'xte' => 1, +'xtg' => 1, +'xti' => 1, +'xtj' => 1, +'xtl' => 1, +'xtm' => 1, +'xtn' => 1, +'xto' => 1, +'xtp' => 1, +'xtq' => 1, +'xtr' => 1, +'xts' => 1, +'xtt' => 1, +'xtu' => 1, +'xtw' => 1, +'xty' => 1, +'xtz' => 1, +'xua' => 1, +'xub' => 1, +'xug' => 1, +'xuj' => 1, +'xum' => 1, +'xuo' => 1, +'xup' => 1, +'xur' => 1, +'xut' => 1, +'xuu' => 1, +'xve' => 1, +'xvi' => 1, +'xvn' => 1, +'xvo' => 1, +'xvs' => 1, +'xwa' => 1, +'xwc' => 1, +'xwe' => 1, +'xwg' => 1, +'xwl' => 1, +'xwo' => 1, +'xwr' => 1, +'xxb' => 1, +'xxk' => 1, +'xxr' => 1, +'xxt' => 1, +'xyl' => 1, +'xzh' => 1, +'xzm' => 1, +'xzp' => 1, +'yaa' => 1, +'yab' => 1, +'yac' => 1, +'yad' => 1, +'yae' => 1, +'yaf' => 1, +'yag' => 1, +'yah' => 1, +'yai' => 1, +'yaj' => 1, +'yak' => 1, +'yal' => 1, +'yam' => 1, +'yao' => 1, +'yap' => 1, +'yaq' => 1, +'yar' => 1, +'yas' => 1, +'yat' => 1, +'yau' => 1, +'yav' => 1, +'yaw' => 1, +'yax' => 1, +'yay' => 1, +'yaz' => 1, +'yba' => 1, +'ybb' => 1, +'ybd' => 1, +'ybe' => 1, +'ybh' => 1, +'ybi' => 1, +'ybj' => 1, +'ybk' => 1, +'ybl' => 1, +'ybm' => 1, +'ybn' => 1, +'ybo' => 1, +'ybx' => 1, +'yby' => 1, +'ych' => 1, +'ycl' => 1, +'ycn' => 1, +'ycp' => 1, +'yde' => 1, +'ydg' => 1, +'ydk' => 1, +'yds' => 1, +'yea' => 1, +'yec' => 1, +'yee' => 1, +'yei' => 1, +'yej' => 1, +'yel' => 1, +'yen' => 1, +'yer' => 1, +'yes' => 1, +'yet' => 1, +'yeu' => 1, +'yev' => 1, +'yey' => 1, +'ygl' => 1, +'ygm' => 1, +'ygp' => 1, +'ygr' => 1, +'ygw' => 1, +'yha' => 1, +'yhl' => 1, +'yia' => 1, +'yif' => 1, +'yig' => 1, +'yii' => 1, +'yij' => 1, +'yik' => 1, +'yil' => 1, +'yim' => 1, +'yin' => 1, +'yip' => 1, +'yiq' => 1, +'yir' => 1, +'yis' => 1, +'yit' => 1, +'yiu' => 1, +'yiv' => 1, +'yix' => 1, +'yiy' => 1, +'yiz' => 1, +'yka' => 1, +'ykg' => 1, +'yki' => 1, +'ykk' => 1, +'ykl' => 1, +'ykm' => 1, +'yko' => 1, +'ykr' => 1, +'ykt' => 1, +'yky' => 1, +'yla' => 1, +'yle' => 1, +'ylg' => 1, +'yli' => 1, +'yll' => 1, +'ylm' => 1, +'yln' => 1, +'ylo' => 1, +'ylr' => 1, +'ylu' => 1, +'yly' => 1, +'yma' => 1, +'ymb' => 1, +'ymc' => 1, +'ymd' => 1, +'yme' => 1, +'ymg' => 1, +'ymh' => 1, +'ymi' => 1, +'ymk' => 1, +'yml' => 1, +'ymm' => 1, +'ymn' => 1, +'ymo' => 1, +'ymp' => 1, +'ymq' => 1, +'ymr' => 1, +'yms' => 1, +'ymt' => 1, +'ymx' => 1, +'ymz' => 1, +'yna' => 1, +'ynd' => 1, +'yne' => 1, +'yng' => 1, +'ynh' => 1, +'ynk' => 1, +'ynl' => 1, +'ynn' => 1, +'yno' => 1, +'yns' => 1, +'ynu' => 1, +'yob' => 1, +'yog' => 1, +'yoi' => 1, +'yok' => 1, +'yol' => 1, +'yom' => 1, +'yon' => 1, +'yos' => 1, +'yox' => 1, +'yoy' => 1, +'ypa' => 1, +'ypb' => 1, +'ypg' => 1, +'yph' => 1, +'ypk' => 1, +'ypm' => 1, +'ypn' => 1, +'ypo' => 1, +'ypp' => 1, +'ypz' => 1, +'yra' => 1, +'yrb' => 1, +'yre' => 1, +'yri' => 1, +'yrk' => 1, +'yrl' => 1, +'yrn' => 1, +'yrs' => 1, +'yrw' => 1, +'ysc' => 1, +'ysd' => 1, +'ysl' => 1, +'ysn' => 1, +'yso' => 1, +'ysp' => 1, +'ysr' => 1, +'yss' => 1, +'ysy' => 1, +'yta' => 1, +'ytl' => 1, +'ytp' => 1, +'yua' => 1, +'yub' => 1, +'yuc' => 1, +'yuf' => 1, +'yug' => 1, +'yui' => 1, +'yuj' => 1, +'yuk' => 1, +'yul' => 1, +'yum' => 1, +'yun' => 1, +'yup' => 1, +'yuq' => 1, +'yur' => 1, +'yut' => 1, +'yuu' => 1, +'yuw' => 1, +'yux' => 1, +'yuy' => 1, +'yuz' => 1, +'yva' => 1, +'yvt' => 1, +'ywa' => 1, +'ywl' => 1, +'ywn' => 1, +'ywq' => 1, +'ywr' => 1, +'ywt' => 1, +'ywu' => 1, +'yww' => 1, +'yyu' => 1, +'yyz' => 1, +'yzg' => 1, +'yzk' => 1, +'zag' => 1, +'zah' => 1, +'zaj' => 1, +'zak' => 1, +'zal' => 1, +'zap' => 1, +'zau' => 1, +'zay' => 1, +'zaz' => 1, +'zbc' => 1, +'zbe' => 1, +'zbl' => 1, +'zbt' => 1, +'zbw' => 1, +'zdj' => 1, +'zea' => 1, +'zeg' => 1, +'zen' => 1, +'zga' => 1, +'zgr' => 1, +'zhb' => 1, +'zhi' => 1, +'zhw' => 1, +'zhx' => 1, +'zia' => 1, +'zib' => 1, +'zik' => 1, +'zim' => 1, +'zin' => 1, +'zir' => 1, +'ziw' => 1, +'ziz' => 1, +'zka' => 1, +'zkb' => 1, +'zkg' => 1, +'zkh' => 1, +'zkk' => 1, +'zko' => 1, +'zkp' => 1, +'zkr' => 1, +'zkt' => 1, +'zku' => 1, +'zkv' => 1, +'zkz' => 1, +'zle' => 1, +'zls' => 1, +'zlw' => 1, +'zma' => 1, +'zmb' => 1, +'zmc' => 1, +'zmd' => 1, +'zme' => 1, +'zmf' => 1, +'zmg' => 1, +'zmh' => 1, +'zmj' => 1, +'zmk' => 1, +'zml' => 1, +'zmm' => 1, +'zmn' => 1, +'zmo' => 1, +'zmp' => 1, +'zmq' => 1, +'zmr' => 1, +'zms' => 1, +'zmt' => 1, +'zmu' => 1, +'zmv' => 1, +'zmw' => 1, +'zmx' => 1, +'zmy' => 1, +'zmz' => 1, +'zna' => 1, +'znd' => 1, +'zne' => 1, +'zng' => 1, +'znk' => 1, +'zns' => 1, +'zoc' => 1, +'zoh' => 1, +'zom' => 1, +'zoq' => 1, +'zor' => 1, +'zos' => 1, +'zra' => 1, +'zrg' => 1, +'zrn' => 1, +'zro' => 1, +'zrp' => 1, +'zrs' => 1, +'zsa' => 1, +'zsk' => 1, +'zsl' => 1, +'zsu' => 1, +'zua' => 1, +'zuh' => 1, +'zum' => 1, +'zun' => 1, +'zuy' => 1, +'zwa' => 1, +'zyp' => 1, +'zza' => 1, +); + +%region_codes = ( +'AC' => 1, +'AD' => 1, +'AE' => 1, +'AF' => 1, +'AG' => 1, +'AI' => 1, +'AL' => 1, +'AM' => 1, +'AN' => 1, +'AO' => 1, +'AQ' => 1, +'AR' => 1, +'AS' => 1, +'AT' => 1, +'AU' => 1, +'AW' => 1, +'AX' => 1, +'AZ' => 1, +'BA' => 1, +'BB' => 1, +'BD' => 1, +'BE' => 1, +'BF' => 1, +'BG' => 1, +'BH' => 1, +'BI' => 1, +'BJ' => 1, +'BL' => 1, +'BM' => 1, +'BN' => 1, +'BO' => 1, +'BR' => 1, +'BS' => 1, +'BT' => 1, +'BU' => 1, +'BV' => 1, +'BW' => 1, +'BY' => 1, +'BZ' => 1, +'CA' => 1, +'CC' => 1, +'CD' => 1, +'CF' => 1, +'CG' => 1, +'CH' => 1, +'CI' => 1, +'CK' => 1, +'CL' => 1, +'CM' => 1, +'CN' => 1, +'CO' => 1, +'CP' => 1, +'CR' => 1, +'CS' => 1, +'CU' => 1, +'CV' => 1, +'CX' => 1, +'CY' => 1, +'CZ' => 1, +'DD' => 1, +'DE' => 1, +'DG' => 1, +'DJ' => 1, +'DK' => 1, +'DM' => 1, +'DO' => 1, +'DZ' => 1, +'EA' => 1, +'EC' => 1, +'EE' => 1, +'EG' => 1, +'EH' => 1, +'ER' => 1, +'ES' => 1, +'ET' => 1, +'EU' => 1, +'FI' => 1, +'FJ' => 1, +'FK' => 1, +'FM' => 1, +'FO' => 1, +'FR' => 1, +'FX' => 1, +'GA' => 1, +'GB' => 1, +'GD' => 1, +'GE' => 1, +'GF' => 1, +'GG' => 1, +'GH' => 1, +'GI' => 1, +'GL' => 1, +'GM' => 1, +'GN' => 1, +'GP' => 1, +'GQ' => 1, +'GR' => 1, +'GS' => 1, +'GT' => 1, +'GU' => 1, +'GW' => 1, +'GY' => 1, +'HK' => 1, +'HM' => 1, +'HN' => 1, +'HR' => 1, +'HT' => 1, +'HU' => 1, +'IC' => 1, +'ID' => 1, +'IE' => 1, +'IL' => 1, +'IM' => 1, +'IN' => 1, +'IO' => 1, +'IQ' => 1, +'IR' => 1, +'IS' => 1, +'IT' => 1, +'JE' => 1, +'JM' => 1, +'JO' => 1, +'JP' => 1, +'KE' => 1, +'KG' => 1, +'KH' => 1, +'KI' => 1, +'KM' => 1, +'KN' => 1, +'KP' => 1, +'KR' => 1, +'KW' => 1, +'KY' => 1, +'KZ' => 1, +'LA' => 1, +'LB' => 1, +'LC' => 1, +'LI' => 1, +'LK' => 1, +'LR' => 1, +'LS' => 1, +'LT' => 1, +'LU' => 1, +'LV' => 1, +'LY' => 1, +'MA' => 1, +'MC' => 1, +'MD' => 1, +'ME' => 1, +'MF' => 1, +'MG' => 1, +'MH' => 1, +'MK' => 1, +'ML' => 1, +'MM' => 1, +'MN' => 1, +'MO' => 1, +'MP' => 1, +'MQ' => 1, +'MR' => 1, +'MS' => 1, +'MT' => 1, +'MU' => 1, +'MV' => 1, +'MW' => 1, +'MX' => 1, +'MY' => 1, +'MZ' => 1, +'NA' => 1, +'NC' => 1, +'NE' => 1, +'NF' => 1, +'NG' => 1, +'NI' => 1, +'NL' => 1, +'NO' => 1, +'NP' => 1, +'NR' => 1, +'NT' => 1, +'NU' => 1, +'NZ' => 1, +'OM' => 1, +'PA' => 1, +'PE' => 1, +'PF' => 1, +'PG' => 1, +'PH' => 1, +'PK' => 1, +'PL' => 1, +'PM' => 1, +'PN' => 1, +'PR' => 1, +'PS' => 1, +'PT' => 1, +'PW' => 1, +'PY' => 1, +'QA' => 1, +'RE' => 1, +'RO' => 1, +'RS' => 1, +'RU' => 1, +'RW' => 1, +'SA' => 1, +'SB' => 1, +'SC' => 1, +'SD' => 1, +'SE' => 1, +'SG' => 1, +'SH' => 1, +'SI' => 1, +'SJ' => 1, +'SK' => 1, +'SL' => 1, +'SM' => 1, +'SN' => 1, +'SO' => 1, +'SR' => 1, +'ST' => 1, +'SU' => 1, +'SV' => 1, +'SY' => 1, +'SZ' => 1, +'TA' => 1, +'TC' => 1, +'TD' => 1, +'TF' => 1, +'TG' => 1, +'TH' => 1, +'TJ' => 1, +'TK' => 1, +'TL' => 1, +'TM' => 1, +'TN' => 1, +'TO' => 1, +'TP' => 1, +'TR' => 1, +'TT' => 1, +'TV' => 1, +'TW' => 1, +'TZ' => 1, +'UA' => 1, +'UG' => 1, +'UM' => 1, +'US' => 1, +'UY' => 1, +'UZ' => 1, +'VA' => 1, +'VC' => 1, +'VE' => 1, +'VG' => 1, +'VI' => 1, +'VN' => 1, +'VU' => 1, +'WF' => 1, +'WS' => 1, +'YD' => 1, +'YE' => 1, +'YT' => 1, +'YU' => 1, +'ZA' => 1, +'ZM' => 1, +'ZR' => 1, +'ZW' => 1, +); + + +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.init exists. + +# @INIT@ +# -*-perl-*- +# vim: set filetype=perl: +###################################################################### +# File: texi2html.init # -%sec2level = ( - 'top', 0, - 'chapter', 1, - 'unnumbered', 1, - 'majorheading', 1, - 'chapheading', 1, - 'appendix', 1, - 'section', 2, - 'unnumberedsec', 2, - 'heading', 2, - 'appendixsec', 2, - 'appendixsection', 2, - 'subsection', 3, - 'unnumberedsubsec', 3, - 'subheading', 3, - 'appendixsubsec', 3, - 'subsubsection', 4, - 'unnumberedsubsubsec', 4, - 'subsubheading', 4, - 'appendixsubsubsec', 4, - ); +# Default values for command-line arguments and for various customizable +# procedures are set in this file. +# +# A copy of this file is pasted into the beginning of texi2html by +# running './configure'. +# +# Copy this file, rename it and make changes to it, if you like. +# Afterwards, load the file with command-line +# option --init-file +# +# $Id: texi2html,v 1.3 2017/03/28 23:22:20 takayama Exp $ +###################################################################### +# The following variables can also be set by command-line options # -# accent map, TeX command to ISO name # -%accent_map = ( - '"', 'uml', - '~', 'tilde', - '^', 'circ', - '`', 'grave', - '\'', 'acute', - ); +# The default values are set in this file, texi2html.init and the content +# of this file is included at the beginning of the texi2html script file. +# Those values may be overrided by values set in $sysconfdir/texi2html/Config +# and then by values set in $HOME/texi2html/Config. +# +# command line switches may override these values, and values set in files +# specified by --init-file are also taken into account. +# values set in these files overwrite values set by the command-line +# options appearing before --init-file and might still be overwritten by +# command-line arguments following the --init-file option. +################################################################## +# options common with makeinfo +# -I +# add a directory to the list of directories where @include files are +# searched for (besides the directory of the file). additional '-I' +# args are appended to this list. +# (APA: Don't implicitely search ., to conform with the docs!) +# my @INCLUDE_DIRS = ("."); + +#use strict; + +@INCLUDE_DIRS = (); + +# -P +# prepend a directory to the list of directories where @include files are +# searched for before the directory of the file. additional '-P' +# args are prepended to this list. +@PREPEND_DIRS = (); + +# --split section|chapter|node|none +# if $SPLIT is set to 'section' (resp. 'chapter') one html file per section +# (resp. chapter) is generated. If $SPLIT is set to 'node' one html file per +# node or sectioning element is generated. In all these cases separate pages +# for Top, Table of content (Toc), Overview and About are generated. +# Otherwise a monolithic html file that contains the whole document is +# created. +#$SPLIT = 'section'; +$SPLIT = ''; + +# --separated-footnotes +# if this is set footnotes are on a separated page. Otherwise they are at +# the end of each file (if the document is split). +$FOOTNOTESTYLE = 'end'; + +# --fill-column +$FILLCOLUMN = 72; + +# --number | --no-number +# if this is set the sections are numbered, and section names and numbers +# are used in references and menus (instead of node names). +$NUMBER_SECTIONS = 1; + +# --headers +# if this is set then navigation panels are printed at the beginning of each +# section. +# If the document is split at nodes then navigation panels are +# printed at the end if there were more than $WORDS_IN_PAGE words on page. # -# texinfo "simple things" (@foo) to HTML ones +# Navigation panels are always printed at the beginning of output files. # -%simple_map = ( - # cf. makeinfo.c - "*", "
    ", # HTML+ - " ", " ", - "\t", " ", - "-", "­", # soft hyphen - "\n", "\n", - "|", "", - 'tab', '<\/TD>', - # spacing commands - ":", "", - "!", "!", - "?", "?", - ".", ".", - "-", "", - ); +# This is most useful if you do not want to have section navigation +# with --split chapter. There will be chapter navigation panel at the +# beginning and at the end of chapters anyway. +# this is mostly not used in the default case, important for html. +$HEADERS = 0; +# -o filename +# If this is set a monolithic document is outputted into $filename. +$OUT = undef; + +# --split-size +# if undef, the info output is not split +$SPLIT_SIZE = 300000; + +# --internal-links +$INTERNAL_LINKS = undef; + +# --no-validate +# suppress node cross-reference validation +$NOVALIDATE = 0; + +# --documentlanguage +# use gdt('my string') if you want to have translations of 'my string' +# and provide the translations in $LANGUAGES->{$DOCUMENTLANGUAGE} with +# 'my string' as key. +# To add a new language use ISO 639 language codes (see e.g. perl module +# Locale-Codes-1.02 for definitions). Supply translations in the +# $LANGUAGES hash and put it in a file with $LANG as name in an i18n +# directory. +# This is used for the initial language, it is overriden during +# document processing if there is a @documentlanguage. +# It is ignored if the language is passed on the command line. +$DOCUMENTLANGUAGE = 'en'; + +# --transliterate-file-names +# transliterate node names for external refs (and internal if NODE_FILES) +$TRANSLITERATE_FILE_NAMES = 1; + +# --error-limit +# quit after NUM errors (default 1000). +$ERROR_LIMIT = 1000; + +# --css-include +# All the specified css files are used. More precisely the @import sections +# are added to the beginning of the CSS_LINES the remaining is added at +# the end of the CSS_LINES (after the css rules generated by the program). +# cf texinfo manual for more info. +# - means STDIN +@CSS_FILES = (); + +# --css-ref +# the specified url are used as stylesheet links +@CSS_REFS = (); + +# --paragraph-indent +$PARAGRAPHINDENT = 3; + +# --enable-encoding +$ENABLE_ENCODING = 0; + +# --force +$FORCE = 0; + +# --no-warn +$NO_WARN = 0; + +# --number-footnotes +$NUMBER_FOOTNOTES = 1; + +# not in makeinfo but in texi2dvi +# --command +@COMMANDS = (); + +################################################################## +# option specific of texi2html +# --debug +# The integer value specifies what kind of debugging output is generated. +$DEBUG = 0; + +# --doctype +# The value is the 'SystemLiteral' which identifies the canonical DTD +# for the document. +# Definition: The SystemLiteral is called the entity's system +# identifier. It is a URI, which may be used to retrieve the entity. +# See http://www.xml.com/axml/target.html#NT-ExternalID +$DOCTYPE = ''; + +# --frameset-doctype +# When frames are used, this SystemLiteral identifies the DTD used for +# the file containing the frame description. +$FRAMESET_DOCTYPE = ''; + +# --test +# If this value is true, some variables which should be dynamically generated +# (the date, the user running texi2html, the version of texi2html) are set to +# fix and given values. This is usefull in case the resulting manual is +# compared with a reference. For example this is used in the tests. +$TEST = 0; + +# --dump-texi +# This value is usefull for debugging purposes. The result of the first pass is +# put in .passtexi, the result of the second pass is put in +# .passfirst. +$DUMP_TEXI = 0; + +# --expand +# the @EXPAND array contains the expanded section names. +@EXPAND = (); + +# --invisible +# This seems obsolete and is not used anywhere. +# This was a workaround for a known bug of many WWW browsers, including +# netscape. This was used to create invisible destination in anchors. +$INVISIBLE_MARK = ''; +# $INVISIBLE_MARK = ' '; + +# --iso +# if this value is true, ISO8859 characters are used for quotes. +# --iso does more than what USE_ISO does. +$USE_ISO = 0; + +# --conf-dir +# append to the files searched for init files. +@CONF_DIRS = (); + +# --top-file +# This file name is used for the top-level file. +# The extension is set appropriately, if necessary. +# If empty, .html is used. +# Typically, you would set this to "index.html". +$TOP_FILE = ''; + +# --toc-file +# This file name is used for the table of contents. The +# extension is set appropriately, if necessary. +# If empty, _toc.html is used. +$TOC_FILE = ''; + +# --frames +# if the value is true, HTML 4.0 "frames" are used. +# A file describing the frame layout is generated, together with a file +# with the short table of contents. +$FRAMES = 0; + +# --menu | --no-menu +# if the value is true the Texinfo menus are shown. +# this is defined in all the formats +$SHOW_MENU = 1; + +# --use-nodes +# if this is set the nodes are used as sectioning elements. +# Otherwise the nodes are incorporated in sections. +$USE_NODES = 1; + +# --node-files +# if this is set one file per node is generated, which can be a target for +# cross manual references. +$NODE_FILES = 0; + +# --toc-links +# if this is set, links from headings to toc entries are created. +$TOC_LINKS = 0; + +# --subdir +# If this is set, then put result files into the specified directory. +# If not set, then result files are put into the current directory. +#$SUBDIR = 'html'; +$SUBDIR = ''; + +# --short-extn +# If this is set, then all HTML files will have extension ".htm" instead of +# ".html". This is helpful when shipping the document to DOS-based systems. +$SHORTEXTN = 0; + +# --prefix +# This set the output file prefix, prepended to all .html, .gif and .pl files. +# By default, this is the basename of the document. +$PREFIX = ''; + +# --short-ref +# if this is set cross-references are given without section. +$SHORT_REF = 1; + +# --idx-sum +# if value is set, then for each @printindex +# _.idx is created which contains lines of the form +# key ref sorted alphabetically (case matters). +$IDX_SUMMARY = 0; + +# --def-table +# If this is set a table construction for @def.... instead of definition +# lists. +# (New Option: 27.07.2000 Karl Heinz Marbaise) +$DEF_TABLE = 0; + +# --verbose +# if this is set chatter about what we are doing. +$VERBOSE = ''; + +# --ignore-preamble-text +# If this is set the text before @node and sectioning commands is ignored. +$IGNORE_PREAMBLE_TEXT = 0; + +# --html-xref-prefix +# base directory for external manuals. +#$EXTERNAL_DIR = '../'; +$EXTERNAL_DIR = undef; + +# --l2h +# if this is set, latex2html is used for generation of math content. +$L2H = ''; + +# --monolithic +# output only one file including ToC. It only makes sense when not split +$MONOLITHIC = 1; + +###################### +# The following options are only relevant if $L2H is set # -# texinfo "things" (@foo{}) to HTML ones +# --l2h-l2h +# name/location of latex2html program +$L2H_L2H = "latex2html"; + +# --l2h-skip +# If this is set the actual call to latex2html is skipped. The previously +# generated content is reused, instead. +# If set to 0, the cache is not used. +# If undef the cache is used for as many tex fragments as possible +# and for the remaining the command is run. +$L2H_SKIP = undef; + +# --l2h-tmp +# If this is set l2h uses the specified directory for temporary files. The path +# leading to this directory may not contain a dot (i.e., a "."); +# otherwise, l2h will fail. +$L2H_TMP = ''; + +# --l2h-file +# If set, l2h uses the file as latex2html init file +$L2H_FILE = 'l2h.init'; + +# --l2h-clean +# if this is set the intermediate files generated by texi2html in relation with +# latex2html are cleaned (they all have the prefix _l2h_). +$L2H_CLEAN = 1; + +############################################################################## # -%things_map = ( - 'TeX', 'TeX', - 'br', '

    ', # paragraph break - 'bullet', '*', - 'copyright', '(C)', - 'dots', '...', - 'equiv', '==', - 'error', 'error-->', - 'expansion', '==>', - 'minus', '-', - 'point', '-!-', - 'print', '-|', - 'result', '=>', - 'today', $TODAY, - ); +# The following can only be set in the init file +# +############################################################################## +@INPUT_FILE_SUFFIXES = ('.txi','.texinfo','.texi','.txinfo',''); + +$FIRSTPARAGRAPHINDENT = 'none'; + +@T2H_FORMAT_EXPAND = ('plaintext'); + +# simple headers formatting, not in a table and using node names. +$HEADER_IN_TABLE = 0; + +# output the generation date in the header. +$DATE_IN_HEADER = 0; + +# use table for indentation of complex formats +$COMPLEX_FORMAT_IN_TABLE = 0; + +# if set, node names are used to construct file names +# if undef, it is set if split at node, or $NODE_FILES is set. +$NODE_FILENAMES = undef; + +# If true do table of contents even if there is no @content +$CONTENTS = undef; + +# If true do short table of contents even if there is no @shortcontent +$SHORTCONTENTS = undef; + +# set by @setcontentsaftertitlepage/@setshortcontentsaftertitlepage +$SETCONTENTSAFTERTITLEPAGE = undef; +$SETSHORTCONTENTSAFTERTITLEPAGE = undef; + +# corresponds with @kbdinputstyle +$KBDINPUTSTYLE = 'distinct'; + +# corresponds with @frenchspacing +$FRENCHSPACING = 'off'; + +# correspond with @allowcodebreaks +$ALLOWCODEBREAKS = 'true'; + +# corresponds with @setfilename. Set with caution. +$SETFILENAME = undef; + +# if unset, don't show a title +$SHOW_TITLE = 1; + +# if set style is added in attribute. +$INLINE_CSS_STYLE = 0; + +# if set, no css is used. +$NO_CSS = 0; + +# if set, the image files are completed to be relative from the +# document directory, to the source manual directory and then to +# the image +$COMPLETE_IMAGE_PATHS = 0; + +# if true, begin outputting at @setfilename, if this command is present. +$IGNORE_BEFORE_SETFILENAME = 1; + +# if true the link in Overview link to the corresponding Toc entry. +$OVERVIEW_LINK_TO_TOC = 1; + +# if set, use node anchors for sections targets +$USE_NODE_TARGET = 1; + +# new style for crossrefs +$NEW_CROSSREF_STYLE = 1; + +# top heading is always at the beginning of the element. +$TOP_HEADING_AT_BEGINNING = 0; + +# use titlepage for the title instead of a simplest title +$USE_TITLEPAGE_FOR_TITLE = 0; + +# if set, center @image by default +# otherwise, do not center by default +# Deprecated and not used anymore +$CENTER_IMAGE = 1; + +# used as identation for block enclosing command @example, etc +# If not empty, must be enclosed in +$EXAMPLE_INDENT_CELL = ''; + +# same as above, only for @small +$SMALL_EXAMPLE_INDENT_CELL = ''; + +# unused +$SMALL_FONT_SIZE = '-1'; + +# horizontal rules +# not used +$SMALL_RULE = ''; +$MIDDLE_RULE = ''; +# used in html +$DEFAULT_RULE = ''; +$BIG_RULE = ''; + +# output the program name in the footer +$PROGRAM_NAME_IN_FOOTER = 0; + +# if non-empty, and no @..heading appeared in Top node, then +# use this as header for top node/section, otherwise use value of +# @settitle or @shorttitle (in that order) +$TOP_HEADING = ''; + +# if set, use this chapter for 'Index' button, else +# use first chapter with @printindex +$INDEX_CHAPTER = ''; + +$SIMPLE_MENU = 1; + +$OPEN_QUOTE_SYMBOL = "\`"; +$CLOSE_QUOTE_SYMBOL = "'"; + +$NO_NUMBER_FOOTNOTE_SYMBOL = '*'; + +# if true put a $MENU_SYMBOL before unnumbered in menus +$UNNUMBERED_SYMBOL_IN_MENU = 0; + +# extension for nodes files when NODE_FILES is true +$NODE_FILE_EXTENSION = 'txt'; + +# extension +$EXTENSION = 'txt'; + +# file name used for Top node when NODE_FILES is true +#$TOP_NODE_FILE = 'index'; +$TOP_NODE_FILE = undef; + +# file name used for Top node in references +$TOP_NODE_FILE_TARGET = 'index'; + +# file used as document basename, when input file is - +$STDIN_DOCU_NAME = 'stdin'; + +# file used as document output basename, when output file is - +$STDOUT_DOCU_NAME = 'stdout'; + +# node name used for Top node when automatic node directions are used +$TOP_NODE_UP = '(dir)'; + +# this controls the pre style for menus +$MENU_PRE_STYLE = 'font-family: serif'; + +# on bug-texinfo is has been said the the style is not code_style +# for menus (except for the node name). +# this controls the menu preformatted format +# FIXME this is not dynamic, so change in MENU_PRE_STYLE is not taken +# into account. +# This is used if the menu appears within a preformatted format (which +# is certainly an invalid construct), and SIMPLE_MENU is not set. +$MENU_PRE_COMPLEX_FORMAT = { + 'class' => 'menu-preformatted', +# 'style' => 'code' + }; + +# This controls the ul style for toc +$NO_BULLET_LIST_STYLE = ''; +$NO_BULLET_LIST_ATTRIBUTE = ''; + +# These lines are inserted before and after the shortcontents +$BEFORE_OVERVIEW = ""; +$AFTER_OVERVIEW = ""; + +# These lines are inserted before and after the contents +$BEFORE_TOC_LINES = ""; +$AFTER_TOC_LINES = ""; + +# if set (e.g., to index.html) replace hrefs to this file +# (i.e., to index.html) by ./ +# Obsolete. Worked around a bug that is fixed now. +$HREF_DIR_INSTEAD_FILE = ''; + +# text inserted after +$AFTER_BODY_OPEN = ''; + +# text inserted before , this will be automatically inside

    +$PRE_BODY_CLOSE = ''; + +# this is added inside after and some <meta name> +# stuff, it can be used for eg. <style>, <script>, <meta> etc. tags. +$EXTRA_HEAD = ''; + +# Specifies the minimum page length required before a navigation panel +# is placed at the bottom of a page +# FIXME this is not true: +# THIS_WORDS_IN_PAGE holds number of words of current page +$WORDS_IN_PAGE = 300; + +# if this is set a vertical navigation panel is used. +$VERTICAL_HEAD_NAVIGATION = 0; + +# html version for latex2html +$L2H_HTML_VERSION = "4.0"; + +# use icons. +$ICONS = 0; + +# use old framework for translations +$I18N_PERL_HASH = 0; + + +# this resets some defaults, those that are also set in formats and +# not set in every formats. # -# texinfo styles (@foo{bar}) to HTML ones +# this is called below after %default_style_map_texi is defined +sub t2h_default_set_variables_default() +{ + $CAPTION_STYLE = 'strong'; + +# if this variable is true, @setfilename is used if found to determine the +# out file name + $USE_SETFILENAME = 1; + +# if true, use the filename and extension from setfilename. For Info. + $USE_SETFILENAME_EXTENSION = 0; + +# FIXME is this right? +# default used in init_out for the setting of the ENCODING_NAME variable + $DEFAULT_ENCODING = 'utf8'; + +# if set and menu entry equals menu description, then do not print +# menu description. +# Likewise, if node name equals entry name, do not print entry name. + $AVOID_MENU_REDUNDANCY = 0; + +# if true, use the original command if the result is an entity + $ENABLE_ENCODING_USE_ENTITY = 0; + +# if set, output the contents where the command is located +# This is ignored if set*contentsaftertitlepage is set + $INLINE_CONTENTS = 1; + +# symbol put at the beginning of nodes entry in menu (and optionnaly of +# unnumbered in menus, see UNNUMBERED_SYMBOL_IN_MENU variable) + $MENU_SYMBOL = '*'; + +# symbol put at the end of nodes entry in menu + $MENU_ENTRY_COLON = ':'; + +# symbol put at the end of index entries + $INDEX_ENTRY_COLON = ':'; + +# if set, then use node names in menu entries, instead of section names + $NODE_NAME_IN_MENU = 1; + +# if set use the node names in index entry, instead of section names +# if not set, it is set to the same value than NODE_NAME_IN_MENU + $NODE_NAME_IN_INDEX = undef; + +# if set always separate description and menu link, even in +# preformatted environment + $SEPARATE_DESCRIPTION = 0; + +# try up sections to complete the node directions + $USE_UP_FOR_ADJACENT_NODES = 0; + +# use accesskey in hrefs + $USE_ACCESSKEY = 1; + +# use rel= and rev= in hrefs. Currently only rel is used + $USE_REL_REV = 1; + +# generate <link> elements in head + $USE_LINKS = 1; + +# if this variable is true, numeric entities are used when there is no +# corresponding textual entity. + $USE_NUMERIC_ENTITY = 0; + +# if set and $SPLIT is set, then split index pages at the next letter +# after they have more than that many entries + $SPLIT_INDEX = 0; + +# file name used for Top node when NODE_FILES is true + $TOP_NODE_FILE = undef; + +# extensions used for images + @IMAGE_EXTENSIONS = ('png','jpg', 'txt'); + + $USE_NODES = 1; + + $USE_SECTIONS = 1; + +# also set by command line options + $FOOTNOTESTYLE = 'end'; + + $DOCTYPE = ''; + + $USE_ISO = 0; + + $NUMBER_SECTIONS = 1; + + $TOP_FILE = ''; + + $ENABLE_ENCODING = 0; + # +# Formatting functions +# +# They will be reset here between formats switch +# if they are defined in this function. +# + +# these are more or less the documented vanilla versions, so they +# are reset +$unknown = \&t2h_default_unknown; +$unknown_style = \&t2h_default_unknown_style; +$external_ref = \&t2h_default_external_ref; +$internal_ref = \&t2h_default_internal_ref; +$tab_item_texi = \&t2h_default_tab_item_texi; +$complex_format = \&t2h_default_complex_format; +$toc_body = \&T2H_DEFAULT_toc_body; +$misc_command_line = \&t2h_default_misc_command_line; +$misc_command_line_texi = \&t2h_default_misc_command_line; +$print_title = \&T2H_DEFAULT_print_title; +# reset in info and xml +$element_heading = \&t2h_default_element_heading; +# reset in html +$inline_contents = \&T2H_DEFAULT_inline_contents; +# reset in docbook and info. +$style = \&T2H_GPL_style; +$format = \&T2H_GPL_format; +# reset in info +$simple_command = \&t2h_default_simple_command; +# reset in info +$thing_command = \&t2h_default_thing_command; +# reset in html and xml +$caption_shortcaption = \&t2h_default_caption_shortcaption; +$caption_shortcaption_command = \&t2h_default_caption_shortcaption_command; +# reset in docbook and xml. Not really vanilla, but documented. +$printindex = \&t2h_GPL_default_printindex; +# reset by xml and html +$misc_element_label = \&t2h_default_misc_element_label; +# set in html +$init_out = \&t2h_default_init_out; +# set in info and xml +$paragraph_style_command = \&t2h_default_paragraph_style_command; +# set in info +$colon_command = \&t2h_default_colon_command; +# set in docbook +$quotation_prepend_text = \&t2h_default_quotation_prepend_text; +# set in info +$copying_comment = \&t2h_default_copying_comment; + +# set in html and info +$print_section = \&T2H_DEFAULT_print_section; + +# set in docbook and xml +%colon_command_punctuation_characters = ( + '.' => '.', + ':' => ':', + '?' => '?', + '!' => '!' +); + + + +# in info +$footnote_texi = undef; +$begin_paragraph_texi = undef; +$begin_style_texi = undef; +$begin_special_region = undef; +$end_special_region = undef; +$empty_preformatted = undef; + +%line_command_map = ( + 'title' => '', + 'subtitle' => '', + 'author' => '', +); + +%format_in_paragraph = ( +); +# map mapping css specification to style + +%css_map = + ( + ); + +@text_substitutions_normal = (); +@text_substitutions_texi = (); +@text_substitutions_simple_format = (); +@text_substitutions_pre = (); + +%region_formats_kept = (); + +%style_map_texi = (); +t2h_default_copy_style_map (\%default_style_map_texi, \%style_map_texi); + +# reset in info +%simple_map_texi = %default_simple_map; + +# modified in docbook +%special_accents = ( + 'ringaccent' => 'aA', + "'" => 'aeiouyAEIOUY', + ',' => 'cC', + '^' => 'aeiouAEIOU', + '`' => 'aeiouAEIOU', + '~' => 'nNaoAO', + '"' => 'aeiouyAEIOU', +# according to http://www2.lib.virginia.edu/small/vhp/download/ISO.txt +# however this doesn't seems to work in firefox +# 'ogonek' => 'aeiuAEIU', +); + +# modified by info, xml, docbook +# %no_paragraph_commands should not be reset since it has been +# filled with defaults for many other commands. + +# FIXME this prevents the user from setting those entries. +$no_paragraph_commands{'cindex'} = 1; +$no_paragraph_commands{'float'} = 1; +delete $no_paragraph_commands{'anchor'}; + +# modified in docbook and xml +%stop_paragraph_command = ( + 'titlefont' => 1, + 'insertcopying' => 1, + 'sp' => 1, + 'verbatiminclude' => 1, + 'page' => 1, +# FIXME they also stop preformatted, so cannot be here. +# 'printindex' => 1, +# 'listoffloats' => 1 +); + +} + +sub t2h_default_raw_text_load() +{ + $SPLIT = ''; + # extension for nodes files when NODE_FILES is true + $NODE_FILE_EXTENSION = 'txt'; + + # extension + $EXTENSION = 'txt'; + @T2H_FORMAT_EXPAND = ('plaintext'); + $USE_TITLEPAGE_FOR_TITLE = 0; + $HEADERS = 0; + $SIMPLE_MENU = 1; + $INLINE_INSERTCOPYING = 0; + $NODE_FILENAMES = undef; + + %simple_map = %default_simple_map; + %simple_map_pre = %simple_map; + + %things_map = %default_things_map; + %pre_map = %things_map; + + %style_map = (); + %style_map_pre = (); + t2h_default_copy_style_map (\%default_style_map, \%style_map); + t2h_default_copy_style_map (\%default_style_map_pre, \%style_map_pre); + + # could also be t2h_default_set_iso_symbols() + t2h_remove_text_substitutions("'", 1, 0, 0, 1); + t2h_remove_text_substitutions('`', 1, 0, 0, 1); + $OPEN_QUOTE_SYMBOL = '`'; + $CLOSE_QUOTE_SYMBOL = "'"; + + $BEFORE_OVERVIEW = ""; + $AFTER_OVERVIEW = ""; + + $BEFORE_TOC_LINES = ""; + $AFTER_TOC_LINES = ""; + + + foreach my $complex_format ('example', 'smallexample', 'display', + 'smalldisplay', 'lisp', 'smalllisp', 'format', 'smallformat', + 'menu', 'detailmenu', 'direntry', 'menu_comment') + { + $complex_format_map{$complex_format}->{'begin'} = ''; + $complex_format_map{$complex_format}->{'end'} = ''; + } + + %format_map = ( +# 'quotation' => 'blockquote', + # lists +# 'itemize' => 'ul', + 'enumerate' => '', +# 'multitable' => 'table', + 'table' => '', + 'vtable' => '', + 'ftable' => '', + 'group' => '', + 'raggedright' => '', +# 'detailmenu' => '', + ); + + # + # Controls the layout + # + + $print_page_head = \&T2H_DEFAULT_print_page_head; + $contents = \&T2H_DEFAULT_contents; + $shortcontents = \&T2H_DEFAULT_shortcontents; + $one_section = \&T2H_DEFAULT_one_section; + $print_Top = \&T2H_DEFAULT_print_Top; + $print_Top_footer = \&T2H_DEFAULT_print_Top_footer; + $print_misc_header = \&T2H_DEFAULT_print_misc_header; + $print_misc_footer = \&T2H_DEFAULT_print_misc_footer; + $print_section_footer = \&T2H_DEFAULT_print_section_footer; + $print_chapter_header = \&T2H_DEFAULT_print_chapter_header; + $print_section_header = \&T2H_DEFAULT_print_section_header; + $print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer; + $print_page_foot = \&T2H_DEFAULT_print_page_foot; + $print_head_navigation = \&T2H_DEFAULT_print_head_navigation; + $print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation; + $end_section = \&T2H_DEFAULT_end_section; + # changed in info + $print_Footnotes = \&T2H_DEFAULT_print_Footnotes; + # used if split + $about_body = \&T2H_DEFAULT_about_body; + $print_navigation = \&T2H_DEFAULT_print_navigation; + + # + # Controls the formatting + # + + $empty_line = \&t2h_default_empty_line; + $anchor = \&t2h_default_anchor; + $anchor_label = \&t2h_default_anchor_label; + $image = \&t2h_default_image; + $heading = \&t2h_default_heading; + $heading_text = \&t2h_default_heading_text; + $heading_text_preformatted = \&t2h_default_heading_text_preformatted; + $element_label = \&t2h_default_element_label; + $index_entry_label = \&t2h_default_index_entry_label; + #$menu_command = \&t2h_default_menu_command; + $menu_link = \&t2h_default_menu_link; + #$menu_description = \&t2h_default_menu_description; + $paragraph = \&t2h_default_paragraph; + $preformatted = \&t2h_default_preformatted; + $protect_text = \&t2h_default_protect_text; + $normal_text = \&t2h_default_normal_text; + $acronym_like = \&t2h_default_acronym_like; + $sp = \&t2h_default_sp; + $quotation = \&t2h_default_quotation; + $table_list = \&t2h_default_table_list; + $list_item = \&t2h_default_list_item; + $table_line = \&t2h_default_table_line; + $table_item = \&t2h_default_table_item; + $cell = \&t2h_default_cell; + $row = \&t2h_default_row; + $def_item = \&t2h_default_def_item; + $def = \&t2h_default_def; + $def_line = \&t2h_default_def_line; + $cartouche = \&t2h_default_cartouche; + $raw = \&t2h_default_raw; + $format_list_item_texi = \&t2h_default_format_list_item_texi; + $print_index = \&t2h_default_print_index; + $index_summary = \&t2h_default_index_summary; + $index_entry = \&t2h_default_index_entry; + $index_letter = \&t2h_default_index_letter; + $foot_line_and_ref = \&t2h_default_foot_line_and_ref; + $foot_section = \&t2h_default_foot_section; + $tab_item_texi = \&t2h_default_tab_item_texi; + $listoffloats = \&t2h_default_listoffloats; + $listoffloats_entry = \&t2h_default_listoffloats_entry; + $float = \&t2h_default_float; + + t2h_default_set_variables_default(); +} + +my %things_map_xml; +my %pre_map_xml; + +sub t2h_default_set_variables_xml() +{ + t2h_default_set_variables_default(); + $ENABLE_ENCODING_USE_ENTITY = 1; + $EXTENSION = 'xml'; + t2h_default_set_iso_symbols(1); + + $empty_line = \&t2h_default_empty_line; + $comment = \&xml_default_comment; + $line_command = \&xml_default_line_command; + + %things_map = %things_map_xml; + %pre_map = %pre_map_xml; + %simple_format_texi_map = %pre_map; + + %simple_format_style_map_texi = (); + t2h_default_copy_style_map (\%default_style_map_texi, \%simple_format_style_map_texi); + foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) + { +# $simple_format_style_map_texi{$accent_command}->{'args'} = ['normal']; + $simple_format_style_map_texi{$accent_command}->{'function'} = \&xml_default_accent; + } +} + +sub t2h_default_set_variables_texi2html() +{ + $USE_SETFILENAME = 0; + $USE_SETFILENAME_EXTENSION = 0; + $FOOTNOTESTYLE = 'separate'; + $INLINE_CONTENTS = 0; + $FORCE = 1; + $AVOID_MENU_REDUNDANCY = 1; + $TOP_HEADING_AT_BEGINNING = 1; + $TOP_FILE = ''; + $USE_ACCESSKEY = 0; + $NODE_NAME_IN_MENU = 0; + $OVERVIEW_LINK_TO_TOC = 0; + $USE_UP_FOR_ADJACENT_NODES = 1; + $USE_ACCESSKEY = 0; + $USE_REL_REV = 0; + $USE_LINKS = 0; + $USE_NODES = undef; + $USE_SECTIONS = 1; + $NODE_FILENAMES = 0; + $USE_NUMERIC_ENTITY = 1; + $SPLIT = ''; + $SPLIT_INDEX = 100; + $PROGRAM_NAME_IN_FOOTER = 1; + $HEADER_IN_TABLE = 1; + $SHORT_REF = 0; + $USE_TITLEPAGE_FOR_TITLE = 1; + $MENU_ENTRY_COLON = ''; + $INDEX_ENTRY_COLON = ''; + + $ENABLE_ENCODING_USE_ENTITY = 1; +} + +# specify in this array which "buttons" should appear in which order +# in the navigation panel for sections; use ' ' for empty buttons (space) +@SECTION_BUTTONS = + ( + 'FastBack', 'Back', 'Up', 'Forward', 'FastForward', + ' ', ' ', ' ', ' ', + 'Top', 'Contents', 'Index', 'About', + ); + +# buttons for misc stuff +@MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About'); + +@TOP_BUTTONS = ( 'Back', 'Forward', ' ','Contents', 'Index', 'About'); +#@TOP_BUTTONS = ('Top', 'Contents', 'Index', 'About'); + + +# buttons for chapter file footers +# (and headers but only if HEADERS is false) +@CHAPTER_BUTTONS = + ( + 'FastBack', 'FastForward', ' ', + ' ', ' ', ' ', ' ', + 'Top', 'Contents', 'Index', 'About', + ); + +# buttons for section file footers +@SECTION_FOOTER_BUTTONS = + ( + 'FastBack', 'Back', 'Up', 'Forward', 'FastForward', + ); + +@NODE_FOOTER_BUTTONS = @SECTION_BUTTONS; + +@LINKS_BUTTONS = + ( + 'Top', 'Index', 'Contents', 'About', 'Up', 'NextFile', 'PrevFile' + ); + + +# insert here name of icon images for buttons +# Icons are used, if $ICONS and resp. value are set +%ACTIVE_ICONS = + ( + 'Top', '', + 'Contents', '', + 'Overview', '', + 'Index', '', + 'This', '', + 'Back', '', + 'FastBack', '', + 'Prev', '', + 'Up', '', + 'Next', '', + 'NodeUp', '', + 'NodeNext', '', + 'NodePrev', '', + 'Following', '', + 'Forward', '', + 'FastForward', '', + 'About' , '', + 'First', '', + 'Last', '', + 'NextFile', '', + 'PrevFile', '', + ' ', '', + ); + +# insert here name of icon images for these, if button is inactive +%PASSIVE_ICONS = + ( + 'Top', '', + 'Contents', '', + 'Overview', '', + 'Index', '', + 'This', '', + 'Back', '', + 'FastBack', '', + 'Prev', '', + 'Up', '', + 'Next', '', + 'NodeUp', '', + 'NodeNext', '', + 'NodePrev', '', + 'Following', '', + 'Forward', '', + 'FastForward', '', + 'About', '', + 'First', '', + 'Last', '', + 'NextFile', '', + 'PrevFile', '', + ); + +%misc_pages_targets = ( + 'Overview' => 'SEC_Overview', + 'Contents' => 'SEC_Contents', + 'Footnotes' => 'SEC_Foot', + 'About' => 'SEC_About' +); + +# determine the null devices +my $default_null_device = File::Spec->devnull(); +%null_device_file = ( + $default_null_device => 1 +); +# special case, djgpp recognizes both null devices +if ($Config{osname} eq 'dos' and $Config{osvers} eq 'djgpp') +{ + $null_device_file{'/dev/null'} = 1; + $null_device_file{'NUL'} = 1; +} + +$finish_out = \&t2h_default_finish_out; +$translate_names = \&t2h_default_translate_names; + +sub t2h_default_translate_names() +{ +# Names of text as alternative for icons +# FIXME maybe get those in simple_format? + %NAVIGATION_TEXT = + ( + 'Top', gdt('Top'), + 'Contents', gdt('Contents'), + 'Overview', gdt('Overview'), + 'Index', gdt('Index'), + ' ', ' ', + 'This', gdt('Current'), + 'Back', ' < ', + 'FastBack', ' << ', + 'Prev', gdt('Previous'), + 'Up', gdt('Up'), + 'Next', gdt('Next'), + 'NodeUp', gdt('Up'), + 'NodeNext', gdt('Next'), + 'NodePrev', gdt('Previous'), + 'Following', gdt('Following'), + 'Forward', ' > ', + 'FastForward', ' >> ', + 'About', ' ? ', + 'First', ' |< ', + 'Last', ' >| ', + 'NextFile', gdt('Next file'), + 'PrevFile', gdt('Previous file'), + ); + %BUTTONS_TEXT = %NAVIGATION_TEXT; + + %BUTTONS_GOTO = + ( + 'Top', gdt('Cover (top) of document'), + 'Contents', gdt('Table of contents'), + 'Overview', gdt('Short table of contents'), + 'Index', gdt('Index'), + 'This', gdt('Current section'), + 'Back', gdt('Previous section in reading order'), + 'FastBack', gdt('Beginning of this chapter or previous chapter'), + 'Prev', gdt('Previous section on same level'), + 'Up', gdt('Up section'), + 'Next', gdt('Next section on same level'), + 'NodeUp', gdt('Up node'), + 'NodeNext', gdt('Next node'), + 'NodePrev', gdt('Previous node'), + 'Following', gdt('Node following in node reading order'), + 'Forward', gdt('Next section in reading order'), + 'FastForward', gdt('Next chapter'), + 'About' , gdt('About (help)'), + 'First', gdt('First section in reading order'), + 'Last', gdt('Last section in reading order'), + 'NextFile', gdt('Forward section in next file'), + 'PrevFile', gdt('Back section in previous file'), + ); + + %BUTTONS_NAME = + ( + 'Top', gdt('Top'), + 'Contents', gdt('Contents'), + 'Overview', gdt('Overview'), + 'Index', gdt('Index'), + ' ', ' ', + 'This', gdt('This'), + 'Back', gdt('Back'), + 'FastBack', gdt('FastBack'), + 'Prev', gdt('Prev'), + 'Up', gdt('Up'), + 'Next', gdt('Next'), + 'NodeUp', gdt('NodeUp'), + 'NodeNext', gdt('NodeNext'), + 'NodePrev', gdt('NodePrev'), + 'Following', gdt('Following'), + 'Forward', gdt('Forward'), + 'FastForward', gdt('FastForward'), + 'About', gdt('About'), + 'First', gdt('First'), + 'Last', gdt('Last'), + 'NextFile', gdt('NextFile'), + 'PrevFile', gdt('PrevFile'), + ); + +} + +sub t2h_default_set_iso_symbols($) +{ + my $value = shift; + $USE_ISO = $value; + if ($value) + { + foreach my $association ([\%things_map, \%things_map_xml], + [\%pre_map, \%pre_map_xml], + [\%simple_format_simple_map_texi, \%pre_map_xml]) + { + foreach my $thing (keys(%{$association->[0]})) + { + if (defined($association->[0]->{$thing}) and $association->[0]->{$thing} !~ /^\&\w+\;$/ and defined($association->[1]->{$thing}) and $association->[1]->{$thing} =~ /^\&\w+\;$/) + { + $association->[0]->{$thing} = $association->[1]->{$thing}; + } + } + } + t2h_add_text_substitutions(["'", '’'], 1, 0, 0, 1); + t2h_add_text_substitutions(['`', '‘'], 1, 0, 0, 1); + $OPEN_QUOTE_SYMBOL = '‘'; + $CLOSE_QUOTE_SYMBOL = '’'; + } + else + { + foreach my $association ([\%things_map, \%default_things_map], + [\%pre_map, \%default_things_map], + [\%simple_format_simple_map_texi, \%default_things_map]) + { + foreach my $thing (keys(%{$association->[0]})) + { + if (defined($association->[0]->{$thing}) and $association->[0]->{$thing} =~ /^\&\w+\;$/ and defined($association->[1]->{$thing}) and $association->[1]->{$thing} !~ /^\&\w+\;$/) + { + $association->[0]->{$thing} = &$protect_text($association->[1]->{$thing}); + } + } + } + t2h_remove_text_substitutions("'", 1, 0, 0, 1); + t2h_remove_text_substitutions('`', 1, 0, 0, 1); + $OPEN_QUOTE_SYMBOL = '`'; + $CLOSE_QUOTE_SYMBOL = "'"; + } +} + +# is used in main program for dumping texi too. +sub t2h_default_set_out_encoding() +{ + # these variables are used for the corresponding + # $Texi2HTML::THISDOC{'*_ENCODING'} to keep code shorter + my ($out_encoding, $encoding_name, $document_encoding); + + $document_encoding = get_conf('DOCUMENT_ENCODING'); + + if (defined($OUT_ENCODING)) + { + $out_encoding = $OUT_ENCODING; + } + + if (defined($ENCODING_NAME)) + { + $encoding_name = $ENCODING_NAME; + } + + if (!defined($out_encoding) and (defined($encoding_name))) + { + my $possible_out_encoding = main::encoding_alias ($encoding_name, undef, 'determining encoding from default encoding'); + $out_encoding = $possible_out_encoding if (defined($possible_out_encoding)); + } + if (!defined($out_encoding) and (defined(get_conf('IN_ENCODING')))) + { + $out_encoding = get_conf('IN_ENCODING'); + } + if (!defined($out_encoding) and (defined($document_encoding))) + { + my $possible_out_encoding = main::encoding_alias ($document_encoding, undef, 'determining encoding from documentencoding'); + $out_encoding = $possible_out_encoding if (defined($possible_out_encoding)); + } + + if (!defined($encoding_name)) + { + if (defined($out_encoding) and defined($perl_charset_to_html{$out_encoding})) + { + $encoding_name = $perl_charset_to_html{$out_encoding}; + } + elsif (defined(get_conf('IN_ENCODING')) and defined($perl_charset_to_html{get_conf('IN_ENCODING')})) + { + $encoding_name = $perl_charset_to_html{get_conf('IN_ENCODING')}; + } + elsif (defined($document_encoding) and defined($perl_charset_to_html{$document_encoding})) + { + $encoding_name = $perl_charset_to_html{$document_encoding}; + } + elsif (defined($out_encoding)) + { + $encoding_name = $out_encoding; + } + elsif (defined(get_conf('IN_ENCODING'))) + { + $encoding_name = get_conf('IN_ENCODING'); + } + elsif (defined($document_encoding)) + { + $encoding_name = $document_encoding; + } + elsif (defined($perl_charset_to_html{$DEFAULT_ENCODING})) + { + $encoding_name = $perl_charset_to_html{$DEFAULT_ENCODING}; + } + else + { + $encoding_name = 'us-ascii'; + } + } + + $Texi2HTML::THISDOC{'OUT_ENCODING'} = $out_encoding; + $Texi2HTML::THISDOC{'ENCODING_NAME'} = $encoding_name; + + $out_encoding = 'UNDEF' if (!defined($out_encoding)); + my $in_encoding = get_conf('IN_ENCODING'); + $in_encoding = 'UNDEF' if (!defined($in_encoding)); + $document_encoding = 'UNDEF' if (!defined($document_encoding)); + print STDERR "# Encodings: doc $document_encoding, in $in_encoding out $out_encoding, name $encoding_name\n" if ($VERBOSE); +} + +sub t2h_default_init_out() +{ + &$translate_names; + # set external cross ref splitting like splitting. + if (!defined($EXTERNAL_CROSSREF_SPLIT)) + { + if (get_conf('SPLIT')) + { + $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 1; + } + else + { + $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 0; + } + } + else + { + $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = $EXTERNAL_CROSSREF_SPLIT; + } + + +} + +my %t2h_default_formats_load_table = ( + 'html' => \&html_default_load, + 'info' => \&info_default_load, + 'docbook' => \&docbook_default_load, + 'xml' => \&xml_default_load, + 'plaintext' => \&plaintext_default_load, + 'raw-text' => \&t2h_default_raw_text_load, +); + +sub t2h_default_load_format($;$) +{ + my $format = shift; + my $from_command_line = shift; + if (defined($t2h_default_formats_load_table{$format})) + { + $OUTPUT_FORMAT = $format; + &{$t2h_default_formats_load_table{$format}}($from_command_line); + $Texi2HTML::THISDOC{'format_from_command_line'} = $format if ($from_command_line); + return 1; + } + else + { + return 0; + } +} + +sub t2h_encoding_is_entity($) +{ + my $text = shift; + return 0 if (!$ENABLE_ENCODING_USE_ENTITY); + return 1 if ($text =~ /^&/ and $text =~ /;$/); +} + +# this is for info.init +use vars qw(%t2h_enable_encoding_default_accent); +my @t2h_enable_encoding_accents_stack; +my %t2h_enable_encoding_default_commands; + +sub t2h_enable_encoding_load() +{ + t2h_default_push_handler(\&t2h_enable_encoding_init, \@command_handler_names); + t2h_default_push_handler(\&t2h_enable_encoding_finish, \@command_handler_finish); + #push @command_handler_process, \&t2h_enable_encoding_init; + #push @command_handler_finish, \&t2h_enable_encoding_finish; + foreach my $key (keys(%unicode_accents), 'dotless') + { + $t2h_enable_encoding_default_accent{'normal'}->{$key} = $style_map{$key}->{'function'}; + $t2h_enable_encoding_default_accent{'texi'}->{$key} = $style_map_texi{$key}->{'function'}; + $t2h_enable_encoding_default_accent{'pre'}->{$key} = $style_map_pre{$key}->{'function'}; + $style_map{$key}->{'function'} = \&t2h_enable_encoding_normal_accent; + $style_map_texi{$key}->{'function'} = \&t2h_enable_encoding_texi_accent; + $style_map_pre{$key}->{'function'} = \&t2h_enable_encoding_pre_accent; + } + foreach my $key (%things_map) + { + if (exists($unicode_map{$key}) and ($unicode_map{$key} ne '')) + { + $t2h_enable_encoding_default_commands{'normal'}->{$key} = $things_map{$key}; + $t2h_enable_encoding_default_commands{'texi'}->{$key} = $texi_map{$key}; + $t2h_enable_encoding_default_commands{'sorting'}->{$key} = $sorting_things_map{$key}; + $t2h_enable_encoding_default_commands{'pre'}->{$key} = $pre_map{$key}; + } + } +} + +sub t2h_enable_encoding_finish() +{ + foreach my $key (%things_map) + { + if (exists($unicode_map{$key}) and ($unicode_map{$key} ne '')) + { + $things_map{$key} = $t2h_enable_encoding_default_commands{'normal'}->{$key}; + $texi_map{$key} = $t2h_enable_encoding_default_commands{'texi'}->{$key}; + $sorting_things_map{$key} = $t2h_enable_encoding_default_commands{'sorting'}->{$key}; + $pre_map{$key} = $t2h_enable_encoding_default_commands{'pre'}->{$key}; + } + } +} + +sub t2h_enable_encoding_init() +{ + if ($Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8') + { + foreach my $key (%things_map) + { + if (exists($unicode_map{$key}) and ($unicode_map{$key} ne '')) + { + $things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($things_map{$key})); + $texi_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($texi_map{$key})); + $sorting_things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($sorting_things_map{$key})); + $pre_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($pre_map{$key})); + } + } + } + elsif (exists($makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}})) + { + my $enc_map = $makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}}; + + foreach my $key (%things_map) + { + if (exists($unicode_map{$key}) and ($unicode_map{$key} ne '') and + exists($makeinfo_unicode_to_eight_bit{$enc_map}->{$unicode_map{$key}})) + { # we let perl handle the conversion + $things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($things_map{$key})); + $texi_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($texi_map{$key})); + $sorting_things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($sorting_things_map{$key})); + $pre_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($pre_map{$key})); + } + } + @t2h_enable_encoding_accents_stack = (); + } +} + +sub t2h_default_string_width($) +{ + my $string = shift; + if ($USE_UNICODE) + { + my $width = 0; + foreach my $character(split '', $string) + { + if ($character =~ /\p{Unicode::EastAsianWidth::InFullwidth}/) + { + $width += 2; + } + else + { + $width += 1; + } + } + return $width; + } + else + { + return length($string); + } +} + +sub t2h_default_finish_out() +{ +} + +####################################################################### +# +# Values guessed if not set here. The value used is in +# $Texi2HTML::THISDOC{'VARNAME'} +# +####################################################################### + +# In file encoding. The @documentencoding allows autodetection of +# that variable. +$DOCUMENT_ENCODING = undef; + +# In file encoding, understandable by perl. Set according to DOCUMENT_ENCODING +$IN_ENCODING = undef; + +# Formatted document encoding name. If undef, set in init_out based on +# $OUT_ENCODING or $DOCUMENT_ENCODING if they are defined +$ENCODING_NAME = undef; + +# Out files encoding, understandable by perl. If undef, set in init_out +# using $ENCODING_NAME or $IN_ENCODING if they are defined +$OUT_ENCODING = undef; + +# Used to set $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'}. +# if undef set to @documentdescription. If there is no @documentdescription, +# set in page_head. +$DOCUMENT_DESCRIPTION = undef; + +# if undef $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} set 1 if SPLIT, +# to 0 otherwise +$EXTERNAL_CROSSREF_SPLIT = undef; + +$DATE = undef; + + +######################################################################## +# Control of Page layout: +# You can make changes of the Page layout at two levels: +# 1.) For small changes, it is often enough to change the value of +# some global string/hash/array variables +# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines, +# give them another name, and assign them to the respective +# $<fnc> variable. + +# As a general interface, the hashes Texi2HTML::HREF, Texi2HTML::NAME, Texi2HTML::NODE, Texi2HTML::NO_TEXI, Texi2HTML::SIMPLE_TEXT hold +# href, html-name, node-name, name after removal of texi commands of +# This -- current section (resp. html page) +# Top -- top element +# Contents -- Table of contents element +# Overview -- Short table of contents element +# Index -- Index page element +# About -- page which explain "navigation buttons" element +# First -- first node element +# Last -- last node element +# +# Whether or not the following hash values are set, depends on the context +# (all values are w.r.t. 'This' section) +# Next -- next element of texinfo +# Prev -- previous element of texinfo +# NodeUp -- up node of texinfo +# Following -- following node in node reading order, taking menu into account +# Forward -- next node in reading order +# Back -- previous node in reading order +# Up -- parent given by sectioning commands +# FastForward -- if leave node, up and next, else next node +# FastBackward-- if leave node, up and prev, else prev node +# +# Furthermore, the following global variabels are set: +# $Texi2HTML::THISDOC{title} -- title as set by @title... +# $Texi2HTML::THISDOC{title_no_texi} -- title without texi (without html elements) +# $Texi2HTML::THISDOC{title_texi} -- title with texinfo @-commands +# $Texi2HTML::THISDOC{fulltitle} -- full title as set by @title... +# $Texi2HTML::THISDOC{subtitle} -- subtitle as set by @subtitle +# $Texi2HTML::THISDOC{author} -- author as set by @author +# $Texi2HTML::THISDOC{copying_comment} -- text of @copying and @end copying in comment +# +# $Texi2HTML::THISDOC{program} -- name and version of texi2html +# $Texi2HTML::THISDOC{program_homepage} -- homepage for texi2html +# $Texi2HTML::THISDOC{program_authors} -- authors of texi2html +# $Texi2HTML::THISDOC{today} -- date formatted with pretty_date +# $Texi2HTML::THISDOC{toc_file} -- table of contents file +# $Texi2HTML::THISDOC{file_base_name} -- base name of the texinfo manual file +# $Texi2HTML::THISDOC{input_file_name} -- name of the texinfo manual file +# $Texi2HTML::THISDOC{destination_directory} + # -- directory for the resulting files +# $Texi2HTML::THISDOC{user} -- user running the script +# $Texi2HTML::THISDOC{css_import_lines} -- ref on @import lines in css files +# $Texi2HTML::THISDOC{css_rule_lines} -- ref on css rules lines +# other $Texi2HTML::THISDOC keys corresponds with texinfo commands, the value +# being the command arg, for the following commands: +# kbdinputstyle, paragraphindent, setchapternewpage, headings, footnotestyle, +# exampleindent, firstparagraphindent, everyheading, everyfooting, +# evenheading, evenfooting, oddheading, oddfooting +# +# and pointer to arrays of lines which need to be printed by main::print_lines +# $Texi2HTML::THIS_SECTION -- lines of 'This' section +# $Texi2HTML::OVERVIEW -- lines of short table of contents +# $Texi2HTML::TOC_LINES -- lines of table of contents +# $Texi2HTML::TITLEPAGE -- lines of title page +# +# $Texi2HTML::THIS_ELEMENT holds the element reference. + +# most of the functions are either reset when switching format, in +# t2h_default_set_variables_default, or set in format, the simplest +# one being setup above in t2h_default_raw_text_load + +# +# The following generic subs control the layout: +# +# misc element formatting functions. They are rather generic, +# their call is controlled by other variables (separate or not +# footnotes, about_body, handling of table of contents...). +# print_Footnotes is the only to be redefined, in info +$print_Toc = \&T2H_DEFAULT_print_Toc; +$print_Overview = \&T2H_DEFAULT_print_Overview; +$print_About = \&T2H_DEFAULT_print_About; +$print_misc = \&T2H_DEFAULT_print_misc; +# generic enough (call print_page_head if needed) +$print_Top_header = \&T2H_DEFAULT_print_Top_header; + +# the following are less generic, but in case a specific format +# doesn't redefine them, the raw text functions are always defined. +$print_page_head = \&T2H_DEFAULT_print_page_head; +$contents = \&T2H_DEFAULT_contents; +$shortcontents = \&T2H_DEFAULT_shortcontents; +$one_section = \&T2H_DEFAULT_one_section; +$print_Top = \&T2H_DEFAULT_print_Top; +$print_Top_footer = \&T2H_DEFAULT_print_Top_footer; +$print_misc_header = \&T2H_DEFAULT_print_misc_header; +$print_misc_footer = \&T2H_DEFAULT_print_misc_footer; +$print_section_footer = \&T2H_DEFAULT_print_section_footer; +$print_chapter_header = \&T2H_DEFAULT_print_chapter_header; +$print_section_header = \&T2H_DEFAULT_print_section_header; +$print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer; +$print_page_foot = \&T2H_DEFAULT_print_page_foot; +$print_head_navigation = \&T2H_DEFAULT_print_head_navigation; +$print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation; +$end_section = \&T2H_DEFAULT_end_section; +# changed in info +$print_Footnotes = \&T2H_DEFAULT_print_Footnotes; +# used if split +$about_body = \&T2H_DEFAULT_about_body; +$print_navigation = \&T2H_DEFAULT_print_navigation; + +# +# generic formatting functions +# + +$button_icon_img = \&T2H_DEFAULT_button_icon_img; +# not really needed nor relevant except for html +$print_frame = \&T2H_DEFAULT_print_frame; +$print_toc_frame = \&T2H_DEFAULT_print_toc_frame; +# generic +$titlepage = \&T2H_DEFAULT_titlepage; +$css_lines = \&T2H_DEFAULT_css_lines; +$print_redirection_page = \&T2H_DEFAULT_print_redirection_page; +$node_file_name = \&T2H_DEFAULT_node_file_name; +$inline_contents = \&T2H_DEFAULT_inline_contents; +$program_string = \&T2H_DEFAULT_program_string; +$element_file_name = \&t2h_default_element_file_name; + +######################################################################## +# Layout for every sections +# + +sub T2H_DEFAULT_print_section($$$$) +{ + my $fh = shift; + my $first_in_page = shift; + my $previous_is_top = shift; + my $element = shift; + + my $nw = main::print_lines($fh); +} + +sub T2H_DEFAULT_one_section($$) +{ + my $fh = shift; + my $element = shift; + main::print_lines($fh); + &$print_page_foot($fh); +} + +################################################################### +# Layout of top-page. It is possible to use @ifnothtml, @ifhtml, +# @html within the Top texinfo node to specify content of top-level +# page. +# +sub T2H_DEFAULT_print_Top_header($$) +{ + my $fh = shift; + my $do_page_head = shift; + &$print_page_head($fh) if ($do_page_head); +} +sub T2H_DEFAULT_print_Top_footer($$$) +{ + my $fh = shift; + my $end_page = shift; + my $element = shift; + if ($end_page) + { + &$print_page_foot($fh); + } +} + +sub T2H_DEFAULT_print_Top($$$) +{ + my $fh = shift; + my $has_top_heading = shift; + my $element = shift; + + if ($Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'}) + { + my $shortcontents = &$inline_contents($fh, 'shortcontents'); + print $fh "".join('',@$shortcontents) if (defined($shortcontents)); + } + if ($Texi2HTML::THISDOC{'setcontentsaftertitlepage'}) + { + my $contents = &$inline_contents($fh, 'contents'); + print $fh "".join('',@$contents) if (defined($contents)); + } + + main::print_lines($fh, $Texi2HTML::THIS_SECTION); +} + +################################################################### +# Layout of Toc, Overview, and Footnotes pages +# By default, we use "normal" layout +# Texi2HTML::HREF of Next, Prev, Up, Forward, Back, etc are not defined +# redefine \@MISC_BUTTONS to change the navigation +sub T2H_DEFAULT_print_Toc +{ + return &$print_misc(@_); +} +sub T2H_DEFAULT_print_Overview +{ + return &$print_misc(@_); +} +sub T2H_DEFAULT_print_Footnotes +{ + return &$print_misc(@_); +} +sub T2H_DEFAULT_print_About +{ + return &$print_misc(@_); +} + +sub T2H_DEFAULT_print_misc_header($$$$) +{ + my $fh = shift; + my $buttons = shift; + my $new_file = shift; + my $misc_page = shift; + &$print_page_head($fh) if ($new_file); +} + +sub T2H_DEFAULT_print_misc_footer($$$) +{ + my $fh = shift; + my $buttons = shift; + my $new_file = shift; + if ($new_file) + { + &$print_page_foot($fh); + } +} + +use vars qw( +%t2h_default_underline_symbol +); + +%t2h_default_underline_symbol = ( + 0 => '*', + 1 => '*', + 2 => '=', + 3 => '-', + 4 => '.' +); + +sub t2h_default_heading_text($$$) +{ + my $command = shift; + my $text = shift; + my $level = shift; + + return '' if ($text !~ /\S/); + my $result = $text ."\n"; + # as seen in encodings/nodetest_utf8_no_unicode, the length can be in + # bytes (certainly) when there hasn't been a require Encode + #$result .=($t2h_default_underline_symbol{$level} x length($text))."\n"; + $result .=($t2h_default_underline_symbol{$level} x t2h_default_string_width($text))."\n"; + return $result; +} + +sub t2h_default_heading_text_preformatted($$$) +{ + my $command = shift; + my $text = shift; + my $level = shift; + + return t2h_default_heading_text($command, $text, $level); +} + +sub T2H_DEFAULT_print_misc($$$) +{ + my $fh = shift; + my $new_file = shift; + my $misc_page = shift; + my $buttons = \@MISC_BUTTONS; + &$print_misc_header($fh, $buttons, $new_file, $misc_page); + print $fh "".&$heading_text('misc heading', $Texi2HTML::NAME{This}, 1) . "\n"; + main::print_lines($fh); + &$print_misc_footer($fh, $buttons, $new_file); +} +################################################################## +# section_footer is only called if SPLIT eq 'section' +# section_footer: after print_section of last section, before print_page_foot +# + +sub T2H_DEFAULT_print_section_footer +{ + my $fh = shift; + my $element = shift; +} + +################################################################### +# chapter_header and chapter_footer are only called if +# SPLIT eq 'chapter' +# chapter_header: after print_page_head, before print_section +# chapter_footer: after print_section of last section, before print_page_foot + +sub T2H_DEFAULT_print_chapter_header +{ + my $fh = shift; + my $element = shift; +} + +sub T2H_DEFAULT_print_chapter_footer +{ + my $fh = shift; + my $element = shift; +} + +sub T2H_DEFAULT_print_section_header +{ + my $fh = shift; +} + + +################################################################### +# Layout of standard header and footer +# + +sub T2H_DEFAULT_print_page_head($) +{ + my $fh = shift; +} + +sub T2H_DEFAULT_program_string() +{ + my $date = $Texi2HTML::THISDOC{'today'}; + $date = '' if (!defined($date)); + if ($date ne '') + { + return gdt('This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.', { + 'date' => $date, 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' => $Texi2HTML::THISDOC{'program'} },{'duplicate'=>1}); + } + return gdt('This document was generated using @uref{{program_homepage}, @emph{{program}}}.', { + 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' +=> $Texi2HTML::THISDOC{'program'} },{'duplicate'=>1}); +} + +sub T2H_DEFAULT_end_section($$$) +{ + my $fh = shift; + my $misc_or_top_and_section_separation = shift; + my $element = shift; +} + +sub T2H_DEFAULT_print_page_foot($) +{ + my $fh = shift; +} + +################################################################### +# Layout of navigation panel + +sub T2H_DEFAULT_print_head_navigation($$$$$) +{ + my $fh = shift; + my $buttons = shift; + my $first_in_page = shift; + my $previous_is_top = shift; + my $element = shift; + + return ''; +} + +sub T2H_DEFAULT_print_foot_navigation +{ + my $fh = shift; + my $buttons = shift; + my $rule = shift; + my $print_navigation_panel = shift; + my $element = shift; + + $rule = '' if (!defined($rule)); + print $fh "$rule\n" if ($rule ne ''); +} + +###################################################################### +# navigation panel +# +# how to create IMG tag +# this is only used in html, and only if ICONS is set and the button +# is active. +sub T2H_DEFAULT_button_icon_img +{ + my $button = shift; + my $icon = shift; + my $name = shift; + return '' if (!defined($icon)); + $button = "" if (!defined ($button)); + $name = '' if (!defined($name)); + my $alt = ''; + if ($name ne '') + { + if ($button ne '') + { + $alt = "$button: $name"; + } + else + { + $alt = $name; + } + } + else + { + $alt = $button; + } + return "$icon $alt"; +} + +sub T2H_DEFAULT_print_navigation +{ + my $buttons = shift; + my $vertical = shift; + + return ''; +} + +###################################################################### +# Frames: this is from "Richard Y. Kim" <ryk@coho.net> +# Should be improved to be more conforming to other _print* functions +# toc_file and main_file passed as args are relative to the texinfo manual +# location, and therefore are not used. + +# no-ops in the default case, doesn't really make sense if output is +# not html + +sub T2H_DEFAULT_print_frame +{ + my $fh = shift; + my $toc_file = shift; + my $main_file = shift; + $main_file = $Texi2HTML::THISDOC{'filename'}->{'top'}; + $toc_file = $Texi2HTML::THISDOC{'filename'}->{'toc_frame'}; +} + +sub T2H_DEFAULT_print_toc_frame +{ + my $fh = shift; + my $stoc_lines = shift; +} + +# This subroutine is intended to fill @Texi2HTML::TOC_LINES and +# @Texi2HTML::OVERVIEW with the table of contents and short table of +# contents. +# +# arguments: +# ref on an array containing all the elements + +# each element is a reference on a hash. The following keys might be of +# use: +# 'top': true if this is the top element +# 'toc_level': level of the element in the table of content. Highest level +# is 1 for the @top element and for chapters, appendix and so on, +# 2 for section, unnumberedsec and so on... +# 'tocid': label used for reference linking to the element in table of +# contents +# 'file': the file containing the element, usefull to do href to that file +# in case the document is split. +# 'text': text of the element, with section number +# 'text_nonumber': text of the element, without section number + +# Relevant configuration variables are: +# $NO_BULLET_LIST_ATTRIBUTE: usefull in case a list is used +# $FRAMES: @Texi2HTML::OVERVIEW is used in one of the frames. +# $BEFORE_OVERVIEW +# $AFTER_OVERVIEW +# $BEFORE_TOC_LINES +# $AFTER_TOC_LINES +# get_conf('contents') +# get_conf('shortcontents') + +sub T2H_DEFAULT_contents($$) +{ + my $elements = shift; + my $toc_file = shift; + my @result; + return unless (get_conf('contents')); + foreach my $element (@$elements) + { + my $level = $element->{'toc_level'}; + $level = 1 if ($level < 1); + my $text = $element->{'text'}; + my $result = (' ' x ($level - 1)) . $text ."\n"; + push @result, $result; + } + if (@result) + { + unshift @result, $BEFORE_TOC_LINES; + push @result, $AFTER_TOC_LINES; + } + return \@result; +} + +sub T2H_DEFAULT_shortcontents($$) +{ + my $elements = shift; + my $stoc_file = shift; + my @result; + return unless (get_conf('shortcontents')); + foreach my $element (@$elements) + { + my $level = $element->{'toc_level'}; + next if ($level > 1); + $level = 1 if ($level < 1); + my $text = $element->{'text'}; + push @result, $text ."\n"; + } + if (@result) + { + unshift @result, $BEFORE_OVERVIEW; + push @result, $AFTER_OVERVIEW; + } + return \@result; +} + +sub T2H_DEFAULT_print_title() +{ + my $element = shift; + return undef unless ($SHOW_TITLE); + if ($USE_TITLEPAGE_FOR_TITLE) + { + my ($titlepage_text, $titlepage_no_texi, $titlepage_simple_format) = main::do_special_region_lines('titlepage',$Texi2HTML::THISDOC{'state'}); + + &$titlepage([],$titlepage_text, $titlepage_no_texi, $titlepage_simple_format); + return $Texi2HTML::TITLEPAGE; + } + else + { + my $title = ''; + $title = $Texi2HTML::THISDOC{'simpletitle'} if (defined($Texi2HTML::THISDOC{'simpletitle'}) and $Texi2HTML::THISDOC{'simpletitle'} !~ /^\s*$/); + if ($title ne '') + { + return &$heading_text('@settitle', $title, 0) . "\n"; + } + } +} + +sub T2H_DEFAULT_toc_body($) +{ + my $elements_list = shift; + my $toc_lines = &$contents($elements_list, $Texi2HTML::THISDOC{'toc_file'}); + @{$Texi2HTML::TOC_LINES} = @$toc_lines if ($toc_lines); + my $stoc_lines = &$shortcontents($elements_list, $Texi2HTML::THISDOC{'stoc_file'}); + @{$Texi2HTML::OVERVIEW} = @$stoc_lines if ($stoc_lines); +} + +# element and elements_list may not be undef when called from the +# main program, but may be if called from other customization function, +# for example, here, print_Top. +sub T2H_DEFAULT_inline_contents($$$$) +{ + my $fh = shift; + my $command = shift; + my $element = shift; + my $elements_list = shift; + my $name; + my $lines; + + my $toc_file; + $toc_file = $element->{'file'} if (defined($element)); + + my $result = undef; + + if ($command eq 'contents') + { + $name = $Texi2HTML::NAME{'Contents'}; + $toc_file = $Texi2HTML::THISDOC{'toc_file'} if (!defined($toc_file)); + if (defined($elements_list)) + { + $lines = &$contents($elements_list, $toc_file); + } + else + { + $lines = $Texi2HTML::TOC_LINES; + } + } + else + { + $name = $Texi2HTML::NAME{'Overview'}; + $toc_file = $Texi2HTML::THISDOC{'stoc_file'} if (!defined($toc_file)); + if (defined($elements_list)) + { + $lines = &$shortcontents($elements_list, $toc_file); + } + else + { + $lines = $Texi2HTML::OVERVIEW; + } + } + if ($lines and @{$lines}) + { + $result = [ &$heading_text("\@$command", $name, 1), "\n" ]; + my $contents_anchor = &$anchor($element->{'id'}); + if (defined($contents_anchor) and $contents_anchor =~ /\S/) + { + unshift @$result, $contents_anchor."\n"; + } + push @$result, (@$lines, "\n"); + } + return $result; +} + + +sub T2H_DEFAULT_css_lines ($$) +{ + my $import_lines = shift; + my $rule_lines = shift; +# return if (defined($CSS_LINES) or (!@$rule_lines and !@$import_lines and (! keys(%css_map)))); + if (defined($CSS_LINES)) + { # if predefined, use CSS_LINES. + $Texi2HTML::THISDOC{'CSS_LINES'} = $CSS_LINES; + return; + } + return if ((!@$rule_lines and !@$import_lines and !keys(%css_map) and !@CSS_REFS) or $NO_CSS); + my $css_text = "<style type=\"text/css\">\n<!--\n"; + $css_text .= join('',@$import_lines) . "\n" if (@$import_lines); + foreach my $css_rule (sort(keys(%css_map))) + { + next unless ($css_map{$css_rule}); + $css_text .= "$css_rule {$css_map{$css_rule}}\n"; + } + $css_text .= join('',@$rule_lines) . "\n" if (@$rule_lines); + $css_text .= "-->\n</style>\n"; + foreach my $ref (@CSS_REFS) + { + $css_text .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$ref\">\n"; + } + $Texi2HTML::THISDOC{'CSS_LINES'} = $css_text; +} + +###################################################################### +# About page +# + +# PRE_ABOUT can be a function reference or a scalar. +# Note that if it is a scalar, T2H_InitGlobals has not been called, +# and all global variables like $ADDRESS are not available. +$PRE_ABOUT = sub +{ + return ' ' . &$program_string() . "\n"; +}; + +# If customizing $AFTER_ABOUT, be sure to put the content inside <p></p>. +$AFTER_ABOUT = ''; + +%BUTTONS_EXAMPLE = + ( + 'Top', ' ', + 'Contents', ' ', + 'Overview', ' ', + 'Index', ' ', + 'This', '1.2.3', + 'Back', '1.2.2', + 'FastBack', '1', + 'Prev', '1.2.2', + 'Up', '1.2', + 'Next', '1.2.4', + 'NodeUp', '1.2', + 'NodeNext', '1.2.4', + 'NodePrev', '1.2.2', + 'Following', '1.2.4', + 'Forward', '1.2.4', + 'FastForward', '2', + 'About', ' ', + 'First', '1.', + 'Last', '1.2.4', + 'NextFile', ' ', + 'PrevFile', ' ', + ); + +sub T2H_DEFAULT_about_body +{ + my $about = ""; + if (ref($PRE_ABOUT) eq 'CODE') + { + $about .= &$PRE_ABOUT(); + } + else + { + $about .= $PRE_ABOUT; + } + return $about; +} + +# return value is currently ignored +sub T2H_DEFAULT_titlepage($$$$) +{ + my $titlepage_lines = shift; + my $titlepage_text = shift; + my $titlepage_no_texi = shift; + my $titlepage_simple_format = shift; + + $Texi2HTML::TITLEPAGE = $titlepage_text; + if ($titlepage_text eq '') + { + my $title = ''; + $title = $Texi2HTML::THISDOC{'simpletitle'} if (defined($Texi2HTML::THISDOC{'simpletitle'}) and $Texi2HTML::THISDOC{'simpletitle'} !~ /^\s*$/); + if ($title ne '') + { + $Texi2HTML::TITLEPAGE = &$heading_text('@settitle', $title, 0); + $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n"; + } + } + else + { + $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n"; + } + + if ($Texi2HTML::THISDOC{'setcontentsaftertitlepage'} and (defined($Texi2HTML::THISDOC{'inline_contents'}->{'contents'})) and @{$Texi2HTML::THISDOC{'inline_contents'}->{'contents'}}) + { + foreach my $line(@{$Texi2HTML::THISDOC{'inline_contents'}->{'contents'}}) + { + $Texi2HTML::TITLEPAGE .= $line; + } + $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n"; + } + if ($Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'} and (defined($Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'})) and @{$Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'}}) + { + foreach my $line(@{$Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'}}) + { + $Texi2HTML::TITLEPAGE .= $line; + } + $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n"; + } + return $Texi2HTML::TITLEPAGE; +} + + +sub T2H_DEFAULT_print_redirection_page() +{ + #return "Redirection files are not of use for the current format.\n"; + return undef; +} + +sub T2H_DEFAULT_node_file_name($$) +{ + my $node = shift; + my $type = shift; + return undef if ($node->{'external_node'} + or ($type eq 'top' and !$NEW_CROSSREF_STYLE)); + my $node_file_base; + if ($type eq 'top' and defined($TOP_NODE_FILE)) + { + $node_file_base = $TOP_NODE_FILE; + } + elsif ($NEW_CROSSREF_STYLE) + { + if ($TRANSLITERATE_FILE_NAMES) + { + $node_file_base = $node->{'cross_manual_file'}; + } + else + { + $node_file_base = $node->{'cross_manual_target'}; + } + } + else + { + $node_file_base = main::remove_texi($node->{'texi'}); + $node_file_base =~ s/[^\w\.\-]/-/g; + } + if (defined($NODE_FILE_EXTENSION) and $NODE_FILE_EXTENSION ne '') + { + return ($node_file_base . ".$NODE_FILE_EXTENSION"); + } + return $node_file_base; +} + +######################################################################## +# Control of formatting: +# 1.) For some changes, it is often enough to change the value of +# some global map. It might necessitate building a little +# function along with the change in hash, if the change is the use +# of another function (in style_map). +# 2.) For other changes, reimplement one of the t2h_default_<fnc>* routines, +# give them another name, and assign them to the respective +# $<fnc> variable (below). + +%deprecated_commands = ( + 'ctrl' => '', + 'allow-recursion' => N__('recursion is always allowed'), + 'quote-arg' => N__('arguments are quoted by default'), +); + +# +# This hash should have keys corresponding with the nonletter command accent +# whose following character is considered to be the argument +# This hash associates an accent macro to the ISO name for the accent if any. +# The customary use of this map is to find the ISO name appearing in html +# entity (like é) associated with a texinfo accent macro. +# +# The keys of the hash are +# ": umlaut +# ~: tilda accent +# ^: circumflex accent +# `: grave accent +# ': acute accent +# =: macron accent +%accent_map = ( + '"', 'uml', + '~', 'tilde', + '^', 'circ', + '`', 'grave', + "'", 'acute', + ",", 'cedil', + '=', '', + 'ringaccent', 'ring', + 'H', '', + 'dotaccent', '', + 'u', '', + 'ubaraccent', '', + 'udotaccent', '', + 'v', '', + 'ogonek', 'ogon', + ); + +# +# ascii representation of texinfo "simple things" @-commands +%default_simple_map = ( + '*', "\n", + ' ', ' ', + "\t", ' ', + "\n", ' ', + '-', '', # hyphenation hint + '|', '', # used in formatting commands @evenfooting and friends + '/', '', + ':', '', + '!', '!', + '?', '?', + '.', '.', + '@', '@', + '}', '}', + '{', '{', +); + +# texinfo "simple things" @-commands +%simple_map = %default_simple_map; + +# this map is used in preformatted text +%simple_map_pre = %simple_map; + +# This map is used when texi elements are removed and replaced +# by simple text +%simple_map_texi = %default_simple_map; + +# maps for the math specific commands +%simple_map_math = ( + '\\', '\\' + ); + +#%simple_map_pre_math = %simple_map_math; +#%simple_map_texi_math = %simple_map_math; + +$punctuation_characters = '.?!'; +$after_punctuation_characters = '"\')]'; + + +%default_things_map = ( + 'TeX' => 'TeX', + 'LaTeX' => 'LaTeX', + 'bullet' => '*', + 'copyright' => '(C)', + 'registeredsymbol' => '(R)', + 'dots' => '...', + 'enddots' => '...', + 'equiv' => '==', +# FIXME i18n + 'error' => 'error-->', + 'expansion' => '==>', + 'arrow' => '->', + 'minus' => '-', + 'point' => '-!-', + 'print' => '-|', + 'result' => '=>', + 'today' => '', + 'aa' => 'aa', + 'AA' => 'AA', + 'ae' => 'ae', + 'oe' => 'oe', + 'AE' => 'AE', + 'OE' => 'OE', + 'o' => '/o', + 'O' => '/O', + 'ss' => 'ss', + 'l' => '/l', + 'L' => '/L', + 'DH' => 'D', + 'dh' => 'd', + 'TH' => 'TH', # http://www.evertype.com/standards/wynnyogh/thorn.html + + 'th' => 'th', + 'exclamdown' => '!', + 'questiondown' => '?', + 'pounds' => '#', + 'ordf' => 'a', + 'ordm' => 'o', + 'comma' => ',', + 'euro' => 'Euro', + 'geq' => '>=', + 'leq' => '<=', + 'tie' => ' ', + 'textdegree' => 'o', + 'quotedblleft' => '``', + 'quotedblright' => "''", + 'quoteleft' => '`', + 'quoteright' => "'", + 'quotedblbase' => ',,', + 'quotesinglbase' => ',', + 'guillemetleft' => '<<', + 'guillemetright' => '>>', + 'guillemotleft' => '<<', + 'guillemotright' => '>>', + 'guilsinglleft' => '<', + 'guilsinglright' => '>', +); + +%things_map = %default_things_map; + +# This map is used in preformatted environments +%pre_map = %things_map; + +# used in math. If not found, pre_map is used. +%math_map = (); + +# text replacing macros when texi commands are removed and plain text is +# produced. +%texi_map = %default_things_map; + +# used for index sorting. +%sorting_things_map = %default_things_map; +foreach my $accent_letter ('o','O','l','L') +{ + $sorting_things_map{$accent_letter} = $accent_letter; +} +$sorting_things_map{'copyright'} = 'C'; +$sorting_things_map{'registeredsymbol'} = 'R'; +$sorting_things_map{'today'} = 't'; + +%default_texi_map = %texi_map; + +# +# texinfo "things" (@foo{}) to XML ones +# +%things_map_xml = ( + 'TeX' => 'TeX', + 'LaTeX' => 'LaTeX', +# pertusus: unknown by makeinfo, not in texinfo manual (@* is the right thing) +# 'br', '<br>', # paragraph break + 'bullet' => '•', +# #'copyright' => '(C)', + 'copyright' => '©', + 'registeredsymbol' => '®', + 'dots' => '…', + 'enddots' => '...', + 'equiv' => '≡', +# FIXME i18n + 'error' => 'error-->', + 'expansion' => '→', + 'arrow' => '→', + 'minus' => '-', + 'point' => '∗', + 'print' => '-|', + 'result' => '⇒', + # set in code using the language + # 'today', &pretty_date, + 'today' => '', + 'aa' => 'å', + 'AA' => 'Å', + 'ae' => 'æ', + 'oe' => 'œ', #pertusus: also œ. œ not in html 3.2 + 'AE' => 'Æ', + 'OE' => 'Œ', #pertusus: also Œ. Œ not in html 3.2 + 'o' => 'ø', + 'O' => 'Ø', + 'ss' => 'ß', + 'DH' => 'Ð', + 'dh' => 'ð', + 'TH' => 'Þ', + 'th' => 'þ', + 'l' => 'ł', + 'L' => 'Ł', + 'exclamdown' => '¡', + 'questiondown' => '¿', + 'pounds' => '£', + 'ordf' => 'ª', + 'ordm' => 'º', + 'comma' => ',', + 'euro' => '€', + 'geq' => '≥', + 'leq' => '≤', + 'tie' => ' ', + 'textdegree' => '°', + 'quotedblleft' => '“', + 'quotedblright' => '”', + 'quoteleft' => '‘', + 'quoteright' => '’', + 'quotedblbase' => '„', + 'quotesinglbase' => '‚', + 'guillemetleft' => '«', + 'guillemetright' => '»', + 'guillemotleft' => '«', + 'guillemotright' => '»', + 'guilsinglleft' => '‹', + 'guilsinglright' => '›', + ); + +# This map is used in preformatted environments +%pre_map_xml = %things_map_xml; + +# taken from +#Latin extended additionnal +#http://www.alanwood.net/unicode/latin_extended_additional.html +#C1 Controls and Latin-1 Supplement +#http://www.alanwood.net/unicode/latin_1_supplement.html +#Latin Extended-A +#http://www.alanwood.net/unicode/latin_extended_a.html +#Latin Extended-B +#http://www.alanwood.net/unicode/latin_extended_b.html +#dotless i: 0131 + +#http://www.alanwood.net/unicode/arrows.html 21** +#http://www.alanwood.net/unicode/general_punctuation.html 20** +#http://www.alanwood.net/unicode/mathematical_operators.html 22** + +%unicode_map = ( + 'bullet' => '2022', + 'copyright' => '00A9', + 'registeredsymbol' => '00AE', + 'dots' => '2026', + 'enddots' => '', + 'equiv' => '2261', + 'error' => '', + 'expansion' => '2192', + 'arrow' => '2192', + 'minus' => '2212', # in mathematical operators +# 'minus' => '002D', # in latin1 + 'point' => '2605', + 'print' => '22A3', + 'result' => '21D2', + 'today' => '', + 'aa' => '00E5', + 'AA' => '00C5', + 'ae' => '00E6', + 'oe' => '0153', + 'AE' => '00C6', + 'OE' => '0152', + 'o' => '00F8', + 'O' => '00D8', + 'ss' => '00DF', + 'DH' => '00D0', + 'dh' => '00F0', + 'TH' => '00DE', + 'th' => '00FE', + 'l' => '0142', + 'L' => '0141', + 'exclamdown' => '00A1', + 'questiondown' => '00BF', + 'pounds' => '00A3', + 'ordf' => '00AA', + 'ordm' => '00BA', + 'comma' => '002C', + 'euro' => '20AC', + 'geq' => '2265', + 'leq' => '2264', + 'tie' => '', +# 'tie' => '0020', + 'textdegree' => '00B0', + 'quotedblleft' => '201C', + 'quotedblright' => '201D', + 'quoteleft' => '2018', + 'quoteright' => '2019', + 'quotedblbase' => '201E', + 'quotesinglbase' => '201A', + 'guillemetleft' => '00AB', + 'guillemetright' => '00BB', + 'guillemotleft' => '00AB', + 'guillemotright' => '00BB', + 'guilsinglleft' => '2039', + 'guilsinglright' => '203A', + ); + +%makeinfo_encoding_to_map = ( + "iso-8859-1", 'iso8859_1', + "iso-8859-2", 'iso8859_2', + "iso-8859-15", 'iso8859_15', + "koi8-r", 'koi8', + "koi8-u", 'koi8', +); + +foreach my $encoding (keys(%makeinfo_encoding_to_map)) +{ + $t2h_encoding_aliases{$encoding} = $encoding; + $t2h_encoding_aliases{$makeinfo_encoding_to_map{$encoding}} = $encoding; +} + +# cut and pasted from eigth_bit_makeinfo_maps.pl, in turn generated with +# ./parse_8bit_makeinfo_maps.pl + +%makeinfo_unicode_to_eight_bit = ( + 'iso8859_1' => { + '00A0' => 'A0', + '00A1' => 'A1', + '00A2' => 'A2', + '00A3' => 'A3', + '00A4' => 'A4', + '00A5' => 'A5', + '00A6' => 'A6', + '00A7' => 'A7', + '00A8' => 'A8', + '00A9' => 'A9', + '00AA' => 'AA', + '00AB' => 'AB', + '00AC' => 'AC', + '00AD' => 'AD', + '00AE' => 'AE', + '00AF' => 'AF', + '00B0' => 'B0', + '00B1' => 'B1', + '00B2' => 'B2', + '00B3' => 'B3', + '00B4' => 'B4', + '00B5' => 'B5', + '00B6' => 'B6', + '00B7' => 'B7', + '00B8' => 'B8', + '00B9' => 'B9', + '00BA' => 'BA', + '00BB' => 'BB', + '00BC' => 'BC', + '00BD' => 'BD', + '00BE' => 'BE', + '00BF' => 'BF', + '00C0' => 'C0', + '00C1' => 'C1', + '00C2' => 'C2', + '00C3' => 'C3', + '00C4' => 'C4', + '00C5' => 'C5', + '00C6' => 'C6', + '00C7' => 'C7', + '00C7' => 'C7', + '00C8' => 'C8', + '00C9' => 'C9', + '00CA' => 'CA', + '00CB' => 'CB', + '00CC' => 'CC', + '00CD' => 'CD', + '00CE' => 'CE', + '00CF' => 'CF', + '00D0' => 'D0', + '00D1' => 'D1', + '00D2' => 'D2', + '00D3' => 'D3', + '00D4' => 'D4', + '00D5' => 'D5', + '00D6' => 'D6', + '00D7' => 'D7', + '00D8' => 'D8', + '00D9' => 'D9', + '00DA' => 'DA', + '00DB' => 'DB', + '00DC' => 'DC', + '00DD' => 'DD', + '00DE' => 'DE', + '00DF' => 'DF', + '00E0' => 'E0', + '00E1' => 'E1', + '00E2' => 'E2', + '00E3' => 'E3', + '00E4' => 'E4', + '00E5' => 'E5', + '00E6' => 'E6', + '00E7' => 'E7', + '00E8' => 'E8', + '00E9' => 'E9', + '00EA' => 'EA', + '00EB' => 'EB', + '00EC' => 'EC', + '00ED' => 'ED', + '00EE' => 'EE', + '00EF' => 'EF', + '00F0' => 'F0', + '00F1' => 'F1', + '00F2' => 'F2', + '00F3' => 'F3', + '00F4' => 'F4', + '00F5' => 'F5', + '00F6' => 'F6', + '00F7' => 'F7', + '00F8' => 'F8', + '00F9' => 'F9', + '00FA' => 'FA', + '00FB' => 'FB', + '00FC' => 'FC', + '00FD' => 'FD', + '00FE' => 'FE', + '00FF' => 'FF', + }, + 'iso8859_15' => { + '00A0' => 'A0', + '00A1' => 'A1', + '00A2' => 'A2', + '00A3' => 'A3', + '20AC' => 'A4', + '00A5' => 'A5', + '0160' => 'A6', + '00A7' => 'A7', + '0161' => 'A8', + '00A9' => 'A9', + '00AA' => 'AA', + '00AB' => 'AB', + '00AC' => 'AC', + '00AD' => 'AD', + '00AE' => 'AE', + '00AF' => 'AF', + '00B0' => 'B0', + '00B1' => 'B1', + '00B2' => 'B2', + '00B3' => 'B3', + '017D' => 'B4', + '00B5' => 'B5', + '00B6' => 'B6', + '00B7' => 'B7', + '017E' => 'B8', + '00B9' => 'B9', + '00BA' => 'BA', + '00BB' => 'BB', + '0152' => 'BC', + '0153' => 'BD', + '0178' => 'BE', + '00BF' => 'BF', + '00C0' => 'C0', + '00C1' => 'C1', + '00C2' => 'C2', + '00C3' => 'C3', + '00C4' => 'C4', + '00C5' => 'C5', + '00C6' => 'C6', + '00C7' => 'C7', + '00C8' => 'C8', + '00C9' => 'C9', + '00CA' => 'CA', + '00CB' => 'CB', + '00CC' => 'CC', + '00CD' => 'CD', + '00CE' => 'CE', + '00CF' => 'CF', + '00D0' => 'D0', + '00D1' => 'D1', + '00D2' => 'D2', + '00D3' => 'D3', + '00D4' => 'D4', + '00D5' => 'D5', + '00D6' => 'D6', + '00D7' => 'D7', + '00D8' => 'D8', + '00D9' => 'D9', + '00DA' => 'DA', + '00DB' => 'DB', + '00DC' => 'DC', + '00DD' => 'DD', + '00DE' => 'DE', + '00DF' => 'DF', + '00E0' => 'E0', + '00E1' => 'E1', + '00E2' => 'E2', + '00E3' => 'E3', + '00E4' => 'E4', + '00E5' => 'E5', + '00E6' => 'E6', + '00E7' => 'E7', + '00E8' => 'E8', + '00E9' => 'E9', + '00EA' => 'EA', + '00EB' => 'EB', + '00EC' => 'EC', + '00ED' => 'ED', + '00EE' => 'EE', + '00EF' => 'EF', + '00F0' => 'F0', + '00F1' => 'F1', + '00F2' => 'F2', + '00F3' => 'F3', + '00F4' => 'F4', + '00F5' => 'F5', + '00F6' => 'F6', + '00F7' => 'F7', + '00F8' => 'F8', + '00F9' => 'F9', + '00FA' => 'FA', + '00FB' => 'FB', + '00FC' => 'FC', + '00FD' => 'FD', + '00FE' => 'FE', + '00FF' => 'FF', + }, + 'iso8859_2' => { + '00A0' => 'A0', + '0104' => 'A1', + '02D8' => 'A2', + '0141' => 'A3', + '00A4' => 'A4', + '013D' => 'A5', + '015A' => 'A6', + '00A7' => 'A7', + '00A8' => 'A8', + '015E' => 'AA', + '0164' => 'AB', + '0179' => 'AC', + '00AD' => 'AD', + '017D' => 'AE', + '017B' => 'AF', + '00B0' => 'B0', + '0105' => 'B1', + '02DB' => 'B2', + '0142' => 'B3', + '00B4' => 'B4', + '013E' => 'B5', + '015B' => 'B6', + '02C7' => 'B7', + '00B8' => 'B8', + '0161' => 'B9', + '015F' => 'BA', + '0165' => 'BB', + '017A' => 'BC', + '02DD' => 'BD', + '017E' => 'BE', + '017C' => 'BF', + '0154' => 'C0', + '00C1' => 'C1', + '00C2' => 'C2', + '0102' => 'C3', + '00C4' => 'C4', + '0139' => 'C5', + '0106' => 'C6', + '00C7' => 'C7', + '010C' => 'C8', + '00C9' => 'C9', + '0118' => 'CA', + '00CB' => 'CB', + '011A' => 'CC', + '00CD' => 'CD', + '00CE' => 'CE', + '010E' => 'CF', + '0110' => 'D0', + '0143' => 'D1', + '0147' => 'D2', + '00D3' => 'D3', + '00D4' => 'D4', + '0150' => 'D5', + '00D6' => 'D6', + '00D7' => 'D7', + '0158' => 'D8', + '016E' => 'D9', + '00DA' => 'DA', + '0170' => 'DB', + '00DC' => 'DC', + '00DD' => 'DD', + '0162' => 'DE', + '00DF' => 'DF', + '0155' => 'E0', + '00E1' => 'E1', + '00E2' => 'E2', + '0103' => 'E3', + '00E4' => 'E4', + '013A' => 'E5', + '0107' => 'E6', + '00E7' => 'E7', + '010D' => 'E8', + '00E9' => 'E9', + '0119' => 'EA', + '00EB' => 'EB', + '011B' => 'EC', + '00ED' => 'ED', + '00EE' => 'EE', + '010F' => 'EF', + '0111' => 'F0', + '0144' => 'F1', + '0148' => 'F2', + '00F3' => 'F3', + '00F4' => 'F4', + '0151' => 'F5', + '00F6' => 'F6', + '00F7' => 'F7', + '0159' => 'F8', + '016F' => 'F9', + '00FA' => 'FA', + '0171' => 'FB', + '00FC' => 'FC', + '00FD' => 'FD', + '0163' => 'FE', + '02D9' => 'FF', + }, + 'koi8' => { + '0415' => 'A3', + '0454' => 'A4', + '0456' => 'A6', + '0457' => 'A7', + '04D7' => 'B3', + '0404' => 'B4', + '0406' => 'B6', + '0407' => 'B7', + '042E' => 'C0', + '0430' => 'C1', + '0431' => 'C2', + '0446' => 'C3', + '0434' => 'C4', + '0435' => 'C5', + '0444' => 'C6', + '0433' => 'C7', + '0445' => 'C8', + '0438' => 'C9', + '0439' => 'CA', + '043A' => 'CB', + '043B' => 'CC', + '043C' => 'CD', + '043D' => 'CE', + '043E' => 'CF', + '043F' => 'D0', + '044F' => 'D1', + '0440' => 'D2', + '0441' => 'D3', + '0442' => 'D4', + '0443' => 'D5', + '0436' => 'D6', + '0432' => 'D7', + '044C' => 'D8', + '044B' => 'D9', + '0437' => 'DA', + '0448' => 'DB', + '044D' => 'DC', + '0449' => 'DD', + '0447' => 'DE', + '044A' => 'DF', + '042D' => 'E0', + '0410' => 'E1', + '0411' => 'E2', + '0426' => 'E3', + '0414' => 'E4', + '0415' => 'E5', + '0424' => 'E6', + '0413' => 'E7', + '0425' => 'E8', + '0418' => 'E9', + '0419' => 'EA', + '041A' => 'EB', + '041B' => 'EC', + '041C' => 'ED', + '041D' => 'EE', + '041E' => 'EF', + '041F' => 'F0', + '042F' => 'F1', + '0420' => 'F2', + '0421' => 'F3', + '0422' => 'F4', + '0423' => 'F5', + '0416' => 'F6', + '0412' => 'F7', + '042C' => 'F8', + '042B' => 'F9', + '0417' => 'FA', + '0428' => 'FB', + '042D' => 'FC', + '0429' => 'FD', + '0427' => 'FE', + '042A' => 'FF', + }, +); + +%eight_bit_to_unicode = (); +foreach my $encoding (keys(%makeinfo_encoding_to_map)) +{ + my $unicode_to_eight = $makeinfo_unicode_to_eight_bit{$makeinfo_encoding_to_map{$encoding}}; +#print STDERR "$encoding, $makeinfo_encoding_to_map{$encoding}, $unicode_to_eight\n"; + foreach my $utf8_key (keys(%{$unicode_to_eight})) + { + $eight_bit_to_unicode{$encoding}->{$unicode_to_eight->{$utf8_key}} = + $utf8_key; + } +} + +# currently unused +my %makeinfo_transliterate_map = ( + '0416' => 'ZH', + '0447' => 'ch', + '00EB' => 'e', + '0414' => 'D', + '0159' => 'r', + '00E6' => 'ae', + '042B' => 'Y', + '00FA' => 'u', + '043B' => 'l', + '00DE' => 'TH', + '00D9' => 'U', + '00C4' => 'A', + '0148' => 'n', + '00F6' => 'o', + '0434' => 'd', + '041E' => 'O', + '041B' => 'L', + '044B' => 'y', + '0107' => 'c', + '0415' => 'E', + '00C1' => 'A', + '00D3' => 'O', + '00DB' => 'U', + '016E' => 'U', + '013A' => 'l', + '017B' => 'Z', + '00F1' => 'n', + '0428' => 'SH', + '0153' => 'oe', + '00F4' => 'o', + '0144' => 'n', + '0404' => 'IE', + '0427' => 'CH', + '0162' => 'T', + '017A' => 'z', + '0448' => 'sh', + '0436' => 'zh', + '00F9' => 'u', + '0406' => 'I', + '0103' => 'a', + '0422' => 'T', + '0160' => 'S', + '0165' => 't', + '017E' => 'z', + '00F0' => 'd', + '043E' => 'o', + '043D' => 'n', + '013E' => 'l', + '0412' => 'V', + '0111' => 'd', + '0155' => 's', + '017C' => 'z', + '00CE' => 'I', + '042D' => 'E', + '00C8' => 'E', + '00F8' => 'oe', + '00F2' => 'o', + '00FF' => 'y', + '0420' => 'R', + '0119' => 'e', + '00D2' => 'O', + '043C' => 'm', + '00D0' => 'DH', + '0179' => 'Z', + '0110' => 'D', + '043F' => 'p', + '0170' => 'U', + '011A' => 'E', + '010C' => 'C', + '015A' => 'S', + '0433' => 'g', + '00E1' => 'a', + '010D' => 'c', + '00CC' => 'I', + '016F' => 'u', + '0457' => 'yi', + '00C2' => 'A', + '0438' => 'i', + '00E3' => 'a', + '0435' => 'e', + '0440' => 'r', + '042A' => 'W', + '0431' => 'b', + '00EE' => 'i', + '0150' => 'O', + '00E8' => 'e', + '0418' => 'I', + '00CF' => 'I', + '015F' => 's', + '0142' => 'l', + '0147' => 'N', + '00DF' => 'ss', + '00E5' => 'aa', + '00C3' => 'A', + '0106' => 'C', + '0141' => 'L', + '0164' => 'T', + '017D' => 'Z', + '00EC' => 'i', + '041C' => 'M', + '00C9' => 'E', + '00E0' => 'a', + '043A' => 'k', + '00F5' => 'o', + '042C' => 'X', + '0449' => 'shch', + '0444' => 'f', + '0139' => 'L', + '0158' => 'R', + '00F3' => 'o', + '00FB' => 'u', + '0424' => 'F', + '0446' => 'c', + '0423' => 'U', + '0442' => 't', + '00FD' => 'y', + '0102' => 'A', + '0104' => 'A', + '00CB' => 'E', + '0426' => 'C', + '00CD' => 'I', + '0437' => 'z', + '0178' => 'y', + '00D4' => 'O', + '044D' => 'e', + '0432' => 'v', + '013D' => 'L', + '0163' => 't', + '0456' => 'i', + '011B' => 'e', + '044F' => 'ya', + '0429' => 'SHCH', + '0411' => 'B', + '044A' => 'w', + '00C6' => 'AE', + '041D' => 'N', + '00DA' => 'U', + '00C0' => 'A', + '0152' => 'OE', + '00DD' => 'Y', + '0154' => 'R', + '00E9' => 'e', + '00D5' => 'O', + '041F' => 'P', + '0161' => 's', + '0430' => 'a', + '0445' => 'h', + '00E2' => 'a', + '00D6' => 'O', + '0407' => 'YI', + '00CA' => 'E', + '0439' => 'i', + '0171' => 'u', + '00DC' => 'U', + '042F' => 'YA', + '0425' => 'H', + '00FE' => 'th', + '00D1' => 'N', + '044C' => 'x', + '010F' => 'd', + '0410' => 'A', + '0443' => 'u', + '00EF' => 'i', + '0105' => 'a', + '00EA' => 'e', + '00E4' => 'a', + '015E' => 'S', + '0417' => 'Z', + '00ED' => 'i', + '00FC' => 'u', + '04D7' => 'IO', + '00D8' => 'OE', + '0419' => 'I', + '0421' => 'S', + '0143' => 'N', + '010E' => 'D', + '0413' => 'G', + '015B' => 's', + '0151' => 'o', + '00E7' => 'c', + '00C5' => 'AA', + '0441' => 's', + '0118' => 'E', + '00C7' => 'C', + '041A' => 'K', + '0454' => 'ie', + '042E' => 'yu', +); + + +%transliterate_map = ( + '00C5' => 'AA', + '00E5' => 'aa', + '00D8' => 'O', + '00F8' => 'o', + '00E6' => 'ae', + '0153' => 'oe', + '00C6' => 'AE', + '0152' => 'OE', + '00DF' => 'ss', + '0141' => 'L', + '0142' => 'l', + '00D0' => 'D', + '00F0' => 'd', + '00DE' => 'TH', + '00FE' => 'th', + '0415' => 'E', + '0435' => 'e', + '0426' => 'C', + '042A' => 'W', + '044A' => 'w', + '042C' => 'X', + '044C' => 'x', + '042E' => 'yu', + '042F' => 'YA', + '044F' => 'ya', + '0433' => 'g', + '0446' => 'c', + '04D7' => 'IO', + '00DD' => 'Y', # unidecode gets this wrong ? + # following appears in tests, this is required to have + # the same output with and without unidecode + '4E2D' => 'Zhong', + '6587' => 'Wen', + '793A' => 'Shi', + '4F8B' => 'Li', + '7B2C' => 'Di', + '7AE0' => 'Zhang', + '53E6' => 'Ling', + '4E2A' => 'Ge', + # in http://www.cantonese.sheik.co.uk/dictionary/characters/7/ + # unidecode certainly gets it wrong + '4E00' => 'Yi', + 'FF08' => '(', + 'FF09' => ')', + 'FF0C' => ',', + '5B66' => 'Xue', + '7FD2' => 'Xi', + '30DE' => 'ma', + '30CB' => 'ni', + '30E5' => 'yu', + '30A2' => 'a', + '30EB' => 'ru', + ); + +foreach my $symbol(keys(%unicode_map)) +{ + if ($unicode_map{$symbol} ne '' and !exists($transliterate_map{$symbol})) + { + $no_transliterate_map{$unicode_map{$symbol}} = 1; + } +} + +%ascii_character_map = ( + ' ' => '0020', + '!' => '0021', + '"' => '0022', + '#' => '0023', + '$' => '0024', + '%' => '0025', + '&' => '0026', + "'" => '0027', + '(' => '0028', + ')' => '0029', + '*' => '002A', + '+' => '002B', + ',' => '002C', + '-' => '002D', + '.' => '002E', + '/' => '002F', + ':' => '003A', + ';' => '003B', + '<' => '003C', + '=' => '003D', + '>' => '003E', + '?' => '003F', + '@' => '0040', + '[' => '005B', + '\\' => '005C', + ']' => '005D', + '^' => '005E', + '_' => '005F', + '`' => '0060', + '{' => '007B', + '|' => '007C', + '}' => '007D', + '~' => '007E', +); + +%perl_charset_to_html = ( + 'utf8' => 'utf-8', + 'utf-8-strict' => 'utf-8', + 'ascii' => 'us-ascii', + 'shiftjis' => 'shift_jis', +); + +%t2h_encoding_aliases = ( + 'latin1' => 'iso-8859-1', +); + +foreach my $perl_charset (keys(%perl_charset_to_html)) +{ + $t2h_encoding_aliases{$perl_charset} = $perl_charset_to_html{$perl_charset}; + $t2h_encoding_aliases{$perl_charset_to_html{$perl_charset}} = $perl_charset_to_html{$perl_charset}; +} + +# These are the encodings from the texinfo manual +foreach my $canonical_encoding('us-ascii', 'utf-8', 'iso-8859-1', + 'iso-8859-15','iso-8859-2','koi8-r', 'koi8-u') +{ + $canonical_texinfo_encodings{$canonical_encoding} = 1; +} + +# not used currently for html, but used in chm.init +%numeric_entity_map = (); + +foreach my $symbol (keys(%unicode_map)) +{ + if ($symbol ne '') + { + $numeric_entity_map{$symbol} = '&#' . hex($unicode_map{$symbol}) . ';'; + } +} + +# When the value begins with & the function with that name is used to do the +# html. The first argument is the text enclosed within {}, the second is the +# style name (which is also the key of the hash) +# +# Otherwithe the value is the html element used to enclose the text, and if +# there is a " the resulting text is also enclosed within `' +my %old_style_map = ( + 'acronym', '', + 'asis', '', + 'b', 'b', + 'cite', 'cite', + 'clicksequence', '', + 'code', 'code', + 'command', 'code', + 'ctrl', '&default_ctrl', + 'dfn', 'em', + 'dmn', '', + 'email', '&default_email', + 'emph', 'em', + 'env', 'code', + 'file', '"tt', + 'i', 'i', + 'kbd', 'kbd', + 'key', 'kbd', + 'math', 'em', + 'option', '"samp', + 'r', '', + 'samp', '"samp', + 'sc', '&default_sc', + 'strong', 'strong', + 't', 'tt', + 'uref', '&default_uref', + 'url', '&default_url', + 'var', 'var', + 'verb', 'tt', + 'titlefont', '&default_titlefont', + 'w', '', + ); + +sub t2h_default_copy_style_map ($$;$) +{ + my $from = shift; + my $to = shift; + my $merge = shift; + + foreach my $command (keys(%$from)) + { + $to->{$command} = {} if (!exists($to->{$command})); + foreach my $key (keys(%{$from->{$command}})) + { + next if (exists($to->{$command}->{$key}) and $merge); + if ($key eq 'args') + { + $to->{$command}->{$key} = [ @{$from->{$command}->{$key}} ]; + } + else + { + $to->{$command}->{$key} = $from->{$command}->{$key}; + } + } + } +} + +# default is {'args' => ['normal'], 'attribute' => ''}, %style_map = ( - 'asis', '', - 'b', 'B', - 'cite', 'CITE', - 'code', 'CODE', - 'ctrl', '&do_ctrl', # special case - 'dfn', 'EM', # DFN tag is illegal in the standard - 'dmn', '', # useless - 'email', '&do_email', # insert a clickable email address - 'emph', 'EM', - 'file', '"TT', # will put quotes, cf. &apply_style - 'i', 'I', - 'kbd', 'KBD', - 'key', 'KBD', - 'math', 'EM', - 'r', '', # unsupported - 'samp', '"SAMP', # will put quotes, cf. &apply_style - 'sc', '&do_sc', # special case - 'strong', 'STRONG', - 't', 'TT', - 'titlefont', '', # useless - 'uref', '&do_uref', # insert a clickable URL - 'url', '&do_url', # insert a clickable URL - 'var', 'VAR', - 'w', '', # unsupported - ); + 'asis', {}, + 'b', {}, + 'cite', {}, + 'clicksequence', {}, + 'click', {'function' => \&t2h_default_click_normal, 'type' => 'simple_style'}, + 'code', {'args' => ['code']}, + 'command', {'args' => ['code']}, + 'ctrl', {'function' => \&t2h_default_ctrl,'type' => 'simple_style'}, + 'dfn', {}, + 'dmn', {'type' => 'simple_style'}, + 'email', {'args' => ['code', 'normal'], + 'function' => \&t2h_default_email, + 'type' => 'simple_style'}, + #'email', {'args' => ['normal', 'normal'], + # 'function' => \&t2h_default_email}, + 'emph', {}, + 'env', {'args' => ['code']}, + 'file', {'args' => ['code'], 'quote' => '"'}, + 'headitemfont', {}, + 'i', {}, + 'slanted', {}, + 'sansserif', {}, + 'kbd', {'args' => ['code'], }, + 'key', {'args' => ['code'], 'begin' => '<', 'end' => '>'}, + 'math', {'function' => \&t2h_default_math, 'args' => ['math'] }, + 'option', {'args' => ['code'], 'quote' => '"'}, + 'r', {}, + 'samp', {'args' => ['code'], 'quote' => '"'}, +# 'sc', {'function' => \&t2h_default_sc}, + 'sc', {}, + 'strong', {}, + 't', {}, + 'uref', {'function' => \&t2h_default_uref, + 'args' => ['code', 'normal', 'normal'], + 'type' => 'simple_style' }, + #'uref', {'function' => \&t2h_default_uref, + # 'args' => ['normal', 'normal', 'normal']}, + 'url', {'function' => \&t2h_default_uref, + 'args' => ['code', 'normal', 'normal'], + 'type' => 'simple_style'}, + 'indicateurl', {'args' => ['code'], 'begin' => '<', 'end' => '>','type' => 'simple_style'}, + 'var', {}, + 'verb', {'args' => ['code'], }, + 'titlefont', {'function' => \&t2h_default_titlefont, + 'type' => 'simple_style'}, + 'w', {}, + 'hyphenation', {'function' => \&t2h_default_hyphenation, 'args' => ['keep']}, + ); +%command_type = (); + +foreach my $style (keys(%style_map)) +{ + if (exists($style_map{$style}->{'type'})) + { + $command_type{$style} = $style_map{$style}->{'type'}; + } + else + { + $command_type{$style} = 'style'; + } +} + + +sub t2h_default_select_substitution($$$) +{ + my $in_raw_text = shift; + my $in_preformatted = shift; + my $in_simple = shift; + + my $substitutions = \@text_substitutions_normal; + if ($in_raw_text) + { + $substitutions = \@text_substitutions_texi; + } + elsif ($in_simple) + { + $substitutions = \@text_substitutions_simple_format; + } + elsif ($in_preformatted) + { + $substitutions = \@text_substitutions_pre; + } + return $substitutions; +} + +sub t2h_text_substitutions($$$$) +{ + my $text = shift; + my $in_raw_text = shift; + my $in_preformatted = shift; + my $in_simple = shift; + + my $substitutions = t2h_default_select_substitution($in_raw_text, $in_preformatted, $in_simple); + foreach my $substitution_entry (@$substitutions) + { + my $from = quotemeta($substitution_entry->[0]); + my $to = $substitution_entry->[1]; + $text =~ s/$from/$to/g; + } + return $text; +} + +sub t2h_add_text_substitutions($$$$$) +{ + my $entry = shift; + my $in_normal = shift; + my $in_raw_text = shift; + my $in_preformatted = shift; + my $in_simple = shift; + + my @formats_to_be_done = ($in_normal, $in_raw_text, $in_preformatted, $in_simple); + + for (my $index = 0; $index < scalar(@formats_to_be_done); $index++) + { + next unless ($formats_to_be_done[$index]); + my @args = (0, 0, 0); + my $found = 0; + $args[$index -1] = 1 if ($index > 0); + my $substitutions = &t2h_default_select_substitution(@args); + foreach my $substitution_entry (@$substitutions) + { + if ($substitution_entry->[0] eq $entry->[0]) + { + $found = 1; + $substitution_entry->[1] = $entry->[1]; + } + } + push @$substitutions, $entry unless ($found); + } +} + +sub t2h_remove_text_substitutions($$$$$) +{ + my $entry = shift; + my $in_normal = shift; + my $in_raw_text = shift; + my $in_preformatted = shift; + my $in_simple = shift; + + my @formats_to_be_done = ($in_normal, $in_raw_text, $in_preformatted, $in_simple); + + for (my $index = 0; $index < scalar(@formats_to_be_done); $index++) + { + next unless ($formats_to_be_done[$index]); + my @args = (0, 0, 0); + $args[$index -1] = 1 if ($index > 0); + my $substitutions = &t2h_default_select_substitution(@args); + + @$substitutions = grep {$_->[0] ne $entry} @$substitutions; + } +} + + +%unicode_diacritical = ( + 'H' => '030B', + 'ringaccent' => '030A', + "'" => '0301', + 'v' => '030C', + ',' => '0327', + '^' => '0302', + 'dotaccent' => '0307', + '`' => '0300', + '=' => '0304', + '~' => '0303', + '"' => '0308', + 'udotaccent' => '0323', + 'ubaraccent' => '0332', + 'u' => '0306', + 'tieaccent' => '0361', + 'ogonek' => '0328' +); + +%unicode_accents = ( + 'dotaccent' => { # dot above + 'A' => '0226', #C moz-1.2 + 'a' => '0227', #c moz-1.2 + 'B' => '1E02', + 'b' => '1E03', + 'C' => '010A', + 'c' => '010B', + 'D' => '1E0A', + 'd' => '1E0B', + 'E' => '0116', + 'e' => '0117', + 'F' => '1E1E', + 'f' => '1E1F', + 'G' => '0120', + 'g' => '0121', + 'H' => '1E22', + 'h' => '1E23', + 'i' => '0069', + 'I' => '0130', + 'N' => '1E44', + 'n' => '1E45', + 'O' => '022E', #Y moz-1.2 + 'o' => '022F', #v moz-1.2 + 'P' => '1E56', + 'p' => '1E57', + 'R' => '1E58', + 'r' => '1E59', + 'S' => '1E60', + 's' => '1E61', + 'T' => '1E6A', + 't' => '1E6B', + 'W' => '1E86', + 'w' => '1E87', + 'X' => '1E8A', + 'x' => '1E8B', + 'Y' => '1E8E', + 'y' => '1E8F', + 'Z' => '017B', + 'z' => '017C', + }, + 'udotaccent' => { # dot below + 'A' => '1EA0', + 'a' => '1EA1', + 'B' => '1E04', + 'b' => '1E05', + 'D' => '1E0C', + 'd' => '1E0D', + 'E' => '1EB8', + 'e' => '1EB9', + 'H' => '1E24', + 'h' => '1E25', + 'I' => '1ECA', + 'i' => '1ECB', + 'K' => '1E32', + 'k' => '1E33', + 'L' => '1E36', + 'l' => '1E37', + 'M' => '1E42', + 'm' => '1E43', + 'N' => '1E46', + 'n' => '1E47', + 'O' => '1ECC', + 'o' => '1ECD', + 'R' => '1E5A', + 'r' => '1E5B', + 'S' => '1E62', + 's' => '1E63', + 'T' => '1E6C', + 't' => '1E6D', + 'U' => '1EE4', + 'u' => '1EE5', + 'V' => '1E7E', + 'v' => '1E7F', + 'W' => '1E88', + 'w' => '1E89', + 'Y' => '1EF4', + 'y' => '1EF5', + 'Z' => '1E92', + 'z' => '1E93', + }, + 'ubaraccent' => { # line below + 'B' => '1E06', + 'b' => '1E07', + 'D' => '1E0E', + 'd' => '1E0F', + 'h' => '1E96', + 'K' => '1E34', + 'k' => '1E35', + 'L' => '1E3A', + 'l' => '1E3B', + 'N' => '1E48', + 'n' => '1E49', + 'R' => '1E5E', + 'r' => '1E5F', + 'T' => '1E6E', + 't' => '1E6F', + 'Z' => '1E94', + 'z' => '1E95', + }, + ',' => { # cedilla + 'C' => '00C7', + 'c' => '00E7', + 'D' => '1E10', + 'd' => '1E11', + 'E' => '0228', #C moz-1.2 + 'e' => '0229', #c moz-1.2 + 'G' => '0122', + 'g' => '0123', + 'H' => '1E28', + 'h' => '1E29', + 'K' => '0136', + 'k' => '0137', + 'L' => '013B', + 'l' => '013C', + 'N' => '0145', + 'n' => '0146', + 'R' => '0156', + 'r' => '0157', + 'S' => '015E', + 's' => '015F', + 'T' => '0162', + 't' => '0163', + }, + '=' => { # macron + 'A' => '0100', + 'a' => '0101', + 'E' => '0112', + 'e' => '0113', + 'I' => '012A', + 'i' => '012B', + 'G' => '1E20', + 'g' => '1E21', + 'O' => '014C', + 'o' => '014D', + 'U' => '016A', + 'u' => '016B', + 'Y' => '0232', #? moz-1.2 + 'y' => '0233', #? moz-1.2 + }, + '"' => { # diaeresis + 'A' => '00C4', + 'a' => '00E4', + 'E' => '00CB', + 'e' => '00EB', + 'H' => '1E26', + 'h' => '1E27', + 'I' => '00CF', + 'i' => '00EF', + 'O' => '00D6', + 'o' => '00F6', + 't' => '1E97', + 'U' => '00DC', + 'u' => '00FC', + 'W' => '1E84', + 'w' => '1E85', + 'X' => '1E8C', + 'x' => '1E8D', + 'y' => '00FF', + 'Y' => '0178', + }, + 'u' => { # breve + 'A' => '0102', + 'a' => '0103', + 'E' => '0114', + 'e' => '0115', + 'G' => '011E', + 'g' => '011F', + 'I' => '012C', + 'i' => '012D', + 'O' => '014E', + 'o' => '014F', + 'U' => '016C', + 'u' => '016D', + }, + "'" => { # acute + 'A' => '00C1', + 'a' => '00E1', + 'C' => '0106', + 'c' => '0107', + 'E' => '00C9', + 'e' => '00E9', + 'G' => '01F4', + 'g' => '01F5', + 'I' => '00CD', + 'i' => '00ED', + 'K' => '1E30', + 'k' => '1E31', + 'L' => '0139', + 'l' => '013A', + 'M' => '1E3E', + 'm' => '1E3F', + 'N' => '0143', + 'n' => '0144', + 'O' => '00D3', + 'o' => '00F3', + 'P' => '1E54', + 'p' => '1E55', + 'R' => '0154', + 'r' => '0155', + 'S' => '015A', + 's' => '015B', + 'U' => '00DA', + 'u' => '00FA', + 'W' => '1E82', + 'w' => '1E83', + 'Y' => '00DD', + 'y' => '00FD', + 'Z' => '0179', + 'z' => '018A', + }, + '~' => { # tilde + 'A' => '00C3', + 'a' => '00E3', + 'E' => '1EBC', + 'e' => '1EBD', + 'I' => '0128', + 'i' => '0129', + 'N' => '00D1', + 'n' => '00F1', + 'O' => '00D5', + 'o' => '00F5', + 'U' => '0168', + 'u' => '0169', + 'V' => '1E7C', + 'v' => '1E7D', + 'Y' => '1EF8', + 'y' => '1EF9', + }, + '`' => { # grave + 'A' => '00C0', + 'a' => '00E0', + 'E' => '00C8', + 'e' => '00E8', + 'I' => '00CC', + 'i' => '00EC', + 'N' => '01F8', + 'n' => '01F9', + 'O' => '00D2', + 'o' => '00F2', + 'U' => '00D9', + 'u' => '00F9', + 'W' => '1E80', + 'w' => '1E81', + 'Y' => '1EF2', + 'y' => '1EF3', + }, + '^' => { # circumflex + 'A' => '00C2', + 'a' => '00E2', + 'C' => '0108', + 'c' => '0109', + 'E' => '00CA', + 'e' => '00EA', + 'G' => '011C', + 'g' => '011D', + 'H' => '0124', + 'h' => '0125', + 'I' => '00CE', + 'i' => '00EE', + 'J' => '0134', + 'j' => '0135', + 'O' => '00D4', + 'o' => '00F4', + 'S' => '015C', + 's' => '015D', + 'U' => '00DB', + 'u' => '00FB', + 'W' => '0174', + 'w' => '0175', + 'Y' => '0176', + 'y' => '0177', + 'Z' => '1E90', + 'z' => '1E91', + }, + 'ringaccent' => { # ring + 'A' => '00C5', + 'a' => '00E5', + 'U' => '016E', + 'u' => '016F', + 'w' => '1E98', + 'y' => '1E99', + }, + 'v' => { # caron + 'A' => '01CD', + 'a' => '01CE', + 'C' => '010C', + 'c' => '010D', + 'D' => '010E', + 'd' => '010F', + 'E' => '011A', + 'e' => '011B', + 'G' => '01E6', + 'g' => '01E7', + 'H' => '021E', #K with moz-1.2 + 'h' => '021F', #k with moz-1.2 + 'I' => '01CF', + 'i' => '01D0', + 'K' => '01E8', + 'k' => '01E9', + 'L' => '013D', #L' with moz-1.2 + 'l' => '013E', #l' with moz-1.2 + 'N' => '0147', + 'n' => '0148', + 'O' => '01D1', + 'o' => '01D2', + 'R' => '0158', + 'r' => '0159', + 'S' => '0160', + 's' => '0161', + 'T' => '0164', + 't' => '0165', + 'U' => '01D3', + 'u' => '01D4', + 'Z' => '017D', + 'z' => '017E', + }, + 'H' => { # double acute + 'O' => '0150', + 'o' => '0151', + 'U' => '0170', + 'u' => '0171', + }, + 'ogonek' => { + 'A' => '0104', + 'a' => '0105', + 'E' => '0118', + 'e' => '0119', + 'I' => '012E', + 'i' => '012F', + 'U' => '0172', + 'u' => '0173', + 'O' => '01EA', + 'o' => '01EB', + }, +); + +foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) +{ + $style_map{$accent_command} = { 'function' => \&t2h_default_accent }; + $old_style_map{$accent_command} = '&default_accent'; + $style_map_texi{$accent_command} = { 'function' => \&t2h_default_accent }; +} + + +%transliterate_accent_map = (); +foreach my $command (keys(%unicode_accents)) +{ + foreach my $letter(keys (%{$unicode_accents{$command}})) + { + $transliterate_accent_map{$unicode_accents{$command}->{$letter}} + = $letter + unless (exists($transliterate_map{$unicode_accents{$command}->{$letter}})); + } +} + +sub default_accent($$) +{ + my $text = shift; + my $accent = shift; + return "&${text}$accent_map{$accent};" if (defined($accent_map{$accent}) and defined($special_accents{$accent}) and ($text =~ /^[$special_accents{$accent}]$/)); + return '&' . $text . 'ring;' if (($accent eq 'ringaccent') and (defined($special_accents{$accent})) and ($text =~ /^[$special_accents{$accent}]$/)); + return $text . '<' if ($accent eq 'v'); + return ascii_accents($text, $accent); +} + +sub t2h_default_accent($$) +{ + my $accent = shift; + my $args = shift; + + my $text = $args->[0]; + + return ascii_accents($text, $accent); +} + +#################################################################### +# special accent/encoding commands # -# texinfo format (@foo/@end foo) to HTML ones +# Some functions used to override normal formatting functions in specific +# cases. The user shouldn't want to change them, but can use them. # + +sub ascii_accents($$) +{ + my $text = shift; + my $accent = shift; + return $text if ($accent eq 'dotless'); + return $text . "''" if ($accent eq 'H'); + return $text . '.' if ($accent eq 'dotaccent'); + return $text . '*' if ($accent eq 'ringaccent'); + return $text . '[' if ($accent eq 'tieaccent'); + return $text . '(' if ($accent eq 'u'); + return $text . '_' if ($accent eq 'ubaraccent'); + return '.' . $text if ($accent eq 'udotaccent'); + return $text . '<' if ($accent eq 'v'); + return $text . ';' if ($accent eq 'ogonek'); + return $text . $accent if (defined($accent_map{$accent})); +} + +sub xml_default_accent($$) +{ + my $accent = shift; + my $args = shift; + + my $text = $args->[0]; + + return "&${text}$accent_map{$accent};" if (defined($accent_map{$accent}) and defined($special_accents{$accent}) and ($text =~ /^[$special_accents{$accent}]$/)); + return '&' . $text . 'ring;' if (($accent eq 'ringaccent') and (defined($special_accents{$accent})) and ($text =~ /^[$special_accents{$accent}]$/)); + return $text . '<' if ($accent eq 'v'); +# FIXME here there could be a conversion to the character in the right +# encoding, like +# if ($USE_UNICODE and defined($OUT_ENCODING) and $OUT_ENCODING ne '' +# and exists($unicode_accents{$accent}) and exists($unicode_accents{$accent}->{$text})) +# { +# my $encoded_char = Encode::encode($OUT_ENCODING, chr(hex($unicode_map{$thing})), Encode::FB_QUIET); +# return $encoded_char if ($encoded_char ne ''); +# } + if ($USE_NUMERIC_ENTITY) + { + if (exists($unicode_accents{$accent}) and exists($unicode_accents{$accent}->{$text})) + { + return ('&#' . hex($unicode_accents{$accent}->{$text}) . ';'); + } + } + return ascii_accents($text, $accent); +} + +# used to utf8 encode the result +sub t2h_utf8_accent($$$) +{ + my $accent = shift; + my $args = shift; + my $style_stack = shift; + + my $text = $args->[0]; + #print STDERR "$accent\[".scalar(@$style_stack) ."\] (@$style_stack)\n"; + + # special handling of @dotless{i} + 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 "\x{0131}"; + } + #return "\x{}" if ($text eq 'j'); # not found ! + return $text; + } + + # FIXME \x{0131}\x{0308} for @dotless{i} @" doesn't lead to NFC 00ef. + return Unicode::Normalize::NFC($text . chr(hex($unicode_diacritical{$accent}))) + if (defined($unicode_diacritical{$accent})); + return ascii_accents($text, $accent); +} + +sub t2h_utf8_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 = &$protect_text($text) unless($in_raw_text); + $text = uc($text) if (in_small_caps($style_stack)); + + if (!$in_code and !$in_preformatted) + { + $text =~ s/---/\x{2014}/g; + $text =~ s/--/\x{2013}/g; + $text =~ s/``/\x{201C}/g; + $text =~ s/''/\x{201D}/g; + } + $text = t2h_text_substitutions($text, $in_raw_text, ($in_preformatted or $in_code), $in_simple); + return Unicode::Normalize::NFC($text); +} + +sub t2h_enable_encoding_normal_accent($$$) +{ + return t2h_enable_encoding_accent ('normal', @_); +} +sub t2h_enable_encoding_texi_accent($$$) +{ + return t2h_enable_encoding_accent ('texi', @_); +} +sub t2h_enable_encoding_pre_accent($$$) +{ + return t2h_enable_encoding_accent ('pre', @_); +} + +sub t2h_enable_encoding_accent($$$$) +{ + my $context = shift; + my @other_args = @_; + + my $accent = shift; + my $args = shift; + my $style_stack = shift; + my $text = $args->[0]; + +#print STDERR "enable_encoding_accent called($context) $accent (@$style_stack)\n"; + + # in case ENCODING_NAME is not known, the accent functions saved previously + # are used. + # This should happen rarely, like during @setfilename parsing. + return &{$t2h_enable_encoding_default_accent{$context}->{$accent}}(@other_args) if (!defined($Texi2HTML::THISDOC{'ENCODING_NAME'})); + + return t2h_utf8_accent($accent,[$text],$style_stack) if ($Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8'); + + # use the saved default handling if this is not a known 8 bit encoding + return &{$t2h_enable_encoding_default_accent{$context}->{$accent}}(@other_args) if (!exists($makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}})); + + # the following is for the handling of known 8 bit encodings. + if (scalar(@t2h_enable_encoding_accents_stack)) + { + # in that case, we already have a result ready that corresponds with the + # formatting of a part of the stack mapped to + # t2h_enable_encoding_accents_stack, so it is emptied and the innermost + # $text is returned as is, such that the unmodified already formatted + # innermost formatted accented text is returned. + + #print STDERR " doing nothing, still in stack (@t2h_enable_encoding_accents_stack), accent: $accent"; + my $stack_accent = shift @t2h_enable_encoding_accents_stack; + #print STDERR " stack_accent $stack_accent\n"; + return $text; + } + + # in that case there is no t2h_enable_encoding_accents_stack, so we are + # at the closing of the innermost accented command. We will try to format + # all the stack in reverse(@$style_stack) that coresponds with + # accent commands + my @accents_stack = (); + my @styles = reverse(@$style_stack); + + # accents are formatted and the intermediate results are kept, such + # that we can return the maximum of multiaccented letters that can be + # rendered with a given eight bit formatting. + + # first put the letter in the stack + my @utf8_partial_results = { 'result' => $text, + 'accents_stack' => [ @accents_stack ]}; + + # then the accent that is associated with the function call + my $current_accent = t2h_utf8_accent($accent,[$text],$style_stack); + @accents_stack = ($accent); + push @utf8_partial_results, { 'result' => $current_accent, + 'accents_stack' => [ @accents_stack ]}; + + # and then all the other accents on the stack + while (scalar(@styles) and (defined($unicode_accents{$styles[0]}) or $styles[0] eq 'dotless')) + { + my $next_style = shift @styles; + my @new_stack = reverse(@styles); + $current_accent = t2h_utf8_accent($next_style,[$current_accent],\@new_stack); + push @accents_stack, $next_style; + push @utf8_partial_results, { 'result' => $current_accent, + 'accents_stack' => [ @accents_stack ]} + ; + } + + my $enc_map = $makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}}; + my $eight_bit; + my $result; + # At this point we have the utf8 encoded results for the accent + # commands stack, with all the intermediate results. + # For each one we'll check if it is possible to encode it in the + # current eight bit output encoding table + foreach my $partial_result (@utf8_partial_results) + { + my $char = $partial_result->{'result'}; + my $new_eight_bit = ''; + my $new_codepoint; + + if (ord($char) <= 128) + { + $new_eight_bit = uc(sprintf("%02x",ord($char))); + $new_codepoint = uc(sprintf("%04x",ord($char))); + } + elsif (ord($char) <= hex(0xFFFF)) + { + $new_codepoint = uc(sprintf("%04x",ord($char))); + if (exists($makeinfo_unicode_to_eight_bit{$enc_map}->{$new_codepoint})) + { + $new_eight_bit = $makeinfo_unicode_to_eight_bit{$enc_map}->{$new_codepoint}; + } + } + #my $eight_bit_txt = 'undef'; + #$eight_bit_txt = $eight_bit if (defined($eight_bit)); + #print STDERR "" . Encode::encode('utf8', "$char") . " (@{$partial_result->{'accents_stack'}}), new_codepoint: $new_codepoint 8bit: $new_eight_bit old:$eight_bit_txt\n"; + # no corresponding eight bit character found + last if ($new_eight_bit eq ''); + + # in that case, the new eight bit character is the same than the one + # found with one less character (and it isnt a @dotless{i}). It may + # mean 2 things + # -> there are 2 characters in accent. This could happen, for example + # if an accent that cannot be rendered is found and it leads to + # appending or prepending a character. For example this happens for + # @={@,{@~{n}}}, where @,{@~{n}} is expanded to a 2 character: + # n with a tilde, followed by a , + # In nthat case, the additional utf8 accent is prepended, which + # means that it is composed with the , and leaves n with a tilde + # untouched. + # -> ord(char) leads to the same for the more inner character. + # this, for example, happens for @ubaraccent{a}, where ord(a) is + # the same than ord(a with underbar). + last if (defined($eight_bit) and (($new_eight_bit eq $eight_bit) + and !($partial_result->{'accents_stack'}[0] eq 'dotless' and $char eq 'i'))); + $result = $partial_result; + $eight_bit = $new_eight_bit; + } + if (defined($result) and scalar(@{$result->{'accents_stack'}})) + { + # we got a result, return it and put in t2h_enable_encoding_accents_stack + # the stack of accent commands that were processed. They wont be used + # further, but only unshifted. + + #print STDERR "Result: ".Encode::encode('utf8', $result->{'result'}) ." '$eight_bit' (@{$result->{'accents_stack'}})\n" if defined($result); + @t2h_enable_encoding_accents_stack = @{$result->{'accents_stack'}}; + # remove the first, it is the accent being processed + shift @t2h_enable_encoding_accents_stack; + # it should be noted that we return the 'utf8' accent (which is really + # a codepoint, and not the eight bit representation, we leave the + # conversion to perl, which should handle it fine + return $result->{'result'}; + } + + return &{$t2h_enable_encoding_default_accent{$context}->{$accent}}(@other_args); +} + +# end special accent/encoding commands +#################################################################### + +#################################################################### +# TeX/LaTeX, that can especially be used in @math +# To load the appropriate hash, use +# default_load_tex_math + +my %tex_default_simple_map_math = ( + '{' => '\{', + '}' => '\}', + '\\' => '\\' +); + +my %tex_default_math_things_map = %default_things_map; + +$tex_default_math_things_map{'bullet'} = '\bullet'; +$tex_default_math_things_map{'copyright'} = '\copyright'; +$tex_default_math_things_map{'registeredsymbol'} = '\circledR'; +$tex_default_math_things_map{'dots'} = '\dots'; +$tex_default_math_things_map{'endots'} = '\dots'; +$tex_default_math_things_map{'equiv'} = '\equiv'; +$tex_default_math_things_map{'expansion'} = '\mapsto'; +$tex_default_math_things_map{'arrow'} = '\rightarrow'; +$tex_default_math_things_map{'point'} = '\star'; +$tex_default_math_things_map{'print'} = '\dashv'; +$tex_default_math_things_map{'result'} = '\Rightarrow'; +$tex_default_math_things_map{'pounds'} = '\pounds'; +$tex_default_math_things_map{'geq'} = '\geq'; +$tex_default_math_things_map{'leq'} = '\leq'; +$tex_default_math_things_map{'textdegree'} = '^\circ'; + +my %latex_default_math_things_map = %tex_default_math_things_map; + +$latex_default_math_things_map{'aa'} = '\mathring{a}'; +$latex_default_math_things_map{'AA'} = '\mathring{A}'; + +# FIXME Maybe this should not be there since it is not for math but +# more for a completly separate format. +my %latex_default_things_map; + +foreach my $thing (keys(%default_things_map)) +{ + $latex_default_things_map{$thing} = '\\'.$thing; +} + +$latex_default_things_map{'error'} = '\fbox{error}'; +$latex_default_things_map{'enddots'} = '\dots\@'; +$latex_default_things_map{'exclamdown'} = '\textexclamdown'; +$latex_default_things_map{'questiondown'} = '\textquestiondown'; +$latex_default_things_map{'tie'} = '~'; +$latex_default_things_map{'registeredsymbol'} = '\textregistered'; +$latex_default_things_map{'ordf'} = '\textordfeminine'; +$latex_default_things_map{'ordm'} = '\textordmasculine'; +$latex_default_things_map{'guillemetleft'} = '\guillemotleft'; +$latex_default_things_map{'guillemetright'} = '\guillemotright'; + +foreach my $text_prefixed_symbols ('bullet', 'exclamdown', 'questiondown', + 'quotedblleft', 'quotedblright', 'quoteleft', 'quoteright') +{ + $latex_default_things_map{$text_prefixed_symbols} = '\text'.$text_prefixed_symbols; +} + +foreach my $math_only ('equiv', 'expansion', 'arrow', 'minus', 'point', + 'print', 'result', 'geq', 'leq') +{ + $latex_default_things_map{$math_only} = '$'.$latex_default_math_things_map{$math_only}.'$'; +} + + +# End TeX/LaTeX +############################################################# + +sub default_sc($$) +{ + return uc($_[0]); +} + +sub default_ctrl($$) +{ + return "^$_[0]"; +} + +# obsolete, no warning, but noop +sub t2h_default_ctrl($$$) +{ + shift; + my $args = shift; + #return "^$args->[0]"; + return "$args->[0]"; +} + +sub default_sc_pre($$) +{ + return uc($_[0]); +} + +sub default_titlefont($$) +{ + return "<h1 class=\"titlefont\">$_[0]</h1>" if ($_[0] =~ /\S/); + return ''; +} + +# Return nothing if the text is empty +sub t2h_default_titlefont($$$) +{ + shift; + my $args = shift; + my $heading = $args->[0]; + return '' unless ($heading =~ /\S/); + return &$heading_text('@titlefont', $heading, 0); +} + +# At some point in time (before 4.7?) according to the texinfo +# manual, url shouldn't lead to a link but rather be formatted +# like text. It is now what indicateurl do, url is the same that +# uref with one arg. If we did like makeinfo did it would have been +#sub url($$) +#{ +# return '<<code>' . $_[0] . '</code>>'; +#} +# +# This is unused, t2h_default_uref is used instead +sub t2h_default_url ($$) +{ + shift; + my $args = shift; + my $url = shift @$args; + $url = main::normalise_space($url); + return '' unless ($url =~ /\S/); + return t2h_default_url_and_text($url); +} + +sub default_url ($$) +{ + my $url = shift; + my $command = shift; + $url =~ s/\s*$//; + $url =~ s/^\s*//; + return t2h_default_url_and_text($url); +} + +sub default_uref($$) +{ + my $arg = shift; + my $command = shift; + my ($url, $text, $replacement); + ($url, $text, $replacement) = split /,\s*/, $arg; + $url =~ s/\s*$//; + $url =~ s/^\s*//; + $text = $replacement if (defined($replacement)); + return t2h_default_url_and_text($url, $text); +} + +sub t2h_default_uref($$) +{ + shift; + my $args = shift; + my $url = shift @$args; + my $text = shift @$args; + my $replacement = shift @$args; + $url = main::normalise_space($url); + $replacement = '' if (!defined($replacement)); + $replacement = main::normalise_space($replacement); + $text = '' if (!defined($text)); + $text = main::normalise_space($text); + $text = $replacement if ($replacement ne ''); + return t2h_default_url_and_text($url, $text); +} + +sub t2h_default_math($$) +{ + shift; + my $args = shift; + my $text = shift @$args; + return "$text"; +} + +sub default_email($$) +{ + my $arg = shift; + my $command = shift; + my ($mail, $text); + ($mail, $text) = split /,\s*/, $arg; + $mail =~ s/\s*$//; + $mail =~ s/^\s*//; + return t2h_default_url_and_text("mailto:$mail", $text); +} + +sub t2h_default_email($$) +{ + my $command = shift; + my $args = shift; + my $mail = shift @$args; + my $text = shift @$args; + $mail = main::normalise_space($mail); + if (defined($text)) + { + #$text =~ s/^\s*//; + #$text =~ s/^\s*$//; + $text = main::normalise_space($text); + } + my $mailto = ''; + $mailto = "mailto:$mail" if ($mail ne ''); + return t2h_default_url_and_text($mailto, $text); +} + +sub t2h_default_click_normal($$$) +{ + return t2h_default_click('normal', @_); +} + +sub t2h_default_click_pre($$$) +{ + return t2h_default_click('pre', @_); +} + +sub t2h_default_click_texi($$$) +{ + return t2h_default_click('texi', @_); +} + +sub t2h_default_click($$$$$) +{ + my $context = shift; + my $command = shift; + my $args = shift; + my $arg = shift @$args; + my $cmd = $Texi2HTML::THISDOC{'clickstyle'}; + $cmd = 'arrow' if (!defined($cmd) or ($cmd eq '')); + + my $hash = \%things_map; + if ($context eq 'pre') + { + $hash = \%pre_map; + } + elsif ($context eq 'texi') + { + $hash = \%texi_map; + } + return $hash->{$cmd} . $arg if (exists($hash->{$cmd})); + return $arg; +} + +sub t2h_default_hyphenation($$) +{ + my $command = shift; + my $args = shift; + my $text = shift @$args; + $text =~ s/^\s*//; + $text =~ s/\s*$//; + my @list = split /\s+/, $text; + foreach my $entry (@list) + { + my $word = $entry; + $word =~ s/-//g; + $Texi2HTML::THISDOC{'hyphenation'}->{$word} = $entry; + } +} + +sub t2h_default_no_texi_email +{ + my $command = shift; + my $args = shift; + my $mail = shift @$args; + my $text = shift @$args; + $mail = main::normalise_space($mail); + return $text if (defined($text) and ($text ne '')); + return $mail; +} + +sub t2h_default_no_texi_image($$$$) +{ + my $command = shift; + my $args = shift; + my $file = $args->[0]; + $file = main::trim_around_spaces($file); + return main::substitute_line($file, "\@$command", {'remove_texi' => 1, 'code_style' => 1}); +} + +sub t2h_default_no_texi_acronym_like($$) +{ + my $command = shift; + my $args = shift; + my $acronym_texi = $args->[0]; + return (main::remove_texi($acronym_texi)); +} + +sub t2h_remove_command($$$$) +{ + return ''; +} + +# This is used for style in preformatted sections +my %old_style_map_pre = %old_style_map; +$old_style_map_pre{'sc'} = '&default_sc_pre'; +$old_style_map_pre{'titlefont'} = ''; + +foreach my $command (keys(%style_map)) +{ + $style_map_texi{$command} = {} if (!exists($style_map_texi{$command})); + $style_map_texi{$command}->{'args'} = [ @{$style_map{$command}->{'args'}} ] + if (exists($style_map{$command}->{'args'})); + #print STDERR "COMMAND $command"; +} + +%style_map_pre = (); + +t2h_default_copy_style_map(\%style_map, \%style_map_pre); + +$style_map_pre{'sc'} = {}; +$style_map_pre{'titlefont'} = {}; +$style_map_pre{'click'}->{'function'} = \&t2h_default_click_pre; + +$style_map_texi{'sc'} = {}; +$style_map_texi{'email'}->{'function'} = \&t2h_default_no_texi_email; +$style_map_texi{'click'}->{'function'} = \&t2h_default_click_texi; + +####### special styles. You shouldn't need to change them +%special_style = ( + #'xref' => ['keep','normal','normal','keep','normal'], + 'xref' => { 'args' => ['keep','keep','keep','keep','keep'], + 'function' => \&main::do_xref }, + 'ref' => { 'args' => ['keep','keep','keep','keep','keep'], + 'function' => \&main::do_xref }, + 'pxref' => { 'args' => ['keep','keep','keep','keep','keep'], + 'function' => \&main::do_xref }, + 'inforef' => { 'args' => ['keep','keep','keep'], + 'function' => \&main::do_xref }, + 'image' => { 'args' => ['keep','keep','keep','keep','keep'], 'function' => \&main::do_image }, + 'anchor' => { 'args' => ['keep'], 'function' => \&main::do_anchor_label }, + 'footnote' => { 'args' => ['keep'], 'function' => \&main::do_footnote }, + 'shortcaption' => { 'args' => ['keep'], 'function' => \&main::do_caption_shortcaption }, + 'caption' => { 'args' => ['keep'], 'function' => \&main::do_caption_shortcaption }, + 'acronym', {'args' => ['keep','keep'], 'function' => \&main::do_acronym_like}, + 'abbr', {'args' => ['keep','keep'], 'function' => \&main::do_acronym_like}, +); + +# @image is replaced by the first arg in strings +$style_map_texi{'image'} = { 'args' => ['keep','keep','keep','keep','keep'], + 'function' => \&t2h_default_no_texi_image }; + +$style_map_texi{'acronym'} = { 'args' => ['keep','keep'], + 'function' => \&t2h_default_no_texi_acronym_like }; +$style_map_texi{'abbr'} = { 'args' => ['keep','keep'], + 'function' => \&t2h_default_no_texi_acronym_like }; + +foreach my $special (keys(%special_style)) +{ + $style_map{$special} = $special_style{$special} + unless (defined($style_map{$special})); + $style_map_pre{$special} = $special_style{$special} + unless (defined($style_map_pre{$special})); + $style_map_texi{$special} = { 'args' => ['keep'], + 'function' => \&t2h_remove_command } + unless (defined($style_map_texi{$special})); +} +####### end special styles. + + +#foreach my $command (keys(%style_map)) +#{ +# print STDERR "STYLE_MAP_TEXI $command($style_map_texi{$command}) "; +# print STDERR "ARGS $style_map_texi{$command}->{'args'} " if (defined($style_map_texi{$command}->{'args'})); +# print STDERR "FUN $style_map_texi{$command}->{'function'} " if (defined($style_map_texi{$command}->{'function'})); +# print STDERR "\n"; +#} + +# uncomment to use the old interface +#%style_map = %old_style_map; +#%style_map_pre = %old_style_map_pre; + +%simple_format_simple_map_texi = %simple_map_pre; +%simple_format_texi_map = %pre_map; +%simple_format_style_map_texi = (); + +t2h_default_copy_style_map(\%style_map_texi, \%simple_format_style_map_texi); + +foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) +{ +# $simple_format_style_map_texi{$accent_command}->{'args'} = ['normal']; + $simple_format_style_map_texi{$accent_command}->{'function'} = \&t2h_default_accent; +} + +foreach my $hash (\%style_map, \%style_map_pre, \%style_map_texi, \%simple_format_style_map_texi) +{ + foreach my $style (keys(%{$hash})) + { + $hash->{$style}->{'args'} = ['normal'] if (!exists($hash->{$style}->{'args'})); + } +} + +%default_style_map = (); +%default_style_map_pre = (); +%default_style_map_texi = (); +%default_simple_format_style_map_texi = (); + +t2h_default_copy_style_map(\%style_map, \%default_style_map); +t2h_default_copy_style_map(\%style_map_pre, \%default_style_map_pre); +t2h_default_copy_style_map(\%style_map_texi, \%default_style_map_texi); +t2h_default_copy_style_map(\%simple_format_style_map_texi, \%default_simple_format_style_map_texi); + +# called here because %default_style_map_texi is used. +t2h_default_set_variables_default(); + +################################################################# +# TeX/LaTeX styles, that can be used in math + +my %default_style_tex_map; +my %default_style_latex_map; + +t2h_default_copy_style_map(\%default_style_map, \%default_style_tex_map); +t2h_default_copy_style_map(\%default_style_map, \%default_style_latex_map); + +# common in TeX and LaTeX and both for math and normal text + +$default_style_latex_map{'w'}->{'inline_begin'} = '\mbox{'; +$default_style_tex_map{'w'}->{'inline_begin'} = '\mbox{'; +$default_style_latex_map{'dmn'}->{'inline_begin'} = '{\thinspace '; +$default_style_tex_map{'dmn'}->{'inline_begin'} = '{\thinspace '; + +my %default_style_latex_math_map; + +t2h_default_copy_style_map(\%default_style_latex_map, \%default_style_latex_math_map); + +my %default_tex_latex_map = ( + 'bf' => [ 'b', 'strong' ], + 'tt' => [ 'code', 'command', 'env', 'file', 'option', 'samp', 't' ], + 'it' => [ 'i', 'var', 'emph' ], + 'sf' => [ 'sanserif' ], + 'rm' => [ 'r' ], + 'sl' => [ 'dfn', 'slanted' ], +); + +foreach my $style (keys (%default_tex_latex_map)) +{ + foreach my $command (@{$default_tex_latex_map{$style}}) + { + $default_style_tex_map{$command}->{'inline_begin'} = '{\\' . $style .' '; + $default_style_latex_map{$command}->{'inline_begin'} = '\text' . $style .'{'; + $style = 'normal' if ($style eq 'sl'); + $default_style_latex_math_map{$command}->{'inline_begin'} = '\math' . $style .'{'; + } +} + +# only in text + +$default_style_latex_map{'emph'}->{'inline_begin'} = '\emph{'; +$default_style_latex_map{'var'}->{'inline_begin'} = '\emph{'; +$default_style_latex_map{'sc'}->{'inline_begin'} = '\textsc{'; + +foreach my $hash (\%default_style_tex_map, \%default_style_latex_map, \%default_style_latex_math_map) +{ + foreach my $command (keys(%$hash)) + { + $hash->{$command}->{'inline_end'} = '}' if ($hash->{$command}->{'inline_begin'}); + } +} + +# no kbd key sc in math +# 'kbd' - ? +# 'key' - ? + +my %default_style_tex_math_map; + +t2h_default_copy_style_map(\%default_style_tex_map, \%default_style_tex_math_map); + +# We don't want to override special commands in math mode for now, as long +# as they are not handled especially. Also we don't want to modify the math +# function, it is called to close the @math command and we don't want +# it to be the turned to the default one when calling +# FIXME maybe it would be even better not to duplicate default styles in +# math, like 'email', 'uref'.... +foreach my $command (keys(%special_style), 'math') +{ + delete $default_style_tex_math_map{$command}; + delete $default_style_latex_math_map{$command}; +} + +foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) +{ + $default_style_latex_map{$accent_command} = { 'function' => \&default_tex_accent }; + $default_style_tex_map{$accent_command} = { 'function' => \&default_tex_accent }; + $default_style_tex_math_map{$accent_command} = { 'function' => \&default_tex_math_accent }; + $default_style_latex_math_map{$accent_command} = { 'function' => \&default_latex_math_accent }; +} + +my %tex_text_accent_map = ( + ',' => 'c', + 'ringaccent' => 'r', + 'dotaccent' => '.', + 'ubaraccent' => 'b', + 'udotaccent' => 'd', + 'ogonek' => 'k', + 'tieaccent' => 'tie', +); + +sub default_tex_accent($$) +{ + my $text = shift; + my $accent = shift; + return "\\$tex_text_accent_map{$accent}\{$text\}" if ($tex_text_accent_map{$accent}); + if ($accent eq 'dotless') + { + return "\\$text" if ($text eq 'i' or $text eq 'j'); + return $text; + } + return "\\$accent\{$text\}"; +} + +my %tex_math_accent_map = ( + "'" => 'acute', + '^' => 'hat', + '`' => 'grave', + '~' => 'tilde', + '"' => 'ddot', + '=' => 'bar', + 'dotaccent' => 'dot', + 'u' => 'breve', + 'ubaraccent' => 'underline', +); + +sub default_latex_math_accent($$) +{ + my $text = shift; + my $accent = shift; + return '\mathring{'.$text.'}' if ($accent eq 'ringaccent'); + return default_tex_math_accent($text, $accent); +} + +sub default_tex_math_accent($$) +{ + my $text = shift; + my $accent = shift; + return "\\$tex_text_accent_map{$accent}\{$text\}" if ($tex_text_accent_map{$accent}); + if ($accent eq 'dotless') + { + return "\\${text}math" if ($text eq 'i' or $text eq 'j'); + return $text; + } + return ascii_accent($text, $accent); +} + +my $kept_normal_text; + +# We assume that in @math the TeX characters have already been +# rightly protected and so don't protect once more. +sub default_tex_normal_math_text($$$$$$$;$) +{ + my @initial_args = @_; + my $text = shift; + my $in_raw_text = shift; # remove_texi + my $in_preformatted = shift; + my $in_code = shift; + my $in_math = shift; + my $in_simple = shift; + my $style_stack = shift; + my $state = shift; + + # Don't protect text in math + if ($in_math) + { + $text = uc($text) if (in_cmd($style_stack, 'sc')); + return $text; + } + return &kept_normal_text(@initial_args); +} + +# This is the entry point to be used by users. +sub default_load_tex_math(;$) +{ + my $style = shift; + $style = 'latex' if (!defined($style)); + %simple_map_math = %tex_default_simple_map_math; + if ($style eq 'tex') + { + %math_map = %tex_default_math_things_map; + t2h_default_copy_style_map(\%default_style_tex_math_map, \%style_map_math); + } + else + { + %math_map = %latex_default_math_things_map; + t2h_default_copy_style_map(\%default_style_latex_math_map, \%style_map_math); + } + $kept_normal_text = $normal_text; + $normal_text = \&default_tex_normal_math_text; +} + +# End TeX/LaTeX styles +################################################################# + +# regions expanded or not depending on the value of this hash. +# @EXPAND sets entries in this hash, and you should better use +# @EXPAND unless you know what you are doing. +%texi_formats_map = ( + 'iftex' => 0, + 'ignore' => 0, + 'menu' => 0, + 'ifplaintext' => 0, + 'ifinfo' => 0, + 'ifxml' => 0, + 'ifhtml' => 0, + 'ifdocbook' => 0, +# 'html' => 0, +# 'tex' => 0, +# 'xml' => 0, +# 'docbook' => 0, + 'titlepage' => 1, + 'documentdescription' => 1, + 'copying' => 1, + 'ifnothtml' => 1, + 'ifnottex' => 1, + 'ifnotplaintext' => 1, + 'ifnotinfo' => 1, + 'ifnotxml' => 1, + 'ifnotdocbook' => 1, + 'direntry' => 'normal', + 'verbatim' => 'raw', + 'macro' => 'raw', + 'ifclear' => 'value', + 'ifset' => 'value' , + ); + %format_map = ( - 'display', 'PRE', - 'example', 'PRE', - 'format', 'PRE', - 'lisp', 'PRE', - 'quotation', 'BLOCKQUOTE', - 'smallexample', 'PRE', - 'smalllisp', 'PRE', - # lists - 'itemize', 'UL', - 'enumerate', 'OL', - # poorly supported - 'flushleft', 'PRE', - 'flushright', 'PRE', - ); +# 'quotation' => 'blockquote', + # lists +# 'itemize' => 'ul', + 'enumerate' => '', +# 'multitable' => 'table', + 'table' => '', + 'vtable' => '', + 'ftable' => '', + 'group' => '', + 'raggedright' => '', +# 'detailmenu' => '', + ); +%special_list_commands = ( + 'table' => {}, + 'vtable' => {}, + 'ftable' => {}, +# 'itemize' => { 'bullet' => '' } + 'itemize' => {}, + ); + +%inter_item_commands = ( + 'c' => 1, + 'comment' => 1, + 'cindex' => 1 +); # -# texinfo definition shortcuts to real ones +# texinfo format to align attribute of paragraphs # + +%paragraph_style = ( + 'center' => 'center', + 'flushleft' => 'left', + 'flushright' => 'right', + ); + +# complex formats (preformatted) +%complex_format_map = (); +foreach my $complex_format ('example', 'smallexample', 'display', + 'smalldisplay', 'lisp', 'smalllisp', 'format', 'smallformat', + 'menu', 'detailmenu', 'direntry', 'menu_comment') +{ + $complex_format_map{$complex_format} = { 'begin' => '', 'end' => '' }; +} +foreach my $code_complex_format ('example', 'smallexample', 'lisp', 'smalllisp') +{ + $complex_format_map{$code_complex_format}->{'style'} = 'code'; +} + +# not in code_style, according to post on bug-texinfo +foreach my $format ('menu', 'detailmenu', 'direntry') +{ + $complex_format_map{$format}->{'class'} = 'menu-preformatted'; +} + +# not in code_style, according to post on bug-texinfo +$complex_format_map{'menu_comment'}->{'class'} = 'menu-comment'; + %def_map = ( - # basic commands - 'deffn', 0, - 'defvr', 0, - 'deftypefn', 0, - 'deftypevr', 0, - 'defcv', 0, - 'defop', 0, - 'deftp', 0, - # basic x commands - 'deffnx', 0, - 'defvrx', 0, - 'deftypefnx', 0, - 'deftypevrx', 0, - 'defcvx', 0, - 'defopx', 0, - 'deftpx', 0, - # shortcuts - 'defun', 'deffn Function', - 'defmac', 'deffn Macro', - 'defspec', 'deffn {Special Form}', - 'defvar', 'defvr Variable', - 'defopt', 'defvr {User Option}', - 'deftypefun', 'deftypefn Function', - 'deftypevar', 'deftypevr Variable', - 'defivar', 'defcv {Instance Variable}', - 'defmethod', 'defop Method', - # x shortcuts - 'defunx', 'deffnx Function', - 'defmacx', 'deffnx Macro', - 'defspecx', 'deffnx {Special Form}', - 'defvarx', 'defvrx Variable', - 'defoptx', 'defvrx {User Option}', - 'deftypefunx', 'deftypefnx Function', - 'deftypevarx', 'deftypevrx Variable', - 'defivarx', 'defcvx {Instance Variable}', - 'defmethodx', 'defopx Method', - ); + # basic commands + 'deffn', [ 'f', 'category', 'name', 'arg' ], + 'defvr', [ 'v', 'category', 'name' ], + 'deftypefn', [ 'f', 'category', 'type', 'name', 'argtype' ], + 'deftypeop', [ 'f', 'category', 'class' , 'type', 'name', 'argtype' ], + 'deftypevr', [ 'v', 'category', 'type', 'name' ], + 'defcv', [ 'v', 'category', 'class' , 'name' ], + 'deftypecv', [ 'v', 'category', 'class' , 'type', 'name' ], + 'defop', [ 'f', 'category', 'class' , 'name', 'arg' ], + 'deftp', [ 't', 'category', 'name', 'argtype' ], + # shortcuts + # FIXME i18n + 'defun', 'deffn Function', + 'defmac', 'deffn Macro', + 'defspec', 'deffn {Special Form}', + 'defvar', 'defvr Variable', + 'defopt', 'defvr {User Option}', + 'deftypefun', 'deftypefn {Function}', + 'deftypevar', 'deftypevr Variable', + 'defivar', 'defcv {Instance Variable}', + 'deftypeivar', 'deftypecv {Instance Variable}', + 'defmethod', 'defop Method', + 'deftypemethod', 'deftypeop Method', + ); +$def_always_delimiters = "()[]"; +$def_in_type_delimiters = ",;"; +$def_argument_separator_delimiters = "()[],"; + +# basic x commands +foreach my $key (keys(%def_map)) +{ + $def_map{$key . 'x'} = $def_map{$key}; +} + # -# things to skip +# miscalleneous commands # -%to_skip = ( - # comments - 'c', 1, - 'comment', 1, - 'ifnothtml', 1, - # useless - 'detailmenu', 1, - 'direntry', 1, - 'contents', 1, - 'shortcontents', 1, - 'summarycontents', 1, - 'footnotestyle', 1, - 'end ifclear', 1, - 'end ifset', 1, - 'titlepage', 1, - 'end titlepage', 1, - # unsupported commands (formatting) - 'afourpaper', 1, - 'cropmarks', 1, - 'finalout', 1, - 'headings', 1, - 'sp', 1, - 'need', 1, - 'page', 1, - 'setchapternewpage', 1, - 'everyheading', 1, - 'everyfooting', 1, - 'evenheading', 1, - 'evenfooting', 1, - 'oddheading', 1, - 'oddfooting', 1, - 'smallbook', 1, - 'vskip', 1, - 'filbreak', 1, - 'paragraphindent', 1, - # unsupported formats - 'cartouche', 1, - 'end cartouche', 1, - 'group', 1, - 'end group', 1, - ); +# Depending on the value, the command arg or spaces following the command +# are handled differently: +# +# the value is a reference on a hash. +# the hash keys are +# 'arg' if the value is 'line' then the remaining of the line is the arg +# if it is a number it is the number of args (separated by spaces) +# 'skip' if the value is 'line' then the remaining of the line is skipped +# if the value is 'space' space but no newline is skipped +# if the value is 'whitespace' space is skipped +# if the value is 'linewhitespace' space is skipped if there are +# only spaces remaining on the line +# if the value is 'linespace' space but no newline is skipped if +# there are only spaces remaining on the line +# 'keep' if true the args and the macro are kept, otherwise the macro +# args and skipped stuffs are removed +%misc_command = ( + 'bye' => {'skip' => 'line'}, # no arg + # set, clear + 'set' => {'skip' => 'line'}, # special arg + 'clear' => {'skip' => 'line'}, # special arg + 'alias' => {'args' => 3, 'skip' => 'line'}, # special arg + # comments + 'comment' => {'arg' => 'line'}, + 'c' => {'arg' => 'line'}, -#+++############################################################################ -# # -# Argument parsing, initialisation # -# # -#---############################################################################ + # not needed for formatting + 'raisesections' => {'skip' => 'line'}, # no arg + 'lowersections' => {'skip' => 'line'}, # no arg + 'contents' => {}, # no arg + 'shortcontents' => {}, # no arg + 'summarycontents'=> {}, # no arg + 'setcontentsaftertitlepage' => {}, # no arg + 'setshortcontentsaftertitlepage' => {}, # no arg +# 'detailmenu' => {'skip' => 'whitespace'}, # no arg +# 'end detailmenu' => {'skip' => 'whitespace'}, # no arg + 'clickstyle' => {'skip' => 'line'}, # arg should be an @-command + # in preamble + 'novalidate' => {}, # no arg + 'dircategory'=> {'arg' => 'line'}, # line. Position with regard + # with direntry is significant + 'pagesizes' => {'skip' => 'line', 'arg' => 'line'}, # can have 2 args + # or one? 200mm,150mm 11.5in + 'finalout' => {'skip' => 'line'}, # no arg + 'paragraphindent' => {'skip' => 'line', 'arg' => 1}, # arg none asis + # or a number and forbids anything else on the line + 'firstparagraphindent' => {'skip' => 'line', 'arg' => 1}, # none insert + 'frenchspacing' => {'arg' => 1, 'skip' => 'line'}, # on off + # not so sure about 'skip' => 'line' + 'fonttextsize' => {'arg' => 1}, # 10 11 + 'allowcodebreaks' => {'arg' => 1, 'skip' => 'line'}, # false or true + 'exampleindent' => {'skip' => 'line', 'arg' => 1}, # asis or a number + 'footnotestyle'=> {'skip' => 'line', 'arg' => 1}, # end and separate + # and nothing else on the line + 'afourpaper' => {'skip' => 'line'}, # no arg + 'afivepaper' => {'skip' => 'line'}, # no arg + 'afourlatex' => {'skip' => 'line'}, # no arg + 'afourwide' => {'skip' => 'line'}, # no arg + 'headings'=> {'skip' => 'line', 'arg' => 1}, + #off on single double singleafter doubleafter + # interacts with setchapternewpage + 'setchapternewpage' => {'skip' => 'line', 'arg' => 1}, # off on odd + 'everyheading' => {'arg' => 'line'}, + 'everyfooting' => {'arg' => 'line'}, + 'evenheading' => {'arg' => 'line'}, + 'evenfooting' => {'arg' => 'line'}, + 'oddheading' => {'arg' => 'line'}, + 'oddfooting' => {'arg' => 'line'}, + 'smallbook' => {'skip' => 'line'}, # no arg + 'setfilename' => {'arg' => 'line'}, + 'definfoenclose' => {'arg' => 'line'}, + #'shorttitle' => {'arg' => 'line', 'texi' => 1}, + #'shorttitlepage' => {'arg' => 'line', 'texi' => 1}, + #'settitle' => {'arg' => 'line', 'texi' => 1}, + #'author' => {'arg' => 'line', 'texi' => 1}, + #'subtitle' => {'arg' => 'line', 'texi' => 1}, + #'title' => {'arg' => 'line', 'texi' => 1}, + 'shorttitle' => {'arg' => 'line'}, + 'shorttitlepage' => {'arg' => 'line'}, + 'settitle' => {'arg' => 'line'}, + 'author' => {'arg' => 'line'}, + 'subtitle' => {'arg' => 'line'}, + 'title' => {'arg' => 'line'}, + 'syncodeindex' => {'skip' => 'line', 'arg' => 2}, + # args are index identifiers + 'synindex' => {'skip' => 'line', 'arg' => 2}, + 'defindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg + 'defcodeindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg + #'documentlanguage' => {'skip' => 'whitespace', 'arg' => 1}, + 'documentlanguage' => {'skip' => 'line', 'arg' => 1}, + # language code arg + 'kbdinputstyle' => {'skip' => 'whitespace', 'arg' => 1}, # code + #example distinct + 'everyheadingmarks' => {'skip' => 'line', 'arg' => 1}, # top bottom + 'everyfootingmarks' => {'skip' => 'whitespace', 'arg' => 1}, + 'evenheadingmarks' => {'skip' => 'whitespace', 'arg' => 1}, + 'oddheadingmarks' => {'skip' => 'whitespace', 'arg' => 1}, + 'evenfootingmarks' => {'skip' => 'whitespace', 'arg' => 1}, + 'oddfootingmarks' => {'skip' => 'whitespace', 'arg' => 1}, + 'sp' => {'skip' => 'line', 'arg' => 1}, # no arg + # at the end of line or a numerical arg + # formatting + 'page' => {}, # no arg (pagebreak) + 'refill' => {}, # no arg (obsolete, to be ignored) + 'noindent' => {'skip' => 'whitespace'}, # no arg + 'indent' => {'skip' => 'whitespace'}, + 'need' => {'skip' => 'line', 'arg' => 1}, # one numerical/real arg + 'exdent' => {'skip' => 'space'}, + # not valid for info (should be in @iftex) + 'vskip' => {'arg' => 'line'}, # arg line in TeX + 'cropmarks' => {}, # no arg + # miscalleneous + 'verbatiminclude'=> {'skip' => 'line'}, + 'documentencoding' => {'arg' => 1, 'skip' => 'line'}, + # ??? + 'filbreak' => {}, + # obsolete @-commands. Remove spaces and end of lines after the + # commands? If no, they can lead to empty lines + 'quote-arg' => {'skip' => 'line'}, + 'allow-recursion' => {'skip' => 'line'}, + ); -%value = (); # hold texinfo variables, see also -D +my %misc_command_old = ( + # not needed for formatting + 'raisesections', 'line', # no arg + 'lowersections', 'line', # no arg + 'contents', 1, # no arg + 'shortcontents', 1, # no arg + 'summarycontents', 1, # no arg + 'detailmenu', 'whitespace', # no arg + 'end detailmenu', 'whitespace', # no arg + #'end detailmenu', 1, # no arg + 'novalidate', 1, # no arg + 'bye', 'line', # no arg + # comments + 'comment', 'line', + 'c', 'line', + # in preamble + 'dircategory', 'line', # line. Position with regard with direntry is + # significant + 'pagesizes', 'line arg2', # can have 2 args + 'finalout', 1, # no arg + 'paragraphindent', 'line arg1', # in fact accepts only none asis + # or a number and forbids anything else on the line + 'firstparagraphindent', 'line arg1', # in fact accepts only none insert + 'exampleindent', 'line arg1', # in fact accepts only asis or a number + 'footnotestyle', 'line arg1', # in fact accepts only end and separate + # and nothing else on the line + 'afourpaper', 'line', # no arg + 'afourlatex', 'line', # no arg + 'afourwide', 'line', # no arg + 'headings', 'line', # one arg, possibilities are + #off on single double singleafter doubleafter + # interacts with setchapternewpage + 'setchapternewpage', 'line', # no arg + 'everyheading', 'line', + 'everyfooting', 'line', + 'evenheading', 'line', + 'evenfooting', 'line', + 'oddheading', 'line', + 'oddfooting', 'line', + 'smallbook', 'line', # no arg + 'setfilename', 'line', + 'shorttitle', 'linetexi', + 'shorttitlepage', 'linetexi', + 'settitle', 'linetexi', + 'author', 'linetexi', + 'subtitle', 'linetexi', + 'title','linetexi', + 'syncodeindex','linespace arg2', # args are + 'synindex','linespace arg2', + 'defindex', 'line arg1', # one identifier arg + 'defcodeindex', 'line arg1', # one identifier arg + 'documentlanguage', 'whitespace arg1', # one language code arg + 'kbdinputstyle', 'whitespace arg1', # one arg within + #code example distnct + 'sp', 'whitespace arg1', # no arg at the en of line or a numerical arg + # formatting + 'page', 1, # no arg (pagebreak) + 'refill', 1, # no arg (obsolete, to be ignored)) + 'noindent', 'space', # no arg + 'need', 'line arg1', # one numerical/real arg + 'exdent', 'space', + # not valid for info (should be in @iftex) + 'vskip', 'line', # arg line in TeX + 'cropmarks', 1, # no arg + # miscalleneous + 'verbatiminclude', 'line', + 'documentencoding', 'arg1', + # ??? + 'filbreak', 1, + ); -$use_bibliography = 1; -$use_acc = 0; -$debug = 0; -$doctype = ''; -$check = 0; -$expandinfo = 0; -$use_glossary = 0; -$invisible_mark = ''; -$use_iso = 0; -@include_dirs = (); -$show_menu = 0; -$number_sections = 0; -$split_node = 0; -$split_chapter = 0; -$monolithic = 0; -$verbose = 0; -$usage = <<EOT; -This is $THISPROG -To convert a Texinfo file to HMTL: $0 [options] file - where options can be: - -expandinfo : use \@ifinfo sections, not \@iftex - -glossary : handle a glossary - -invisible name: use 'name' as an invisible anchor - -Dname : define name like with \@set - -I dir : search also for files in 'dir' - -menu : handle menus - -monolithic : output only one file including ToC - -number : number sections - -split_chapter : split on main sections - -split_node : split on nodes - -usage : print usage instructions - -verbose : verbose output -To check converted files: $0 -check [-verbose] files -It accepts only ja_JP.EUC and ascii files. +# The command_handler arrays are for commands formatted externally. +# The function references in @command_handler_init are called +# before the second pass, before the @-commands text collection. +# Those in @command_handler_process are called between the second pass +# and the third pass, after collection of @-commands text and before their +# expansion. +# Those in @command_handler_process are called after the third pass, +# after the document generation. +@command_handler_setup = (); +@command_handler_init = (); +@command_handler_names = (); +@command_handler_process = (); +@command_handler_output = (); +@command_handler_finish = (); + + +sub t2h_default_push_handler($$) +{ + my $function = shift; + my $handlers = shift; + push @$handlers, $function unless (grep {$_ eq $function} @$handlers); +} + +# the keys of %command_handler are @-command names and the value +# is a hash reference with the following keys: +# 'init' function reference used to collect the @-command text +# 'expand' function reference used when expanding the @-command text +%command_handler = (); + + +# formatting functions + +$anchor = \&t2h_default_anchor; +$def_item = \&t2h_default_def_item; +$def = \&t2h_default_def; +$menu_command = \&t2h_default_menu_command; +$menu_link = \&t2h_default_menu_link; +#$menu_comment = \&t2h_default_menu_comment; +$menu_description = \&t2h_default_menu_description; +#$simple_menu_link = \&t2h_default_simple_menu_link; +$table_item = \&t2h_default_table_item; +$table_line = \&t2h_default_table_line; +$table_list = \&t2h_default_table_list; +$row = \&t2h_default_row; +$cell = \&t2h_default_cell; +$list_item = \&t2h_default_list_item; +$comment = \&t2h_default_comment; +$def_line = \&t2h_default_def_line; +$def_line_no_texi = \&t2h_default_def_line_no_texi; +$raw = \&t2h_default_raw; +$raw_no_texi = \&t2h_default_raw_no_texi; +$heading = \&t2h_default_heading; +$heading_text = \&t2h_default_heading_text; +$heading_text_preformatted = \&t2h_default_heading_text_preformatted; +$element_heading = \&t2h_default_element_heading; +$heading_no_texi = \&t2h_default_heading_no_texi; +$external_href = \&t2h_default_external_href; +$paragraph = \&t2h_default_paragraph; +$preformatted = \&t2h_default_preformatted; +$foot_line_and_ref = \&t2h_default_foot_line_and_ref; +$foot_section = \&t2h_default_foot_section; +$image_files = \&t2h_default_image_files; +$image = \&t2h_default_image; +$index_entry_label = \&t2h_default_index_entry_label; +$index_summary = \&t2h_default_index_summary; +$summary_letter = \&t2h_default_summary_letter; +$index_entry = \&t2h_default_index_entry; +$index_entry_command = \&t2h_default_index_entry_command; +$index_letter = \&t2h_default_index_letter; +#$printindex = \&t2h_default_printindex; +$print_index = \&t2h_default_print_index; +$protect_text = \&t2h_default_protect_text; +$normal_text = \&t2h_default_normal_text; +$cartouche = \&t2h_default_cartouche; +$sp = \&t2h_default_sp; +$definition_category = \&t2h_default_definition_category; +$definition_index_entry = \&t2h_default_definition_index_entry; +$copying_comment = \&t2h_default_copying_comment; +$documentdescription = \&t2h_default_documentdescription; +$index_summary_file_entry = \&t2h_default_index_summary_file_entry; +$index_summary_file_end = \&t2h_default_index_summary_file_end; +$index_summary_file_begin = \&t2h_default_index_summary_file_begin; +$empty_line = \&t2h_default_empty_line; +$float = \&t2h_default_float; +$listoffloats = \&t2h_default_listoffloats; +$listoffloats_entry = \&t2h_default_listoffloats_entry; +$listoffloats_caption = \&t2h_default_listoffloats_caption; +$listoffloats_float_style = \&t2h_default_listoffloats_float_style; +$listoffloats_style = \&t2h_default_listoffloats_style; +$acronym_like = \&t2h_default_acronym_like; +$quotation = \&t2h_default_quotation; +$paragraph_style_command = \&t2h_default_paragraph_style_command; +$heading_texi = \&t2h_default_heading_texi; +$index_element_heading_texi = \&t2h_default_index_element_heading_texi; +$element_label = \&t2h_default_element_label; +$anchor_label = \&t2h_default_anchor_label; +$preserve_misc_command = \&t2h_default_preserve_misc_command; +$format_list_item_texi = \&t2h_default_format_list_item_texi; +$begin_format_texi = \&t2h_default_begin_format_texi; +$insertcopying = \&t2h_default_insertcopying; +$simple_command = \&t2h_default_simple_command; +$thing_command = \&t2h_default_thing_command; +$line_command = \&t2h_default_line_command; +$internal_links = \&t2h_default_internal_links; + +# address is not used anymore +$address = \&t2h_default_address; + +# return the line after preserving things according to misc_command map. +# You should not change it. It is here, nevertheless, to be used +# in other function references if needed. +sub t2h_default_preserve_misc_command($$) +{ + my $line = shift; + my $macro = shift; + my $text = ''; + my $args = []; + my $skip_spec = ''; + my $arg_spec = ''; + +#print STDERR "HHHHHHHHH $line $macro\n"; + $skip_spec = $misc_command{$macro}->{'skip'} + if (defined($misc_command{$macro}->{'skip'})); + $arg_spec = $misc_command{$macro}->{'arg'} + if (defined($misc_command{$macro}->{'arg'})); + + if ($arg_spec eq 'line') + { + $text .= $line; + $args = [ $line ]; + $line = ''; + } + elsif ($arg_spec) + { + my $arg_nr = $misc_command{$macro}->{'arg'}; + while ($arg_nr) + { + $line =~ s/(\s+\S*)//o; + my $argument = $1; + if (defined($argument)) + { + $text .= $argument; + push @$args, $argument; + } + $arg_nr--; + } + } + + if ($macro eq 'bye') + { + $line = ''; + $text = "\n"; + } + elsif ($skip_spec eq 'linespace') + { + if ($line =~ /^\s*$/o) + { + $line =~ s/([ \t]*)//o; + $text .= $1; + } + } + elsif ($skip_spec eq 'linewhitespace') + { + if ($line =~ /^\s*$/o) + { + $text .= $line; + $line = ''; + } + } + elsif ($skip_spec eq 'line') + { + $text .= $line; + $line = ''; + } + elsif ($skip_spec eq 'whitespace') + { + $line =~ s/(\s*)//o; + $text .= $1; + } + elsif ($skip_spec eq 'space') + { + $line =~ s/([ \t]*)//o; + $text .= $1; + } + $line = '' if (!defined($line)); + return ($line, $text, $args); +} + +sub t2h_default_simple_command($$$$$) +{ + my $command = shift; + my $in_preformatted = shift; + my $in_math = shift; + my $line_nr = shift; + my $state = shift; + + if ($in_math) + { + my $result = $simple_map_pre{$command}; + $result = $simple_map_math{$command} if (defined($simple_map_math{$command})); + return $result; + } + elsif ($in_preformatted) + { + return $simple_map_pre{$command}; + } + else + { + return $simple_map{$command}; + } +} + +sub t2h_default_thing_command($$$$$$) +{ + my $command = shift; + my $text = shift; + my $in_preformatted = shift; + my $in_math = shift; + my $line_nr = shift; + my $state = shift; + + my $result; + if ($in_math) + { + $result = $pre_map{$command}; + $result = $math_map{$command} if (defined($math_map{$command})); + } + elsif ($in_preformatted) + { + $result = $pre_map{$command}; + } + else + { + $result = $things_map{$command}; + } + return $result . $text; +} + +# this is called each time a format begins. Here it is used to keep a +# record of the multitables to have a faithful count of the cell nr. +sub t2h_default_begin_format_texi($$$) +{ + my $command = shift; + my $line = shift; + my $state = shift; + + # remove space in front of center, unless it removes the end of line! + $line =~ s/^\s*// if ($command eq 'center' and $line =~ /\S/); + return $line; +} + +# This function is called whenever a complex format is processed +# +# arguments: +# name of the format +# text appearing inside the format +# +# an eval of $complex_format->{format name}->{'begin'} should lead to the +# beginning of the complex format, an eval of +# $complex_format->{format name}->{'end'} should lead to the end of the +# complex format. +sub t2h_default_complex_format($$) +{ + my $name = shift; + my $text = shift; + return '' if ($text eq ''); + return '' if ($name eq 'direntry'); + my $beginning; + my $end; + # FIXME obsoleted in nov 2009 + if (exists($complex_format_map->{$name})) + { + $beginning = eval "$complex_format_map->{$name}->{'begin'}"; + if ($@ ne '') + { + main::msg_debug("Evaluation of $complex_format_map->{$name}->{'begin'}: $@"); + $beginning = ''; + + } + $end = eval "$complex_format_map->{$name}->{'end'}"; + if ($@ ne '') + { + main::msg_debug("Evaluation of $complex_format_map->{$name}->{'end'}: $@"); + $end = ''; + } + } + else + { + $beginning = $complex_format_map{$name}->{'begin'}; + $beginning = '' if (!defined($beginning)); + $end = $complex_format_map{$name}->{'end'}; + $end = '' if (!defined($end)); + } + return $beginning . $text . $end; +} + +sub t2h_default_empty_line($$) +{ + my $text = shift; + my $state = shift; + #ignore the line if it just follows a deff + return '' if ($state->{'deff_line'}); + return $text; +} + +sub t2h_default_unknown($$$$$) +{ + my $macro = shift; + my $line = shift; + my $pass = shift; + my $stack = shift; + my $state = shift; + + my ($result_line, $result, $result_text, $message); + return ($line, 0, undef, undef); +} + +sub t2h_default_unknown_style($$$$$) +{ + my $command = shift; + my $text = shift; + my $state = shift; + my $no_close = shift; + my $no_open = shift; + + my ($result, $result_text, $message); + return (0, undef, undef); +} + +sub t2h_default_caption_shortcaption($) +{ + my $float = shift; + my $caption_lines; + my $shortcaption_lines; + my $style = $float->{'style_texi'}; + if (defined($float->{'nr'})) + { + my $nr = $float->{'nr'}; + if ($style ne '') + { + $style = gdt('{style} {number}', { 'style' => $style, 'number' => $nr}); + } + else + { + $style = $nr; + } + } + my $empty_caption = 1; + if (defined($float->{'caption_texi'}) and @{$float->{'caption_texi'}}) + { + @$caption_lines = @{$float->{'caption_texi'}}; + $caption_lines->[0] =~ s/^\s*//; + if ($caption_lines->[0] =~ /\S/ or @$caption_lines > 2) + { + $empty_caption = 0; + } + } + + if (!$empty_caption) + { + if (defined($style)) + { + $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . gdt('{style}: {caption_first_line}', { 'style' => $style, 'caption_first_line' => $caption_lines->[0] }); + } + else + { + $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $caption_lines->[0]; + } + push @$caption_lines, "}\n"; + } + elsif (defined($style)) + { + $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $style . '}' . "\n"; + } + + my $empty_shortcaption = 1; + if (defined($float->{'shortcaption_texi'}) and @{$float->{'shortcaption_texi'}}) + { + @$shortcaption_lines = @{$float->{'shortcaption_texi'}}; + $shortcaption_lines->[0] =~ s/^\s*//; + if ($shortcaption_lines->[0] =~ /\S/ or @$shortcaption_lines > 1) + { + $empty_shortcaption = 0; + } + } + + if (!$empty_shortcaption) + { + if (defined($style)) + { + $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . gdt('{style}: {shortcaption_first_line}', { 'style' => $style, 'shortcaption_first_line' => $shortcaption_lines->[0] }); + } + else + { + $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $shortcaption_lines->[0]; + } + push @$shortcaption_lines, "}\n"; + } + elsif (defined($style)) + { + $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $style . '}' . "\n"; + } + return ($caption_lines, $shortcaption_lines); +} + +# everything is done in &$float +sub t2h_default_caption_shortcaption_command($$$$) +{ + my $command = shift; + my $text = shift; + my $texi_lines = shift; + my $float_element = shift; + return ''; +} + +sub t2h_default_float($$$$$) +{ + my $text = shift; + my $float = shift; + my $caption = shift; + my $shortcaption = shift; + + my $label = ''; + if (exists($float->{'id'})) + { + $label = &$anchor($float->{'id'}); + } + my $caption_text = ''; + + if (defined($float->{'caption_texi'})) + { + $caption_text = $caption; + } + elsif (defined($float->{'shortcaption_texi'})) + { + $caption_text = $shortcaption; + } + elsif (defined($caption)) + { + $caption_text = $caption; + } + + return $text . "\n" . $caption_text; +} + +sub t2h_default_listoffloats_style($) +{ + my $style_texi = shift; + return ($style_texi); +} + +sub t2h_default_listoffloats_float_style($$) +{ + my $style_texi = shift; + my $float = shift; + + my $style = $float->{'style_texi'}; + #print STDERR "listoffloat/float style mismatch $style_texi $style\n" if ($style_texi ne $style); + if (defined($float->{'nr'})) + { + my $nr = $float->{'nr'}; + if ($style ne '') + { + $style = gdt('{style} {number}', { 'style' => $style, 'number' => $nr}); + } + else + { + $style = $nr; + } + } + return $style; +} + +sub t2h_default_listoffloats_caption($) +{ + my $float = shift; + if (defined($float->{'shortcaption_texi'})) + { + return ([ @{$float->{'shortcaption_texi'}} ], 'shortcaption'); + } + elsif (defined($float->{'caption_texi'})) + { + return ([ @{$float->{'caption_texi'}} ], 'caption'); + } + return ([ ], undef); +} + +sub t2h_default_listoffloats_entry($$$$) +{ + my $style_texi = shift; + my $float = shift; + my $float_style = shift; + my $caption = shift; + my $href = shift; + + my @lines = split /^/, $caption; + $caption = $lines[0]; + $caption = '' if (!defined($caption)); + chomp ($caption); + + $caption = $float->{'text'} if ($caption eq '' and defined($float->{'text'}) and $float->{'text'} =~ /\S/); + + return "* $float_style: ${caption}\n"; +} + +sub t2h_default_listoffloats($$$) +{ + my $style_texi = shift; + my $style = shift; + my $float_entries = shift; + + my $result = "* List of $style:\n"; + foreach my $float_entry (@$float_entries) + { + $result .= $float_entry; + } + return $result . "\n"; +} + +sub t2h_default_insertcopying($$$) +{ + my $text = shift; + my $comment = shift; + my $simple_text = shift; + return $text; +} + +sub t2h_default_protect_text($) +{ + my $text = shift; + return $text; +} + +# This function is used to protect characters which are special in xml +# in inline text: &, ", <, and >. +# +# argument: +# text to be protected +sub xml_default_protect_text($) +{ + my $text = shift; + $text =~ s/&/&/g; + $text =~ s/</</g; + $text =~ s/>/>/g; + $text =~ s/\"/"/g; + return $text; +} + +sub in_cmd($$) +{ + my $style_stack = shift; + my $command = shift; + my $result = 0; + if ($style_stack and scalar(@{$style_stack})) + { + my $level = $#$style_stack; + #print STDERR ":::$level ::@{$style_stack}\n"; + while ($level >= 0) + { + if ($style_stack->[$level] eq $command) + { + $result = 1; + last; + } + $level--; + } + } + return $result; +} +# +# + +sub in_small_caps($) +{ + my $style_stack = shift; + my $in_sc = 0; + if ($style_stack and scalar(@{$style_stack})) + { + my $level = $#$style_stack; + #print STDERR ":::$level ::@{$style_stack}\n"; + while ($level >= 0) + { + if ($style_stack->[$level] eq 'sc') + { + $in_sc = 1; + last; + } + $level--; + } + } + return $in_sc; +} +# +# +sub t2h_default_normal_text($$$$$$$;$) +{ + my @initial_args = @_; + my $text = shift; + my $in_raw_text = shift; # remove_texi + my $in_preformatted = shift; + my $in_code = shift; + my $in_math = shift; + my $in_simple = shift; + my $style_stack = shift; + my $state = shift; + + # like utf8.init + if ($ENABLE_ENCODING and !$ENABLE_ENCODING_USE_ENTITY and defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and $Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8' and $USE_UNICODE) + { + return &t2h_utf8_normal_text(@initial_args); + } + + $text = uc($text) if (in_cmd($style_stack, 'sc')); + if (! $in_code and !$in_preformatted) + { + $text =~ s/---/\x{1F}/g; + $text =~ s/--/-/g; + $text =~ s/\x{1F}/--/g; + $text =~ s/``/"/g; + $text =~ s/\'\'/"/g; + } + else + { + # to be like tex. This would be wrong, however. +# my $special_code = 0; +# $special_code = 1 if (in_cmd($style_stack, 'code') or +# in_cmd($style_stack, 'example') or in_cmd($style_stack, 'verbatim')); +# $text =~ s/'/\&rsquo\;/g unless ($special_code and exists($main::value{'txicodequoteundirected'})); +# $text =~ s/`/\&lsquo\;/g unless ($special_code and exists($main::value{'txicodequotebacktick'})); + } + $text = t2h_text_substitutions($text, $in_raw_text, ($in_preformatted or $in_code), $in_simple); + return $text; +} + +sub t2h_default_url_and_text($;$) +{ + my $url = shift; + my $text = shift; + if (!defined($text) or $text eq '') + { + return "<$url>" if (defined($url) and $url ne ''); + return ''; + } + else + { + return $text if (!defined($url) or $url eq ''); + return "$text <$url>"; + } +} + +# This function produces an anchor. This need is quite html specific. +# +# arguments: +# $name : anchor name +# $href : anchor href +# text : text displayed +# extra_attribs : added to anchor attributes list +sub t2h_default_anchor($;$$$) +{ + my $name = shift; + my $href = shift; + my $text = shift; + my $attributes = shift; + return $text if (defined($text)); + return ''; +} + +# This function is used to format the text associated with a @deff/@end deff +# +# argument: +# text +# +# $DEF_TABLE should be used to distinguish between @def formatted as table +# and as definition lists. +sub t2h_default_def_item($$$) +{ + my $text = shift; + my $only_inter_item_commands = shift; + my $command = shift; + if ($text =~ /\S/) + { + return $text; + } + return ''; +} + +sub t2h_default_definition_category($$$$) +{ + my $name = shift; + my $class = shift; + my $style = shift; + my $command = shift; + return ($name) if (!defined($class) or $class =~ /^\s*$/); + if ($style eq 'f') + { + return gdt('{name} on {class}', { 'name' => $name, 'class' => $class }); + } + elsif ($style eq 'v') + { + return gdt('{name} of {class}', { 'name' => $name, 'class' => $class }); + } + else + { + return $name; + } +} + +sub t2h_default_definition_index_entry($$$$) +{ + my $name = shift; + my $class = shift; + my $style = shift; + my $command = shift; + return ($name) if (!defined($class) or $class =~ /^\s*$/); + if ($style eq 'f') + { + return gdt('{name} on {class}', { 'name' => $name, 'class' => $class }); + } + elsif ($style eq 'v' and $command ne 'defcv') + { + return gdt('{name} of {class}', { 'name' => $name, 'class' => $class }); + } + else + { + return $name; + } +} + +sub t2h_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 ''; +} + + +# format the container for the @deffn line and text +# +# argument +# text of the whole @def, line and associated text. +# +# $DEF_TABLE should be used. +sub t2h_default_def($$) +{ + my $text = shift; + my $command = shift; + if ($text =~ /\S/) + { + return $text; + } + return ''; + +} + +# a whole menu +# +# argument: +# the whole menu text (entries and menu comments) +# +# argument: +# whole menu text. +# not used since menu is a normal preformatted command with SIMPLE_MENU +sub t2h_default_menu_command($$$) +{ + my $format = shift; + my $text = shift; + my $in_preformatted = shift; + return "* Menu:\n".$text."\n"; + +} + +# formats a menu entry link pointing to a node or section +# +# arguments: +# the entry text +# the state, a hash reference holding informations about the context, with a +# usefull entry, 'preformatted', true if we are in a preformatted format +# (a format keeping space between words). In that case a function +# of the main program, main::do_preformatted($text, $state) might +# be used to format the text with the current format style. +# href is optionnal. It is the reference to the section or the node anchor +# which should be used to make the link (typically it is the argument +# of a href= attribute in a <a> element). +sub t2h_default_menu_link($$$$$$$$) +{ + my $entry = shift; + my $state = shift; + my $href = shift; + my $node = shift; + my $title = shift; + my $ending = shift; + my $has_title = shift; + my $command_stack = shift; + my $preformatted = shift; + + $title = '' unless ($has_title); + $title .= ':' if ($title ne ''); + return "$MENU_SYMBOL$title$node$ending" if ($NODE_NAME_IN_MENU); + return "$MENU_SYMBOL$title$entry$ending"; +} + +# formats a menu entry description, ie the text appearing after the node +# specification in a menu entry an spanning until there is another +# menu entry, an empty line or some text at the very beginning of the line +# (we consider that text at the beginning of the line begins a menu comment) +# +# arguments: +# the description text +# the state. See menu_entry. +# the heading of the element associated with the node. +# not usd since in SIMPLE_MENU +sub t2h_default_menu_description($$$$) +{ + my $text = shift; + my $state = shift; + my $element_text = shift; + my $command_stack = shift; + my $preformatted = shift; + + return $text; +} + +%htmlxref_entries = ( + 'node' => [ 'node', 'section', 'chapter', 'mono' ], + 'section' => [ 'section', 'chapter','node', 'mono' ], + 'chapter' => [ 'chapter', 'section', 'node', 'mono' ], + 'mono' => [ 'mono', 'chapter', 'section', 'node' ], +); + + +# Construct a href to an external source of information. +# node is the node with texinfo @-commands +# node_id is the node transliterated and transformed as explained in the +# texinfo manual +# node_xhtml_id is the node transformed such that it is unique and can +# be used to make an html cross ref as explained in the texinfo manual +# file is the file in '(file)node' +# This is used to construct href, so is likely to be ignored oustside of +# html. +sub t2h_default_external_href($$$) +{ + my $node = shift; + my $node_id = shift; + my $node_xhtml_id = shift; + my $file = shift; + $file = '' if (!defined($file)); + my $default_target_split = $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'}; + my $target_split; + #my $target_mono; + #my $href_split; + #my $href_mono; + if ($file ne '') + { + if ($NEW_CROSSREF_STYLE) + { + $file =~ s/\.[^\.]*$//; + $file =~ s/^.*\///; + my $href; + my $document_split = get_conf('SPLIT'); + $document_split = 'mono' if (!$document_split); + my $split_found; + if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file})) + { + foreach my $split_ordered (@{$htmlxref_entries{$document_split}}) + { + if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}->{$split_ordered})) + { + $split_found = $split_ordered; + $href = $Texi2HTML::THISDOC{'htmlxref'}->{$file}->{$split_ordered}->{'href'}; + last; + } + } + } + if (defined($split_found)) + { + $target_split = 1 unless ($split_found eq 'mono'); + } + else + { # nothing specified for that manual, use default + $target_split = $default_target_split; + } + + if ($target_split) + { + if (defined($href)) + { + $file = $href; + } + elsif (defined($EXTERNAL_DIR)) + { + $file = "$EXTERNAL_DIR/$file"; + } + elsif (get_conf('SPLIT')) + { + $file = "../$file"; + } + $file .= "/"; + } + else + {# target not split + if (defined($href)) + { + $file = $href; + } + else + { + if (defined($EXTERNAL_DIR)) + { + $file = "$EXTERNAL_DIR/$file"; + } + elsif (get_conf('SPLIT')) + { + $file = "../$file"; + } + $file .= "." . $NODE_FILE_EXTENSION; + } + } + } + else + { + $file .= "/"; + if (defined($EXTERNAL_DIR)) + { + $file = $EXTERNAL_DIR . $file; + } + else + { + $file = '../' . $file; + } + } + } + else + { + $target_split = $default_target_split; + } + if ($node eq '') + { + if ($NEW_CROSSREF_STYLE) + { + if ($target_split) + { + if (defined($TOP_NODE_FILE_TARGET)) + { + return $file . $TOP_NODE_FILE_TARGET . '.' . $NODE_FILE_EXTENSION . '#Top'; + } + else + { + return $file . '#Top'; + } + } + else + { + return $file . '#Top'; + } + } + else + { + return $file; + } + } + my $target; + if ($NEW_CROSSREF_STYLE) + { + $node = $node_id; + $target = $node_xhtml_id; + } + else + { + $node = main::remove_texi($node); + $node =~ s/[^\w\.\-]/-/g; + } + my $file_basename = $node; + $file_basename = $TOP_NODE_FILE_TARGET if ($node =~ /^top$/i and defined($TOP_NODE_FILE_TARGET)); + if ($NEW_CROSSREF_STYLE) + { + if ($target_split) + { + return $file . $file_basename . ".$NODE_FILE_EXTENSION" . '#' . $target; + } + else + { + return $file . '#' . $target; + } + } + else + { + return $file . $file_basename . ".$NODE_FILE_EXTENSION"; + } +} + +# format a reference external to the generated manual. This produces a full +# reference with introductive words and the reference itself. +# +# arguments: +# type of the reference: xref (reference at the beginning of a sentence), +# pxref (reference in a parenthesis), +# section in the book. This might be undef. +# book name. +# manual file name +# href linking to the html page containing the referenced node. A typical +# use for this href is a href attribute in an <a> element +# cross reference name +# array of texi arguments of the reference +# array of the formatted arguments of the reference +# node name +sub t2h_default_external_ref($$$$$$$$$) +{ + my $type = shift; + my $section = shift; + my $book = shift; + my $file = shift; + #my $file_node = shift; + my $href = shift; + my $cross_ref = shift; + my $args_texi = shift; + my $formatted_args = shift; + my $node = shift; + + my $name = $section; + $name = $cross_ref if ($name eq ''); + $name = $node if ($name eq ''); + + my $reference = $name; + + if ($book eq '' and $file ne '') + { + $name = "($file)$name"; + } + $reference = &$anchor('', $href, $name) if ($href ne ''); + + # Yes, this is ugly, yet this helps internationalization + if ($type eq 'pxref') + { + if (($book ne '') and ($href ne '')) + { + return gdt('see {reference} in @cite{{book}}', { 'reference' => $reference, 'book' => $book },{'duplicate'=>1}); + } + elsif (($book ne '') and ($reference ne '')) + { + return gdt('see `{section}\' in @cite{{book}}', { 'section' => $reference, 'book' => $book },{'duplicate'=>1}); + } + elsif ($book ne '') + { # should seldom or even never happen + return gdt('see @cite{{book}}', { 'book' => $book },{'duplicate'=>1}); + } + elsif ($href ne '') + { + return gdt('see {reference}', { 'reference' => $reference },{'duplicate'=>1}); + } + elsif ($reference ne '') + { + return gdt('see `{section}\'', { 'section' => $reference },{'duplicate'=>1}); + } + } + if ($type eq 'xref' or $type eq 'inforef') + { + if (($book ne '') and ($href ne '')) + { + return gdt('See {reference} in @cite{{book}}', { 'reference' => $reference, 'book' => $book },{'duplicate'=>1}); + } + elsif (($book ne '') and ($reference ne '')) + { + return gdt('See `{section}\' in @cite{{book}}', { 'section' => $reference, 'book' => $book },{'duplicate'=>1}); + } + elsif ($book ne '') + { # should seldom or even never happen + return gdt('See @cite{{book}}', { 'book' => $book },{'duplicate'=>1}); + } + elsif ($href ne '') + { + return gdt('See {reference}', { 'reference' => $reference },{'duplicate'=>1}); + } + elsif ($reference ne '') + { + return gdt('See `{section}\'', { 'section' => $reference },{'duplicate'=>1}); + } + } + if ($type eq 'ref') + { + if (($book ne '') and ($href ne '')) + { + return gdt('{reference} in @cite{{book}}', { 'reference' => $reference, 'book' => $book },{'duplicate'=>1}); + } + elsif (($book ne '') and ($reference ne '')) + { + return gdt('`{section}\' in @cite{{book}}', { 'section' => $reference, 'book' => $book },{'duplicate'=>1}); + } + elsif ($book ne '') + { # should seldom or even never happen + return gdt('@cite{{book}}', { 'book' => $book },{'duplicate'=>1}); + } + elsif ($href ne '') + { + return gdt('{reference}', { 'reference' => $reference },{'duplicate'=>1}); + } + elsif ($reference ne '') + { + return gdt('`{section}\'', { 'section' => $reference },{'duplicate'=>1}); + } + } + return ''; +} + +# format a reference to a node or a section in the generated manual. This +# produces a full reference with introductive words and the reference itself. +# +# arguments: +# type of the reference: xref (reference at the beginning of a sentence), +# pxref (reference in a parenthesis), +# href linking to the html page containing the node or the section. A typical +# use for this href is a href attribute in an <a> element +# short name for this reference +# name for this reference +# boolean true if the reference is a reference to a section +# +# $SHORT_REF should be used. +sub t2h_default_internal_ref($$$$$$$$) +{ + my $type = shift; + my $href = shift; + my $short_name = shift; + my $name = shift; + my $is_section = shift; + my $args_texi = shift; + my $formatted_args = shift; + my $element = shift; + + if (! $SHORT_REF) + { + $name = &$anchor('', $href, $name); + if ($type eq 'pxref') + { + return gdt('see section {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section); + return gdt('see {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); + } + elsif ($type eq 'xref' or $type eq 'inforef') + { + return gdt('See section {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section); + return gdt('See {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); + } + elsif ($type eq 'ref') + { + return gdt('{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); + } + } + else + { + $name = &$anchor('', $href, $short_name); + if ($type eq 'pxref') + { + return gdt('see {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); + } + elsif ($type eq 'xref' or $type eq 'inforef') + { + return gdt('See {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); + } + elsif ($type eq 'ref') + { + return gdt('{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); + } + } + return ''; +} + +# text after @item in table, vtable and ftable +sub t2h_default_table_item($$$$$$$) +{ + my $text = shift; + my $index_label = shift; + my $format = shift; + my $command = shift; + my $style_stack = shift; + my $item_cmd = shift; + my $formatted_index_entry = shift; + + return $text . "\n"; +} + +# format text on the line following the @item line (in table, vtable and ftable) +sub t2h_default_table_line($$$) +{ + my $text = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + if ($text =~ /\S/) + { + return $text; + } + return ''; +} + +#my $cell_nr = -1; + +# row in multitable +sub t2h_default_row($$$$$$$$) +{ + my $text = shift; + my $macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + if ($text =~ /\S/) + { + return $text ."\n"; + } + return ''; +} + +# cell in multitable +sub t2h_default_cell($$$$$$$$) +{ + my $text = shift; + my $row_macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + $text =~ s/^\s*//; + $text =~ s/\s*$//; + + return " $text"; +} + +# format an itemize, enumerate or @*table @item line, returning +# a texinfo line. +sub t2h_default_format_list_item_texi($$$$$) +{ + my $format = shift; + my $line = shift; + my $prepended = shift; + my $command = shift; + my $number = shift; + + my $result_line; + my $open_command = 0; + + $command = 'bullet' if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize'); + $prepended = "\@$command\{\}" if (defined($command) and $command ne ''); + $prepended = "$number." if (defined($number) and $number ne ''); + + if (defined($command) and $command ne '' and $format ne 'itemize') + { + #@*table + $open_command = 1; + $line =~ s/^\s*//; + $line =~ s/\s*$//; + if (exists ($style_map{$command})) + { + $result_line = "\@$command\{$line\}\n"; + } + elsif (exists ($things_map{$command})) + { + $result_line = "\@$command\{\} $line\n"; + } + else + { + $result_line = "\@$command $line\n"; + } + } + elsif (defined($prepended) and $prepended ne '') + { + $prepended =~ s/^\s*//; + $prepended =~ s/\s*$//; + $line =~ s/^\s*//; + $result_line = $prepended . ' ' . $line; + } + return ($result_line, $open_command); +} + + +# format an item in a list +# +# argument: +# text of the item +# format of the list (itemize or enumerate) +# command passed as argument to the format +# formatted_command leading command formatted, if it is a thing command +sub t2h_default_list_item($$$$$$$$$$$$) +{ + my $text = shift; + my $format = shift; + my $command = shift; + my $formatted_command = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $prepended = shift; + my $prepended_formatted = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + my $item_command = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + if ($text =~ /\S/) + { + return $text; + } + return ''; +} + +sub t2h_default_table_list($$$$$$$$$) +{ + my $format_command = shift; + my $text = shift; + my $command = shift; + my $formatted_command = shift; +# enumerate + my $item_nr = shift; + my $enumerate_style = shift; +# itemize + my $prepended = shift; + my $prepended_formatted = shift; +# multitable + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; +# my $number = shift; + return $text; +} + +# an comment +sub t2h_default_comment($) +{ + my $text = shift; + return ''; +} + +# an xml comment +sub xml_default_comment($) +{ + my $text = shift; + $text =~ s/--+/-/go; + return '<!-- ' . $text . ' -->' . "\n"; +} + +sub t2h_collect_styles($) +{ + my $cmd_stack = shift; + my @result = (); + foreach my $style (reverse(@$cmd_stack)) + { +# last unless (defined($command_type{$style}) and $command_type{$style} eq 'style'); + push @result, $style if (defined($command_type{$style}) and $command_type{$style} eq 'style'); + } + return @result; +} + +sub html_default_parse_attribute($) +{ + my $element = shift; + return ('', '', '') if (!defined($element)); + my ($class, $attributes) = ('', ''); + if ($element =~ /^(\w+)(\s+.*)/) + { + $element = $1; + $attributes = $2; + if ($attributes =~ s/^\s+class=\"([^\"]+)\"//) + { + $class = $1; + } + } + return ($element, $class, $attributes); +} + +sub t2h_get_attribute($;$) +{ + my $command = shift; + my $map_ref = shift; + $map_ref = \%style_map if (!defined($map_ref)); + return unless (defined($map_ref->{$command})); + my ($element, $class, $attributes) = ('', '', ''); + if (defined($map_ref->{$command})) + { + if (ref($map_ref->{$command}) eq 'HASH') + { + ($element, $class, $attributes) = t2h_html_parse_attribute ($map_ref->{$command}->{'attribute'}); + } + elsif ($map_ref->{$command} !~ /^&/) + { + $element = $map_ref->{$command}; + $element =~ s/^\"//; + } + } + return ($element, $class, $attributes); +} + +# a paragraph +# arguments: +# $text of the paragraph +# $align for the alignement +# $indent for the indent style (indent or noindent) +# The following is usefull if the paragraph is in an itemize. +# $paragraph_command is the leading formatting command (like @minus) +# $paragraph_command_formatted is the leading formatting command formatted +# $paragraph_number is a reference on the number of paragraphs appearing +# in the format. The value should be increased if a paragraph is done +# $format is the format name (@itemize) +sub t2h_default_paragraph($$$$$$$$$$$$) +{ + my $text = shift; + my $align = shift; + my $indent = shift; + my $paragraph_command = shift; + my $paragraph_command_formatted = shift; + my $paragraph_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; +#print STDERR "format: $format\n" if (defined($format)); +#print STDERR "paragraph @$command_stack_at_end; @$command_stack_at_begin\n"; +# $paragraph_command_formatted = '' if (!defined($paragraph_command_formatted) or +# exists($special_list_commands{$format}->{$paragraph_command})); + return '' if ($text =~ /^\s*$/); + + return $text; +} + +# a preformatted region +# arguments: +# $text of the preformatted region +# $pre_style css style +# $class identifier for the preformatted region (example, menu-comment) +# The following is usefull if the preformatted is in an itemize. +# $leading_command is the leading formatting command (like @minus) +# $leading_command_formatted is the leading formatting command formatted +# $preformatted_number is a reference on the number of preformatteds appearing +# in the format. The value should be increased if a preformatted is done +sub t2h_default_preformatted($$$$$$$$$$$$) +{ + my $text = shift; + my $pre_style = shift; + my $class = shift; + my $leading_command = shift; + my $leading_command_formatted = shift; + my $preformatted_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + +#print STDERR "preformatted @$command_stack_at_end; @$command_stack_at_begin\n"; + return '' if ($text eq ''); + + my $top_stack = ''; + $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); + if ($top_stack eq 'multitable') + { + $text =~ s/^\s*//; + $text =~ s/\s*$//; + } + + # add a new line at the end in case there is none + chomp($text); + return $text . "\n"; +} + +# $new_element is set if the element is associated with a different +# reference element than the preceding element. This is where we +# do the navigation. For example it could be a @node before a @section. +# +# The heading function is always called, though -- in the default case +# nodes don't lead to an outputted title. +sub t2h_default_element_heading($$$$$$$$$$$$) +{ + my $element = shift; + my $command = shift; + my $texi_line = shift; + my $line = shift; + my $in_preformatted = shift; + my $one_section = shift; + my $element_heading = shift; + my $first_in_page = shift; + my $is_top = shift; + my $previous_is_top = shift; + my $command_line = shift; + my $element_id = shift; + my $new_element = shift; +#print STDERR ":::::::: $element $command i_p $in_preformatted o_s $one_section e_h $element_heading f_p $first_in_page i_t $is_top p_i_t $previous_is_top id $element_id new $new_element\n"; + +# my $result = ''; + my $result = &$element_label($element_id, $element, $command, $command_line); + + # in default case, print_head_navigation and print_navigation are no-ops. + # and $print_element_header is undef, so the following nothing. + if ($new_element and !$one_section) + { + main::msg_debug ("For $element->{'texi'}, element_ref not defined", $element->{'line_nr'}) if (!defined($element->{'element_ref'})); + if (!defined($element->{'element_ref'}->{'top'})) + { + if (defined($print_element_header)) + { # FIXME backward compatibility, print_element_header is obsoleted in nov 2009 + $result .= &$print_element_header($first_in_page, $previous_is_top); + } + else + { + if (($first_in_page or $previous_is_top) and get_conf('headers')) + { + $result .= &$print_head_navigation(undef, \@SECTION_BUTTONS, $first_in_page, $previous_is_top, $element); + } + else + { # got to do this here, as it isn't done otherwise sinc + # print_head_navigation is not called + $result .= &$print_navigation(\@SECTION_BUTTONS) if (get_conf('headers') or get_conf('SPLIT') eq 'node'); + } + } + } + else + { # this is here because we want to always print the head navigation for top + # and use TOP_BUTTONS + $result .= &$print_head_navigation(undef, \@TOP_BUTTONS, $first_in_page, $previous_is_top, $element) + if (get_conf('SPLIT') or get_conf('headers')); + } + } + return $result. &$heading($element, $command, $texi_line, $line, $in_preformatted, $one_section, $element_heading); +} + +# This function formats a heading for an element +# +# argument: +# an element. It is a hash reference for a node or a sectioning command. +# it may be the wrong one in case of headings. +# The interesting keys are: +# 'text': the heading text +# 'text_nonumber': the heading text without section number +# 'node': true if it is a node +# 'level': level of the element. 0 for @top, 1 for chapter, heading, +# appendix..., 2 for section and so on... +# 'tag_level': the sectioning element name, raisesections and lowersections +# taken into account +sub t2h_default_heading($$$$$;$$) +{ + my $element = shift; + my $command = shift; + my $texi_line = shift; + my $line = shift; + my $in_preformatted = shift; + my $one_section = shift; + my $element_heading = shift; + + my $level = $element->{'level'}; + if ($element->{'node'}) + { + if ($element->{'text'} =~ /^top$/i) + { + $level = 0; + } + else + { + $level = 3; + } + return '' if (!$element->{'this'} or $element->{'with_section'}) + } + else + { + $command = $element->{'tag_level'}; + } + my $text = $element->{'text'}; + + if ($TOC_LINKS and $command !~ /heading/ and defined($element->{'tocid'})) + { + $text = &$anchor ('', "$Texi2HTML::THISDOC{'toc_file'}#$element->{'tocid'}", $text); + } + + my $result; + if ($in_preformatted) + { + $result = &$heading_text_preformatted("\@$command", $text, $level); + } + else + { + $result = &$heading_text("\@$command", $text, $level); + } + #$result .= "\n"; + return $result; +} + +sub t2h_default_heading_no_texi($$$) +{ + my $element = shift; + my $command = shift; + my $line = shift; + return main::remove_texi($line) . "\n"; +} + +# formatting of raw regions +# if L2H is true another mechanism is used for tex +sub t2h_default_raw($$;$) +{ + my $style = shift; + my $text = shift; + my $line_nr = shift; + my $expanded = 1 if (grep {$style eq $_} @EXPAND); + if ($style eq 'verbatim' or $style eq 'verbatiminclude' or ($style eq 'tex' and $expanded)) + { + return $text; + } + elsif ($expanded) + { + main::line_warn (sprintf(__("Raw format %s is not converted"), $style), $line_nr); + return $text; + } + else + { + return ''; + } +} + +# raw environment when removing texi (in comments) +sub t2h_default_raw_no_texi($$) +{ + my $style = shift; + my $text = shift; + if ($style eq 'verbatim' or $style eq 'verbatiminclude' or grep {$style eq $_} @EXPAND) + { + return $text; + } + return ''; +} + +# This function formats a footnote reference and the footnote text associated +# with a given footnote. +# The footnote reference is the text appearing in the main document pointing +# to the footnote text. +# +# arguments: +# absolute number of the footnote (in the document) +# relative number of the footnote (in the page) +# identifier for the footnote +# identifier for the footnote reference in the main document +# main document file +# footnote text file +# array with the footnote text lines +# the state. See menu entry. +# +# returns: +# reference on an array containing the footnote text lines which should +# have been updated +# the text for the reference pointing on the footnote text +sub t2h_default_foot_line_and_ref($$$$$$$$$) +{ + my $number_in_doc = shift; + my $number_in_page = shift; + my $footnote_id = shift; + my $place_id = shift; + my $document_file = shift; + my $footnote_file = shift; + my $lines = shift; + my $document_state = shift; + + $number_in_doc = $NO_NUMBER_FOOTNOTE_SYMBOL if (!$NUMBER_FOOTNOTES); + + if ($document_file eq $footnote_file) + { + $document_file = $footnote_file = ''; + } + unshift (@$lines, "($number_in_doc)\n"); + push @$lines, "\n"; + return ($lines, "($number_in_doc)"); +} + +# formats a group of footnotes. +# +# argument: +# array reference on the footnotes texts lines +# +# returns an array reference on the group of footnotes lines +sub t2h_default_foot_section($) +{ + my $lines = shift; + my $header = &$heading_text('footnotes', gdt('Footnotes'), 3); + unshift (@$lines, "$header\n"); + return $lines; +} + +sub t2h_default_image_files($$$$) +{ + my $base = shift; + my $extension = shift; + my $texi_base = shift; + my $texi_extension = shift; + my @files = (); + return @files if (!defined($base) or ($base eq '')); + if (defined($extension) and ($extension ne '')) + { + push @files,["$base.$extension", "$texi_base.$texi_extension"]; + } + foreach my $ext (@IMAGE_EXTENSIONS) + { + push @files,["$base.$ext", "$texi_base.$ext"]; + } + return @files; +} + +# format an image +# +# arguments: +# image file name with path +# image basename +# a boolean true if we are in a preformatted format +# image file name without path +# alt text +# width +# height +# raw alt +# extension +# path to working dir +# path to file relative from working dir +sub t2h_default_image($$$$$$$$$$$$$$$$$) +{ + my $file = shift; + my $base = shift; + my $preformatted = shift; + my $file_name = shift; + my $alt = shift; + my $width = shift; + my $height = shift; + my $raw_alt = shift; + my $extension = shift; + my $working_dir = shift; + my $file_path = shift; + my $in_paragraph = shift; + my $file_locations = shift; + my $base_simple_format = shift; + my $extension_simple_format = shift; + my $file_name_simple_format = shift; + my $line_nr = shift; + + if (!defined($file_path) or $file_path eq '') + { + if (defined($extension) and $extension ne '') + { + $file = "$base.$extension"; + } + else + { + $file = "$base.txt"; + } + } + elsif (! $COMPLETE_IMAGE_PATHS) + { + $file = $file_name; + } + my $alt_txt = ''; + $alt_txt = ": $alt" if (defined($alt) and $alt =~ /\S/); + return "[ $file$alt_txt ]"; + # it is possible that $file_name is more correct as it allows the user + # to chose the relative path. +} + +# address put in footer describing when was generated and who did the manual +# not used anymore +sub t2h_default_address($) +{ + my $date = shift; + $date = '' if (!defined($date)); + if ($date ne '') + { + return gdt('on @emph{{date}}', { 'date' => $date }); + } + return ''; +} + +# format a target in the main document for an index entry. +# +# arguments: +# target identifier +# boolean true if in preformatted format +sub t2h_default_index_entry_label($$$$$$$$$) +{ + my $identifier = shift; + my $preformatted = shift; + my $entry = shift; + my $index_name = shift; + my $index_command = shift; + my $texi_entry = shift; + my $formatted_entry = shift; + my $in_region_not_in_output = shift; + my $index_entry_ref = shift; + + return '' if (!defined($identifier) or ($identifier !~ /\S/)); + my $label = &$anchor($identifier); + return $label; +} + +sub t2h_default_index_entry_command($$$$$$) +{ + my $command = shift; + my $index_name = shift; + my $label = shift; + my $entry_texi = shift; + my $entry_formatted = shift; + my $index_entry_ref = shift; + + return $label; +} + +# process definition commands line @deffn for example +sub t2h_default_def_line($$$$$$$$$$$$$$$$) +{ + my $category_prepared = shift; + my $name = shift; + my $type = shift; + my $arguments = shift; + my $index_label = shift; + my $arguments_array = shift; + my $arguments_type_array = shift; + my $unformatted_arguments_array = shift; + my $command = shift; + my $class_name = shift; + my $category = shift; + my $class = shift; + my $style = shift; + my $original_command = shift; + + $name = '' if (!defined($name) or ($name =~ /^\s*$/)); + $type = '' if (!defined($type) or $type =~ /^\s*$/); + $arguments = '' if (!defined($arguments) or $arguments =~ /^\s*$/); + + my $type_name = ''; + $type_name .= "$type " if ($type ne ''); + $type_name .= $name if ($name ne ''); + + my $result = " -- $category_prepared: ${type_name}$arguments"; + $result =~ s/\s*$//; + $result .= "\n"; + +} + +# process definition commands line @deffn for example while removing texi +# commands +sub t2h_default_def_line_no_texi($$$$$) +{ + my $category = shift; + my $name = shift; + my $type = shift; + my $arguments = shift; + $name = '' if (!defined($name) or ($name =~ /^\s*$/)); + $type = '' if (!defined($type) or $type =~ /^\s*$/); + if (!defined($arguments) or $arguments =~ /^\s*$/) + { + $arguments = ''; + } + my $type_name = ''; + $type_name = " $type" if ($type ne ''); + $type_name .= ' ' . $name if ($name ne ''); + $type_name .= $arguments; + if (! $DEF_TABLE) + { + return $category . ':' . $type_name . "\n"; + } + else + { + + return $type_name . " " . $category . "\n"; + } +} + +# a cartouche +sub t2h_default_cartouche($$) +{ + my $text = shift; + + if ($text =~ /\S/) + { + return $text; + } + return ''; +} + +my $IDXFILE; +# key: +# origin_href: +# entry: +# texi entry: +# element_href: +# element_text: +sub t2h_default_index_summary_file_entry ($$$$$$$$$) +{ + my $index_name = shift; + my $key = shift; + my $origin_href = shift; + my $entry = shift; + my $texi_entry = shift; + my $element_href = shift; + my $element_text = shift; + my $is_printed = shift; + my $manual_name = shift; + + $element_text = 'UNDEF' if (!defined($element_text)); + print $IDXFILE "key: $key\n origin_href: $origin_href\n entry: $entry\n" + . " texi_entry: $texi_entry\n" + . " element_href: $element_href\n element_text: $element_text\n"; +} + +sub t2h_default_index_summary_file_begin($$$) +{ + my $name = shift; + my $is_printed = shift; + my $manual_name = shift; + + $IDXFILE = main::open_out("$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx"); + #open(IDXFILE, ">$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx") + # || die "Can't open >$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx for writing: $!\n"; +} + +sub t2h_default_index_summary_file_end($$$) +{ + my $name = shift; + my $is_printed = shift; + my $manual_name = shift; + + close ($IDXFILE); +} + +sub t2h_default_sp($$) +{ + my $number = shift; + my $preformatted = shift; + return "\n" x $number; +} + +sub t2h_default_acronym_like($$$$$$) +{ + my $command = shift; + my $acronym_texi = shift; + my $acronym_text = shift; + my $with_explanation = shift; + my $explanation_lines = shift; + my $explanation_text = shift; + my $explanation_simply_formatted = shift; + + if ($with_explanation) + { + #return "$acronym_text ($explanation_text)"; + return gdt('{acronym_like} ({explanation})', {'acronym_like' => $acronym_text, 'explanation' => $explanation_text},{'duplicate'=>1}); + } + else + { + return "$acronym_text"; + } + +} + +sub t2h_default_quotation_prepend_text($$) +{ + my $command = shift; + my $text = shift; + return undef if (!defined($text) or $text =~ /^$/); + # If there is a @ protecting the end of line the result is, + # after the chomp: + # @b{some text @:} + # It is likely not to be what was intended, but it is certainly right. + # this is tested in formatting/quotation.texi + chomp($text); + return gdt('@b{{quotation_arg}:} ', {'quotation_arg' => $text}, {'keep_texi' => 1}); +} + +sub t2h_default_quotation($$$$$) +{ + my $command = shift; + my $text = shift; + my $argument_text = shift; + my $argument_text_texi = shift; + my $authors = shift; + my $class_text = ''; + # this allows to add an end of line if there was none, which can happen + # if there is an argument to @quotation, but an empty quotation, like + # @quotation something + # @end quotation + chomp($text); + $text .= "\n"; + return $text; +} + +# format the text within a paragraph style format, +# +# argument: +# format name +# text within the format +sub t2h_default_paragraph_style_command($$) +{ + my $format = shift; + my $text = shift; + return $text; +} + +# format a whole index +# +# argument: +# index text +# index name +sub t2h_default_print_index($$) +{ + my $text = shift; + my $name = shift; + return '' if (!defined($text)); + return "* Index:\n" . $text; +} + +# format a letter entry in an index page. The letter entry contains +# the index entries for the words beginning with that letter. It is +# a target for links pointing from the summary of the index. +# +# arguments: +# the letter +# identifier for the letter entry. This should be used to make the target +# identifier +# text of the index entries +sub t2h_default_index_letter($$$) +{ + my $letter = shift; + my $id = shift; + my $text = shift; + return $text; +} + +# format an index entry (in a letter entry). +# +# arguments: +# href to the main text, linking to the place where the index entry appears +# entry text +# href to the main text, linking to the section or node where the index +# entry appears +# section or node heading +sub t2h_default_index_entry($$$$$$$$$$) +{ + my $text_href = shift; + my $entry = shift; + my $element_href = shift; + my $element_text = shift; + my $entry_file = shift; + my $current_element_file = shift; + my $entry_target = shift; + my $entry_element_target = shift; + my $in_region_not_in_output = shift; + my $index_entry_ref = shift; + + return '' if ($in_region_not_in_output); + #!$index_entry_ref->{'seen_in_output'} and defined($index_entry_ref->{'region'})); + $entry = main::substitute_line($index_entry_ref->{'texi'}, "index entry in \@printindex"); + return '' if ($entry =~ /^\s*$/); + + my $real_element_text; + my $element = $index_entry_ref->{'real_element'}; + # in case $element->{'text'} is not defined, it certainly means that we + # are n a special elemet, most likely the virtual element appearing + # before anything else + if (defined($element->{'text'})) + { + my $element_set = 0; + if ($NODE_NAME_IN_INDEX) + { + if ($element->{'node'}) + { + $element_set = 1; + } + elsif ($element->{'with_node'}) + { + $element = $element->{'with_node'}; + $element_set = 1; + } + } + elsif (defined($NODE_NAME_IN_INDEX)) + { + if (!$element->{'node'}) + { + $element_set = 1; + } + elsif ($element->{'with_section'}) + { + $element = $element->{'with_section'}; + $element_set = 1; + } + } + $element = $element->{'element_ref'} if ($element->{'element_ref'} and !$element_set); + $real_element_text = $element->{'text'}; + } + else + { + $real_element_text = gdt('(outside of any element)'); + } + return "* $entry: ".$real_element_text . '.'."\n"; +} + + +sub t2h_default_copying_comment($$$$) +{ + my $copying_lines = shift; + my $copying_text = shift; + my $copying_no_texi = shift; + my $copying_simple_text = shift; + return '' if ($copying_no_texi eq ''); + my $text = &$comment($copying_no_texi); + return $text; +} + +# return value is currently ignored +sub t2h_default_documentdescription($$$$) +{ + my $decription_lines = shift; + my $description_text = shift; + my $description_no_texi = shift; + my $description_simple_text = shift; + + if (defined($DOCUMENT_DESCRIPTION)) + { + $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = $DOCUMENT_DESCRIPTION; + return $DOCUMENT_DESCRIPTION; + } + + #return '' if ($description_no_texi eq ''); + #my @documentdescription = split (/\n/, $description_no_texi); + if ($description_simple_text eq '') + { + $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = undef; + return undef; + } + my @documentdescription = split (/\n/, $description_simple_text); + my $document_description = shift @documentdescription; + chomp $document_description; + foreach my $line (@documentdescription) + { + chomp $line; + $document_description .= ' ' . $line; + } + $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = $document_description; + return $document_description; +} + +# format an index summary. This is a list of letters linking to the letter +# entries. +# +# arguments: +# array reference containing the formatted alphabetical letters +# array reference containing the formatted non lphabetical letters +sub t2h_default_index_summary($$) +{ + my $alpha = shift; + my $nonalpha = shift; + + my $join = ''; + my $nonalpha_text = ''; + my $alpha_text = ''; + return ''; +} + +# return the heading with number texinfo text +# also called for nodes. +sub t2h_default_heading_texi($$$) +{ + my $tag = shift; + my $texi = shift; + my $number = shift; + #$texi = main::trim_around_spaces($texi); + return "$number $texi" if ($NUMBER_SECTIONS and defined($number) and ($number !~ /^\s*$/)) ; + return $texi; +} + +# return the heading texinfo text for split index sections +sub t2h_default_index_element_heading_texi($$$) +{ # FIXME i18n + my $heading_texi = shift; + my $tag = shift; + my $texi = shift; + my $number = shift; + my $first_letter = shift; + my $last_letter = shift; + return "$heading_texi: $first_letter -- $last_letter" if ($last_letter ne $first_letter); + return "$heading_texi: $first_letter"; +} + +sub t2h_default_element_label($$$$) +{ + my $id = shift; + my $element = shift; + my $command = shift; + my $line = shift; + + return &$anchor($id); +} + +sub t2h_default_misc_element_label($$) +{ + my $id = shift; + my $misc_page_name = shift; + return &$anchor($id); +} + +sub t2h_default_anchor_label($$$$) +{ + my $id = shift; + my $anchor_text = shift; + my $anchor_reference = shift; + my $in_special_region = shift; + return &$anchor($id); +} + +sub t2h_default_colon_command($) +{ + my $punctuation_character = shift; + return $colon_command_punctuation_characters{$punctuation_character} if defined($colon_command_punctuation_characters{$punctuation_character}); + return $punctuation_character; +} + +# called each time a @tab or an @itemx is encountered. +# To be noticed that there is another function better suited for +# formatting of an @item line: $format_list_item_texi +sub t2h_default_tab_item_texi($$$$$$) +{ + my $command = shift; + my $commands_stack = shift; + my $stack = shift; + my $state = shift; + my $line = shift; + my $line_nr = shift; + + return undef; +} + +sub xml_default_line_command($$$$) +{ + my $command = shift; + my $arg_text = shift; + my $arg_texi = shift; + my $state = shift; + + my $style = $line_command_map{$command}; + return '' if ($arg_text eq '' and !defined($style) or $style eq ''); + if ($style) + { + my $attribute_text = ''; + if ($style =~ /^(\w+)(\s+.*)/) + { + $style = $1; + $attribute_text = $2; + } + $arg_text = "<${style}$attribute_text>$arg_text</$style>"; + } + $arg_text .= "\n"; + return $arg_text; +} + +sub t2h_default_line_command($$$$) +{ + my $command = shift; + my $arg_text = shift; + my $arg_texi = shift; + my $state = shift; + + return $arg_text; +} + +# info is special, since it doesn't use the basename but directly the +# setfilename output, contrary to all the other formats +sub t2h_default_element_file_name($$$) +{ + my $element = shift; + my $type = shift; + my $prefix = shift; + + my $outname; + return unless ($USE_SETFILENAME_EXTENSION and $PREFIX eq ''); + $outname = $OUT if (defined($OUT) and $OUT ne '' and $OUT !~ /\/$/ and $Texi2HTML::THISDOC{'input_file_number'} == 0); + if ($type eq 'doc' or !get_conf('SPLIT')) + { + if (defined($Texi2HTML::THISDOC{'setfilename'}) and !defined($outname)) + { + $Texi2HTML::THISDOC{'extension'} = ''; + return $Texi2HTML::THISDOC{'setfilename'}; + } + } + + return undef; +} + +sub t2h_default_misc_command_line($$$$$) +{ + my $macro = shift; + my $line = shift; + my $args = shift; + my $stack = shift; + my $state = shift; + + my $result; + return ($macro, $line, $result); +} + +sub t2h_default_internal_links($$$) +{ + my $fh = shift; + my $elements_list = shift; + my $indices = shift; + + foreach my $element (@$elements_list) + { + my $text = $element->{'no_texi'}; + #$text =~ s/^([\w.]+)\. /$1 /; + #$text = "Annexe ".$text if ($element->{'tag'} =~ /appendix/); + print $fh "$element->{'file'}#$element->{'id'}\ttoc\t$text\n"; + } + foreach my $index_name (sort(keys(%$indices))) + { + my $entries = $indices->{$index_name}; + + foreach my $letter_entries (@$entries) + { + foreach my $entry (@{$letter_entries->{'entries'}}) + { + #print STDERR "($index_name) key $key, t $entry->{'texi'}: $entry->{'file'}#$entry->{'target'}\n"; + print $fh "$entry->{'file'}#$entry->{'target'}\t$index_name\t$entry->{'key'}\n" if ($entry->{'key'} =~ /\S/); + } + } + } +} + +1; + +require "$T2H_HOME/texi2html.init" + if ($0 =~ /\.pl$/ && + -e "$T2H_HOME/texi2html.init" && -r "$T2H_HOME/texi2html.init"); + +# @INIT_HTML@ +# -*-perl-*- +# vim: set filetype=perl: +###################################################################### +# File: html.init +# html output formatting +# +# A copy of this file is pasted into the beginning of texi2html by +# running './configure'. +# +# $Id: texi2html,v 1.3 2017/03/28 23:22:20 takayama Exp $ + +use strict; + +use vars qw(@html_default_multitable_stack); +# used in mediawiki.init +#my @html_default_multitable_stack; +# tracks menu entry index +my $html_menu_entry_index; +# the simple_formatted document title +my $html_default_title; + +# initialise the html output +sub html_default_load(;$) +{ +my $from_command_line = shift; + +t2h_default_set_variables_xml(); + +############################################################### +# defaults + +$HEADERS = 1; + +@T2H_FORMAT_EXPAND = ('html'); + +# The value is the 'SystemLiteral' which identifies the canonical DTD +# for the document. +# Definition: The SystemLiteral is called the entity's system +# identifier. It is a URI, which may be used to retrieve the entity. +# See http://www.xml.com/axml/target.html#NT-ExternalID +$DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'; + +# When frames are used, this SystemLiteral identifies the DTD used for +# the file containing the frame description. +$FRAMESET_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'; + +# if this value is true, ISO8859 characters are used for special symbols +# (like copyright, etc). +$USE_ISO = 1; + +# if the value is true the Texinfo menus are shown. +$SHOW_MENU = 1; + +$SHOW_TITLE = 1; + +# default is to use nodes only as elements. +$USE_SECTIONS = undef; + +$TOP_FILE = 'index.html'; + +# file name used for Top node when NODE_FILES is true +$TOP_NODE_FILE = 'index'; + +############################################################################## +# +# The following can only be set in the init file +# +############################################################################## + +$INLINE_INSERTCOPYING = 0; + +# if this variable is true, numeric entities are used when there is no +# corresponding textual entity. +$USE_NUMERIC_ENTITY = 1; + +# if true, use the original command if the result is an entity +$ENABLE_ENCODING_USE_ENTITY = 1; + +# used as identation for block enclosing command @example, etc +# If not empty, must be enclosed in <td></td> +$EXAMPLE_INDENT_CELL = '<td> </td>'; + +# same as above, only for @small +$SMALL_EXAMPLE_INDENT_CELL = '<td> </td>'; + +# font size for @small +$SMALL_FONT_SIZE = '-1'; + +# horizontal rules +# Not used +$SMALL_RULE = '<hr size="1">'; +$MIDDLE_RULE = '<hr size="2">'; +# used almost everywhere +$DEFAULT_RULE = '<hr>'; +# used for top element and before misc elements +$BIG_RULE = '<hr size="6">'; + +# symbol put at the beginning of nodes entry in menu (and optionnaly of +# unnumbered in menus, see next variable) +$MENU_SYMBOL = '•'; +#$MENU_SYMBOL = '*'; + +$SIMPLE_MENU = 0; + +# extension for nodes files when NODE_FILES is true +$NODE_FILE_EXTENSION = 'html'; + +# extension +$EXTENSION = 'html'; + +# default is to split the html output +$SPLIT = 'node'; + +# this resets all the variables to the texi2html specific values if +# called as texi2html + +t2h_default_set_variables_texi2html() if ($COMMAND_NAME eq 'texi2html'); + +# this controls the pre style for menus +$MENU_PRE_STYLE = 'font-family: serif'; + +# on bug-texinfo is has been said the the style is not code_style +# for menus (except for the node name). +# this controls the menu preformatted format +# FIXME this is not dynamic, so change in MENU_PRE_STYLE is not taken +# into account. +# This is used if the menu appears within a preformatted format (which +# is certainly an invalid construct), and SIMPLE_MENU is not set. +$MENU_PRE_COMPLEX_FORMAT = { + 'pre_style' => $MENU_PRE_STYLE, + 'class' => 'menu-preformatted', +# 'style' => 'code' + }; + +# This controls the ul style for toc +$NO_BULLET_LIST_STYLE = 'list-style: none'; +$NO_BULLET_LIST_CLASS = 'no-bullet'; +$NO_BULLET_LIST_ATTRIBUTE = ' class="'.$NO_BULLET_LIST_CLASS.'"'; + +# These lines are inserted before and after the shortcontents +$BEFORE_OVERVIEW = "<div class=\"shortcontents\">\n"; +$AFTER_OVERVIEW = "</div>\n"; + +# These lines are inserted before and after the contents +$BEFORE_TOC_LINES = "<div class=\"contents\">\n"; +$AFTER_TOC_LINES = "</div>\n"; + +# text inserted after <body ...> +$AFTER_BODY_OPEN = ''; + +# text inserted before </body>, this will be automatically inside <p></p> +$PRE_BODY_CLOSE = ''; + +# this is added inside <head></head> after <title> and some <meta name> +# stuff, it can be used for eg. <style>, <script>, <meta> etc. tags. +$EXTRA_HEAD = ''; + +# Specifies the minimum page length required before a navigation panel +# is placed at the bottom of a page +$WORDS_IN_PAGE = 300; + +# html version for latex2html +$L2H_HTML_VERSION = "4.0"; + +# this is not set dynamically +if (!$HEADER_IN_TABLE) +{ + @SECTION_BUTTONS = ([ 'NodeNext', \&html_default_node_direction ], + [ 'NodePrev', \&html_default_node_direction ], + [ 'NodeUp', \&html_default_node_direction ], ' ', + 'Contents', 'Index'); + @CHAPTER_BUTTONS = @SECTION_FOOTER_BUTTONS = @NODE_FOOTER_BUTTONS = + @MISC_BUTTONS = @TOP_BUTTONS = @SECTION_BUTTONS; + $BIG_RULE = $DEFAULT_RULE; +} + +$ICONS = 0; + +%BUTTONS_ACCESSKEY = +( + 'Top', '', + 'Contents', '', + 'Overview', '', + 'Index', '', + 'This', '', + 'Back', 'p', + 'FastBack', '', + 'Prev', 'p', + 'Up', 'u', + 'Next', 'n', + 'NodeUp', 'u', + 'NodeNext', 'n', + 'NodePrev', 'p', + 'Following', '', + 'Forward', 'n', + 'FastForward', '', + 'About' , '', + 'First', '', + 'Last', '', + 'NextFile', '', + 'PrevFile', '', +); + +# see http://www.w3.org/TR/REC-html40/types.html#type-links +%BUTTONS_REL = +( + 'Top', 'start', + 'Contents', 'contents', + 'Overview', '', + 'Index', 'index', + 'This', '', + 'Back', 'previous', + 'FastBack', '', + 'Prev', 'previous', + 'Up', 'up', + 'Next', 'next', + 'NodeUp', 'up', + 'NodeNext', 'next', + 'NodePrev', 'previous', + 'Following', '', + 'Forward', 'next', + 'FastForward', '', + 'About' , 'help', + 'First', '', + 'Last', '', + 'NextFile', 'next', + 'PrevFile', 'previous', +); + + + +# PRE_ABOUT can be a function reference or a scalar. +# Note that if it is a scalar, T2H_InitGlobals has not been called, +# and all global variables like $ADDRESS are not available. +$PRE_ABOUT = sub +{ + return ' ' . &$program_string() . "\n"; +}; + +# If customizing $AFTER_ABOUT, be sure to put the content inside <p></p>. +$AFTER_ABOUT = ''; + +%BUTTONS_EXAMPLE = + ( + 'Top', '   ', + 'Contents', '   ', + 'Overview', '   ', + 'Index', '   ', + 'This', '1.2.3', + 'Back', '1.2.2', + 'FastBack', '1', + 'Prev', '1.2.2', + 'Up', '1.2', + 'Next', '1.2.4', + 'NodeUp', '1.2', + 'NodeNext', '1.2.4', + 'NodePrev', '1.2.2', + 'Following', '1.2.4', + 'Forward', '1.2.4', + 'FastForward', '2', + 'About', '   ', + 'First', '1.', + 'Last', '1.2.4', + 'NextFile', '   ', + 'PrevFile', '   ', + ); + +@IMAGE_EXTENSIONS = ('png','jpg','jpeg','gif'); +#, 'txt'); + +####################################################################### +# +# Values guessed if not set here. The value used is in +# $Texi2HTML::THISDOC{'VARNAME'} +# +####################################################################### + +$BODYTEXT = undef; + +#$init_out = \&html_default_init_out; +$translate_names = \&html_default_translate_names; + +t2h_default_push_handler(\&html_default_initialize, \@command_handler_init); +# This must be done after language has been set +t2h_default_push_handler(\&html_default_bodytext, \@command_handler_process); +# This must be done after the fulltitle has been set +t2h_default_push_handler(\&html_default_do_title, \@command_handler_output); + +######################################################################## +# Control of Page layout: +# You can make changes of the Page layout at two levels: +# 1.) For small changes, it is often enough to change the value of +# some global string/hash/array variables +# 2.) For larger changes, reimplement one of the HTML_DEFAULT_<fnc>* routines, +# give them another name, and assign them to the respective +# $<fnc> variable. + +# As a general interface, the hashes Texi2HTML::HREF, Texi2HTML::NAME, Texi2HTML::NODE, Texi2HTML::NO_TEXI, Texi2HTML::SIMPLE_TEXT hold +# href, html-name, node-name, name after removal of texi commands of +# This -- current section (resp. html page) +# Top -- top element +# Contents -- Table of contents element +# Overview -- Short table of contents element +# Index -- Index page element +# About -- page which explain "navigation buttons" element +# First -- first node element +# Last -- last node element +# +# Whether or not the following hash values are set, depends on the context +# (all values are w.r.t. 'This' section) +# Next -- next element of texinfo +# Prev -- previous element of texinfo +# NodeUp -- up node of texinfo +# Following -- following node in node reading order, taking menu into account +# Forward -- next node in reading order +# Back -- previous node in reading order +# Up -- parent given by sectioning commands +# FastForward -- if leave node, up and next, else next node +# FastBackward-- if leave node, up and prev, else prev node +# +# Furthermore, the following global variabels are set: +# $Texi2HTML::THISDOC{title} -- title as set by @title... +# $Texi2HTML::THISDOC{title_no_texi} -- title without texi (without html elements) +# $Texi2HTML::THISDOC{title_texi} -- title with texinfo @-commands +# $Texi2HTML::THISDOC{fulltitle} -- full title as set by @title... +# $Texi2HTML::THISDOC{subtitle} -- subtitle as set by @subtitle +# $Texi2HTML::THISDOC{author} -- author as set by @author +# $Texi2HTML::THISDOC{copying_comment} -- text of @copying and @end copying in comment +# +# $Texi2HTML::THISDOC{program} -- name and version of texi2html +# $Texi2HTML::THISDOC{program_homepage} -- homepage for texi2html +# $Texi2HTML::THISDOC{program_authors} -- authors of texi2html +# $Texi2HTML::THISDOC{today} -- date formatted with pretty_date +# $Texi2HTML::THISDOC{toc_file} -- table of contents file +# $Texi2HTML::THISDOC{file_base_name} -- base name of the texinfo manual file +# $Texi2HTML::THISDOC{input_file_name} -- name of the texinfo manual file +# $Texi2HTML::THISDOC{destination_directory} + # -- directory for the resulting files +# $Texi2HTML::THISDOC{user} -- user running the script +# $Texi2HTML::THISDOC{css_import_lines} -- ref on @import lines in css files +# $Texi2HTML::THISDOC{css_rule_lines} -- ref on css rules lines +# other $Texi2HTML::THISDOC keys corresponds with texinfo commands, the value +# being the command arg, for the following commands: +# kbdinputstyle, paragraphindent, setchapternewpage, headings, footnotestyle, +# exampleindent, firstparagraphindent, everyheading, everyfooting, +# evenheading, evenfooting, oddheading, oddfooting +# +# and pointer to arrays of lines which need to be printed by main::print_lines +# $Texi2HTML::THIS_SECTION -- lines of 'This' section +# $Texi2HTML::OVERVIEW -- lines of short table of contents +# $Texi2HTML::TOC_LINES -- lines of table of contents +# $Texi2HTML::TITLEPAGE -- lines of title page +# +# $Texi2HTML::THIS_ELEMENT holds the element reference. + +# +# There are the following subs which control the layout: +# +$print_section = \&HTML_DEFAULT_print_section; +$end_section = \&HTML_DEFAULT_end_section; +$one_section = \&HTML_DEFAULT_one_section; +$print_Top_footer = \&HTML_DEFAULT_print_Top_footer; +$print_Top = \&HTML_DEFAULT_print_Top; +# changed in info format, but irrelevant for non-split formats +$print_Footnotes = \&T2H_DEFAULT_print_Footnotes; +$print_misc_header = \&HTML_DEFAULT_print_misc_header; +$print_misc_footer = \&HTML_DEFAULT_print_misc_footer; +$print_section_footer = \&HTML_DEFAULT_print_section_footer; +$print_chapter_header = \&HTML_DEFAULT_print_chapter_header; +$print_section_header = \&HTML_DEFAULT_print_section_header; +$print_chapter_footer = \&HTML_DEFAULT_print_chapter_footer; +$print_page_head = \&HTML_DEFAULT_print_page_head; +$print_page_foot = \&HTML_DEFAULT_print_page_foot; +$print_head_navigation = \&HTML_DEFAULT_print_head_navigation; +$print_foot_navigation = \&HTML_DEFAULT_print_foot_navigation; +$button_icon_img = \&HTML_DEFAULT_button_icon_img; +$button_formatting = \&HTML_DEFAULT_button_formatting; + +$print_navigation = \&HTML_DEFAULT_print_navigation; +$about_body = \&HTML_DEFAULT_about_body; + +$print_frame = \&HTML_DEFAULT_print_frame; +$print_toc_frame = \&HTML_DEFAULT_print_toc_frame; +$contents = \&HTML_DEFAULT_contents; +$shortcontents = \&HTML_DEFAULT_shortcontents; +$print_redirection_page = \&HTML_DEFAULT_print_redirection_page; + +######################################################################## +# Control of formatting: +# 1.) For some changes, it is often enough to change the value of +# some global map. It might necessitate building a little +# function along with the change in hash, if the change is the use +# of another function (in style_map). +# 2.) For other changes, reimplement one of the t2h_default_<fnc>* routines, +# give them another name, and assign them to the respective +# $<fnc> variable (below). + + +# +# texinfo "simple things" (@foo) to HTML ones +# +%simple_map = %default_simple_map; +$simple_map{'*'} = '<br>'; # HTML+ +$simple_map{' '} = ' '; +$simple_map{"\t"} = ' '; +$simple_map{"\n"} = ' '; + # "­" or "­" could also be possible for @-, but it seems + # that some browser will consider this as an always visible hyphen mark + # which is not what we want (see http://www.cs.tut.fi/~jkorpela/shy.html) +#$simple_map{'-'} = ''; # hyphenation hint + +# this map is used in preformatted text +%simple_map_pre = %simple_map; +$simple_map_pre{'*'} = "\n"; + +# use entities in the default case +#$things_map{'dots'} = '<small class="dots">...</small>'; +$things_map{'enddots'} = '<small class="enddots">...</small>'; + +%style_map = (); +%style_map_pre = (); +t2h_default_copy_style_map (\%default_style_map, \%style_map); +t2h_default_copy_style_map (\%default_style_map_pre, \%style_map_pre); +# default is {'args' => ['normal'], 'attribute' => ''}, +my %style_map_html = ( + 'b', {'inline_attribute' => 'b'}, + 'cite', {'inline_attribute' => 'cite'}, + 'code', {'inline_attribute' => 'code'}, + 'command', {'inline_attribute' => 'code'}, + 'dfn', {'inline_attribute' => 'em'}, + 'email', {'function' => \&html_default_email}, + 'emph', {'inline_attribute' => 'em'}, + 'env', {'inline_attribute' => 'code'}, + 'file', {'inline_attribute' => 'tt', 'quote' => '"'}, + 'headitemfont', {'inline_attribute' => 'b'}, # not really that, in fact it is + # in <th> rather than <td> + 'i', {'inline_attribute' => 'i'}, + 'slanted', {'inline_attribute' => 'i'}, + 'sansserif', {'inline_attribute' => 'span class="sansserif"'}, + 'kbd', {'inline_attribute' => 'kbd'}, + 'key', {'begin' => '<', 'end' => '>'}, + 'math', {'function' => \&html_default_math}, + 'option', {'inline_attribute' => 'samp', 'quote' => '"'}, + 'r', {'inline_attribute' => 'span class="roman"'}, + 'samp', {'inline_attribute' => 'samp', 'quote' => '"'}, + 'sc', {'inline_attribute' => 'small'}, + 'strong', {'inline_attribute' => 'strong'}, + 't', {'inline_attribute' => 'tt'}, + 'uref', {'function' => \&html_default_uref}, + 'url', {'function' => \&html_default_uref}, + 'indicateurl', {'begin' => '<<code>', 'end' => '</code>>'}, + 'var', {'inline_attribute' => 'var'}, + 'verb', {'inline_attribute' => 'tt'}, + ); + +foreach my $style_command (keys(%style_map_html)) +{ + foreach my $key (keys(%{$style_map_html{$style_command}})) + { + $style_map_pre{$style_command}->{$key} = $style_map_html{$style_command}->{$key}; + $style_map{$style_command}->{$key} = $style_map_html{$style_command}->{$key}; + } +} + +%line_command_map = ( + 'title' => 'h1', + 'subtitle' => 'h3 align="right"', + 'author' => 'strong', +); + +foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) +{ + $style_map{$accent_command} = { 'function' => \&xml_default_accent }; + $style_map_pre{$accent_command} = { 'function' => \&xml_default_accent }; +} + +$style_map_pre{'sc'} = {}; +$style_map_pre{'titlefont'} = {}; +$style_map_pre{'click'}->{'function'} = \&t2h_default_click_pre; + +# uncomment to use the old interface +#%style_map = %old_style_map; +#%style_map_pre = %old_style_map_pre; + +%simple_format_simple_map_texi = %simple_map_pre; + +%format_map = ( +# 'quotation' => 'blockquote', + # lists +# 'itemize' => 'ul', + 'enumerate' => 'ol', +# 'multitable' => 'table', + 'table' => 'dl compact="compact"', + 'vtable' => 'dl compact="compact"', + 'ftable' => 'dl compact="compact"', + 'group' => '', + 'raggedright' => '', +# 'detailmenu' => '', + ); + +#%special_list_commands = ( +# 'table' => {}, +# 'vtable' => {}, +# 'ftable' => {}, +# 'itemize' => { 'bullet' => '' } +# ); + +$special_list_commands{'itemize'}->{ 'bullet'} = ''; + +# +# texinfo format to align attribute of paragraphs +# + +%paragraph_style = ( + 'center' => 'center', + 'flushleft' => 'left', + 'flushright' => 'right', + ); + +# preformatted formats formatting +if ($COMPLEX_FORMAT_IN_TABLE) +{ + foreach my $indented_format ('example', 'display', 'lisp') + { + $complex_format_map{"small$indented_format"}->{'begin'} = "<table><tr>$SMALL_EXAMPLE_INDENT_CELL<td>"; + $complex_format_map{$indented_format}->{'begin'} = "<table><tr>$EXAMPLE_INDENT_CELL<td>"; + $complex_format_map{$indented_format}->{'end'} = "</td></tr></table>\n"; + $complex_format_map{"small$indented_format"}->{'end'} = "</td></tr></table>\n"; + } + + foreach my $non_indented_formats ('format', 'smallformat') + { + $complex_format_map{$non_indented_formats}->{'begin'} = ''; + $complex_format_map{$non_indented_formats}->{'end'} = "\n"; + } +} +else +{ + foreach my $format ('example', 'display', 'lisp', 'format') + { + $complex_format_map{$format}->{'begin'} = html_default_attribute_class('div', $format).">\n"; + $complex_format_map{"small$format"}->{'begin'} = html_default_attribute_class('div', "small$format").">\n"; + $complex_format_map{$format}->{'end'} = '</div>'."\n"; + $complex_format_map{"small$format"}->{'end'} = '</div>'."\n"; + } +} + +foreach my $format ('menu', 'detailmenu', 'direntry') +{ + $complex_format_map{$format} = { 'begin' => '' , 'end' => '', + 'class' => 'menu-preformatted', + }; +} + +$complex_format_map{'menu_comment'} = { + 'begin' => "<tr><th colspan=\"3\" align=\"left\" valign=\"top\">", + 'end' => "</th></tr>", 'class' => 'menu-comment', +}; + + +%format_in_paragraph = ( + 'html' => 1, +); +# map mapping css specification to style + +%css_map = + ( + "ul.$NO_BULLET_LIST_CLASS" => "$NO_BULLET_LIST_STYLE", + 'pre.menu-comment' => "$MENU_PRE_STYLE", + 'pre.menu-preformatted' => "$MENU_PRE_STYLE", + 'a.summary-letter' => 'text-decoration: none', + 'blockquote.smallquotation' => 'font-size: smaller', +# 'pre.display' => 'font-family: inherit', +# 'pre.smalldisplay' => 'font-family: inherit; font-size: smaller', + 'pre.display' => 'font-family: serif', + 'pre.smalldisplay' => 'font-family: serif; font-size: smaller', + 'pre.smallexample' => 'font-size: smaller', + 'span.sansserif' => 'font-family:sans-serif; font-weight:normal', + 'span.roman' => 'font-family:serif; font-weight:normal', + 'span.nocodebreak' => 'white-space:pre', + 'span.nolinebreak' => 'white-space:pre' + ); + +$css_map{'pre.format'} = $css_map{'pre.display'}; +$css_map{'pre.smallformat'} = $css_map{'pre.smalldisplay'}; +$css_map{'pre.smalllisp'} = $css_map{'pre.smallexample'}; + +foreach my $indented_format ('example', 'display', 'lisp') +{ + $css_map{"div.$indented_format"} = 'margin-left: 3.2em'; + $css_map{"div.small$indented_format"} = 'margin-left: 3.2em'; +} + +# formatting functions + +$acronym_like = \&html_default_acronym_like; +$anchor = \&html_default_anchor; +$anchor_label = \&html_default_anchor_label; +$begin_format_texi = \&html_default_begin_format_texi; +$caption_shortcaption = \&html_default_caption_shortcaption; +$caption_shortcaption_command = \&html_default_caption_shortcaption_command; +$cartouche = \&html_default_cartouche; +$cell = \&html_default_cell; +$def = \&html_default_def; +$def_item = \&html_default_def_item; +$def_line = \&html_default_def_line; +$element_label = \&html_default_element_label; +$float = \&html_default_float; +$foot_line_and_ref = \&html_default_foot_line_and_ref; +$foot_section = \&html_default_foot_section; +$format_list_item_texi = \&html_default_format_list_item_texi; +$heading = \&t2h_default_heading; +$heading_text = \&html_default_heading_text; +$heading_text_preformatted = \&html_default_heading_text_preformatted; +$image = \&html_default_image; +$image_files = \&html_default_image_files; +$index_entry = \&html_default_index_entry; +$index_entry_command = \&html_default_index_entry_command; +$index_entry_label = \&html_default_index_entry_label; +$index_letter = \&html_default_index_letter; +$index_summary = \&html_default_index_summary; +$insertcopying = \&html_default_insertcopying; +$line_command = \&html_default_line_command; +$list_item = \&html_default_list_item; +$listoffloats = \&html_default_listoffloats; +$listoffloats_entry = \&html_default_listoffloats_entry; +$listoffloats_caption = \&html_default_listoffloats_caption; +$listoffloats_float_style = \&html_default_listoffloats_float_style; +$menu_command = \&html_default_menu_command; +$menu_link = \&html_default_menu_link; +$menu_description = \&html_default_menu_description; +$misc_element_label = \&html_default_misc_element_label; +$normal_text = \&html_default_normal_text; +$paragraph = \&html_default_paragraph; +$preformatted = \&html_default_preformatted; +$print_index = \&html_default_print_index; +$protect_text = \&xml_default_protect_text; +$quotation = \&html_default_quotation; +$sp = \&html_default_sp; +$summary_letter = \&html_default_summary_letter; +$tab_item_texi = \&html_default_tab_item_texi; +$table_item = \&html_default_table_item; +$table_line = \&html_default_table_line; +$table_list = \&html_default_table_list; +$raw = \&html_default_raw; +$row = \&html_default_row; + +} + + + +# The functions + +sub html_default_initialize() +{ + @html_default_multitable_stack = (); + $html_default_title = undef; +} + +# We have to do this dynamically because of internationalization and because +# in body $DOCUMENTLANGUAGE could be used. +sub html_default_bodytext() +{ + # Set the default body text, inserted between <body ... > + if (defined($BODYTEXT)) + { + $Texi2HTML::THISDOC{'BODYTEXT'} = $BODYTEXT; + } + else + { + $Texi2HTML::THISDOC{'BODYTEXT'} = 'lang="' . get_conf('documentlanguage') . '" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"'; + } +} + +sub html_default_translate_names() +{ + t2h_default_translate_names(); + + %NAVIGATION_TEXT = + ( + 'Top', gdt('Top'), + 'Contents', gdt('Contents'), + 'Overview', gdt('Overview'), + 'Index', gdt('Index'), + ' ', '   ', + 'This', gdt('current'), + 'Back', ' < ', + 'FastBack', ' << ', + 'Prev', gdt('Prev'), + 'Up', gdt(' Up '), + 'Next', gdt('Next'), + 'NodeUp', gdt('Node up'), + 'NodeNext', gdt('Next node'), + 'NodePrev', gdt('Previous node'), + 'Following', gdt('Following node'), + 'Forward', ' > ', + 'FastForward', ' >> ', + 'About', ' ? ', + 'First', ' |< ', + 'Last', ' >| ', + 'NextFile', gdt('Next file'), + 'PrevFile', gdt('Previous file'), + ); + +} + +sub html_default_do_title() +{ + $html_default_title = "$Texi2HTML::THISDOC{'fulltitle_simple_format'}"; + if ($html_default_title !~ /\S/) + { + $html_default_title = gdt('Untitled Document',{},{'simple_format' => 1}); + main::document_warn("Must specify a title with a title command or \@top"); + } +} + +######################################################################## +# Page formatting functions +# + +######################################################################## +# Layout for html for every sections +# + +sub HTML_DEFAULT_print_section +{ + my $fh = shift; + my $first_in_page = shift; + my $previous_is_top = shift; + my $element = shift; + my $buttons = \@SECTION_BUTTONS; + + my $nw = main::print_lines($fh); + if ((get_conf('SPLIT') eq 'node') && get_conf('headers')) + { + my $buttons = \@NODE_FOOTER_BUTTONS; + &$print_foot_navigation($fh, $buttons, $DEFAULT_RULE, + (!defined($WORDS_IN_PAGE) or (defined ($nw) and $nw >= $WORDS_IN_PAGE)), + $element); + } +} + +sub HTML_DEFAULT_one_section($$) +{ + my $fh = shift; + my $element = shift; + main::print_lines($fh); + print $fh "$DEFAULT_RULE\n"; + &$print_page_foot($fh); +} + +################################################################### +# Layout of top-page I recommend that you use @ifnothtml, @ifhtml, +# @html within the Top texinfo node to specify content of top-level +# page. +# +sub HTML_DEFAULT_print_Top_footer($$$) +{ + my $fh = shift; + my $end_page = shift; + my $element = shift; + my $buttons = \@TOP_BUTTONS; + my $rule = $DEFAULT_RULE; + $rule = $BIG_RULE if (!$end_page); + #print STDERR "end_page: $end_page\n"; + &$print_foot_navigation($fh, $buttons, $rule, + ($end_page and (get_conf('headers') or (get_conf('SPLIT') and get_conf('SPLIT') ne 'node'))), $element); + if ($end_page) + { + &$print_page_foot($fh); + } +} + +sub HTML_DEFAULT_print_Top($$$) +{ + my $fh = shift; + my $has_top_heading = shift; + my $element = shift; + + main::print_lines($fh, $Texi2HTML::THIS_SECTION); +} + +################################################################### +# Layout of Toc, Overview, and Footnotes pages +# By default, we use "normal" layout +# Texi2HTML::HREF of Next, Prev, Up, Forward, Back, etc are not defined +# use: my $buttons = [...] to redefine navigation buttons +sub HTML_DEFAULT_print_Footnotes +{ + return &$print_misc(@_); +} + +sub HTML_DEFAULT_print_misc_header +{ + my $fh = shift; + my $buttons = shift; + my $new_file = shift; + my $misc_page = shift; + &$print_page_head($fh) if ($new_file); + print $fh "".&$misc_element_label($misc_pages_targets{$misc_page}, $misc_page); + &$print_head_navigation($fh, $buttons) if ($new_file or get_conf('headers')); +} + +sub HTML_DEFAULT_print_misc_footer +{ + my $fh = shift; + my $buttons = shift; + my $new_file = shift; + &$print_foot_navigation($fh, $buttons, $DEFAULT_RULE, + ($new_file and (get_conf('headers') or (get_conf('SPLIT') and get_conf('SPLIT') ne 'node'))), undef); + if ($new_file) + { + &$print_page_foot($fh); + } +} + +################################################################## +# section_footer is only called if SPLIT eq 'section' +# section_footer: after print_section of last section, before print_page_foot +# + +sub HTML_DEFAULT_print_section_footer +{ + my $fh = shift; + my $element = shift; + my $buttons = \@SECTION_FOOTER_BUTTONS; + &$print_foot_navigation($fh, $buttons, $DEFAULT_RULE, 1, $element); +} + +################################################################### +# chapter_header and chapter_footer are only called if +# SPLIT eq 'chapter' +# chapter_header: after print_page_head, before print_section +# chapter_footer: after print_section of last section, before print_page_foot +# +# If you want to get rid of navigation stuff after each section, +# redefine print_section such that it does not call print_navigation, +# and put print_navigation into print_chapter_header +sub HTML_DEFAULT_print_chapter_header +{ + my $fh = shift; + my $element = shift; + # nothing to do there, by default, the navigation panel + # is the element navigation panel + if (! get_conf('headers')) + { # in this case print_navigation is called here. + my $buttons = \@CHAPTER_BUTTONS; + &$print_head_navigation($fh, $buttons); + print $fh "\n$DEFAULT_RULE\n" unless ($VERTICAL_HEAD_NAVIGATION); + } +} + +sub HTML_DEFAULT_print_chapter_footer +{ + my $fh = shift; + my $element = shift; + my $buttons = \@CHAPTER_BUTTONS; + &$print_foot_navigation($fh, $buttons, $DEFAULT_RULE, 1, $element); +} + +sub HTML_DEFAULT_print_section_header +{ + # nothing to do there, by default + if (! get_conf('headers')) + { # in this case print_navigation is called here. + my $fh = shift; + my $buttons = \@SECTION_BUTTONS; + &$print_head_navigation($fh, $buttons); + } +} + + +################################################################### +# Layout of standard header and footer +# + +sub HTML_DEFAULT_print_page_head($) +{ + my $fh = shift; + my $longtitle = $html_default_title; + $longtitle .= ": $Texi2HTML::SIMPLE_TEXT{'This'}" if (defined ($Texi2HTML::SIMPLE_TEXT{'This'}) and ($Texi2HTML::SIMPLE_TEXT{'This'} !~ /^\s*$/) and get_conf('SPLIT') and ($html_default_title ne $Texi2HTML::SIMPLE_TEXT{'This'})); + my $description = $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'}; + $description = $longtitle if (!defined($description)); + $description = "<meta name=\"description\" content=\"$description\">" if + ($description ne ''); + my $encoding = ''; + $encoding = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$Texi2HTML::THISDOC{'ENCODING_NAME'}\">" if (defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and ($Texi2HTML::THISDOC{'ENCODING_NAME'} ne '')); + my $date = ''; + my $today = $Texi2HTML::THISDOC{'today'}; + $today = '' if (!defined($today)); + $date = "\n<meta name=\"date\" content=\"$today\">" if ($DATE_IN_HEADER and $today ne ''); + my $links = ''; + if ($USE_LINKS) + { + foreach my $link (@LINKS_BUTTONS) + { +#print STDERR "$link!!$Texi2HTML::HREF{$link}\n"; + if (defined($Texi2HTML::HREF{$link}) and $Texi2HTML::HREF{$link} ne '') + { + my $title = ''; + $title = " title=\"$Texi2HTML::SIMPLE_TEXT{$link}\"" if (defined($Texi2HTML::SIMPLE_TEXT{$link})); + my $rel = ''; + $rel = " rel=\"$BUTTONS_REL{$link}\"" if (defined($BUTTONS_REL{$link})); + $links .= "<link href=\"$Texi2HTML::HREF{$link}\"${rel}${title}>\n"; + } + } + } + + my $css_text = ''; + $css_text = $Texi2HTML::THISDOC{'CSS_LINES'} if (defined($Texi2HTML::THISDOC{'CSS_LINES'})); + my $doctype = get_conf('doctype'); + print $fh <<EOT; +$doctype +<html> +$Texi2HTML::THISDOC{'copying_comment'}<!-- Created on $Texi2HTML::THISDOC{today} by $Texi2HTML::THISDOC{program} +$Texi2HTML::THISDOC{program_authors}--> +<head> +<title>$longtitle + +$description + + + +$date +$encoding +${links}$css_text +$EXTRA_HEAD + + + +$AFTER_BODY_OPEN EOT +} -while (@ARGV && $ARGV[0] =~ /^-/) { - $_ = shift(@ARGV); - if (/^-acc$/) { $use_acc = 1; next; } - if (/^-d(ebug)?(\d+)?$/) { $debug = $2 || shift(@ARGV); next; } - if (/^-doctype$/) { $doctype = shift(@ARGV); next; } - if (/^-c(heck)?$/) { $check = 1; next; } - if (/^-e(xpandinfo)?$/) { $expandinfo = 1; next; } - if (/^-g(lossary)?$/) { $use_glossary = 1; next; } - if (/^-i(nvisible)?$/) { $invisible_mark = shift(@ARGV); next; } - if (/^-iso$/) { $use_iso = 1; next; } - if (/^-D(.+)?$/) { $value{$1 || shift(@ARGV)} = 1; next; } - if (/^-I(.+)?$/) { push(@include_dirs, $1 || shift(@ARGV)); next; } - if (/^-m(enu)?$/) { $show_menu = 1; next; } - if (/^-mono(lithic)?$/) { $monolithic = 1; next; } - if (/^-n(umber)?$/) { $number_sections = 1; next; } - if (/^-s(plit)?_?(n(ode)?|c(hapter)?)?$/) { - if ($2 =~ /^n/) { - $split_node = 1; - } else { - $split_chapter = 1; - } - next; +sub HTML_DEFAULT_end_section($$$) +{ + my $fh = shift; + my $misc_or_top_and_section_separation = shift; + my $element = shift; + if ($misc_or_top_and_section_separation) + { + my $rule = $BIG_RULE; + # in that case we are almost surely at the end of the document + $rule = $DEFAULT_RULE if (! $MONOLITHIC); + &$print_foot_navigation($fh, undef, $rule, 0, $element, 1); } - if (/^-v(erbose)?$/) { $verbose = 1; next; } - die $usage; + else + { + print $fh "$DEFAULT_RULE\n"; + } } -if ($check) { - die $usage unless @ARGV > 0; - ✓ - exit; + +sub HTML_DEFAULT_print_page_foot($) +{ + my $fh = shift; + my $program_text = ''; + if ($PROGRAM_NAME_IN_FOOTER) + { + my $program_string = &$program_string(); + $program_text = " + $program_string + +
    "; + } + print $fh < +$program_text +$PRE_BODY_CLOSE +

    + + +EOT } -if (($split_node || $split_chapter) && $monolithic) { - warn "Can't use -monolithic with -split, -monolithic ignored.\n"; - $monolithic = 0; +################################################################### +# Layout of navigation panel + +sub HTML_DEFAULT_print_head_navigation($$$$$) +{ + my $fh = shift; + my $buttons = shift; + my $first_in_page = shift; + my $previous_is_top = shift; + my $element = shift; + + my $result = ''; + if ($VERTICAL_HEAD_NAVIGATION) + { + $result .= < + + +EOT + } + $result .= &$print_navigation($buttons, $VERTICAL_HEAD_NAVIGATION); + if ($VERTICAL_HEAD_NAVIGATION) + { + $result .= < + +EOT + } + elsif (get_conf('SPLIT') eq 'node') + { + $result .= "$DEFAULT_RULE\n"; + } + + print $fh $result if (defined($fh)); + return $result; } -if ($expandinfo) { - $to_skip{'ifinfo'}++; - $to_skip{'end ifinfo'}++; - $to_skip{'ifnottex'}++; - $to_skip{'end ifnottex'}++; -} else { - $to_skip{'iftex'}++; - $to_skip{'end iftex'}++; + +sub HTML_DEFAULT_print_foot_navigation +{ + my $fh = shift; + my $buttons = shift; + my $rule = shift; + my $print_navigation_panel = shift; + my $element = shift; + # set if called between sections and top or between sections and misc. + # could also be the last element + my $maybe_in_page = shift; + + $rule = '' if (!defined($rule)); + $print_navigation_panel = 1 if (!defined($print_navigation_panel) + and defined($buttons)); + + # avoid the rule if at the end of a page and there is nothing below + $rule = '' if (!$PROGRAM_NAME_IN_FOOTER and !$print_navigation_panel and !$maybe_in_page); + + if ($VERTICAL_HEAD_NAVIGATION) + { + print $fh < + + +EOT + } + print $fh "$rule\n" if ($rule ne ''); + print $fh "".&$print_navigation($buttons) if ($print_navigation_panel); } -$invisible_mark = '' if $invisible_mark eq 'xbm'; -die $usage unless @ARGV == 1; -$docu = shift(@ARGV); -if ($docu =~ /.*\//) { - chop($docu_dir = $&); - $docu_name = $'; -} else { - $docu_dir = '.'; - $docu_name = $docu; + +###################################################################### +# navigation panel +# +# how to create IMG tag +sub HTML_DEFAULT_button_icon_img +{ + my $button = shift; + my $icon = shift; + my $name = shift; + return '' if (!defined($icon)); + $button = "" if (!defined ($button)); + $name = '' if (!defined($name)); + my $alt = ''; + if ($name ne '') + { + if ($button ne '') + { + $alt = "$button: $name"; + } + else + { + $alt = $name; + } + } + else + { + $alt = $button; + } + return qq{$alt}; } -unshift(@include_dirs, $docu_dir); -$docu_name =~ s/\.te?x(i|info)?$//; # basename of the document -$docu_doc = "$docu_name.html"; # document's contents -if ($monolithic) { - $docu_toc = $docu_foot = $docu_doc; -} else { - $docu_toc = "${docu_name}_toc.html"; # document's table of contents - $docu_foot = "${docu_name}_foot.html"; # document's footnotes +sub HTML_DEFAULT_button_formatting($$) +{ + my $button = shift; + my $vertical = shift; + + my ($active, $passive); + if (ref($button) eq 'CODE') + { + $active = &$button($vertical); + } + elsif (ref($button) eq 'SCALAR') + { + $active = "$$button" if defined($$button); + } + elsif (ref($button) eq 'ARRAY') + { + my $text = $button->[1]; + my $button_href = $button->[0]; + # verify that $button_href is simple text and text is a reference + if (defined($button_href) and !ref($button_href) + and defined($text) and (ref($text) eq 'SCALAR') and defined($$text)) + { # use given text + if ($Texi2HTML::HREF{$button_href}) + { + my $anchor_attributes = ''; + if ($USE_ACCESSKEY and (defined($BUTTONS_ACCESSKEY{$button_href})) and ($BUTTONS_ACCESSKEY{$button_href} ne '')) + { + $anchor_attributes = "accesskey=\"$BUTTONS_ACCESSKEY{$button_href}\""; + } + if ($USE_REL_REV and (defined($BUTTONS_REL{$button_href})) and ($BUTTONS_REL{$button_href} ne '')) + { + $anchor_attributes .= " rel=\"$BUTTONS_REL{$button_href}\""; + } + $active = "" . + &$anchor('', + $Texi2HTML::HREF{$button_href}, + $$text, + $anchor_attributes + ); + } + else + { + $passive = $$text; + } + } + elsif (defined($button_href) and !ref($button_href) + and defined($text) and (ref($text) eq 'CODE')) + { + $active = &$text($button_href); + } + } + elsif ($button eq ' ') + { # handle space button + $active = + ($ICONS && $ACTIVE_ICONS{' '}) ? + &$button_icon_img($BUTTONS_NAME{$button}, $ACTIVE_ICONS{' '}) : + $NAVIGATION_TEXT{' '}; + #next; + } + elsif ($Texi2HTML::HREF{$button}) + { # button is active + my $btitle = $BUTTONS_GOTO{$button} ? + 'title="' . $BUTTONS_GOTO{$button} . '"' : ''; + if ($USE_ACCESSKEY and (defined($BUTTONS_ACCESSKEY{$button})) and ($BUTTONS_ACCESSKEY{$button} ne '')) + { + $btitle .= " accesskey=\"$BUTTONS_ACCESSKEY{$button}\""; + } + if ($USE_REL_REV and (defined($BUTTONS_REL{$button})) and ($BUTTONS_REL{$button} ne '')) + { + $btitle .= " rel=\"$BUTTONS_REL{$button}\""; + } + if ($ICONS && $ACTIVE_ICONS{$button}) + { # use icon + $active = '' . + &$anchor('', + $Texi2HTML::HREF{$button}, + &$button_icon_img($BUTTONS_NAME{$button}, + $ACTIVE_ICONS{$button}, + $Texi2HTML::SIMPLE_TEXT{$button}), + $btitle + ); + } + else + { # use text + $active = + '[' . + &$anchor('', + $Texi2HTML::HREF{$button}, + $NAVIGATION_TEXT{$button}, + $btitle + ) . + ']'; + } + } + else + { # button is passive + $passive = + $ICONS && $PASSIVE_ICONS{$button} ? + &$button_icon_img($BUTTONS_NAME{$button}, + $PASSIVE_ICONS{$button}, + $Texi2HTML::SIMPLE_TEXT{$button}) : + "[" . $NAVIGATION_TEXT{$button} . "]"; + } + return ($active, $passive); } +my %html_default_node_directions; +foreach my $node_directions ('NodeNext', 'NodePrev', 'NodeUp') +{ + $html_default_node_directions{$node_directions} = 1; +} + +sub HTML_DEFAULT_print_navigation($;$) +{ + my $buttons = shift; + my $vertical = shift; + + my $first_button = 1; + my $result = ''; + if ($HEADER_IN_TABLE) + { + $result .= html_default_attribute_class('table', 'header').' cellpadding="1" cellspacing="1" border="0">'."\n"; + $result .= "" unless $vertical; + } + else + { + $result .= html_default_attribute_class('div', 'header').">\n

    \n"; + } + for my $button (@$buttons) + { + if ($HEADER_IN_TABLE) + { + $result .= qq{\n} if $vertical; + $result .= qq{}; + } + my $direction; + if (ref($button) eq 'ARRAY' and defined($button->[0]) and !ref($button->[0])) + { + $direction = $button->[0]; + } + elsif (defined($button) and !ref($button)) + { + $direction = $button; + } + + my ($active, $passive) = &$button_formatting($button, $vertical); + if ($HEADER_IN_TABLE) + { + if (defined($active)) + { + $first_button = 0 if ($first_button); + $result .= $active; + } + elsif (defined($passive)) + { + $first_button = 0 if ($first_button); + $result .= $passive; + } + $result .= "\n"; + $result .= "\n" if $vertical; + } + elsif (defined($active)) + { # only active buttons are print out when not in table + if (defined($direction) and $html_default_node_directions{$direction} and !$first_button) + { + $active = ', ' .$active; + } + $result .= $active; + $first_button = 0 if ($first_button); + } + } + if ($HEADER_IN_TABLE) + { + $result .= "" unless $vertical; + $result .= "\n"; + } + else + { + $result .= "

    \n\n"; + } + return $result; +} + +sub html_default_node_direction($) +{ + my $direction = shift; + my $result = undef; + if ($Texi2HTML::HREF{$direction} and $Texi2HTML::NODE{$direction}) + { + my $anchor_attributes = ''; + if ($USE_ACCESSKEY and (defined($BUTTONS_ACCESSKEY{$direction})) and ($BUTTONS_ACCESSKEY{$direction} ne '')) + { + $anchor_attributes = "accesskey=\"$BUTTONS_ACCESSKEY{$direction}\""; + } + if ($USE_REL_REV and (defined($BUTTONS_REL{$direction})) and ($BUTTONS_REL{$direction} ne '')) + { + $anchor_attributes .= " rel=\"$BUTTONS_REL{$direction}\""; + } + my $anchor = &$anchor('', + $Texi2HTML::HREF{$direction}, + $Texi2HTML::NODE{$direction}, + $anchor_attributes + ) + ; + # i18n + $result = "$BUTTONS_TEXT{$direction}: $anchor"; + } + return $result; +} + +###################################################################### +# Frames: this is from "Richard Y. Kim" +# Should be improved to be more conforming to other _print* functions +# toc_file and main_file passed as args are relative to the texinfo manual +# location, and therefore are not used. + +sub HTML_DEFAULT_print_frame +{ + my $fh = shift; + my $toc_file = shift; + my $main_file = shift; + $main_file = $Texi2HTML::THISDOC{'filename'}->{'top'}; + $toc_file = $Texi2HTML::THISDOC{'filename'}->{'toc_frame'}; + print $fh < +$Texi2HTML::THISDOC{'fulltitle'} + + + + + +EOT +} + +sub HTML_DEFAULT_print_toc_frame +{ + my $fh = shift; + my $stoc_lines = shift; + &$print_page_head($fh); + print $fh <Content +EOT + print $fh map {s/\bhref=/target="main" href=/; $_;} @$stoc_lines; + print $fh "\n"; +} + +###################################################################### +# About page # -# variables + +sub HTML_DEFAULT_about_body +{ + return undef if (!$HEADER_IN_TABLE); + my $about = "

    \n"; + if (ref($PRE_ABOUT) eq 'CODE') + { + $about .= &$PRE_ABOUT(); + } + else + { + $about .= $PRE_ABOUT; + } + $about .= < +

    +EOT + $about .= gdt(' The buttons in the navigation panels have the following meaning:') . "\n"; + $about .= < + + +EOT + $about .= ' \n" . +' \n" . +' \n" . +' \n" . " \n"; + + for my $button (@SECTION_BUTTONS) + { + next if $button eq ' ' || ref($button) eq 'CODE' || ref($button) eq 'SCALAR' || ref($button) eq 'ARRAY'; + $about .= " \n \n"; + $about .= <$BUTTONS_NAME{$button} + + + +EOT + } + + $about .= < + +

    +EOT + $about .= gdt(' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:') . "\n"; + +# where the Example assumes that the current position +# is at Subsubsection One-Two-Three of a document of +# the following structure: + $about .= < + +

      +EOT + $about .= '
    • 1. ' . gdt('Section One') . "\n" . +"
        \n" . +'
      • 1.1 ' . gdt('Subsection One-One') . "\n"; + $about .= < +
      • ...
      • +
      +
    • +EOT + $about .= '
    • 1.2 ' . gdt('Subsection One-Two') . "\n" . +"
        \n" . +'
      • 1.2.1 ' . gdt('Subsubsection One-Two-One') . "
      • \n" . +'
      • 1.2.2 ' . gdt('Subsubsection One-Two-Two') . "
      • \n" . +'
      • 1.2.3 ' . gdt('Subsubsection One-Two-Three') . "    \n" +. +' <== ' . gdt('Current Position') . "
      • \n" . +'
      • 1.2.4 ' . gdt('Subsubsection One-Two-Four') . "
      • \n" . +"
      \n" . +"
    • \n" . +'
    • 1.3 ' . gdt('Subsection One-Three') . "\n"; + $about .= < +
    • ...
    • +
    + +EOT + $about .= '
  • 1.4 ' . gdt('Subsection One-Four') . "
  • \n"; + $about .= < + + +$AFTER_ABOUT +EOT + return $about; +} + +sub HTML_DEFAULT_print_redirection_page() +{ + #my $fh = shift; + my $longtitle = $html_default_title; + $longtitle .= ": $Texi2HTML::SIMPLE_TEXT{'This'}" if (defined ($Texi2HTML::SIMPLE_TEXT{'This'}) and ($Texi2HTML::SIMPLE_TEXT{'This'} !~ /^\s*$/) and ($html_default_title ne $Texi2HTML::SIMPLE_TEXT{'This'})); + my $description = $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'}; + $description = $longtitle if (!defined($description)); + my $encoding = ''; + $encoding = "" if (defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and ($Texi2HTML::THISDOC{'ENCODING_NAME'} ne '')); + my $href = &$anchor('', $Texi2HTML::HREF{'This'}, $Texi2HTML::NAME{'This'}); + my $string = gdt('The node you are looking for is at {href}.', + { 'href' => $href }); + my $doctype = get_conf('doctype'); + my $css_text = ''; + $css_text = $Texi2HTML::THISDOC{'CSS_LINES'} if (defined($Texi2HTML::THISDOC{'CSS_LINES'})); + #print $fh < + + + +$longtitle + + + + + + +$encoding +$css_text + +$EXTRA_HEAD + + + +$AFTER_BODY_OPEN +

    $string

    + +EOT + return $result; +} + +sub html_default_uref($$) +{ + shift; + my $args = shift; + my $url = shift @$args; + my $text = shift @$args; + my $replacement = shift @$args; + $url = main::normalise_space($url); + $replacement = '' if (!defined($replacement)); + $replacement = main::normalise_space($replacement); + $text = '' if (!defined($text)); + $text = main::normalise_space($text); + $text = $replacement if ($replacement ne ''); + $text = $url unless ($text ne ''); + return $text if ($url eq ''); + return &$anchor('', $url, $text); +} + +sub html_default_math($$) +{ + shift; + my $args = shift; + my $text = shift @$args; + return "$text"; +} + +sub html_default_email($$) +{ + my $command = shift; + my $args = shift; + my $mail = shift @$args; + my $text = shift @$args; + $mail = main::normalise_space($mail); + $text = $mail unless (defined($text) and ($text ne '')); + $text = main::normalise_space($text); + return $text if ($mail eq ''); + return &$anchor('', "mailto:$mail", $text); +} + +sub html_default_attribute_class($$) +{ + my $element = shift; + my $class = shift; + return "<$element" if (!defined($class) or $class eq '' or $NO_CSS); + my $style = ''; + if ($INLINE_CSS_STYLE and defined($css_map{"$element.$class"})) + { + $style = ' style="'.$css_map{"$element.$class"}.'"'; + } + return "<$element class=\"$class\"$style"; +} + +# this is called each time a format begins. Here it is used to keep a +# record of the multitables to have a faithful count of the cell nr. +sub html_default_begin_format_texi($$$) +{ + my $command = shift; + my $line = shift; + my $state = shift; + + # first array element is the number of cell in a row + # second is the number of paragraphs in a cell + push (@html_default_multitable_stack, [-1,-1]) if ($command eq 'multitable'); + + return $line; +} + +sub html_default_caption_shortcaption($) +{ + my $float = shift; + my $caption_lines; + my $shortcaption_lines; + my $style = $float->{'style_texi'}; + if (defined($float->{'nr'})) + { + my $nr = $float->{'nr'}; + if ($style ne '') + { + $style = gdt('{style} {number}', { 'style' => $style, 'number' => $nr}); + } + else + { + $style = $nr; + } + } + + if (defined($float->{'caption_texi'})) + { + @$caption_lines = @{$float->{'caption_texi'}}; + $caption_lines->[0] =~ s/^\s*//; + if (defined($style)) + { + $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . gdt('{style}: {caption_first_line}', { 'style' => $style, 'caption_first_line' => $caption_lines->[0] }); + } + else + { + $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $caption_lines->[0]; + } + push @$caption_lines, "}\n"; + } + elsif (defined($style)) + { + $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $style . '}' . "\n"; + } + if (defined($float->{'shortcaption_texi'})) + { + @$shortcaption_lines = @{$float->{'shortcaption_texi'}}; + if (defined($style)) + { + $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . gdt('{style}: {shortcaption_first_line}', { 'style' => $style, 'shortcaption_first_line' => $shortcaption_lines->[0] }); + } + else + { + $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $shortcaption_lines->[0]; + } + push @$shortcaption_lines, "}\n"; + } + elsif (defined($style)) + { + $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $style . '}' . "\n"; + } + return ($caption_lines, $shortcaption_lines); +} + +# everything is done in &$float +sub html_default_caption_shortcaption_command($$$$) +{ + my $command = shift; + my $text = shift; + my $texi_lines = shift; + my $float_element = shift; + return ''; +} + +sub html_default_float($$$$$) +{ + my $text = shift; + my $float = shift; + my $caption = shift; + my $shortcaption = shift; + + my $label = ''; + if (exists($float->{'id'})) + { + $label = &$anchor($float->{'id'}); + } + my $caption_text = ''; + + if (defined($float->{'caption_texi'})) + { + $caption_text = $caption; + } + elsif (defined($float->{'shortcaption_texi'})) + { + $caption_text = $shortcaption; + } + elsif (defined($caption)) + { + $caption_text = $caption; + } + + return html_default_attribute_class('div','float'). '>' . "$label\n" . $text . '' . $caption_text; +} + +sub html_default_listoffloats_float_style($$) +{ + my $style_texi = shift; + my $float = shift; + + my $style = $float->{'style_texi'}; + #print STDERR "listoffloat/float style mismatch $style_texi $style\n" if ($style_texi ne $style); + if (defined($float->{'nr'})) + { + my $nr = $float->{'nr'}; + if ($style ne '') + { + $style = gdt('{style} {number}', { 'style' => $style, 'number' => $nr}); + } + else + { + $style = $nr; + } + } + return $style; +} + +sub html_default_listoffloats_caption($) +{ + my $float = shift; + if (defined($float->{'shortcaption_texi'})) + { + return ([ @{$float->{'shortcaption_texi'}} ], 'shortcaption'); + } + elsif (defined($float->{'caption_texi'})) + { + return ([ @{$float->{'caption_texi'}} ], 'caption'); + } + return ([ ], undef); +} + +sub html_default_listoffloats_entry($$$$) +{ + my $style_texi = shift; + my $float = shift; + my $float_style = shift; + my $caption = shift; + my $href = shift; + + return '
    ' . &$anchor('', $href, $float_style) . '
    ' . $caption +. '
    ' . "\n"; +} + +sub html_default_listoffloats($$$) +{ + my $style_texi = shift; + my $style = shift; + my $float_entries = shift; + + my $result = html_default_attribute_class('dl', 'listoffloats').">\n" ; + foreach my $float_entry (@$float_entries) + { + $result .= $float_entry; + } + return $result . "\n"; +} + +sub html_default_insertcopying($$$) +{ + my $text = shift; + my $comment = shift; + my $simple_text = shift; + return $text; +} + +sub html_default_protect_space_codebreak($$$$$) +{ + my $text = shift; + my $in_raw_text = shift; # remove_texi + my $in_preformatted = shift; + my $in_code = shift; + my $style_stack = shift; + + return $text if ($in_preformatted or $in_raw_text); + + my $in_w = 1 if (in_cmd($style_stack, 'w')); + + if ($in_w or ($in_code and get_conf('allowcodebreaks') eq 'false')) + { + my $class = 'nolinebreak'; + $class = 'nocodebreak' if ($in_code and get_conf('allowcodebreaks') eq 'false'); + my $open = html_default_attribute_class('span', $class).'>'; + # protect spaces in the html leading attribute in case we are in 'w' + $open =~ s/ /\x{1F}/g if ($in_w); + $text =~ s/(\S*[_-]\S*)/${open}$1<\/span>/g; + } + + if ($in_w) + { + $text .= ' ' if (chomp($text)); + # protect spaces within text + $text =~ s/ / /g; + # revert protected spaces in leading html attribute + $text =~ s/\x{1F}/ /g; + } + return $text; +} + +sub html_default_normal_text($$$$$$$;$) +{ + my @initial_args = @_; + my $text = shift; + my $in_raw_text = shift; # remove_texi + my $in_preformatted = shift; + my $in_code = shift; + my $in_math = shift; + my $in_simple = shift; + my $style_stack = shift; + my $state = shift; + + # like utf8.init + if ($ENABLE_ENCODING and !$ENABLE_ENCODING_USE_ENTITY and defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and $Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8') + { + my $result = &t2h_utf8_normal_text(@initial_args); + $result = html_default_protect_space_codebreak($result, $in_raw_text, $in_preformatted, $in_code, $style_stack); + return $result; + } + + $text = uc($text) if (in_cmd($style_stack, 'sc')); + $text = &$protect_text($text) unless($in_raw_text); + #$text =~ s/ / /g + # if (!$in_raw_text and !$in_preformatted and in_cmd($style_stack, 'w')); + if (! $in_code and !$in_preformatted) + { + if ($USE_ISO and !$in_raw_text) + { + $text =~ s/---/\&mdash\;/g; + $text =~ s/--/\&ndash\;/g; + $text =~ s/``/\&ldquo\;/g; + $text =~ s/''/\&rdquo\;/g; + } + else + { + if ($in_raw_text) #FIXME really do that ? It is done by makeinfo + { + $text =~ s/``/"/g; + $text =~ s/''/"/g; + } + else + { + $text =~ s/``/"/g; + $text =~ s/''/"/g; + # to be like texinfo + #$text =~ s/'/\&rsquo\;/g; + #$text =~ s/`/\&lsquo\;/g; + } + # FIXME really do that in raw text? + $text =~ s/---/\x{1F}/g; + $text =~ s/--/-/g; + $text =~ s/\x{1F}/--/g; + } + } + $text = html_default_protect_space_codebreak($text, $in_raw_text, $in_preformatted, $in_code, $style_stack); + $text = t2h_text_substitutions($text, $in_raw_text, ($in_preformatted or $in_code), $in_simple); + return $text; +} + +# This function produces an anchor # -$value{'html'} = 1; # predefine html (the output format) -$value{'texi2html'} = $THISVERSION; # predefine texi2html (the translator) -# _foo: internal to track @foo -foreach ('_author', '_title', '_subtitle', - '_settitle', '_setfilename') { - $value{$_} = ''; # prevent -w warnings +# arguments: +# $name : anchor name +# $href : anchor href +# text : text displayed +# extra_attribs : added to anchor attributes list +sub html_default_anchor($;$$$) +{ + my $name = shift; + my $href = shift; + my $text = shift; + my $attributes = shift; + my $class = ''; +#print STDERR "!$name!$href!$text!$attributes!\n"; + if (!defined($attributes) or ($attributes !~ /\S/)) + { + $attributes = ''; + } + else + { + if ($attributes =~ s/^class=\"([^\"]+)\"//) + { + $class = $1; + } + + $attributes = ' ' . $attributes if ($attributes ne ''); + } + $name = '' if (!defined($name) or ($name !~ /\S/)); + $href = '' if (!defined($href) or ($href !~ /\S/)); + $text = '' if (!defined($text)); + return $text if (($name eq '') and ($href eq '')); + $name = "name=\"$name\"" if ($name ne ''); + $href = "href=\"$href\"" if ($href ne ''); + $href = ' ' . $href if (($name ne '') and ($href ne '')); +#print STDERR "!!!$name!$href!$text!$attributes!\n"; + return html_default_attribute_class('a', $class). " ${name}${href}${attributes}>$text"; } -%node2sec = (); # node to section name -%node2href = (); # node to HREF -%bib2href = (); # bibliography reference to HREF -%gloss2href = (); # glossary term to HREF -@sections = (); # list of sections -%tag2pro = (); # protected sections +# This function is used to format the text associated with a @deff/@end deff # -# initial indexes +# argument: +# text # -$bib_num = 0; -$foot_num = 0; -$gloss_num = 0; -$idx_num = 0; -$sec_num = 0; -$doc_num = 0; -$html_num = 0; +# $DEF_TABLE should be used to distinguish between @def formatted as table +# and as definition lists. +sub html_default_def_item($$$) +{ + my $text = shift; + my $only_inter_item_commands = shift; + my $command = shift; + if ($text =~ /\S/) + { + if (! $DEF_TABLE) + { + return '
    ' . $text . '
    ';# unless $only_inter_item_commands; + #return $text; # invalid without dd in ul + } + else + { + return '
    '; + } + } + return ''; +} +# format the container for the @deffn line and text +# +# argument +# text of the whole @def, line and associated text. # -# can I use ISO8879 characters? (HTML+) +# $DEF_TABLE should be used. +sub html_default_def($$) +{ + my $text = shift; + my $command = shift; + if ($text =~ /\S/) + { + if (! $DEF_TABLE) + { + return "
    \n" . $text . "
    \n"; + } + else + { + return "
    ' . gdt('Button') . " ' . gdt('Name') . " ' . gdt('Go to') . " ' . gdt('From 1.2.3 go to') . "
    "; + $about .= + ($ICONS && $ACTIVE_ICONS{$button} ? + &$button_icon_img($BUTTONS_NAME{$button}, $ACTIVE_ICONS{$button}) : + ' [' . $NAVIGATION_TEXT{$button} . '] '); + $about .= "$BUTTONS_GOTO{$button}$BUTTONS_EXAMPLE{$button}
    ' . $text . '
    \n" . $text . "
    \n"; + } + } + return ''; + +} + +# a whole menu # -if ($use_iso) { - $things_map{'bullet'} = "•"; - $things_map{'copyright'} = "©"; - $things_map{'dots'} = "…"; - $things_map{'equiv'} = "≡"; - $things_map{'expansion'} = "→"; - $things_map{'point'} = "∗"; - $things_map{'result'} = "⇒"; +# argument: +# the whole menu text (entries and menu comments) +# +# argument: +# whole menu text. +sub html_default_menu_command($$$) +{ + my $format = shift; + my $text = shift; + my $in_preformatted = shift; + + $html_menu_entry_index=0; + + my $begin_row = ''; + my $end_row = ''; + if ($in_preformatted) + { + $begin_row = ''; + $end_row = ''; + } + if ($text =~ /\S/) + { + return '' if ($format eq 'direntry'); + return $text if ($format eq 'detailmenu'); + return html_default_attribute_class('table', 'menu')." border=\"0\" cellspacing=\"0\">${begin_row}\n" + . $text . "${end_row}\n"; + } } +# formats a menu entry link pointing to a node or section # -# read texi2html extensions (if any) +# arguments: +# the entry text +# the state, a hash reference holding informations about the context, with a +# usefull entry, 'preformatted', true if we are in a preformatted format +# (a format keeping space between words). In that case a function +# of the main program, main::do_preformatted($text, $state) might +# be used to format the text with the current format style. +# href is optionnal. It is the reference to the section or the node anchor +# which should be used to make the link (typically it is the argument +# of a href= attribute in a element). +sub html_default_menu_link($$$$$$$$) +{ + my $element_name = shift; + my $state = shift; + my $href = shift; + my $node = shift; + my $title = shift; + my $ending = shift; + my $has_title = shift; + my $command_stack = shift; + my $preformatted = shift; + + my $in_commands = 0; + $in_commands = 1 if ($command_stack->[-1] and $command_stack->[-1] ne 'menu' and $command_stack->[-1] ne 'detailmenu' and $command_stack->[-1] ne 'direntry'); + + $title = '' unless ($has_title); +#print STDERR "MENU_LINK($in_commands)($state->{'preformatted'})\n"; + my $entry; + my $symbol = ''; + if ($preformatted) + { + $title .= ':' if ($title ne ''); + $entry = "$MENU_SYMBOL$title$node"; + } + elsif ($element_name eq '' or $NODE_NAME_IN_MENU) + { + if ($has_title) + { + $entry = "$title"; + } + else + { + $entry = "$node"; + } + $entry =~ s/^\s*//; + $symbol = "$MENU_SYMBOL "; + } + else + { + $entry = $element_name; + } + $html_menu_entry_index++; + my $accesskey; + $accesskey = "accesskey=\"$html_menu_entry_index\"" if ($USE_ACCESSKEY and ($html_menu_entry_index < 10)); + $entry = &$anchor ('', $href, $entry, $accesskey) if (defined($href)); + + return $entry.$ending if ($preformatted); + # FIXME conditionalise to not having a description + return "$symbol$entry$MENU_ENTRY_COLON" .' ' if ($in_commands); + return "$symbol$entry$MENU_ENTRY_COLON  "; +} + +sub html_simplify_text($) +{ + my $text = shift; + $text =~ s/[^\w]//og; + return $text; +} + +# formats a menu entry description, ie the text appearing after the node +# specification in a menu entry an spanning until there is another +# menu entry, or empty line # -$extensions = 'texi2html.ext'; # extensions in working directory -if (-f $extensions) { - print "# reading extensions from $extensions\n" if $verbose; - require($extensions); +# arguments: +# the description text +# the state. See menu_entry. +# the heading of the element associated with the node. +sub html_default_menu_description($$$$) +{ + my $text = shift; + my $state = shift; + my $element_text = shift; + my $command_stack = shift; + my $preformatted = shift; + + my $in_commands = 0; + $in_commands = 1 if ($command_stack->[-1] and $command_stack->[-1] ne 'menu' and $command_stack->[-1] ne 'detailmenu' and $command_stack->[-1] ne 'direntry'); + return $text if ($preformatted); + return $text."
    " if ($in_commands); + if ($AVOID_MENU_REDUNDANCY) + { + $text = '' if (html_simplify_text($element_text) eq html_simplify_text($text)); + } + return "$text\n"; } -($progdir = $0) =~ s/[^\/]+$//; -if ($progdir && ($progdir ne './')) { - $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory - if (-f $extensions) { - print "# reading extensions from $extensions\n" if $verbose; - require($extensions); + +sub html_teletyped_in_stack($) +{ + my $stack = shift; + foreach my $element(reverse(@$stack)) + { + return 1 if ($complex_format_map{$element} and + $complex_format_map{$element}->{'style'} and + $complex_format_map{$element}->{'style'} eq 'code'); } + return 0; } -print "# reading from $docu\n" if $verbose; +# text after @item in table, vtable and ftable +sub html_default_table_item($$$$$$$) +{ + my $text = shift; + my $index_label = shift; + my $format = shift; + my $command = shift; +# my $formatted_command = shift; + my $style_stack = shift; +# my $text_formatted = shift; +# my $text_formatted_leading_spaces = shift; +# my $text_formatted_trailing_spaces = shift; + my $item_cmd = shift; + my $formatted_index_entry = shift; -#+++############################################################################ -# # -# Pass 1: read source, handle command, variable, simple substitution # -# # -#---############################################################################ +# if (defined($text_formatted) and !exists $special_list_commands{$format}->{$command}) +# { +# $text = $text_formatted_leading_spaces . $text_formatted .$text_formatted_trailing_spaces; +# } +# $formatted_command = '' if (!defined($formatted_command) or +# exists($special_list_commands{$format}->{$command})); + if (html_teletyped_in_stack($style_stack)) + { +# $text .= ''; +# $formatted_command = '' . $formatted_command; + $text = '' . $text . ''; + } + $text .= "\n" . $index_label if (defined($index_label)); +# return '

    ' . $formatted_command . $text . '
    ' . "\n"; + return '
    ' . $text . '
    ' . "\n"; +} -@lines = (); # whole document -@toc_lines = (); # table of contents -$toplevel = 0; # top level seen in hierarchy -$curlevel = 0; # current level in TOC -$node = ''; # current node name -$in_table = 0; # am I inside a table -$table_type = ''; # type of table ('', 'f', 'v', 'multi') -@tables = (); # nested table support -$in_bibliography = 0; # am I inside a bibliography -$in_glossary = 0; # am I inside a glossary -$in_top = 0; # am I inside the top node -$in_pre = 0; # am I inside a preformatted section -$in_list = 0; # am I inside a list -$in_html = 0; # am I inside an HTML section -$first_line = 1; # is it the first line -$dont_html = 0; # don't protect HTML on this line -$split_num = 0; # split index -$deferred_ref = ''; # deferred reference for indexes -@html_stack = (); # HTML elements stack -$html_element = ''; # current HTML element -&html_reset; +# format text on the line following the @item line (in table, vtable and ftable) +sub html_default_table_line($$$) +{ + my $text = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; -# build code for simple substitutions -# the maps used (%simple_map and %things_map) MUST be aware of this -# watch out for regexps, / and escaped characters! -$subst_code = ''; -foreach (keys(%simple_map)) { - ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars - $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n"; + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + if ($text =~ /\S/) + { + return '
    ' . $text . '
    ' . "\n";# unless ($only_inter_item_commands); + #return $text; # invalid without dd in ul + } + return ''; } -foreach (keys(%things_map)) { - $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n"; + +#my $cell_nr = -1; + +# row in multitable +sub html_default_row($$$$$$$$) +{ + my $text = shift; + my $macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + # this is used to keep the cell number + $html_default_multitable_stack[-1]->[0] = -1; + + if ($text =~ /\S/) + { + if ($macro eq 'headitem') + { + return '' . $text . '' . "\n"; + } + return '' . $text . '' . "\n"; + } + return ''; } -if ($use_acc) { - # accentuated characters - foreach (keys(%accent_map)) { - if ($_ eq "`") { - $subst_code .= "s/$;3"; - } elsif ($_ eq "'") { - $subst_code .= "s/$;4"; - } else { - $subst_code .= "s/\\\@\\$_"; - } - $subst_code .= "([aeiou])/&\${1}$accent_map{$_};/gi;\n"; + +# cell in multitable +sub html_default_cell($$$$$$$$) +{ + my $text = shift; + my $row_macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + $html_default_multitable_stack[-1]->[0]++; + my $cell_nr = $html_default_multitable_stack[-1]->[0]; + my $fractions = ''; + + if (defined($columnfractions) and (ref($columnfractions) eq 'ARRAY') + and exists($columnfractions->[$cell_nr])) + { + my $fraction = sprintf('%d', 100*$columnfractions->[$cell_nr]); + $fractions = " width=\"$fraction%\""; } + + # in constructs like + # @strong{ + # @multitable .... + # } + # the space won't be removed since the is put before the space. + $text =~ s/^\s*//; + $text =~ s/\s*$//; + + if ($row_macro eq 'headitem') + { + return "" . $text . ''; + } + return "" . $text . ''; } -eval("sub simple_substitutions { $subst_code }"); -&init_input; -while ($_ = &next_line) { - # - # remove \input on the first lines only - # - if ($first_line) { - next if /^\\input/; - $first_line = 0; +sub html_default_format_list_item_texi($$$$$) +{ + my $format = shift; + my $line = shift; + my $prepended = shift; + my $command = shift; + my $number = shift; + + my $result_line; + my $open_command = 0; + if (defined($command) and $command ne '' and !exists $special_list_commands{$format}->{$command} and $format ne 'itemize') + { + #@*table + $open_command = 1; + $line =~ s/^\s*//; + $line =~ s/\s*$//; + if (exists ($style_map{$command})) + { + $result_line = "\@$command\{$line\}\n"; + } + elsif (exists ($things_map{$command})) + { + $result_line = "\@$command\{\} $line\n"; + } + else + { + $result_line = "\@$command $line\n"; + } } - # - # parse texinfo tags - # - $tag = ''; - $end_tag = ''; - if (/^\s*\@end\s+(\w+)\b/) { - $end_tag = $1; - } elsif (/^\s*\@(\w+)\b/) { - $tag = $1; + elsif (defined($prepended) and $prepended ne '') + { + $prepended =~ s/^\s*//; + $prepended =~ s/\s*$//; + $line =~ s/^\s*//; + $result_line = $prepended . ' ' . $line; } - # - # handle @ifhtml / @end ifhtml - # - if ($in_html) { - if ($end_tag eq 'ifhtml') { - $in_html = 0; - } else { - $tag2pro{$in_html} .= $_; - } - next; - } elsif ($tag eq 'ifhtml') { - $in_html = $PROTECTTAG . ++$html_num; - push(@lines, $in_html); - next; + return ($result_line, $open_command); +} + + +# format an item in a list +# +# argument: +# text of the item +# format of the list (itemize or enumerate) +# command passed as argument to the format +# formatted_command leading command formatted, if it is a thing command +sub html_default_list_item($$$$$$$$$$$) +{ + my $text = shift; + my $format = shift; + my $command = shift; + my $formatted_command = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $prepended = shift; + my $prepended_formatted = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + + $formatted_command = '' if (!defined($formatted_command) or + exists($special_list_commands{$format}->{$command})); + my $prepend = ''; +# if (defined($prepended) and $prepended ne '') +# { +# $prepend = $prepended; +# } +# elsif ($formatted_command ne '') + if ($formatted_command ne '') + { + $prepend = $formatted_command; } - # - # try to skip the line - # - if ($end_tag) { - next if $to_skip{"end $end_tag"}; - } elsif ($tag) { - next if $to_skip{$tag}; - last if $tag eq 'bye'; + if ($text =~ /\S/) + { + return '
  • ' . $prepend . $text . '
  • '; } - if ($in_top) { - # parsing the top node - if ($tag eq 'node' || $tag eq 'include' || $sec2level{$tag}) { - # no more in top - $in_top = 0; - } else { - # skip it - next; - } + return ''; +} + +sub html_default_table_list($$$$$$$$$) +{ + my $format_command = shift; + my $text = shift; + my $command = shift; + my $formatted_command = shift; +# enumerate + my $item_nr = shift; + my $enumerate_style = shift; +# itemize + my $prepended = shift; + my $prepended_formatted = shift; +# multitable + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; +# my $number = shift; + $formatted_command = '' if (!defined($formatted_command) or + exists($special_list_commands{$format}->{$command})); + if ($format_command eq 'itemize') + { + return "
      \n" . $text . "
    \n" if (($command eq 'bullet') or (($command eq '') and ($prepended eq ''))); + return html_default_attribute_class('ul',$NO_BULLET_LIST_CLASS).">\n" . $text . "\n"; } - # - # try to remove inlined comments - # syntax from tex-mode.el comment-start-skip - # - s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/; - # non-@ substitutions cf. texinfmt.el - unless ($in_pre) { - s/``/\"/g; - s/''/\"/g; - s/([\w ])---([\w ])/$1--$2/g; + elsif ($format_command eq 'multitable') + { + pop @html_default_multitable_stack; + return &$format('multitable', 'table', $text); } - # - # analyze the tag - # - if ($tag) { - # skip lines - &skip_until($tag), next if $tag eq 'ignore'; - if ($expandinfo) { - &skip_until($tag), next if $tag eq 'iftex'; - } else { - &skip_until($tag), next if $tag eq 'ifinfo'; - } - &skip_until($tag), next if $tag eq 'tex'; - # handle special tables - if ($tag =~ /^(|f|v|multi)table$/) { - $table_type = $1; - $tag = 'table'; - } - # special cases - if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) { - $in_top = 1; - @lines = (); # ignore all lines before top (title page garbage) - next; - } elsif ($tag eq 'node') { - $in_top = 0; - warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o; - $_ = &protect_html($_); # if node contains '&' for instance - s/^\@node\s+//; - ($node) = split(/,/); - &normalise_node($node); - if ($split_node) { - &next_doc; - push(@lines, $SPLITTAG) if $split_num++; - push(@sections, $node); - } - next; - } elsif ($tag eq 'include') { - if (/^\@include\s+($FILERE)\s*$/o) { - $file = $1; - unless (-e $file) { - foreach $dir (@include_dirs) { - $file = "$dir/$1"; - last if -e $file; - } - } - if (-e $file) { - &open($file); - print "# including $file\n" if $verbose; - } else { - warn "$ERROR Can't find $file, skipping"; - } - } else { - warn "$ERROR Bad include line: $_"; - } - next; - } elsif ($tag eq 'ifclear') { - if (/^\@ifclear\s+($VARRE)\s*$/o) { - next unless defined($value{$1}); - &skip_until($tag); - } else { - warn "$ERROR Bad ifclear line: $_"; - } - next; - } elsif ($tag eq 'ifset') { - if (/^\@ifset\s+($VARRE)\s*$/o) { - next if defined($value{$1}); - &skip_until($tag); - } else { - warn "$ERROR Bad ifset line: $_"; - } - next; - } elsif ($tag eq 'menu') { - unless ($show_menu) { - &skip_until($tag); - next; - } - &html_push_if($tag); - push(@lines, &html_debug("\n", __LINE__)); - } elsif ($format_map{$tag}) { - $in_pre = 1 if $format_map{$tag} eq 'PRE'; - &html_push_if($format_map{$tag}); - push(@lines, &html_debug("\n", __LINE__)); - $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ; - push(@lines, &debug("<$format_map{$tag}>\n", __LINE__)); - next; - } elsif ($tag eq 'table') { - if (/^\s*\@(|f|v|multi)table\s+\@(\w+)/) { - $in_table = $2; - unshift(@tables, join($;, $table_type, $in_table)); - if ($table_type eq "multi") { - push(@lines, &debug("\n", __LINE__)); - &html_push_if('TABLE'); - } else { - push(@lines, &debug("
    \n", __LINE__)); - &html_push_if('DL'); - } - push(@lines, &html_debug("\n", __LINE__)); - } else { - warn "$ERROR Bad table line: $_"; - } - next; - } elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') { - if (/^\@$tag\s+(\w)\w\s+(\w)\w\s*$/) { - eval("*${1}index = *${2}index"); - } else { - warn "$ERROR Bad syn*index line: $_"; - } - next; - } elsif ($tag eq 'sp') { - push(@lines, &debug("

    \n", __LINE__)); - next; - } elsif ($tag eq 'setref') { - &protect_html; # if setref contains '&' for instance - if (/^\@$tag\s*{($NODERE)}\s*$/) { - $setref = $1; - $setref =~ s/\s+/ /g; # normalize - $setref =~ s/ $//; - $node2sec{$setref} = $name; - $node2href{$setref} = "$docu_doc#$docid"; - } else { - warn "$ERROR Bad setref line: $_"; - } - next; - } elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') { - if (/^\@$tag\s+(\w\w)\s*$/) { - $valid_index{$1} = 1; - } else { - warn "$ERROR Bad defindex line: $_"; - } - next; - } elsif ($tag eq 'lowersections') { - local ($sec, $level); - while (($sec, $level) = each %sec2level) { - $sec2level{$sec} = $level + 1; - } - next; - } elsif ($tag eq 'raisesections') { - local ($sec, $level); - while (($sec, $level) = each %sec2level) { - $sec2level{$sec} = $level - 1; - } - next; - } elsif (defined($def_map{$tag})) { - if ($def_map{$tag}) { - s/^\@$tag\s+//; - $tag = $def_map{$tag}; - $_ = "\@$tag $_"; - $tag =~ s/\s.*//; - } - } elsif (defined($user_sub{$tag})) { - s/^\@$tag\s+//; - $sub = $user_sub{$tag}; - print "# user $tag = $sub, arg: $_" if $debug & $DEBUG_USER; - if (defined(&$sub)) { - chop($_); - &$sub($_); - } else { - warn "$ERROR Bad user sub for $tag: $sub\n"; - } - next; - } - if (defined($def_map{$tag})) { - s/^\@$tag\s+//; - if ($tag =~ /x$/) { - # extra definition line - $tag = $`; - $is_extra = 1; - } else { - $is_extra = 0; - } - while (/\{([^\{\}]*)\}/) { - # this is a {} construct - ($before, $contents, $after) = ($`, $1, $'); - # protect spaces - $contents =~ s/\s+/$;9/g; - # restore $_ protecting {} - $_ = "$before$;7$contents$;8$after"; - } - @args = split(/\s+/, &protect_html($_)); - foreach (@args) { - s/$;9/ /g; # unprotect spaces - s/$;7/\{/g; # ... { - s/$;8/\}/g; # ... } - } - $type = shift(@args); - $type =~ s/^\{(.*)\}$/$1/; - print "# def ($tag): {$type} ", join(', ', @args), "\n" - if $debug & $DEBUG_DEF; - $type .= ':'; # it's nicer like this - $name = shift(@args); - $name =~ s/^\{(.*)\}$/$1/; - if ($is_extra) { - $_ = &debug("

    ", __LINE__); - } else { - $_ = &debug("
    \n
    ", __LINE__); - } - if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') { - $_ .= "$type $name"; - $_ .= " @args" if @args; - } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr' - || $tag eq 'defcv' || $tag eq 'defop') { - $ftype = $name; - $name = shift(@args); - $name =~ s/^\{(.*)\}$/$1/; - $_ .= "$type $ftype $name"; - $_ .= " @args" if @args; - } else { - warn "$ERROR Unknown definition type: $tag\n"; - $_ .= "$type $name"; - $_ .= " @args" if @args; - } - $_ .= &debug("\n
    ", __LINE__); - $name = &unprotect_html($name); - if ($tag eq 'deffn' || $tag eq 'deftypefn') { - unshift(@input_spool, "\@findex $name\n"); - } elsif ($tag eq 'defop') { - unshift(@input_spool, "\@findex $name on $ftype\n"); - } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') { - unshift(@input_spool, "\@vindex $name\n"); - } else { - unshift(@input_spool, "\@tindex $name\n"); - } - $dont_html = 1; - } - } elsif ($end_tag) { - if ($format_map{$end_tag}) { - $in_pre = 0 if $format_map{$end_tag} eq 'PRE'; - $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ; - &html_pop_if('LI', 'P'); - &html_pop_if(); - push(@lines, &debug("\n", __LINE__)); - push(@lines, &html_debug("\n", __LINE__)); - } elsif ($end_tag =~ /^(|f|v|multi)table$/) { - unless (@tables) { - warn "$ERROR \@end $end_tag without \@*table\n"; - next; - } - ($table_type, $in_table) = split($;, shift(@tables)); - unless ($1 eq $table_type) { - warn "$ERROR \@end $end_tag without matching \@$end_tag\n"; - next; - } - if ($table_type eq "multi") { - push(@lines, "
    \n"); - &html_pop_if('TR'); - } else { - push(@lines, "\n"); - &html_pop_if('DD'); - } - &html_pop_if(); - if (@tables) { - ($table_type, $in_table) = split($;, $tables[0]); - } else { - $in_table = 0; - } - } elsif (defined($def_map{$end_tag})) { - push(@lines, &debug("\n", __LINE__)); - } elsif ($end_tag eq 'menu') { - &html_pop_if(); - push(@lines, $_); # must keep it for pass 2 - } - next; +} + +# a paragraph +# arguments: +# $text of the paragraph +# $align for the alignement +# $indent for the indent style (indent or noindent) +# The following is usefull if the paragraph is in an itemize. +# $paragraph_command is the leading formatting command (like @minus) +# $paragraph_command_formatted is the leading formatting command formatted +# $paragraph_number is a reference on the number of paragraphs appearing +# in the format. The value should be increased if a paragraph is done +# $format is the format name (@itemize) +sub html_default_paragraph($$$$$$$$$$$$) +{ + my $text = shift; + my $align = shift; + my $indent = shift; + my $paragraph_command = shift; + my $paragraph_command_formatted = shift; + my $paragraph_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; +#print STDERR "format: $format\n" if (defined($format)); +#print STDERR "paragraph @$command_stack_at_end; @$command_stack_at_begin\n"; +# $paragraph_command_formatted = '' if (!defined($paragraph_command_formatted) or +# exists($special_list_commands{$format}->{$paragraph_command})); + return '' if ($text =~ /^\s*$/); + + if (defined($paragraph_number) and defined($$paragraph_number)) + { + $$paragraph_number++; + return $text if (($format eq 'itemize' or $format eq 'enumerate') and + ($$paragraph_number == 1)); } - # - # misc things - # - # protect texi and HTML things - &protect_texi; - $_ = &protect_html($_) unless $dont_html; - $dont_html = 0; - # substitution (unsupported things) - s/^\@center\s+//g; - s/^\@exdent\s+//g; - s/\@noindent\s+//g; - s/\@refill\s+//g; - # other substitutions - &simple_substitutions; - s/\@value{($VARRE)}/$value{$1}/eg; - s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4 - # - # analyze the tag again - # - if ($tag) { - if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) { - if (/^\@$tag\s+(.+)$/) { - $name = $1; - $name =~ s/\s+$//; - $level = $sec2level{$tag}; - $name = &update_sec_num($tag, $level) . " $name" - if $number_sections && $tag !~ /^unnumbered/; - if ($tag =~ /heading$/) { - push(@lines, &html_debug("\n", __LINE__)); - if ($html_element ne 'body') { - # We are in a nice pickle here. We are trying to get a H? heading - # even though we are not in the body level. So, we convert it to a - # nice, bold, line by itself. - $_ = &debug("\n\n

    $name\n\n", __LINE__); - } else { - $_ = &debug("$name\n", __LINE__); - &html_push_if('body'); - } - print "# heading, section $name, level $level\n" - if $debug & $DEBUG_TOC; - } else { - if ($split_chapter) { - unless ($toplevel) { - # first time we see a "section" - unless ($level == 1) { - warn "$ERROR The first section found is not of level 1: $_"; - warn "$ERROR I'll split on sections of level $level...\n"; - } - $toplevel = $level; - } - if ($level == $toplevel) { - &next_doc; - push(@lines, $SPLITTAG) if $split_num++; - push(@sections, $name); - } - } - $sec_num++; - $docid = "SEC$sec_num"; - $tocid = "TOC$sec_num"; - # check biblio and glossary - $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i); - $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i); - # check node - if ($node) { - if ($node2sec{$node}) { - warn "$ERROR Duplicate node found: $node\n"; - } else { - $node2sec{$node} = $name; - $node2href{$node} = "$docu_doc#$docid"; - print "# node $node, section $name, level $level\n" - if $debug & $DEBUG_TOC; - } - $node = ''; - } else { - print "# no node, section $name, level $level\n" - if $debug & $DEBUG_TOC; - } - # update TOC - while ($level > $curlevel) { - $curlevel++; - push(@toc_lines, "

      \n"); - } - while ($level < $curlevel) { - $curlevel--; - push(@toc_lines, "
    \n"); - } - $_ = "
  • " . &anchor($tocid, "$docu_doc#$docid", $name, 1); - push(@toc_lines, &substitute_style($_)); - # update DOC - push(@lines, &html_debug("\n", __LINE__)); - &html_reset; - $_ = "".&anchor($docid, "$docu_toc#$tocid", $name)."\n"; - $_ = &debug($_, __LINE__); - push(@lines, &html_debug("\n", __LINE__)); - } - # update DOC - foreach $line (split(/\n+/, $_)) { - push(@lines, "$line\n"); - } - next; - } else { - warn "$ERROR Bad section line: $_"; - } - } else { - # track variables - $value{$1} = $2, next if /^\@set\s+($VARRE)\s+(.*)$/o; - delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o; - # store things - $value{'_setfilename'} = $1, next if /^\@setfilename\s+(.*)$/; - $value{'_settitle'} = $1, next if /^\@settitle\s+(.*)$/; - $value{'_author'} .= "$1\n", next if /^\@author\s+(.*)$/; - $value{'_subtitle'} .= "$1\n", next if /^\@subtitle\s+(.*)$/; - $value{'_title'} .= "$1\n", next if /^\@title\s+(.*)$/; - # index - if (/^\@(..?)index\s+/) { - unless ($valid_index{$1}) { - warn "$ERROR Undefined index command: $_"; - next; - } - $id = 'IDX' . ++$idx_num; - $index = $1 . 'index'; - $what = &substitute_style($'); - $what =~ s/\s+$//; - print "# found $index for '$what' id $id\n" - if $debug & $DEBUG_INDEX; - eval(<\n", __LINE__)); - push(@lines, &anchor($id, '', $invisible_mark, !$in_pre)); - &html_push('P'); - } elsif ($html_element eq 'DL' || - $html_element eq 'UL' || - $html_element eq 'OL' ) { - $deferred_ref .= &anchor($id, '', $invisible_mark, !$in_pre) . " "; - } - next; - } - # list item - if (/^\s*\@itemx?\s+/) { - $what = $'; - $what =~ s/\s+$//; - if ($in_bibliography && $use_bibliography) { - if ($what =~ /^$BIBRE$/o) { - $id = 'BIB' . ++$bib_num; - $bib2href{$what} = "$docu_doc#$id"; - print "# found bibliography for '$what' id $id\n" - if $debug & $DEBUG_BIB; - $what = &anchor($id, '', $what); - } - } elsif ($in_glossary && $use_glossary) { - $id = 'GLOSS' . ++$gloss_num; - $entry = $what; - $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; - $gloss2href{$entry} = "$docu_doc#$id"; - print "# found glossary for '$entry' id $id\n" - if $debug & $DEBUG_GLOSS; - $what = &anchor($id, '', $what); - } - &html_pop_if('P'); - if ($html_element eq 'DL' || $html_element eq 'DD') { - if ($things_map{$in_table} && !$what) { - # special case to allow @table @bullet for instance - push(@lines, &debug("
    $things_map{$in_table}\n", __LINE__)); - } else { - push(@lines, &debug("
    \@$in_table\{$what\}\n", __LINE__)); - } - push(@lines, "
    "); - &html_push('DD') unless $html_element eq 'DD'; - if ($table_type) { # add also an index - unshift(@input_spool, "\@${table_type}index $what\n"); - } - } elsif ($html_element eq 'TABLE') { - push(@lines, &debug("$what\n", __LINE__)); - &html_push('TR'); - } elsif ($html_element eq 'TR') { - push(@lines, &debug("\n", __LINE__)); - push(@lines, &debug("$what\n", __LINE__)); - } else { - push(@lines, &debug("
  • $what\n", __LINE__)); - &html_push('LI') unless $html_element eq 'LI'; - } - push(@lines, &html_debug("\n", __LINE__)); - if ($deferred_ref) { - push(@lines, &debug("$deferred_ref\n", __LINE__)); - $deferred_ref = ''; - } - next; - } elsif (/^\@tab\s+(.*)$/) { - push(@lines, "$1\n"); - next; - } - } + + my $top_stack = ''; + $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); + if ($top_stack eq 'multitable') + { + $html_default_multitable_stack[-1]->[1]++; + if ($html_default_multitable_stack[-1]->[1] == 0) + { + return $text; + } } - # paragraph separator - if ($_ eq "\n") { - next if $#lines >= 0 && $lines[$#lines] eq "\n"; - if ($html_element eq 'P') { - push(@lines, "\n"); - $_ = &debug("\n", __LINE__); - &html_pop; - } - } elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE') { - push(@lines, "

    \n"); - &html_push('P'); - $_ = &debug($_, __LINE__); + + my $open = '

    '; + if ($align) + { + $open = "

    "; } - # otherwise - push(@lines, $_); + return $open.$text.'

    '; } -# finish TOC -$level = 0; -while ($level < $curlevel) { - $curlevel--; - push(@toc_lines, "\n"); +# a preformatted region +# arguments: +# $text of the preformatted region +# $pre_style css style +# $class identifier for the preformatted region (example, menu-comment) +# The following is usefull if the preformatted is in an itemize. +# $leading_command is the leading formatting command (like @minus) +# $leading_command_formatted is the leading formatting command formatted +# $preformatted_number is a reference on the number of preformatteds appearing +# in the format. The value should be increased if a preformatted is done +sub html_default_preformatted($$$$$$$$$$$$) +{ + my $text = shift; + my $pre_style = shift; + my $class = shift; + my $leading_command = shift; + my $leading_command_formatted = shift; + my $preformatted_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + +#print STDERR "preformatted @$command_stack_at_end; @$command_stack_at_begin\n"; + return '' if ($text eq ''); + $leading_command_formatted = '' if (!defined($leading_command_formatted) or + exists($special_list_commands{$format}->{$leading_command})); + if (defined($preformatted_number) and defined($$preformatted_number)) + { + $$preformatted_number++; + } + my $top_stack = ''; + $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); + if ($top_stack eq 'multitable') + { + $text =~ s/^\s*//; + $text =~ s/\s*$//; + } + + return html_default_attribute_class('pre', $class).">".$text.""; } -print "# end of pass 1\n" if $verbose; +sub html_default_heading_text($$$) +{ + my $command = shift; + my $text = shift; + my $level = shift; + return '' if ($text !~ /\S/); + # FIXME use a class=*contents? + my $class = ''; + if ($command =~ /^@/ and $command !~ /^@.*contents$/) + { + $class = $command; + $class =~ s/^@//; + $class = 'node-heading' if ($command eq '@node'); + } + my $align = ''; + $align = ' align="center"' if ($command eq '@centerchap' or $command eq '@settitle'); + $level = 1 if ($level == 0); + my $result = html_default_attribute_class ("h$level", $class) ."$align>$text"; + # FIXME titlefont appears inline in text, so no end of line is + # added. The end of line should be added by the user if needed. + $result .= "\n" unless ($command eq '@titlefont'); + $result .= $DEFAULT_RULE . "\n" if ($command eq '@part' and defined($DEFAULT_RULE) and $DEFAULT_RULE ne ''); + return $result; +} + +sub html_default_heading_text_preformatted($$$) +{ + my $command = shift; + my $text = shift; + my $level = shift; + + return '' if ($text !~ /\S/); + return ''.$text.''."\n"; +} + +# formatting of raw regions +# if L2H is true another mechanism is used for tex +sub html_default_raw($$;$) +{ + my $style = shift; + my $text = shift; + my $line_nr = shift; + my $expanded = 1 if (grep {$style eq $_} @EXPAND); + if ($style eq 'verbatim' or $style eq 'verbatiminclude' or ($style eq 'tex' and $expanded)) + { + $style = 'verbatim' if ($style eq 'verbatiminclude'); + return html_default_attribute_class('pre', $style).">" . &$protect_text($text) . ''; + } + elsif ($style eq 'html' and $expanded) + { + chomp ($text); + return $text; + } + elsif ($expanded) + { + main::line_warn (sprintf(__("Raw format %s is not converted"), $style), $line_nr); + return &$protect_text($text); + } + else + { + return ''; + } +} + +# This function formats a footnote reference and the footnote text associated +# with a given footnote. +# The footnote reference is the text appearing in the main document pointing +# to the footnote text. +# +# arguments: +# absolute number of the footnote (in the document) +# relative number of the footnote (in the page) +# identifier for the footnote +# identifier for the footnote reference in the main document +# main document file +# footnote text file +# array with the footnote text lines +# the state. See menu entry. +# +# returns: +# reference on an array containing the footnote text lines which should +# have been updated +# the text for the reference pointing on the footnote text +sub html_default_foot_line_and_ref($$$$$$$$$) +{ + my $number_in_doc = shift; + my $number_in_page = shift; + my $footnote_id = shift; + my $place_id = shift; + my $document_file = shift; + my $footnote_file = shift; + my $lines = shift; + my $document_state = shift; + + if ($document_file eq $footnote_file) + { + $document_file = $footnote_file = ''; + } + + $number_in_doc = $NO_NUMBER_FOOTNOTE_SYMBOL if (!$NUMBER_FOOTNOTES); + + unshift (@$lines, '

    ' . + &$anchor($footnote_id, $document_file . "#$place_id", + "($number_in_doc)") + . "

    \n"); + # this is a bit obscure, this allows to add an anchor only if formatted + # as part of the document. + #$place_id = '' if ($document_state->{'outside_document'} or $document_state->{'multiple_pass'} or $document_state->{'expansion'}); + $place_id = '' if ($document_state->{'outside_document'} or (defined($document_state->{'multiple_pass'}) and $document_state->{'multiple_pass'} > 0)); + return ($lines, &$anchor($place_id, $footnote_file . "#$footnote_id", + "($number_in_doc)")); +} + +# formats a group of footnotes. +# +# argument: +# array reference on the footnotes texts lines +# +# returns an array reference on the group of footnotes lines +sub html_default_foot_section($) +{ + my $lines = shift; + unshift (@$lines, html_default_attribute_class('div', 'footnote').">\n" ,"$DEFAULT_RULE\n", + &$heading_text('footnotes', gdt('Footnotes'), 3) + ); + push (@$lines, "\n"); + return $lines; +} + +sub html_default_image_files($$$$) +{ + my $base = shift; + my $extension = shift; + my $texi_base = shift; + my $texi_extension = shift; + my @files = (); + return @files if (!defined($base) or ($base eq '')); + if (defined($extension) and ($extension ne '')) + { + push @files,["$base.$extension", "$texi_base.$texi_extension"]; + } + foreach my $ext (@IMAGE_EXTENSIONS) + { + push @files,["$base.$ext", "$texi_base.$ext"]; + } + return @files; +} + +# format an image +# +# arguments: +# image file name with path +# image basename +# a boolean true if we are in a preformatted format +# image file name without path +# alt text +# width +# height +# raw alt +# extension +# path to working dir +# path to file relative from working dir +sub html_default_image($$$$$$$$$$$$$$$$$) +{ + my $file = shift; + my $base = shift; + my $preformatted = shift; + my $file_name = shift; + my $alt = shift; + my $width = shift; + my $height = shift; + my $raw_alt = shift; + my $extension = shift; + my $working_dir = shift; + my $file_path = shift; + my $in_paragraph = shift; + my $file_locations = shift; + my $base_simple_format = shift; + my $extension_simple_format = shift; + my $file_name_simple_format = shift; + my $line_nr = shift; + + if (!defined($file_path) or $file_path eq '') + { + if (defined($extension) and $extension ne '') + { + $file = "$base.$extension"; + } + else + { + $file = "$base.jpg"; + } + main::line_warn (sprintf(__("\@image file `%s' (for HTML) not found, using `%s'"), $base, $file), $line_nr); + } + elsif (! $COMPLETE_IMAGE_PATHS) + { + $file = $file_name; + } + $alt = &$protect_text($base) if (!defined($alt) or ($alt eq '')); + return "[ $alt ]" if ($preformatted); + # it is possible that $file_name is more correct as it allows the user + # to chose the relative path. + $file = &$protect_text($file); + return "\"$alt\""; +} + +# format a target in the main document for an index entry. +# +# arguments: +# target identifier +# boolean true if in preformatted format +# FIXME document the remaining +sub html_default_index_entry_label($$$$$$$$$) +{ + my $identifier = shift; + my $preformatted = shift; + my $entry = shift; + my $index_name = shift; + my $index_command = shift; + my $texi_entry = shift; + my $formatted_entry = shift; + my $in_region_not_in_output = shift; + my $index_entry_ref = shift; + + return '' if (!defined($identifier) or ($identifier !~ /\S/)); + my $label = &$anchor($identifier); + return $label . "\n" if (!$preformatted); + return $label; +} + +sub html_default_index_entry_command($$$$$$) +{ + my $command = shift; + my $index_name = shift; + my $label = shift; + my $entry_texi = shift; + my $entry_formatted = shift; + my $index_entry_ref = shift; + + return $label; +} + +# process definition commands line @deffn for example +sub html_default_def_line($$$$$$$$$$$$$$$$) +{ + my $category_prepared = shift; + my $name = shift; + my $type = shift; + my $arguments = shift; + my $index_label = shift; + my $arguments_array = shift; + my $arguments_type_array = shift; + my $unformatted_arguments_array = shift; + my $command = shift; + my $class_name = shift; + my $category = shift; + my $class = shift; + my $style = shift; + my $original_command = shift; + + $index_label = '' if (!defined($index_label)); + chomp($index_label); + $category_prepared = '' if (!defined($category_prepared) or ($category_prepared =~ /^\s*$/)); + $name = '' if (!defined($name) or ($name =~ /^\s*$/)); + $type = '' if (!defined($type) or $type =~ /^\s*$/); + if (!defined($arguments) or $arguments =~ /^\s*$/) + { + $arguments = ''; + } + else + { + chomp ($arguments); + $arguments = '' . $arguments . ''; + } + my $type_name = ''; + $type_name = " $type" if ($type ne ''); + $type_name .= ' ' . $name . '' if ($name ne ''); + $type_name .= $arguments; + if (! $DEF_TABLE) + { + return '
    '. $index_label. $category_prepared . ':' . $type_name . "
    \n"; + } + else + { + return "" . $type_name . + "" . $category_prepared . $index_label . "\n"; + } +} + +# a cartouche +sub html_default_cartouche($$) +{ + my $text = shift; + + if ($text =~ /\S/) + { + return html_default_attribute_class('table', 'cartouche')." border=\"1\">\n" . $text . "\n"; + } + return ''; +} + +sub html_default_sp($$) +{ + my $number = shift; + my $preformatted = shift; + return "
    \n" x $number if (!$preformatted); + return "\n" x $number; +} + +sub html_default_acronym_like($$$$$$) +{ + my $command = shift; + my $acronym_texi = shift; + my $acronym_text = shift; + my $with_explanation = shift; + my $explanation_lines = shift; + my $explanation_text = shift; + my $explanation_simply_formatted = shift; + + my $attribute = $command; + my $opening = "<$attribute>"; + if (defined($explanation_simply_formatted)) + { + $opening = "<$attribute title=\"$explanation_simply_formatted\">"; + } + if ($with_explanation) + { + return gdt('{acronym_like} ({explanation})', {'acronym_like' => $opening . $acronym_text . "", 'explanation' => $explanation_text},{'duplicate'=>1}) + } + else + { + return $opening . $acronym_text . ""; + } +} + +sub html_default_quotation($$$$$) +{ + my $command = shift; + my $text = shift; + my $argument_text = shift; + my $argument_text_texi = shift; + my $authors = shift; + my $class = ''; + $class = $command if ($command ne 'quotation'); + my $attribution = ''; + if ($authors) + { + foreach my $author (@$authors) + { + my $author_texi = $author->{'author_texi'}; + chomp($author_texi); + $attribution .= gdt("\@center --- \@emph{{author}}\n", {'author' => $author_texi}, {'duplicate' => 1, 'allow_paragraph' => 1}); + } + } + return html_default_attribute_class('blockquote', $class).">\n" . $text ."\n" . $attribution; +} + +# format a whole index +# +# argument: +# index text +# index name +sub html_default_print_index($$) +{ + my $text = shift; + my $name = shift; + return '' if (!defined($text)); + return html_default_attribute_class('table', "index-$name")." border=\"0\">\n" . + "" . gdt('Index Entry') . "  " . gdt('Section') . "\n" + . " $DEFAULT_RULE\n" . $text . + "\n"; +} + +# format a letter entry in an index page. The letter entry contains +# the index entries for the words beginning with that letter. It is +# a target for links pointing from the summary of the index. +# +# arguments: +# the letter +# identifier for the letter entry. This should be used to make the target +# identifier +# text of the index entries +sub html_default_index_letter($$$) +{ + my $letter = shift; + my $id = shift; + my $text = shift; + return $text if ($letter =~ /^\s*$/); + return '' . &$anchor($id,'',&$normal_text($letter, 0, 0, 0, 0, 0, [])) . + "\n" . $text . + " $DEFAULT_RULE\n"; +} + +# format an index entry (in a letter entry). +# +# arguments: +# href to the main text, linking to the place where the index entry appears +# entry text +# href to the main text, linking to the section or node where the index +# entry appears +# section or node heading +sub html_default_index_entry($$$$$$$$$$) +{ + my $text_href = shift; + my $entry = shift; + my $element_href = shift; + my $element_text = shift; + my $entry_file = shift; + my $current_element_file = shift; + my $entry_target = shift; + my $entry_element_target = shift; + my $in_region_not_in_output = shift; + my $index_entry_ref = shift; + + return '' if ($entry !~ /\S/); + my $element = $index_entry_ref->{'real_element'}; + if (defined($element)) + { + my $element_set = 0; + if ($NODE_NAME_IN_INDEX) + { + if ($element->{'node'}) + { + $element_set = 1; + } + elsif ($element->{'with_node'}) + { + $element = $element->{'with_node'}; + $element_set = 1; + } + } + elsif (defined($NODE_NAME_IN_INDEX)) + { + if (!$element->{'node'}) + { + $element_set = 1; + } + elsif ($element->{'with_section'}) + { + $element = $element->{'with_section'}; + $element_set = 1; + } + } + if ($element_set) + { + $element_href = main::href($element, $Texi2HTML::THIS_ELEMENT->{'file'}, + $Texi2HTML::THISDOC{'line_nr'}); + $element_text = $element->{'text'}; + } + } + + return '' . &$anchor('', $text_href, $entry) + . $INDEX_ENTRY_COLON . ' ' . &$anchor('', $element_href, $element_text) + . "\n"; +} + + +# format an index summary. This is a list of letters linking to the letter +# entries. +# +# arguments: +# array reference containing the formatted alphabetical letters +# array reference containing the formatted non lphabetical letters +sub html_default_index_summary($$) +{ + my $alpha = shift; + my $nonalpha = shift; + + my $join = ''; + my $nonalpha_text = ''; + my $alpha_text = ''; + $join = "   \n
    \n" if (@$nonalpha and @$alpha); + if (@$nonalpha) + { + $nonalpha_text = join("\n   \n", @$nonalpha) . "\n"; + } + if (@$alpha) + { + $alpha_text = join("\n   \n", @$alpha) . "\n   \n"; + } + return "
    " . gdt('Jump to') .":   " . + $nonalpha_text . $join . $alpha_text . "
    \n"; +} + +sub html_default_element_label($$$$) +{ + my $id = shift; + my $element = shift; + my $command = shift; + my $line = shift; + + return &$anchor($id) . "\n"; +} + +sub html_default_misc_element_label($$) +{ + my $id = shift; + my $misc_page_name = shift; + return &$anchor($id) . "\n"; +} + +sub html_default_anchor_label($$$$) +{ + my $id = shift; + my $anchor_text = shift; + my $anchor_reference = shift; + my $in_special_region = shift; + return &$anchor($id); +} + +sub html_default_tab_item_texi($$$$$$) +{ + my $command = shift; + my $commands_stack = shift; + my $stack = shift; + my $state = shift; + my $line = shift; + my $line_nr = shift; + + if (defined($commands_stack) and @$commands_stack and $commands_stack->[-1] eq 'multitable' and @html_default_multitable_stack) + { + $html_default_multitable_stack[-1]->[1] = -1; + } + return undef; +} + +sub html_default_line_command($$$$) +{ + my $command = shift; + my $arg_text = shift; + my $arg_texi = shift; + my $state = shift; + + return '' if ($arg_text eq '' or ($command eq 'author' and (!$state->{'region'} or $state->{'region'} ne 'titlepage'))); + my $style = $line_command_map{$command}; + if ($style) + { + my $attribute_text = ''; + if ($style =~ /^(\w+)(\s+.*)/) + { + $style = $1; + $attribute_text = $2; + } + $arg_text = "<${style}$attribute_text>$arg_text"; + } + $arg_text .= "
    " if ($command eq 'author'); + $arg_text .= "\n"; + return $arg_text; +} + +1; + +require "$T2H_HOME/formats/html.init" + if ($0 =~ /\.pl$/ && + -e "$T2H_HOME/formats/html.init" && -r "$T2H_HOME/formats/html.init"); + +# @INIT_INFO@ +# vim: set filetype=perl: +# +#+############################################################################## +# +# info.init: convert to info +# +# Copyright (C) 2008, 2009 Patrice Dumas +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA +# +# 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+. +# +#-############################################################################## + +use Data::Dumper; + +use strict; + +$Data::Dumper::Maxdepth = 25; + +my %info_default_indented_commands; +my %info_default_format; +my %info_default_enable_encoding_accents; +my @simple_quoted_commands; +my @asis_commands; +my @chevron_commands; +my %info_default_accent_commands = (); +my %info_default_leaf_command = (); +my $info_default_end_sentence_character; +my $info_default_after_punctuation_characters; +my $info_default_indent_length; +my %info_default_indent_format_length; +my $info_default_index_length_to_node; +my $info_default_listoffloat_caption_entry_length; +my $info_default_listoffloat_append; +my %info_default_index_entries_counts; + +sub info_default_load(;$) +{ +my $from_command_line = shift; + +t2h_default_set_variables_default(); +$USE_SECTIONS = 0; +$USE_NODES = 1; +#set_conf('SPLIT', 0, 1); +$SPLIT = ''; +@T2H_FORMAT_EXPAND = ('info', 'direntry'); +$EXTENSION = 'info'; +$SHOW_MENU = 1; +$SHOW_TITLE = 0; +$USE_SETFILENAME_EXTENSION = 1; +$INLINE_INSERTCOPYING = 1; +$SIMPLE_MENU = 1; +$MENU_SYMBOL = '*'; +$USE_ISO = 0; +$ENABLE_ENCODING_USE_ENTITY = 0; +$ENABLE_ENCODING = 1; +@IMAGE_EXTENSIONS = ('png', 'jpg', 'txt'); +$CAPTION_STYLE = 'asis'; +$DEFAULT_ENCODING = 'ascii'; +$HEADERS = 1; +$INLINE_CONTENTS = 0; + + +$no_paragraph_commands{'anchor'} = 1; + +%simple_map = %default_simple_map; +%simple_map_pre = %simple_map; +%simple_map_texi = %simple_map; + +%things_map = %default_things_map; +%pre_map = %things_map; + +%line_command_map = ( + 'dircategory' => '' +); + +# sc and var upcase. +@simple_quoted_commands = ('cite', 'code', 'command', 'env', 'file', 'kbd', + 'option', 'samp'); +@asis_commands = ('asis', 'w', 'b', 'ctrl', 'i', 'math', 'sc', 't', 'r', + 'slanted', 'sansserif', 'var', 'titlefont', 'verb', 'clickstyle', + 'headitemfont'); +@chevron_commands = ('key', 'indicateurl'); + +%info_default_accent_commands = (); +%info_default_leaf_command = (); + +%style_map = (); +t2h_default_copy_style_map (\%default_style_map, \%style_map); + +foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents), keys(%accent_map)) +{ + $info_default_accent_commands{$accent_command} = 1; + $style_map{$accent_command} = { 'function' => \&info_default_accent }; +} + +foreach my $command (keys(%style_map)) +{ + delete $style_map{$command}->{'quote'} if (exists($style_map{$command}->{'quote'})); + if (grep {$_ eq $command} @simple_quoted_commands) + { + delete $style_map{$command}->{'function'} if (exists($style_map{$command}->{'function'})); + $style_map{$command}->{'begin'} = '`'; + $style_map{$command}->{'end'} = "'"; + next; + } + elsif (grep {$_ eq $command} @asis_commands) + { + delete $style_map{$command}->{'function'} if (exists($style_map{$command}->{'function'})); + delete $style_map{$command}->{'begin'} if (exists($style_map{$command}->{'begin'})); + delete $style_map{$command}->{'end'} if (exists($style_map{$command}->{'end'})); + } + if (grep {$_ eq $command} @chevron_commands) + { + delete $style_map{$command}->{'function'} if (exists($style_map{$command}->{'function'})); + $style_map{$command}->{'begin'} = '<'; + $style_map{$command}->{'end'} = '>'; + next; + } + $info_default_leaf_command{$command} = 1 if ($style_map{$command}->{'type'} and $style_map{$command}->{'type'} eq 'simple_style'); +} + +$style_map{'strong'}->{'begin'} = '*'; +$style_map{'strong'}->{'end'} = '*'; +$style_map{'dfn'}->{'begin'} = '"'; +$style_map{'dfn'}->{'end'} = '"'; +$style_map{'emph'}->{'begin'} = '_'; +$style_map{'emph'}->{'end'} = '_'; + + +foreach my $command (keys(%info_default_leaf_command)) +{ + if (defined ($style_map{$command}->{'args'})) + { + $style_map{$command}->{'orig_args'} = [ @{$style_map{$command}->{'args'}} ]; + } + else + { + $style_map{$command}->{'orig_args'} = [ 'normal' ]; + } + $style_map{$command}->{'args'} = []; + foreach my $arg (@{$style_map{$command}->{'orig_args'}}) + { + push @{$style_map{$command}->{'args'}}, 'keep'; + } +} + +$style_map{'uref'}->{'function'} = \&info_default_uref; +$style_map{'url'}->{'function'} = \&info_default_uref; +$style_map{'email'}->{'function'} = \&info_default_email; + +%style_map_pre = (); +%style_map_texi = (); +t2h_default_copy_style_map (\%style_map, \%style_map_pre); +t2h_default_copy_style_map (\%style_map, \%style_map_texi); + +$special_list_commands{'itemize'} = {}; + +%info_default_indent_format_length = ('enumerate' => 2, + 'itemize' => 3, + 'table' => 0, + 'vtable' => 0, + 'ftable' => 0, + ); + + +%format_map = (); +foreach my $format ('group', 'raggedright', 'cartouche') +{ + $format_map{$format} = ''; +} + +foreach my $menu_command('menu', 'detailmenu', 'direntry', 'menu_comment') +{ + $complex_format_map{$menu_command} = {'begin' => '' , 'end' => ''}; +} + +foreach my $command (keys (%complex_format_map), keys(%info_default_indent_format_length), 'quotation', 'smallquotation', 'deff_item', 'deff_itemx') +{ + $info_default_indented_commands{$command} = 1; +} + +foreach my $command (keys(%info_default_indented_commands), 'multitable', 'float', 'flushright', 'flushleft', 'center') +{ + $info_default_format{$command} = 1; +} + +# it doesn't change anything for multitable +foreach my $non_indented_command('format', 'smallformat', 'menu', + 'detailmenu', 'direntry', 'multitable') +{ + $info_default_indented_commands{$non_indented_command} = 0; +} + +$info_default_end_sentence_character = quotemeta($punctuation_characters); +$info_default_after_punctuation_characters = quotemeta($after_punctuation_characters); +$info_default_indent_length = 5; + +$info_default_index_length_to_node = 41; + +$info_default_listoffloat_caption_entry_length = 41; +#$info_default_listoffloat_append = '...: '; +$info_default_listoffloat_append = '...'; + +t2h_default_push_handler(\&info_default_init_accent_enable_encoding, \@command_handler_init); +t2h_default_push_handler(\&info_default_init_variables, \@command_handler_init); + + +$style = \&info_default_style; +$print_page_head = \&info_default_print_page_head; +$contents = \&info_default_noop; +$shortcontents = \&info_default_noop; +$about_body = \&info_default_noop; +$print_Footnotes = \&info_default_noop; +$copying_comment = \&info_default_copying_comment; +$element_heading = \&info_default_element_heading; +$heading = \&info_default_heading; +$normal_text = \&info_default_normal_text; +$paragraph = \&info_default_paragraph; +$preformatted = \&info_default_preformatted; +$empty_preformatted = \&info_default_preformatted; +$empty_line = \&info_default_empty_line; +# maybe should not be called from the main program? +$print_page_foot = \&info_default_print_page_foot; +$print_Top_footer = \&info_default_print_Top_footer; +$print_Top = \&info_default_print_section; +$print_section = \&info_default_print_section; +$end_section = \&info_default_end_section; +$one_section = \&info_default_one_section; +$begin_format_texi = \&info_default_begin_format_texi; +$begin_style_texi = \&info_default_begin_style_texi; +$begin_paragraph_texi = \&info_default_begin_paragraph_texi; +$simple_command = \&info_default_simple_command; +$thing_command = \&info_default_thing_command; +$begin_special_region = \&info_default_begin_special_region; +$end_special_region = \&info_default_end_special_region; +$anchor_label = \&info_default_anchor_label; +$element_label = \&info_default_noop; +$menu_link = \&info_default_menu_link; +#$menu_command = \&info_default_menu_command; +$complex_format = \&info_default_complex_format; +$quotation = \&info_default_quotation; +$misc_command_line = \&info_default_misc_commands; +$external_ref = \&info_default_external_ref; +$internal_ref = \&info_default_internal_ref; +$image = \&info_default_image; +$image_files = \&info_default_image_files; +$index_summary = \&info_default_index_summary; +$summary_letter = \&info_default_summary_letter; +$index_entry = \&info_default_index_entry; +$index_entry_command = \&t2h_default_index_entry_command; +$index_letter = \&info_default_index_letter; +$printindex = \&info_default_printindex; +$print_index = \&info_default_print_index; +$index_entry_label = \&info_default_index_entry_label; +$foot_section = \&info_default_foot_lines; +$foot_line_and_ref = \&info_default_foot_line_and_ref; +$footnote_texi = \&info_default_footnote_texi; +$list_item = \&info_default_list_item; +$format_list_item_texi = \&info_default_format_list_item_texi; +$format = \&info_default_format; +$tab_item_texi = \&info_default_tab_item_texi; +$acronym_like = \&info_default_acronym_like; +$sp = \&info_default_sp; +$paragraph_style_command = \&info_default_paragraph_style_command; +$cell = \&info_default_cell; +$row = \&info_default_row; +$table_list = \&info_default_table_list; +$def_item = \&info_default_def_item; +$def = \&info_default_def; +$def_line = \&info_default_def_line; +$float = \&info_default_float; +$listoffloats_entry = \&info_default_listoffloats_entry; +$listoffloats = \&info_default_listoffloats; +$colon_command = \&info_default_colon_command; +$raw = \&info_default_raw; +$line_command = \&info_default_line_command; +$comment = \&t2h_default_comment; +$unknown_style = \&info_default_unknown_style; +$heading_text = \&t2h_default_heading_text; + +} + +my %info_default_state_map = (); +my $info_default_out_file_nr = 1; +my $info_default_dir_specification = ''; +my @info_default_pending_indirect = (); +my @info_default_pending_footnotes = (); +my $info_default_state_nr = 0; + +# maximal length of index entries line number information. Each entry is +# an index name. +my %info_default_index_line_string_length = (); +my %info_default_index_entries = (); +my $info_default_footnote_index = 0; +my $info_default_current_node = undef; + +my %info_default_command_handler_expand; + +sub info_default_intercept_handler +{ + my $command = $_[0]; + my $result = &{$info_default_command_handler_expand{$command}}(@_); + return info_default_store_text (undef, $result, $command); +} + +sub info_default_init_variables() +{ + %info_default_state_map = (); + $info_default_out_file_nr = 1; + $info_default_dir_specification = ''; + @info_default_pending_indirect = (); + @info_default_pending_footnotes = (); + $info_default_state_nr = 0; + + %info_default_index_line_string_length = (); + %info_default_index_entries = (); + $info_default_footnote_index = 0; + $info_default_current_node = undef; + $Texi2HTML::THISDOC{'SPLIT'} = 0 if ($OUTPUT_FORMAT eq 'info'); + $FRAMES = 0 if ($OUTPUT_FORMAT eq 'info'); + + foreach my $command (keys (%command_handler)) + { + if ($command_handler{$command}->{'expand'}) + { + $info_default_command_handler_expand{$command} = $command_handler{$command}->{'expand'}; + $command_handler{$command}->{'expand'} = \&info_default_intercept_handler; + } + } +} + +# this is put in command_handler_init such that it sets things right +# in case $ENABLE_ENCODING is set and has lead to modification of the +# accent functions +sub info_default_init_accent_enable_encoding() +{ + return unless ($ENABLE_ENCODING and $USE_UNICODE); + foreach my $key (keys(%unicode_accents), 'dotless') + { + $info_default_enable_encoding_accents{$key} = 1; + $t2h_enable_encoding_default_accent{'normal'}->{$key} = \&t2h_default_accent; + $t2h_enable_encoding_default_accent{'texi'}->{$key} = \&t2h_default_accent; + $t2h_enable_encoding_default_accent{'pre'}->{$key} = \&t2h_default_accent; + $style_map{$key}->{'function'} = \&info_default_accent; + $style_map_texi{$key}->{'function'} = \&info_default_accent; + $style_map_pre{$key}->{'function'} = \&info_default_accent; + } +} + +sub info_default_uref($$) +{ + shift; + my $args = shift; + my $url = shift @$args; + my $text = shift @$args; + my $replacement = shift @$args; + $url = main::normalise_space($url); + $replacement = '' if (!defined($replacement)); + $replacement = main::normalise_space($replacement); + return $replacement if ($replacement ne ''); + $text = '' if (!defined($text)); + $text = main::normalise_space($text); + return "`$url'" if ($text eq ''); + return "$text ($url)"; +} + +sub info_default_email($$) +{ + my $command = shift; + my $args = shift; + my $mail = shift @$args; + my $text = shift @$args; + $mail = main::normalise_space($mail); + $text = '' if (!defined($text)); + $text = main::normalise_space($text); + $mail = "<$mail>"; + return $mail unless ($text ne ''); + return "$text $mail"; +} + + +sub info_default_accent($$$) +{ + my @args = @_; + my $command = shift; + my $args = shift; + my $text = $args->[0]; + my $style_stack = shift; + my $state = shift; + + my $result; + if ($ENABLE_ENCODING and $info_default_enable_encoding_accents{$command}) + { + $result = &t2h_enable_encoding_normal_accent(@args); + } + else + { + $result = &t2h_default_accent(@args); + } + if (scalar(@$style_stack) and $info_default_accent_commands{$style_stack->[-1]}) + { # still more accents on the stack + return $result; + } + return info_default_store_text($state,$result,'accents_commands'); +} + +sub info_default_noop +{ + return ''; +} + +sub info_default_copying_comment($$$$) +{ + my $copying_lines = shift; + my $copying_text = shift; + my $copying_no_texi = shift; + my $copying_simple_text = shift; + return '' if ($copying_text eq ''); + return $copying_text; +} + +sub info_default_byte_count($) +{ + my $string = shift; + my $out_encoding = Texi2HTML::Config::get_conf('OUT_ENCODING'); + if ($out_encoding and lc($out_encoding) ne 'us-ascii' and $USE_UNICODE) + { + return length (Encode::encode($out_encoding, $string)); + } + # There is no default encoding. We assume it is us-ascii. Not sure + # about what perl thinks it is... + #print STDERR "Unknown encoding for: $string\n" if (!$out_encoding); + return length($string); +} + +sub info_default_count_lines($;$$) +{ + my $text = shift; + my $indent_length = shift; + my $indentation_done = shift; + + my $blank_line; + my $no_indentation = 0; + + if (!defined($indentation_done) or $indentation_done) + { + $no_indentation = 1; + $indent_length = 0; + } + my @lines = split /^/, $text; + # don't accept empty text. + @lines = ('') if (!@lines); + my $line_passed = scalar(@lines); + $line_passed-- if ($line_passed); + + my $end_of_line = 0; + if (($#lines > 1) and !$end_of_line and ($lines[-1] !~ /\S/) and ($lines[-2] !~ /\S/)) + { + $blank_line = 1; + } + my $last_line = $lines[-1]; + + my $indented_text = shift (@lines); + #print STDERR "COUNT info_default_count_lines(i_done $no_indentation, i_l $indent_length) i_t `$indented_text'\n"; + foreach my $line (@lines) + { + if ($indent_length and $line =~ /\S/) + { + $indented_text .= ' ' x $indent_length . $line; + } + else + { + $indented_text .= $line; + } + } + if (chomp($text)) + { + $line_passed++; + $end_of_line = 1; + } + return ($line_passed, $end_of_line, $last_line, $indented_text, $blank_line); +} + +sub info_default_get_state($) +{ + my $state = shift; + if (!exists $info_default_state_map{$state}) + { + #print STDERR "NEW state $info_default_state_nr\n"; + my ($current_command, $top_stack); + $info_default_state_map{$state} = {}; + info_default_reset_state($info_default_state_map{$state}); + # since the page head always leave a blank line, and the state may be + # used for text right after the page head, we set it to 1 here. + # it may be wrong in other contexts, to be seen. + $info_default_state_map{$state}->{'blank_line'} = 1; + $info_default_state_map{$state}->{'only_spaces'} = 1; + # this is the first line, so set to 1. This is reset later in + # most cases, when a node is seen, but may still be useful in + # @footnote, for example + $info_default_state_map{$state}->{'line_count'} = 1; + $info_default_state_map{$state}->{'offset_in_file'} = 0; + $info_default_state_map{$state}->{'nr'} = $info_default_state_nr; + $info_default_state_map{$state}->{'state'} = $state; + $info_default_state_map{$state}->{'multitable_stack'} = []; + @{$info_default_state_map{$state}->{'align_stack'}} = ({'command'=>'normal'}); + $info_default_state_nr++; + } + #print STDERR "RETURN state $state $info_default_state_map{$state} $info_default_state_map{$state}->{'nr'}\n"; + return $info_default_state_map{$state}; +} + +sub info_default_reset_state($) +{ + my $info_state = shift; + $info_state->{'top'} = {}; + $info_state->{'current'} = $info_state->{'top'}; +} + +sub info_default_iterator_next($$$) +{ + my $current_command = shift; + my $command_index = shift; + my $command_close = shift; + #print STDERR "NNNNNNNNNNNNNN iterator_next current $current_command idx $command_index close $command_close\n"; + + my $sub_command = $current_command->{'content'}->[$command_index]; + + if ($sub_command->{'content'} and !$command_close) + { + return ($sub_command, 0, 0); + } + + if ($current_command->{'content'}->[$command_index+1]) + { + return ($current_command, $command_index+1, 0); + } + elsif (defined($current_command->{'parent'})) + { + return ($current_command->{'parent'}, $current_command->{'index_in_parent'}, 1); + } + else + { + return (undef, undef, undef); + } +} + +# return ($current_next, $index_next, $close_next, $text, $command); +# +# returns the next in tree, identified by the triplet +# ($current_next, $index_next, $close_next) and also the command +# and/or text if defined, in $text and $command. +sub info_default_next($$$) +{ + my $current = shift; + my $index = shift; + my $close = shift; + + my $text; + my $command; + + my ($current_next, $index_next, $close_next) = info_default_iterator_next($current, $index, $close); + return ($current_next, $index_next, $close_next, $text, $command) if (!defined($current_next)); + + my $content = $current_next->{'content'}->[$index_next]; + $command = $content->{'command'} if (defined($content->{'command'})); + if ($close_next) + { + return ($current_next, $index_next, $close_next, $content->{'end'}, $command); + } + if (defined($content->{'text'})) + { + return ($current_next, $index_next, $close_next, $content->{'text'}, $command); + } + if (defined($content->{'begin'})) + { + $text = $content->{'begin'}; + } + if (defined($content->{'end'}) and !defined($content->{'content'})) + { + if (!defined($text)) + { + $text = $content->{'end'}; + } + else + { + $text .= $content->{'end'}; + } + } + return ($current_next, $index_next, $close_next, $text, $command); +} + + +sub info_default_process_line_text($$$) +{ + my $text = shift; + my $line_width_counter = shift; + my $indent_length = shift; + $indent_length = 0 if (!defined($indent_length)); + + my $line_passed = 0; + my $chomped_text = $text; + my $end_of_line = chomp($chomped_text); + if ($indent_length > $line_width_counter and $chomped_text ne '') + { + $text = ' ' x ($indent_length - $line_width_counter) . $text; + } + $line_width_counter += t2h_default_string_width($text); + # it seems like it never happens in the tests. + if ($end_of_line) + { + $line_passed = 1; + $line_width_counter = 0; + } + return ($line_width_counter, $line_passed, $text); +} + +# Beware that there is a pending word if the text doesn't end with +# a space +sub info_default_process_para_text($$$$$;$$) +{ + my $text = shift; + my $line_char_counter = shift; + my $pending_spaces_word = shift; + my $indent_length = shift; + my $max_column = shift; + my $keep_end_of_lines = shift; + $keep_end_of_lines = 0 if (!$keep_end_of_lines); +# indentation for the lines except for the first one + my $indent_length_next = shift; + $indent_length = 0 if (!defined($indent_length)); + $indent_length_next = $indent_length if (!defined($indent_length_next)); + + my $line_passed = 0; + my $result = ''; + + #print STDERR "process_text(indent($indent_length,$indent_length_next),keep_eol $keep_end_of_lines) spaces `$pending_spaces_word->{'spaces'}') line_char_counter $line_char_counter |$text|\n"; + + while ($text ne '') + { + #print STDERR "l_c_c $line_char_counter pending_word ".var_to_str($pending_spaces_word->{'word'}).", pending_spaces `$pending_spaces_word->{'spaces'}', result `$result'\n"; + if (!$keep_end_of_lines and $text =~ s/^(\s+)//) + { + my $new_spaces = $1; + # in general there are no end of lines in the lines cut, since they + # are replaced by spaces in the main loop. However, it may happen + # with @* in @def* lines + my @lines = split /^/, $new_spaces; + my $eol_spaces; + # last line is in $new_spaces, other lines are in $eol_spaces + if (@lines > 1) + { + $new_spaces = pop @lines; + $eol_spaces = join ("", @lines); + #print STDERR "EOL_SPACES[$line_char_counter](+$pending_spaces_word->{'spaces'}) `$eol_spaces'\n"; + } + if (defined($pending_spaces_word->{'word'})) + { + # add spaces in front if needed for the indentation + if ($indent_length > $line_char_counter + t2h_default_string_width($pending_spaces_word->{'spaces'})) + { + $pending_spaces_word->{'spaces'} = ' ' x ($indent_length - $line_char_counter) . $pending_spaces_word->{'spaces'}; + } + $result .= $pending_spaces_word->{'spaces'} . $pending_spaces_word->{'word'}; + $line_char_counter += t2h_default_string_width($pending_spaces_word->{'spaces'})+t2h_default_string_width($pending_spaces_word->{'word'}); + $pending_spaces_word->{'spaces'} = $new_spaces; + $pending_spaces_word->{'word'} = undef; + } + elsif (!$eol_spaces) + { + $pending_spaces_word->{'spaces'} .= $new_spaces; + } + if ($eol_spaces) + { + $result .= $eol_spaces; + $line_passed += scalar(@lines); + $indent_length = $indent_length_next; + $line_char_counter = 0; + $pending_spaces_word->{'spaces'} = ''; + } + if ((t2h_default_string_width($pending_spaces_word->{'spaces'}) + $line_char_counter > $max_column)) + { + $pending_spaces_word->{'spaces'} = ''; + $result .= "\n"; + $line_passed++; + $indent_length = $indent_length_next; + $line_char_counter = 0; + } + } + else + { + my $word; + if ($keep_end_of_lines) + { + $word = $text; + $text = ''; + } + elsif ($text =~ s/^([^\s]+)//) + { + $word = $1; + } + #else + #{ + # die "BUG: Impossible situation.\n"; + #} + $pending_spaces_word->{'word'} = '' if (!defined($pending_spaces_word->{'word'})); + $pending_spaces_word->{'word'} .= $word; + # The $line_char_counter != 0 is here to cope with the case of a + # word longer than $line_char_counter followed by more text: + # a line would be passed each time some piece text is appended. + if ((t2h_default_string_width($pending_spaces_word->{'spaces'})+t2h_default_string_width($pending_spaces_word->{'word'}) + $line_char_counter > $max_column) and $line_char_counter != 0) + { + $pending_spaces_word->{'spaces'} = ''; + $result .= "\n"; + $line_passed++; + $indent_length = $indent_length_next; + $line_char_counter = 0; + } + } + } + return ($line_char_counter, $pending_spaces_word, $line_passed, $result) +} + +sub info_default_skip_spaces($$$) +{ + my $current = shift; + my $index = shift; + my $close = shift; + + #print STDERR "SKIP_SPACES\n"; + while(1) + { + my ($current_next, $index_next, $close_next) = info_default_iterator_next($current, $index, $close); + return if ($close_next or (!defined($current_next))); + my $content = $current_next->{'content'}->[$index_next]; + if (defined($content->{'begin'})) + { + $content->{'begin'} =~ s/^\s*//; + #print STDERR "SKIP_SPACES begin\n"; + return if ($content->{'begin'} ne ''); + } + if (defined($content->{'content'}) or defined($content->{'format_name'}) + or $content->{'definition_line'}) + { # non empty commands stop space skipping, even if they contain + # only spaces, like @asis{ } + # also for item(x) that have format_name defined + #print STDERR "SKIP_SPACES command?\n"; + return; + } + if (defined($content->{'text'})) + { + my $command = ''; + $command = $content->{'command'} if (defined($content->{'command'})); + #print STDERR "SKIP_SPACES($command) text\n"; + $content->{'text'} =~ s/^\s*//; + return if ($content->{'text'} ne ''); + } + if (defined($content->{'end'})) + { + #print STDERR "SKIP_SPACES end\n"; + $content->{'end'} =~ s/^\s*//; + return if ($content->{'end'} ne ''); + } + ($current, $index, $close) = ($current_next, $index_next, $close_next); + } +} + +sub info_default_store_pending($$;$) +{ + my $line_char_counter = shift; + my $pending_spaces_word = shift; + my $indent_length = shift; + + $indent_length = 0 if (!defined($indent_length)); + my $indent_text = ''; + $indent_text = ' ' x $indent_length; + + #print STDERR "store_pending(spaces `$pending_spaces_word->{'spaces'}', indent($indent_length) `$indent_text' word `".var_to_str($pending_spaces_word->{'word'})."'\n"; + my $result = $pending_spaces_word->{'spaces'}; + $pending_spaces_word->{'spaces'} = ''; + if (defined($pending_spaces_word->{'word'})) + { + $result .= $pending_spaces_word->{'word'}; + $pending_spaces_word->{'word'} = undef; + } + + my $chomped_result = $result; + chomp ($chomped_result); + if ($line_char_counter == 0 and $chomped_result ne '') + { + $result = $indent_text . $result; + } + + $line_char_counter += t2h_default_string_width($result); + return ($line_char_counter, $pending_spaces_word, $result); +} + +sub info_default_output($) +{ + my $info_state = shift; + my $result = ''; + #print STDERR "Storing the stack\n"; + print STDERR "" . Data::Dumper->Dump([$info_state->{'top'}]) if ($DEBUG); + my ($bytes_count, $lines_count); + ($bytes_count, $result, $lines_count) = info_default_process_content($info_state->{'top'}, $info_state); + $info_state->{'offset_in_file'} += $bytes_count; + $info_state->{'line_count'} += $lines_count; + #print STDERR "HHHHHH($lines_count) $info_state->{'line_count'}: $result\n"; + info_default_reset_state($info_state) + if (!defined($info_state->{'current'}->{'command'})); + return $result; +} + +sub info_default_process_content($$) +{ + my $current_command = shift; + my $info_state = shift; + + my $length = 0; + my $result = ''; + + my $line_char_counter = 0; + my $all_line_passed = 0; + + my $pending_spaces_word; + $pending_spaces_word->{'spaces'} = ''; + my $preformatted = 0; + my $indent_level = 0; + my $item_pending; + my $in_exdent = 0; + my $in_para = 0; + my $in_w = 0; + my $table_item_line = 0; + my $in_table_item = 0; + my $max_column = get_conf('fillcolumn'); + my $direntry = 0; + my $preformatted_format = 0; + my $indent_length = 0; + + # for formats that needs to process a full line (center and flushright) + # to know the line length before outputing + my $current_line = undef; + + my ($current, $index, $close) = ($current_command, 0, 0); + + #print STDERR "info_default_process_content: $current_command\n"; + while(1) + { + last if (!defined($current)); + my $content = $current->{'content'}->[$index]; + my $text_added = ''; + my $line_added_before_item = 0; + my $indentation_done = 0; + my $prepend_newline; + + if ($DEBUG) + { + my $text_item_pending = ''; + $text_item_pending = $item_pending if (defined($item_pending)); + my $text_length = ''; + $text_length = "$content->{'text'}" if defined($content->{'text'}); + my $text_command = ''; + $text_command = $content->{'command'} if defined($content->{'command'}); + my $in_node_count = 0; + $in_node_count = $info_state->{'line_count'} if defined($info_state->{'line_count'}); + print STDERR "($text_command|$text_length|$close|${all_line_passed}+$in_node_count|l_c_cnt $line_char_counter) prfrmted $preformatted para $in_para indent_lvl $indent_level($indent_length) in_exdent $in_exdent in_w $in_w only_spaces $info_state->{'only_spaces'} blank_line $info_state->{'blank_line'} table_item_line $table_item_line in_table_item $in_table_item item_pending $text_item_pending spaces: `$pending_spaces_word->{'spaces'}' word: ".main::var_to_str($pending_spaces_word->{'word'})."\n"; + } + + if ($close) + { + if (defined($content->{'end'})) + { + $text_added .= $content->{'end'}; + } + if ($complex_format_map{$content->{'command'}} and $content->{'content'}) + { + $preformatted_format--; + } + # the format is always empty in the main program so the warning + # has to be done here + if (defined($content->{'total_item_nr'}) and !$content->{'total_item_nr'} and $content->{'content'}) + { + main::line_warn (sprintf(__("\@%s has text but no \@item"), $content->{'command'}), $content->{'line_nr'}); + } + # check whether there is a blank line following, to avoid adding + # one when closing a format. + # This is not a required check if not in preformatted since doubled + # blank lines are discarded. + my $followed_by_blank_line = 0; + if ($preformatted_format) + { + my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close); + if (defined($command_next) and $command_next eq 'preformatted') + { + ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current_next, $index_next, $close_next); + $followed_by_blank_line = 1 if (defined($text_next) and $text_next =~ /^\s*$/); + } + } + if ($info_default_indented_commands{$content->{'command'}}) + { + $indent_level--; + $indent_length = $indent_level * $info_default_indent_length; + # $preformatteed cannot be used here since preformatted + # is closed before the end of a format + #if ($indent_level > 0 and !$info_state->{'blank_line'} and $content->{'command'} !~ /^deff_item/ and !$preformatted_format) + if ($indent_level > 0 and !$info_state->{'blank_line'} and $content->{'command'} !~ /^deff_item/ and !$followed_by_blank_line) + { + $text_added .= "\n"; + } + # this nullify a potential noindent in a random format + $info_state->{'indent_para'} = undef; + } + elsif (($complex_format_map{$content->{'command'}} and $content->{'command'} ne 'menu') or $content->{'command'} eq 'cartouche') + { + if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level > 0) and !$followed_by_blank_line) + { + $text_added .= "\n"; + } + } + if ($content->{'command'} eq 'paragraph' and $info_state->{'align_stack'}->[-1]->{'command'} eq 'normal') + { + # if there is no space at the end of a paragraph, there may be + # pending text, for example, if there is an ending line like + # Some text@c a comment + my $pending; + ($line_char_counter, $pending_spaces_word, $pending) = info_default_store_pending($line_char_counter, $pending_spaces_word, $indent_length); + $text_added .= $pending if (defined($pending)); + $text_added =~ s/\s*$//; + $pending_spaces_word->{'spaces'} = ''; + $in_para = 0; + $info_state->{'indent_para'} = undef; + $text_added .= "\n" unless (($line_char_counter + t2h_default_string_width($text_added)) == 0); + } + elsif ($content->{'command'} eq 'preformatted') + { + # if preformatted doesn't end with a newline, it is added here + $text_added .= "\n" unless ($line_char_counter == 0); + $preformatted--; + } + elsif ($content->{'command'} eq 'menu') + { + $text_added .= "\n" unless ($info_state->{'blank_line'}); + } + elsif ($content->{'command'} eq 'float') + { + #$text_added = "\n" . $text_added unless ($info_state->{'blank_line'}); + $prepend_newline = 1 unless ($info_state->{'blank_line'}); + } + elsif ($content->{'command'} eq 'w') + { + $in_w--; + } + elsif ($paragraph_style{$content->{'command'}}) + { + my $popped = pop @{$info_state->{'align_stack'}}; + print STDERR "BUG".main::format_line_number().": align_stack, popped $popped->{'command'} ne command $content->{'command'}\n" if ($popped->{'command'} ne $content->{'command'}); + } + elsif ($content->{'command'} eq 'multitable') + { + my $multitable = pop @{$info_state->{'multitable_stack'}}; + if (!defined($multitable->{'cells'}) and ($result ne '')) + { + $multitable->{'result'} .= $result; + $multitable->{'length'} += $length; + $multitable->{'line_count'} += $all_line_passed; + } + $max_column = $multitable->{'max_column_kept'}; + $result = $multitable->{'result_kept'}; + $line_char_counter = $multitable->{'line_char_counter_kept'}; + $all_line_passed = $multitable->{'all_line_passed_kept'}; + $indent_level = $multitable->{'indent_level_kept'}; + $indent_length = $multitable->{'indent_length_kept'}; + #$indent_length_next_line = undef; + $length = $multitable->{'length_kept'}; + $info_state->{'offset_in_file'} = $multitable->{'offset_in_file_kept'}; + $info_state->{'line_count'} = $multitable->{'line_count_kept'}; + #print STDERR "MULTITABLE close, lines: $multitable->{'line_count_kept'} + $all_line_passed\n"; + foreach my $anchor_and_index (@{$multitable->{'anchors'}}, @{$multitable->{'index_entries'}}) + { + $anchor_and_index->{'line_nr'} += $multitable->{'line_count_kept'} + $all_line_passed; + } + if (! scalar(@{$info_state->{'multitable_stack'}})) + { + #print STDERR "MULTITABLE close, lengths: $multitable->{'offset_in_file_kept'} + $length\n"; + foreach my $anchor (@{$multitable->{'anchors'}}) + { + $anchor->{'info_offset'} += $multitable->{'offset_in_file_kept'} + $length; + } + } + else + { + push @{$info_state->{'multitable_stack'}->[-1]->{'anchors'}}, @{$multitable->{'anchors'}}; + push @{$info_state->{'multitable_stack'}->[-1]->{'index_entries'}}, @{$multitable->{'index_entries'}}; + } + $text_added .= $multitable->{'result'}; + $indentation_done = 1; + + goto new_text; + } + elsif ($content->{'command'} eq 'multitable_cell') + { + my $cell = $info_state->{'multitable_stack'}->[-1]->{'cells'}->[-1]; + $cell->{'result'} = $result; + $cell->{'length'} = $length; + $cell->{'line_passed'} = $all_line_passed; + } + elsif ($content->{'command'} eq 'direntry') + { + $direntry--; + # this has to be done here, otherwise, at the end, $direntry + # would be 0 + $info_default_dir_specification .= $text_added; + $text_added = ''; + } + elsif ($content->{'command'} eq 'multitable_row') + { + my $multitable = $info_state->{'multitable_stack'}->[-1]; + my $indent_len = $multitable->{'indent_length_kept'}; + #print STDERR "INDENT: $indent_len\n"; + my $row_length = 0; + my $row = ''; + my $max_lines = 0; + my $cell_beginning = 0; + my @anchor_lines_array; + my $cell_idx = 0; + my @anchors; + my @indices; + foreach my $cell (@{$multitable->{'cells'}}) + { + $cell->{'beginning'} = $cell_beginning; + $cell_beginning += $cell->{'cell_width'}+1; + @{$cell->{'lines'}} = split /^/, $cell->{'result'}; + $max_lines = scalar(@{$cell->{'lines'}}) if (scalar(@{$cell->{'lines'}}) > $max_lines); + foreach my $anchor (@{$cell->{'anchors'}}) + { + push @{$anchor_lines_array[$anchor->{'line_nr'}]}, $anchor; + $anchor->{'cell_idx'} = $cell_idx; + push @anchors, $anchor; + } + push @indices, @{$cell->{'index_entries'}}; + $cell_idx++; + } + my $previous_last_cell = scalar(@{$multitable->{'cells'}}); + #print STDERR "ROW cell_beginning $cell_beginning, max_lines $max_lines, previous_last_cell $previous_last_cell\n"; + for (my $line_idx = 0; $line_idx < $max_lines; $line_idx++) + { + my $line_width = $indent_len; + my $line_bytes = info_default_byte_count(' ' x$indent_len); + my $line = ''; + # determine the last cell in the line, to fill spaces in + # cells preceding that cell on the line + my $last_cell = 0; + for (my $cell_idx = 0; $cell_idx < $previous_last_cell; $cell_idx++) + { + $last_cell = $cell_idx+1 if (defined($multitable->{'cells'}->[$cell_idx]->{'lines'}->[$line_idx])); + } + #print STDERR " L(last_cell $last_cell): $line_idx\n"; + for (my $cell_idx = 0; $cell_idx < $last_cell; $cell_idx++) + { + my $cell_text = $multitable->{'cells'}->[$cell_idx]->{'lines'}->[$line_idx]; + #print STDERR " C($cell_idx) "; + if (defined($cell_text)) + { + chomp($cell_text); + #print STDERR "$cell_text"; + if ($line eq '' and $cell_text ne '') + { + $line = ' ' x $indent_len; + } + $line .= $cell_text; + $line_width += t2h_default_string_width($cell_text); + $line_bytes += info_default_byte_count($cell_text); + } + if ($cell_idx+1 < $last_cell) + { + if ($line_width < $indent_len + $multitable->{'cells'}->[$cell_idx+1]->{'beginning'}) + { + if ($line eq '') + { + $line = ' ' x $indent_len; + } + my $spaces = ' ' x ($indent_len + $multitable->{'cells'}->[$cell_idx+1]->{'beginning'} - $line_width); + $line_width += t2h_default_string_width($spaces); + $line_bytes += info_default_byte_count($spaces); + $line .= $spaces; + #print STDERR " Csp($line_width) `$spaces'"; + } + } + } + if (defined($anchor_lines_array[$line_idx])) + { + foreach my $anchor (@{$anchor_lines_array[$line_idx]}) + { + my $anchor_position = $indent_len + $anchor->{'line_char_counter'} + $multitable->{'cells'}->[$anchor->{'cell_idx'}]->{'beginning'}; + if ($anchor_position > $line_width) + { + my $spaces = ' ' x ($anchor_position - $line_width); + $line .= $spaces; + $line_width += t2h_default_string_width($spaces); + $line_bytes += info_default_byte_count($spaces); + } + $anchor->{'info_offset'} = $line_bytes + $row_length + $multitable->{'length'}; + #print STDERR "ROW anchor close: anchor[$anchor->{'cell_idx'}]($multitable->{'cells'}->[$anchor->{'cell_idx'}]->{'beginning'}+$anchor->{'line_char_counter'}) $anchor_position $anchor->{'info_offset'}\n"; + $anchor->{'line_char_counter'} = $anchor_position; + } + } + $line .= "\n"; + $row_length += info_default_byte_count($line); + #print STDERR " ($line_width,".length($line).") $line"; + $row .= $line; + $previous_last_cell = $last_cell; + } + foreach my $anchor_and_index (@anchors, @indices) + { + $anchor_and_index->{'line_nr'} += $multitable->{'line_count'}; + #print STDERR "ROW close: new line count: $anchor_and_index->{'line_nr'} + \n"; + } + if ($content->{'item_command'} eq 'headitem') + { + # at this point cell_beginning is at the beginning of + # the cell following the end of the table -> full width + my $line = ' ' x $indent_len . '-' x $cell_beginning . "\n"; + $row .= $line; + $row_length += info_default_byte_count($line); + } + #print STDERR "ROW_LENGTH $row_length\n"; + $multitable->{'result'} .= $row; + $multitable->{'length'} += $row_length; + $multitable->{'line_count'} += $max_lines; + $multitable->{'cells'} = []; + push @{$multitable->{'anchors'}}, @anchors; + push @{$multitable->{'index_entries'}}, @indices; + } + } + else + { + if ($content->{'command'}) + { + # if processing a paragraph, there may be some pending text + # and spaces, as the idea is to write them down only when + # there is a space in case of pending text, or when there is some + # text in case of pending space. So all the commands + # that should write something within paragraph must flush the + # pending text/spaces _before_ they output something, or the + # text order will be reversed, with the pending things output + # after the other commands text. + my $pending_added_length = 0; + my $pending_added_bytes = 0; + + if ($content->{'command'} eq 'anchor' or $content->{'command'} eq 'image' or $content->{'command'} eq 'index_command' or $content->{'command'} eq 'sp' or $content->{'raw_command'}) + { + my $pending; + ($line_char_counter, $pending_spaces_word, $pending) = info_default_store_pending($line_char_counter, $pending_spaces_word, $indent_length); + # here spaces out of any environment are ignored. + if ($in_para or $preformatted or $pending =~ /\S/) + { # this has to be done before the anchor related code + # to have the right count. + # FIXME this is wrong if an end of line was passed. + # in that case line_char_counter has been increased and + # $pending ends with an end of line + $pending_added_length += t2h_default_string_width($pending); + $pending_added_bytes += info_default_byte_count($pending); + $text_added .= $pending; + } + } + if ($content->{'command'} eq 'strong') + { + my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close); + if (defined($text_next) and $text_next =~ /^Note\b/i) + { + main::line_warn(__("\@strong{Note...} produces a spurious cross-reference in Info; reword to avoid that"), $content->{'line_nr'}); + } + } + elsif ($content->{'command'} eq 'w') + { + $in_w++ if ($content->{'content'}); + } + elsif ($content->{'command'} eq 'anchor' or ($content->{'command'} eq 'float' and $content->{'anchor_reference'})) + { + #print STDERR "anchor: offset_in_file $info_state->{'offset_in_file'}, line_count $info_state->{'line_count'}, line_char_counter $line_char_counter pending_added_length $pending_added_length\n"; + $content->{'anchor_reference'}->{'info_offset'} = $length + $info_state->{'offset_in_file'} + $pending_added_bytes; + $content->{'anchor_reference'}->{'line_nr'} = $all_line_passed + $info_state->{'line_count'}; + $content->{'anchor_reference'}->{'line_char_counter'} = $line_char_counter + $pending_added_length; + if (@{$info_state->{'multitable_stack'}}) + { + if ($info_state->{'multitable_stack'}->[-1]->{'cells'}) + { + push @{$info_state->{'multitable_stack'}->[-1]->{'cells'}->[-1]->{'anchors'}}, $content->{'anchor_reference'}; + } + else + { + push @{$info_state->{'multitable_stack'}->[-1]->{'anchors'}}, $content->{'anchor_reference'}; + } + } + push @{$info_state->{'pending_tags'}}, $content->{'anchor_reference'}; + push @{$info_state->{'align_stack'}->[-1]->{'anchors'}}, $content->{'anchor_reference'} if ($info_state->{'align_stack'}->[-1]->{'command'} eq 'center' or $info_state->{'align_stack'}->[-1]->{'command'} eq 'flushright'); + } + elsif ($content->{'command'} eq 'index_label') + { + #print STDERR "FFFFFFFFF($content->{'index_command'}) $all_line_passed + $info_state->{'line_count'} `$content->{'texi_entry'}'\n"; + my $index_line_nr = $all_line_passed + $info_state->{'line_count'}; + if ($info_state->{'blank_line'} and $content->{'index_command'} =~ /index$/) + { + my ($current_next, $index_next, $close_nex) = info_default_iterator_next($current, $index, $close); + $index_line_nr-- if (!defined($current_next)); + } + elsif ($content->{'index_command'} =~ /^[vf]table$/) + { + # if in a table, index label is systematically entered after + # the line is processed, as the line is processed with the + # item command, while the index entry is entered with the + # index_label callback that is done much later. + $index_line_nr--; + } + #print STDERR "index in a blank_line $content->{'index_command'} `$content->{'texi_entry'}'\n" if ($info_state->{'blank_line'}); + my $index_name = $content->{'index_entry_reference'}->{'index_name'}; + $info_default_index_line_string_length{$index_name} = t2h_default_string_width($index_line_nr) + if (!defined($info_default_index_line_string_length{$index_name}) or $info_default_index_line_string_length{$index_name} < t2h_default_string_width($index_line_nr)); + #print STDERR "RRRRRRRRRRRRR($content->{'index_entry_reference'}) $content->{'index_entry_reference'}->{'texi'} name: $index_name line: $index_line_nr max: $info_default_index_line_string_length{$index_name}\n"; + my $index_ref = { 'index_entry_reference' => $content->{'index_entry_reference'}, 'line_nr' => $index_line_nr }; +#print STDERR "INDEX($index_name) line $index_line_nr\n"; + $info_default_index_entries{$content->{'index_entry_reference'}} = $index_ref; + # there may be no cell in case of an empty multitable + if (@{$info_state->{'multitable_stack'}}) + { + if ($info_state->{'multitable_stack'}->[-1]->{'cells'}) + { + push @{$info_state->{'multitable_stack'}->[-1]->{'cells'}->[-1]->{'index_entries'}}, $index_ref; + } + else + { + push @{$info_state->{'multitable_stack'}->[-1]->{'index_entries'}}, $index_ref; + } + } + push @{$info_state->{'pending_index_entries'}}, $index_ref; + } + elsif ($content->{'command'} eq '*' and !$preformatted) + { + if (defined($pending_spaces_word->{'word'})) + { + $text_added .= $pending_spaces_word->{'spaces'} . $pending_spaces_word->{'word'}; + $pending_spaces_word->{'word'} = undef; + } + # spaces preceding @* are skipped + $pending_spaces_word->{'spaces'} = ''; + $text_added .= $content->{'text'}; + # just like following spaces + info_default_skip_spaces($current, $index, $close); + # this isn't done otherwise, though, here it is not important + # since this end the line + $line_char_counter += t2h_default_string_width($content->{'text'}); + goto new_text; + } + elsif ($content->{'command'} eq 'paragraph' and $info_state->{'align_stack'}->[-1]->{'command'} eq 'normal') + { + # empty paragraph + goto new_text if (!$content->{'content'}); + my $paragraphindent = get_conf('paragraphindent'); + $paragraphindent = 0 if ($paragraphindent eq 'none'); + if ($paragraphindent ne 'asis') + { + info_default_skip_spaces($current, $index, $close); + } + # if within a format $content->{'paragraph_in_element_nr'} + # should not be defined so no indentation will take place + if ($paragraphindent ne 'asis' and $paragraphindent and $line_char_counter == 0 and (defined($content->{'paragraph_in_element_nr'})) and ($info_state->{'indent_para'} or (!defined($info_state->{'indent_para'}) and ($content->{'paragraph_in_element_nr'} or (get_conf('firstparagraphindent') eq 'insert'))))) + { + $text_added .= ' ' x $paragraphindent; + } + $in_para = 1; + } + elsif ($content->{'command'} eq 'preformatted') + { + $preformatted++ if ($content->{'content'}); + } + elsif ($content->{'command'} eq 'exdent') + { + # if an end of line is added, in_exdent is set to 2 and + # set to one when processing the end of line that was just + # added, and set to 0 at the end of the line. + # if there is no end of line added, it is only set to 1. + if ($line_char_counter != 0) + { + $text_added .= "\n"; + $in_exdent = 2; + } + else + { + $in_exdent = 1; + } + $indent_length = ($indent_level -1) * $info_default_indent_length if ($indent_level > 0); + #goto new_text; + } + elsif ($content->{'command'} eq 'indent') + { + $info_state->{'indent_para'} = 1; + } + elsif ($content->{'command'} eq 'noindent') + { + $info_state->{'indent_para'} = 0; + } + elsif ($content->{'command'} eq 'sp') + { + $text_added .= $content->{'text'}; + goto new_text; + } + elsif ($content->{'command'} eq 'image') + { + # @image result count isn't counted in line_char_counter + # since it is not displayed in info + my $indent_added = 0; + $indent_added = ($indent_length - $line_char_counter) if ($indent_length - $line_char_counter > 0); + $text_added .= ' ' x $indent_added . $content->{'text'}; + $line_char_counter += $indent_added; + goto new_text; + } + elsif ($content->{'command'} eq 'ref') + { # adds a . if needed. + if ($content->{'text'} !~ /[\.,]$/ and $content->{'text'} !~ /::$/) + { + my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close); + if (!defined($text_next) or $text_next !~ /^[\.,]/) + { + $content->{'text'} .= '.'; + } + } + } + elsif ($content->{'command'} eq 'xref') + { # warn if there is no punctuation following + my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close); + if (!defined($text_next) or $text_next !~ /^./) + { # in makeinfo it is + # "End of file reached while looking for `.' or `,'" + # but maybe it may not be true. + main::line_warn(__("`.' or `,' must follow \@xref."), $Texi2HTML::THISDOC{'line_nr'}); + } + elsif ($text_next !~ /^[\.,]/) + { + my $char = substr($text_next, 0, 1); + main::line_warn(sprintf(__("`.' or `,' must follow \@xref, not %s"), $char), $Texi2HTML::THISDOC{'line_nr'}); + } + } + elsif ($content->{'definition_line'}) + { + + my $dummy_line_passed; + print STDERR "BUG: defined pending_word before DEFINITION_LINE\n" if defined($pending_spaces_word->{'word'}); + #print STDERR "DEFINITION_LINE($line_char_counter,$pending_spaces_word->{'spaces'},$indent_length,$in_para,$max_column): $content->{'text'}"; + ($line_char_counter, $pending_spaces_word, $dummy_line_passed, $text_added) = info_default_process_para_text($content->{'text'}, $line_char_counter, $pending_spaces_word, $indent_length, $max_column, 0, $indent_length+2*$info_default_indent_length); + $text_added .= $pending_spaces_word->{'spaces'}; + $pending_spaces_word->{'spaces'} = ''; + #print STDERR "DEFINITION_LINE($line_char_counter,$pending_spaces_word->{'spaces'}) -> $text_added"; + print STDERR "BUG: defined pending_word after DEFINITION_LINE\n" if defined($pending_spaces_word->{'word'}); + $indentation_done = 1; + + goto new_text; + } + elsif (($content->{'command'} eq 'item' or $content->{'command'} eq 'itemx') and exists $info_default_indent_format_length{$content->{'format_name'}}) + { + $item_pending = $content->{'format_name'}; + #if (!$info_state->{'blank_line'} and $content->{'command'} eq 'item') + my $first_item = 0; + + if ($content->{'command'} eq 'item') + { + if (!defined($content->{'parent'}->{'item_nr'})) + { + $content->{'parent'}->{'item_nr'} = 1; + $first_item = 1; + } + else + { + $content->{'parent'}->{'item_nr'}++; + } + } + + if ($item_pending =~ /table$/) + { + $table_item_line = 1; + $indent_length = ($indent_level -1) * $info_default_indent_length if ($indent_level > 0); + $in_table_item = 0; + } + else + { + $indent_length = ($info_default_indent_format_length{$item_pending} + +($indent_level -1)* $info_default_indent_length); + } + if (!$info_state->{'blank_line'} and ($content->{'command'} ne 'itemx') and (!$first_item or $indent_level > 1)) + { + my $dummy_line_passed; + ($line_char_counter, $dummy_line_passed, $text_added) = info_default_process_line_text($text_added, $line_char_counter, $indent_length); + $indentation_done = 1; + $line_added_before_item = 1; + $prepend_newline = 1; + #$text_added = "\n" . $text_added; + } + + if ($item_pending =~ /table$/) + { + # one less indentation level and no line break + # adding line_added_before_item allows the table_item_line to + # still be active after the additional blank line + $table_item_line = 1+$line_added_before_item; + } + else + { + info_default_skip_spaces($current, $index, $close); + } + } + elsif ($content->{'command'} eq 'menu' or $content->{'command'} eq 'listoffloats' or $content->{'heading_command'}) + { + $text_added .= "\n" unless ($info_state->{'blank_line'}); + } + elsif ($content->{'command'} eq 'direntry') + { + if ($content->{'content'}) + { + $direntry++; + } + } + elsif ($paragraph_style{$content->{'command'}}) + { + goto new_text if (!$content->{'content'}); + push @{$info_state->{'align_stack'}}, {'command' => $content->{'command'}}; + } + elsif ($content->{'command'} eq 'verbatim' or $content->{'command'} eq 'verbatiminclude') + { + # $preformatted cannot be used here since preformatted + # is closed before a verbatim, $preformatted_format is used + if (!$preformatted_format and $indent_level != 0) + { + if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'}) + { + $text_added .= "\n"; + } + my $verb_text = $content->{'text'}; + my ($line_passed, $end_of_line, $last_line, $text_indented, $blank_line) = info_default_count_lines($verb_text); + $content->{'text'} .= "\n" unless ($blank_line or ($last_line =~ /^\s*$/)); + } + } + # other raw commands + elsif ($content->{'raw_command'}) + { + # not considered as in a paragraph even if in a paragraph + $text_added .= $content->{'text'}; + goto new_text; + } + elsif ($content->{'command'} eq 'multitable' and $content->{'content'}) + { + my $indent_length_kept = $indent_level * $info_default_indent_length; + my $multitable = { + 'offset_in_file_kept' => $info_state->{'offset_in_file'}, + 'line_count_kept' => $info_state->{'line_count'}, + 'columns_size' => [ @{$content->{'columns_size'}} ], + 'result' => '', + 'length' => 0, + 'line_count' => 0, + 'result_kept' => $result, + 'length_kept' => $length, + 'all_line_passed_kept' => $all_line_passed, + 'line_char_counter_kept' => $line_char_counter, + 'max_column_kept' => $max_column, + 'indent_level_kept' => $indent_level, + 'indent_length_kept' => $indent_length_kept, + }; + push @{$info_state->{'multitable_stack'}}, $multitable; + $info_state->{'offset_in_file'} = 0; + $info_state->{'line_count'} = 0; + $result = ''; + $length = 0; + $all_line_passed = 0; + $line_char_counter = 0; + $indent_level = 0; + $indent_length = 0; + } + elsif ($content->{'command'} eq 'multitable_row') + { + my $multitable = $info_state->{'multitable_stack'}->[-1]; + if (!defined($multitable->{'cells'}) and ($result ne '')) + { + $multitable->{'result'} .= $result; + $multitable->{'length'} += $length; + $multitable->{'line_count'} += $all_line_passed; + $multitable->{'cells'} = []; + } + $multitable->{'cell_index'} = -1; + } + elsif ($content->{'command'} eq 'multitable_cell') + { + my $multitable = $info_state->{'multitable_stack'}->[-1]; + $multitable->{'cell_index'}++; + my $cell_width = $content->{'parent'}->{'parent'}->{'columns_size'}->[$multitable->{'cell_index'}]; + #$max_column = $cell_width-1; + $max_column = $cell_width -2; + my $cell = {'cell_width' => $cell_width, 'index_entries' => [], 'anchors' => []}; + push @{$multitable->{'cells'}}, $cell; + $result = ''; + $length = 0; + $all_line_passed = 0; + $line_char_counter = 0; + $indent_level = 0; + $indent_length = 0; + if (!$content->{'content'}) + {# empty cell + $cell->{'result'} = $result; + $cell->{'length'} = $length; + $cell->{'line_passed'} = $all_line_passed; + } + #info_default_skip_spaces($current, $index, $close); + } + if ($info_default_indented_commands{$content->{'command'}}) + { + if ($content->{'command'} =~ /^deff_item/) + { + info_default_skip_spaces($current, $index, $close); + } + #elsif (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0) and !$preformatted) + elsif (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0)) + { + $text_added .= "\n"; + } + # there is no close if !$content->{'content'} + $indent_level++ if ($content->{'content'}); + $indent_length = $indent_level * $info_default_indent_length; + } + elsif (($complex_format_map{$content->{'command'}} and $content->{'command'} ne 'menu') or $content->{'command'} eq 'cartouche') + { + #if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0) and !$preformatted_format) + if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0)) + { + $text_added .= "\n"; + } + } + if ($complex_format_map{$content->{'command'}} and $content->{'content'}) + { + $preformatted_format++; + } + } + + if (defined($content->{'text'})) + { + if ($in_para and !$in_exdent) + { + #print STDERR "IN_PARA text\n"; + my $new_text = $content->{'text'}; + # first find if in a context of no puncutation related + # modification: code style command or @var, @cite, @math + # acceptable for punctuation related modifications: + # asis b dfn emph i slanted sansserif r sc strong t w + my $current_tested = $content; + my $no_punctation_munging_command; + while ($current_tested) + { + if (defined($current_tested->{'command'}) and (($style_map{$current_tested->{'command'}} and $style_map{$current_tested->{'command'}}->{'args'} and $style_map{$current_tested->{'command'}}->{'args'}->[0] and $style_map{$current_tested->{'command'}}->{'args'}->[0] eq 'code') or $current_tested->{'command'} eq 'var' or $current_tested->{'command'} eq 'cite' or $current_tested->{'command'} eq 'math')) + { + $no_punctation_munging_command = 1; + last; + } + $current_tested = $current_tested->{'parent'}; + } + # a punctuation at the end of line in a command is treated + # like a punctuation in plain text, except for @:, + # accent commands, @dots, 'simple_style' command, and if in + # a command as found out just above. + + if (!$no_punctation_munging_command and (!defined($content->{'command'}) or ($content->{'command'} ne ':' and $content->{'command'} ne 'accents_commands' and $content->{'command'} ne 'dots') and !$info_default_leaf_command{$content->{'command'}}) and get_conf('frenchspacing') ne 'on' and $new_text =~ /([$info_default_end_sentence_character])([$info_default_after_punctuation_characters]*)(\s*)$/) + { + my $spaces = $3; + if (chomp($new_text)) + { + $new_text =~ s/(\s*)$/ /; + } + else + { + # these variables hold the place where the end + # of line characters are normalized. + my ($current_start_from, $index_start_from, $close_start_from) = ($current, $index, $close); + my $only_after_punctuation_characters = 1; + my $spaces_to_normalize = 0; + + # first find whether there are only + # after_punctuation_characters followed by spaces + # and find the place where the + # after_punctuation_characters end + my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close); + # go through the text as long as there are after_punctuation_characters + if (!$spaces) + { + while (1) + { + # !defined($text_next) catches many special + # commands, like anchor, index. Not sure if + # it is right or wrong. + # Also a style_map command never stops + # the search, so that @emph{ or @strong{ + # begin and end are not taken into account + if (!defined($current_next) or (!defined($text_next)) or (defined($command_next) and $command_next eq '*') or ($text_next !~ /^[$info_default_after_punctuation_characters]*(\s*)$/ and (!defined($command_next) or !$style_map{$command_next}))) + { + $only_after_punctuation_characters = 0; + last; + } + my $text_next_kept = $text_next; + # begin normalizing spaces at the last place + # where there are after_punctuation_characters + $current_start_from = $current_next; + $index_start_from = $index_next; + $index_start_from = $index_next; + ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current_next, $index_next, $close_next); + if ($text_next_kept =~ /^[$info_default_after_punctuation_characters]*\s+$/) + { + if (chomp($text_next_kept)) + { + $spaces_to_normalize = 1; + } + last; + } + } + } + # check if there are only spaces until end of line + if ($only_after_punctuation_characters and !$spaces_to_normalize) + { + while (1) + { + # !defined($text_next) catches many special + # commands, like anchor, index. Not sure if + # it is right or wrong. + last if (!defined($current_next) or (!defined($text_next)) or (defined($command_next) and $command_next eq '*')); + if ($text_next =~ /\S/ and (!defined($command_next) or !$style_map{$command_next})) + { + last; + } + else + { + if (chomp($text_next)) + { + $spaces_to_normalize = 1; + last; + } + } + ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current_next, $index_next, $close_next); + } + + } + if ($spaces_to_normalize) + { + # now do the spaces normalization + info_default_skip_spaces($current_start_from, $index_start_from, $close_start_from); + my $content = $current_start_from->{'content'}->[$index_start_from]; + $content->{'text'} =~ s/(\s*)$/ /; + } + } + } + elsif (chomp($new_text)) + { + $new_text =~ s/(\s*)$/ /; + } + $text_added .= $new_text; + } # ignore spaces outside of paragraphs and preformatted + elsif ($preformatted or $info_state->{'align_stack'}->[-1]->{'command'} ne 'normal') + { + #print STDERR "IN_PREFORMATTED or ALIGN text\n"; + $text_added .= $content->{'text'}; + } + else + { + my $chomped_text = $content->{'text'}; + if ($chomped_text !~ /\S/ and chomp($chomped_text) and !$item_pending) + { + if ($in_table_item and $info_state->{'only_spaces'}) + { + # in a blank_line + #print STDERR "IN_ITEM ignored: `$content->{'text'}'\n"; + } + elsif (!$info_state->{'blank_line'} or !$info_state->{'only_spaces'}) + { + #print STDERR "IN_ADDING_BLANK_LINE because no line before or text before\n"; + $text_added .= "\n"; + } + else + { + #print STDERR "IN_NOT_ADDING_BLANK_LINE\n"; + } + } + else + { # exdent, item not in paragraph nor in preformatted + #print STDERR "NOWHERE and not end of line (or item_pending) `$content->{'text'}'\n"; + $text_added .= $content->{'text'}; + } + } + } + else + { + if (defined($content->{'begin'})) + { + $text_added .= $content->{'begin'}; + } + # command that won't be closed, so the end has to be added + # here. It should mostly happen for empty style @-commands. + if (defined($content->{'end'}) and !defined($content->{'content'})) + { + $text_added .= $content->{'end'}; + } + } + } + if (!$preformatted and !$in_exdent and $info_state->{'align_stack'}->[-1]->{'command'} eq 'normal' and $in_para) + { + # the line_passed returned here are not used, since they are computed + # below. + $indentation_done = 1; + my $dummy_line_passed; + ($line_char_counter, $pending_spaces_word, $dummy_line_passed, $text_added) = info_default_process_para_text($text_added, $line_char_counter, $pending_spaces_word, $indent_length, $max_column, $in_w, $indent_level * $info_default_indent_length) if ($text_added ne ''); + } + elsif ($info_state->{'align_stack'}->[-1]->{'command'} ne 'center' and $info_state->{'align_stack'}->[-1]->{'command'} ne 'flushright') + { + my $dummy_line_passed; + ($line_char_counter, $dummy_line_passed, $text_added) = info_default_process_line_text($text_added, $line_char_counter, $indent_length); + #$indentation_done = 1; + } + else + { + $line_char_counter += t2h_default_string_width($text_added); + } + new_text: + if ($text_added ne '') + { + if ($item_pending and !$line_added_before_item) + { + #info_default_skip_spaces($current, $index, $close); + $item_pending = undef; + } + } + if ($text_added =~ /\S/) + { + $in_table_item = 0 if ($in_table_item); + $info_state->{'blank_line'} = 0; + } + $text_added = "\n" . $text_added if ($prepend_newline); + print STDERR "TEXT_ADDED($indent_length) `$text_added'\n" if ($text_added ne '' and $DEBUG); + #print STDERR "TEXT_ADDED($indent_length) `$text_added'\n"; + # from here, the next cmmand is available + ($current, $index, $close) = info_default_iterator_next($current, $index, $close); + + my ($line_passed, $end_of_line, $last_line, $text_indented, $blank_line) = info_default_count_lines($text_added, $indent_length, ($indentation_done + or $info_state->{'align_stack'}->[-1]->{'command'} eq 'center' + or $info_state->{'align_stack'}->[-1]->{'command'} eq 'flushright')); + $info_state->{'blank_line'} = 1 if ($blank_line); + print STDERR "ADDING `$text_indented'\n" if ($text_indented ne '' and $DEBUG); + # only_space is set in all the conditionals + if ($end_of_line) + { + $line_char_counter = 0; + if ($in_exdent) + { + $in_exdent--; + } + if ($table_item_line) + { + $table_item_line--; + $in_table_item = 1; + } + if (!$table_item_line and !$in_exdent and !$item_pending) + { + $indent_length = $indent_level * $info_default_indent_length; + } + $info_state->{'blank_line'} = 1 if ($info_state->{'only_spaces'} and ($last_line !~ /\S/)); + $info_state->{'only_spaces'} = 1; + } + else + { + if ($line_passed) + {# in that case we added more than one line, the $line_char_counter + # is reset to the last line length. + $line_char_counter = t2h_default_string_width($last_line); + $in_exdent = 0; + $indent_length = $indent_level * $info_default_indent_length; + if ($last_line !~ /\S/) + { + $info_state->{'only_spaces'} = 1; + } + else + { + $info_state->{'only_spaces'} = 0; + } + } + else + { + $info_state->{'only_spaces'} = 0 if ($last_line =~ /\S/); + } + } + if ($info_state->{'align_stack'}->[-1]->{'command'} eq 'center' + or $info_state->{'align_stack'}->[-1]->{'command'} eq 'flushright') + { + if (defined($current_line)) + { + $text_added = $current_line . $text_added; + } + $text_indented = ''; + $current_line = undef; + my $spaces_prepended = undef; + foreach my $line (split /^/, $text_added) + { + my $chomped_line = $line; + if (chomp($chomped_line)) + { + $line =~ s/^\s*//; + $line =~ s/\s*$//; + + if (t2h_default_string_width($line) eq 0) + { + $spaces_prepended = 0; + $text_indented .= "\n"; + } + else + { + my $line_width = t2h_default_string_width($line); + if ($line_width > $max_column) + { + $spaces_prepended = 0; + } + elsif ($info_state->{'align_stack'}->[-1]->{'command'} eq 'center') + { + $spaces_prepended = (($max_column -1 - $line_width) /2); + } + else + { + $spaces_prepended = ($max_column -1 - $line_width); + } + $text_indented .= ' ' x$spaces_prepended . $line ."\n"; + } + } + else + { + $current_line = $line; + } + } + if (defined ($spaces_prepended) and defined($info_state->{'align_stack'}->[-1]->{'anchors'})) + { + while (@{$info_state->{'align_stack'}->[-1]->{'anchors'}}) + { + my $anchor = shift @{$info_state->{'align_stack'}->[-1]->{'anchors'}}; + $anchor->{'info_offset'} += info_default_byte_count(' ' x$spaces_prepended); + } + } + } + + if ($direntry) + { + $info_default_dir_specification .= $text_indented; + } + else + { + $result .= $text_indented; + $length += info_default_byte_count($text_indented); + $all_line_passed += $line_passed; + } + } + return ($length, $result, $all_line_passed); +} + +sub info_default_open_command($$;$) +{ + my $state = shift; + my $command = shift; + my $additional_entries = shift; + + my $index = 0; + + my $info_state = info_default_get_state($state); + # index in the parent content list + $index = scalar(@{$info_state->{'current'}->{'content'}}) + if (defined($info_state->{'current'}->{'content'})); + my $new_command = {'command' => $command, 'parent' => $info_state->{'current'}, 'index_in_parent' => $index }; + if (defined($additional_entries)) + { + foreach my $key (keys(%$additional_entries)) + { + $new_command->{$key} = $additional_entries->{$key}; + } + } + + push @{$info_state->{'current'}->{'content'}}, $new_command; + $info_state->{'current'} = $new_command; + print STDERR "TREE($info_state->{'nr'}): Opened $command\n" if ($DEBUG); +} + +sub info_default_close_command($$;$$$) +{ + my $state = shift; + my $command = shift; + my $begin = shift; + my $end = shift; + my $command_entries = shift; + + $state = $Texi2HTML::THISDOC{'state'} if (!defined($state)); + my $info_state = info_default_get_state($state); + print STDERR "TREE($info_state->{'nr'}): Closing $command\n" if ($DEBUG); + if (!defined($info_state->{'current'})) + { + print STDERR "info_state->{'current'} not defined (closing $command)\n"; + } + elsif (!defined($info_state->{'current'}->{'command'})) + { + print STDERR "info_state->{'current'}->{'command'} not defined (closing $command)\n"; + } + elsif ($command ne $info_state->{'current'}->{'command'}) + { + print STDERR "Was waiting for $info_state->{'current'}->{'command'} (closing $command)\n"; + } + #return if $no_close; + $command_entries->{'begin'} = $begin; + $command_entries->{'end'} = $end; + $command_entries->{'line_nr'} = $Texi2HTML::THISDOC{'line_nr'}; + foreach my $key (keys(%$command_entries)) + { + $info_state->{'current'}->{$key} = $command_entries->{$key} + if (defined($command_entries->{$key})); + } + + $info_state->{'current'} = $info_state->{'current'}->{'parent'}; + + return info_default_output($info_state) + if (!defined($info_state->{'current'}->{'command'})); + return ''; +} + +sub info_default_store_text($$;$$) +{ + my $state = shift; + my $text = shift; + my $command = shift; + my $text_entries = shift; + + $state = $Texi2HTML::THISDOC{'state'} if (!defined($state)); + my $info_state = info_default_get_state($state); + return '' if ((!defined($text) or $text eq '') and !defined($command)); + + ################################## debug + my $command_text = ''; + $command_text = "\[$command\]" if (defined($command)); + $command_text .= $text if (defined($text)); + print STDERR "TREE($info_state->{'nr'}) Storing: ${command_text}\n" if ($DEBUG); + ################################## end debug + + $text_entries->{'text'} = $text if (defined($text)); + $text_entries->{'command'} = $command if (defined($command)); + $text_entries->{'parent'} = $info_state->{'current'}; + $text_entries->{'line_nr'} = $Texi2HTML::THISDOC{'line_nr'}; + push @{$info_state->{'current'}->{'content'}}, $text_entries; + return info_default_output($info_state) + if (!defined($info_state->{'current'}->{'command'})); + return ''; +} + +sub info_default_increment_paragraph ($$$;$) +{ + my $in_format = shift; + my $parent_format = shift; + my $info_state = shift; + my $command = shift; + + if ($in_format) + { + $parent_format->{'paragraph_in_format_nr'} = 0 if (!defined($parent_format->{'paragraph_in_format_nr'})); + $parent_format->{'paragraph_in_format_nr'}++; + } + else + { + $info_state->{'paragraph_in_element_nr'}++; + } + ####################### debug + $command = 'PARA' if (!defined($command)); + if (0) + #if (1) + { + my $format_info = ''; + if ($in_format) + { + $format_info = "format: [$parent_format->{'command'}],$parent_format->{'paragraph_in_format_nr'}" + } + print STDERR "INCREMENT_PARA($command) $info_state->{'paragraph_in_element_nr'} $format_info\n"; + } + ####################### end debug +} + +sub info_default_begin_format_texi($$$) +{ + my $command = shift; + my $line = shift; + my $state = shift; + + my $info_state = info_default_get_state ($state); + my ($parent_format, $in_format); + ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'}); + info_default_increment_paragraph ($in_format, $parent_format, $info_state, $command); + # remove space in front of center, unless it removes the end of line! + $line =~ s/^\s*// if ($command eq 'center' and $line =~ /\S/); + # don't open a format if it is a @def*x command and we are already in the + # corresponding @def* command + info_default_open_command($state,$command) unless ($def_map{$command} and $command =~ /x$/ and defined($info_state->{'current'}->{'command'}) and "$info_state->{'current'}->{'command'}x" eq $command); + return $line; +} + +sub info_default_begin_style_texi($$$$$) +{ + my $command = shift; + my $state = shift; + my $stack = shift; + my $real_style_command = shift; + my $remove_texi = shift; + + info_default_open_command($state,$command) + unless ($info_default_accent_commands{$command} or exists $things_map{$command} + or $command =~ /^special_(\w+)_(\d+)$/); +# if ($real_style_command); +} + +sub info_default_begin_paragraph_texi($$$) +{ + my $command = shift; + my $paragraph_macros = shift; + my $paragraph_command = shift; + #print STDERR "begin_paragraph $command\n"; + my $state = shift; + my $stack = shift; + info_default_open_command($state,$command); + foreach my $style_command (@$paragraph_macros) + { + #print STDERR "para stack: $style_command->{'style'}\n"; + info_default_open_command($state,$style_command->{'style'}); + } +} + +sub info_default_simple_command($$$$$) +{ + my $command = shift; + my $in_preformatted = shift; + my $in_math = shift; + my $line_nr = shift; + my $state = shift; + + my $result = $simple_map{$command}; + $result = $simple_map_math{$command} if ($in_math and defined($simple_map_math{$command})); + # discards '-' '|' '/' and ':'. If ':' is associated with a punctuation + # character it is added to the tree in info_default_colon_command + return info_default_store_text($state,$result,$command) if ($result ne ''); + return ''; +} + +sub info_default_colon_command($) +{ + my $punctuation_character = shift; + if (defined($colon_command_punctuation_characters{$punctuation_character}) + and $punctuation_character =~ /^[$punctuation_characters]$/) + { + return info_default_store_text(undef,$colon_command_punctuation_characters{$punctuation_character}, ':'); + } + else + { + return info_default_store_text(undef,$punctuation_character); + } +} + +sub info_default_thing_command($$$$$$) +{ + my $command = shift; + my $text = shift; + my $in_preformatted = shift; + my $in_math = shift; + my $line_nr = shift; + my $state = shift; + + my $result = $things_map{$command}; + #return info_default_close_command($state, $command, $result, $text, ''); + return info_default_store_text($state, $result, $command); +# return $result . $text; +} + + +sub info_default_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 $command_stack = shift; + my $kept_line_nrs = shift; + + my $begin = ''; + my $end = ''; + + # note that the $text is always discarded for closed commands + + # the formatting is done right here, and the result is entered as text below. + if ($info_default_leaf_command{$command}) + { + my $style_index = 0; + my @formatted_args = (); + foreach my $arg (@$args) + { + # we don't use style, since we only set 'orig_args' in style_map + # and not in style_map_pre. + my $arg_style = $style_map{$command}->{'orig_args'}->[$style_index]; + my $new_state = main::duplicate_formatting_state($state); + if ($arg_style eq 'normal') + { + push @formatted_args, main::substitute_line($arg, "\@$command", $new_state); + } + elsif ($arg_style eq 'code') + { + $new_state->{'code_style'} = 1; + push @formatted_args, main::substitute_line($arg, "\@$command", $new_state); + } + else + { + print STDERR "Unknown arg style($style_index) $arg_style for $command, $state->{'remove_texi'}\n"; + } + $style_index++; + } + $args = \@formatted_args; + } + if (defined($style->{'function'})) + { # in case of an accent, some text is returned here if there are still + # more accents on the command_stack, otherwise it is put in the tree. + # Other commands text results are put in the tree below. + $text = &{$style->{'function'}}($command, $args, $command_stack, $state, $line_nr, $kept_line_nrs); + } + elsif ($info_default_leaf_command{$command}) + { # no formatting function but a leaf command, it is just replaced + # by the formatted argument, and put in the tree below. + $text = $args->[0]; + } + if (defined($style->{'begin'}) and !$no_open) + { + $begin = $style->{'begin'}; + } + if (defined($style->{'end'}) and !$no_close) + { + $end = $style->{'end'}; + } + # normal style commands + unless($special_style{$command} or $info_default_accent_commands{$command} or ($command eq 'hyphenation') or $info_default_leaf_command{$command}) + { + return info_default_close_command($state, $command, $begin, $end); + } + # this is for *ref, images and footnotes text registering and putting + # in the tree. + # anchor is already in the tree, from anchor_label. + if (($special_style{$command} or $info_default_leaf_command{$command}) and $command ne 'anchor') + { + return info_default_store_text ($state, $begin.$text.$end, $command); + } + # for accents, hyphenation and anchor + # (though the result for anchor is always an empty string). + return $begin.$text.$end; +} + +sub info_default_header () +{ + return $Texi2HTML::THISDOC{'info_header'} if (defined($Texi2HTML::THISDOC{'info_header'})); +# $Texi2HTML::THISDOC{'program'} + my $input_basename = $Texi2HTML::THISDOC{'input_file_name'}; + $input_basename =~ s/^.*\///; # if ($TEST); + $input_basename = $STDIN_DOCU_NAME if ($input_basename eq '-'); + my $output_basename = $Texi2HTML::THISDOC{'filename'}->{'top'}; + $output_basename =~ s/^.*\///; + my $result = "This is $output_basename, produced by makeinfo version 4.13 from $input_basename. "; + my $dummy; + ($dummy, $dummy, $dummy, $result) = info_default_process_para_text($result, 0, {'spaces' => ''}, undef, get_conf('fillcolumn')); + $result .= "\n\n"; + $result .= "$Texi2HTML::THISDOC{'copying_comment'}"; + if ($info_default_dir_specification) + { + $result .= "$info_default_dir_specification\n"; + } + $Texi2HTML::THISDOC{'info_header'} = $result; + return $result; +} + +sub info_default_print_page_head($) +{ + my $fh = shift; + my $header = info_default_header(); + print $fh "".$header; + + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + $info_state->{'offset_in_file'} += info_default_byte_count($header); + $info_state->{'blank_line'} = 1 if ($Texi2HTML::THISDOC{'copying_comment'} eq ''); +} + +sub info_default_parent_format($) +{ + my $parent_format = shift; + my $in_format = 0; + while (1) + { + if (defined($parent_format->{'command'}) and $info_default_format{$parent_format->{'command'}}) + { + $in_format = 1; + last; + } + last if (!defined($parent_format->{'parent'})); + + $parent_format = $parent_format->{'parent'}; + } + return ($parent_format, $in_format); +} + +sub info_default_paragraph($$$$$$$$$$$$) +{ + my $text = shift; + my $align = shift; + my $indent = shift; + my $paragraph_command = shift; + my $paragraph_command_formatted = shift; + my $paragraph_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + + my $top_stack = ''; + $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); + + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + my ($parent_format, $in_format); + ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'}->{'parent'}); + info_default_increment_paragraph ($in_format, $parent_format, $info_state); + my $additional_args = {'top_stack' => $top_stack, 'parent_format' => $parent_format}; + $additional_args->{'paragraph_in_element_nr'} = ($info_state->{'paragraph_in_element_nr'} - 1) if (!$in_format); + + return info_default_close_command(undef, 'paragraph', undef, undef, $additional_args); +} + +# currently not used, but could be used if info_default_preformatted +# return something that is not 'false', for example spaces, though we +# want the preformatted to be ignored. Though it is not sure that if there +# are spaces we want to ignore the preformatted. +sub info_default_empty_preformatted($) +{ + my $text = shift; + my $result = info_default_preformatted($text, undef, undef, undef, undef, + undef, undef, undef, undef, undef, undef, undef); + return 0; +} + +sub info_default_preformatted($$$$$$$$$$$$) +{ + my $text = shift; + my $pre_style = shift; + my $class = shift; + my $leading_command = shift; + my $leading_command_formatted = shift; + my $preformatted_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + + return info_default_close_command(undef, 'preformatted'); +} + + +sub info_default_node_line($$) +{ + my $element = shift; + my $info_state = shift; + my $outfile = $Texi2HTML::THISDOC{'filename'}->{'top'}; + $outfile = $STDOUT_DOCU_NAME if ($outfile eq '-'); + my $result = "\x{1F}\nFile: $outfile, Node: $element->{'text'}"; + if (defined($element->{'NodeNext'})) + { # This is not translatable + $result .= ", Next: $element->{'NodeNext'}->{'text'}"; + } + if (defined($element->{'NodePrev'})) + { + $result .= ", Prev: $element->{'NodePrev'}->{'text'}"; + } + if (defined($element->{'NodeUp'})) + { + $result .= ", Up: $element->{'NodeUp'}->{'text'}"; + } + $result .= "\n\n"; + # the line_count is ahead from the number of lines by one. + $info_state->{'line_count'} = 3; + $info_state->{'offset_in_file'} += info_default_byte_count($result); + $info_state->{'blank_line'} = 1; + return $result; +} + +sub info_default_element_heading($$$$$$$$$$$$) +{ + my $element = shift; + my $command = shift; + my $texi_line = shift; + my $line = shift; + my $in_preformatted = shift; + my $one_section = shift; + my $element_heading = shift; + my $first_in_page = shift; + my $is_top = shift; + my $previous_is_top = shift; + my $command_line = shift; + my $element_id = shift; + my $new_element = shift; + + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + + # FIXME use $element or $Texi2HTML::THIS_ELEMENT? Main program should + # ensure they are the same. + if ($new_element and ($element ne $new_element and $element->{'node'})) + { + die "There is a new element, but element `$element->{'texi'}' is not the new element\n"; + } + # FIXME + # non node element may appear if the element appears before the first + # node/section element. For example `element not associated with a node' + # won't be associated with a node. + # @unnumbered element not associated with a node + # @node Top + # @top Top element + if (!$element->{'node'}) + { + return &$heading($element, $command, $texi_line, $line, $in_preformatted, $one_section, $element_heading); + } + + my $before = ''; + $element->{'info_offset'} = $info_state->{'offset_in_file'}; + push @{$info_state->{'pending_tags'}}, $element; + + my $result = info_default_node_line($element, $info_state); + + $info_default_footnote_index = 0; + $info_default_current_node = $element; + + return $before.$result; +} + +sub info_default_heading($$$$$;$$) +{ + my $element = shift; + my $command = shift; + my $texi_line = shift; + my $line = shift; + my $in_preformatted = shift; + my $one_section = shift; + my $element_heading = shift; + + die "Heading called for a node\n" if ($element->{'node'}); + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + $info_state->{'paragraph_in_element_nr'} = 0; + if (!defined($element->{'texi'})) + { + main::msg_debug("for $element, element->{'texi'} not defined, texi_line: $texi_line"); + } + elsif (!defined($element->{'text'})) + { + main::msg_debug("for $element, $element->{'texi'}, element->{'text'} not defined"); + } + return '' if ($element->{'tag'} eq 'part'); + + my $text = "$element->{'text'}"; + # when @top is empty, use settitle + $text = $Texi2HTML::THISDOC{'settitle'} if (!length($text) and $element->{'tag'} eq 'top' and defined ($Texi2HTML::THISDOC{'settitle'}) and length($Texi2HTML::THISDOC{'settitle'})); + my $result = &$heading_text ("\@$command", $text, $element->{'level'}); + + $result .= "\n"; + + return info_default_store_text($state, $result, $command, {'heading_command' => 1}); +} + +sub info_default_normal_text($$$$$$$;$) +{ + my @initial_args = @_; + my $text = shift; + my $in_raw_text = shift; # remove_texi + my $in_preformatted = shift; + my $in_code = shift; + my $in_math = shift; + my $in_simple = shift; + my $style_stack = shift; + my $state = shift; + + # $Texi2HTML::THISDOC{'ENCODING_NAME'}) should be defined, but maybe + # not when parsing commands in first or second pass, and removeing texi + # like what is done for @setfilename. + if ($ENABLE_ENCODING and defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and ($Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8') and $USE_UNICODE) + { + $text = &t2h_utf8_normal_text(@initial_args); + } + else + { + #print STDERR "info_default_normal_text $text $in_preformatted $in_code \n"; + $text = uc($text) if (in_cmd($style_stack, 'sc')); + $text = uc($text) if (in_cmd($style_stack, 'var')); + if (! $in_code and !$in_preformatted) + { + $text =~ s/---/\x{1F}/g; + $text =~ s/--/-/g; + $text =~ s/\x{1F}/--/g; + $text =~ s/``/"/g; + $text =~ s/\'\'/"/g; + } + } + # accented characters are not handled as normal text, but when the last + # accent command on the stack is closed. + if ($style_stack and @$style_stack and $info_default_accent_commands{$style_stack->[-1]}) + { + return $text; + } +#print STDERR "NORMAL\n"; + return info_default_store_text($state,$text); +} + +# this is not called in preformatted +sub info_default_empty_line($$) +{ + my $text = shift; + my $state = shift; + #ignore the line if it just follows a deff + #return '' if ($state->{'deff_line'}); + return info_default_store_text($state,$text); +# return ''; +} + +# change interface? +sub info_default_anchor_label($$$$) +{ + my $id = shift; + my $anchor_text = shift; + my $anchor_reference = shift; + my $in_special_region = shift; + return '' if ($in_special_region); + #print STDERR "Storing anchor $anchor_reference->{'text'}\n"; + main::line_warn(__("anchor outside of any node, it won't be registered"), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node)); + return info_default_store_text(undef,undef,'anchor',{'anchor_reference' => $anchor_reference}); +} + +sub info_default_acronym_like($$$$$$) +{ + my $command = shift; + my $acronym_texi = shift; + my $acronym_text = shift; + my $with_explanation = shift; + my $explanation_lines = shift; + my $explanation_text = shift; + my $explanation_simply_formatted = shift; + + if ($with_explanation) + { + return "$acronym_text ($explanation_text)"; + } + else + { + return "$acronym_text"; + } +} + + +sub info_default_print_page_foot($) +{ + my $fh = shift; + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + my $indirect = 0; + if (!defined ($info_state->{'pending_tags'})) + { # i18n + main::document_warn ("Document without nodes."); + } + else + { + $indirect = 1 if ($info_default_out_file_nr > 1); + if ($indirect) + { + close ($Texi2HTML::THISDOC{'FH'}); + unless (rename ("$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'}", "$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'}-1")) + { + main::document_warn ("Rename $Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'} failed: $!"); + } + + my $INDIRECT = main::open_out("$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'}"); + print $INDIRECT "".info_default_header(); + print $INDIRECT "\x{1F}\nIndirect:"; + foreach my $indirect (@info_default_pending_indirect) + { + print $INDIRECT "\n$indirect->{'file'}: $indirect->{'offset'}"; + } + $fh = $INDIRECT; + } + # makeinfo seems to add systematically an additional \n, done just below + print $fh "\n\x{1F}\nTag Table:\n"; + + if ($indirect) + { + print $fh "(Indirect)\n"; + } + my $Top_seen; + foreach my $element (@{$info_state->{'pending_tags'}}) + { + my $prefix; + $prefix = 'Node' if ($element->{'node'}); + $prefix = 'Ref' if ($element->{'anchor'} or $element->{'float'}); + print $fh "$prefix: $element->{'text'}\x{7F}$element->{'info_offset'}\n"; + $Top_seen = 1 if ($element->{'text'} =~ /^top$/i); + } + if (!$Top_seen) + {# i18n + main::document_warn ("Document without Top node."); + } + print $fh "\x{1F}\nEnd Tag Table\n"; + } + + # IN_ENCODING is the documentencoding transformed to the encoding names + # usually seen in html. This is what the info readers should understand. + my $coding = get_conf('IN_ENCODING'); + $coding = get_conf('DOCUMENT_ENCODING') if (!defined($coding)); + if (defined($coding)) + { + print $fh "\n\x{1F}\nLocal Variables:\ncoding: $coding\nEnd:\n"; + } +} + +sub info_default_print_Top_footer($$$) +{ + my $fh = shift; + my $end_page = shift; + my $element = shift; + if ($end_page) + { + &$print_page_foot($fh); + } + info_default_end_section($fh, $end_page, $element); +} + +sub info_default_footnote_texi($$$) +{ + my $text = shift; + my $state = shift; + my $style_stack = shift; + + unless ($state->{'outside_document'} or (defined($state->{'multiple_pass'}) and $state->{'multiple_pass'} > 0)) + { + $info_default_footnote_index++; + } + my $footnote_number = $info_default_footnote_index; + $footnote_number = $NO_NUMBER_FOOTNOTE_SYMBOL if (!$NUMBER_FOOTNOTES); + return "($footnote_number) $text"; + #return undef; +} + +sub info_default_print_section +{ + my $fh = shift; + my $first_in_page = shift; + my $previous_is_top = shift; + my $element = shift; + my $nw = main::print_lines($fh); + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + if (!$info_state->{'blank_line'}) + { + my $end = "\n"; + $info_state->{'offset_in_file'} += info_default_byte_count($end); + $info_state->{'line_count'}++; + print $fh "$end"; + } + if (@info_default_pending_footnotes) + { + my $footnote_text; + my $footnote_element; + if (get_conf('footnotestyle') eq 'separate') + { + my $node_ref = $info_default_current_node; + # thee is a warning when processing the footnote, like + # "Footnote defined without parent node" + $node_ref = {'text' => 'no node', 'file' => ''} if (!defined($node_ref)); + $footnote_element = { 'NodeUp' => $node_ref, + 'text' => $node_ref->{'text'} . "-Footnotes", + 'file' => $node_ref->{'file'}, + 'info_offset' => $info_state->{'offset_in_file'}, + 'node' => 1, + }; + $footnote_element->{'element_ref'} = $footnote_element; + push @{$info_state->{'pending_tags'}}, $footnote_element; + $footnote_text = info_default_node_line($footnote_element, $info_state); + } + else + { # FIXME i18n? + $footnote_text = " ---------- Footnotes ----------\n\n"; + $info_state->{'offset_in_file'} += info_default_byte_count($footnote_text); + $info_state->{'line_count'} += 2; + #print STDERR "MMMMMMMMMMMMMMMMMM $info_state->{'line_count'}\n"; + } + while (@info_default_pending_footnotes) + { + #push @info_default_pending_footnotes, [$lines, $footnote_text, ${info_default_footnote_index}, $node_name, $footnote_info_state]; + my $footnote = shift @info_default_pending_footnotes; + my $foot_nr = $footnote->{'footnote_index'}; + my $node_name = $footnote->{'node_name'}; + my $lines = $footnote->{'lines'}; + push @{$info_state->{'pending_tags'}}, {'anchor' => 1, 'text' => "${node_name}-Footnote-${foot_nr}", 'info_offset' => $info_state->{'offset_in_file'} }; + my $footnote_info_state = $footnote->{'footnote_info_state'}; + my $footnote_result = shift @{$lines}; + # this is used to keep track of the size when there were + # leading spaces that will be removed below. This is only used + # to get the difference, the value itself is not of use. + my $initial_length = info_default_byte_count($footnote_result); + + $footnote_result =~ s/^\s*//; + #$footnote_result = " ($foot_nr) " . $footnote_result; + $footnote_result = ' ' x get_conf('paragraphindent') . $footnote_result; + foreach my $footnote_pending_tags(@{$footnote_info_state->{'pending_tags'}}) + { + $footnote_pending_tags->{'info_offset'} += $info_state->{'offset_in_file'} + info_default_byte_count($footnote_result) - $initial_length; + push @{$info_state->{'pending_tags'}}, $footnote_pending_tags; + } + foreach my $footnote_pending_index_entry(@{$footnote_info_state->{'pending_index_entries'}}) + { + #print STDERR "TTTTTTTTTTT($footnote_pending_index_entry->{'index_entry_reference'}->{'entry'}) $footnote_pending_index_entry->{'line_nr'} $info_state->{'line_count'}\n"; + $footnote_pending_index_entry->{'line_nr'} += $info_state->{'line_count'}; + $footnote_pending_index_entry->{'index_entry_reference'}->{'real_element'} = $footnote_element if (get_conf('footnotestyle') eq 'separate'); + } + my $line; + while (@$lines) + { + $line = shift @$lines; + $footnote_result .= $line; + } + my ($line_passed, $end_of_line, $last_line, $text_indented, $blank_line) = info_default_count_lines($footnote_result); + if ($line_passed == 0) + {# certainly out of paragraph commands + $footnote_result =~ s/\s*$//; + $footnote_result .= "\n"; + $line_passed = 1; + } + unless (($last_line !~ /\S/ and $end_of_line) or ($blank_line)) + { + $footnote_result .= "\n"; + $line_passed += 1; + } + + $info_state->{'offset_in_file'} += info_default_byte_count($footnote_result); + $info_state->{'line_count'} += $line_passed; + $footnote_text .= $footnote_result; + } + print $fh "$footnote_text"; + } +} + +sub info_default_end_section($$$) +{ + my $fh = shift; + my $end_foot_navigation = shift; + my $element = shift; + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + + if (defined($Texi2HTML::THISDOC{'SPLIT_SIZE'}) and + $info_state->{'offset_in_file'} > ($info_default_out_file_nr) * $Texi2HTML::THISDOC{'SPLIT_SIZE'}) + { + if ($info_default_out_file_nr == 1) + { # push also the first node, which is always the first pending_tags + push @info_default_pending_indirect, {'file'=>"$Texi2HTML::THISDOC{'filename'}->{'top'}-$info_default_out_file_nr", 'offset' => $info_state->{'pending_tags'}->[0]->{'info_offset'} }; + } + $info_default_out_file_nr++; + # these file descriptors leak, but this allows the user to write a + # foot navigation himself, otherwise he would write on a closed file + # descriptor + #close($Texi2HTML::THISDOC{'FH'}); + if (!$end_foot_navigation) + { + main::open_out_file("$Texi2HTML::THISDOC{'filename'}->{'top'}-$info_default_out_file_nr"); + #print STDERR "X-$info_default_out_file_nr: $info_state->{'offset_in_file'}\n"; + &$print_page_head($Texi2HTML::THISDOC{'FH'}); + push @info_default_pending_indirect, {'file'=>"$Texi2HTML::THISDOC{'filename'}->{'top'}-$info_default_out_file_nr", 'offset' => $info_state->{'offset_in_file'}}; + } + } +} + +sub info_default_one_section($$) +{ + my $fh = shift; + my $element = shift; + &$print_section($fh, 1, 0, $element); + &$print_page_foot($fh); +} + +sub info_default_begin_special_region($$$) +{ + my $region = shift; + my $state = shift; + my $lines = shift; + my $info_state = info_default_get_state ($state); + # reset paragraph_in_element_nr if out ofdocument formatting + if ($state->{'outside_document'}) + { + $info_state->{'paragraph_in_element_nr'} = 0; + } +} + +sub info_default_end_special_region($$$) +{ + my $region = shift; + my $state = shift; + my $text = shift; + my $info_state = info_default_get_state ($state); + my $end = ''; + if (!$info_state->{'blank_line'}) + { + $end = "\n"; + $info_state->{'offset_in_file'} += info_default_byte_count($end); + } + return $text.$end; +} + +sub info_default_menu_link($$$$$$$$) +{ + my $entry = shift; + my $state = shift; + my $href = shift; + my $node = shift; + my $title = shift; + my $ending = shift; + my $has_title = shift; + my $command_stack = shift; + my $preformatted = shift; + + $title = '' unless ($has_title); + $title .= ':' if ($title ne ''); + my $result = "$MENU_SYMBOL$title$node$ending"; + return info_default_store_text($state,$result,'menu_entry'); +} + +# not used, menu is a normal preformatted command +#sub info_default_menu_command($$$) +#{ +# my $format = shift; +# my $text = shift; +# my $in_preformatted = shift; +# return info_default_close_command(undef, $format, "* Menu:\n", undef, "\n"); +#} + +sub info_default_complex_format($$) +{ + my $name = shift; + my $text = shift; + my ($begin, $end); + if ($name eq 'menu') + { + main::line_warn(__("\@menu before first node"), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node)); + $begin = "* Menu:\n\n"; + } + elsif ($name eq 'direntry') + { + main::line_warn(__("\@direntry after first node"), $Texi2HTML::THISDOC{'line_nr'}) if (defined($info_default_current_node)); + $begin = "START-INFO-DIR-ENTRY\n"; + $end = "END-INFO-DIR-ENTRY\n"; + } + return info_default_close_command(undef, $name, $begin, $end); +} + +sub info_default_quotation($$$$$) +{ + my $command = shift; + my $text = shift; + my $argument_text = shift; + my $argument_text_texi = shift; + my $authors = shift; + + my $attribution; + if ($authors) + { + $attribution = ''; + foreach my $author (@$authors) + { + my $author_texi = $author->{'author_texi'}; + chomp($author_texi); + $attribution .= gdt("\@center --- \@emph{{author}}\n", {'author' => $author_texi}, {'duplicate' => 1, 'allow_paragraph' => 1}); + } + } + + return info_default_close_command(undef, $command, undef, $attribution); +} + +sub info_default_misc_commands($$$$$) +{ + my $command = shift; + my $line = shift; + my $args = shift; + my $stack = shift; + my $state = shift; + + info_default_store_text($state,undef,$command) if ($command eq 'exdent' or $command eq 'noindent' or $command eq 'indent'); + return ($command, $line, undef); +} + +sub info_default_external_ref($$$$$$$$$) +{ + my $type = shift; + my $section = shift; + my $book = shift; + my $file = shift; + my $href = shift; + my $cross_ref = shift; + my $args_texi = shift; + my $formatted_args = shift; + my $node = shift; + + return info_default_inforef($formatted_args) if ($type eq 'inforef'); + return info_default_normal_reference($type, $formatted_args); +} + +sub info_default_internal_ref($$$$$$$$) +{ + my $type = shift; + my $href = shift; + my $short_name = shift; + my $name = shift; + my $is_section = shift; + my $args_texi = shift; + my $formatted_args = shift; + my $element = shift; + + $formatted_args->[1] = $name if ($element->{'float'} and (!defined($formatted_args->[1]) or $formatted_args->[1] eq '')); + return info_default_inforef($formatted_args) if ($type eq 'inforef'); + return info_default_normal_reference($type, $formatted_args); +} + +sub info_default_normal_reference($$) +{ + my $command = shift; + my $formatted_args = shift; + for (my $i = 0; $i < scalar(@$formatted_args); $i++) + { + $formatted_args->[$i] = undef if (defined($formatted_args->[$i]) and + $formatted_args->[$i] =~ /^\s*$/); + } + my $node = $formatted_args->[0]; + # an error, should trigger the message: Undefined node `' in @ref. + # avoid undef value and use an empty string instead. + $node = '' if (!defined($node)); + my $name = $formatted_args->[1]; + $name = $formatted_args->[2] if (!defined($name)); + my $file = $formatted_args->[3]; + $file = '' if (!defined($file) and defined($formatted_args->[4])); + $name = $node if (!defined($name) and defined($file)); + my $result = '*note '; + $result = '*Note ' if ($command eq 'xref'); + if (defined($name)) + { + $result .= "${name}: "; + $result .= "($file)" if (defined($file)); + $result .= "$node"; + $result .= '.' if ($command eq 'pxref'); + } + else + { + $result .= "${node}::"; + } + return $result; +} + +sub info_default_inforef($) +{ + my $formatted_args = shift; + return info_default_normal_reference('ref', [$formatted_args->[0], $formatted_args->[1], undef, $formatted_args->[2], 'dumb manual name']); +} + +sub info_default_image_files($$$$) +{ + my $base = shift; + my $extension = shift; + my $texi_base = shift; + my $texi_extension = shift; + my @files = (); + return @files if (!defined($base) or ($base eq '')); + + if (defined($extension) and ($extension ne '')) + { + push @files, ["${base}$extension", "${texi_base}$extension"]; + push @files, ["$base.$extension", "$texi_base.$extension"]; + } + foreach my $ext (@IMAGE_EXTENSIONS) + { + push @files, ["$base.$ext", "$texi_base.$ext"]; + } + return @files; +} + +sub info_default_image($$$$$$$$$$$$$$$$$) +{ + my $file = shift; + my $base = shift; + my $preformatted = shift; + my $file_name = shift; + my $alt = shift; + my $width = shift; + my $height = shift; + my $raw_alt = shift; + my $extension = shift; + my $working_dir = shift; + my $file_path = shift; + my $in_paragraph = shift; + my $file_locations = shift; + my $base_simple_format = shift; + my $extension_simple_format = shift; + my $file_name_simple_format = shift; + my $line_nr = shift; + + my $txt_path; + my $found_file; + + my @extensions = @IMAGE_EXTENSIONS; + if (defined($extension) and ($extension ne '')) + { + unshift @extensions, ".$extension"; + unshift @extensions, "$extension"; + } + else + { + $extension = undef; + } + my $file_found_index = undef; + my $file_index = 0; + foreach my $file_location (@$file_locations) + { + my ($file_located, $path, $file_simple_format) = @$file_location; + my $extension = shift @extensions; + if (defined($path)) + { + if ($extension eq 'txt' and !defined($txt_path)) + { + $txt_path = $path; + } + elsif (!defined($found_file)) + { + $found_file = [$file_located, $extension, $file_simple_format]; + $file_found_index = $file_index; + } + } + $file_index++; + } + + my $text; + if (defined($txt_path)) + { + if (open(TXT, "<$txt_path")) + { + if (defined($Texi2HTML::THISDOC{'IN_ENCODING'}) and $USE_UNICODE) + { + binmode(TXT, ":encoding($Texi2HTML::THISDOC{'IN_ENCODING'})"); + } + $text='[' if ($in_paragraph or $preformatted); + while (my $img_txt = ) + { + $text .= $img_txt; + } + # remove last end of line + chomp ($text); + $text .= ']' if ($in_paragraph or $preformatted); + close(TXT); + } + else + { + main::line_warn (sprintf(__("\@image file `%s' unreadable: %s"), $txt_path, $!), $line_nr); + } + } + elsif (!defined($found_file)) + { + main::line_warn (sprintf(__("Cannot find \@image file `%s.txt'"), $base), $line_nr); + } + if (defined($found_file) and (!defined($extension) or $file_found_index <= 1)) + { + my $filename = $found_file->[2]; + $filename =~ s/\\/\\\\/g; + $filename =~ s/\"/\\\"/g; + my $result = "\x{00}\x{08}[image src=\"$filename\""; + if (defined($alt)) + { + $alt =~ s/\\/\\\\/g; + $alt =~ s/\"/\\\"/g; + $result .= " alt=\"$alt\""; + } + if (defined($text)) + { + $text =~ s/\\/\\\\/g; + $text =~ s/\"/\\\"/g; + $result .= " text=\"$text\""; + } + $result .= "\x{00}\x{08}]"; + return $result; + } + return $text if (defined($text)); + return ''; +} + +sub info_default_printindex($$) +{ + my $index_name = shift; + my $printindex = shift; + %info_default_index_entries_counts = (); + return info_default_store_text(undef,t2h_GPL_default_printindex($index_name,$printindex),'printindex'); +} + +sub info_default_print_index($$) +{ + my $text = shift; + my $name = shift; + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + my $before = ''; + if (!$info_state->{'blank_line'}) + { + $before = "\n"; + } + return $before if (!defined($text)); + my $result = "\x{00}\x{08}[index\x{00}\x{08}]\n* Menu:\n\n" .$text."\n"; + return $before.$result; +} + +sub info_default_index_letter($$$) +{ + my $letter = shift; + my $id = shift; + my $text = shift; + return $text; +} + +sub info_default_index_entry_label($$$$$$$$$) +{ + my $identifier = shift; + my $preformatted = shift; + my $entry = shift; + my $index_name = shift; + my $index_command = shift; + my $texi_entry = shift; + my $formatted_entry = shift; + my $in_region_not_in_output = shift; + my $index_entry_ref = shift; + + #return '' if ($index_entry_ref->{'hidden'}); + #return '' if (!$index_entry_ref->{'seen_in_output'} and defined($index_entry_ref->{'region'})); + return '' if ($in_region_not_in_output or !defined($index_entry_ref->{'index_name'})); + main::line_warn(sprintf(__("Entry for index `%s' outside of any node"), $index_entry_ref->{'index_name'}), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node) and !$Texi2HTML::THISDOC{'state'}->{'outside_document'}); + my $index_entry_stored = {'index_entry_reference' => $index_entry_ref, 'index_command' => $index_command, 'texi_entry' => $texi_entry}; + return info_default_store_text(undef, undef, 'index_label', $index_entry_stored); +} + +sub info_default_index_entry($$$$$$$$$$) +{ + my $text_href = shift; + my $entry = shift; + my $element_href = shift; + my $element_text = shift; + my $entry_file = shift; + my $current_element_file = shift; + my $entry_target = shift; + my $entry_element_target = shift; + my $in_region_not_in_output = shift; + my $index_entry_ref = shift; + + #return '' if ($index_entry_ref->{'hidden'}); + #return '' if (!$index_entry_ref->{'seen_in_output'} and defined($index_entry_ref->{'region'})); + return '' if ($in_region_not_in_output); + $entry = main::substitute_line($index_entry_ref->{'texi'}, "index entry in \@printindex"); + return '' if ($entry =~ /^\s*$/); + + my $entry_nr = ''; + if (!defined($info_default_index_entries_counts{$entry})) + { + $info_default_index_entries_counts{$entry} = 0; + } + else + { + $info_default_index_entries_counts{$entry} ++; + $entry_nr = ' <'.$info_default_index_entries_counts{$entry}.'>'; + } + + my $result = "* $entry${entry_nr}: "; + if (t2h_default_string_width($result) < $info_default_index_length_to_node) + { + $result .= ' ' x($info_default_index_length_to_node - t2h_default_string_width($result)); + } + + #print STDERR "DDDDDDDDDDD $index_entry_ref `$index_entry_ref->{'texi'}'\n"; + my $info_index_entry_ref = $info_default_index_entries{$index_entry_ref}; + my $line_nr = $info_index_entry_ref->{'line_nr'}; + + my $real_element_text; + my $element = $index_entry_ref->{'real_element'}; + # in case $element->{'text'} is not defined, it certainly means that we + # are n a special elemet, most likely the virtual element appearing + # before anything else + if (!defined($element->{'text'})) + { + $real_element_text = gdt('(outside of any node)'); + $line_nr = 0; + } + else + { + $element = $element->{'element_ref'} if ($element->{'element_ref'}); + $real_element_text = $element->{'text'}; + # this happens for index entries appearing after @printindex. In that case + # it is considered that they are at the beginning of the node. + $line_nr = 3 if (defined($line_nr) and $line_nr < 3); + $line_nr = 4 if (!defined($line_nr)); + } + $result .= $real_element_text . '.'; + my $max_len = $info_default_index_line_string_length{$index_entry_ref->{'index_name'}}; + $max_len = t2h_default_string_width($line_nr) if (!defined($max_len)); + my $line_nr_spaces = sprintf("%${max_len}d", $line_nr); + my $line_part = "(line ${line_nr_spaces})"; + #print STDERR "GGGGGGGGGG name: $index_entry_ref->{'index_name'} max: ${max_len} line_nr: `$line_nr' line_nr_spaces `$line_nr_spaces' $line_part \n"; + if (t2h_default_string_width($result)+t2h_default_string_width($line_part) +1 > get_conf('fillcolumn')) + { + $result .= "\n" . ' ' x (get_conf('fillcolumn') - t2h_default_string_width($line_part)) ; + } + else + { + $result .= ' ' x (get_conf('fillcolumn') - t2h_default_string_width($line_part) - t2h_default_string_width($result)); + } + $result .= "$line_part\n"; + + return $result; +} + +sub info_default_index_summary($$) +{ + my $alpha = shift; + my $nonalpha = shift; + + return ''; +} + +sub info_default_summary_letter +{ + return ''; +} + +sub info_default_foot_line_and_ref($$$$$$$$) +{ + my $foot_num = shift; + my $relative_num = shift; + my $footid = shift; + my $docid = shift; + my $from_file = shift; + my $footnote_file = shift; + my $lines = shift; + my $state = shift; + + my $footnote_state = $Texi2HTML::THISDOC{'state'}; + my $footnote_info_state = info_default_get_state ($footnote_state); + + my $footnote_text = "($info_default_footnote_index)"; + $footnote_text = "($NO_NUMBER_FOOTNOTE_SYMBOL)" if (!$NUMBER_FOOTNOTES); + my $node_name; + $node_name = ''; + if (defined($info_default_current_node)) + { + $node_name = $info_default_current_node->{'text'}; + } + else + { # i18n + # no warning when outside of document, for footnotes in + # titlepage and copying + main::line_error(__("Footnote defined without parent node"), $Texi2HTML::THISDOC{'line_nr'}) unless ($footnote_state->{'outside_document'}); + #print STDERR "".main::context_string()."\n"; + } + if (get_conf('footnotestyle') eq 'separate') + { + $footnote_text .= ' (' . info_default_normal_reference('pxref', ["${node_name}-Footnote-${info_default_footnote_index}"]) . ')'; + } + push @info_default_pending_footnotes, {'lines' => $lines, + 'footnote_text' => $footnote_text, + 'footnote_index' => ${info_default_footnote_index}, + 'node_name' => $node_name, + 'footnote_info_state' => $footnote_info_state} + unless ($state->{'outside_document'} or (defined($state->{'multiple_pass'}) and $state->{'multiple_pass'} > 0)); + return ([], $footnote_text); +} + +sub info_default_foot_lines($) +{ + my $lines = shift; + #my $state = $Texi2HTML::THISDOC{'state'}; + #my $info_state = info_default_get_state ($state); + @$lines = (); +} + +# remark: table_item is the html one, but it gets added to the table text +# on the stack, and is ignored there (in info_default_format). +sub info_default_format_list_item_texi($$$$) +{ + my $format = shift; + my $line = shift; + my $prepended = shift; + my $command = shift; + my $number = shift; + + my $open_command = 0; + my $result_line; + $command = 'bullet' if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize'); + $prepended = "\@$command\{\}" if (defined($command) and $command ne ''); + $prepended = "$number." if (defined($number) and $number ne ''); + + $line =~ s/^\s*//; + + if (defined($command) and $command ne '' and $format ne 'itemize') + { + #@*table + $line =~ s/\s*$//; + if (exists ($style_map{$command})) + { + $result_line = "\@$command\{$line\}\n"; + } + elsif (exists ($things_map{$command})) + { + $result_line = "\@$command\{\} $line\n"; + } + else + { + $result_line = "\@$command $line\n"; + } + } +# elsif (defined($prepended) and $prepended ne '') +# { # @enumerate and @itemize +# $prepended =~ s/^\s*//; +# $prepended =~ s/\s*$//; +# $result_line = $prepended . ' ' . $line; +# } + + return ($result_line, $open_command); +} + +sub info_default_list_item($$$$$$$$$$$$) +{ + my $text = shift; + my $format = shift; + my $command = shift; + my $formatted_command = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $prepended = shift; + my $prepended_formatted = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + my $item_command = shift; + +# my $prepend = ''; +# if (defined($formatted_command) and $formatted_command ne '') +# { +# $prepend = $formatted_command; +# } +# return $prepend . $text; +# $command = 'bullet' if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize'); + $formatted_command = $things_map{'bullet'} if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize'); + + if ($format !~ /table$/) + { + my $result = ''; + if ($format eq 'enumerate') + { + $result = $number.'.'; + } + elsif ($format eq 'itemize') + { + if (defined($formatted_command) and $formatted_command ne '') + { + $result = $formatted_command; + } + elsif (defined ($prepended_formatted) and $prepended_formatted ne '') + { + $prepended_formatted =~ s/^\s*//; + $prepended_formatted =~ s/\s*$//; + $result = $prepended_formatted; + } + } + else + { + $result = ''; + } + $result .= ' ' if ($result ne ''); + return info_default_close_command (undef, $item_command, $result); + } + return $text; +} + +sub info_default_format($$$) +{ + my $tag = shift; + my $element = shift; + my $text = shift; + + # currently no command has something else than '' as $element. + # notice that any text is discarded + $element = undef if ($element eq ''); + my $element_end = $element; + if (defined($element) and $element =~ /^(\w+)(\s+)(.+)/) + { + $element = $1; + $element_end = $2; + } + return info_default_close_command(undef, $tag, $element, $element_end); +} + +sub info_default_tab_item_texi($$$$$$) +{ + my $command = shift; + my $commands_stack = shift; + my $stack = shift; + my $state = shift; + my $line = shift; + my $line_nr = shift; + + $line =~ s/^\s*//; + my $format; + my $info_state = info_default_get_state ($state); + #$format = $commands_stack->[-1] if (defined($commands_stack) and @$commands_stack and $commands_stack->[-1]); + my ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'}); + print STDERR "Not in_format in info_default_tab_item_texi\n" if (!$in_format); + $format = $parent_format->{'command'}; + # in case of an @item or @tab outside of any format $format will be + # undefined, or not multitable for a @tab. + # however the main program still do as if something was opened, plus + # it is checked there that the nesting is correct + #return $line if (!defined($format) or $command eq 'tab' and $format ne 'multitable'); + #print STDERR "tab_item_texi $format $command $commands_stack, $stack, $state, $line, ".main::format_line_number($line_nr)."\n"; + if ($format eq 'multitable') + { # even if it is a tab, if it is not already in a multitable_row, one + # should be started + if ($command ne 'tab' or $info_state->{'current'}->{'command'} ne 'multitable_row') + { + info_default_open_command($state, 'multitable_row'); + } + info_default_open_command($state, 'multitable_cell'); + } + elsif ($format =~ /table$/) + { + info_default_store_text ($state, undef, $command, {'format_name' => $format}); + } + else + { + info_default_open_command ($state, $command, {'format_name' => $format}); + } + # this should have already been done for @item when the line + # is modified by the @-command and so on. + return $line; +} + +sub info_default_sp($$) +{ + my $number = shift; + my $preformatted = shift; + my $result = "\n" x $number; + return info_default_store_text(undef,$result,'sp'); +} + +sub info_default_paragraph_style_command($$) +{ + my $format = shift; + my $text = shift; + return info_default_close_command(undef, $format); +} + +sub info_default_row($$$$$$$$) +{ + my $text = shift; + my $macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + #print STDERR "info_default_row: $text\n"; + + return info_default_close_command(undef, 'multitable_row', undef, undef, {'item_command' => $macro}); +} + +sub info_default_cell($$$$$$$$) +{ + my $text = shift; + my $row_macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + # in general, when before_items, there will be no call to the function + # since there should never be a text sent back, so that this + # function will not be called for the first row (the multitable title). + # However, if there is a @tab before the first @item, the main program + # is less careful and closes the cell in any case, so before_items + # has to be checked for that case. + return info_default_close_command(undef, 'multitable_cell') unless ($before_items); +} + +sub info_default_table_list($$$$$$$$$) +{ + my $format_command = shift; + my $text = shift; + my $command = shift; + my $formatted_command = shift; +# enumerate + my $item_nr = shift; + my $enumerate_style = shift; +# itemize + my $prepended = shift; + my $prepended_formatted = shift; +# multitable + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + + die "BUG: $format_command item_nr undef\n" if (!defined($item_nr)); + + return info_default_close_command(undef, $format_command, undef, undef, {'total_item_nr' => $item_nr}) if ($format_command ne 'multitable'); + + my $columnsize = []; + if (defined($prototype_lengths) and @$prototype_lengths) + { + $columnsize = [ @$prototype_lengths ]; + } + elsif (defined($columnfractions) and @$columnfractions) + { + foreach my $fraction (@$columnfractions) + { + push @$columnsize, int($fraction * get_conf('fillcolumn') +0.5); + } + } + else + { # empty multitable + #print STDERR "Empty multitable?\n"; + } + + return info_default_close_command(undef, $format_command, undef, undef, {'columns_size' => $columnsize, 'total_item_nr' => $item_nr}); +} + +sub info_default_def_item($$$) +{ + my $text = shift; + my $only_inter_item_commands = shift; + my $command = shift; + + my $format = 'deff_item'; + $format = 'deff_itemx' if ($command =~ /x$/); + return info_default_close_command(undef, $format); +} + +sub info_default_def_line($$$$$$$$$$$$$$$$) +{ + my $category_prepared = shift; + my $name = shift; + my $type = shift; + my $arguments = shift; + my $index_label = shift; + my $arguments_array = shift; + my $arguments_type_array = shift; + my $unformatted_arguments_array = shift; + my $command = shift; + my $class_name = shift; + my $category = shift; + my $class = shift; + my $style = shift; + my $original_command = shift; + + $name = '' if (!defined($name) or ($name =~ /^\s*$/)); + $type = '' if (!defined($type) or $type =~ /^\s*$/); + $arguments = '' if (!defined($arguments) or $arguments =~ /^\s*$/); + + my $type_name = ''; + $type_name .= "$type " if ($type ne ''); + $type_name .= $name if ($name ne ''); + + my $result = " -- $category_prepared: ${type_name}$arguments"; + $result =~ s/\s*$//; + $result .= "\n"; + my $state = $Texi2HTML::THISDOC{'state'}; + info_default_store_text(undef,$result,"${command}_line",{'definition_line' => 1}); + my $format = 'deff_item'; + $format = 'deff_itemx' if ($original_command =~ /x$/); + return info_default_open_command($state, $format); +} + +sub info_default_def($$) +{ + my $text = shift; + my $command = shift; + return info_default_close_command(undef, $command); +} + +sub info_default_float($$$$$) +{ + my $text = shift; + my $float = shift; + my $caption = shift; + my $shortcaption = shift; + + my $additional_arguments; + if (exists($float->{'id'})) + { + $additional_arguments->{'anchor_reference'} = $float; + main::line_warn(__("float reference outside of any node, it won't be registered"), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node) and !$Texi2HTML::THISDOC{'state'}->{'outside_document'}); + } + my $caption_text = ''; + + if (defined($float->{'caption_texi'})) + { + $caption_text = $caption; + } + elsif (defined($float->{'shortcaption_texi'})) + { + $caption_text = $shortcaption; + } + elsif (defined($caption)) + { + $caption_text = $caption; + } + + #return $caption_text; + return info_default_close_command(undef, 'float', undef, $caption_text, $additional_arguments); +} + +sub info_default_listoffloats_entry($$$$) +{ + my $style_texi = shift; + my $float = shift; + my $float_style = shift; + my $caption = shift; + my $href = shift; + + my @lines = split /^/, $caption; + $caption = $lines[0]; + $caption = '' if (!defined($caption)); + chomp ($caption); + + my $result = ''; + #$caption .= ':' if ($caption ne ''); + my $caption_entry = "* $float_style: $float->{'text'}."; + if (t2h_default_string_width($caption_entry) > $info_default_listoffloat_caption_entry_length) + { + $caption_entry .= "\n" . ' ' x $info_default_listoffloat_caption_entry_length; + } + else + { + $caption_entry .= ' ' x ($info_default_listoffloat_caption_entry_length - length($caption_entry)); + } + my $width = $info_default_listoffloat_caption_entry_length; + while ($caption =~ s/^(\S+\s*)//) + { + my $new_word = $1; + if ((t2h_default_string_width($new_word) + $width) > get_conf('fillcolumn') - 3) + { + $caption_entry .= $info_default_listoffloat_append; + last; + } + else + { + $caption_entry .= $new_word; + $width += t2h_default_string_width($new_word); + } + } + return $caption_entry. "\n"; +} + +sub info_default_listoffloats($$$) +{ + my $style_texi = shift; + my $style = shift; + my $float_entries = shift; + + my $state = $Texi2HTML::THISDOC{'state'}; + my $info_state = info_default_get_state ($state); + my $result = "* Menu:\n\n"; + foreach my $float_entry (@$float_entries) + { + $result .= $float_entry; + } + my ($parent_format, $in_format); + ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'}); + #print STDERR "\@listoffloats not at top level\n" if ($in_format); + info_default_increment_paragraph ($in_format, $parent_format, $info_state, 'listoffloats'); + return info_default_store_text($state,$result,'listoffloats'); +} + +sub info_default_raw($$) +{ + my $style = shift; + my $text = shift; + my $expanded = 1 if (grep {$style eq $_} @EXPAND); + # no warning for unknown raw formats + if ($style eq 'verbatim' or $style eq 'verbatiminclude' or $expanded) + { + return info_default_store_text(undef, $text, $style, {'raw_command' => 1}); + } + return ''; +} + +sub info_default_line_command($$$$) +{ + my $command = shift; + my $arg_text = shift; + my $arg_texi = shift; + my $state = shift; + + main::line_warn(__("\@dircategory after first node"), $Texi2HTML::THISDOC{'line_nr'}) if (defined($info_default_current_node)); + return '' if ($arg_text eq ''); + $info_default_dir_specification .= "INFO-DIR-SECTION $arg_text\n"; + return ''; +} + +sub info_default_unknown_style($$$$$) +{ + my $command = shift; + my $text = shift; + my $state = shift; + my $no_close = shift; + my $no_open = shift; + + my ($result, $result_text, $message); + $result_text = info_default_close_command(undef, $command, undef, undef, undef); + $message = "Unknown command with braces `\@$command'" if (!$no_open); + return (1, $result_text, $message); +} + +1; + +require "$T2H_HOME/formats/info.init" + if ($0 =~ /\.pl$/ && + -e "$T2H_HOME/formats/info.init" && -r "$T2H_HOME/formats/info.init"); + +# @INIT_DOCBOOK@ +#+############################################################################## +# +# docbook.init: convert to docbook +# +# Copyright (C) 2008, 2009 Patrice Dumas +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA +# +#-############################################################################## + + +# regarding sections and nodes, in docbook we don't care at all about the +# splitting done in the main program. When there is a node, it is recorded as +# being pending. When there is a section it is opened, and closed when +# there is the next section or end of file. + +use strict; + +my %docbook_complex_format; +my $kept_footnote_function; +my $docbook_in_footnote; +my %docbook_sections; +my %def_format_docbook; +my %def_argument_types_docbook; + +my $docbook_pending_node_id; +my $docbook_current_section; +my @docbook_multitable_stack = (); +my @docbook_table_stack = (); +my @docbook_special_quotation; + + +sub docbook_default_load(;$) +{ +my $from_command_line = shift; + +t2h_default_set_variables_xml(); +$DOCTYPE = ' + +]>'; +@T2H_FORMAT_EXPAND = ('docbook'); +@IMAGE_EXTENSIONS = ('eps', 'gif', 'jpg', 'jpeg', 'pdf', 'png', 'svg', 'txt'); +$INLINE_INSERTCOPYING = 1; +# this should lead to end_section being only called at the end of sectioning +$USE_NODES = 0; +$USE_SECTIONS = 1; + +$SHOW_MENU = 0; +$SHOW_TITLE = 0; +$HEADERS = 0; +# certainly irrelevant +$SIMPLE_MENU = 0; + +t2h_default_push_handler(\&docbook_initialize_variables, \@command_handler_init); + +%style_map = (); +t2h_default_copy_style_map (\%default_style_map, \%style_map); +foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) +{ + $style_map{$accent_command} = { 'function' => \&xml_default_accent }; +} + +delete $style_map{'sc'}->{'inline_attribute'}; +# FIXME there is a code element in v4.3 +$style_map{'code'}->{'inline_attribute'} = 'literal'; +$style_map{'strong'}->{'inline_attribute'} = 'emphasis role="bold"'; +$style_map{'kbd'}->{'inline_attribute'} = 'userinput'; +$style_map{'w'}->{'end'} = ''; +$style_map{'='}->{'function'} = \&docbook_macron; +$style_map{'b'}->{'inline_attribute'} = 'emphasis role="bold"'; +$style_map{'cite'}->{'inline_attribute'} = 'citetitle'; +$style_map{'command'}->{'inline_attribute'} = 'command'; +$style_map{'dfn'}->{'inline_attribute'} = 'firstterm'; +$style_map{'emph'}->{'inline_attribute'} = 'emphasis'; +$style_map{'env'}->{'inline_attribute'} = 'envar'; +$style_map{'file'}->{'inline_attribute'} = 'filename'; +$style_map{'i'}->{'inline_attribute'} = 'wordasword'; +$style_map{'key'}->{'inline_attribute'} = 'keycap'; +delete $style_map{'key'}->{'begin'}; +delete $style_map{'key'}->{'end'}; +$style_map{'option'}->{'inline_attribute'} = 'option'; +$style_map{'t'}->{'inline_attribute'} = 'literal'; +delete $style_map{'sansserif'}->{'inline_attribute'}; +delete $style_map{'r'}->{'inline_attribute'}; +$style_map{'indicateurl'}->{'inline_attribute'} = 'wordasword'; +delete $style_map{'indicateurl'}->{'begin'}; +delete $style_map{'indicateurl'}->{'end'}; +$style_map{'var'}->{'inline_attribute'} = 'replaceable'; +delete $style_map{'verb'}->{'inline_attribute'}; +$style_map{'email'}->{'function'} = \&docbook_email; +$style_map{'math'}->{'function'} = \&docbook_math; +$style_map{'uref'}->{'function'} = \&docbook_uref; +$style_map{'url'}->{'function'} = \&docbook_uref; +$style_map{'titlefont'}->{'function'} = \&docbook_titlefont; +#$style_map{'samp'}->{'function'} = \&docbook_samp; +#delete $style_map{'samp'}->{'inline_attribute'}; +$style_map{'samp'}->{'inline_attribute'} = 'literal'; +$style_map{'samp'}->{'begin'} = '‘'; +$style_map{'samp'}->{'end'} = '’'; + +$kept_footnote_function = $style_map{'footnote'}->{'function'}; +$style_map{'footnote'}->{'function'} = \&docbook_footnote; + +foreach my $style (keys(%style_map)) +{ + delete ($style_map{$style}->{'quote'}); +} + +#use Data::Dumper; +%style_map_pre = (); +t2h_default_copy_style_map (\%style_map, \%style_map_pre); + +$style_map_pre{'r'}->{'inline_attribute'} = 'lineannotation'; + +$colon_command_punctuation_characters{'.'} = '.'; +$colon_command_punctuation_characters{':'} = ':'; +$colon_command_punctuation_characters{'?'} = '?'; +$colon_command_punctuation_characters{'!'} = '!'; + +$stop_paragraph_command{'titlefont'} = 0; + +# FIXME +#$no_paragraph_commands{'anchor'} = 0; + +# FIXME +delete $special_accents{'ringaccent'}; +$special_accents{'ogonek'} = 'aeiuAEIU'; + +%simple_map = %default_simple_map; +%simple_map_pre = %simple_map; + +# FIXME right? ł Ł +$things_map{'l'} = '/l'; +$things_map{'L'} = '/L'; +$things_map{'TeX'} = '&tex;'; +$things_map{'LaTeX'} = '&latex;'; +$things_map{'enddots'} = '….'; +$things_map{'minus'} = '−'; +# FIXME ∗ +$things_map{'point'} = '-!-'; +# FIXME ≡ +$things_map{'equiv'} = '=='; +# FIXME no ‹ nor › +$things_map{'guilsinglright'} = '>'; +$things_map{'guilsinglleft'} = '<'; +# The following is unneeded because normal_text is redefined. +# FIXME it should certainly be better to leave those substitutions, +# or even hardcodes them in normal_text. +# t2h_remove_text_substitutions("'", 1, 0, 0, 1); +# t2h_remove_text_substitutions('`', 1, 0, 0, 1); + +$things_map{'quotedblbase'} = '„'; +$things_map{'quotesinglbase'} = '‚'; + +%pre_map = %things_map; + +#delete $inter_item_commands{'cindex'}; + +#$no_paragraph_commands{'cindex'} = 0; +$no_paragraph_commands{'float'} = 0; + +%docbook_complex_format = ( + 'example' => 'screen', + 'smallexample' => 'screen', + 'display' => 'literallayout', + 'smalldisplay' => 'literallayout', + 'lisp' => 'programlisting', + 'smalllisp' => 'programlisting', + 'format' => 'abstract', + 'smallformat' => 'screen' +); + +%docbook_sections = ( + 'top' => 'chapter', + 'part' => 'part', + 'chapter' => 'chapter', + 'unnumbered' => 'chapter', + 'centerchap' => 'chapter', + 'appendix' => 'appendix', + 'majorheading' => 'other', + 'chapheading' => 'other', + 'heading' => 'sect1', + 'subheading' => 'sect2', + 'subsubheading' => 'sect3', + 2 => 'sect1', + 3 => 'sect2', + 4 => 'sect3' +); + +%def_format_docbook = ( + 'deffn' => [ ['function', 'name'] ], + 'defvr' => [ ['varname', 'name'] ], + 'deftypefn' => [ [ 'returnvalue', 'type' ], ['function', 'name'] ], + 'deftypeop' => [ ['returnvalue', 'type'], ['methodname', 'name'] ], + 'deftypevr' => [ ['returnvalue', 'type'], ['varname', 'name'] ], + 'defcv' => [ ['classname', 'class'], ['property', 'name'] ], + 'deftypecv' => [ ['returnvalue', 'type'], ['property', 'name'] ], + 'defop' => [ ['classname', 'class'], ['methodname', 'name'] ], + 'deftp' => [ ['structname', 'name'] ] +); + +%def_argument_types_docbook = ( + 'param' => 'replaceable', + 'paramtype' => 'type', + 'delimiter' => '' +); + +@docbook_special_quotation = ('note', 'caution', 'important', 'tip', 'warning'); + +$region_formats_kept{'copying'} = 1; + +%format_map = ( + 'group' => '', + 'raggedright' => '', + 'copying' => 'copying', + ); + +$print_Top = \&docbook_print_Top; +$print_Top_footer = \&docbook_print_Top_footer; +$print_page_head = \&docbook_print_page_head; +$print_foot_navigation = \&docbook_noop; +$contents = \&docbook_noop; +$shortcontents = \&docbook_noop; +$about_body = \&docbook_noop; +$print_page_foot = \&docbook_print_page_foot; +$end_section = \&docbook_end_section; +$one_section = \&docbook_one_section; + +$acronym_like = \&docbook_acronym_like; +$anchor_label = \&docbook_anchor_label; +$begin_format_texi = \&docbook_begin_format_texi; +$cartouche = \&docbook_cartouche; +$cell = \&docbook_cell; +$complex_format = \&docbook_complex_format; +$def = \&docbook_def; +$def_line = \&docbook_def_line; +$def_item = \&docbook_def_item; +$element_label = \&docbook_element_label; +$external_ref = \&docbook_external_ref; +$float = \&docbook_float; +$foot_line_and_ref = \&docbook_foot_line_and_ref; +$format = \&docbook_format; +$format_list_item_texi = \&docbook_format_list_item_texi; +$heading = \&docbook_heading; +$image = \&docbook_image; +$image_files = \&docbook_image_files; +$index_entry_command = \&docbook_index_entry_command; +$index_entry_label = \&docbook_index_entry_label; +$index_summary = \&docbook_index_summary; +$internal_ref = \&docbook_internal_ref; +$insertcopying = \&docbook_insertcopying; +$list_item = \&docbook_list_item; +$misc_element_label = \&docbook_noop; +$normal_text = \&docbook_normal_text; +$paragraph = \&docbook_paragraph; +$preformatted = \&docbook_preformatted; +$printindex = \&docbook_printindex; +$protect_text = \&xml_default_protect_text; +$quotation = \&docbook_quotation; +$quotation_prepend_text = \&docbook_quotation_prepend_text; +$listoffloats = \&docbook_noop; +$raw = \&docbook_raw; +$row = \&docbook_row; +$sp = \&docbook_sp; +$style = \&docbook_style; +$table_item = \&docbook_table_item; +$table_line = \&docbook_table_line; +$table_list = \&docbook_table_list; +$misc_command_line = \&docbook_misc_commands; + + +} + +sub docbook_footnote +{ + $docbook_in_footnote = 1; + my $result = &$kept_footnote_function(@_); + $docbook_in_footnote = 0; + return $result; +} + +sub docbook_macron($$) +{ + my $accent = shift; + my $args = shift; + return $args->[0] . "¯"; +} + +sub docbook_samp($$) +{ + shift; + my $args = shift; + return "‘$args->[0]’"; +} + +sub docbook_email($$) +{ + my $command = shift; + my $args = shift; + my $mail = shift @$args; + my $text = shift @$args; + $mail = main::normalise_space($mail); + if (defined($text) and $text =~ /\S/) + { + # FIXME normalise_space would be more legible. + #return docbook_add_id('ulink').' url="mailto:'.$mail.'">'.main::normalise_space($text).''; + return docbook_add_id('ulink').' url="mailto:'.$mail.'">'.$text.''; + } + return docbook_add_id('email').">$mail"; +} + +sub docbook_uref($$) +{ + shift; + my $args = shift; + my $url = shift @$args; + my $text = shift @$args; + my $replacement = shift @$args; + $url = main::normalise_space($url); + $text = '' if (!defined($text)); + $replacement = '' if (!defined($replacement)); + $replacement = $text if ($replacement eq ''); + $replacement = $url if ($replacement eq ''); + $replacement = main::normalise_space($replacement); + + return docbook_add_id('ulink')." url=\"$url\">$replacement"; +} + +# FIXME +sub docbook_titlefont($$) +{ + shift; + my $args = shift; + return "$args->[0]"; +} + +# FIXME there ought to be something better... Like use tex4ht mathml +# output or something like that +sub docbook_math($$) +{ + shift; + my $args = shift; + my $text = shift @$args; + return $text; +} + + +sub docbook_print_page_head($) +{ + my $fh = shift; + my $language = get_conf('documentlanguage'); + my $doctype = get_conf('doctype'); + print $fh < +$doctype + +EOT +} + +sub docbook_print_page_foot($) +{ + my $fh = shift; + print $fh "". docbook_close_section(); + print $fh < +EOT +} + +sub docbook_print_Top($$$) +{ + my $fh = shift; + my $has_top_heading = shift; + my $element = shift; + main::print_lines($fh, $Texi2HTML::THIS_SECTION); +} + +sub docbook_element_tag($) +{ + my $element = shift; +#print STDERR "$element->{'texi'}, $element->{'tag_level'}, $element->{'level'}\n"; + return $docbook_sections{$element->{'tag_level'}} if (exists($docbook_sections{$element->{'tag_level'}})); + return $docbook_sections{$element->{'level'}} if (exists($docbook_sections{$element->{'level'}})); +} + +sub docbook_node_id($) +{ + my $node_texi = shift; + my $node = main::substitute_line($node_texi, 'docbook node id', {'code_style' => 1, 'remove_texi' => 1}); + $node =~ s/[\s\"]/-/g; + return &$protect_text($node); +} + +sub docbook_initialize_variables() +{ + $docbook_pending_node_id = undef; + $docbook_current_section = undef; + @docbook_multitable_stack = (); + @docbook_table_stack = (); + $Texi2HTML::THISDOC{'SPLIT'} = 0 if ($OUTPUT_FORMAT eq 'docbook'); +} + +sub docbook_add_id($) +{ + my $element = shift; + my $result = "<$element"; + if (defined($docbook_pending_node_id) and (!$docbook_in_footnote or $element eq 'footnote')) + { + $result .= " id=\"$docbook_pending_node_id\""; + $docbook_pending_node_id = undef; + } + return $result; +} + +sub docbook_heading($$$$$) +{ + my $element = shift; + my $command = shift; + my $texi_line = shift; + my $line = shift; + my $in_preformatted = shift; + + if (defined($command) and $command =~ /heading/) + { + my $text = ''; + if (defined($line)) + { + $text = $line; + # this isn't done in main program in that case... + chomp ($text); + $text =~ s/^\s*//; + } + return docbook_add_id('bridgehead')." renderas=\"$docbook_sections{$command}\">$text\n"; + } + + my $result = ''; + +# FIXME verify xreflabel + if ($command ne 'node') + { + # close previous section + $result .= docbook_close_section(); + my $title = $element->{'text_nonumber'}; + my $label = ''; + my $xreflabel = ''; + if ($element->{'number'}) + { + my $label_nr = $element->{'number'}; + #$label_nr =~ s/\.$//; + $label = $label_nr; + } + else + { + my $xreftitle = $title; + $xreflabel = " xreflabel=\"$xreftitle\""; + } + $result .= docbook_add_id(docbook_element_tag($element) . " label=\"${label}\"${xreflabel}"); + $result .= ">\n$title\n"; + $docbook_current_section = $element; + } + return $result; +} + +sub docbook_element_label($$$$) +{ + my $id = shift; + my $element = shift; + my $command = shift; + my $line = shift; + + if ($command eq 'node') + { + $docbook_pending_node_id = docbook_node_id($element->{'texi'}); + } + return ''; +} + +sub docbook_paragraph($$$$$$$$$$$$) +{ + my $text = shift; + my $align = shift; + my $indent = shift; + my $paragraph_command = shift; + my $paragraph_command_formatted = shift; + my $paragraph_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + + if (defined($paragraph_number) and defined($$paragraph_number)) + { + $$paragraph_number++; + } + + # no para in multitables, caption and shortcaptions. + my $top_stack = ''; + $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); + return $text if ($top_stack eq 'multitable' or $top_stack eq 'shortcaption' or $top_stack eq 'caption' or $top_stack eq 'documentdescription'); + + if ($text =~ /\S/) + { + #return docbook_add_id('para').">$text"; + return "$text"; + } + return $text; +} + + +sub docbook_def_line($$$$$$$$$$$$$$$) +{ + my $category_prepared = shift; + my $name = shift; + my $type = shift; + my $arguments = shift; + my $index_label = shift; + my $arguments_array = shift; + my $arguments_type_array = shift; + my $unformatted_arguments_array = shift; + my $command = shift; + my $class_name = shift; + my $category = shift; + my $class = shift; + my $style = shift; + my $original_command = shift; + + my %unformatted_arguments = (); + + my @unformatted_args = @$unformatted_arguments_array; + foreach my $type (@$arguments_type_array) + { + my $unformatted_arg = shift @unformatted_args; + $unformatted_arguments{$type} = $unformatted_arg; + } + # FIXME unformatted! + my $result = "$class_name"; + + my %arguments = ( 'prepared_category' => $category_prepared, + 'category' => $category, + 'name' => $name, + 'type' => $type, + 'class' => $class + ); + foreach my $type (keys(%arguments)) + { + $arguments{$type} = '' if (!defined($arguments{$type})); + } + + foreach my $mandatory_arg (@{$def_format_docbook{$command}}) + { + my $elem = $mandatory_arg->[0]; + #if ($elem eq 'returnvalue' and $unformatted_arguments{$mandatory_arg->[1]} =~ /^\s*\@code\{/) + if ($elem eq 'returnvalue' and $unformatted_arguments{$mandatory_arg->[1]} =~ /\@code\{/) + { + # FIXME unformatted + my $arg_without_at_command = $unformatted_arguments{$mandatory_arg->[1]}; + #$arg_without_at_command =~ s/\s*\@code\{//; + #$arg_without_at_command =~ s/\}\s*$//; + while ($arg_without_at_command =~ /\@code\{([^\{\}]*)\}/) + { + $arg_without_at_command =~ s/\@code\{([^\{\}]*)\}/$1/; + } + $result .= "<$elem>$arg_without_at_command"; + } + else + { + $result .= "<$elem>$arguments{$mandatory_arg->[1]}"; + } + } + + my @types = @$arguments_type_array; + @unformatted_args = @$unformatted_arguments_array; + foreach my $arg (@$arguments_array) + { + my $type = shift @types; + my $unformatted = shift @unformatted_args; + if (exists ($def_argument_types_docbook{$type})) + { + if ($def_argument_types_docbook{$type} and + ($type eq 'paramtype' or ($unformatted !~ /^\s*\@var\{/))) + { + $result .= "<$def_argument_types_docbook{$type}>$arg"; + } + else + { + $result .= $arg; + } + } + } + + $result .= "\n"; + return $result; +} + +# FIXME +# @deffn +# @c comment +# @end deffn +# leads to the creation of a with a comment within, +# while there should be no definitionitem +sub docbook_def_item($) +{ + my $text = shift; + my $only_inter_item_commands = shift; + + if ($text =~ /\S/) + { + return '
    ' . $text . '
    ' unless $only_inter_item_commands; + return $text; + } + return ''; +} + +sub docbook_def($) +{ + my $text = shift; + return docbook_add_id('informalfigure').'>'.$text.''; +} + +sub docbook_preformatted($$$$$$$$$$$$) +{ + my $text = shift; + my $pre_style = shift; + my $class = shift; + my $leading_command = shift; + my $leading_command_formatted = shift; + my $preformatted_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + + return $text; +} + +sub docbook_misc_commands($$$$$) +{ + my $macro = shift; + my $line = shift; + my $args = shift; + my $stack = shift; + my $state = shift; +#print STDERR "$macro $line"; +#print STDERR "ARGS @$args\n" if defined ($args); + my $result_text = undef; + if ($macro eq 'c' or $macro eq 'comment' and scalar(@$args)) + { + my $comment_line = $args->[0]; + chomp ($comment_line); + # makeinfo remove all the leading spaces + $comment_line =~ s/^\s//; + $result_text = &$comment ($comment_line); + } + elsif ($macro eq 'settitle') + { + # FIXME to be formatted? Also maybe in line_command. And in html, it + # is handled by heading _text + my $arg = $args->[0]; + $arg =~ s/^\s*//; + chomp($arg); + $result_text = "$arg\n"; + } + return ($macro, $line, $result_text); +} + +sub docbook_foot_line_and_ref($$$$$$$) +{ + my $number_in_doc = shift; + my $number_in_page = shift; + my $footnote_id = shift; + my $place_id = shift; + my $document_file = shift; + my $footnote_file = shift; + my $lines = shift; + my $state = shift; + + my $result = docbook_add_id('footnote').'>'; + foreach my $line (@$lines) + { + $result .= $line; + } + return ([], $result . ''); +} + +sub docbook_any_ref($$$) +{ + my $type = shift; + my $args = shift; + my $unformatted_args = shift; + + # FIXME? + if ($type eq 'inforef') + { + my $node_file = "($args->[2])$args->[0]"; + if ($args->[1] ne '') + { + return "*note $args->[1]: $node_file"; + } + else + { + return "*note ${node_file}::"; + } + } + else + { + if (($args->[3] ne '') or ($args->[4] ne '')) + { + return '' if ($args->[4] eq ''); + my $section_name = $args->[2]; + $section_name = $args->[0] if ($section_name eq ''); + if ($type eq 'ref') + { + return gdt('section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', { 'section_name' => $section_name, 'book' => $args->[4] },{'duplicate'=>1}); + } + elsif ($type eq 'xref') + { + return gdt('See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', { 'section_name' => $section_name, 'book' => $args->[4] },{'duplicate'=>1}); + } + elsif ($type eq 'pxref') + { + return gdt('see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', { 'section_name' => $section_name, 'book' => $args->[4] },{'duplicate'=>1}); + } + } + my $link = docbook_node_id($unformatted_args->[0]); + my $title = $args->[2]; + $title = $args->[1] if ($title eq ''); + if ($title eq '') + { + if ($type eq 'ref') + { + return gdt('{ref}', {'ref' => docbook_add_id('xref')." linkend=\"$link\">"}); + } + elsif ($type eq 'pxref') + { + return gdt('see {ref}', {'ref' => docbook_add_id('xref')." linkend=\"$link\">"}); + } + elsif ($type eq 'xref') + { + return gdt('See {ref}', {'ref' => docbook_add_id('xref')." linkend=\"$link\">"}); + } + } + else + { + if ($type eq 'ref') + { + return gdt('{title_ref}', {'title_ref' => docbook_add_id('link')." linkend=\"$link\">$title"}); + } + elsif ($type eq 'pxref') + { + return gdt('see {title_ref}', {'title_ref' => docbook_add_id('link')." linkend=\"$link\">$title"},{'duplicate'=>1}); + } + elsif ($type eq 'xref') + { + return gdt('See {title_ref}', {'title_ref' => docbook_add_id('link')." linkend=\"$link\">$title"},{'duplicate'=>1}); + } + } + } +} + +sub docbook_external_ref($$$$$$$$$) +{ + my $type = shift; + my $section = shift; + my $book = shift; + my $file = shift; + my $href = shift; + my $cross_ref = shift; + my $args_texi = shift; + my $formatted_args = shift; + my $node = shift; + + return docbook_any_ref ($type, $formatted_args, $args_texi); +} + +sub docbook_internal_ref($$$$$) +{ + my $type = shift; + my $href = shift; + my $short_name = shift; + my $name = shift; + my $is_section = shift; + my $args_texi = shift; + my $formatted_args = shift; + + return docbook_any_ref ($type, $formatted_args, $args_texi ); +} + +sub docbook_index_entry_command($$$$$) +{ + my $command = shift; + my $index_name = shift; + my $label = shift; + my $entry_texi = shift; + my $entry_formatted = shift; + + return $label if (defined($label) and $label ne ''); + return docbook_index_entry_label('','','',$main::index_prefix_to_name{$index_name}, '', '', $entry_formatted, {}); +} + +sub docbook_index_entry_label($$$$$$$$$) +{ + my $identifier = shift; + my $preformatted = shift; + my $entry = shift; + my $index_name = shift; + my $index_command = shift; + my $texi_entry = shift; + my $formatted_entry = shift; + my $in_region_not_in_output = shift; + my $index_entry = shift; + + return "${formatted_entry}"; +} + +sub docbook_close_section() +{ + my $element = $docbook_current_section; + + if (!defined($element)) + { + return ''; + } + + my $result = ''; + + # there is a special case for a @chapter that is a child of @top + # but should not be considered as is, since it is also toplevel. + # @part, however may have other toplevel elements as children. + return '' if ($element->{'child'} and (!$element->{'child'}->{'toplevel'} or $element->{'tag'} ne 'top')); + $result .= '\n"; + + my $current = $element; + # the second condition is such that top is closed only if it has + # sub-elements below chapter. + # the third condition is such that elements with a next element are + # only closed for the last element, except when the next element is + # toplevel and below top, such that @top is closed before the first + # @chapter if there are @section or the like below @top + while ($current->{'sectionup'} and !($current->{'sectionup'}->{'tag'} eq 'top' and $current->{'toplevel'}) and (!$current->{'childnext'} or ($current->{'childnext'}->{'toplevel'} and $current->{'sectionup'}->{'tag'} eq 'top'))) + { + $current = $current->{'sectionup'}; + $result .= '\n"; + } + return $result; +} + +sub docbook_end_section($$$) +{ + my $fh = shift; + my $end_foot_navigation = shift; + my $element = shift; +} + +sub docbook_print_Top_footer($$) +{ + my $fh = shift; + my $end_page = shift; + my $element = shift; +} + +sub docbook_one_section($$) +{ + my $fh = shift; + my $element = shift; + main::print_lines($fh); + &$print_page_foot($fh); +} + +sub docbook_insertcopying($) +{ + my $text = shift; + my $comment = shift; + my $simple_text = shift; + + return $text; +} + +sub docbook_acronym_like($$$$$$) +{ + my $command = shift; + my $acronym_texi = shift; + my $acronym_text = shift; + my $with_explanation = shift; + my $explanation_lines = shift; + my $explanation_text = shift; + my $explanation_simply_formatted = shift; + + $command = 'abbrev' if ($command eq 'abbr'); + my $result = docbook_add_id($command).">$acronym_text"; + if ($with_explanation) + { + $result .= " ($explanation_text)"; + } + return $result; +} + + +sub docbook_image_files($$$$) +{ + my $base = shift; + my $extension = shift; + my $texi_base = shift; + my $texi_extension = shift; + my @files = (); + return @files if (!defined($base) or ($base eq '')); +# FIXME should look at extension argument? makeinfo doesn't +# push @files,"$base.$extension" if (defined($extension) and ($extension ne '')); + foreach my $ext (@IMAGE_EXTENSIONS) + { + push @files, ["$base.$ext", "$texi_base.$ext"]; + } + return @files; +} + + +sub docbook_image($$$$$$$$$$$$$$$$;$) +{ + my $file = shift; + my $base = shift; + my $preformatted = shift; + my $file_name = shift; + my $alt = shift; + my $width = shift; + my $height = shift; + my $raw_alt = shift; + my $extension = shift; + my $working_dir = shift; + my $file_path = shift; + my $in_paragraph = shift; + my $file_locations = shift; + my $base_simple_format = shift; + my $extension_simple_format = shift; + my $file_name_simple_format = shift; + my $line_nr = shift; + +# if (!defined($file_path) or $file_path eq '' or $file_path =~ /\.txt$/) +# { +# if (defined($extension) and $extension ne '') +# { +# $file = "$base.$extension"; +# } +# else +# { +# $file = "$base.jpg"; +# $extension = 'jpg'; +# } +# main::line_warn ("no image file for $base, (using $file)"); +# } + my $txt_path; + my @files = (); + my @extensions = @IMAGE_EXTENSIONS; + foreach my $file_location (@$file_locations) + { + my ($file_located, $path, $file_simple_format) = @$file_location; + my $extension = shift @extensions; + if (defined($path)) + { + if ($extension eq 'txt' and !defined($txt_path)) + { + $txt_path = $path; + } + else + { + push @files, [$file_located, uc($extension), $file_simple_format]; + } + } + } + push @files, ["$base.jpg", 'JPG', "$base_simple_format.jpg" ] unless (@files); + + my $begin = docbook_add_id('inlinemediaobject').'>'; + my $end = ''; + if ($preformatted or !$in_paragraph) + { + $begin = docbook_add_id('informalfigure').'>'; + $end = ''; + } + my $result = $begin; + foreach my $file_spec (@files) + { + $result .= "[2]\" format=\"$file_spec->[1]\">"; + } + if (defined($txt_path)) + { + if (open(TXT, "<$txt_path")) + { + if (defined($Texi2HTML::THISDOC{'IN_ENCODING'}) and $USE_UNICODE) + { + binmode(TXT, ":encoding($Texi2HTML::THISDOC{'IN_ENCODING'})"); + } + $result.=""; + while (my $img_txt = ) + { + $result .= $img_txt; + } + $result .= ''; + close(TXT); + } + else + { + main::line_warn (sprintf(__("\@image file `%s' unreadable: %s"), $txt_path, $!), $line_nr); + } + } + else + { + main::line_warn (sprintf(__("Cannot find \@image file `%s.txt'"), $base), $line_nr); + } + + return "$result$end"; +} + +sub docbook_format_list_item_texi($$$$) +{ + my $format = shift; + my $line = shift; + my $prepended = shift; + my $command = shift; + + my $result_line = undef; + + if (defined($command) and $command ne '' and !exists $special_list_commands{$format}->{$command} and $format ne 'itemize') + { + #@*table + $line =~ s/^\s*//; + $line =~ s/\s*$//; + if (exists ($style_map{$command})) + { + $result_line = "\@$command\{$line\}\n"; + } + elsif (exists ($things_map{$command})) + { + $result_line = "\@$command\{\} $line\n"; + } + else + { + $result_line = "\@$command $line\n"; + } + } + + return ($result_line, 0); +} + + +# row in multitable +sub docbook_row($$;$$) +{ + my $text = shift; + my $macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + + my $result = ''; + if ($macro eq 'headitem') + { + if ($docbook_multitable_stack[-1] != 0) + { + $result .= ""; + $result = "" . $result if ($docbook_multitable_stack[-1] == 1); + $docbook_multitable_stack[-1] = 0; + } + } + elsif ($docbook_multitable_stack[-1] != 1) + { + $result .= ""; + $result = "" . $result if ($docbook_multitable_stack[-1] == 0); + $docbook_multitable_stack[-1] = 1; + } + $result .= "$text"; + + return $result; +} + +# cell in multitable +sub docbook_cell($$;$$) +{ + my $text = shift; + my $row_macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + + return "" . $text . ''; +} + +# if varlistentry_state is > 0 it means that a varlistentry is opened. +# if varlistentry_state is == 2 it means that we are in a succession +# of term +# if varlistentry_state is == 1 it means that we are in the line +# Having a listitem in a varlistentry is a must, so an empty +# listitem is added if a varlistentry is closed and varlistentry_state == 2 +# +# varlistentry acceps only term and listitem, so inter_item_commands +# are put in the next term, or, if at the end of the table in a last +# listitem +sub docbook_table_item($$$$$$) +{ + my $text = shift; + my $index_label = shift; + my $format = shift; + my $command = shift; +# my $formatted_command = shift; + my $style_stack = shift; +# my $text_formatted = shift; +# my $text_formatted_leading_spaces = shift; +# my $text_formatted_trailing_spaces = shift; + my $item_cmd = shift; + +# $formatted_command = '' if (!defined($formatted_command)); + +# if (defined($text_formatted)) +# { +# $text_item = $text_formatted_leading_spaces . $text_formatted .$text_formatted_trailing_spaces; +# } +# else +# { +# $text_item = $text; +# } + + my $result = ''; + my $prepended = ''; + if (defined($docbook_table_stack[-1]->{'inter_item'})) + { + #$formatted_command = $docbook_table_stack[-1]->{'inter_item'} . $formatted_command; + $prepended = $docbook_table_stack[-1]->{'inter_item'}; + delete $docbook_table_stack[-1]->{'inter_item'}; + } + if ($item_cmd eq 'item') + { + if ($docbook_table_stack[-1]->{'varlistentry_state'} == 2) + { + $result .= ""; + } + if ($docbook_table_stack[-1]->{'varlistentry_state'} >= 1) + { + $result .= ''; + } + $docbook_table_stack[-1]->{'varlistentry_state'} = 2; + $result .= ''; + } + $result .= ''; + $result .= $prepended . $text ."\n"; + return $result; +} + +sub docbook_table_line($$$) +{ + my $text = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + +#print STDERR + + if ($text =~ /\S/) + { + if ($before_items) + { + return $text; + } + + if ($only_inter_item_commands) + { + $docbook_table_stack[-1]->{'inter_item'} = $text; + return ''; + } + else + { + $docbook_table_stack[-1]->{'varlistentry_state'} = 1; + return "$text"; + } + #return $text; + } + else + { + return ''; + } +} + +sub docbook_list_item($$$$$$$$$) +{ + my $text = shift; + my $format = shift; + my $command = shift; + my $formatted_command = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $prepended = shift; + my $prepended_formatted = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); + +#my $prep_t = 'UNDEF'; $prep_t = $prepended if (defined($prepended)); +#$item_nr = 0 if (!defined($item_nr)); +#print STDERR " $item_nr --> $prep_t|${text}!!!!!\n"; + #return $text if ($only_inter_item_commands and $before_items); + return $text if ($before_items); + return '' . $text . "\n"; +} + +sub docbook_table_list($$$$$$$$$) +{ + my $format_command = shift; + my $text = shift; + my $command = shift; + my $formatted_command = shift; +# enumerate + my $item_nr = shift; + my $enumerate_style = shift; +# itemize + my $prepended = shift; + my $prepended_formatted = shift; +# multitable + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $number = shift; + + my $result = "<$format_command>"; + if ($format_command eq 'itemize') + { + my $itemfunction; + #$prepended_formatted =~ s/^\s*// if (defined($prepended_formatted)); + $prepended =~ s/^\s*// if (defined($prepended)); + #if (defined($formatted_command) and $formatted_command ne '') + if (defined($command) and $command ne '') + { + #$itemfunction = $formatted_command; + $itemfunction = $command; + #$itemfunction .= " $prepended_formatted" if (defined($prepended_formatted) and $prepended_formatted ne ''); + $itemfunction .= " $prepended" if (defined($prepended) and $prepended ne ''); + } + #elsif (defined($prepended_formatted)) + elsif (defined($prepended)) + { + #$itemfunction = $prepended_formatted; + $itemfunction = $prepended; + } + my $mark = ''; + $mark = " mark=\"$itemfunction\"" if (defined($itemfunction) and $itemfunction ne ''); + return docbook_add_id('itemizedlist')."${mark}>$text"; + } + elsif ($format_command eq 'enumerate') + { + my $numeration='arabic'; + if (defined($enumerate_style) and $enumerate_style ne '') + { + if ($enumerate_style =~ /^[A-Z]/) + { + $numeration = 'upperalpha'; + } + elsif ($enumerate_style =~ /^[a-z]/) + { + $numeration = 'loweralpha'; + } + } + return docbook_add_id('orderedlist') ." numeration=\"$numeration\">$text"; + } + elsif ($format_command eq 'multitable') + { + my $result = docbook_add_id('informaltable').'>'; + my $fractions; + my $multiply = 1; + if (defined($columnfractions) and (ref($columnfractions) eq 'ARRAY') + and scalar(@$columnfractions)) + { + $fractions = [ @$columnfractions ]; + $multiply = 100; + } + elsif (defined($prototype_lengths) and (ref($prototype_lengths) eq 'ARRAY') + and scalar(@$prototype_lengths)) + { + $fractions = [ @$prototype_lengths ]; + } + + if (defined ($fractions)) + { + foreach my $fraction (@$fractions) + { + $result .= ''; + } + } + $text .= "" if ($docbook_multitable_stack[-1] == 1); + $text .= "" if ($docbook_multitable_stack[-1] == 0); + pop @docbook_multitable_stack; + return $result . "$text"; + } + elsif ($format_command =~ /^(v|f)?table$/) + { + $result = docbook_add_id('variablelist').'>'; + if (defined($docbook_table_stack[-1]->{'inter_item'})) + { # there is a para in case there is only a comment, to avoid + # an empty listitem + $text .= "$docbook_table_stack[-1]->{'inter_item'}"; + } + elsif ($docbook_table_stack[-1]->{'varlistentry_state'} == 2) + { + $text .= ""; + } + $text .= '' if ($docbook_table_stack[-1]->{'varlistentry_state'} >= 1); + pop @docbook_table_stack; + return $result . "$text\n"; + } +} + +sub docbook_begin_format_texi($$$) +{ + my $command = shift; + my $line = shift; + my $state = shift; + + push (@docbook_multitable_stack, -1) if ($command eq 'multitable'); + push (@docbook_table_stack, {'varlistentry_state' => 0}) if ($command =~ /^(v|f)?table/); + return $line; +} + +# FIXME +sub docbook_sp($$) +{ + my $number = shift; + my $preformatted = shift; + return ""; +} + +sub docbook_index_summary($$) +{ + my $alpha = shift; + my $nonalpha = shift; + return ''; +} + +sub docbook_printindex($$) +{ + my $name = shift; + my $printindex = shift; + return docbook_add_id('index').">\n"; +} + +sub docbook_complex_format($$) +{ + my $name = shift; + my $text = shift; + return '' if ($text eq ''); + my $result = docbook_add_id($docbook_complex_format{$name}).'>' .$text.""; + return $result; +} + +sub docbook_format($$) +{ + my $name = shift; + my $element = shift; + my $text = shift; + return '' if ($text eq ''); + return $text if ($format_map{$name} eq ''); + if ($name eq 'copying') + { + # FIXME is info in docbook 5.0 + return "\n\n$text\n\n"; + } + return docbook_add_id($format_map{$name}).'>' .$text.""; +} + +sub docbook_quotation_prepend_text($$) +{ + my $command = shift; + my $argument_text = shift; + + return undef if (!defined($argument_text) or $argument_text =~ /^$/); + + chomp($argument_text); + + return undef if (grep {lc($argument_text) eq $_} @docbook_special_quotation); + return gdt('@b{{quotation_arg}:} ', {'quotation_arg' => $argument_text}, {'keep_texi' => 1}); +} + + +sub docbook_quotation($$$$$) +{ + my $command = shift; + my $text = shift; + my $argument_text = shift; + my $argument_text_texi = shift; + my $authors = shift; + + $argument_text_texi = '' if (!defined($argument_text_texi)); + chomp($argument_text_texi); + my $docbook_command = 'blockquote'; + if (grep {lc($argument_text_texi) eq $_} @docbook_special_quotation) + { + $docbook_command = lc($argument_text_texi); + } + my $attribution = ''; + if ($authors) + { + foreach my $author (@$authors) + { + $attribution .= $author->{'author_text'}; + } + $attribution = '' .$attribution. '' . "\n"; + } + return docbook_add_id($docbook_command).'>' .$attribution . $text . "\n"; +} + +sub docbook_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 $command_stack = shift; + my $kept_line_nrs = shift; + + my $result = $text; + if (exists($style->{'function'})) + { + my $function = $style->{'function'}; + $result = &$function($command, $args, $command_stack, $state, $line_nr, $kept_line_nrs); + } + elsif (exists($style->{'inline_attribute'})) + { + my $element = $style->{'inline_attribute'}; + my $attribute_text = ''; + if ($element =~ /^(\w+)(\s+.*)/) + { + $element = $1; + $attribute_text = $2; + } + + if ($no_open) + { + $result = "<$element"; + } + else + { + $result = docbook_add_id($element); + } + $result .= "$attribute_text>$text"; + } + if (exists($style->{'begin'}) and !$no_open) + { + $result = $style->{'begin'} . $result; + } + if (exists($style->{'end'}) and !$no_close) + { + $result .= $style->{'end'}; + } + return $result; +} + +sub docbook_raw($$$) +{ + my $style = shift; + my $text = shift; + my $line_nr = shift; + + if ($style eq 'verbatim' or $style eq 'verbatiminclude') + { + return docbook_add_id('screen').'>' . &$protect_text($text) . ''; + } + return '' unless (grep {$style eq $_} @EXPAND); + if ($style eq 'docbook') + { + chomp ($text); + return $text; + } + else + { + main::line_warn (sprintf(__("Raw format %s is not converted"), $style), $line_nr); + return &$protect_text($text); + } +} + +sub docbook_cartouche($$) +{ + my $text = shift; + + return $text; +} + +sub docbook_anchor_label($$) +{ + my $id = shift; + my $anchor_text = shift; + # FIXME use docbook_node_id + return ''; +} + +sub docbook_float($$$$$) +{ + my $text = shift; + my $float = shift; + my $caption = shift; + my $shortcaption = shift; + + my $label_texi = $float->{'texi'}; + return $text if (!defined($label_texi) or $label_texi eq ''); + + return docbook_anchor_label('',$label_texi) . $text; +} + +sub docbook_normal_text($$$$$$$;$) +{ + my $text = shift; + my $in_raw_text = shift; # remove_texi + my $in_preformatted = shift; + my $in_code = shift; + my $in_math = shift; + my $in_simple = shift; +#print STDERR "Bug: in_raw_text in_simple $text\n" if ($in_raw_text and $in_simple); + my $style_stack = shift; + my $state = shift; + + #$text = uc($text) if (in_cmd($style_stack, 'sc')); + $text = &$protect_text($text) unless($in_raw_text); + if (! $in_code and !$in_preformatted) + { + if (!$in_raw_text) + { + $text =~ s/---/\&mdash\;/g; + $text =~ s/--/\&ndash\;/g; + $text =~ s/``/\&ldquo\;/g; + $text =~ s/''/\&rdquo\;/g; + } + else + { + #FIXME really do that ? It is done by makeinfo in html + $text =~ s/``/"/g; + $text =~ s/''/"/g; + # FIXME really do that in raw text? + $text =~ s/---/\x{1F}/g; + $text =~ s/--/-/g; + $text =~ s/\x{1F}/--/g; + } + } + return $text; +} + +sub docbook_noop +{ + return ''; +} + +1; + +require "$T2H_HOME/formats/docbook.init" + if ($0 =~ /\.pl$/ && + -e "$T2H_HOME/formats/docbook.init" && -r "$T2H_HOME/formats/docbook.init"); + +# @INIT_XML@ +# vim: set filetype=perl: + +use strict; + +my @xml_multitable_stack = (); +my @xml_table_stack = (); + +my @xml_ignored_misc_commands; +my %xml_misc_command_output; +my %xml_misc_elements_with_arg_map; +my @xml_misc_elements_with_arg; +my %def_format_xml; +my $xml_current_section; + +sub xml_default_load(;$) +{ +my $from_command_line = shift; + +t2h_default_set_variables_xml(); +$DOCTYPE = ''; +$SIMPLE_MENU = 0; +$SEPARATE_DESCRIPTION = 1; +@T2H_FORMAT_EXPAND = ('xml', 'direntry'); +$USE_ISO = 0; +$HEADERS = 0; +$INLINE_INSERTCOPYING = 0; +$SHOW_MENU = 1; +$SHOW_TITLE = 0; +$NUMBER_SECTIONS = 0; +$USE_NODES = 1; +$USE_SECTIONS = 1; + +t2h_default_push_handler(\&xml_init_variables, \@command_handler_init); + +$colon_command_punctuation_characters{'.'} = '.'; +$colon_command_punctuation_characters{':'} = ':'; +$colon_command_punctuation_characters{'?'} = '?'; +$colon_command_punctuation_characters{'!'} = '!'; + +$simple_map{'*'} = '&linebreak;'; +$simple_map{' '} = '&space;'; +$simple_map{"\t"} = '&space;'; +$simple_map{"\n"} = '&space;'; +$simple_map{'.'} = '&eosperiod;'; +$simple_map{'!'} = '&eosexcl;'; +$simple_map{'?'} = '&eosquest;'; + +%simple_map_pre = %simple_map; + +# FIXME right? +$things_map{'l'} = '/l'; +$things_map{'L'} = '/L'; +$things_map{'enddots'} = '&enddots;'; +$things_map{'dots'} = '&dots;'; +# FIXME equiv, point, expansion could be ameliorated +$things_map{'equiv'} = '=='; +$things_map{'point'} = '-!-'; +$things_map{'expansion'} = '==>'; # →? + +$things_map{'minus'} = '−'; +$things_map{'result'} = '⇒'; +$things_map{'bullet'} = '•'; +$things_map{'copyright'} = '©right;'; +$things_map{'registeredsymbol'} = '®istered;'; +$things_map{'arrow'} = '→'; +$things_map{'TeX'} = '&tex;'; +$things_map{'LaTeX'} = '&latex;'; + +%pre_map = %things_map; + +$stop_paragraph_command{'caption'} = 1; +$stop_paragraph_command{'shortcaption'} = 1; + +%line_command_map = (); +foreach my $command ('contents', 'shortcontents', 'summarycontents') +{ + $line_command_map{$command} = $command; +} + +%format_map = (); + +$format_map{'copying'} = ''; +$format_map{'titlepage'} = 'titlepage'; +$format_map{'documentdescription'} = 'documentdescription'; +$format_map{'group'} = 'group'; +$format_map{'raggedright'} = 'raggedright'; + +foreach my $region ('titlepage', 'documentdescription', 'copying') +{ + $region_formats_kept{$region} = 1; +} + +%style_map = (); +t2h_default_copy_style_map (\%default_style_map, \%style_map); + +foreach my $style (keys(%style_map)) +{ + next if grep {$style eq $_} ('asis', 'ctrl', 'w'); + if (grep {$style eq $_} ('tieaccent', 'dotless', keys(%unicode_accents))) + { + $style_map{$style} = { 'function' => \&xml_default_accent }; + } + elsif (!exists($style_map{$style}->{'args'}) or (scalar(@{$style_map{$style}->{'args'}}) eq 1 and ($style_map{$style}->{'args'}->[0] eq 'code' or $style_map{$style}->{'args'}->[0] eq 'normal'))) + { + $style_map{$style}->{'inline_attribute'} = $style; + delete ($style_map{$style}->{'quote'}); + delete ($style_map{$style}->{'begin'}); + delete ($style_map{$style}->{'end'}); + delete ($style_map{$style}->{'function'}); + } +} + +foreach my $complex_format (keys(%complex_format_map)) +{ + my $style = $complex_format_map{$complex_format}->{'style'}; + delete $complex_format_map{$complex_format}; + $complex_format_map{$complex_format}->{'begin'} = "<$complex_format xml:space=\"preserve\">"; + $complex_format_map{$complex_format}->{'end'} = ""; + $complex_format_map{$complex_format}->{'style'} = $style if (defined($style)); +} +foreach my $menu_command('menu', 'detailmenu', 'direntry', 'menu_comment') +{ + $complex_format_map{$menu_command} = undef; + delete $complex_format_map{$menu_command}; +} + +# this is not needed because normal_text isn't the same than in html +#t2h_remove_text_substitutions("'", 1, 0, 0, 1); +#t2h_remove_text_substitutions('`', 1, 0, 0, 1); + +$style_map{'w'}->{'end'} = ''; +$style_map{'='}->{'function'} = \&xml_macron; +$style_map{'email'}->{'function'} = \&xml_email; +$style_map{'titlefont'}->{'function'} = \&xml_titlefont; +$style_map{'math'}->{'function'} = \&xml_math; +$style_map{'uref'}->{'function'} = \&xml_uref; +$style_map{'url'}->{'function'} = \&xml_uref; +$style_map{'t'}->{'inline_attribute'} = 'tt'; +# FIXME +delete $special_accents{'ringaccent'}; +$special_accents{'ogonek'} = 'aeiuAEIU'; + +%style_map_pre = %style_map; + +$no_paragraph_commands{'cindex'} = 0; + +#my @xml_ignored_misc_commands = ('bye', 'sp', 'verbatiminclude'); + +@xml_ignored_misc_commands = ('bye', 'sp', 'verbatiminclude', 'clickstyle', + 'defcodeindex', + 'syncodeindex', 'paragraphindent', 'shorttitlepage', 'refill', 'noindent'); + +# we want to proceed all the misc commands +# makeinfo ignores clickstyle, changes setfilename. Not sure it is right. +foreach my $misc_command (keys(%misc_command)) +{ + next if (grep {$misc_command eq $_} @xml_ignored_misc_commands); + $xml_misc_command_output{$misc_command} = 1; +} + +$format_map{'menu'} = 'menu'; +# checked on bug-texinfo, only node is in code_style, as with makeinfo --xml +#$format_code_style{'menu'} = 1; +#$format_code_style{'menu_name'} = 1; +#$format_code_style{'menu_description'} = 1; +$format_map{'detailmenu'} = 'detailmenu'; +$format_map{'direntry'} = 'direntry'; +$format_map{'menu_comment'} = ''; + +$menu_description = \&xml_menu_description; +$menu_link = \&xml_menu_link; +$element_heading = \&xml_heading; +$heading = \&xml_heading; +$paragraph = \&xml_paragraph; +$preformatted = \&xml_preformatted; +$misc_element_label = \&xml_noop; +$element_label = \&xml_noop; +$anchor_label = \&xml_anchor_label; +$index_entry_label = \&xml_index_entry_label; +$index_entry_command = \&xml_index_entry_command; +$listoffloats = \&xml_listoffloats; +$acronym_like = \&xml_acronym_like; +$foot_line_and_ref = \&xml_foot_line_and_ref; +$image = \&xml_image; +$sp = \&xml_sp; +$quotation = \&xml_quotation; +$table_list = \&xml_table_list; +$row = \&xml_row; +$cell = \&xml_cell; +$list_item = \&xml_list_item; +$format_list_item_texi = \&xml_format_list_item_texi; +$misc_command_line = \&xml_misc_commands; +$begin_format_texi = \&xml_begin_format_texi; +$def_line = \&xml_def_line; +$def = \&xml_def; +$def_item = \&xml_def_item; +$printindex = \&xml_printindex; +$index_summary = \&xml_index_summary; +$external_ref = \&xml_external_ref; +$internal_ref = \&xml_internal_ref; +$table_item = \&xml_table_item; +$table_line = \&xml_table_line; +$float = \&xml_float; +$caption_shortcaption = \&xml_caption_shortcaption; +$caption_shortcaption_command = \&xml_caption_shortcaption_command; +$normal_text = \&xml_normal_text; +$protect_text = \&xml_default_protect_text; +$paragraph_style_command = \&xml_paragraph_style_command; +$raw = \&xml_raw; +$cartouche = \&xml_cartouche; + +$print_Top = \&xml_print_Top; +$print_Top_footer = \&xml_print_Top_footer; +$print_page_head = \&xml_print_page_head; +$print_foot_navigation = \&xml_noop; +$toc_body = \&xml_noop; +$about_body = \&xml_noop; +$print_page_foot = \&xml_print_page_foot; +$end_section = \&xml_end_section; +$one_section = \&xml_one_section; + +%xml_misc_elements_with_arg_map = ( + 'title' => 'booktitle', + 'subtitle' => 'booksubtitle' +); + +@xml_misc_elements_with_arg = ('author', + 'dircategory', 'settitle'); +#my @xml_misc_elements_with_arg = ('author', 'shorttitlepage', +# 'vskip', 'dircategory', 'settitle'); + +%def_format_xml = ( + 'deffn' => [ ['category', 'category'], ['function', 'name'] ], + 'defvr' => [ ['category', 'category'], ['variable', 'name'] ], + 'deftypefn' => [ ['category', 'category'], ['type', 'type'], ['function', 'name'] ], + 'deftypeop' => [ ['category', 'category'], ['type', 'type'], ['operation', 'name'] ], + 'deftypevr' => [ ['category', 'category'], ['type', 'type'], ['variable', 'name'] ], + 'defcv' => [ ['category' , 'category'], ['class', 'class'], ['classvar', 'name'] ], + 'deftypecv' => [ ['category', 'category'], ['type', 'type'], ['classvar', 'name'] ], + 'defop' => [ ['category', 'category'], ['class', 'class'], ['operation', 'name'] ], + 'deftp' => [ ['category', 'category'], ['datatype', 'name'] ] +); + + +} + +sub xml_macron($$) +{ + my $accent = shift; + my $args = shift; + return $args->[0] . "¯"; +} + +sub xml_email($$) +{ + my $command = shift; + my $args = shift; + my $mail = shift @$args; + my $text = shift @$args; + $mail = main::normalise_space($mail); + my $result = "$mail"; + if (defined($text) and $text =~ /\S/) + { + $result .= "".main::normalise_space($text).""; + } + return $result . ''; +} + +sub xml_uref($$) +{ + shift; + my $args = shift; + my $url = shift @$args; + my $text = shift @$args; + my $replacement = shift @$args; + $url = main::normalise_space($url); + $replacement = '' if (!defined($replacement)); + $replacement = main::normalise_space($replacement); + $text = '' if (!defined($text)); + $text = main::normalise_space($text); + my $result = "$url"; + $result .= "$text" if ($text ne ''); + $result .= "$replacement" if ($replacement ne ''); + return $result.''; +} + + +sub xml_titlefont($$) +{ + shift; + my $args = shift; + return "$args->[0]"; +} + +sub xml_math($$) +{ + shift; + my $args = shift; + my $text = shift @$args; + return "$text"; +} + + +sub xml_menu_description($$$) +{ + my $text = shift; + my $state = shift; + my $element_text = shift; + return "$text\n"; +} + +sub xml_menu_link($$$$$$$$$$) +{ + my $entry = shift; + my $state = shift; + my $href = shift; + my $menunode = shift; + my $menutitle = shift; + my $ending = shift; + my $has_title = shift; + my $command_stack = shift; + my $in_preformatted = shift; + my $menunode_normalized = shift; + + return "\n$menunode_normalized\n$menutitle\n"; +} + +sub xml_print_page_head($) +{ + my $fh = shift; + my $setfilename = ''; + $setfilename = "$Texi2HTML::THISDOC{file_base_name}.$EXTENSION" + unless (defined($Texi2HTML::THISDOC{'setfilename'}) and $Texi2HTML::THISDOC{'setfilename'} ne ''); + my $language = get_conf('documentlanguage'); + my $doctype = get_conf('doctype'); + print $fh < +$doctype + +$setfilename +EOT +} + +sub xml_print_page_foot($) +{ + my $fh = shift; + print $fh "". xml_close_section(); + print $fh < +EOT +} + +sub xml_one_section($$) +{ + my $fh = shift; + my $element = shift; + main::print_lines($fh); + #print $fh "". xml_footing($element); + &$print_foot_navigation($fh); + &$print_page_foot($fh); +} + +sub xml_heading($$$$$) +{ + my $element = shift; + my $command = shift; + my $texi_line = shift; + my $line = shift; + my $in_preformatted = shift; + +#print STDERR "'$command' $line"; + if (defined($command) and $command =~ /heading/) + { + my $text = ''; + if (defined($line)) + { + $text = $line; + # this isn't done in main program in that case... + chomp ($text); + $text =~ s/^\s*//; + } + return "<${command}>$text\n"; + } + elsif (defined($command) and $command eq 'node') + { +#print STDERR "node $command $node_element->{'texi'}\n"; + my $result = ''; + $result .= xml_close_section(); + $result .= "\n"; + $result .= "$element->{'text'}\n"; + foreach my $direction('nodenext', 'nodeprev', 'nodeup') + { + if ($element->{$direction}) + { + $result .= "<${direction}>$element->{$direction}->{'text'}\n"; + } + } + $result .= "\n"; + return $result; + + } + else + { + my $result = ''; + $result .= xml_close_section(); + $result .= "<".xml_element_tag($element).">\n$element->{'text'}\n"; + $xml_current_section = $element; + return $result; + } +} + +sub xml_element_tag($) +{ + my $element = shift; + my $class = $element->{'tag_level'}; + return $class; +} + +sub xml_close_section() +{ + my $element = $xml_current_section; + + if (!defined($element)) + { + return ''; + } + my $result = ''; + + $xml_current_section = undef; + + # there is a special case for a @chapter that is a child of @top + # but should not be considered as is, since it is also toplevel. + # @part, however may have other toplevel elements as children. + return '' if ($element->{'child'} and (!$element->{'child'}->{'toplevel'} or $element->{'tag'} ne 'top')); + $result .= '\n"; + + my $current = $element; + # the second condition is such that top is closed only if it has + # sub-elements below chapter. + # the third condition is such that elements with a next element are + # only closed for the last element, except when the next element is + # toplevel and below top, such that @top is closed before the first + # @chapter if there are @section or the like below @top + while ($current->{'sectionup'} and !($current->{'sectionup'}->{'tag'} eq 'top' and $current->{'toplevel'}) and (!$current->{'childnext'} or ($current->{'childnext'}->{'toplevel'} and $current->{'sectionup'}->{'tag'} eq 'top'))) + { + $current = $current->{'sectionup'}; + $result .= '\n"; + } + return $result; + + ## there is a special case for a @chapter that is a child of @top + ## but should not be considered as is, since it is also toplevel. + #return '' if ($element->{'child'} and !$element->{'child'}->{'toplevel'}); + #$result .= '\n"; + + #return $result if ($element->{'sectionnext'} or $element->{'level'} <= 1); + #my $current = $element; + #while ($current->{'level'} != 1 and $current->{'sectionup'} and !$current->{'sectionnext'}) + #{ + # $current = $current->{'sectionup'}; + # $result .= '\n"; + #} + #return $result; +} + +sub xml_end_section($$$) +{ + my $fh = shift; + my $end_foot_navigation = shift; + my $element = shift; +} + +sub xml_print_Top($$$) +{ + my $fh = shift; + my $has_top_heading = shift; + my $element = shift; + main::print_lines($fh, $Texi2HTML::THIS_SECTION); +} + +sub xml_print_Top_footer($$) +{ + my $fh = shift; + my $end_page = shift; + my $element = shift; +} + +# FIXME warning: +# +# @samp{first para +# +# second para}. +# +# maybe should lead to: +# first para second para. +# +# But it leads to +# first para +# +# second para. +# +sub xml_paragraph($$$$$$$$$$$$) +{ + my $text = shift; + my $align = shift; + my $indent = shift; + my $paragraph_command = shift; + my $paragraph_command_formatted = shift; + my $paragraph_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + + # no para in multitables, caption and shortcaptions. + my $top_stack = ''; + $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); + return $text if ($top_stack eq 'multitable' or $top_stack eq 'shortcaption' or $top_stack eq 'caption' or $top_stack eq 'documentdescription'); + + if ($text =~ /\S/) + { + return "$text"; + } + return $text; +} + +sub xml_preformatted($$$$$$$$$$$$) +{ + my $text = shift; + my $pre_style = shift; + my $class = shift; + my $leading_command = shift; + my $leading_command_formatted = shift; + my $preformatted_number = shift; + my $format = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $command_stack_at_end = shift; + my $command_stack_at_begin = shift; + + return $text; +} + +sub xml_misc_commands($$$$$) +{ + my $macro = shift; + my $line = shift; + my $args = shift; + my $stack = shift; + my $state = shift; + +#print STDERR "$macro $line"; +#print STDERR "ARGS @$args\n" if defined ($args); + return ($macro, $line, undef) unless($xml_misc_command_output{$macro}); + + my $value_name = ''; + my $value = ''; + if ($macro eq 'set' or $macro eq 'clear') + { + my $value_line = $line; + if ($value_line =~ s/^\s+([\w\-]+)//) + { + $value_name = $1; + if ($macro eq 'set') + { + $value = $value_line; + chomp ($value); + $value =~ s/^\s*//; + } + } + } + my $result_text = "<${macro}>"; + if ($macro eq 'set' or $macro eq 'clear') + { + $result_text = "<${macro}value name=\"$value_name\">$value\n"; + } + if ($macro eq 'c' or $macro eq 'comment' and scalar(@$args)) + { + my $comment_line = $args->[0]; + chomp ($comment_line); + # makeinfo remove all the leading spaces + $comment_line =~ s/^\s//; + $result_text = &$comment ($comment_line); + } + if ($macro eq 'frenchspacing') + { + my $value = $args->[0]; + $value =~ s/\s*//g; + $result_text = "<${macro} var=\"$value\">"; + } + if (grep {$macro eq $_} @xml_misc_elements_with_arg) + { + my $arg = $args->[0]; + $arg =~ s/^\s*//; + chomp($arg); + $result_text = "<${macro}>".main::substitute_line($arg, "\@$macro")."\n"; + } + if (exists($xml_misc_elements_with_arg_map{$macro})) + { + my $arg = $args->[0]; + $arg =~ s/^\s*//; + chomp($arg); + $result_text = "<$xml_misc_elements_with_arg_map{$macro}>".main::substitute_line($arg, "\@$macro")."\n"; + } + if ($macro eq 'setfilename') + { + my $arg = $args->[0]; + #$arg =~ s/^\s*//; + #$arg =~ s/\s*$//; + #$arg = main::substitute_line($arg, "\@$macro"); + if ($arg =~ /\S/) + { + $arg = get_conf('setfilename'); + $arg =~ s/\.[^\.]*$//; + $result_text = "<${macro}>${arg}.xml\n"; + } + } + return ($macro, $line, $result_text); +} + + +sub xml_anchor_label($$) +{ + my $id = shift; + my $anchor_text = shift; + return ''; +} + +sub xml_index_entry_command($$$$$) +{ + my $command = shift; + my $index_name = shift; + my $label = shift; + my $entry_texi = shift; + my $entry_formatted = shift; + + return $label if (defined($label) and $label ne ''); + return xml_index_entry_label('','','',$main::index_prefix_to_name{$index_name}, '', '', $entry_formatted, {}); +} + +sub xml_index_entry_label($$$$$$$$$) +{ + my $identifier = shift; + my $preformatted = shift; + my $formatted_entry = shift; + my $index_name = shift; + my $index_command = shift; + my $texi_entry = shift; + my $formatted_entry_reference = shift; + my $in_region_not_in_output = shift; + my $index_entry_ref = shift; + + + return "${formatted_entry_reference}"; +} + +sub xml_listoffloats($$$) +{ + my $style_texi = shift; + my $style = shift; + my $float_entries = shift; + # FIXME style, style_texi? Protected? + return ""; +} + +sub xml_acronym_like($$$$$$) +{ + my $command = shift; + my $acronym_texi = shift; + my $acronym_text = shift; + my $with_explanation = shift; + my $explanation_lines = shift; + my $explanation_text = shift; + my $explanation_simply_formatted = shift; + + $command = 'abbrev' if ($command eq 'abbr'); + my $opening = "<${command}><${command}word>$acronym_text"; + if ($with_explanation) + { + $opening .= "<${command}desc>$explanation_text"; + } + return $opening . ""; +} + +sub xml_foot_line_and_ref($$$$$$$) +{ + my $number_in_doc = shift; + my $number_in_page = shift; + my $footnote_id = shift; + my $place_id = shift; + my $document_file = shift; + my $footnote_file = shift; + my $lines = shift; + my $state = shift; + + my $result = ''; + foreach my $line (@$lines) + { + $result .= $line; + } + return ([], $result . ''); +} + +sub xml_image($$$$$$$$$$$$$) +{ + my $file = shift; + my $base = shift; + my $preformatted = shift; + my $file_name = shift; + my $alt = shift; + my $width = shift; + my $height = shift; + my $raw_alt = shift; + my $extension = shift; + my $working_dir = shift; + my $file_path = shift; + my $in_paragraph = shift; + my $file_locations = shift; + + $alt = '' if (!defined($alt)); + # dirty hack to avoid " that can be here because of a @verb + $alt =~ s/"/"/g; + + $width = '' if (!defined($width)); + $height = '' if (!defined($height)); + + my $tag = 'inlineimage'; + $tag = 'image' if ($preformatted or !$in_paragraph); + + return "<$tag width=\"$width\" height=\"$height\" name=\"". &$protect_text($base)."\" extension=\"$extension\">$alt"; +} + +sub xml_sp($$) +{ + my $number = shift; + my $preformatted = shift; + return "\n"; +} + +sub xml_quotation($$$$$) +{ + my $command = shift; + my $text = shift; + my $argument_text = shift; + my $argument_text_texi = shift; + my $authors = shift; + return "<$command>\n" . $text . "\n"; +} + +sub xml_format_list_item_texi($$$$) +{ + my $format = shift; + my $line = shift; + my $prepended = shift; + my $command = shift; + + my $result_line = undef; + + if (defined($command) and $command ne '' and !exists $special_list_commands{$format}->{$command} and $format ne 'itemize') + { + #@*table + $line =~ s/^\s*//; + $line =~ s/\s*$//; + if (exists ($style_map{$command})) + { + $result_line = "\@$command\{$line\}\n"; + } + elsif (exists ($things_map{$command})) + { + $result_line = "\@$command\{\} $line\n"; + } + else + { + $result_line = "\@$command $line\n"; + } + } + + return ($result_line, 0); +} + +sub xml_list_item($$$$$$$$$) +{ + my $text = shift; + my $format = shift; + my $command = shift; + my $formatted_command = shift; + my $item_nr = shift; + my $enumerate_style = shift; + my $number = shift; + my $prepended = shift; + my $prepended_formatted = shift; + + return '' . $text . "\n"; +} + +sub xml_init_variables() +{ + @xml_multitable_stack = (); + @xml_table_stack = (); + $xml_current_section = undef; + $Texi2HTML::THISDOC{'SPLIT'} = 0 if ($OUTPUT_FORMAT eq 'xml'); +} + +# row in multitable +sub xml_row($$;$$) +{ + my $text = shift; + my $macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + + my $result = ''; + if ($macro eq 'headitem') + { + if ($xml_multitable_stack[-1] != 0) + { + $result .= ""; + $result = "" . $result if ($xml_multitable_stack[-1] == 1); + $xml_multitable_stack[-1] = 0; + } + } + elsif ($xml_multitable_stack[-1] != 1) + { + $result .= ""; + $result = "" . $result if ($xml_multitable_stack[-1] == 0); + $xml_multitable_stack[-1] = 1; + } + $result .= "$text"; + + return $result; +} + +# cell in multitable +sub xml_cell($$;$$) +{ + my $text = shift; + my $row_macro = shift; + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $column_number = shift; + + return "" . $text . ''; +} + +sub xml_table_list($$$$$$$$$) +{ + my $format_command = shift; + my $text = shift; + my $command = shift; + my $formatted_command = shift; +# enumerate + my $item_nr = shift; + my $enumerate_style = shift; +# itemize + my $prepended = shift; + my $prepended_formatted = shift; +# multitable + my $columnfractions = shift; + my $prototype_row = shift; + my $prototype_lengths = shift; + my $number = shift; + + my $result = "<$format_command>"; + if ($format_command eq 'itemize') + { + my $itemfunction; + $prepended_formatted =~ s/^\s*// if (defined($prepended_formatted)); + if (defined($formatted_command) and $formatted_command ne '') + { + $itemfunction = $formatted_command; + $itemfunction .= " $prepended_formatted" if (defined($prepended_formatted) and $prepended_formatted ne ''); + } + elsif (defined($prepended_formatted)) + { + $itemfunction = $prepended_formatted; + } + $itemfunction = "•" if (!defined($itemfunction) or + $itemfunction eq ''); + $result .= "$itemfunction"; + } + elsif ($format_command eq 'enumerate') + { + $result = "<$format_command first=\"$enumerate_style\">"; + } + elsif ($format_command eq 'multitable') + { + my $fractions; + my $multiply = 1; + if (defined($columnfractions) and (ref($columnfractions) eq 'ARRAY') + and scalar(@$columnfractions)) + { + $fractions = [ @$columnfractions ]; + $multiply = 100; + } + elsif (defined($prototype_lengths) and (ref($prototype_lengths) eq 'ARRAY') + and scalar(@$prototype_lengths)) + { + $fractions = [ @$prototype_lengths ]; + } + + if (defined ($fractions)) + { + foreach my $fraction (@$fractions) + { + $result .= "".($fraction*$multiply)."\n"; + } + } + $text .= "" if ($xml_multitable_stack[-1] == 1); + $text .= "" if ($xml_multitable_stack[-1] == 0); + pop @xml_multitable_stack; + } + elsif ($format_command =~ /^(v|f)?table$/) + { + $result = ''; + $text .= '' if ($xml_table_stack[-1] == 1); + pop @xml_table_stack; + return $result . "$text
    \n"; + } + return $result . "$text\n"; +} + +sub xml_begin_format_texi($$$) +{ + my $command = shift; + my $line = shift; + my $state = shift; + + push (@xml_multitable_stack, -1) if ($command eq 'multitable'); + push (@xml_table_stack, 0) if ($command =~ /^(v|f)?table/); + return $line; +} + +sub xml_def_line($$$$$$$$$$$$$$$) +{ + my $category_prepared = shift; + my $name = shift; + my $type = shift; + my $arguments = shift; + my $index_label = shift; + my $arguments_array = shift; + my $arguments_type_array = shift; + my $unformatted_arguments_array = shift; + my $command = shift; + my $class_name = shift; + my $category = shift; + my $class = shift; + my $style = shift; + my $original_command = shift; + + my $result = "$class_name"; + + my %arguments = ( 'prepared_category' => $category_prepared, + 'category' => $category, + 'name' => $name, + 'type' => $type, + 'class' => $class + ); + foreach my $type (keys(%arguments)) + { + $arguments{$type} = '' if (!defined($arguments{$type})); + } + + foreach my $mandatory_arg (@{$def_format_xml{$command}}) + { + my $elem = $mandatory_arg->[0]; + $result .= "$arguments{$mandatory_arg->[1]}"; + } + + my $params = ''; + my @types = @$arguments_type_array; + foreach my $arg (@$arguments_array) + { + my $type = shift @types; + if (grep {$_ eq $type} ('param', 'paramtype', 'delimiter')) + { + $result .= "$arg"; + } + } + + $result .= "\n"; + return $result; +} + +# FIXME +# @deffn +# @c comment +# @end deffn +# leads to the creation of a with a comment within, +# while there should be no definitionitem +sub xml_def_item($$) +{ + my $text = shift; + my $only_inter_item_commands = shift; + + if ($text =~ /\S/) + { + return '' . $text . '' unless $only_inter_item_commands; + return $text; + } + return ''; +} + +sub xml_def($) +{ + my $text = shift; + return ''.$text.''; +} + +sub xml_index_summary($$) +{ + my $alpha = shift; + my $nonalpha = shift; + return ''; +} + +sub xml_printindex($$) +{ + my $name = shift; + my $printindex = shift; + return "$name\n"; +} + +sub xml_any_ref($$) +{ + my $type = shift; + my $args = shift; + my $result = ''; + if ($type eq 'pxref') + { + $result = gdt('see ',{'duplicate'=>1}); + } + elsif ($type eq 'xref' or $type eq 'inforef') + { + $result = gdt('See ',{'duplicate'=>1}); + } + if ($type eq 'inforef') + { + $result .= "$args->[0]"; + $result .= "$args->[1]" if ($args->[1] ne ''); + $result .= "$args->[2]" + } + else + { + $result .= "$args->[0]"; + $result .= "$args->[1]" if ($args->[1] ne ''); + $result .= "$args->[2]" if ($args->[2] ne ''); + $result .= "$args->[3]" if ($args->[3] ne ''); + $result .= "$args->[4]" if ($args->[4] ne ''); + $result .= ''; + } + return $result; +} + +sub xml_external_ref($$$$$$$$$) +{ + my $type = shift; + my $section = shift; + my $book = shift; + my $file = shift; + my $href = shift; + my $cross_ref = shift; + my $args_texi = shift; + my $formatted_args = shift; + my $node = shift; + + return xml_any_ref ($type, $formatted_args); +} + +sub xml_internal_ref($$$$$) +{ + my $type = shift; + my $href = shift; + my $short_name = shift; + my $name = shift; + my $is_section = shift; + my $args_texi = shift; + my $formatted_args = shift; + + return xml_any_ref ($type, $formatted_args); +} + +sub xml_table_item($$$$$$$) +{ + my $text = shift; + my $index_label = shift; + my $format = shift; + my $command = shift; +# my $formatted_command = shift; + my $style_stack = shift; +# my $text_formatted = shift; +# my $text_formatted_leading_spaces = shift; +# my $text_formatted_trailing_spaces = shift; + my $item_cmd = shift; + my $formatted_index_entry = shift; + + +# $formatted_command = '' if (!defined($formatted_command)); +# +# if (defined($text_formatted)) +# { +# $text_item = $text_formatted_leading_spaces . $text_formatted .$text_formatted_trailing_spaces; +# } +# else +# { +# $text_item = $text; +# } + + my $result = ''; + if ($item_cmd eq 'item') + { + $result .= '' if ($xml_table_stack[-1] == 1); + $xml_table_stack[-1] = 1; + $result .= ''; + } + $result .= ''; + #print STDERR "$text | $format | $command | $formatted_command | $text_formatted | $item_cmd \n"; + my $indexterm = ''; +#print STDERR "FFFFFFFFFFFFFFFFf `$index_label' `$text'\n"; + if ($format =~ /^(v|f)/) + { +# my $index_prefix = $1; +# $indexterm = $text; +# $indexterm =~ s/^\s*//; +# $result .= "$formatted_index_entry"; + $result .= "$index_label"; + } + $result .= $text ."\n"; + return $result; +} + +sub xml_table_line($) +{ + my $text = shift; + my $only_inter_item_commands = shift; + my $before_items = shift; + + if ($text =~ /\S/) + { + return "$text" unless $only_inter_item_commands; + return $text; + } + else + { + return ''; + } +} + +sub xml_caption_shortcaption($) +{ + my $float = shift; + my $caption_lines; + my $shortcaption_lines; + if (defined($float->{'caption_texi'})) + { + @$caption_lines = @{$float->{'caption_texi'}}; + } + if (defined($float->{'shortcaption_texi'})) + { + @$shortcaption_lines = @{$float->{'shortcaption_texi'}}; + } + return ($caption_lines, $shortcaption_lines); +} + +sub xml_caption_shortcaption_command($$$) +{ + my $command = shift; + my $text = shift; + my $texi_lines = shift; + my $float_element = shift; + + if ($text =~ /\S/) + { + return "<$command>$text"; + } + return ''; +} + +sub xml_float($$$$$) +{ + my $text = shift; + my $float = shift; + my $caption = shift; + my $shortcaption = shift; + + # FIXME don't use the texi, but a normalized node name + my $label_texi = $float->{'texi'}; + $label_texi = '' if (!defined($label_texi)); + my $result = "\n"; + my $style = $float->{'style'}; + $style = '' if (!defined($style)); + $result .= "$style\n"; + $result .= "\n"; + $result .= $text; + return $result."\n"; +} + +sub xml_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; +#print STDERR "Bug: in_raw_text in_simple $text\n" if ($in_raw_text and $in_simple); + my $style_stack = shift; + my $state = shift; + + $text = &$protect_text($text) unless($in_raw_text); + + if (! $in_code and !$in_preformatted and !$in_raw_text) + { + $text =~ s/---/\&mdash\;/g; + $text =~ s/--/\&ndash\;/g; + $text =~ s/``/\&ldquo\;/g; + $text =~ s/''/\&rdquo\;/g; + } + return $text; +} + +sub xml_paragraph_style_command($$) +{ + my $format = shift; + my $text = shift; + return "<$format>$text" if ($format eq 'center'); + return $text; +} + +sub xml_raw($$) +{ + my $style = shift; + my $text = shift; + + if ($style eq 'verbatim' or $style eq 'verbatiminclude') + { + return '' . &$protect_text($text) . ''; + } + return '' unless (grep {$style eq $_} @EXPAND); + if ($style eq 'xml') + { + chomp ($text); + return $text; + } + else + { + main::msg_warn ("Raw style $style not handled", $Texi2HTML::THISDOC{'line_nr'}); + return &$protect_text($text); + } +} + +sub xml_cartouche($$) +{ + my $text = shift; + + return "$text"; +} + +sub xml_noop +{ + return ''; +} + +1; + +require "$T2H_HOME/formats/xml.init" + if ($0 =~ /\.pl$/ && + -e "$T2H_HOME/formats/xml.init" && -r "$T2H_HOME/formats/xml.init"); + +# @INIT_PLAINTEXT@ +#+############################################################################## +# +# plaintext.init: convert to plaintext +# +# Copyright (C) 2009 Patrice Dumas +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA +# +#-############################################################################## + +use strict; + +sub plaintext_default_load(;$) +{ +my $from_command_line = shift; +info_default_load(); + +$SHOW_MENU = 0; +$OUT = '-' unless(defined($OUT) and $OUT !~ m:/$:); +$HEADERS = 0; +@T2H_FORMAT_EXPAND = ('plaintext'); + +$print_page_head = \&plaintext_default_print_page_head; +$print_page_foot = \&plaintest_default_print_page_foot; +$element_heading = \&plaintext_default_element_heading; +$image = \&plaintext_default_image; +$print_index = \&plaintext_default_print_index; + +} + +sub plaintext_default_print_page_head($) +{ + my $fh = shift; +} + +sub plaintest_default_print_page_foot($) +{ + my $fh = shift; +} + +sub plaintext_default_element_heading($$$$$$$$$$$$) +{ + my $info_result = &Texi2HTML::Config::info_default_element_heading(@_); + my $element = shift; + my $command = shift; + my $texi_line = shift; + my $line = shift; + my $in_preformatted = shift; + my $one_section = shift; + my $element_heading = shift; + my $first_in_page = shift; + my $is_top = shift; + my $previous_is_top = shift; + my $command_line = shift; + my $element_id = shift; + my $new_element = shift; + + return $info_result if (!$element->{'node'}); + return ''; +} + +sub plaintext_default_image($$$$$$$$$$$$$$$$$) +{ + my $file = shift; + my $base = shift; + my $preformatted = shift; + my $file_name = shift; + my $alt = shift; + my $width = shift; + my $height = shift; + my $raw_alt = shift; + my $extension = shift; + my $working_dir = shift; + my $file_path = shift; + my $in_paragraph = shift; + my $file_locations = shift; + my $base_simple_format = shift; + my $extension_simple_format = shift; + my $file_name_simple_format = shift; + my $line_nr = shift; + + my $txt_path; + my $found_file; + + my @extensions = @IMAGE_EXTENSIONS; + if (defined($extension) and ($extension ne '')) + { + unshift @extensions, ".$extension"; + unshift @extensions, "$extension"; + } + else + { + $extension = undef; + } + my $file_found_index = undef; + my $file_index = 0; + + foreach my $file_location (@$file_locations) + { + my ($file_located, $path, $file_simple_format) = @$file_location; + my $extension = shift @extensions; + if (defined($path)) + { + if ($extension eq 'txt' and !defined($txt_path)) + { + $txt_path = $path; + } + elsif (!defined($found_file)) + { + $found_file = [$file_located, $extension, $file_simple_format]; + $file_found_index = $file_index; + } + } + $file_index++; + } + + my $text = ''; + if (defined($txt_path)) + { + if (open(TXT, "<$txt_path")) + { + if (defined($Texi2HTML::THISDOC{'IN_ENCODING'}) and $USE_UNICODE) + { + binmode(TXT, ":encoding($Texi2HTML::THISDOC{'IN_ENCODING'})"); + } + $text='[' if ($in_paragraph or $preformatted); + while (my $img_txt = ) + { + $text .= $img_txt; + } + $text .= ']' if ($in_paragraph or $preformatted); + close(TXT); + } + else + { + main::line_warn (sprintf(__("\@image file `%s' unreadable: %s"), $txt_path, $!), $line_nr); + } + } + elsif (!defined($found_file)) + { + main::line_warn (sprintf(__("Cannot find \@image file `%s.txt'"), $base), $line_nr); + } + return $text; +} + +sub plaintext_default_print_index($$) +{ + my $text = shift; + my $name = shift; + return ''; +} + +1; + +require "$T2H_HOME/formats/plaintext.init" + if ($0 =~ /\.pl$/ && + -e "$T2H_HOME/formats/plaintext.init" && -r "$T2H_HOME/formats/plaintext.init"); + +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@ +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'nl'} = { + ' The buttons in the navigation panels have the following meaning:' => '', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '', + ' Up ' => '', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => '', + 'About (help)' => '', + 'About This Document' => 'No translation available!', + 'April' => 'April', + 'August' => 'Augustus', + 'Back' => '', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => '', + 'Button' => '', + 'Contents' => '', + 'Cover (top) of document' => '', + 'Current' => '', + 'Current Position' => '', + 'Current section' => '', + 'December' => 'December', + 'FastBack' => '', + 'FastForward' => '', + 'February' => 'Februari', + 'First' => '', + 'First section in reading order' => '', + 'Following' => '', + 'Following node' => '', + 'Footnotes' => 'No translation available!', + 'Forward' => '', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => '', + 'Go to' => '', + 'Index' => 'Index', + 'Index Entry' => '', + 'January' => 'Januari', + 'July' => 'Juli', + 'Jump to' => '', + 'June' => 'Juni', + 'Last' => '', + 'Last section in reading order' => '', + 'March' => 'Maart', + 'May' => 'Mei', + 'Menu:' => '', + 'Name' => '', + 'Next' => '', + 'Next chapter' => '', + 'Next file' => '', + 'Next node' => '', + 'Next section in reading order' => '', + 'Next section on same level' => '', + 'NextFile' => '', + 'Node following in node reading order' => '', + 'Node up' => '', + 'NodeNext' => '', + 'NodePrev' => '', + 'NodeUp' => '', + 'November' => 'November', + 'October' => 'Oktober', + 'Overview' => '', + 'Prev' => '', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => '', + 'Previous node' => '', + 'Previous section in reading order' => '', + 'Previous section on same level' => '', + 'Section' => '', + 'Section One' => '', + 'See ' => '', + 'See @cite{{book}}' => '', + 'See `{section}\'' => '', + 'See `{section}\' in @cite{{book}}' => '', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => '', + 'See {reference_name}' => '', + 'See {reference}' => '', + 'See {reference} in @cite{{book}}' => '', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => 'September', + 'Short Table of Contents' => 'Korte inhoudsopgave', + 'Short table of contents' => '', + 'Subsection One-Four' => '', + 'Subsection One-One' => '', + 'Subsection One-Three' => '', + 'Subsection One-Two' => '', + 'Subsubsection One-Two-Four' => '', + 'Subsubsection One-Two-One' => '', + 'Subsubsection One-Two-Three' => '', + 'Subsubsection One-Two-Two' => '', + 'Table of Contents' => 'Inhoudsopgave', + 'Table of contents' => '', + 'The node you are looking for is at {href}.' => '', + 'This' => '', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => '', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => '', + 'Top' => '', + 'Untitled Document' => '', + 'Up' => '', + 'Up node' => '', + 'Up section' => '', + '`{section}\'' => '', + '`{section}\' in @cite{{book}}' => '', + 'current' => '', + 'on @emph{{date}}' => '', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => '', + 'see `{section}\'' => '', + 'see `{section}\' in @cite{{book}}' => '', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section {reference_name}' => '', + 'see {reference_name}' => '', + 'see {reference}' => '', + 'see {reference} in @cite{{book}}' => '', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => '', + '{name} of {class}' => '', + '{name} on {class}' => '', + '{reference_name}' => '', + '{reference}' => '', + '{reference} in @cite{{book}}' => '', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'ja'} = { + ' The buttons in the navigation panels have the following meaning:' => 'ナビゲーションパネル中のボタンには以下の意味があります。', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '@strong{例}では、以下に示す構造を持つ文書の@strong{1.2.3項}を現在位置に仮定しています。', + ' Up ' => '上', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => '', + 'About (help)' => '', + 'About This Document' => 'この文書について', + 'April' => '4月', + 'August' => '8月', + 'Back' => '', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => '', + 'Button' => 'ボタン', + 'Contents' => '目次', + 'Cover (top) of document' => '', + 'Current' => '', + 'Current Position' => '現在位置', + 'Current section' => '', + 'December' => '12月', + 'FastBack' => '', + 'FastForward' => '', + 'February' => '2月', + 'First' => '', + 'First section in reading order' => '', + 'Following' => '', + 'Following node' => '', + 'Footnotes' => '脚注', + 'Forward' => '', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => '1.2.3項からの移動先', + 'Go to' => '移動先', + 'Index' => '見出し', + 'Index Entry' => '見出し一覧', + 'January' => '1月', + 'July' => '7月', + 'Jump to' => '移動', + 'June' => '6月', + 'Last' => '', + 'Last section in reading order' => '', + 'March' => '3月', + 'May' => '5月', + 'Menu:' => 'メニュー', + 'Name' => '名称', + 'Next' => '次', + 'Next chapter' => '', + 'Next file' => '', + 'Next node' => '', + 'Next section in reading order' => '', + 'Next section on same level' => '', + 'NextFile' => '', + 'Node following in node reading order' => '', + 'Node up' => '', + 'NodeNext' => '', + 'NodePrev' => '', + 'NodeUp' => '', + 'November' => '11月', + 'October' => '10月', + 'Overview' => '概要', + 'Prev' => '前', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => '', + 'Previous node' => '', + 'Previous section in reading order' => '', + 'Previous section on same level' => '', + 'Section' => '項', + 'Section One' => '第1項', + 'See ' => '', + 'See @cite{{book}}' => '', + 'See `{section}\'' => '項', + 'See `{section}\' in @cite{{book}}' => '@cite{{book}}の `{section}\' ', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => '', + 'See {reference_name}' => '', + 'See {reference}' => '', + 'See {reference} in @cite{{book}}' => '{node_file_href} @cite{{book}}参照', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => '9月', + 'Short Table of Contents' => '簡略化した目次', + 'Short table of contents' => '', + 'Subsection One-Four' => '第1.4項', + 'Subsection One-One' => '第1.1項', + 'Subsection One-Three' => '第1.3項', + 'Subsection One-Two' => '第1.2項', + 'Subsubsection One-Two-Four' => '第1.2.4項', + 'Subsubsection One-Two-One' => '第1.2.1項', + 'Subsubsection One-Two-Three' => '第1.2.3項', + 'Subsubsection One-Two-Two' => '第1.2.2項', + 'Table of Contents' => '目次', + 'Table of contents' => '', + 'The node you are looking for is at {href}.' => '', + 'This' => '', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'この文書は@emph{{date}}に@uref{{program_homepage}, @emph{{program}}}を用いて生成されました。', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'この文書は@uref{{program_homepage}, @emph{{program}}}を用いて生成されました。', + 'Top' => '冒頭', + 'Untitled Document' => '無題の文書', + 'Up' => '', + 'Up node' => '', + 'Up section' => '', + '`{section}\'' => '項', + '`{section}\' in @cite{{book}}' => '@cite{{book}}の `{section}\' ', + 'current' => '現在位置', + 'on @emph{{date}}' => '@emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => '', + 'see `{section}\'' => '', + 'see `{section}\' in @cite{{book}}' => '@cite{{book}}の `{section}\' ', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section {reference_name}' => '', + 'see {reference_name}' => '', + 'see {reference}' => '{node_file_href}参照', + 'see {reference} in @cite{{book}}' => '{node_file_href} @cite{{book}}参照', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => '', + '{name} of {class}' => '', + '{name} on {class}' => '', + '{reference_name}' => '', + '{reference}' => '', + '{reference} in @cite{{book}}' => '{node_file_href} @cite{{book}}参照', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'fr'} = { + ' The buttons in the navigation panels have the following meaning:' => ' Les boutons de navigation ont la signification suivante :', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' Dans cet exemple on est @`a @strong{ Sous sous section un-deux-trois } dans un document dont la structure est :', + ' Up ' => 'Plus haut', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => 'A propos', + 'About (help)' => 'A propos (page d\'aide)', + 'About This Document' => 'A propos de ce document', + 'April' => 'avril', + 'August' => 'ao@^ut', + 'Back' => 'Retour', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => 'D@\'ebut de ce chapitre ou chapitre pr@\'ec@\'edent', + 'Button' => 'Bouton', + 'Contents' => 'Table des mati@`eres', + 'Cover (top) of document' => 'Couverture (top) du document', + 'Current' => '', + 'Current Position' => 'Position', + 'Current section' => 'Section actuelle', + 'December' => 'd@\'ecembre', + 'FastBack' => 'RetourRapide', + 'FastForward' => 'AvanceRapide', + 'February' => 'f@\'evrier', + 'First' => 'Premier', + 'First section in reading order' => 'Premi@`e section dans l\'ordre de lecture', + 'Following' => 'Suivant', + 'Following node' => 'N@oe{}ud suivant', + 'Footnotes' => 'Notes de bas de page', + 'Forward' => 'Avant', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => 'Depuis 1.2.3 aller @`a', + 'Go to' => 'Aller @`a', + 'Index' => 'Index', + 'Index Entry' => 'Entr@\'ee d\'index', + 'January' => 'janvier', + 'July' => 'juillet', + 'Jump to' => 'Aller @`a', + 'June' => 'juin', + 'Last' => 'Dernier', + 'Last section in reading order' => 'Derni@`ere section dans l\'ordre de lecture', + 'March' => 'mars', + 'May' => 'mai', + 'Menu:' => 'Menu@ :', + 'Name' => 'Nom', + 'Next' => 'Suivant', + 'Next chapter' => 'Chapitre suivant', + 'Next file' => 'Fichier suivant', + 'Next node' => 'N@oe{}ud suivant', + 'Next section in reading order' => 'Section suivante dans l\'ordre de lecture', + 'Next section on same level' => 'Section suivante au m@^eme niveau', + 'NextFile' => 'FichierSuivant', + 'Node following in node reading order' => 'N@oe{}ud suivant dans l\'ordre de lecture', + 'Node up' => 'N@oe{}ud au dessus', + 'NodeNext' => 'N@oe{}udSuivant', + 'NodePrev' => 'N@oe{}udPr@\'ec@\'edent', + 'NodeUp' => 'N@oe{}udMonter', + 'November' => 'novembre', + 'October' => 'octobre', + 'Overview' => 'Vue d\'ensemble', + 'Prev' => 'Pr@\'ec@\'edent', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => 'Fichier pr@\'ec@\'edent', + 'Previous node' => 'N@oe{}ud pr@\'ec@\'edent', + 'Previous section in reading order' => 'Section pr@\'ec@\'edente dans l\'ordre de lecture', + 'Previous section on same level' => 'Section pr@\'ec@\'edente au m@^eme niveau', + 'Section' => '', + 'Section One' => 'Section un', + 'See ' => '', + 'See @cite{{book}}' => 'Voir @cite{{book}}', + 'See `{section}\'' => 'Section sup@\'erieure', + 'See `{section}\' in @cite{{book}}' => 'Voir la section `{section}\' dans @cite{{book}}', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => 'Voir la section {reference_name}', + 'See {node_file_href}' => 'Voir {node_file_href}', + 'See {node_file_href} section `{section}\' in @cite{{book}}' => 'Voir {node_file_href} section `{section}\' dans @cite{{book}}', + 'See {reference_name}' => 'Voir {reference_name}', + 'See {reference}' => 'Voir {reference_name}', + 'See {reference} in @cite{{book}}' => 'Voir {node_file_href} @cite{{book}}', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => 'septembre', + 'Short Table of Contents' => 'R@\'esum@\'e du contenu', + 'Short table of contents' => 'R@\'esum@\'e du contenu', + 'Subsection One-Four' => 'Sous section un-quatre', + 'Subsection One-One' => 'Sous section un-un', + 'Subsection One-Three' => 'Sous section un-trois', + 'Subsection One-Two' => 'Sous section un-deux', + 'Subsubsection One-Two-Four' => 'Sous sous section un-deux-quatre', + 'Subsubsection One-Two-One' => 'Sous sous section un-deux-un', + 'Subsubsection One-Two-Three' => 'Sous sous section un-deux-trois', + 'Subsubsection One-Two-Two' => 'Sous sous section un-deux-deux', + 'Table of Contents' => 'Table des mati@`eres', + 'Table of contents' => 'Table des mati@`eres', + 'The node you are looking for is at {href}.' => 'Le n@oe{}ud que vous recherchez est ici@ : {href}.', + 'This' => 'Ici', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e le @emph{{date}} en utilisant @uref{{program_homepage}, @emph{{program}}}', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e en utilisant @uref{{program_homepage}, @emph{{program}}}.', + 'Top' => 'Racine', + 'Untitled Document' => 'Document sans titre', + 'Up' => 'Monter', + 'Up node' => 'N@oe{}ud au dessus', + 'Up section' => 'Section sup@\'erieure', + '`{section}\'' => 'Section sup@\'erieure', + '`{section}\' in @cite{{book}}' => 'section `{section}\' dans @cite{{book}}', + 'current' => 'courante', + 'on @emph{{date}}' => 'le @emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => 'voir @cite{{book}}', + 'see `{section}\'' => 'Section sup@\'erieure', + 'see `{section}\' in @cite{{book}}' => 'section `{section}\' dans @cite{{book}}', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section `{section}\' in @cite{{book}}' => 'voir la section `{section}\' dans @cite{{book}}', + 'see section {reference_name}' => 'voir la section {reference_name}', + 'see {node_file_href}' => 'voir {node_file_href}', + 'see {node_file_href} section `{section}\' in @cite{{book}}' => 'voir {node_file_href} section `{section}\' dans @cite{{book}}', + 'see {reference_name}' => 'voir {reference_name}', + 'see {reference}' => 'voir {reference_name}', + 'see {reference} in @cite{{book}}' => 'voir {node_file_href} @cite{{book}}', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => 'le {day} {month} {year}', + '{name} of {class}' => '{name} de {class}', + '{name} on {class}' => '{name} de {class}', + '{node_file_href} section `{section}\' in @cite{{book}}' => '{node_file_href} section `{section}\' dans @cite{{book}}', + '{reference_name}' => '', + '{reference}' => 'voir {reference_name}', + '{reference} in @cite{{book}}' => 'voir @cite{{book}}', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'de'} = { + ' The buttons in the navigation panels have the following meaning:' => ' Die Links in der Navigationsleiste haben die folgende Bedeutung: ', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' wobei das @strong{ Beispiel } annimmt, dass die aktuelle Position bei @strong{ Unterabschnitt 1-2-3 } in einem Dokument mit folgender Struktur liegt:', + ' Up ' => ' Nach oben ', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '@b{{quotation_arg}:} ', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '@cite{{book}}', + '@{No value for `{value}\'@}' => '', + 'About' => '@"Uber', + 'About (help)' => '@"Uber (Hilfe)', + 'About This Document' => '@"Uber dieses Dokument', + 'April' => 'April', + 'August' => 'August', + 'Back' => 'Zur@"uck', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => 'Anfang dieses oder des letzten Kapitels', + 'Button' => '', + 'Contents' => 'Inhalt', + 'Cover (top) of document' => 'Titelseite des Dokuments', + 'Current' => '', + 'Current Position' => 'Aktuelle Position', + 'Current section' => 'Aktueller Abschnitt', + 'December' => 'Dezember', + 'FastBack' => '', + 'FastForward' => '', + 'February' => 'Februar', + 'First' => '', + 'First section in reading order' => 'Erster Abschnitt in Lesereihenfolge', + 'Following' => '', + 'Following node' => 'N@"achster Knoten', + 'Footnotes' => 'Fu@ss{}noten', + 'Forward' => 'Nach vorne', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => 'Von 1.2.3 gehe zu', + 'Go to' => 'Gehe zu', + 'Index' => 'Index', + 'Index Entry' => 'Indexeintrag', + 'January' => 'Januar', + 'July' => 'Juli', + 'Jump to' => 'Springe zu', + 'June' => 'Juni', + 'Last' => '', + 'Last section in reading order' => 'Letzter Abschnitt in Lesereihenfolge', + 'March' => 'M@"arz', + 'May' => 'Mai', + 'Menu:' => 'Auswahl:', + 'Name' => 'Name', + 'Next' => '', + 'Next chapter' => 'N@"achstes Kapitel', + 'Next file' => '', + 'Next node' => 'N@"achster Knoten', + 'Next section in reading order' => 'N@"achster Abschnitt in Lesereihenfolge', + 'Next section on same level' => 'N@"achster Abschitt derselben Ebene', + 'NextFile' => '', + 'Node following in node reading order' => 'N@"achster Abschnitt in Lesereihenfolge', + 'Node up' => 'Knoten nach oben', + 'NodeNext' => '', + 'NodePrev' => '', + 'NodeUp' => '', + 'November' => 'November', + 'October' => 'Oktober', + 'Overview' => '@"Ubersicht', + 'Prev' => '', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => '', + 'Previous node' => 'Voriger Knoten', + 'Previous section in reading order' => 'Voriger Abschnitt in Lesereihenfolge', + 'Previous section on same level' => 'Voriger Abschnitt derselben Ebene', + 'Section' => 'Abschnitt', + 'Section One' => 'Abschnitt 1', + 'See ' => '', + 'See @cite{{book}}' => '', + 'See `{section}\'' => 'Abschnitt nach oben', + 'See `{section}\' in @cite{{book}}' => 'Siehe Abschnitt `{section}\' in @cite{{book}}', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => '', + 'See {node_file_href}' => 'Siehe {node_file_href}', + 'See {node_file_href} section `{section}\' in @cite{{book}}' => 'Siehe {node_file_href} in Abschnitt `{section}\' in @cite{{book}}', + 'See {reference_name}' => '', + 'See {reference}' => 'siehe {reference_name}', + 'See {reference} in @cite{{book}}' => 'Siehe {node_file_href} @cite{{book}}', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => 'September', + 'Short Table of Contents' => 'Kurzes Inhaltsverzeichnis', + 'Short table of contents' => 'Kurzes Inhaltsverzeichnis', + 'Subsection One-Four' => 'Unterabschnitt 1-4', + 'Subsection One-One' => 'Unterabschnitt 1-1', + 'Subsection One-Three' => 'Unterabschnitt 1-3', + 'Subsection One-Two' => 'Unterabschnitt 1-2', + 'Subsubsection One-Two-Four' => 'Unterabschnitt 1-2-4', + 'Subsubsection One-Two-One' => 'Unterabschnitt 1-2-1', + 'Subsubsection One-Two-Three' => 'Unterabschnitt 1-2-3', + 'Subsubsection One-Two-Two' => 'Unterabschnitt 1-2-2', + 'Table of Contents' => 'Inhaltsverzeichnis', + 'Table of contents' => 'Inhaltsverzeichnis', + 'The node you are looking for is at {href}.' => 'Der Knoten, den Sie sehen, befindet sich bei {href}', + 'This' => '', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'Dieses Dokument wurde erzeugt am @i{{date}} durch @uref{{program_homepage}, @i{{program}}}.', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'Dieses Dokument wurde erzeugt durch @uref{{program_homepage}, @emph{{program}}}.', + 'Top' => 'Anfang', + 'Untitled Document' => 'Unbenanntes Dokumen', + 'Up' => 'Nach oben', + 'Up node' => 'Knoten nach oben', + 'Up section' => 'Abschnitt nach oben', + '`{section}\'' => 'Abschnitt nach oben', + '`{section}\' in @cite{{book}}' => 'Abschnitt `{section}\' in @cite{{book}}', + 'current' => '', + 'on @emph{{date}}' => 'am @emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => 'siehe @cite{{book}}', + 'see `{section}\'' => 'Abschnitt nach oben', + 'see `{section}\' in @cite{{book}}' => 'Abschnitt `{section}\' in @cite{{book}}', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section `{section}\' in @cite{{book}}' => 'siehe Abschnitt `{section}\' in @cite{{book}}', + 'see section {reference_name}' => 'siehe Abschnitt {reference_name}', + 'see {node_file_href}' => 'siehe {node_file_href}', + 'see {node_file_href} section `{section}\' in @cite{{book}}' => 'siehe {node_file_href} im Abschnitt `{section}\' in @cite{{book}}', + 'see {reference_name}' => 'siehe {reference_name}', + 'see {reference}' => 'siehe {reference_name}', + 'see {reference} in @cite{{book}}' => 'siehe {node_file_href} @cite{{book}}', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '{acronym_like} ({explanation})', + '{month} {day}, {year}' => '{day}. {month} {year}', + '{name} of {class}' => '', + '{name} on {class}' => '', + '{node_file_href} section `{section}\' in @cite{{book}}' => '{node_file_href} in Abschnitt `{section}\' in @cite{{book}}', + '{reference_name}' => '{reference_name}', + '{reference}' => '{reference_name}', + '{reference} in @cite{{book}}' => 'siehe @cite{{book}}', + '{ref}' => '', + '{style} {number}' => '{style} {number}', + '{style}: {caption_first_line}' => '{style}: {caption_first_line}', + '{style}: {shortcaption_first_line}' => '{style}: {shortcaption_first_line}', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'pt'} = { + ' The buttons in the navigation panels have the following meaning:' => ' Os bot@~oes nos pain@\'eis de navega@,{c}@~ao possuem os seguintes significados:', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' onde o @strong{ Exemplo } assume que a posi@,{c}@~ao atual localiza-se em @strong{ Subsub@,{c}@~ao Um-Dois-Tr@^es } de um documento com a seguinte estrutura:', + ' Up ' => ' Acima ', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => 'Sobre', + 'About (help)' => 'Sobre (ajuda)', + 'About This Document' => 'Sobre Esse Documento', + 'April' => 'Abril', + 'August' => 'Agosto', + 'Back' => 'Volta', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => 'Come@,{c}o desse cap@\'itulo ou cap@\'itulo anterior', + 'Button' => 'Bot@~ao', + 'Contents' => 'Conte@\'udo', + 'Cover (top) of document' => 'In@\'icio (topo) do documento', + 'Current' => '', + 'Current Position' => 'Posi@,{c}@~ao Atual', + 'Current section' => 'Se@,{c}@~ao atual', + 'December' => 'Dezembro', + 'FastBack' => 'Voltar R@\'apido', + 'FastForward' => 'Avan@,{c}ar R@\'apido', + 'February' => 'Fevereiro', + 'First' => 'Primeiro', + 'First section in reading order' => 'Primeira se@,{c}@~ao na ordem de leitura', + 'Following' => 'Seguinte', + 'Following node' => 'Nodo seguinte', + 'Footnotes' => 'Notas de Rodap@\'e', + 'Forward' => 'Avan@,{c}ar', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => 'De 1.2.3 v@\'a para', + 'Go to' => 'V@\'a para', + 'Index' => '@\'Indice', + 'Index Entry' => 'Entrada de @\'Indice', + 'January' => 'Janeiro', + 'July' => 'Julho', + 'Jump to' => 'Pular para', + 'June' => 'Junho', + 'Last' => '@\'Ultimo', + 'Last section in reading order' => '@\'Ultima se@,{c}@~ao na ordem de leitura', + 'March' => 'Mar@,{c}o', + 'May' => 'Maio', + 'Menu:' => '', + 'Name' => 'Nome', + 'Next' => 'Pr@\'oximo', + 'Next chapter' => 'Pr@\'oximo cap@\'itulo', + 'Next file' => '', + 'Next node' => 'Pr@\'oximo nodo', + 'Next section in reading order' => 'Pr@\'oxima se@,{c}@~ao na ordem de leitura', + 'Next section on same level' => 'Pr@\'oxima se@,{c}@~ao no mesmo n@\'ivel', + 'NextFile' => '', + 'Node following in node reading order' => 'Nodo seguinte na ordem de leitura de nodos', + 'Node up' => 'Nodo acima', + 'NodeNext' => 'Pr@\'oximo Nodo', + 'NodePrev' => 'Nodo Anterior', + 'NodeUp' => 'Nodo Acima', + 'November' => 'Novembro', + 'October' => 'Outubro', + 'Overview' => 'Vis@~ao geral', + 'Prev' => 'Pr@\'evio', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => '', + 'Previous node' => 'Nodo anterior', + 'Previous section in reading order' => 'Se@,{c}@~ao anterior na ordem de leitura', + 'Previous section on same level' => 'Se@,{c}@~ao anterior no mesmo n@\'ivel', + 'Section' => 'Se@,{c}@~ao', + 'Section One' => 'Se@,{c}@~ao Um', + 'See ' => '', + 'See @cite{{book}}' => 'Veja @cite{{book}}', + 'See `{section}\'' => 'Se@,{c}@~ao acima', + 'See `{section}\' in @cite{{book}}' => 'Veja se@,{c}@~ao `{section}\' em @cite{{book}}', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => 'Veja se@,{c}@~ao {reference_name}', + 'See {node_file_href}' => 'Veja {node_file_href}', + 'See {node_file_href} section `{section}\' in @cite{{book}}' => 'Veja {node_file_href} se@,{c}@~ao `{section}\' em @cite{{book}}', + 'See {reference_name}' => 'Veja {reference_name}', + 'See {reference}' => 'Veja {reference_name}', + 'See {reference} in @cite{{book}}' => 'Veja {node_file_href} @cite{{book}}', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => 'Setembro', + 'Short Table of Contents' => 'Breve Sum@\'ario', + 'Short table of contents' => 'Breve sum@\'ario', + 'Subsection One-Four' => 'Subse@,{c}@~ao Um-Quatro', + 'Subsection One-One' => 'Subse@,{c}@~ao Um-Um', + 'Subsection One-Three' => 'Subse@,{c}@~ao Um-Tr@^es', + 'Subsection One-Two' => 'Subse@,{c}@~ao Um-Dois', + 'Subsubsection One-Two-Four' => 'Subse@,{c}@~ao Um-Dois-Quatro', + 'Subsubsection One-Two-One' => 'Subse@,{c}@~ao Um-Dois-Um', + 'Subsubsection One-Two-Three' => 'Subse@,{c}@~ao Um-Dois-Tr@^es', + 'Subsubsection One-Two-Two' => 'Subse@,{c}@~ao Um-Dois-Dois', + 'Table of Contents' => 'Sum@\'ario', + 'Table of contents' => 'Sum@\'ario', + 'The node you are looking for is at {href}.' => 'O nodo que vo@^e est@\'a olhando est@\'a em {href}.', + 'This' => 'Esse', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'Esse documento foi gerado em @i{{date}} usando @uref{{program_homepage}, @i{{program}}}.', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'Esse documento foi gerado usando @uref{{program_homepage}, @emph{{program}}}.', + 'Top' => 'Topo', + 'Untitled Document' => 'Documento Sem Nome', + 'Up' => 'Acima', + 'Up node' => 'Nodo acima', + 'Up section' => 'Se@,{c}@~ao acima', + '`{section}\'' => 'Se@,{c}@~ao acima', + '`{section}\' in @cite{{book}}' => 'se@,{c}@~ao `{section}\' em @cite{{book}}', + 'current' => 'atual', + 'on @emph{{date}}' => 'em @emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => 'veja @cite{{book}}', + 'see `{section}\'' => 'Se@,{c}@~ao acima', + 'see `{section}\' in @cite{{book}}' => 'se@,{c}@~ao `{section}\' em @cite{{book}}', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section `{section}\' in @cite{{book}}' => 'veja se@,{c}@~ao `{section}\' em @cite{{book}}', + 'see section {reference_name}' => 'veja se@,{c}@~ao {reference_name}', + 'see {node_file_href}' => 'veja {node_file_href}', + 'see {node_file_href} section `{section}\' in @cite{{book}}' => 'veja {node_file_href} se@,{c}@~ao `{section}\' em @cite{{book}}', + 'see {reference_name}' => 'veja {reference_name}', + 'see {reference}' => 'veja {reference_name}', + 'see {reference} in @cite{{book}}' => 'veja {node_file_href} @cite{{book}}', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => '{day} de {month} de {year}', + '{name} of {class}' => '{name} da {class}', + '{name} on {class}' => '{name} na {class}', + '{node_file_href} section `{section}\' in @cite{{book}}' => '{node_file_href} se@,{c}@~ao `{section}\' em @cite{{book}}', + '{reference_name}' => '', + '{reference}' => 'veja {reference_name}', + '{reference} in @cite{{book}}' => 'veja @cite{{book}}', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'hu'} = { + ' The buttons in the navigation panels have the following meaning:' => ' A navigációs panelen levő gombok jelentése a következő:', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' @strong{ Példánkban } az aktuális pozíció az @strong{ 1.2.3 alalszakasz } egy olyan dokumentumban, melynek szerkezete a következő:', + ' Up ' => 'Fel', + '(outside of any element)' => '(bármelyik elemen kívül)', + '(outside of any node)' => '(bármelyik csomóponton kívül)', + '@b{{quotation_arg}:} ' => '@b{{quotation_arg}:} ', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '@cite{{book}}', + '@{No value for `{value}\'@}' => '@{Nincs értéke ennek: `{value}\'@}', + 'About' => 'Súgó', + 'About (help)' => 'Segítség a navigációhoz', + 'About This Document' => 'A navigációs panel használata', + 'April' => 'április', + 'August' => 'augusztus', + 'Back' => 'Vissza', + 'Back section in previous file' => 'Előző fájl hátsó szakasza', + 'Beginning of this chapter or previous chapter' => 'Fejezet eleje vagy előző fejezet', + 'Button' => 'Gomb', + 'Contents' => 'Tartalom', + 'Cover (top) of document' => 'Dokumentum címoldala', + 'Current' => 'Aktuális', + 'Current Position' => 'Aktuális pozíció', + 'Current section' => 'Aktuális szakasz', + 'December' => 'december', + 'FastBack' => 'Visszaugrás', + 'FastForward' => 'Előreugrás', + 'February' => 'február', + 'First' => 'Első', + 'First section in reading order' => 'Első szakasz az olvasási sorrendben', + 'Following' => 'Következő', + 'Following node' => 'Következő csomópont', + 'Footnotes' => 'Lábjegyzet', + 'Forward' => 'Előre', + 'Forward section in next file' => 'Következő fájl elülső szakasza', + 'From 1.2.3 go to' => '1.2.3-ból ide jutunk', + 'Go to' => 'Cél', + 'Index' => 'Tárgymutató', + 'Index Entry' => 'Tárgymutató-bejegyzés', + 'January' => 'január', + 'July' => 'július', + 'Jump to' => 'Ugorj ide', + 'June' => 'június', + 'Last' => 'Utolsó', + 'Last section in reading order' => 'Utolsó szakasz az olvasási sorrendben', + 'March' => 'március', + 'May' => 'május', + 'Menu:' => 'Menü:', + 'Name' => 'Név', + 'Next' => 'Következő', + 'Next chapter' => 'Következő fejezet', + 'Next file' => 'Következő fájl', + 'Next node' => 'Következő csomópont', + 'Next section in reading order' => 'Következő szakasz az olvasási sorrendben', + 'Next section on same level' => 'Következő szakasz ugyanazon a szinten', + 'NextFile' => 'KövetkezőFájl', + 'Node following in node reading order' => 'Következő csomópont az olvasási sorrendben', + 'Node up' => 'Szülő csomópont', + 'NodeNext' => 'KövetkezőCsomópont', + 'NodePrev' => 'ElőzőCsomópont', + 'NodeUp' => 'SzülőCsomópont', + 'November' => 'november', + 'October' => 'október', + 'Overview' => 'Áttekintés', + 'Prev' => 'Előző', + 'PrevFile' => 'ElőzőFájl', + 'Previous' => 'Előző', + 'Previous file' => 'Előző fájl', + 'Previous node' => 'Előző csomópont', + 'Previous section in reading order' => 'Előző szakasz az olvasási sorrendben', + 'Previous section on same level' => 'Előző szakasz ugyanazon a szinten', + 'Section' => 'Szakasz', + 'Section One' => 'szakasz', + 'See ' => 'Ld. ', + 'See @cite{{book}}' => 'Ld. @cite{{book}}', + 'See `{section}\'' => 'Szülő szakasz', + 'See `{section}\' in @cite{{book}}' => 'Ld. ezt a szakaszt: `{section}\' itt: @cite{{book}}', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => 'Ld. ezt a szakaszt: `@asis{}`{section_name}\'@asis{}\' itt: @cite{{book}}', + 'See section {reference_name}' => 'Ld. ezt a szakaszt: {reference_name}', + 'See {node_file_href}' => 'Ld. {node_file_href}', + 'See {node_file_href} section `{section}\' in @cite{{book}}' => 'Ld. {node_file_href} ezt a szakaszt: `{section}\' itt: @cite{{book}}', + 'See {reference_name}' => 'Ld. {reference_name}', + 'See {reference}' => 'Ld. {reference_name}', + 'See {reference} in @cite{{book}}' => 'See {node_file_href} @cite{{book}}', + 'See {ref}' => 'Ld. {ref}', + 'See {title_ref}' => 'Ld. {title_ref}', + 'September' => 'szeptember', + 'Short Table of Contents' => 'Rövid tartalomjegyzék', + 'Short table of contents' => 'Rövid tartalomjegyzék', + 'Subsection One-Four' => 'alszakasz', + 'Subsection One-One' => 'alszakasz', + 'Subsection One-Three' => 'alszakasz', + 'Subsection One-Two' => 'alszakasz', + 'Subsubsection One-Two-Four' => 'alalszakasz', + 'Subsubsection One-Two-One' => 'alalszakasz', + 'Subsubsection One-Two-Three' => 'alalszakasz', + 'Subsubsection One-Two-Two' => 'alalszakasz', + 'Table of Contents' => 'Tartalomjegyzék', + 'Table of contents' => 'Tartalomjegyzék', + 'The node you are looking for is at {href}.' => 'A keresett csomópont itt található: {href}.', + 'This' => 'Ez a(z)', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'Ezt a dokumentumot @i{{date}} napon generálta a(z) @uref{{program_homepage}, @i{{program}}}.', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'Ezt a dokumentumot a(z) @uref{{program_homepage}, @emph{{program}}} generálta.', + 'Top' => 'Címoldal', + 'Untitled Document' => 'Névtelen dokumentum', + 'Up' => 'Fel', + 'Up node' => 'Szülő csomópont', + 'Up section' => 'Szülő szakasz', + '`{section}\'' => 'Szülő szakasz', + '`{section}\' in @cite{{book}}' => 'szakasz: `{section}\' itt: @cite{{book}}', + 'current' => 'aktuális', + 'on @emph{{date}}' => 'ekkor: @emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => 'szakasz: `@asis{}`{section_name}\'@asis{}\' itt: @cite{{book}}', + 'see ' => 'ld. ', + 'see @cite{{book}}' => 'ld. @cite{{book}}', + 'see `{section}\'' => 'Szülő szakasz', + 'see `{section}\' in @cite{{book}}' => 'szakasz: `{section}\' itt: @cite{{book}}', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => 'ld. ezt a szakaszt: `@asis{}`{section_name}\'@asis{}\' itt: @cite{{book}}', + 'see section `{section}\' in @cite{{book}}' => 'ld. ezt a szakaszt: `{section}\' itt: @cite{{book}}', + 'see section {reference_name}' => 'ld. ezt a szakaszt: {reference_name}', + 'see {node_file_href}' => 'ld. {node_file_href}', + 'see {node_file_href} section `{section}\' in @cite{{book}}' => 'ld. {node_file_href} ezt a szakaszt: `{section}\' itt: @cite{{book}}', + 'see {reference_name}' => 'ld. {reference_name}', + 'see {reference}' => 'ld. {reference_name}', + 'see {reference} in @cite{{book}}' => 'ld. {node_file_href} @cite{{book}}', + 'see {ref}' => 'ld. {ref}', + 'see {title_ref}' => 'ld. {title_ref}', + '{acronym_like} ({explanation})' => '{acronym_like} ({explanation})', + '{month} {day}, {year}' => '', + '{name} of {class}' => '{name} típusa: {class}', + '{name} on {class}' => '{name} ezen: {class}', + '{node_file_href}' => '{node_file_href}', + '{node_file_href} section `{section}\' in @cite{{book}}' => '{node_file_href} szakasz: `{section}\' itt: @cite{{book}}', + '{reference_name}' => '{reference_name}', + '{reference}' => '{reference_name}', + '{reference} in @cite{{book}}' => '{node_file_href} @cite{{book}}', + '{ref}' => '{ref}', + '{style} {number}' => '{style} {number}', + '{style}: {caption_first_line}' => '{style}: {caption_first_line}', + '{style}: {shortcaption_first_line}' => '{style}: {shortcaption_first_line}', + '{title_ref}' => '{title_ref}' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'pt_BR'} = { + ' The buttons in the navigation panels have the following meaning:' => ' Os bot@~oes nos pain@\'eis de navega@,{c}@~ao possuem os seguintes significados:', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' onde o @strong{ Exemplo } assume que a posi@,{c}@~ao atual localiza-se em @strong{ Subsub@,{c}@~ao Um-Dois-Tr@^es } de um documento com a seguinte estrutura:', + ' Up ' => ' Acima ', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => 'Sobre', + 'About (help)' => 'Sobre (ajuda)', + 'About This Document' => 'Sobre Esse Documento', + 'April' => 'Abril', + 'August' => 'Agosto', + 'Back' => 'Volta', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => 'Come@,{c}o desse cap@\'itulo ou cap@\'itulo anterior', + 'Button' => 'Bot@~ao', + 'Contents' => 'Conte@\'udo', + 'Cover (top) of document' => 'In@\'icio (topo) do documento', + 'Current' => '', + 'Current Position' => 'Posi@,{c}@~ao Atual', + 'Current section' => 'Se@,{c}@~ao atual', + 'December' => 'Dezembro', + 'FastBack' => 'Voltar R@\'apido', + 'FastForward' => 'Avan@,{c}ar R@\'apido', + 'February' => 'Fevereiro', + 'First' => 'Primeiro', + 'First section in reading order' => 'Primeira se@,{c}@~ao na ordem de leitura', + 'Following' => 'Seguinte', + 'Following node' => 'Nodo seguinte', + 'Footnotes' => 'Notas de Rodap@\'e', + 'Forward' => 'Avan@,{c}ar', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => 'De 1.2.3 v@\'a para', + 'Go to' => 'V@\'a para', + 'Index' => '@\'Indice', + 'Index Entry' => 'Entrada de @\'Indice', + 'January' => 'Janeiro', + 'July' => 'Julho', + 'Jump to' => 'Pular para', + 'June' => 'Junho', + 'Last' => '@\'Ultimo', + 'Last section in reading order' => '@\'Ultima se@,{c}@~ao na ordem de leitura', + 'March' => 'Mar@,{c}o', + 'May' => 'Maio', + 'Menu:' => '', + 'Name' => 'Nome', + 'Next' => 'Pr@\'oximo', + 'Next chapter' => 'Pr@\'oximo cap@\'itulo', + 'Next file' => '', + 'Next node' => 'Pr@\'oximo nodo', + 'Next section in reading order' => 'Pr@\'oxima se@,{c}@~ao na ordem de leitura', + 'Next section on same level' => 'Pr@\'oxima se@,{c}@~ao no mesmo n@\'ivel', + 'NextFile' => '', + 'Node following in node reading order' => 'Nodo seguinte na ordem de leitura de nodos', + 'Node up' => 'Nodo acima', + 'NodeNext' => 'Pr@\'oximo Nodo', + 'NodePrev' => 'Nodo Anterior', + 'NodeUp' => 'Nodo Acima', + 'November' => 'Novembro', + 'October' => 'Outubro', + 'Overview' => 'Vis@~ao geral', + 'Prev' => 'Pr@\'evio', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => '', + 'Previous node' => 'Nodo anterior', + 'Previous section in reading order' => 'Se@,{c}@~ao anterior na ordem de leitura', + 'Previous section on same level' => 'Se@,{c}@~ao anterior no mesmo n@\'ivel', + 'Section' => 'Se@,{c}@~ao', + 'Section One' => 'Se@,{c}@~ao Um', + 'See ' => '', + 'See @cite{{book}}' => 'Veja @cite{{book}}', + 'See `{section}\'' => 'Se@,{c}@~ao acima', + 'See `{section}\' in @cite{{book}}' => 'Veja se@,{c}@~ao `{section}\' em @cite{{book}}', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => 'Veja se@,{c}@~ao {reference_name}', + 'See {node_file_href}' => 'Veja {node_file_href}', + 'See {node_file_href} section `{section}\' in @cite{{book}}' => 'Veja {node_file_href} se@,{c}@~ao `{section}\' em @cite{{book}}', + 'See {reference_name}' => 'Veja {reference_name}', + 'See {reference}' => 'Veja {reference_name}', + 'See {reference} in @cite{{book}}' => 'Veja {node_file_href} @cite{{book}}', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => 'Setembro', + 'Short Table of Contents' => 'Breve Sum@\'ario', + 'Short table of contents' => 'Breve sum@\'ario', + 'Subsection One-Four' => 'Subse@,{c}@~ao Um-Quatro', + 'Subsection One-One' => 'Subse@,{c}@~ao Um-Um', + 'Subsection One-Three' => 'Subse@,{c}@~ao Um-Tr@^es', + 'Subsection One-Two' => 'Subse@,{c}@~ao Um-Dois', + 'Subsubsection One-Two-Four' => 'Subse@,{c}@~ao Um-Dois-Quatro', + 'Subsubsection One-Two-One' => 'Subse@,{c}@~ao Um-Dois-Um', + 'Subsubsection One-Two-Three' => 'Subse@,{c}@~ao Um-Dois-Tr@^es', + 'Subsubsection One-Two-Two' => 'Subse@,{c}@~ao Um-Dois-Dois', + 'Table of Contents' => 'Sum@\'ario', + 'Table of contents' => 'Sum@\'ario', + 'The node you are looking for is at {href}.' => 'O nodo que vo@^e est@\'a olhando est@\'a em {href}.', + 'This' => 'Esse', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'Esse documento foi gerado em @i{{date}} usando @uref{{program_homepage}, @i{{program}}}.', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'Esse documento foi gerado usando @uref{{program_homepage}, @emph{{program}}}.', + 'Top' => 'Topo', + 'Untitled Document' => 'Documento Sem Nome', + 'Up' => 'Acima', + 'Up node' => 'Nodo acima', + 'Up section' => 'Se@,{c}@~ao acima', + '`{section}\'' => 'Se@,{c}@~ao acima', + '`{section}\' in @cite{{book}}' => 'se@,{c}@~ao `{section}\' em @cite{{book}}', + 'current' => 'atual', + 'on @emph{{date}}' => 'em @emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => 'veja @cite{{book}}', + 'see `{section}\'' => 'Se@,{c}@~ao acima', + 'see `{section}\' in @cite{{book}}' => 'se@,{c}@~ao `{section}\' em @cite{{book}}', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section `{section}\' in @cite{{book}}' => 'veja se@,{c}@~ao `{section}\' em @cite{{book}}', + 'see section {reference_name}' => 'veja se@,{c}@~ao {reference_name}', + 'see {node_file_href}' => 'veja {node_file_href}', + 'see {node_file_href} section `{section}\' in @cite{{book}}' => 'veja {node_file_href} se@,{c}@~ao `{section}\' em @cite{{book}}', + 'see {reference_name}' => 'veja {reference_name}', + 'see {reference}' => 'veja {reference_name}', + 'see {reference} in @cite{{book}}' => 'veja {node_file_href} @cite{{book}}', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => '{day} de {month} de {year}', + '{name} of {class}' => '{name} da {class}', + '{name} on {class}' => '{name} na {class}', + '{node_file_href} section `{section}\' in @cite{{book}}' => '{node_file_href} se@,{c}@~ao `{section}\' em @cite{{book}}', + '{reference_name}' => '', + '{reference}' => 'veja {reference_name}', + '{reference} in @cite{{book}}' => 'veja @cite{{book}}', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'es'} = { + ' The buttons in the navigation panels have the following meaning:' => ' Los botones de los paneles de navegaci@\'on tienen el significado siguiente:', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' donde el @strong{ Ejemplo } supone que la posici@\'on actual est@\'a en la @strong{ Sub-subsecci@\'on uno-dos-tres } de un documento de la estructura siguiente:', + ' Up ' => ' Subir ', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => 'Acerca de', + 'About (help)' => 'Acerca de (p@\'agina de ayuda)', + 'About This Document' => 'Acerca de este documento', + 'April' => 'abril', + 'August' => 'agosto', + 'Back' => 'Atr@\'as', + 'Back section in previous file' => 'Retroceder secci@\'on en el archivo anterior', + 'Beginning of this chapter or previous chapter' => 'Inicio de este cap@\'itulo o cap@\'itulo anterior', + 'Button' => 'Bot@\'on', + 'Contents' => '@\'Indice general', + 'Cover (top) of document' => 'Portada del documento', + 'Current' => '', + 'Current Position' => 'Posici@\'on actual', + 'Current section' => 'Secci@\'on actual', + 'December' => 'diciembre', + 'FastBack' => 'Retroceso r@\'apido', + 'FastForward' => 'Avance r@\'apido', + 'February' => 'febrero', + 'First' => 'Primero', + 'First section in reading order' => 'Primera secci@\'on en orden de lectura', + 'Following' => 'Siguiente', + 'Following node' => 'Nodo siguiente', + 'Footnotes' => 'Notas al pie', + 'Forward' => 'Adelante', + 'Forward section in next file' => 'Avanzar secci@\'on en el pr@\'oximo archivo', + 'From 1.2.3 go to' => 'Desde 1.2.3 ir a', + 'Go to' => 'Ir a', + 'Index' => '@\'Indice', + 'Index Entry' => 'Entrada de @\'indice', + 'January' => 'enero', + 'July' => 'julio', + 'Jump to' => 'Saltar a', + 'June' => 'junio', + 'Last' => '@\'Ultimo', + 'Last section in reading order' => '@\'Ultima secci@\'on en orden de lectura', + 'March' => 'marzo', + 'May' => 'mayo', + 'Menu:' => 'Men@\'u:', + 'Name' => 'Nombre', + 'Next' => 'Siguiente', + 'Next chapter' => 'Cap@\'itulo siguiente', + 'Next file' => 'Archivo siguiente', + 'Next node' => 'Nodo siguiente', + 'Next section in reading order' => 'Secci@\'on siguiente en orden de lectura', + 'Next section on same level' => 'Secci@\'on siguiente en el mismo nivel', + 'NextFile' => 'ArchivoSiguiente', + 'Node following in node reading order' => 'Nodo siguiente en orden de lectura de nodos', + 'Node up' => 'Subir nodo', + 'NodeNext' => 'NodoSiguiente', + 'NodePrev' => 'NodoAnterior', + 'NodeUp' => 'SubirNodo', + 'November' => 'noviembre', + 'October' => 'octubre', + 'Overview' => 'Panor@\'amica', + 'Prev' => 'Ant', + 'PrevFile' => 'ArchivoAnt', + 'Previous' => '', + 'Previous file' => 'Archivo anterior', + 'Previous node' => 'Nodo anterior', + 'Previous section in reading order' => 'Secci@\'on anterior en orden de lectura', + 'Previous section on same level' => 'Secci@\'on anterior en el mismo nivel', + 'Section' => 'Secci@\'on', + 'Section One' => 'Secci@\'on Uno', + 'See ' => '', + 'See @cite{{book}}' => 'V@\'ease @cite{{book}}', + 'See `{section}\'' => 'Subir secci@\'on', + 'See `{section}\' in @cite{{book}}' => 'V@\'ease la secci@\'on `{section}\' en @cite{{book}}', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => 'V@\'ease la secci@\'on {reference_name}', + 'See {node_file_href}' => 'V@\'ease {node_file_href}', + 'See {node_file_href} section `{section}\' in @cite{{book}}' => 'V@\'ease {node_file_href} secci@\'on `{section}\' en @cite{{book}}', + 'See {reference_name}' => 'V@\'ease {reference_name}', + 'See {reference}' => 'V@\'ease {reference_name}', + 'See {reference} in @cite{{book}}' => 'V@\'ease {node_file_href} @cite{{book}}', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => 'septiembre', + 'Short Table of Contents' => 'Resumen del Contenido', + 'Short table of contents' => 'Resumen del contenido', + 'Subsection One-Four' => 'Subsecci@\'on uno-cuatro', + 'Subsection One-One' => 'Subsecci@\'on uno-uno', + 'Subsection One-Three' => 'Subsecci@\'on uno-tres', + 'Subsection One-Two' => 'Subsecci@\'on uno-dos', + 'Subsubsection One-Two-Four' => 'Sub-subsecci@\'on uno-dos-cuatro', + 'Subsubsection One-Two-One' => 'Sub-subsecci@\'on uno-dos-uno', + 'Subsubsection One-Two-Three' => 'Sub-subsecci@\'on uno-dos-tres', + 'Subsubsection One-Two-Two' => 'Sub-subsecci@\'on uno-dos-dos', + 'Table of Contents' => '@\'{@dotless{I}}ndice General', + 'Table of contents' => '@\'{@dotless{I}}ndice general', + 'The node you are looking for is at {href}.' => 'El nodo que busca se encuentra en {href}.', + 'This' => 'Este', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'Este documento se gener@\'o el @i{{date}} utilizando @uref{{program_homepage}, @i{{program}}}.', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'Este documento se gener@\'o utilizando @uref{{program_homepage}, @emph{{program}}}.', + 'Top' => 'Arriba', + 'Untitled Document' => 'Documento sin t@\'itulo', + 'Up' => 'Subir', + 'Up node' => 'Subir nodo', + 'Up section' => 'Subir secci@\'on', + '`{section}\'' => 'Subir secci@\'on', + '`{section}\' in @cite{{book}}' => 'secci@\'on `{section}\' en @cite{{book}}', + 'current' => 'actual', + 'on @emph{{date}}' => 'el @emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => 'v@\'ease @cite{{book}}', + 'see `{section}\'' => 'Subir secci@\'on', + 'see `{section}\' in @cite{{book}}' => 'secci@\'on `{section}\' en @cite{{book}}', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section `{section}\' in @cite{{book}}' => 'v@\'ease la secci@\'on `{section}\' en @cite{{book}}', + 'see section {reference_name}' => 'v@\'ease la secci@\'on {reference_name}', + 'see {node_file_href}' => 'v@\'ease {node_file_href}', + 'see {node_file_href} section `{section}\' in @cite{{book}}' => 'v@\'ease {node_file_href} secci@\'on `{section}\' en @cite{{book}}', + 'see {reference_name}' => 'v@\'ease {reference_name}', + 'see {reference}' => 'v@\'ease {reference_name}', + 'see {reference} in @cite{{book}}' => 'v@\'ease {node_file_href} @cite{{book}}', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => 'el {day} {month} {year}', + '{name} of {class}' => '{name} de {class}', + '{name} on {class}' => '{name} en {class}', + '{node_file_href} section `{section}\' in @cite{{book}}' => '{node_file_href} secci@\'on `{section}\' en @cite{{book}}', + '{reference_name}' => '', + '{reference}' => 'v@\'ease {reference_name}', + '{reference} in @cite{{book}}' => 'v@\'ease @cite{{book}}', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'it'} = { + ' The buttons in the navigation panels have the following meaning:' => ' I bottoni nei pannelli di navigazione hanno il seguente significato:', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' dove @strong{ Esempio } assume che l\'attuale posizione è alla @strong{ Sottosottosezione Uno-Due-Tre } di un documento che ha la seguente struttura:', + ' Up ' => ' Su ', + '(outside of any element)' => '(fuori da qualsiasi elemento)', + '(outside of any node)' => '(fuori da qualsiasi nodo)', + '@b{{quotation_arg}:} ' => '@b{{quotation_arg}:} ', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '@cite{{book}}', + '@{No value for `{value}\'@}' => '@{Nessun valore per `{value}\'@}', + 'About' => 'Informazioni', + 'About (help)' => 'Informazioni (aiuto)', + 'About This Document' => 'Informazioni su questo documento', + 'April' => 'Aprile', + 'August' => 'Agosto', + 'Back' => 'Indietro', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => 'Inizio di questo capitolo o capitolo precedente', + 'Button' => 'Bottone', + 'Contents' => 'Contenuti', + 'Cover (top) of document' => 'Copertina (inizio) del documento', + 'Current' => 'Attuale', + 'Current Position' => 'Posizione Attuale', + 'Current section' => 'Sezione attuale', + 'December' => 'Dicembre', + 'FastBack' => 'Indietro veloce', + 'FastForward' => 'Avanti veloce', + 'February' => 'Febbraio', + 'First' => 'Primo', + 'First section in reading order' => 'Prima sezione in ordine di lettura', + 'Following' => 'Seguente', + 'Following node' => 'Nodo seguente', + 'Footnotes' => 'Note a piè di pagina', + 'Forward' => 'Avanti', + 'Forward section in next file' => 'Sezione successiva nel prossimo file', + 'From 1.2.3 go to' => 'Da 1.2.3 vai a', + 'Go to' => 'Vai a', + 'Index' => 'Indice', + 'Index Entry' => 'Voce dell\'indice', + 'January' => 'Gennaio', + 'July' => 'Luglio', + 'Jump to' => 'Salta a', + 'June' => 'Giugno', + 'Last' => 'Ultimo', + 'Last section in reading order' => 'Ultima sezione in ordine di lettura', + 'March' => 'Marzo', + 'May' => 'Maggio', + 'Menu:' => 'Menu', + 'Name' => 'Nome', + 'Next' => 'Successivo', + 'Next chapter' => 'Capitolo successivo', + 'Next file' => 'File successivo', + 'Next node' => 'Nodo successivo', + 'Next section in reading order' => 'Sezione successiva in ordine di lettura', + 'Next section on same level' => 'Sezione successiva sullo stesso livello', + 'NextFile' => 'File successivo', + 'Node following in node reading order' => 'Nodo seguente in ordine di lettura', + 'Node up' => 'Nodo superiore', + 'NodeNext' => 'Nodo successivo', + 'NodePrev' => 'Nodo precedente', + 'NodeUp' => 'Nodo superiore', + 'November' => 'Novembre', + 'October' => 'Ottobre', + 'Overview' => 'Panoramica', + 'Prev' => 'Prec.', + 'PrevFile' => 'File precedente', + 'Previous' => 'Precedente', + 'Previous file' => 'File precedente', + 'Previous node' => 'Nodo precedente', + 'Previous section in reading order' => 'Sezione precedente in ordine di lettura', + 'Previous section on same level' => 'Sezione precedente sullo stesso livello', + 'Section' => 'Sezione', + 'Section One' => 'Sezione uno', + 'See ' => 'Vedi', + 'See @cite{{book}}' => 'Vedi @cite{{book}}', + 'See `{section}\'' => 'Sezione superiore', + 'See `{section}\' in @cite{{book}}' => 'Vedi la sezione `{section}\' in @cite{{book}}', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => 'Vedi la sezione `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', + 'See section {reference_name}' => 'Vedi la sezione {reference_name}', + 'See {node_file_href}' => 'Vedi {node_file_href}', + 'See {node_file_href} section `{section}\' in @cite{{book}}' => 'Vedi {node_file_href} nella sezione `{section}\' in @cite{{book}}', + 'See {reference_name}' => 'Vedi {reference_name}', + 'See {reference}' => 'Vedi {reference_name}', + 'See {reference} in @cite{{book}}' => 'Vedi {node_file_href} @cite{{book}}', + 'See {ref}' => 'Vedi {ref}', + 'See {title_ref}' => 'Vedi {title_ref}', + 'September' => 'Settembre', + 'Short Table of Contents' => 'Indice breve', + 'Short table of contents' => 'Indice breve', + 'Subsection One-Four' => 'Sottosezione Uno-Quattro', + 'Subsection One-One' => 'Sottosezione Uno-Uno', + 'Subsection One-Three' => 'Sottosezione Uno-Tre', + 'Subsection One-Two' => 'Sottosezione Uno-Due', + 'Subsubsection One-Two-Four' => 'Sottosottosezione Uno-Due-Quattro', + 'Subsubsection One-Two-One' => 'Sottosottosezione Uno-Due-Uno', + 'Subsubsection One-Two-Three' => 'Sottosottosezione Uno-Due-Tre', + 'Subsubsection One-Two-Two' => 'Sottosottosezione Uno-Due-Due', + 'Table of Contents' => 'Indice', + 'Table of contents' => 'Indice', + 'The node you are looking for is at {href}.' => 'Il nodo che stai cercando è {href}', + 'This' => 'Questo', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => 'Questo documento è stato generato il @i{{date}} con @uref{{program_homepage}, @i{{program}}}.', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => 'Questo documento è stato generato con @uref{{program_homepage}, @emph{{program}}}.', + 'Top' => 'Inizio', + 'Untitled Document' => 'Documento senza titolo', + 'Up' => 'Su', + 'Up node' => 'Nodo superiore', + 'Up section' => 'Sezione superiore', + '`{section}\'' => 'Sezione superiore', + '`{section}\' in @cite{{book}}' => 'sezione `{section}\' in @cite{{book}}', + 'current' => 'attuale', + 'on @emph{{date}}' => 'il @emph{{date}}', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => 'sezione `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', + 'see ' => 'vedi ', + 'see @cite{{book}}' => 'vedi @cite{{book}}', + 'see `{section}\'' => 'Sezione superiore', + 'see `{section}\' in @cite{{book}}' => 'sezione `{section}\' in @cite{{book}}', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => 'vedi la sezione `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', + 'see section `{section}\' in @cite{{book}}' => 'vedi la sezione `{section}\' in @cite{{book}}', + 'see section {reference_name}' => 'vedi la sezione {reference_name}', + 'see {node_file_href}' => 'vedi {node_file_href}', + 'see {node_file_href} section `{section}\' in @cite{{book}}' => 'vedi {node_file_href} nella sezione `{section}\' in @cite{{book}}', + 'see {reference_name}' => 'vedi {reference_name}', + 'see {reference}' => 'vedi {reference_name}', + 'see {reference} in @cite{{book}}' => 'vedi {node_file_href} @cite{{book}}', + 'see {ref}' => 'vedi {ref}', + 'see {title_ref}' => 'vedi {title_ref}', + '{acronym_like} ({explanation})' => '{acronym_like} ({explanation})', + '{month} {day}, {year}' => '', + '{name} of {class}' => '{name} di {class}', + '{name} on {class}' => '{name} in {class}', + '{node_file_href}' => '{node_file_href}', + '{node_file_href} section `{section}\' in @cite{{book}}' => '{node_file_href} nella sezione `{section}\' in @cite{{book}}', + '{reference_name}' => '{reference_name}', + '{reference}' => '{reference_name}', + '{reference} in @cite{{book}}' => '{node_file_href} @cite{{book}}', + '{ref}' => '{ref}', + '{style} {number}' => '{style} {number}', + '{style}: {caption_first_line}' => '{style}: {caption_first_line}', + '{style}: {shortcaption_first_line}' => '{style}: {shortcaption_first_line}', + '{title_ref}' => '{title_ref}' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'no'} = { + ' The buttons in the navigation panels have the following meaning:' => '', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '', + ' Up ' => '', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => '', + 'About (help)' => '', + 'About This Document' => 'No translation available!', + 'April' => 'april', + 'August' => 'august', + 'Back' => '', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => '', + 'Button' => '', + 'Contents' => '', + 'Cover (top) of document' => '', + 'Current' => '', + 'Current Position' => '', + 'Current section' => '', + 'December' => 'desember', + 'FastBack' => '', + 'FastForward' => '', + 'February' => 'februar', + 'First' => '', + 'First section in reading order' => '', + 'Following' => '', + 'Following node' => '', + 'Footnotes' => 'No translation available!', + 'Forward' => '', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => '', + 'Go to' => '', + 'Index' => 'Indeks', + 'Index Entry' => '', + 'January' => 'januar', + 'July' => 'juli', + 'Jump to' => '', + 'June' => 'juni', + 'Last' => '', + 'Last section in reading order' => '', + 'March' => 'mars', + 'May' => 'mai', + 'Menu:' => '', + 'Name' => '', + 'Next' => '', + 'Next chapter' => '', + 'Next file' => '', + 'Next node' => '', + 'Next section in reading order' => '', + 'Next section on same level' => '', + 'NextFile' => '', + 'Node following in node reading order' => '', + 'Node up' => '', + 'NodeNext' => '', + 'NodePrev' => '', + 'NodeUp' => '', + 'November' => 'november', + 'October' => 'oktober', + 'Overview' => '', + 'Prev' => '', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => '', + 'Previous node' => '', + 'Previous section in reading order' => '', + 'Previous section on same level' => '', + 'Section' => '', + 'Section One' => '', + 'See ' => '', + 'See @cite{{book}}' => '', + 'See `{section}\'' => '', + 'See `{section}\' in @cite{{book}}' => '', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => '', + 'See {reference_name}' => '', + 'See {reference}' => '', + 'See {reference} in @cite{{book}}' => '', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => 'september', + 'Short Table of Contents' => 'Kort innholdsfortegnelse', + 'Short table of contents' => '', + 'Subsection One-Four' => '', + 'Subsection One-One' => '', + 'Subsection One-Three' => '', + 'Subsection One-Two' => '', + 'Subsubsection One-Two-Four' => '', + 'Subsubsection One-Two-One' => '', + 'Subsubsection One-Two-Three' => '', + 'Subsubsection One-Two-Two' => '', + 'Table of Contents' => 'Innholdsfortegnelse', + 'Table of contents' => '', + 'The node you are looking for is at {href}.' => '', + 'This' => '', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => '', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => '', + 'Top' => '', + 'Untitled Document' => '', + 'Up' => '', + 'Up node' => '', + 'Up section' => '', + '`{section}\'' => '', + '`{section}\' in @cite{{book}}' => '', + 'current' => '', + 'on @emph{{date}}' => '', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => '', + 'see `{section}\'' => '', + 'see `{section}\' in @cite{{book}}' => '', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section {reference_name}' => '', + 'see {reference_name}' => '', + 'see {reference}' => '', + 'see {reference} in @cite{{book}}' => '', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => '', + '{name} of {class}' => '', + '{name} on {class}' => '', + '{reference_name}' => '', + '{reference}' => '', + '{reference} in @cite{{book}}' => '', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; +# Automatically generated file. Edit the .po file instead. +$LANGUAGES->{'en'} = { + ' The buttons in the navigation panels have the following meaning:' => '', + ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '', + ' Up ' => '', + '(outside of any element)' => '', + '(outside of any node)' => '', + '@b{{quotation_arg}:} ' => '', + '@center --- @emph{{author}} +' => '', + '@cite{{book}}' => '', + '@{No value for `{value}\'@}' => '', + 'About' => '', + 'About (help)' => '', + 'About This Document' => '', + 'April' => '', + 'August' => '', + 'Back' => '', + 'Back section in previous file' => '', + 'Beginning of this chapter or previous chapter' => '', + 'Button' => '', + 'Contents' => '', + 'Cover (top) of document' => '', + 'Current' => '', + 'Current Position' => '', + 'Current section' => '', + 'December' => '', + 'FastBack' => '', + 'FastForward' => '', + 'February' => '', + 'First' => '', + 'First section in reading order' => '', + 'Following' => '', + 'Following node' => '', + 'Footnotes' => '', + 'Forward' => '', + 'Forward section in next file' => '', + 'From 1.2.3 go to' => '', + 'Go to' => '', + 'Index' => '', + 'Index Entry' => '', + 'January' => '', + 'July' => '', + 'Jump to' => '', + 'June' => '', + 'Last' => '', + 'Last section in reading order' => '', + 'March' => '', + 'May' => '', + 'Menu:' => '', + 'Name' => '', + 'Next' => '', + 'Next chapter' => '', + 'Next file' => '', + 'Next node' => '', + 'Next section in reading order' => '', + 'Next section on same level' => '', + 'NextFile' => '', + 'Node following in node reading order' => '', + 'Node up' => '', + 'NodeNext' => '', + 'NodePrev' => '', + 'NodeUp' => '', + 'November' => '', + 'October' => '', + 'Overview' => '', + 'Prev' => '', + 'PrevFile' => '', + 'Previous' => '', + 'Previous file' => '', + 'Previous node' => '', + 'Previous section in reading order' => '', + 'Previous section on same level' => '', + 'Section' => '', + 'Section One' => '', + 'See ' => '', + 'See @cite{{book}}' => '', + 'See `{section}\'' => '', + 'See `{section}\' in @cite{{book}}' => '', + 'See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'See section {reference_name}' => '', + 'See {reference_name}' => '', + 'See {reference}' => '', + 'See {reference} in @cite{{book}}' => '', + 'See {ref}' => '', + 'See {title_ref}' => '', + 'September' => '', + 'Short Table of Contents' => '', + 'Short table of contents' => '', + 'Subsection One-Four' => '', + 'Subsection One-One' => '', + 'Subsection One-Three' => '', + 'Subsection One-Two' => '', + 'Subsubsection One-Two-Four' => '', + 'Subsubsection One-Two-One' => '', + 'Subsubsection One-Two-Three' => '', + 'Subsubsection One-Two-Two' => '', + 'Table of Contents' => '', + 'Table of contents' => '', + 'The node you are looking for is at {href}.' => '', + 'This' => '', + 'This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.' => '', + 'This document was generated using @uref{{program_homepage}, @emph{{program}}}.' => '', + 'Top' => '', + 'Untitled Document' => '', + 'Up' => '', + 'Up node' => '', + 'Up section' => '', + '`{section}\'' => '', + '`{section}\' in @cite{{book}}' => '', + 'current' => '', + 'on @emph{{date}}' => '', + 'section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see ' => '', + 'see @cite{{book}}' => '', + 'see `{section}\'' => '', + 'see `{section}\' in @cite{{book}}' => '', + 'see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}' => '', + 'see section {reference_name}' => '', + 'see {reference_name}' => '', + 'see {reference}' => '', + 'see {reference} in @cite{{book}}' => '', + 'see {ref}' => '', + 'see {title_ref}' => '', + '{acronym_like} ({explanation})' => '', + '{month} {day}, {year}' => '', + '{name} of {class}' => '', + '{name} on {class}' => '', + '{reference_name}' => '', + '{reference}' => '', + '{reference} in @cite{{book}}' => '', + '{ref}' => '', + '{style} {number}' => '', + '{style}: {caption_first_line}' => '', + '{style}: {shortcaption_first_line}' => '', + '{title_ref}' => '' + }; + +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 ($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 ($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('DOCUMENT_ENCODING'); + 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.init for details. + #+++############################################################################ # # -# Pass 2/3: handle style, menu, index, cross-reference # +# Pasted content of File $(srcdir)/MySimple.pm: Command-line processing # # # #---############################################################################ -@lines2 = (); # whole document (2nd pass) -@lines3 = (); # whole document (3rd pass) -$in_menu = 0; # am I inside a menu +# leave this within comments, and keep the require statement +# This way, you can directly run texi2html.pl, if $T2H_HOME/MySimple.pm +# exists. -while (@lines) { - $_ = shift(@lines); - # - # special case (protected sections) - # - if (/^$PROTECTTAG/o) { - push(@lines2, $_); - next; - } - # - # menu - # - $in_menu = 1, push(@lines2, &debug("
      \n", __LINE__)), next if /^\@menu\b/; - $in_menu = 0, push(@lines2, &debug("
    \n", __LINE__)), next if /^\@end\s+menu\b/; - if ($in_menu) { - if (/^\*\s+($NODERE)::/o) { - $descr = $'; - chop($descr); - &menu_entry($1, $1, $descr); - } elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) { - $descr = $'; - chop($descr); - &menu_entry($1, $2, $descr); - } elsif (/^\*/) { - warn "$ERROR Bad menu line: $_"; - } else { # description continued? - push(@lines2, $_); +# @MYSIMPLE@ +package Getopt::MySimple; + +# Name: +# Getopt::MySimple. +# +# Documentation: +# POD-style (incomplete) documentation is in file MySimple.pod +# +# Tabs: +# 4 spaces || die. +# +# Author: +# Ron Savage rpsavage@ozemail.com.au. +# 1.00 19-Aug-97 Initial version. +# 1.10 13-Oct-97 Add arrays of switches (eg '=s@'). +# 1.20 3-Dec-97 Add 'Help' on a per-switch basis. +# 1.30 11-Dec-97 Change 'Help' to 'verbose'. Make all hash keys lowercase. +# 1.40 10-Nov-98 Change width of help report. Restructure tests. +# 1-Jul-00 Modifications for Texi2html + +# -------------------------------------------------------------------------- +# Locally modified by obachman (Display type instead of env, order by cmp) +# $Id: texi2html,v 1.3 2017/03/28 23:22:20 takayama Exp $ + +# use strict; +# no strict 'refs'; + +use vars qw(@EXPORT @EXPORT_OK @ISA); +use vars qw($fieldWidth $opt $VERSION); + +use Exporter(); +use Getopt::Long; + +@ISA = qw(Exporter); +@EXPORT = qw(); +@EXPORT_OK = qw($opt); # An alias for $self -> {'opt'}. + +# -------------------------------------------------------------------------- + +$fieldWidth = 20; +$VERSION = '1.41'; + +# -------------------------------------------------------------------------- + +sub byOrder +{ + my($self) = @_; + + return uc($a) cmp (uc($b)); +} + +# -------------------------------------------------------------------------- + +sub dumpOptions +{ + my($self) = @_; + + print 'Option', ' ' x ($fieldWidth - length('Option') ), "Value\n"; + + for (sort byOrder keys(%{$self -> {'opt'} }) ) + { + print "-$_", ' ' x ($fieldWidth - (1 + length) ), "${$self->{'opt'} }{$_}\n"; } - next; - } - # - # printindex - # - if (/^\@printindex\s+(\w\w)\b/) { - local($index, *ary, @keys, $key, $letter, $last_letter, @refs); - if ($predefined_index{$1}) { - $index = $predefined_index{$1} . 'index'; - } else { - $index = $1 . 'index'; + + print "\n"; + +} # End of dumpOptions. + +# -------------------------------------------------------------------------- +# Return: +# 0 -> Error. +# 1 -> Ok. + +sub getOptions +{ + push(@_, 0) if ($#_ == 2); # Default for $ignoreCase is 0. + push(@_, 1) if ($#_ == 3); # Default for $helpThenExit is 1. + + my($self, $default, $helpText, $versionText, + $helpThenExit, $versionThenExit, $ignoreCase) = @_; + + $helpThenExit = 1 unless (defined($helpThenExit)); + $versionThenExit = 1 unless (defined($versionThenExit)); + $ignoreCase = 0 unless (defined($ignoreCase)); + + $self -> {'default'} = $default; + $self -> {'helpText'} = $helpText; + $self -> {'versionText'} = $versionText; + $Getopt::Long::ignorecase = $ignoreCase; + + unless (defined($self -> {'default'}{'help'})) + { + $self -> {'default'}{'help'} = + { + type => ':i', + default => '', + linkage => sub {$self->helpOptions($_[1]); sleep 5;exit (0) if $helpThenExit;}, + verbose => "print help and exit" + }; } - eval("*ary = *$index"); - @keys = keys(%ary); - foreach $key (@keys) { - $_ = $key; - 1 while s/<(\w+)>\`(.*)\'<\/\1>/$2/; # remove HTML tags with quotes - 1 while s/<(\w+)>(.*)<\/\1>/$2/; # remove HTML tags - $_ = &unprotect_html($_); - &unprotect_texi; - tr/A-Z/a-z/; # lowercase - $key2alpha{$key} = $_; - print "# index $key sorted as $_\n" - if $key ne $_ && $debug & $DEBUG_INDEX; + + unless (defined($self -> {'default'}{'version'})) + { + $self -> {'default'}{'version'} = + { + type => '', + default => '', + linkage => sub {print $self->{'versionText'}; exit (0) if $versionThenExit;}, + verbose => "print version and exit" + }; } - push(@lines2, "Jump to:\n"); - $last_letter = undef; - foreach $key (sort byalpha @keys) { - $letter = substr($key2alpha{$key}, 0, 1); - $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;; - if (!defined($last_letter) || $letter ne $last_letter) { - push(@lines2, "-\n") if defined($last_letter); - push(@lines2, "
    " . &protect_html($letter) . "\n"); - $last_letter = $letter; - } + + for (keys(%{$self -> {'default'} }) ) + { + next unless (ref(${$self -> {'default'} }{$_}) eq 'HASH'); + my $type = ${$self -> {'default'} }{$_}{'type'}; + push(@{$self -> {'type'} }, "$_$type"); + my $key = $_; + # get rid of aliases, if any + $key =~ s/\|.*//; + $self->{'opt'}->{$key} = ${$self -> {'default'} }{$_}{'linkage'} + if ${$self -> {'default'} }{$_}{'linkage'}; } - push(@lines2, "

    \n"); - $last_letter = undef; - foreach $key (sort byalpha @keys) { - $letter = substr($key2alpha{$key}, 0, 1); - $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;; - if (!defined($last_letter) || $letter ne $last_letter) { - push(@lines2, "\n") if defined($last_letter); - push(@lines2, "

    " . &protect_html($letter) . "

    \n"); - push(@lines2, "\n"); - $last_letter = $letter; - } - @refs = (); - foreach (split(/$;/, $ary{$key})) { - push(@refs, &anchor('', $_, $key, 0)); - } - push(@lines2, "
  • " . join(", ", @refs) . "\n"); + + my($result) = &GetOptions($self -> {'opt'}, @{$self -> {'type'} }); + + return $result unless $result; + + for (keys(%{$self -> {'default'} }) ) + { + if (! defined(${$self -> {'opt'} }{$_})) #{ + { + ${$self -> {'opt'} }{$_} = ${$self -> {'default'} }{$_}{'default'}; + } } - push(@lines2, "
  • \n") if defined($last_letter); - next; - } - # - # simple style substitutions - # - $_ = &substitute_style($_); - # - # xref - # - while (/\@(x|px|info|)ref{($XREFRE)(}?)/o) { - # note: Texinfo may accept other characters - ($type, $nodes, $full) = ($1, $2, $3); - ($before, $after) = ($`, $'); - if (! $full && $after) { - warn "$ERROR Bad xref (no ending } on line): $_"; - $_ = "$before$;0${type}ref\{$nodes$after"; - next; # while xref - } - if ($type eq 'x') { - $type = 'See '; - } elsif ($type eq 'px') { - $type = 'see '; - } elsif ($type eq 'info') { - $type = 'See Info'; - } else { - $type = ''; - } - unless ($full) { - $next = shift(@lines); - $next = &substitute_style($next); - chop($nodes); # remove final newline - if ($next =~ /\}/) { # split on 2 lines - $nodes .= " $`"; - $after = $'; - } else { - $nodes .= " $next"; - $next = shift(@lines); - $next = &substitute_style($next); - chop($nodes); - if ($next =~ /\}/) { # split on 3 lines - $nodes .= " $`"; - $after = $'; - } else { - warn "$ERROR Bad xref (no ending }): $_"; - $_ = "$before$;0xref\{$nodes$after"; - unshift(@lines, $next); - next; # while xref + + $result; +} # End of getOptions. + +# -------------------------------------------------------------------------- + +sub helpOptions +{ + my($self) = shift; + my($noHelp) = shift; + $noHelp = 0 unless $noHelp; + my($optwidth, $typewidth, $defaultwidth, $maxlinewidth, $valind, $valwidth) + = (10, 5, 9, 78, 4, 11); + + print "$self->{'helpText'}" if ($self -> {'helpText'}); + + print ' Option', ' ' x ($optwidth - length('Option') -1 ), + 'Type', ' ' x ($typewidth - length('Type') + 1), + 'Default', ' ' x ($defaultwidth - length('Default') ), + "Description\n"; + + for (sort byOrder keys(%{$self -> {'default'} }) ) + { + my($line, $help, $option, $val); + $option = $_; + next if (ref(${$self -> {'default'} }{$_}) ne 'HASH' or (${$self->{'default'} }{$_}{'noHelp'} && ${$self->{'default'} }{$_}{'noHelp'} > $noHelp)); + #$line = " -$_" . ' ' x ($optwidth - (2 + length) ) . + # "${$self->{'default'} }{$_}{'type'} ". + # ' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) )); + $line = " --$_" . "${$self->{'default'} }{$_}{'type'}". + ' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) )); + + $val = ${$self->{'default'} }{$_}{'linkage'}; + if ($val) + { + if ((ref($val) eq 'SCALAR') and (defined($$val))) + { + $val = $$val; + } + else + { + $val = ''; + } + } + elsif (defined(${$self->{'default'} }{$_}{'default'})) + { + $val = ${$self->{'default'} }{$_}{'default'}; } - } + else + { + $val = ''; + } + $line .= "$val "; + $line .= ' ' x ($optwidth + $typewidth + $defaultwidth + 1 - length($line)); + + if (defined(${$self -> {'default'} }{$_}{'verbose'}) && + ${$self -> {'default'} }{$_}{'verbose'} ne '') + { + $help = "${$self->{'default'} }{$_}{'verbose'}"; + } + else + { + $help = ' '; + } + if ((length("$line") + length($help)) < $maxlinewidth) + { + print $line , $help, "\n"; + } + else + { + print $line, "\n", ' ' x $valind, $help, "\n"; + } + for $val (sort byOrder keys(%{${$self->{'default'}}{$option}{'values'}})) + { + print ' ' x ($valind + 2); + print $val, ' ', ' ' x ($valwidth - length($val) - 2); + print ${$self->{'default'}}{$option}{'values'}{$val}, "\n"; + } } - $nodes =~ s/\s+/ /g; # remove useless spaces - @args = split(/\s*,\s*/, $nodes); - $node = $args[0]; # the node is always the first arg - &normalise_node($node); - $sec = $node2sec{$node}; - if (@args == 5) { # reference to another manual - $sec = $args[2] || $node; - $man = $args[4] || $args[3]; - $_ = "${before}${type}section `$sec' in \@cite{$man}$after"; - } elsif ($type =~ /Info/) { # inforef - warn "$ERROR Wrong number of arguments: $_" unless @args == 3; - ($nn, $_, $in) = @args; - $_ = "${before}${type} file `$in', node `$nn'$after"; - } elsif ($sec) { - $href = $node2href{$node}; - $_ = "${before}${type}section " . &anchor('', $href, $sec) . $after; - } else { - warn "$ERROR Undefined node ($node): $_"; - $_ = "$before$;0xref{$nodes}$after"; - } + + print <| ! no argument: variable is set to 1 on -foo (or, to 0 on -nofoo) + =s | :s mandatory (or, optional) string argument + =i | :i mandatory (or, optional) integer argument +EOT +} # End of helpOptions. + +#------------------------------------------------------------------- + +sub new +{ + my($class) = @_; + my($self) = {}; + $self -> {'default'} = {}; + $self -> {'helpText'} = ''; + $self -> {'opt'} = {}; + $opt = $self -> {'opt'}; # An alias for $self -> {'opt'}. + $self -> {'type'} = (); + + return bless $self, $class; + +} # End of new. + +# -------------------------------------------------------------------------- + +1; + +# End MySimple.pm + +require "$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@ +#+############################################################################## +# +# T2h_i18n.pm: Internationalization for texi2html +# +# Copyright (C) 1999-2005 Patrice Dumas , +# Derek Price , +# Adrian Aichner , +# & others. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +#-############################################################################## + +# This requires perl version 5 or higher +require 5.0; + +package Texi2HTML::I18n; + +use strict; + +use vars qw( +@ISA +@EXPORT +); + +use Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(pretty_date); + +my $language; +my $i18n_dir = 'i18n'; # name of the directory containing the per language files +#my $translation_file = 'translations.pl'; # file containing all the translations +#my @known_languages = ('de', 'nl', 'es', 'no', 'pt', 'fr'); # The supported + # languages + +######################################################################## +# Language dependencies: +# To add a new language extend the WORDS hash and create $T2H_<...>_WORDS hash +# To redefine one word, simply do: +# $T2h_i18n::T2H_LANGUAGES->{}->{} = 'whatever' in your personal init file. +# + +# Those hashes are obsolete but retained here for reference + +my $T2H_WORDS_EN = +{ + # titles of pages + #'Table of Contents' => 'Table of Contents', + #'Short Table of Contents' => 'Short Table of Contents', + #'Index' => 'Index', + #'About This Document' => 'About This Document', + #'Footnotes' => 'Footnotes', + #'See' => 'See', + #'see' => 'see', + #'section' => 'section', + 'About This Document' => '', + 'Table of Contents' => '', + 'Short Table of Contents', => '', + 'Index' => '', + 'Footnotes' => '', + 'See' => '', + 'see' => '', + 'section' => '', + 'Top' => '', + 'Untitled Document' => '', + # If necessary, we could extend this as follows: + # # text for buttons + # 'Top_Button' => 'Top', + # 'ToC_Button' => 'Contents', + # 'Overview_Button' => 'Overview', + # 'Index_button' => 'Index', + # 'Back_Button' => 'Back', + # 'FastBack_Button' => 'FastBack', + # 'Prev_Button' => 'Prev', + # 'Up_Button' => 'Up', + # 'Next_Button' => 'Next', + # 'Forward_Button' =>'Forward', + # 'FastWorward_Button' => 'FastForward', + # 'First_Button' => 'First', + # 'Last_Button' => 'Last', + # 'About_Button' => 'About' + 'January' => '', + 'February' => '', + 'March' => '', + 'April' => '', + 'May' => '', + 'June' => '', + 'July' => '', + 'August' => '', + 'September' => '', + 'October' => '', + 'November' => '', + 'December' => '', + 'T2H_today' => '%s, %d %d', +}; + +my $T2H_WORDS_DE = +{ + 'Table of Contents' => 'Inhaltsverzeichniss', + 'Short Table of Contents' => 'Kurzes Inhaltsverzeichniss', + 'Index' => 'Index', + 'About This Document' => 'Über dieses Dokument', + 'Footnotes' => 'Fußnoten', + 'See' => 'Siehe', + 'see' => 'siehe', + 'section' => 'Abschnitt', + 'January' => 'Januar', + 'February' => 'Februar', + 'March' => 'März', + 'April' => 'April', + 'May' => 'Mai', + 'June' => 'Juni', + 'July' => 'Juli', + 'August' => 'August', + 'September' => 'September', + 'October' => 'Oktober', + 'November' => 'November', + 'December' => 'Dezember', +}; + +my $T2H_WORDS_NL = +{ + 'Table of Contents' => 'Inhoudsopgave', + 'Short Table of Contents' => 'Korte inhoudsopgave', + 'Index' => 'Index', #Not sure ;-) + 'About This Document' => 'No translation available!', #No translation available! + 'Footnotes' => 'No translation available!', #No translation available! + 'See' => 'Zie', + 'see' => 'zie', + 'section' => 'sectie', + 'January' => 'Januari', + 'February' => 'Februari', + 'March' => 'Maart', + 'April' => 'April', + 'May' => 'Mei', + 'June' => 'Juni', + 'July' => 'Juli', + 'August' => 'Augustus', + 'September' => 'September', + 'October' => 'Oktober', + 'November' => 'November', + 'December' => 'December', +}; + +my $T2H_WORDS_ES = +{ + 'Table of Contents' => 'índice General', + 'Short Table of Contents' => 'Resumen del Contenido', + 'Index' => 'Index', #Not sure ;-) + 'About This Document' => 'No translation available!', #No translation available! + 'Footnotes' => 'Fußnoten', + 'See' => 'Véase', + 'see' => 'véase', + 'section' => 'sección', + 'January' => 'enero', + 'February' => 'febrero', + 'March' => 'marzo', + 'April' => 'abril', + 'May' => 'mayo', + 'June' => 'junio', + 'July' => 'julio', + 'August' => 'agosto', + 'September' => 'septiembre', + 'October' => 'octubre', + 'November' => 'noviembre', + 'December' => 'diciembre', +}; + +my $T2H_WORDS_NO = +{ + 'Table of Contents' => 'Innholdsfortegnelse', + 'Short Table of Contents' => 'Kort innholdsfortegnelse', + 'Index' => 'Indeks', #Not sure ;-) + 'About This Document' => 'No translation available!', #No translation available! + 'Footnotes' => 'No translation available!', + 'See' => 'Se', + 'see' => 'se', + 'section' => 'avsnitt', + 'January' => 'januar', + 'February' => 'februar', + 'March' => 'mars', + 'April' => 'april', + 'May' => 'mai', + 'June' => 'juni', + 'July' => 'juli', + 'August' => 'august', + 'September' => 'september', + 'October' => 'oktober', + 'November' => 'november', + 'December' => 'desember', +}; + +my $T2H_WORDS_PT = +{ + 'Table of Contents' => 'Sumário', + 'Short Table of Contents' => 'Breve Sumário', + 'Index' => 'Índice', #Not sure ;-) + 'About This Document' => 'No translation available!', #No translation available! + 'Footnotes' => 'No translation available!', + 'See' => 'Veja', + 'see' => 'veja', + 'section' => 'Seção', + 'January' => 'Janeiro', + 'February' => 'Fevereiro', + 'March' => 'Março', + 'April' => 'Abril', + 'May' => 'Maio', + 'June' => 'Junho', + 'July' => 'Julho', + 'August' => 'Agosto', + 'September' => 'Setembro', + 'October' => 'Outubro', + 'November' => 'Novembro', + 'December' => 'Dezembro', +}; + +my $T2H_WORDS_FR = +{ + 'Table of Contents' => 'Table des matières', + 'Short Table of Contents' => 'Résumée du contenu', + 'Index' => 'Index', + 'About This Document' => 'A propos de ce document', + 'Footnotes' => 'Notes de bas de page', + 'See' => 'Voir', + 'see' => 'voir', + 'section' => 'section', + 'January' => 'Janvier', + 'February' => 'Février', + 'March' => 'Mars', + 'April' => 'Avril', + 'May' => 'Mai', + 'June' => 'Juin', + 'July' => 'Juillet', + 'August' => 'Août', + 'September' => 'Septembre', + 'October' => 'Octobre', + 'November' => 'Novembre', + 'December' => 'Décembre', + 'T2H_today' => 'le %2$d %1$s %3$d' +}; + +#$T2H_LANGUAGES = +#{ +# 'en' => $T2H_WORDS_EN, +# 'de' => $T2H_WORDS_DE, +# 'nl' => $T2H_WORDS_NL, +# 'es' => $T2H_WORDS_ES, +# 'no' => $T2H_WORDS_NO, +# 'pt' => $T2H_WORDS_PT, +# 'fr' => $T2H_WORDS_FR, +#}; + +sub set_language($) +{ + my $lang = shift; + if (defined($lang) && exists($Texi2HTML::Config::LANGUAGES->{$lang}) && defined($Texi2HTML::Config::LANGUAGES->{$lang})) + { + $language = $lang; + return 1; } + else + { + return 0; + } +} + +sub get_language() +{ + return $language; +} + +my @MONTH_NAMES = + ( + 'January', 'February', 'March', 'April', 'May', + 'June', 'July', 'August', 'September', 'October', + 'November', 'December' + ); + +# This is not used as code, but used to mark months as strings to be +# translated +if (0) +{ + my @mark_month_for_translation = ( + gdt('January'), + gdt('February'), + gdt('March'), + gdt('April'), + gdt('May'), + gdt('June'), + gdt('July'), + gdt('August'), + gdt('September'), + gdt('October'), + gdt('November'), + gdt('December') + ); +} + +my $I = \&get_string; + +sub pretty_date($) +{ + my $lang = shift; + my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); + + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); + $year += ($year < 70) ? 2000 : 1900; + return main::gdt('{month} {day}, {year}', { 'month' => main::gdt($MONTH_NAMES[$mon]), + 'day' => $mday, 'year' => $year }); +} + +my $error_no_en = 0; + +my %missing_strings; + +# arguments should already be converted +sub get_string($;$$) +{ + my $string = shift; + my $arguments = shift; + $arguments = undef if (!ref($arguments)); + my $state = shift; + # 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 $translated_string; + my $T2H_LANGUAGES = $Texi2HTML::Config::LANGUAGES; + if (! exists($T2H_LANGUAGES->{'en'})) + { + unless($error_no_en) + { + print STDERR "i18n: no LANGUAGES->{'en'} hash\n"; + $error_no_en = 1; + } + } + else + { + unless (exists ($T2H_LANGUAGES->{'en'}->{$string})) + { + unless (exists($missing_strings{$string})) + { + #print STDERR "i18n: missing string $string\n"; + $missing_strings{$string} = 1; + } + } + if (defined ($T2H_LANGUAGES->{$language}->{$string}) and + ($T2H_LANGUAGES->{$language}->{$string} ne '')) + { + $translated_string = $T2H_LANGUAGES->{$language}->{$string}; + } + elsif (defined ($T2H_LANGUAGES->{'en'}->{$string}) and + ($T2H_LANGUAGES->{'en'}->{$string} ne '')) + { + $translated_string = $T2H_LANGUAGES->{'en'}->{$string}; + } + else + { + $translated_string = $string; + } + } + return main::substitute_line($translated_string, "translation", $state) unless (defined($arguments) or !keys(%$arguments)); - if (/^\@image\s*{/) { - s/\@image\s*{//; - my (@args) = split (/,/); - my $base = $args[0]; - my $image; - if (-r "$base.jpg") { - $image = "$base.jpg"; - } elsif (-r "$base.png") { - $image = "$base.png"; - } elsif (-r "$base.gif") { - $image = "$base.gif"; - } else { - warn "$ERROR no image file for $base: $_"; - } - $_ = "\"$base\""; + # taken from libintl perl, copyright Guido. sub __expand + my %args = %$arguments; + my $re = join '|', map { quotemeta $_ } keys %args; + + if ($state->{'keep_texi'}) + { + $translated_string =~ s/\{($re)\}/defined $args{$1} ? $args{$1} : "{$1}"/ge; + return $translated_string; } - # - # try to guess bibliography references or glossary terms - # - unless (/^/) { - $done .= $pre . &anchor('', $href, $what); - } else { - $done .= "$pre$what"; - } - $_ = $post; - } - $_ = $done . $_; - } - if ($use_glossary) { - $done = ''; - while (/\b\w+\b/) { - ($pre, $what, $post) = ($`, $&, $'); - $entry = $what; - $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; - $href = $gloss2href{$entry}; - if (defined($href) && $post !~ /^[^<]*<\/A>/) { - $done .= $pre . &anchor('', $href, $what); - } else { - $done .= "$pre$what"; - } - $_ = $post; - } - $_ = $done . $_; - } + # if there are arguments, we must protect the {arg} constructs before + # doing substitute_line. So there is a first pass here to change {arg} + # to %@internal_translation_open_brace{}arg@internal_translation_close_brace{} + $translated_string =~ 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'} = '}'; } - # otherwise - push(@lines2, $_); + $translated_string = main::substitute_line($translated_string, "translation", $state); + $translated_string =~ s/\{($re)\}/defined $args{$1} ? $args{$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 $translated_string; + } -print "# end of pass 2\n" if $verbose; +1; +require "$T2H_HOME/T2h_i18n.pm" + if ($0 =~ /\.pl$/ && + -e "$T2H_HOME/T2h_i18n.pm" && -r "$T2H_HOME/T2h_i18n.pm"); +} + + +######################################################################### # -# split style substitutions +# latex2html code # -while (@lines2) { - $_ = shift(@lines2); - # - # special case (protected sections) - # - if (/^$PROTECTTAG/o) { - push(@lines3, $_); - next; +#---###################################################################### + +{ +# 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@ +#+############################################################################## +# +# T2h_l2h.pm: interface to LaTeX2HTML +# +# Copyright (C) 1999-2005 Patrice Dumas , +# Derek Price , +# Adrian Aichner , +# & others. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA +# +#-############################################################################## + +require 5.0; +use strict; + +package Texi2HTML::LaTeX2HTML; +use Cwd; + + +# latex2html conversions consist of three stages: +# 1) to latex: Put "latex" code into a latex file +# (init, to_latex, finish_to_latex) +# 2) to html: Use latex2html to generate corresponding html code and images +# (to_html) +# 3) from html: Extract generated code and images from latex2html run +# (init_from_html, do_tex) + +# init l2h defaults for files and names + +# global variable used for caching +# FIXME there is no reason for this variable to be global +use vars qw( + %l2h_cache + ); + +my ($l2h_name, $l2h_latex_file, $l2h_cache_file, $l2h_html_file, $l2h_prefix); + +# holds the status of latex2html operations. If 0 it means that there was +# an error +my $status = 0; + +my $debug; +my $verbose; +my $docu_rdir; +my $docu_name; + +# init_from_html +my $extract_error_count; +my $invalid_counter_count; + +# change_image_file_names +my %l2h_img; # associate src file to destination file + # such that files are not copied twice +my $image_count; + +# do_tex +my $html_output_count = 0; # html text outputed in html result file + +########################## +# +# First stage: Generation of Latex file +# Initialize with: init +# Add content with: to_latex ($text) --> HTML placeholder comment +# Finish with: finish_to_latex +# + +my $l2h_latex_preamble = <{'top'}}); + + $docu_name = $Texi2HTML::THISDOC{'file_base_name'}; + $docu_rdir = $Texi2HTML::THISDOC{'destination_directory'}; + $docu_rdir = '' if (!defined($docu_rdir)); + $l2h_name = "${docu_name}_l2h"; + $l2h_latex_file = "$docu_rdir${l2h_name}.tex"; + $l2h_cache_file = "${docu_rdir}${docu_name}-l2h_cache.pm"; + # destination dir -- generated images are put there, should be the same + # as dir of enclosing html document -- + $l2h_html_file = "$docu_rdir${l2h_name}.html"; + $l2h_prefix = "${l2h_name}_"; + $debug = $Texi2HTML::THISDOC{'debug_l2h'}; + $verbose = $Texi2HTML::Config::VERBOSE; + + unless ($Texi2HTML::Config::L2H_SKIP) + { + unless (open(L2H_LATEX, ">$l2h_latex_file")) + { + main::document_error ("l2h: Can't open latex file '$l2h_latex_file' for writing: $!"); + $status = 0; + return; + } + warn "# l2h: use ${l2h_latex_file} as latex file\n" if ($verbose); + print L2H_LATEX $l2h_latex_preamble; } - # - # split style substitutions - # - $old = ''; - while ($old ne $_) { - $old = $_; - if (/\@(\w+)\{/) { - ($before, $style, $after) = ($`, $1, $'); - if (defined($style_map{$style})) { - $_ = $after; - $text = ''; - $after = ''; - $failed = 1; - while (@lines2) { - if (/\}/) { - $text .= $`; - $after = $'; - $failed = 0; - last; - } else { - $text .= $_; - $_ = shift(@lines2); - } - } - if ($failed) { - die "* Bad syntax (\@$style) after: $before\n"; - } else { - $text = &apply_style($style, $text); - $_ = "$before$text$after"; - } - } - } + # open the database that holds cached text + init_cache() if (!defined($Texi2HTML::Config::L2H_SKIP) or $Texi2HTML::Config::L2H_SKIP); + $status = 1; +} + + +# print text (2nd arg) into latex file (if not already there nor in cache) +# which can be later on replaced by the latex2html generated text. +# +sub to_latex($$$) +{ + my $command = shift; + my $text = shift; + my $counter = shift; + return unless ($status); + if ($command eq 'tex') + { + $text .= ' '; } - # otherwise - push(@lines3, $_); + elsif ($command eq 'math') + { + $text = "\$".$text."\$"; + } + $to_latex_count++; + $text =~ s/(\s*)$//; + # try whether we have text already on things to do + my $count = $l2h_to_latex{$text}; + unless ($count) + { + $latex_count++; + $count = $latex_count; + # try whether we can get it from cache + my $cached_text = from_cache($text); + if (defined($cached_text)) + { + $cached_count++; + # put the cached result in the html result array + $l2h_from_html[$count] = $cached_text; + } + else + { + $latex_converted_count++; + unless ($Texi2HTML::Config::L2H_SKIP) + { + print L2H_LATEX "\\begin{rawhtml}\n\n"; + print L2H_LATEX "\n"; + print L2H_LATEX "\\end{rawhtml}\n"; + + print L2H_LATEX "$text\n"; + + print L2H_LATEX "\\begin{rawhtml}\n"; + print L2H_LATEX "\n\n"; + print L2H_LATEX "\\end{rawhtml}\n"; + } + } + $l2h_to_latex[$count] = $text; + $l2h_to_latex{$text} = $count; + } + $global_count{"${command}_$counter"} = $count; + return 1; } -print "# end of pass 3\n" if $verbose; +# print closing into latex file and close it +sub finish_to_latex() +{ + my $reused = $to_latex_count - $latex_converted_count - $cached_count; + unless ($Texi2HTML::Config::L2H_SKIP) + { + print L2H_LATEX $l2h_latex_closing; + close (L2H_LATEX); + } + warn "# l2h: finished to latex ($cached_count cached, $reused reused, $latex_converted_count to process)\n" if ($verbose); + unless ($latex_count) + { + # no @tex nor @math + finish(); + return 0; + } + return 1; +} + +################################### +# Second stage: Use latex2html to generate corresponding html code and images +# +# to_html([$l2h_latex_file, [$l2h_html_dir]]): +# Call latex2html on $l2h_latex_file +# Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir +# Return 1, on success +# 0, otherwise +# +sub to_html() +{ + my ($call, $dotbug); + # when there are no tex constructs to convert (happens in case everything + # comes from the cache), there is no latex2html run + if ($Texi2HTML::Config::L2H_SKIP or ($latex_converted_count == 0)) + { + warn "# l2h: skipping latex2html run\n" if ($verbose); + return 1; + } + # Check for dot in directory where dvips will work + if ($Texi2HTML::Config::L2H_TMP) + { + if ($Texi2HTML::Config::L2H_TMP =~ /\./) + { + main::document_warn ("l2h: l2h_tmp dir contains a dot."); + $dotbug = 1; + } + } + else + { + if (cwd() =~ /\./) + { + main::document_warn ("l2h: current dir contains a dot."); + $dotbug = 1; + } + } + # fix it, if necessary and hope that it works + #$Texi2HTML::Config::L2H_TMP = "/tmp" if ($dotbug); + return 0 if ($dotbug); + + $call = $Texi2HTML::Config::L2H_L2H; + # use init file, if specified + my $init_file = main::locate_init_file($Texi2HTML::Config::L2H_FILE); + $call = $call . " -init_file " . $init_file if ($init_file); + # set output dir + $call .= (($docu_rdir ne '') ? " -dir $docu_rdir" : " -no_subdir"); + # use l2h_tmp, if specified + $call .= " -tmp $Texi2HTML::Config::L2H_TMP" + if (defined($Texi2HTML::Config::L2H_TMP) and $Texi2HTML::Config::L2H_TMP ne ''); + # use a given html version if specified + $call .= " -html_version $Texi2HTML::Config::L2H_HTML_VERSION" + if (defined($Texi2HTML::Config::L2H_HTML_VERSION) and $Texi2HTML::Config::L2H_HTML_VERSION ne ''); + # options we want to be sure of + $call .= " -address 0 -info 0 -split 0 -no_navigation -no_auto_link"; + $call .= " -prefix $l2h_prefix $l2h_latex_file"; + + warn "# l2h: executing '$call'\n" if ($verbose); + if (system($call)) + { + main::document_error ("l2h: '${call}' did not succeed"); + return 0; + } + else + { + warn "# l2h: latex2html finished successfully\n" if ($verbose); + return 1; + } +} + +########################## +# Third stage: Extract generated contents from latex2html run +# Initialize with: init_from_html +# open $l2h_html_file for reading +# reads in contents into array indexed by numbers +# return 1, on success -- 0, otherwise +# Finish with: finish +# closes $l2h_html_dir/$l2h_name.".$docu_ext" + + +# the images generated by latex2html have names like ${docu_name}_l2h_img?.png +# they are copied to ${docu_name}_?.png, and html is changed accordingly. + +# FIXME is it really necessary to bother doing that? Looks like an unneeded +# complication to me (pertusus, 2009), and it could go bad if there is some +# SRC="(.*?)" in the text (though the regexp could be made more specific). + +# %l2h_img; # associate src file to destination file + # such that files are not copied twice +sub change_image_file_names($) +{ + my $content = shift; + my @images = ($content =~ /SRC="(.*?)"/g); + my ($src, $dest); + + for $src (@images) + { + $dest = $l2h_img{$src}; + unless ($dest) + { + my $ext = ''; + if ($src =~ /.*\.(.*)$/ and (!defined($Texi2HTML::THISDOC{'extension'}) or $1 ne $Texi2HTML::THISDOC{'extension'})) + { + $ext = ".$1"; + } + else + { # A warning when the image extension is the same than the + # document extension. copying the file could result in + # overwriting an output file (almost surely if the default + # texi2html file names are used). + main::document_warn ("L2h image $src has invalid extension"); + next; + } + while (-e "$docu_rdir${docu_name}_${image_count}$ext") + { + $image_count++; + } + $dest = "${docu_name}_${image_count}$ext"; + if ($debug) + { + # not portable, but only used with debug. + system("cp -f $docu_rdir$src $docu_rdir$dest"); + } + else + { + # FIXME error condition not checked. + rename ("$docu_rdir$src", "$docu_rdir$dest"); + } + $l2h_img{$src} = $dest; + #unlink "$docu_rdir$src" unless ($debug); + } + $content =~ s/SRC="$src"/SRC="$dest"/g; + } + return $content; +} + +sub init_from_html() +{ + # when there are no tex constructs to convert (happens in case everything + # comes from the cache), the html file that was generated by previous + # latex2html runs isn't reused. + if ($latex_converted_count == 0) + { + return 1; + } + + if (! open(L2H_HTML, "<$l2h_html_file")) + { + main::document_warn ("l2h: Can't open $l2h_html_file for reading"); + return 0; + } + warn "# l2h: use $l2h_html_file as html file\n" if ($verbose); + + my $html_converted_count = 0; # number of html resulting texts + # retrieved in the file + + my ($count, $h_line); + while ($h_line = ) + { + if ($h_line =~ /!-- l2h_begin $l2h_name ([0-9]+) --/) + { + $count = $1; + my $h_content = ''; + my $h_end_found = 0; + while ($h_line = ) + { + if ($h_line =~ /!-- l2h_end $l2h_name $count --/) + { + $h_end_found = 1; + chomp $h_content; + chomp $h_content; + $html_converted_count++; + # transform image file names and copy image files + $h_content = change_image_file_names($h_content); + # store result in the html result array + $l2h_from_html[$count] = $h_content; + # also add the result in cache hash + $l2h_cache{$l2h_to_latex[$count]} = $h_content; + last; + } + $h_content = $h_content.$h_line; + } + unless ($h_end_found) + { # couldn't found the closing comment. Certainly a bug. + main::msg_debug ("l2h: l2h_end $l2h_name $count not found"); + close(L2H_HTML); + return 0; + } + } + } + + # Not the same number of converted elements and retrieved elements + if ($latex_converted_count != $html_converted_count) + { + main::msg_debug ("l2h: waiting for $latex_converted_count elements found $html_converted_count"); + } + + warn "# l2h: Got $html_converted_count of $latex_count html contents\n" + if ($verbose); + + close(L2H_HTML); + return 1; +} + +# $html_output_count = 0; # html text outputed in html result file + +# called each time a construct handled by latex2html is encountered, should +# output the corresponding html +sub do_tex($$$$) +{ + my $style = shift; + my $counter = shift; + my $state = shift; + return unless ($status); + my $count = $global_count{"${style}_$counter"}; + ################################## begin debug section (incorrect counts) + if (!defined($count)) + { + # counter is undefined + $invalid_counter_count++; + main::msg_debug ("l2h: undefined count for ${style}_$counter"); + return ("") + if ($debug); + return ''; + } + elsif(($count <= 0) or ($count > $latex_count)) + { + # counter out of range + $invalid_counter_count++; + main::msg_debug ("l2h: Request of $count content which is out of valide range [0,$latex_count)"); + return ("") + if ($debug); + return ''; + } + ################################## end debug section (incorrect counts) + + # this seems to be a valid counter + my $result = ''; + $result = "" if ($debug); + if (defined($l2h_from_html[$count])) + { + $html_output_count++; + # maybe we could also have something if simple_format + # with Texi2HTML::Config::protect_text in case there + # was some @math on a line passed through simple_format. + # This would certainly be illegal texinfo, however. + if ($state->{'remove_texi'}) + {# don't protect anything + $result .= $l2h_to_latex[$count]; + } + else + { + $result .= $l2h_from_html[$count]; + } + } + else + { + # if the result is not in @l2h_from_html, there is an error somewhere. + $extract_error_count++; + main::msg_debug ("l2h: can't extract content $count from html"); + # try simple (ordinary) substitution (without l2h) + $result .= "" if ($debug); + $result .= main::substitute_text({}, undef, 'error in l2h', $l2h_to_latex[$count]); + } + $result .= "" if ($debug); + return $result; +} + +# store results in the cache and remove temporary files. +sub finish() +{ + return unless($status); + if ($verbose) + { + if ($extract_error_count + $invalid_counter_count) + { + warn "# l2h: finished from html ($extract_error_count extract and $invalid_counter_count invalid counter errors)\n"; + } + else + { + warn "# l2h: finished from html (no error)\n"; + } + if ($html_output_count != $latex_converted_count) + { # this may happen if @-commands are collected at some places + # but @-command at those places are not expanded later. For + # example @math on @multitable lines. + warn "# l2h: $html_output_count html outputed for $latex_converted_count converted\n"; + } + } + store_cache(); + if ($Texi2HTML::Config::L2H_CLEAN) + { + local ($_); + warn "# l2h: removing temporary files generated by l2h extension\n" + if $verbose; + while (<"$docu_rdir$l2h_name"*>) + { +# FIXME error condition not checked + unlink $_; + } + } + warn "# l2h: Finished\n" if $verbose; + return 1; +} + +# the driver of end of first pass and second pass +# +sub latex2html() +{ + return unless($status); + return unless ($status = finish_to_latex()); + return unless ($status = to_html()); +} + + +############################## +# stuff for l2h caching +# +# FIXME it is clear that l2h stuff takes very long compared with texi2html +# which is already quite long. However this also adds some complexity + +# I tried doing this with a dbm data base, but it did not store all +# keys/values. Hence, I did as latex2html does it +sub init_cache +{ + if (-r "$l2h_cache_file") + { + my $rdo = do "$l2h_cache_file"; + main::document_error ("l2h: could not load $docu_rdir$l2h_cache_file: $@") + unless ($rdo); + } +} + +# store all the text obtained through latex2html +sub store_cache +{ + return unless $latex_count; + my ($key, $value); + unless (open(FH, ">$l2h_cache_file")) + { + main::document_error ("l2h: could not open $docu_rdir$l2h_cache_file for writing: $!"); + return; + } + while (($key, $value) = each %l2h_cache) + { + # escape stuff + $key =~ s|/|\\/|g; + $key =~ s|\\\\/|\\/|g; + # weird, a \ at the end of the key results in an error + # maybe this also broke the dbm database stuff + $key =~ s|\\$|\\\\|; + $value =~ s/\|/\\\|/go; + $value =~ s/\\\\\|/\\\|/go; + $value =~ s|\\\\|\\\\\\\\|g; + print FH "\n\$l2h_cache_key = q/$key/;\n"; + print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n"; + } + print FH "1;"; + close (FH); +} + +# return cached html, if it exists for text, and if all pictures +# are there, as well +sub from_cache($) +{ + my $text = shift; + my $cached = $l2h_cache{$text}; + if (defined($cached)) + { + while ($cached =~ m/SRC="(.*?)"/g) + { + unless (-e "$docu_rdir$1") + { + return undef; + } + } + return $cached; + } + return undef; +} + +1; + +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@ + +###################################################################### +# from here on, its l2h init stuff +# + +## initialization for latex2html as for Singular manual generation +## obachman 3/99 + +# +# Options controlling Titles, File-Names, Tracing and Sectioning +# +$TITLE = ''; + +$SHORTEXTN = 0; + +$LONG_TITLES = 0; + +#$DESTDIR = ''; + +$NO_SUBDIR = 1; + +#$PREFIX = ''; + +$AUTO_PREFIX = 0; + +$AUTO_LINK = 0; + +$SPLIT = 0; + +$MAX_LINK_DEPTH = 0; + +#$TMP = ''; + +$DEBUG = 0; + +$VERBOSE = 1; + +# +# Options controlling Extensions and Special Features +# +#$HTML_VERSION = "3.2"; # set by command line + +$TEXDEFS = 1; # we absolutely need that + +$EXTERNAL_FILE = ''; + +$SCALABLE_FONTS = 1; + +$NO_SIMPLE_MATH = 1; + +$LOCAL_ICONS = 1; + +$SHORT_INDEX = 0; + +$NO_FOOTNODE = 1; + +$ADDRESS = ''; + +$INFO = ''; + +# +# Switches controlling Image Generation +# +$ASCII_MODE = 0; + +$NOLATEX = 0; + +$EXTERNAL_IMAGES = 0; + +$PS_IMAGES = 0; + +$NO_IMAGES = 0; + +$IMAGES_ONLY = 0; + +$REUSE = 2; + +$ANTI_ALIAS = 1; + +$ANTI_ALIAS_TEXT = 1; + +# +#Switches controlling Navigation Panels +# +$NO_NAVIGATION = 1; +$ADDRESS = ''; +$INFO = 0; # 0 = do not make a "About this document..." section + +# +#Switches for Linking to other documents +# +# currently -- we don't care + +$MAX_SPLIT_DEPTH = 0; # Stop making separate files at this depth + +$MAX_LINK_DEPTH = 0; # Stop showing child nodes at this depth + +$NOLATEX = 0; # 1 = do not pass unknown environments to Latex + +$EXTERNAL_IMAGES = 0; # 1 = leave the images outside the document + +$ASCII_MODE = 0; # 1 = do not use any icons or internal images + +# 1 = use links to external postscript images rather than inlined bitmap +# images. +$PS_IMAGES = 0; +$SHOW_SECTION_NUMBERS = 0; + +### Other global variables ############################################### + +# put dvips stderr on stdout since latex2html is alread very verbose +$DVIPS = "$DVIPS ".' 2>&1'; + +$CHILDLINE = ""; + +# This is the line width measured in pixels and it is used to right justify +# equations and equation arrays; +$LINE_WIDTH = 500; + +# Used in conjunction with AUTO_NAVIGATION +$WORDS_IN_PAGE = 300; + +# The value of this variable determines how many words to use in each +# title that is added to the navigation panel (see below) +# +$WORDS_IN_NAVIGATION_PANEL_TITLES = 0; + +# This number will determine the size of the equations, special characters, +# and anything which will be converted into an inlined image +# *except* "image generating environments" such as "figure", "table" +# or "minipage". +# Effective values are those greater than 0. +# Sensible values are between 0.1 - 4. +$MATH_SCALE_FACTOR = 1.5; + +# This number will determine the size of +# image generating environments such as "figure", "table" or "minipage". +# Effective values are those greater than 0. +# Sensible values are between 0.1 - 4. +$FIGURE_SCALE_FACTOR = 1.6; + + +# If both of the following two variables are set then the "Up" button +# of the navigation panel in the first node/page of a converted document +# will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set +# to some text which describes this external link. +$EXTERNAL_UP_LINK = ""; +$EXTERNAL_UP_TITLE = ""; + +# If this is set then the resulting HTML will look marginally better if viewed +# with Netscape. +$NETSCAPE_HTML = 1; + +# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0" +# Paper sizes has no effect other than in the time it takes to create inlined +# images and in whether large images can be created at all ie +# - larger paper sizes *MAY* help with large image problems +# - smaller paper sizes are quicker to handle +$PAPERSIZE = "a4"; + +# Replace "english" with another language in order to tell LaTeX2HTML that you +# want some generated section titles (eg "Table of Contents" or "References") +# to appear in a different language. Currently only "english" and "french" +# is supported but it is very easy to add your own. See the example in the +# file "latex2html.config" +$TITLES_LANGUAGE = "english"; + +1; # This must be the last non-comment line + +# End File l2h.init +###################################################################### + +} + +package main; + +if (!defined(Texi2HTML::Config::get_conf('use_nls'))) +{ + my $use_nls = ('yes' eq 'yes' or $0 =~ /\.pl$/); + Texi2HTML::Config::set_conf('use_nls', $use_nls); +} + +# 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. + +my $strings_textdomain = 'texi2html' . '_document'; +$strings_textdomain = 'texi2html_document' if ($strings_textdomain eq '@'.'PACKAGE@' . '_document'); +my $messages_textdomain = 'texi2html'; +$messages_textdomain = 'texi2html' if ($messages_textdomain eq '@'.'PACKAGE@'); + +#my $messages_textdomain = 'texinfo'; + +if (Texi2HTML::Config::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 ('no' 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"); +} +else +{ + unshift @INC, "$pkgdatadir/lib/libintl-perl/lib"; + require Locale::Messages; +} + +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' => { 'prefixes' => {'cp' => 0,'c' => 0}}, + 'fn' => { 'prefixes' => {'fn' => 1, 'f' => 1}}, + 'vr' => { 'prefixes' => {'vr' => 1, 'v' => 1}}, + 'ky' => { 'prefixes' => {'ky' => 1, 'k' => 1}}, + 'pg' => { 'prefixes' => {'pg' => 1, 'p' => 1}}, + 'tp' => { 'prefixes' => {'tp' => 1, 't' => 1}} +); + +foreach my $name(keys(%index_names)) +{ + foreach my $prefix (keys %{$index_names{$name}->{'prefixes'}}) + { + $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', 'Following', '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); +} + +foreach my $key (keys(%Texi2HTML::Config::misc_command), keys(%reference_sec2level)) +{ + set_no_line_macro($key, 1); +} + +# 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); +} + +# 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)) +{ + 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"})); +} + + + #+++############################################################################ # # -# Pass 4: foot notes, final cleanup # +# Argument parsing, initialisation # # # #---############################################################################ -@foot_lines = (); # footnotes -@doc_lines = (); # final document -$end_of_para = 0; # true if last line is

    +# shorthand for Texi2HTML::Config::VERBOSE +my $T2H_VERBOSE; +my $T2H_DEBUG; -while (@lines3) { - $_ = shift(@lines3); - # - # special case (protected sections) - # - if (/^$PROTECTTAG/o) { - push(@doc_lines, $_); - $end_of_para = 0; - next; +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; + +# file: file name to locate. It can be a file path. +# all_files: if true collect all the files with that name, otherwise stop +# at first match. +# directories: a reference on a array containing a list of directories to +# search the file in. default is +# @Texi2HTML::Config::CONF_DIRS, @program_config_dirs. +sub locate_init_file($;$$) +{ + my $file = shift; + my $all_files = shift; + my $directories = shift; + + if (!defined($directories)) + { + if ($all_files) + { + $directories = [ @program_config_dirs ]; + } + else + { + $directories = [ @Texi2HTML::Config::CONF_DIRS, @program_init_dirs ]; + } } - # - # footnotes - # - while (/\@footnote([^\{\s]+)\{/) { - ($before, $d, $after) = ($`, $1, $'); - $_ = $after; - $text = ''; - $after = ''; - $failed = 1; - while (@lines3) { - if (/\}/) { - $text .= $`; - $after = $'; - $failed = 0; - last; - } else { - $text .= $_; - $_ = shift(@lines3); - } - } - if ($failed) { - die "* Bad syntax (\@footnote) after: $before\n"; - } else { - $foot_num++; - $docid = "DOCF$foot_num"; - $footid = "FOOT$foot_num"; - $foot = "($foot_num)"; - push(@foot_lines, "

    " . &anchor($footid, "$d#$docid", $foot) . "

    \n"); - $text = "

    $text" unless $text =~ /^\s*

    /; - push(@foot_lines, "$text\n"); - $_ = $before . &anchor($docid, "$docu_foot#$footid", $foot) . $after; - } + + if ($file =~ /^\//) + { + return $file if (-e $file and -r $file); } - # - # remove unnecessary

    - # - if (/^\s*

    \s*$/) { - next if $end_of_para++; - } else { - $end_of_para = 0; + 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); } - # otherwise - push(@doc_lines, $_); + return undef; } -print "# end of pass 4\n" if $verbose; +# 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; + if ($file = locate_init_file($init_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 (!$Texi2HTML::Config::TEST) + { + print STDERR "# Setting date in $language\n" if ($T2H_DEBUG); + $Texi2HTML::THISDOC{'today'} = Texi2HTML::I18n::pretty_date($language); # like "20 September 1993"; + } + else + { + $Texi2HTML::THISDOC{'today'} = 'a sunny day'; + } + $Texi2HTML::THISDOC{'today'} = $Texi2HTML::Config::DATE + if (defined($Texi2HTML::Config::DATE)); + $::things_map_ref->{'today'} = $Texi2HTML::THISDOC{'today'}; + $::pre_map_ref->{'today'} = $Texi2HTML::THISDOC{'today'}; + $::texi_map_ref->{'today'} = $Texi2HTML::THISDOC{'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 $silent = shift; + my $line_nr = shift; + + my @langs = ($lang); + +# my $lang_code = $lang; +# my $region_code; + + my $main_lang; + + if ($lang =~ /^([a-z]+)_([A-Z]+)/) + { + $main_lang = $1; +# $region_code = $2; +# $lang_code = $main_lang; + push @langs, $main_lang; + } + +# if (!$silent) +# { +# if (! $Texi2HTML::Config::language_codes{$lang_code}) +# { # i18n +# msg_warn("$lang_code is not a valid language code.", $line_nr); +# } +# if (defined($region_code) and ! $Texi2HTML::Config::region_codes{$region_code}) +# { # i18n +# msg_warn("$region_code is not a valid region code.", $line_nr); +# } +# } + # Always succeed if using a gettext-like environment + if (!$Texi2HTML::Config::I18N_PERL_HASH) + { + set_date($lang); + return 1; + } + + my @files = locate_init_file("$i18n_dir/$lang.thl", 1); + if (! scalar(@files) and defined($main_lang)) + { + @files = locate_init_file("$i18n_dir/$main_lang.thl", 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); + # since it may be different from get_conf('documentlanguage'), + # we record it. + # Currently this is not used anywhere, not sure what the value + # really corresponds with. + $Texi2HTML::THISDOC{'current_language'} = $language; + 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') + { + Texi2HTML::Config::set_conf($command, $value, !$from_command_line); + } + 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); + } +} + + +# find the encoding alias. +# with encoding support (USE_UNICODE), may return undef if no alias was found +sub encoding_alias($;$$) +{ + my $encoding = shift; + my $line_nr = shift; + my $context_string = shift; + return undef if (!defined($encoding) or $encoding eq ''); + if ($Texi2HTML::Config::USE_UNICODE) + { + my $result_encoding = Encode::resolve_alias($encoding); + if (! $result_encoding) + { + msg_warn(sprintf(__("unrecognized encoding name `%s'"), $encoding), $line_nr, $context_string); + 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}; + document_warn (__("Document encoding is utf8, but there is no unicode support")) if ($encoding eq 'utf-8'); + return $encoding; + } + msg_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 $Texi2HTML::Config::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 = lc(Texi2HTML::Config::get_conf('DOCUMENT_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 ($Texi2HTML::Config::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 (Texi2HTML::Config::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 = Texi2HTML::Config::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; +} + +my %nodes; # nodes hash. The key is the texi node name +my %cross_reference_nodes; # normalized node names arrays + +# +# %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 +my %value_initial = + ( + 'html' => 1, + 'texi2html' => $THISVERSION, + ); + +# +# _foo: internal variables to track @foo +# +foreach my $key ('_author', '_title', '_subtitle', '_shorttitlepage', + '_settitle', '_titlefont') +{ + $value_initial{$key} = ''; # prevent -w warnings +} + + +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 ($Texi2HTML::Config::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; +} + +# 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') + { + Texi2HTML::Config::set_conf($command, $value, !$from_command_line); + } + 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); + } +} + +# 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 -> {'debug'} = +{ + type => '=i', + linkage => \$Texi2HTML::Config::DEBUG, + verbose => 'output HTML with debuging information', +}; + +$T2H_OPTIONS -> {'doctype'} = +{ + type => '=s', + linkage => sub {Texi2HTML::Config::set_conf('doctype', $_[1]);}, + verbose => 'document type which is output in header of HTML files', + noHelp => 1 +}; + +$T2H_OPTIONS -> {'frameset-doctype'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::FRAMESET_DOCTYPE, + verbose => 'document type for HTML frameset documents', + noHelp => 1 +}; + +$T2H_OPTIONS -> {'test'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::TEST, + verbose => 'use predefined information to avoid differences with reference files', + noHelp => 1 +}; + +$T2H_OPTIONS -> {'dump-texi'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::DUMP_TEXI, + verbose => 'dump the output of first pass into a file with extension passfirst and exit', + noHelp => 1 +}; + +$T2H_OPTIONS -> {'macro-expand|E'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::MACRO_EXPAND, + 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 -> {'iso'} = +{ + type => 'iso', + linkage => sub {Texi2HTML::Config::t2h_default_set_iso_symbols ($_[1]);}, + verbose => 'if set, entities are used for special symbols (like copyright, etc...) and quotes', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'I'} = +{ + type => '=s', + linkage => \@Texi2HTML::Config::INCLUDE_DIRS, + 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 -> {'top-file'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::TOP_FILE, + verbose => 'use $s as top file, instead of .html', +}; + +$T2H_OPTIONS -> {'toc-file'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::TOC_FILE, + verbose => 'use $s as ToC file, instead of _toc.html', +}; + +$T2H_OPTIONS -> {'frames'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::FRAMES, + verbose => 'output files which use HTML 4.0 frames (experimental)', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'menu'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::SHOW_MENU, + verbose => 'output Texinfo menus', +}; + +$T2H_OPTIONS -> {'number-sections'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::NUMBER_SECTIONS, + verbose => 'output chapter and sectioning numbers.', +}; + +$T2H_OPTIONS -> {'number-footnotes'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::NUMBER_FOOTNOTES, + verbose => 'output footnote numbers.', +}; + +$T2H_OPTIONS -> {'use-nodes'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::USE_NODES, + verbose => 'use nodes for sectioning', +}; + +$T2H_OPTIONS -> {'node-files'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::NODE_FILES, + 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 -> {'toc-links'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::TOC_LINKS, + verbose => 'create links from headings to toc entries' +}; + +$T2H_OPTIONS -> {'split'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::SPLIT, + verbose => 'split document on section|chapter|node else no splitting', +}; + +$T2H_OPTIONS -> {'no-split'} = +{ + type => '!', + linkage => sub {$Texi2HTML::Config::SPLIT = ''; $Texi2HTML::Config::SPLIT_SIZE = undef;}, + verbose => 'no splitting of document', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'headers'} = +{ + type => '!', + linkage => sub { + Texi2HTML::Config::set_conf('headers', $_[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 -> {'subdir'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::SUBDIR, + verbose => 'put files in directory $s, not $cwd', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'short-ext'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::SHORTEXTN, + verbose => 'use "htm" extension for output HTML files', +}; + +$T2H_OPTIONS -> {'prefix'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::PREFIX, + verbose => 'use as prefix for output files, instead of ', +}; + +$T2H_OPTIONS -> {'output|out|o'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::OUT, + verbose => 'output goes to $s (directory if split)', +}; + +$T2H_OPTIONS -> {'no-validate|no-pointer-validate'} = +{ + type => '', + linkage => sub {Texi2HTML::Config::set_conf('novalidate',$_[1])}, + verbose => 'suppress node cross-reference validation', +}; + +$T2H_OPTIONS -> {'no-warn'} = +{ + type => '', + linkage => \$Texi2HTML::Config::NO_WARN, + verbose => 'suppress warnings (but not errors).' +}; + +$T2H_OPTIONS -> {'short-ref'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::SHORT_REF, + verbose => 'if set, references are without section numbers', +}; + +$T2H_OPTIONS -> {'idx-sum'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::IDX_SUMMARY, + verbose => 'if set, also output index summary', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'def-table'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::DEF_TABLE, + verbose => 'if set, \@def.. are converted using tables.', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'verbose'} = 0; +$T2H_OPTIONS -> {'verbose|v'} = +{ + type => '!', + linkage=> \$Texi2HTML::Config::VERBOSE, + verbose => 'print progress info to stdout', +}; + +$T2H_OPTIONS -> {'document-language'} = +{ + type => '=s', + linkage => sub { + warn_unknown_language ($_[1]); + Texi2HTML::Config::set_conf('documentlanguage', $_[1]) + }, + verbose => 'use $s as document language', +}; + +$T2H_OPTIONS -> {'ignore-preamble-text'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::IGNORE_PREAMBLE_TEXT, + verbose => 'if set, ignore the text before @node and sectioning commands', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'html-xref-prefix'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::EXTERNAL_DIR, + verbose => '$s is the base dir for external manual references', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'l2h'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::L2H, + verbose => 'if set, uses latex2html for @math and @tex', +}; + +$T2H_OPTIONS -> {'l2h-l2h'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::L2H_L2H, + verbose => 'program to use for latex2html translation', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'l2h-skip'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::L2H_SKIP, + verbose => 'if set, tries to reuse previously latex2html output', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'l2h-tmp'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::L2H_TMP, + verbose => 'if set, uses $s as temporary latex2html directory', + noHelp => 1, +}; + +$T2H_OPTIONS -> {'l2h-file'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::L2H_FILE, + verbose => 'if set, uses $s as latex2html init file', + noHelp => 1, +}; + + +$T2H_OPTIONS -> {'l2h-clean'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::L2H_CLEAN, + verbose => 'if set, do not keep intermediate latex2html files for later reuse', + noHelp => 1, +}; + +$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 -> {'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=> \$Texi2HTML::Config::TRANSLITERATE_FILE_NAMES, + verbose => 'produce file names in ASCII transliteration', +}; + +$T2H_OPTIONS -> {'error-limit|e'} = +{ + type => '=i', + linkage => \$Texi2HTML::Config::ERROR_LIMIT, + verbose => 'quit after NUM errors (default 1000).', +}; + +$T2H_OPTIONS -> {'split-size'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::SPLIT_SIZE, + verbose => 'split Info files at size s (default 300000).', +}; + +$T2H_OPTIONS -> {'paragraph-indent|p'} = +{ + type => '=s', + linkage => sub {set_paragraphindent($_[1], 1);}, + 'verbose' => "indent Info paragraphs by VAL spaces (default 3). + If VAL is `none', do not indent; if VAL is + `asis', preserve existing indentation.", +}; + +$T2H_OPTIONS -> {'fill-column|f'} = +{ + type => '=i', + linkage => sub {Texi2HTML::Config::set_conf('fillcolumn',$_[1]);}, + 'verbose' => "break Info lines at NUM characters (default 72).", +}; + +$T2H_OPTIONS -> {'enable-encoding'} = +{ + type => '', + linkage => \$Texi2HTML::Config::ENABLE_ENCODING, + verbose => 'override --disable-encoding (default in Info).', +}; + +$T2H_OPTIONS -> {'disable-encoding'} = +{ + type => '', + linkage => sub {$Texi2HTML::Config::ENABLE_ENCODING = 0}, + verbose => 'do not output accented and special characters + in Info output based on @documentencoding.', +}; + +$T2H_OPTIONS -> {'internal-links'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::INTERNAL_LINKS, + verbose => 'produce list of internal links in FILE.' +}; + +$T2H_OPTIONS -> {'force|F'} = +{ type => '!', + linkage => \$Texi2HTML::Config::FORCE, + verbose => 'preserve output even if errors.' +}; + +$T2H_OPTIONS -> {'monolithic'} = +{ + type => '!', + linkage => \$Texi2HTML::Config::MONOLITHIC, + verbose => 'output only one file including ToC, About...', + noHelp => 1 +}; + +$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' +}; + +$T2H_OPTIONS -> {'program'} = +{ + type => '=s', + linkage => sub {set_config_init_dirs_output($_[1]);}, + 'verbose' => 'Call as $s, setting corresponding defaults' +}; + +#$T2H_OPTIONS -> {'command'} = +#{ +# type => '=s', +# linkage => \@Texi2HTML::Config::COMMANDS, +# verbose => 'insert CMD in copy of input file' +#}; + + +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); + $T2H_OPTIONS -> {$output_format} = + { + type => '', + linkage => sub {Texi2HTML::Config::t2h_default_load_format($_[0], 1);}, + 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 +}; + +## +## obsolete cmd line options +## +my $T2H_OBSOLETE_OPTIONS; + +# actually a noop, since it is not used anywhere +$T2H_OBSOLETE_OPTIONS -> {'invisible'} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::INVISIBLE_MARK, + verbose => 'use text in invisble anchor', + noHelp => 2, +}; + +$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 {$Texi2HTML::Config::OUT = $_[1]; $Texi2HTML::Config::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 {Texi2HTML::Config::set_conf('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=> \$Texi2HTML::Config::VERBOSE, + 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 => \$Texi2HTML::Config::L2H_CLEAN, + verbose => 'obsolete, use "-l2h-clean" instead', + noHelp => 2, +}; + +$T2H_OBSOLETE_OPTIONS -> {l2h_l2h} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::L2H_L2H, + verbose => 'obsolete, use "-l2h-l2h" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {l2h_skip} = +{ + type => '!', + linkage => \$Texi2HTML::Config::L2H_SKIP, + verbose => 'obsolete, use "-l2h-skip" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {l2h_tmp} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::L2H_TMP, + verbose => 'obsolete, use "-l2h-tmp" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {out_file} = +{ + type => '=s', + linkage => sub {$Texi2HTML::Config::OUT = $_[1]; $Texi2HTML::Config::SPLIT = '';}, + verbose => 'obsolete, use "-out-file" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {short_ref} = +{ + type => '!', + linkage => \$Texi2HTML::Config::SHORT_REF, + verbose => 'obsolete, use "-short-ref" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {idx_sum} = +{ + type => '!', + linkage => \$Texi2HTML::Config::IDX_SUMMARY, + verbose => 'obsolete, use "-idx-sum" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {def_table} = +{ + type => '!', + linkage => \$Texi2HTML::Config::DEF_TABLE, + verbose => 'obsolete, use "-def-table" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {short_ext} = +{ + type => '!', + linkage => \$Texi2HTML::Config::SHORTEXTN, + verbose => 'obsolete, use "-short-ext" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {sec_nav} = +{ + type => '!', + linkage => sub {Texi2HTML::Config::set_conf('headers', $_[1]);}, + verbose => 'obsolete, use "-headers" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {'sec-nav'} = +{ + type => '!', + linkage => sub {Texi2HTML::Config::set_conf('headers', $_[1]);}, + verbose => 'obsolete, use "--header" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {top_file} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::TOP_FILE, + verbose => 'obsolete, use "-top-file" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {toc_file} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::TOC_FILE, + verbose => 'obsolete, use "-toc-file" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {glossary} = +{ + type => '!', + linkage => \$Texi2HTML::Config::USE_GLOSSARY, + 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 => \$Texi2HTML::Config::DUMP_TEXI, + verbose => 'obsolete, use "-dump-texi" instead', + noHelp => 1 +}; + +$T2H_OBSOLETE_OPTIONS -> {frameset_doctype} = +{ + type => '=s', + linkage => \$Texi2HTML::Config::FRAMESET_DOCTYPE, + verbose => 'obsolete, use "-frameset-doctype" instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {'no-section_navigation'} = +{ + type => '!', + linkage => sub {Texi2HTML::Config::set_conf('headers', 0);}, + verbose => 'obsolete, use -nosec_nav', + noHelp => 2, +}; +my $use_acc; # not used +$T2H_OBSOLETE_OPTIONS -> {use_acc} = +{ + type => '!', + linkage => \$use_acc, + 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{$Texi2HTML::Config::SPLIT = 'section';}, + verbose => 'obsolete, use "-split section" instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {split_chapter} = +{ + type => '!', + linkage => sub{$Texi2HTML::Config::SPLIT = 'chapter';}, + verbose => 'obsolete, use "-split chapter" instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {no_verbose} = +{ + type => '!', + linkage => sub {$Texi2HTML::Config::VERBOSE = 0;}, + verbose => 'obsolete, use -noverbose instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {output_file} = +{ + type => '=s', + linkage => sub {$Texi2HTML::Config::OUT = $_[1]; $Texi2HTML::Config::SPLIT = '';}, + verbose => 'obsolete, use --out-file instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {section_navigation} = +{ + type => '!', + linkage => sub {Texi2HTML::Config::set_conf('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, 1)) +{ + print STDERR "# reading initialization file from $file\n" if ($T2H_VERBOSE); + Texi2HTML::Config::load($file); +} + + #+++############################################################################ # # -# Pass 5: print things # +# parse command-line options # # #---############################################################################ -$header = < +# 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. +# dump-texi', 'debug', 'test' are for debugging. +# 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 = ('dump-texi', 'debug', 'test', 'conf-dir', 'init-file', +'split', 'program'); + +# --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). + -v, --verbose explain what is being done. + --version display version information and exit.\n"), $Texi2HTML::Config::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. + --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 HTML).\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"), + $Texi2HTML::Config::FILLCOLUMN, $Texi2HTML::Config::PARAGRAPHINDENT, $Texi2HTML::Config::SPLIT_SIZE) +."\n"; +$makeinfo_help .= __("Options for HTML: + --css-include=FILE include FILE in HTML