# -*-perl-*-
######################################################################
# File: texi2html.init
#
# 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 <your_init_file>
#
# $Id: texi2html.init,v 1.173 2009/01/01 22:35:10 pertusus Exp $

######################################################################
# The following variables can also be set by command-line options
#
#
# 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/texi2htmlrc 
# and then by values set in $HOME/texi2htmlrc.
#
# 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.

# -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 = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">';

# -frameset-doctype
# 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/html401/frameset.dtd">';

# -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 of test.sh.
$TEST = 0;

# -dump-texi
# This value is usefull for debugging purposes. The result of the first pass is
# put in <document name>.passtexi, the result of the second pass is put in 
# <document name>.passfirst.
$DUMP_TEXI = 0;

# -expand
# the @EXPAND array contains the expanded section names.
@EXPAND = ('html');

# -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 = '&#160;';

# -iso
# if this value is true, ISO8859 characters are used for special symbols 
# (like copyright, etc).
$USE_ISO = 1;

# -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 = (".");
@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 = ();

# --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, <basename of document>.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, <basename of document>_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 | -nomenu
# if the value is true the Texinfo menus are shown.
$SHOW_MENU = 1;

# -number | -nonumber
# 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;

# -use-nodes
# if this is set the nodes are used as sectionning elements. 
# Otherwise the nodes are incorporated in sections.
#$USE_NODES = 0;
$USE_NODES = undef;

$USE_SECTIONS = 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;

# -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 sectionning 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 = '';

# -sec-nav|-nosec-nav
# 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.
#
# Navigation panels are always printed at the beginning of output files.
#
# 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.
$SECTION_NAVIGATION = 1;

# -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).
$SEPARATED_FOOTNOTES = 1;

# -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 = '';

# -o filename
# If this is set a monolithic document is outputted into $filename.
$OUT = '';

# -no-validate
# suppress node cross-reference validation
$NOVALIDATE = 0;

# -short-ref
# if this is set cross-references are given without section numbers.
$SHORT_REF = '';

# -idx-sum
# if value is set, then for each @printindex <index name>
# <document name>_<index name>.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 = '';

# -lang
# use &$I('my string') if you want to have translations of 'my string'
# and provide the translations in $LANGUAGES->{$LANG} 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.
$LANG = 'en';

# -ignore-preamble-text
# If this is set the text before @node and sectionning 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 = '';

# -transliterate-file-names 
# transliterate node names for external refs (and internal if NODE_FILES)
$TRANSLITERATE_NODE = 1;

# --error-limit
# quit after NUM errors (default 1000).
$ERROR_LIMIT = 1000;

# -monolithic
# output only one file including ToC. It only makes sense when not split
$MONOLITHIC = 1;

# -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 texi2html).
# cf texinfo manual for more info.
# - means STDIN
@CSS_FILES = ();

# -css-ref
# the specified url are used as stylesheet links
@CSS_REFS = ();

######################
# The following options are only relevant if $L2H is set
#
# -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.
$L2H_SKIP = '';

# -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 <document name>_l2h_).
$L2H_CLEAN = 1;

##############################################################################
#
# The following can only be set in the init file
#
##############################################################################

# If true do table of contents even if there is no @content
$DO_CONTENTS = undef;

# If true do short table of contents even if there is no @shortcontent
$DO_SCONTENTS = undef;

# if set, output the contents where the command is located
$INLINE_CONTENTS = 0;

# if this variable is true, numeric entities are used when there is no
# corresponding textual entity.
$USE_NUMERIC_ENTITY = 1;

# 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 this variable is true, @setfilename is used if found to determine the
# out file name
$USE_SETFILENAME = 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 = 0;

# if set always separate description and menu link, even in 
# preformatted environment
$SEPARATE_DESCRIPTION = 0;

# if set, then use node names in menu entries, instead of section names
$NODE_NAME_IN_MENU = 0;

# 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 = 1;

# 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 = 1;

# 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 <td></td>
$EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';

# same as above, only for @small
$SMALL_EXAMPLE_INDENT_CELL = '<td>&nbsp;</td>';

# font size for @small
$SMALL_FONT_SIZE = '-1';

# horizontal rules
$SMALL_RULE = '<hr size="1">';
$DEFAULT_RULE = '<hr>';
$MIDDLE_RULE = '<hr size="2">';
$BIG_RULE = '<hr size="6">';

# 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 = '';

# if set and $SPLIT is set, then split index pages at the next letter
# after they have more than that many entries
$SPLIT_INDEX = 100;

# symbol put at the beginning of nodes entry in menu (and optionnaly of 
# unnumbered in menus, see next variable)
$MENU_SYMBOL = '&bull;';
#$MENU_SYMBOL = '*';

$SIMPLE_MENU = 0;

$OPEN_QUOTE_SYMBOL = "\`";
$CLOSE_QUOTE_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 = 'html';	    

# extension
$EXTENSION = 'html';

# file name used for Top node when NODE_FILES is true
$TOP_NODE_FILE = 'index';

# 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.
$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_ATTRIBUTE = ' class="toc"';

# 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";

# 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 <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 
# 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 the information given by menus to complete the node directions
$USE_MENU_DIRECTIONS = 1;

# try up sections to complete the node directions
$USE_UP_FOR_ADJACENT_NODES = 1;

# use accesskey in hrefs
$USE_ACCESSKEY = 0;

# use rel= and rev= in hrefs. Currently only rel is used
$USE_REL_REV = 0;

# generate <link> elements in head
$USE_LINKS = 0;

# specify in this array which "buttons" should appear in which order
# in the navigation panel for sections; use ' ' for empty buttons (space)
@SECTION_BUTTONS =
    (
     'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward',
     ' ', ' ', ' ', ' ',
     'Top', 'Contents', 'Index', 'About',
    );

# buttons for misc stuff
@MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About');

# buttons for chapter file footers
# (and headers but only if SECTION_NAVIGATION is false)
@CHAPTER_BUTTONS =
    (
     'FastBack', 'FastForward', ' ',
     ' ', ' ', ' ', ' ',
     'Top', 'Contents', 'Index', 'About',
    );

# buttons for section file footers
@SECTION_FOOTER_BUTTONS =
    (
     'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward'
    );

@NODE_FOOTER_BUTTONS =
    (
     'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward',
     ' ', ' ', ' ', ' ',
     'Top', 'Contents', 'Index', 'About',
#     'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward'
    );

@LINKS_BUTTONS =
    (
      'Top', 'Index', 'Contents', 'About', 'Up', 'NextFile', 'PrevFile'
    );

$ICONS = 0;

# 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',    '',
    );

@IMAGE_EXTENSIONS = ('png','jpg','jpeg','gif');
#, 'txt');


%misc_pages_targets = (
   'Overview' => 'SEC_Overview',
   'Contents' => 'SEC_Contents',
   'Footnotes' => 'SEC_Foot',
   'About' => 'SEC_About'
);

$init_out    = \&t2h_default_init_out;
$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',         &$I('Top'),
     'Contents',    &$I('Contents'),
     'Overview',    &$I('Overview'),
     'Index',       &$I('Index'),
     ' ',           ' &nbsp; ',
     'This',        &$I('current'),
     'Back',        ' &lt; ',
     'FastBack',    ' &lt;&lt; ',
     'Prev',        &$I('Prev'),
     'Up',          &$I(' Up '),
     'Next',        &$I('Next'),
     'NodeUp',      &$I('Node up'),
     'NodeNext',    &$I('Next node'),
     'NodePrev',    &$I('Previous node'),
     'Following',   &$I('Following node'),
     'Forward',     ' &gt; ',
     'FastForward', ' &gt;&gt; ',
     'About',       ' ? ',
     'First',       ' |&lt; ',
     'Last',        ' &gt;| ',
     'NextFile',    &$I('Next file'),
     'PrevFile',    &$I('Previous file'),
    );

    %BUTTONS_GOTO =
    (
     'Top',         &$I('Cover (top) of document'),
     'Contents',    &$I('Table of contents'),
     'Overview',    &$I('Short table of contents'),
     'Index',       &$I('Index'),
     'This',        &$I('Current section'),
     'Back',        &$I('Previous section in reading order'),
     'FastBack',    &$I('Beginning of this chapter or previous chapter'),
     'Prev',        &$I('Previous section on same level'),
     'Up',          &$I('Up section'),
     'Next',        &$I('Next section on same level'),
     'NodeUp',      &$I('Up node'),
     'NodeNext',    &$I('Next node'),
     'NodePrev',    &$I('Previous node'),
     'Following',   &$I('Node following in node reading order'),
     'Forward',     &$I('Next section in reading order'),
     'FastForward', &$I('Next chapter'),
     'About' ,      &$I('About (help)'),
     'First',       &$I('First section in reading order'),
     'Last',        &$I('Last section in reading order'),
     'NextFile',    &$I('Forward section in next file'),
     'PrevFile',    &$I('Back section in previous file'),
    );

    %BUTTONS_NAME =
    (
     'Top',         &$I('Top'),
     'Contents',    &$I('Contents'),
     'Overview',    &$I('Overview'),
     'Index',       &$I('Index'),
     ' ',           ' ',
     'This',        &$I('This'),
     'Back',        &$I('Back'),
     'FastBack',    &$I('FastBack'),
     'Prev',        &$I('Prev'),
     'Up',          &$I('Up'),
     'Next',        &$I('Next'),
     'NodeUp',      &$I('NodeUp'),
     'NodeNext',    &$I('NodeNext'),
     'NodePrev',    &$I('NodePrev'),
     'Following',   &$I('Following'),
     'Forward',     &$I('Forward'),
     'FastForward', &$I('FastForward'),
     'About',       &$I('About'),
     'First',       &$I('First'),
     'Last',        &$I('Last'),
     'NextFile',    &$I('NextFile'),
     'PrevFile',    &$I('PrevFile'),
    );

    %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',
    );

}

# 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);

    if (defined($DOCUMENT_ENCODING))
    {
        $document_encoding = $DOCUMENT_ENCODING;
    }
    elsif (defined($Texi2HTML::THISDOC{'documentencoding'}))
    {
        $document_encoding = $Texi2HTML::THISDOC{'documentencoding'};
    }

    if (defined($OUT_ENCODING))
    {
        $out_encoding = $OUT_ENCODING;
    }

    if (defined($ENCODING_NAME))
    {
        $encoding_name = $ENCODING_NAME;
    }

    if (!defined($out_encoding) and (defined($encoding_name)))
    {
        $out_encoding = main::encoding_alias ($encoding_name);
        $out_encoding = $encoding_name if (!defined($out_encoding));
    }
    if (!defined($out_encoding) and (defined($Texi2HTML::THISDOC{'IN_ENCODING'})))
    {
        $out_encoding = $Texi2HTML::THISDOC{'IN_ENCODING'};
    }
    if (!defined($out_encoding) and (defined($document_encoding)))
    {
        $out_encoding = main::encoding_alias ($document_encoding);
        $out_encoding = $document_encoding if (!defined($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($Texi2HTML::THISDOC{'IN_ENCODING'}) and defined($perl_charset_to_html{$Texi2HTML::THISDOC{'IN_ENCODING'}}))
         {
             $encoding_name = $perl_charset_to_html{$Texi2HTML::THISDOC{'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($Texi2HTML::THISDOC{'IN_ENCODING'}))
         {
             $encoding_name = $Texi2HTML::THISDOC{'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;
    $Texi2HTML::THISDOC{'DOCUMENT_ENCODING'} = $document_encoding;

    $out_encoding = 'UNDEF' if (!defined($out_encoding));
    my $in_encoding = $Texi2HTML::THISDOC{'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);
}

my  @t2h_default_multitable_stack;
# We have to do this dynamically because of internationalization and because
# in body $LANG could be used.
sub t2h_default_init_out()
{
    @t2h_default_multitable_stack = ();
    &$translate_names;
    # Set the default body text, inserted between <body ... >
    if (defined($BODYTEXT))
    {
        $Texi2HTML::THISDOC{'BODYTEXT'} = $BODYTEXT;
    }
    else
    {
        $Texi2HTML::THISDOC{'BODYTEXT'} = 'lang="' . $Texi2HTML::THISDOC{'current_lang'} . '" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"';
    }
    if (!defined($EXTERNAL_CROSSREF_SPLIT))
    {
        if ($SPLIT) 
        {
            $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 1;
        }
        else
        {
            $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 0;
        }
    }
    else
    {
        $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = $EXTERNAL_CROSSREF_SPLIT;
    }

    t2h_default_set_out_encoding();
    
    # not in code_style, according to post on bug-texinfo
    if ($SIMPLE_MENU)
    {
        foreach my $format ('menu', 'detailmenu')
        {
            if (!defined($complex_format_map->{$format}))
            { 
                $complex_format_map->{$format} = { 'begin' => q{''} , 'end' => q{''},
                 'pre_style' => "$MENU_PRE_STYLE", 'class' => 'menu-preformatted', 
#                 'style' => 'code' 
                };
            }
        }
        #$SEPARATE_DESCRIPTION = 1;
        #$format_map{'menu_comment'} = '' if (!defined($format_map{'menu_comment'}));
    }
    elsif (!defined($format_map{'menu_comment'}) and !defined($complex_format_map->{'menu_comment'}))
    {
        $complex_format_map->{'menu_comment'} = 
        {
           'begin' => q{"<tr><th colspan=\"3\" align=\"left\" valign=\"top\">"},
           'end' => q{"</th></tr>"}, 'pre_style' => "$MENU_PRE_STYLE", 'class' => 'menu-comment',
#            'style' => 'code'
        }
    }
    # obsolete
    #return $OUT_ENCODING;
};

sub t2h_default_finish_out()
{
}

#######################################################################
#
# Values guessed if not set here. The value used is in 
# $Texi2HTML::THISDOC{'VARNAME'}
#
#######################################################################

$BODYTEXT = undef;

# default used in init_out for the setting of the ENCODING_NAME variable
$DEFAULT_ENCODING = 'utf8';

# 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;

$USER = 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 sectionning 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_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            = \&T2H_DEFAULT_print_section;
$end_section              = \&T2H_DEFAULT_end_section;
$one_section              = \&T2H_DEFAULT_one_section;
$print_Top_header         = \&T2H_DEFAULT_print_Top_header;
$print_Top_footer	      = \&T2H_DEFAULT_print_Top_footer;
$print_Top		      = \&T2H_DEFAULT_print_Top;
$print_Toc		      = \&T2H_DEFAULT_print_Toc;
$print_Overview	      = \&T2H_DEFAULT_print_Overview;
$print_Footnotes	      = \&T2H_DEFAULT_print_Footnotes;
$print_About	      = \&T2H_DEFAULT_print_About;
$print_misc_header	      = \&T2H_DEFAULT_print_misc_header;
$print_misc_footer	      = \&T2H_DEFAULT_print_misc_footer;
$print_misc		      = \&T2H_DEFAULT_print_misc;
$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_element_header     = \&T2H_DEFAULT_print_element_header;
$print_chapter_footer     = \&T2H_DEFAULT_print_chapter_footer;
$print_page_head	      = \&T2H_DEFAULT_print_page_head;
$print_page_foot	      = \&T2H_DEFAULT_print_page_foot;
$print_head_navigation    = \&T2H_DEFAULT_print_head_navigation;
$print_foot_navigation    = \&T2H_DEFAULT_print_foot_navigation;
$button_icon_img	      = \&T2H_DEFAULT_button_icon_img;
$print_navigation	      = \&T2H_DEFAULT_print_navigation;
$about_body		      = \&T2H_DEFAULT_about_body;
$print_frame              = \&T2H_DEFAULT_print_frame;
$print_toc_frame          = \&T2H_DEFAULT_print_toc_frame;
#$toc_body                 = \&T2H_DEFAULT_toc_body;
$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;

########################################################################
# Layout for html for every sections
#

sub T2H_DEFAULT_print_element_header
{
    my $first_in_page = shift;
    my $previous_is_top = shift;
    my $buttons = \@SECTION_BUTTONS;

    if (($first_in_page or $previous_is_top) and $SECTION_NAVIGATION)
    {
        return &$print_head_navigation(undef, $buttons);
    }
    else
    { # got to do this here, as it isn't done in print_head_navigation
        return &$print_navigation($buttons) if ($SECTION_NAVIGATION or $SPLIT eq 'node');
    }
}

sub T2H_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 (defined $SPLIT
        and (($SPLIT eq 'node') && $SECTION_NAVIGATION))
    {
        my $buttons = \@NODE_FOOTER_BUTTONS;
        &$print_foot_navigation($fh, $buttons, $SMALL_RULE,
          (!defined($WORDS_IN_PAGE) or (defined ($nw) and $nw >= $WORDS_IN_PAGE)),
          $element);
#        print $fh "$SMALL_RULE\n";
#        &$print_navigation($buttons) if (!defined($WORDS_IN_PAGE) or (defined ($nw)
#                                    and $nw >= $WORDS_IN_PAGE));
    }
}

sub T2H_DEFAULT_one_section($$)
{
    my $fh = shift;
    my $element = shift;
    main::print_lines($fh);
    print $fh "$SMALL_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.
#
# If you enclose everything in @ifnothtml, then title, subtitle,
# author and overview is printed
# Texi2HTML::HREF of Next, Prev, Up, Forward, Back are not defined
# if $T2H_SPLIT then Top page is in its own html file
sub T2H_DEFAULT_print_Top_header($$)
{
    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;
    my $buttons = \@MISC_BUTTONS;
    &$print_foot_navigation($fh, $buttons, $SMALL_RULE, 
       ($end_page and ($SECTION_NAVIGATION or ($SPLIT and $SPLIT ne 'node'))), $element);
#    &$print_foot_navigation($fh);
#    print $fh "$SMALL_RULE\n";
    if ($end_page)
    {
#        &$print_navigation($fh, $buttons);
        &$print_page_foot($fh);
    }
}

sub T2H_DEFAULT_print_Top($$$)
{
    my $fh = shift;
    my $has_top_heading = shift;
    my $element = shift;

    # for redefining navigation buttons use:
    # my $buttons = [...];
    # as it is, 'Top', 'Contents', 'Index', 'About' are printed
    my $buttons = \@MISC_BUTTONS;

    my $nw;
    # a dirty hack. A section is considered to be empty if there are 2
    # lines or less in it. Indeed, this catches the sectionning command like
    # @top and the @node.
    if (scalar(@$Texi2HTML::THIS_SECTION) > 2)
    {
        # if top-level node has content
        $nw = main::print_lines($fh, $Texi2HTML::THIS_SECTION);
    }
    else
    {
        # top-level node is fully enclosed in @ifnothtml
        # print fulltitle, subtitle, author, Overview or table of contents
        # redo the titlepage with the actual state
        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); 
        # only print the header and node label
        print $fh $Texi2HTML::THIS_SECTION->[0];
        print $fh $Texi2HTML::TITLEPAGE;
        if (@{$Texi2HTML::OVERVIEW} and !$Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'})
        {
             print $fh '<h2> ' . $Texi2HTML::NAME{'Overview'} . "</h2>\n" . "<blockquote\n";
             my $nw = main::print_lines($fh, $Texi2HTML::OVERVIEW);
             print $fh "</blockquote>\n";
        }
        elsif (@{$Texi2HTML::TOC_LINES} and !$Texi2HTML::THISDOC{'setcontentsaftertitlepage'})
        {
             print $fh '<h1> ' . $Texi2HTML::NAME{'Contents'}  . "</h1>\n";
             my $nw = main::print_lines($fh, $Texi2HTML::TOC_LINES);
        }
    }
}

###################################################################
# 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 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
{
    # if there is no section navigation and it is not split, the 
    # navigation information is useless
    return &$print_misc(@_) if ($SPLIT or $SECTION_NAVIGATION);
}

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);
    print $fh "".&$misc_element_label($misc_pages_targets{$misc_page}, $misc_page);
    &$print_head_navigation($fh, $buttons) if ($new_file or $SECTION_NAVIGATION);
}

sub T2H_DEFAULT_print_misc_footer
{
    my $fh = shift;
    my $buttons = shift;
    my $new_file = shift;
    &$print_foot_navigation($fh, $buttons, $SMALL_RULE, 
        ($new_file and ($SECTION_NAVIGATION or ($SPLIT and $SPLIT ne 'node'))), undef);
#    print $fh "$SMALL_RULE\n";
    if ($new_file)
    {
#        &$print_navigation($fh, $buttons);# if ($SPLIT ne 'node');
        &$print_page_foot($fh);
    }
}

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 "<h1>$Texi2HTML::NAME{This}</h1>\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;
    my $buttons = \@SECTION_FOOTER_BUTTONS;
    &$print_foot_navigation($fh, $buttons, $BIG_RULE, 1, $element);
#    &$end_section ($fh, 1, $element);
#    &$print_navigation($fh, $buttons);
}

###################################################################
# 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 T2H_DEFAULT_print_chapter_header
{
    my $fh = shift;
    my $element = shift;
    # nothing to do there, by default, the navigation panel 
    # is the section navigation panel
    if (! $SECTION_NAVIGATION)
    { # in this case print_navigation is called here. 
        my $buttons = \@CHAPTER_BUTTONS;
        &$print_head_navigation($fh, $buttons);
        print $fh "\n$MIDDLE_RULE\n" unless ($VERTICAL_HEAD_NAVIGATION);
    }
}

sub T2H_DEFAULT_print_chapter_footer
{
    my $fh = shift;
    my $element = shift;
    my $buttons = \@CHAPTER_BUTTONS;
    &$print_foot_navigation($fh, $buttons, $BIG_RULE, 1, $element);
#    print $fh "$BIG_RULE\n";
#    &$print_navigation($fh, $buttons);
}

sub T2H_DEFAULT_print_section_header
{
    # nothing to do there, by default
    if (! $SECTION_NAVIGATION)
    { # 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 T2H_DEFAULT_print_page_head($)
{
    my $fh = shift;
    my $longtitle = "$Texi2HTML::THISDOC{'fulltitle_simple_format'}";
    $longtitle .= ": $Texi2HTML::SIMPLE_TEXT{'This'}" if (defined ($Texi2HTML::SIMPLE_TEXT{'This'}) and ($Texi2HTML::SIMPLE_TEXT{'This'} !~ /^\s*$/) and $SPLIT);
    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 $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";
            }
        }
    }

    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</title>

$description
<meta name="keywords" content="$longtitle">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="$Texi2HTML::THISDOC{program}">
$encoding
${links}$Texi2HTML::THISDOC{'CSS_LINES'}
$EXTRA_HEAD
</head>

<body $Texi2HTML::THISDOC{'BODYTEXT'}>
$AFTER_BODY_OPEN
EOT
}

sub T2H_DEFAULT_program_string()
{
    my $user = $Texi2HTML::THISDOC{'user'};
    my $date = $Texi2HTML::THISDOC{'today'};
    $user = '' if (!defined($user));
    $date = '' if (!defined($date));
    if (($user ne '') and ($date ne ''))
    {
        return  &$I('This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.', {
           'user' => $user, 'date' => $date, 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' => $Texi2HTML::THISDOC{'program'} }, {'duplicate'=>1});
    }
    elsif ($user ne '')
    {
        return  &$I('This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.', {
           'user' => $user, 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' => $Texi2HTML::THISDOC{'program'} }, {'duplicate'=>1});
    }
    elsif ($date ne '')
    {
        return  &$I('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 &$I('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_and_section_separation = shift;
    my $element = shift;
    #&$print_foot_navigation($fh) if ($end_foot_navigation);
    #print $fh "$BIG_RULE\n";
    if ($misc_and_section_separation)
    {
        &$print_foot_navigation($fh, undef, $BIG_RULE, 0, $element);
    }
    else
    {
        print $fh "$BIG_RULE\n";
    }
}

sub T2H_DEFAULT_print_page_foot($)
{
    my $fh = shift;
    my $program_string = &$program_string();
    print $fh <<EOT;
<p>
 <font size="-1">
  $program_string
 </font>
 <br>
$PRE_BODY_CLOSE
</p>
</body>
</html>
EOT
}

###################################################################
# Layout of navigation panel

sub T2H_DEFAULT_print_head_navigation($$)
{
    my $fh = shift;
    my $buttons = shift;

    my $result = '';
    if ($VERTICAL_HEAD_NAVIGATION)
    {
        $result .= <<EOT;
<table border="0" cellpadding="0" cellspacing="0">
<tr valign="top">
<td align="left">
EOT
    }
    $result .= &$print_navigation($buttons, $VERTICAL_HEAD_NAVIGATION);
    if ($VERTICAL_HEAD_NAVIGATION)
    {
        $result .= <<EOT;
</td>
<td align="left">
EOT
    }
    elsif (defined $SPLIT
           and ($SPLIT eq 'node'))
    {
        $result .= "$SMALL_RULE\n";
    }
 
    print $fh $result if (defined($fh));
    return $result;
}

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_navigation_panel = 1 if (!defined($print_navigation_panel)
             and defined($buttons));

    if ($VERTICAL_HEAD_NAVIGATION)
    {
        print $fh <<EOT;
</td>
</tr>
</table>
EOT
    }
    print $fh "$rule\n" if ($rule ne '');
    print $fh "".&$print_navigation($buttons) if ($print_navigation_panel);
}

######################################################################
# navigation panel
#
# how to create IMG tag
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 qq{<img src="$icon" border="0" alt="$alt" align="middle">};
}

sub T2H_DEFAULT_print_navigation
{
    my $buttons = shift;
    my $vertical = shift;

    my $result = '';
    $result .= '<table cellpadding="1" cellspacing="1" border="0">'."\n";
    $result .= "<tr>" unless $vertical;
    for my $button (@$buttons)
    {
        $result .= qq{<tr valign="top" align="left">\n} if $vertical;
        $result .=  qq{<td valign="middle" align="left">};

        if (ref($button) eq 'CODE')
        {
            $result .= &$button($vertical);
        }
        elsif (ref($button) eq 'SCALAR')
        {
            $result .= "$$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}\"";
                  }
                  $result .=  "" .
                        &$anchor('',
                                    $Texi2HTML::HREF{$button_href},
                                    $$text,
                                    $anchor_attributes
                                   ) 
                                    ;
                }
                else
                {
                  $result .=  $$text;
                }
            }
        }
        elsif ($button eq ' ')
        {                       # handle space button
            $result .= 
                ($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
                $result .= '' .
                    &$anchor('',
                        $Texi2HTML::HREF{$button},
                        &$button_icon_img($BUTTONS_NAME{$button},
                                   $ACTIVE_ICONS{$button},
                                   $Texi2HTML::SIMPLE_TEXT{$button}),
                        $btitle
                      );
            }
            else
            {                   # use text
                $result .= 
                    '[' .
                        &$anchor('',
                                    $Texi2HTML::HREF{$button},
                                    $NAVIGATION_TEXT{$button},
                                    $btitle
                                   ) .
                                       ']';
            }
        }
        else
        {                       # button is passive
            $result .= 
                $ICONS && $PASSIVE_ICONS{$button} ?
                    &$button_icon_img($BUTTONS_NAME{$button},
                                          $PASSIVE_ICONS{$button},
                                          $Texi2HTML::SIMPLE_TEXT{$button}) :

                                              "[" . $NAVIGATION_TEXT{$button} . "]";
        }
        $result .= "</td>\n";
        $result .= "</tr>\n" if $vertical;
    }
    $result .= "</tr>" unless $vertical;
    $result .= "</table>\n";
    return $result;
}

######################################################################
# 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.

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'};
    print $fh <<EOT;
$FRAMESET_DOCTYPE
<html>
<head><title>$Texi2HTML::THISDOC{'fulltitle'}</title></head>
<frameset cols="140,*">
  <frame name="toc" src="$toc_file">
  <frame name="main" src="$main_file">
</frameset>
</html>
EOT
}

sub T2H_DEFAULT_print_toc_frame
{
    my $fh = shift;
    my $stoc_lines = shift;
    &$print_page_head($fh);
    print $fh <<EOT;
<h2>Content</h2>
EOT
    print $fh map {s/\bhref=/target="main" href=/; $_;} @$stoc_lines;
    print $fh "</body></html>\n";
}

# 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:
# $NUMBER_SECTIONS
# $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
# $DO_CONTENTS
# $DO_SCONTENTS

sub T2H_DEFAULT_toc_body($)
{
}

sub T2H_DEFAULT_inline_contents($$$)
{
    my $fh = shift;
    my $command = shift;
    my $element = shift;
    my $name;
    my $lines;

    my $result = undef;

    if ($command eq 'contents')
    {
        $name = $Texi2HTML::NAME{'Contents'};
        $lines = $Texi2HTML::TOC_LINES;
    }
    else
    {
        $name = $Texi2HTML::NAME{'Overview'};
        $lines = $Texi2HTML::OVERVIEW;
    }
    if (@{$lines})
    {
         $result = [ "".&$anchor($element->{'id'})."\n",
            "<h1>$name</h1>\n" ]; 
         push @$result, @$lines;
    }

    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)));
    my $css_lines = "<style type=\"text/css\">\n<!--\n";
    $css_lines .= join('',@$import_lines) . "\n" if (@$import_lines);
    foreach my $css_rule (sort(keys(%css_map)))
    {
        next unless ($css_map{$css_rule});
        $css_lines .= "$css_rule {$css_map{$css_rule}}\n";
    }
    $css_lines .= join('',@$rule_lines) . "\n" if (@$rule_lines);
    $css_lines .= "-->\n</style>\n";
    foreach my $ref (@CSS_REFS)
    {
        $css_lines .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$ref\">\n";
    }
    $Texi2HTML::THISDOC{'CSS_LINES'} = $css_lines;
}

######################################################################
# 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',         ' &nbsp; ',
     'Contents',    ' &nbsp; ',
     'Overview',    ' &nbsp; ',
     'Index',       ' &nbsp; ',
     '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',       ' &nbsp; ',
     'First',       '1.',
     'Last',        '1.2.4',
     'NextFile',    ' &nbsp; ',
     'PrevFile',    ' &nbsp; ',
    );

sub T2H_DEFAULT_about_body
{
    my $about = "<p>\n";
    if (ref($PRE_ABOUT) eq 'CODE')
    {
        $about .= &$PRE_ABOUT();
    }
    else
    {
        $about .= $PRE_ABOUT;
    }
    $about .= <<EOT;
</p>
<p>
EOT
    $about .= &$I('  The buttons in the navigation panels have the following meaning:') . "\n";
    $about .= <<EOT;
</p>
<table border="1">
  <tr>
EOT
    $about .= '    <th> ' . &$I('Button') . " </th>\n" .
'    <th> ' . &$I('Name') . " </th>\n" .
'    <th> ' . &$I('Go to') . " </th>\n" .
'    <th> ' . &$I('From 1.2.3 go to') . "</th>\n" . "  </tr>\n";

    for my $button (@SECTION_BUTTONS)
    {
        next if $button eq ' ' || ref($button) eq 'CODE' || ref($button) eq 'SCALAR' || ref($button) eq 'ARRAY';
        $about .= "  <tr>\n    <td align=\"center\">";
        $about .=
            ($ICONS && $ACTIVE_ICONS{$button} ?
             &$button_icon_img($BUTTONS_NAME{$button}, $ACTIVE_ICONS{$button}) :
             ' [' . $NAVIGATION_TEXT{$button} . '] ');
        $about .= "</td>\n";
        $about .= <<EOT;
    <td align="center">$BUTTONS_NAME{$button}</td>
    <td>$BUTTONS_GOTO{$button}</td>
    <td>$BUTTONS_EXAMPLE{$button}</td>
  </tr>
EOT
    }

    $about .= <<EOT;
</table>

<p>
EOT
    $about .= &$I('  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 <strong> Example </strong> assumes that the current position
#  is at <strong> Subsubsection One-Two-Three </strong> of a document of
#  the following structure:
    $about .= <<EOT;
</p>

<ul>
EOT
    $about .= '  <li> 1. ' . &$I('Section One') . "\n" .
"    <ul>\n" .
'      <li>1.1 ' . &$I('Subsection One-One') . "\n";
    $about .= <<EOT;
        <ul>
          <li>...</li>
        </ul>
      </li>
EOT
    $about .= '      <li>1.2 ' . &$I('Subsection One-Two') . "\n" .
"        <ul>\n" .
'          <li>1.2.1 ' . &$I('Subsubsection One-Two-One') . "</li>\n" .
'          <li>1.2.2 ' . &$I('Subsubsection One-Two-Two') . "</li>\n" .
'          <li>1.2.3 ' . &$I('Subsubsection One-Two-Three') . " &nbsp; &nbsp;\n"
.
'            <strong>&lt;== ' . &$I('Current Position') . " </strong></li>\n" .
'          <li>1.2.4 ' . &$I('Subsubsection One-Two-Four') . "</li>\n" .
"        </ul>\n" .
"      </li>\n" .
'      <li>1.3 ' . &$I('Subsection One-Three') . "\n";
    $about .= <<EOT;
        <ul>
          <li>...</li>
        </ul>
      </li>
EOT
    $about .= '      <li>1.4 ' . &$I('Subsection One-Four') . "</li>\n";
    $about .= <<EOT;
    </ul>
  </li>
</ul>
$AFTER_ABOUT
EOT
    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;

    my $result = '';
    my $title = '';
    $title = $Texi2HTML::THISDOC{'title'} if (defined($Texi2HTML::THISDOC{'title'}) and $Texi2HTML::THISDOC{'title'} !~ /^\s*$/);
    if ($title ne ''
        or @{$Texi2HTML::THISDOC{'subtitles'}} 
        or @{$Texi2HTML::THISDOC{'authors'}})
    {     
        $result = "<div align=\"center\">\n";
        if ($title ne '')
        {
            $result .= '<h1>' . $title . "</h1>\n";
        }    
        foreach my $subtitle (@{$Texi2HTML::THISDOC{'subtitles'}})
        {
            $result .= '<h2>' . $subtitle . "</h2>\n";
        }
        foreach my $author (@{$Texi2HTML::THISDOC{'authors'}})
        {
            $result .= '<strong> ' . $author . " </strong><br>\n";
        }
        $result .= "</div>\n$DEFAULT_RULE\n";
    }

    $Texi2HTML::TITLEPAGE = $titlepage_text;

    $Texi2HTML::TITLEPAGE = $result . $Texi2HTML::TITLEPAGE;
    
    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;
}

# FIXME Honor DOCUMENT_DESCRIPTION? 
sub T2H_DEFAULT_print_redirection_page($)
{
    my $fh = shift;
    my $longtitle = "$Texi2HTML::THISDOC{'fulltitle_simple_format'}";
    $longtitle .= ": $Texi2HTML::SIMPLE_TEXT{'This'}" if exists $Texi2HTML::SIMPLE_TEXT{'This'};
    my $description = $longtitle;
    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 $href = &$anchor('', $Texi2HTML::HREF{'This'}, $Texi2HTML::NAME{'This'}); 
    my $string = &$I('The node you are looking for is at %{href}.',
       { 'href' => $href });
    print $fh <<EOT;
$DOCTYPE
<html>
<!-- Created on $Texi2HTML::THISDOC{'today'} by $Texi2HTML::THISDOC{'program'} -->
<!--
$Texi2HTML::THISDOC{'program_authors'}
-->
<head>
<title>$longtitle</title>

<meta name="description" content="$description">
<meta name="keywords" content="$longtitle">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="$Texi2HTML::THISDOC{program}">
$encoding
$Texi2HTML::THISDOC{'CSS_LINES'}
<meta http-equiv="Refresh" content="2; url=$Texi2HTML::HREF{'This'}">
$EXTRA_HEAD
</head>

<body $Texi2HTML::THISDOC{'BODYTEXT'}>
$AFTER_BODY_OPEN
<p>$string</p>
</body>
EOT
}

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_NODE)
        {
            $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).


#
# 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 &eacute;) 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',
         );

#
# texinfo "simple things" (@foo) to HTML ones
#
%simple_map = (
           '*', "<br>",     # HTML+
           ' ', '&nbsp;',
           "\t", '&nbsp;',
           "\n", '&nbsp;',
     # "&#173;" or "&shy;" 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)
           '-', '',  # hyphenation hint
           '|', '',  # used in formatting commands @evenfooting and friends
           '/', '',
       # spacing commands
           ':', '',
           '!', '!',
           '?', '?',
           '.', '.',
           '@', '@',
           '}', '}',
           '{', '{',
          );

# this map is used in preformatted text
%simple_map_pre = %simple_map;
$simple_map_pre{'*'} = "\n";

# maps for the math specific commands
%simple_map_math = (
           '\\', '\\'
           );

%simple_map_pre_math = %simple_map_math;
%simple_map_texi_math = %simple_map_math;

%colon_command_punctuation_characters = (
   '.' => '.',
   ':' => ':',
   '?' => '?',
   '!' => '!'
);

#
# texinfo "things" (@foo{}) to HTML ones
#
%things_map = (
               'TeX'          => 'TeX',
               'LaTeX'          => 'LaTeX',
# pertusus: unknown by makeinfo, not in texinfo manual (@* is the right thing)
#               'br', '<br>',     # paragraph break
               'bullet'       => '*',
#               #'copyright' => '(C)',
               'copyright'    => '&copy;',
               'registeredsymbol'   => '&reg;',
               'dots'         => '<small class="dots">...</small>',
               'enddots'      => '<small class="enddots">...</small>',
               'equiv'        => '==',
# FIXME i18n
               'error'        => 'error--&gt;',
               'expansion'    => '==&gt;',
               'arrow'        => '->',
               'minus'        => '-',
               'point'        => '-!-',
               'print'        => '-|',
               'result'       => '=&gt;',
               # set in code using the language
               # 'today', &pretty_date,
               'today'        => '',
               'aa'           => '&aring;',
               'AA'           => '&Aring;',
               'ae'           => '&aelig;',
               'oe'           => '&oelig;', #pertusus: also &#156;. &oelig; not in html 3.2
               'AE'           => '&AElig;',
               'OE'           => '&OElig;', #pertusus: also &#140;. &OElig; not in html 3.2
               'o'            =>  '&oslash;',
               'O'            =>  '&Oslash;',
               'ss'           => '&szlig;',
               'l'            => '&#322;',
               'L'            => '&#321;',
               'exclamdown'   => '&iexcl;',
               'questiondown' => '&iquest;',
               'pounds'       => '&pound;',
               'ordf'         => '&ordf;',
               'ordm'         => '&ordm;',
               'comma'        => ',',
               'euro'         => '&euro;',
               'geq'          => '&ge;',
               'leq'          => '&le;',
               'tie'          => '&nbsp;',
               'textdegree'          => '&deg;',
               'quotedblleft'          => '&ldquo;',
               'quotedblright'          => '&rdquo;',
               'quoteleft'          => '&lsquo;',
               'quoteright'          => '&rsquo;',
               'quotedblbase'          => '&bdquo;',
               'quotesinglbase'          => '&sbquo;',
               'guillemetleft'          => '&laquo;',
               'guillemetright'          => '&raquo;',
               'guillemotleft'          => '&laquo;',
               'guillemotright'          => '&raquo;',
               'guilsinglleft'          => '&lsaquo;',
               'guilsinglright'          => '&rsaquo;',
             );

# This map is used in preformatted environments
%pre_map = %things_map;
$pre_map{'dots'} = '...';
$pre_map{'enddots'} = '...';
#$pre_map{'br'} = "\n";

%ascii_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',
               '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'          => '>',
);

# ascii representation of @-commands
%ascii_simple_map = (
           '*', "\n",
           ' ', ' ',
           "\t", ' ',
           "\n", ' ',
           '-', '',  # hyphenation hint
           '|', '',  # used in formatting commands @evenfooting and friends
           '/', '',
           ':', '',
           '!', '!',
           '?', '?',
           '.', '.',
           '@', '@',
           '}', '}',
           '{', '{',
);

#
# This map is used when texi elements are removed and replaced 
# by simple text
#
%simple_map_texi = %ascii_simple_map;


# text replacing macros when texi commands are removed and plain text is 
# produced 
%texi_map = (
               'TeX', 'TeX',
               'LaTeX', 'LaTeX',
               'bullet', '*',
               'copyright', 'C',
               'registeredsymbol', 'R',
               'dots', '...',
               'enddots', '...',
               'equiv', '==',
               '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',
               'exclamdown', '! upside-down',
               #'exclamdown', '&iexcl;',
               'questiondown', '? upside-down',
               #'questiondown', '&iquest;',
               'pounds', 'pound sterling',
               #'pounds', '&pound;'
               'ordf'         => 'a',
               'ordm'         => 'o',
               'comma'        => ',',
               'euro'         => 'Euro',
               'geq'          => '>=',
               'leq'          => '<=',
               'tie'          => ' ',
               'textdegree'          => 'o',
               'quotedblleft'          => '``',
               'quotedblright'          => "''",
               'quoteleft'          => '`',
               'quoteright'          => "'",
               'quotedblbase'          => ',,',
               'quotesinglbase'          => ',',
               'guillemetleft'          => '<<',
               'guillemetright'          => '>>',
               'guillemotleft'          => '<<',
               'guillemotright'          => '>>',
               'guilsinglleft'          => '<',
               'guilsinglright'          => '>',
            );

# 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',
               '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;
   }
}

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'  => 'OE',
               '00F8'  => 'oe',
               '00E6' => 'ae',
               '0153' => 'oe',
               '00C6' => 'AE',
               '0152' => 'OE',
               '00DF' => 'ss',
               '0141' => 'L',
               '0142' => 'l',
               '00D0'  => 'DH',
               '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 ?
          );

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',
);

%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};
}

# symbols used for the commands if $USE_ISO is true.
%iso_symbols = (
         'equiv'     => '&equiv;',
         'dots'      => '&hellip;',
         'bullet'    => '&bull;',
         'result'    => '&rArr;',
         'expansion' => '&rarr;',
         'arrow'     => '&rarr;',
         'point'     => '&lowast;',
         "'"         => '&rsquo;',
         '`'         => '&lsquo;',
        );

%stop_paragraph_command = (
 'titlefont' => 1,
 'insertcopying' => 1
);

# on bug-texinfo verified that code_style shouldn't be used for anything
# else than node.
# anyway it doesn't make sense since the section name normally formatted
# is used
#%format_code_style = (
#  'menu_name' => 1,
#  'menu_description' => 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',          '',
     );

# default is {'args' => ['normal'], 'attribute' => ''},   
%style_map = (
      'asis',       {},
      'b',          {'attribute' => 'b'},
      'cite',       {'attribute' => 'cite'},
      'clicksequence', {},
      'click',      {'function' => \&t2h_default_click_normal},
      'code',       {'args' => ['code'], 'attribute' => 'code'},
      'command',    {'args' => ['code'], 'attribute' => 'code'},
      'ctrl',       {'function' => \&t2h_default_ctrl,'type' => 'simple_style'}, 
      'dfn',        {'attribute' => 'em'}, 
      'dmn',        {},   
      'email',      {'args' => ['code', 'normal'], 
                       'function' => \&t2h_default_email,
                       'type' => 'simple_style'}, 
      #'email',      {'args' => ['normal', 'normal'], 
      #                 'function' => \&t2h_default_email}, 
      'emph',       {'attribute' => 'em'}, 
      'env',        {'args' => ['code'], 'attribute' => 'code'},
      'file',       {'args' => ['code'], 'attribute' => 'tt', 'quote' => '"'},
      'i',          {'attribute' => 'i'},
      'slanted',    {'attribute' => 'i'},
      'sansserif',  {'attribute' => 'span class="sansserif"'},
      'kbd',        {'args' => ['code'], 'attribute' => 'kbd'},
      'key',        {'args' => ['code'], 'begin' => '&lt;', 'end' => '&gt;'},
      'math',       {'function' => \&t2h_default_math, 'args' => ['math'] },
      'option',     {'args' => ['code'], 'attribute' => 'samp', 'quote' => '"'},
      'r',          {'attribute' => 'span class="roman"'},
      'samp',       {'args' => ['code'], 'attribute' => 'samp', 'quote' => '"'},
#      'sc',         {'function' => \&t2h_default_sc},
      'sc',         {'attribute' => 'small'},
      'strong',     {'attribute' => 'strong'},
      't',          {'attribute' => 'tt'},
      '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' => '&lt;<code>', 'end' => '</code>&gt;','type' => 'simple_style'},
      'var',        {'attribute' => 'var'},
      'verb',       {'args' => ['code'], 'attribute' => 'tt'},
      'titlefont',  {'function' => \&t2h_default_titlefont, 
            'type' => 'simple_style'},
      'w',          {'type' => 'simple_style'},
      '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';
   }
}

%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',
    },
);

%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}}));
    }
}

%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',
);

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_ascii_accent };
}

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 . '&lt;' if ($accent eq 'v');
    return ascii_accents($text, $accent);
}

sub t2h_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 . '&lt;' 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);
}

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 default_sc($$)
{
    return '<small>' . uc($_[0]) . '</small>';
}

# now unused, upcasing is done in normal_text
sub t2h_default_sc($$$)
{ 
    shift;
    my $args = shift;
    return '<small>' . uc($args->[0]) . '</small>';
}

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]);
}

# now unused, upcasing is done in normal_text
sub t2h_default_sc_pre($$$)
{
    shift;
    my $args = shift;
    return uc($args->[0]);
}

sub default_titlefont($$)
{
    return "<h1 class=\"titlefont\">$_[0]</h1>" if ($_[0] =~ /\S/);
    return '';
}

# Avoid adding h1 if the text is empty
sub t2h_default_titlefont($$$)
{
    shift;
    my $args = shift;
    return "<h1 class=\"titlefont\">$args->[0]</h1>" if ($args->[0] =~ /\S/);
    return '';
}

# 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 '&lt;<code>' . $_[0] . '</code>&gt;';
#}
# 
# This is unused, t2h_default_uref is used instead
sub t2h_default_url ($$)
{
    shift;
    my $args = shift;
    my $url = shift @$args;
    #$url =~ s/\s*$//;
    #$url =~ s/^\s*//;
    $url = main::normalise_space($url);
    return '' unless ($url =~ /\S/);
    return &$anchor('', $url, $url);
}

sub default_url ($$)
{
    my $url = shift;
    my $command = shift;
    $url =~ s/\s*$//;
    $url =~ s/^\s*//;
    return '' unless ($url =~ /\S/);
    return &$anchor('', $url, $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));
    $text = $url unless ($text);
    return $text if ($url eq '');
    return &$anchor('', $url, $text);
}

sub t2h_default_uref($$)
{
    shift;
    my $args = shift;
    my $url = shift @$args;
    my $text = shift @$args;
    my $replacement = shift @$args;
    #$url =~ s/\s*$//;
    #$url =~ s/^\s*//;
    $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 t2h_default_math($$)
{
    shift;
    my $args = shift;
    my $text = shift @$args;
#print STDERR "t2h_default_math $text\n";
    $text =~ s/[{}]//g; 
#    $text =~ s/\@\\/\\/g; 
    return "<em>$text</em>";
}

sub default_email($$)
{
    my $arg = shift;
    my $command = shift;
    my ($mail, $text);
    ($mail, $text) = split /,\s*/, $arg;
    $mail =~ s/\s*$//;
    $mail =~ s/^\s*//;
    $text = $mail unless ($text);
    return $text if ($mail eq '');
    return &$anchor('', "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);
    #$mail =~ s/\s*$//;
    #$mail =~ s/^\s*//;
    $text = $mail unless (defined($text) and ($text ne ''));
    $text = main::normalise_space($text);
    return $text if ($mail eq '');
    return &$anchor('', "mailto:$mail", $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_ascii_accent($$$$)
{
    my $accent = shift;
    my $args = shift;

    my $text = $args->[0];
    return ascii_accents($text, $accent);
}

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);
    #$mail =~ s/\s*$//;
    #$mail =~ s/^\s*//;
    return $text if (defined($text) and ($text ne ''));
    return $mail;
}

sub t2h_default_no_texi_image($$$$)
{
    my $command = shift;
    my $args = shift;
    #my $text = $args->[0];
    #$text = main::normalise_space($text); 
    #my @args = split (/\s*,\s*/, $text);
    my $file = $args->[0];
    $file =~ s/^\s*//;
    $file =~ s/\s*$//;
    return main::substitute_line($file, {'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_pre{$command} = {};
    $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";
    
    foreach my $key (keys(%{$style_map{$command}}))
    {
        $style_map_pre{$command}->{$key} = $style_map{$command}->{$key};
    }
}

#$style_map_pre{'sc'}->{'function'} = \&t2h_default_sc_pre;
$style_map_pre{'sc'} = {};
$style_map_pre{'titlefont'} = {};
$style_map_pre{'click'}->{'function'} = \&t2h_default_click_pre;

#$style_map_texi{'sc'}->{'function'} = \&t2h_default_sc_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 = ();

foreach my $command (keys(%style_map_texi))
{
    #$simple_format_style_map_texi{$command} = {};
    foreach my $key (keys (%{$style_map_texi{$command}}))
    {
    #print STDERR "$command, $key, $style_map_texi{$command}->{$key}\n";
        $simple_format_style_map_texi{$command}->{$key} = 
             $style_map_texi{$command}->{$key};
    }
    $simple_format_style_map_texi{$command} = {} if (!defined($simple_format_style_map_texi{$command}));
}

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;
}

# 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' => 0,
     'verbatim' => 'raw', 
     'ifclear' => 'value', 
     'ifset' => 'value' ,
     );
    
%format_map = (
#       'quotation'   =>  'blockquote',
       # lists
#       'itemize'     =>  'ul',
       'enumerate'   =>  'ol',
#       'multitable'  =>  'table',
       'table'       =>  'dl compact="compact"',
       'vtable'      =>  'dl compact="compact"',
       'ftable'      =>  'dl compact="compact"',
       'group'       =>  '',
#       'detailmenu'  =>  '',
       );

%special_list_commands = (
       'table'        =>  {},
       'vtable'       =>  {},
       'ftable'       =>  {},
       'itemize'      =>  { 'bullet'  => '' }
       );

%inter_item_commands = (
  'c' => 1,
  'comment' => 1,
  'cindex' => 1
);
#
# texinfo format to align attribute of paragraphs
#

%paragraph_style = (
      'center'     => 'center',
      'flushleft'  => 'left',
      'flushright' => 'right',
      );
      
# an eval of these $complex_format_map->{what}->{'begin'} yields beginning
# an eval of these $complex_format_map->{what}->{'end'} yields end
# $EXAMPLE_INDENT_CELL and SMALL_EXAMPLE_INDENT_CELL can be usefull here
$complex_format_map =
{
 'example' =>
 {
  'begin' => q{"<table><tr>$EXAMPLE_INDENT_CELL<td>"},
  'end' => q{"</td></tr></table>\n"},
  'style' => 'code',
 },
 'smallexample' =>
 {
  'begin' => q{"<table><tr>$SMALL_EXAMPLE_INDENT_CELL<td>"},
  'end' => q{"</td></tr></table>\n"},
  'style' => 'code',
 },
 'display' =>
 {
  'begin' => q{"<table><tr>$EXAMPLE_INDENT_CELL<td>"},
  'end' => q{"</td></tr></table>\n"},
 },
 'smalldisplay' =>
 {
  'begin' => q{"<table><tr>$SMALL_EXAMPLE_INDENT_CELL<td>"},
  'end' => q{"</td></tr></table>\n"},
 }
};

# format shouldn't narrow the margins

$complex_format_map->{'lisp'} =  $complex_format_map->{'example'};
$complex_format_map->{'smalllisp'} = $complex_format_map->{'smallexample'};
$complex_format_map->{'format'} = $complex_format_map->{'display'};
$complex_format_map->{'smallformat'} = $complex_format_map->{'smalldisplay'};

%def_map = (
    # 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};
}

#
# miscalleneous commands
#
# 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
        # comments
        'comment' => {'arg' => 'line'},
        'c' => {'arg' => 'line'},

        # 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' => {}, # 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}, # on off
        'fonttextsize' => {'arg' => 1}, # 10 11
        'allowcodebreaks' => {'arg' => 1}, # 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'},
        #'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' => 'linespace', 'arg' => 2}, 
                          # args are index identifiers
        'synindex' => {'skip' => 'linespace', 'arg' => 2},
        'defindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg
        'defcodeindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg
        'documentlanguage' => {'skip' => 'whitespace', 'arg' => 1}, 
                                                       # language code arg
        'kbdinputstyle' => {'skip' => 'whitespace', 'arg' => 1}, # code 
                                                        #example distinct
        'everyheadingmarks' => {'skip' => 'whitespace', 'arg' => 1}, # top bottom
                                                        #makeinfo ignore line
        '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' => 'whitespace', '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}, # makeinfo ignore the whole line
        # ???
        'filbreak' => {},
        # obsolete @-commands
        'quote-arg' => {},
        'allow-recursion' => {},
     );
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,
     );

%format_in_paragraph = (
        'html'  => 1,
);
# map mapping css specification to style

%css_map = 
     (
         'ul.toc'                 => "$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;'
     );

$css_map{'pre.format'} = $css_map{'pre.display'};
$css_map{'pre.smallformat'} = $css_map{'pre.smalldisplay'}; 
$css_map{'pre.smalllisp'} = $css_map{'pre.smallexample'};

# 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_init = ();
@command_handler_process = ();
@command_handler_finish = ();

# 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;
$external_ref      = \&t2h_default_external_ref;
$external_href     = \&t2h_default_external_href;
$internal_ref      = \&t2h_default_internal_ref;
$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;
$element_heading   = \&t2h_default_element_heading;
$heading_no_texi   = \&t2h_default_heading_no_texi;
$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;
$address           = \&t2h_default_address;
$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;
$complex_format    = \&t2h_default_complex_format;
$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;
$unknown                  = \&t2h_default_unknown;
$unknown_style            = \&t2h_default_unknown_style;
$caption_shortcaption     = \&t2h_default_caption_shortcaption;
$caption_shortcaption_command  = \&t2h_default_caption_shortcaption_command;
$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;
$quotation_prepend_text   = \&t2h_default_quotation_prepend_text;
$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;
$misc_element_label         = \&t2h_default_misc_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;
$tab_item_texi              = \&t2h_default_tab_item_texi;
$insertcopying              = \&t2h_default_insertcopying;
$colon_command              = \&t2h_default_colon_command;
$simple_command             = \&t2h_default_simple_command;
$thing_command              = \&t2h_default_thing_command;

# 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 $line_nr = shift;
    my $state = shift;

    if ($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 $line_nr = shift;
    my $state = shift;

    my $result;
    if ($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;

    # first array element is the number of cell in a row
    # second is the number of paragraphs in a cell
    push (@t2h_default_multitable_stack, [-1,-1]) if ($command eq 'multitable');

    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 '');
    my $beginning = eval "$complex_format_map->{$name}->{'begin'}";
    if ($@ ne '')
    {
        print STDERR "$ERROR Evaluation of $complex_format_map->{$name}->{'begin'}: $@";
        $beginning = '';

    }
    my $end = eval "$complex_format_map->{$name}->{'end'}";
    if ($@ ne '')
    {
        print STDERR "$ERROR Evaluation of $complex_format_map->{$name}->{'end'}: $@";
        $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 ($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 = &$I('%{style} %{number}', { 'style' => $style, 'number' => $nr});
        }
        else 
        {
            $style = $nr;
        }
    }
    
    if (defined($float->{'caption_texi'}))
    {
        @$caption_lines = @{$float->{'caption_texi'}};
        if (defined($style))
        {
            $caption_lines->[0] = '@strong{' . &$I('%{style}: %{caption_first_line}', { 'style' => $style, 'caption_first_line' => $caption_lines->[0] });
        }
        else
        {
            $caption_lines->[0] = '@strong{' .  $caption_lines->[0];
        }
        push @$caption_lines, "}\n";
    }
    elsif (defined($style))
    {
        $caption_lines->[0] = '@strong{' . $style . '}' . "\n";
    }
    if (defined($float->{'shortcaption_texi'}))
    {
         @$shortcaption_lines = @{$float->{'shortcaption_texi'}};
         if (defined($style))
         {
              $shortcaption_lines->[0] = '@strong{' . &$I('%{style}: %{shortcaption_first_line}', { 'style' => $style, 'shortcaption_first_line' => $shortcaption_lines->[0] });
         }
         else
         {
              $shortcaption_lines->[0] = '@strong{' .  $shortcaption_lines->[0];
         }
         push @$shortcaption_lines, "}\n";
    }
    elsif (defined($style))
    {
         $shortcaption_lines->[0] = '@strong{' . $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 '<div class="float">' . "$label\n" . $text . '</div>' . $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'};
    if (defined($float->{'nr'}))
    {
         my $nr = $float->{'nr'};
         if ($style ne '')
         {
              $style = &$I('%{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'}} ];
    }
    elsif (defined($float->{'caption_texi'}))
    {
         return [ @{$float->{'caption_texi'}} ];
    }
    return [ ];
}

sub t2h_default_listoffloats_entry($$$$)
{
    my $style_texi = shift;
    my $float = shift;
    my $float_style = shift;
    my $caption = shift;
    my $href = shift;

    return '<dt>' . &$anchor('', $href, $float_style) . '</dt><dd>' . $caption
. '</dd>' . "\n";
}

sub t2h_default_listoffloats($$$)
{
    my $style_texi = shift;
    my $style = shift;
    my $float_entries = shift;

    my $result = "<dl class=\"listoffloats\">\n" ;
    foreach my $float_entry (@$float_entries)
    {
         $result .= $float_entry;
    }
    return $result . "</dl>\n";
} 

sub t2h_default_insertcopying($$$)
{
    my $text = shift;
    my $comment = shift;
    my $simple_text = shift;
    return $text;
}

# This function is used to protect characters which are special in html 
# in inline text:  &, ", <, and >. 
#
# argument:
# text to be protected
sub t2h_default_protect_text($)
{
   my $text = shift;
   $text =~ s/&/&amp;/g;
   $text =~ s/</&lt;/g;
   $text =~ s/>/&gt;/g;
   $text =~ s/\"/&quot;/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 $text = shift;
   my $in_raw_text = shift; # remove_texi
   my $in_preformatted = shift;
   my $in_code = shift;
   my $in_simple = shift;
   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 ($USE_ISO and !$in_raw_text)
       {
           $text =~ s/---/\&mdash\;/g;
           $text =~ s/--/\&ndash\;/g;
           $text =~ s/``/\&ldquo\;/g;
           $text =~ s/''/\&rdquo\;/g;
           if (! $in_simple)
           { # lquot and rquot don't seem to be accepted in title.
               $text =~ s/'/$iso_symbols{"'"}/g if (defined ($iso_symbols{"'"}));
               $text =~ s/`/$iso_symbols{'`'}/g if (defined ($iso_symbols{'`'}));
           }
       }
       else
       {
            if ($in_raw_text) #FIXME really do that ? It is done by makeinfo
            {
                 $text =~ s/``/"/g;
                 $text =~ s/''/"/g;
            }
            else
            {
                $text =~ s/``/&quot;/g;
                $text =~ s/''/&quot;/g;
                # to be like texinfo
                #$text =~ s/'/\&rsquo\;/g;
                #$text =~ s/`/\&lsquo\;/g;
            }
            # temporary reuse '' to store --- !....
            # FIXME won't '---' be handled wrongly?
            # FIXME really do that in raw text?
            $text =~ s/---/''/g; 
            $text =~ s/--/-/g; 
            $text =~ s/''/--/g;
       }
   }
   else
   {
       # to be like texinfo
#       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'}));
   }
   return $text;
}

# This function produces an anchor 
#
# 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;
#print STDERR "!$name!$href!$text!$attributes!\n";
    if (!defined($attributes) or ($attributes !~ /\S/))
    {
        $attributes = '';
    }
    else 
    {
        $attributes = ' ' . $attributes;
    }
    $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 "<a ${name}${href}${attributes}>$text</a>";
}

# 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;
    if ($text =~ /\S/)
    {
        if (! $DEF_TABLE)
        {
            return '<dd>' . $text . '</dd>';# unless $only_inter_item_commands;
            #return $text; # invalid without dd in ul
        }
        else
        {
            return '<tr><td colspan="2">' . $text . '</td></tr>';
        }
    }
    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 &$I('%{name} on %{class}', { 'name' => $name, 'class' => $class });
    }
    elsif ($style eq 'v')
    {
        return &$I('%{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 &$I('%{name} on %{class}', { 'name' => $name, 'class' => $class });
    }
    elsif ($style eq 'v' and $command ne 'defcv')
    {
        return &$I('%{name} of %{class}', { 'name' => $name, 'class' => $class });
    }
    else
    {
        return $name;
    }
}

# 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;
    if ($text =~ /\S/)
    {
        if (! $DEF_TABLE)
        {
            return "<dl>\n" . $text . "</dl>\n";
        }
        else
        {
            return "<table width=\"100%\">\n" . $text . "</table>\n";
        }
    }
    return '';

}

# tracks menu entry index
my $menu_entry_index;

# a whole menu
#
# argument:
# the whole menu text (entries and menu comments)
#
# argument:
# whole menu text.
sub t2h_default_menu_command($$$)
{
    my $format = shift;
    my $text = shift;
    my $in_preformatted = shift;

    $menu_entry_index=0;

    my $begin_row = '';
    my $end_row = '';
    if ($in_preformatted)
    {
        $begin_row = '<tr><td>';
        $end_row = '</td></tr>';
    }
    if ($text =~ /\S/)
    {
        return $text if ($format eq 'detailmenu');
        return "<table class=\"menu\" border=\"0\" cellspacing=\"0\">${begin_row}\n" 
        . $text . "${end_row}</table>\n";
    }
}

# obsolete
# a simple menu entry ref in case we aren't in a standard menu context
#sub t2h_default_simple_menu_link($$$$$$$)
#{
#    my $entry = shift;
#    my $preformatted = shift;
#    my $href = shift;
#    my $node = shift;
#    my $title = shift;
#    my $ending = shift;
#    my $has_title = shift;
#    $title = '' unless($has_title);
#    $ending = '' if (!defined($ending));
#    if (($entry eq '') or $NODE_NAME_IN_MENU or $preformatted)
#    {
#        $title .= ':' if ($title ne '');
#        $entry = "$MENU_SYMBOL$title$node";
#    }
#    $menu_entry_index++;
#    my $accesskey;
#    $accesskey = "accesskey=\"$menu_entry_index\"" if ($USE_ACCESSKEY and ($menu_entry_index < 10));
#    $entry = &$anchor('', $href, $entry, $accesskey) if ($href);
#    $entry .= $ending if ($preformatted);
#    $entry .= '&nbsp;' unless $preformatted;
#    return $entry;
#}

# 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;

    my $in_commands = 0;
    $in_commands = 1 if ($command_stack->[-1] and $command_stack->[-1] ne 'menu' and $command_stack->[-1] ne 'detailmenu');

    $title = '' unless ($has_title);
#print STDERR  "MENU_LINK($in_commands)($state->{'preformatted'})\n";
    if (($entry eq '') or $NODE_NAME_IN_MENU or $preformatted)
    {
        $title .= ':' if ($title ne '');
        $entry = "$MENU_SYMBOL$title$node";
    }
    $menu_entry_index++;
    my $accesskey;
    $accesskey = "accesskey=\"$menu_entry_index\"" if ($USE_ACCESSKEY and ($menu_entry_index < 10));
    $entry = &$anchor ('', $href, $entry, $accesskey) if (defined($href));

    return $entry.$ending if ($preformatted);
    return $entry .'&nbsp;' if ($in_commands);
    return "<tr><td align=\"left\" valign=\"top\">$entry</td><td>&nbsp;&nbsp;</td>";
}

sub 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, 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.
sub t2h_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');
    return $text if ($preformatted or $in_commands);
    # FIXME: the following is better-looking.
    #return $text."<br>" if ($in_commands and !$state->{'preformatted'});
    if ($AVOID_MENU_REDUNDANCY)
    {
        $text = '' if (simplify_text($element_text) eq simplify_text($text));
    }
    return "<td align=\"left\" valign=\"top\">$text</td></tr>\n";
}

# a menu comment (between menu lines, obsolete)
# formats the container of a menu comment. A menu comment is any text 
# appearing between menu lines, either separated by an empty line from
# the preceding menu entry, or a text beginning at the first character
# of the line (text not at the very beginning of the line is considered to
# be the continuation of a menu entry description text).
#
# The text itself is considered to be in a preformatted environment
# with name 'menu-commment' and with style $MENU_PRE_STYLE.
#
# argument
# text contained in the menu comment.
#sub t2h_default_menu_comment($)
#{
#   my $text = shift;
#   return $text if ($SIMPLE_MENU); 
#   if ($text =~ /\S/)
#   {
#       return "<tr><th colspan=\"3\" align=\"left\" valign=\"top\">$text</th></tr>";
#   }
#   return '';
#}

# 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'
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;
             if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}))
             {
                  if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'split'}))
                  {
                       $target_split = 1;
                       $href_split =  $Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'split'}->{'href'};
                  }
                  if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'mono'}))
                  {
                       $target_mono = 1;
                       $href_mono =  $Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'mono'}->{'href'};
                  }
             }

             if ((not $target_mono) and (not $target_split))
             { # nothing specified for that manual, use default
                  $target_split = $default_target_split;
             }
             elsif ($target_split and $target_mono)
             { # depends on the splitting of the manual
                  $target_split = $SPLIT;
             }
             elsif ($target_mono)
             { # only mono specified
                  $target_split = 0;
             }

             if ($target_split)
             {
                  if (defined($href_split))
                  {
                       $file = "$href_split";
                  }
                  elsif (defined($EXTERNAL_DIR))
                  {
                       $file = "$EXTERNAL_DIR/$file";
                  }
                  elsif ($SPLIT)
                  {
                       $file = "../$file";
                  }
                  $file .= "/";
             }
             else
             {# target not split
                  if (defined($href_mono))
                  {
                       $file = "$href_mono";
                  }
                  else
                  {
                       if (defined($EXTERNAL_DIR))
                       {
                            $file = "$EXTERNAL_DIR/$file";
                       }
                       elsif ($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)
             {
                 return $file . $TOP_NODE_FILE . '.' . $NODE_FILE_EXTENSION . '#Top';
                 # or ?
                 #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 if ($node =~ /^top$/i);
    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.
# node and file name formatted according to the convention used in info
#     '(file)node' and no node means the Top node.
# href linking to the html page containing the referenced node. A typical
#     use for this href is a href attribute in an <a> element
# an optionnal cross reference name
sub t2h_default_external_ref($$$$$$$$)
{
    my $type = shift;
    my $section = shift;
    my $book = shift;
    my $file_node = shift;
    my $href = shift;
    my $cross_ref = shift;
    my $args_texi = shift;
    my $formatted_args = shift;

    $file_node = "$cross_ref: $file_node" if (($file_node ne '') and ($cross_ref ne ''));
    $file_node = &$anchor('', $href, $file_node) if ($file_node ne '');

    # Yes, this is ugly, but this helps internationalization
    if ($type eq 'pxref')
    {
         if (($book ne '') and ($file_node ne ''))
         {
              return &$I('see %{node_file_href} section `%{section}\' in @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne '');
              return &$I('see %{node_file_href} @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book },{'duplicate'=>1});
         }
         elsif ($book ne '')
         {
              return &$I('see section `%{section}\' in @cite{%{book}}', { 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne '');
              return &$I('see @cite{%{book}}', { 'book' => $book },{'duplicate'=>1});
         }
         elsif ($file_node ne '')
         {
              return &$I('see %{node_file_href}', { 'node_file_href' => $file_node },{'duplicate'=>1});
         }
    }
    if ($type eq 'xref' or $type eq 'inforef')
    {
         if (($book ne '') and ($file_node ne ''))
         {
              return &$I('See %{node_file_href} section `%{section}\' in @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne '');
              return &$I('See %{node_file_href} @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book },{'duplicate'=>1});
         }
         elsif ($book ne '')
         {
              return &$I('See section `%{section}\' in @cite{%{book}}', { 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne '');
              return &$I('See @cite{%{book}}', { 'book' => $book },{'duplicate'=>1});
         }
         elsif ($file_node ne '')
         {
              return &$I('See %{node_file_href}', { 'node_file_href' => $file_node },{'duplicate'=>1});
         }
    }
    if ($type eq 'ref')
    {
         if (($book ne '') and ($file_node ne ''))
         {
              return &$I('%{node_file_href} section `%{section}\' in @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne '');
              return &$I('%{node_file_href} @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book },{'duplicate'=>1});
         }
         elsif ($book ne '')
         {
              return &$I('section `%{section}\' in @cite{%{book}}', { 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne '');
              return &$I('@cite{%{book}}', { 'book' => $book },{'duplicate'=>1});
         }
         elsif ($file_node ne '')
         {
              return &$I('%{node_file_href}', { 'node_file_href' => $file_node },{'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;

    if (! $SHORT_REF)
    {
        $name = &$anchor('', $href, $name);
        if ($type eq 'pxref')
        {
            return &$I('see section %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section);
            return &$I('see %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
        }
        elsif ($type eq 'xref' or $type eq 'inforef')
        {
            return &$I('See section %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section);
            return &$I('See %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
        }
        elsif ($type eq 'ref')
        {
            return &$I('%{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
        }
    }
    else
    {
        $name = &$anchor('', $href, $short_name);
        if ($type eq 'pxref')
        {
            return &$I('see %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
        }
        elsif ($type eq 'xref' or $type eq 'inforef')
        {
            return &$I('See %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
        }
        elsif ($type eq 'ref')
        {
            return &$I('%{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
        }
    }
    return '';
}

sub 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;
}

# 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 $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;

    #print STDERR "-> $format (@$style_stack)\n";
    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 (teletyped_in_stack($style_stack))
    {
       $text .= '</tt>';
       $formatted_command = '<tt>' . $formatted_command;
    }
    $text .= "\n" . $index_label  if (defined($index_label));
    return '<dt>' . $formatted_command . $text . '</dt>' . "\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 '<dd>' . $text . '</dd>' . "\n";# unless ($only_inter_item_commands);
        #return $text; # invalid without dd in ul
    }
    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));

    # this is used to keep the cell number
    $t2h_default_multitable_stack[-1]->[0] = -1;

    if ($text =~ /\S/)
    {
         if ($macro eq 'headitem')
         {
              return '<thead><tr>' . $text . '</tr></thead>' . "\n";
         }
         return '<tr>' . $text . '</tr>' . "\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));

    $t2h_default_multitable_stack[-1]->[0]++;
    my $cell_nr = $t2h_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 <strong> is put before the space.
    $text =~ s/^\s*//;
    $text =~ s/\s*$//;

    if ($row_macro eq 'headitem')
    {
        return "<th${fractions}>" . $text . '</th>';
    }
    return "<td${fractions}>" . $text . '</td>';
}

sub t2h_default_format_list_item_texi($$$$)
{
    my $format = shift;
    my $line = shift;
    my $prepended = shift;
    my $command = shift;

    my $result_line;
    my $open_command = 0;

    if (defined($prepended) and $prepended ne '')
    {
         $result_line = $prepended . ' ' . $line;
    }
    $open_command = 1 if (defined($command));
    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;

    $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;
    }
    if ($text =~ /\S/)
    {
        return '<li>' . $prepend . $text . '</li>';
    }
    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;
    $formatted_command = '' if (!defined($formatted_command) or 
          exists($special_list_commands{$format}->{$command}));
    if ($format_command eq 'itemize')
    {
        return "<ul>\n" . $text . "</ul>\n" if (($command eq 'bullet') or (($command eq '') and ($prepended eq '')));
        return "<ul$NO_BULLET_LIST_ATTRIBUTE>\n" . $text . "</ul>\n";
    }
    elsif ($format_command eq 'multitable')
    {
        pop @t2h_default_multitable_stack;
        return &$format('multitable', 'table', $text);
    }
}

# an html comment
sub t2h_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 t2h_get_attribute($;$)
{
    my $command = shift;
    my $map_ref = shift;
    $map_ref = \%style_map if (!defined($map_ref));
    return '' unless (defined($map_ref->{$command}));
    if ((ref($map_ref->{$command}) eq 'HASH') 
       and exists($map_ref->{$command}->{'attribute'}))
    {
        return $map_ref->{$command}->{'attribute'};
    }
    elsif ($map_ref->{$command} !~ /^&/)
    {
        my $attribute = $map_ref->{$command};
        $attribute =~ s/^\"//;
        return $attribute;
    }
    return '';
}

sub t2h_begin_style($$;$)
{
    my $command = shift;
    my $text = shift;
    my $map_ref = shift;
    my $attribute = t2h_get_attribute($command,$map_ref);
    $attribute = "<$attribute>" if ($attribute ne '');
    return $attribute.$text;
}

sub t2h_end_style($$;$)
{
    my $command = shift;
    my $text = shift;
    my $map_ref = shift;
    my $attribute = t2h_get_attribute($command,$map_ref);
    if ($attribute =~ /^(\w+)/)
    {
        $attribute = $1;
    }
    $attribute = "</$attribute>" if ($attribute ne '');
    return $text.$attribute;
}

# 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*$/);

    foreach my $style(t2h_collect_styles($command_stack_at_begin))
    {
       $text = t2h_begin_style($style, $text);
    }
    foreach my $style(t2h_collect_styles($command_stack_at_end))
    {
       $text = t2h_end_style($style, $text);
    }

    if (defined($paragraph_number) and defined($$paragraph_number))
    {
         $$paragraph_number++;
         return $text  if (($format eq 'itemize' or $format eq 'enumerate') and
            ($$paragraph_number == 1));
    }

    my $top_stack = '';
    $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin));
    if ($top_stack eq 'multitable')
    {
       $t2h_default_multitable_stack[-1]->[1]++;
       if ($t2h_default_multitable_stack[-1]->[1] == 0)
       {
           return $text;
       }
    }

    my $open = '<p>';
    if ($align)
    {
        $open = "<p align=\"$paragraph_style{$align}\">";
    }
    return $open.$text.'</p>';
}

# 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 '');
    $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*$//;
    }

    foreach my $style(t2h_collect_styles($command_stack_at_begin))
    {
       $text = t2h_begin_style($style, $text, \%style_map_pre);
    }
    foreach my $style(t2h_collect_styles($command_stack_at_end))
    {
       $text = t2h_end_style($style, $text, \%style_map_pre);
    }
    return "<pre class=\"$class\">".$text."</pre>";
}

# This function formats a heading for an element
#
# argument:
# an element. It is a hash reference for a node or a sectionning 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 sectionning element name, raisesections and lowersections
#      taken into account
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 = &$element_label($element_id, $element, $command, $command_line);
    if ($new_element and !$one_section)
    {
       if (!$element->{'element_ref'}->{'top'})
       {
    #return $result if (defined($command) and $command eq 'node' and !$element_heading);
           $result .= &$print_element_header($first_in_page, $previous_is_top);
       }
       else
       {
           $result .= &$print_head_navigation(undef, \@MISC_BUTTONS) if ($SPLIT or $SECTION_NAVIGATION);
       }
    }

    return $result if (!$element_heading);
    return $result. &$heading($element, $command, $texi_line, $line, $in_preformatted, $one_section, $element_heading);
}

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 = 3;
    if (!$element->{'node'})
    {
        $level = $element->{'level'};
    }
    my $text = $element->{'text'};
    my $class = $element->{'tag_level'};
    $class = 'unnumbered' if ($class eq 'top');
    my $align = '';
    $align = ' align="center"' if ($element->{'tag'} eq 'centerchap');
    if ($element->{'top'})
    {
       return '' if ($element->{'titlefont'});
       $level = 1;
       $text = $Texi2HTML::NAME{'Top'};
       $class = 'settitle' unless ($one_section);
    }
    # when it is a heading, the element is irrelevant, so the command and the
    # line are used...
    if (defined($command) and $command =~ /heading/)
    {
        $level = $main::sec2level{$command} if (defined($main::sec2level{$command}));
        if (defined($line)) 
        {
            $text = $line;
            # this isn't done in main program in that case...
            chomp ($text);
            $text =~ s/^\s*//;
        }
        $class = $command;
    }
    elsif (defined($element->{'tocid'}) and $TOC_LINKS)
    {
         $text = &$anchor ('', "$Texi2HTML::THISDOC{'toc_file'}#$element->{'tocid'}", $text);
    }
    $level = 1 if ($level == 0);
    return '' if ($text !~ /\S/);
    if (!$in_preformatted)
    {
       return "<h$level class=\"$class\"$align>$text</h$level>\n";
    }
    else
    {
       return "<strong>$text</strong>\n";
    }
}

sub t2h_default_heading_no_texi($$$)
{
    my $element = shift;
    my $command = shift;
    my $line = shift;
    return main::remove_texi($line);
}

# formatting of raw regions
# if L2H is true another mechanism is used for tex
sub t2h_default_raw($$)
{
    my $style = shift;
    my $text = shift;
    if ($style eq 'verbatim' or $style eq 'tex')
    {
        return "<pre class=\"$style\">" . &$protect_text($text) . '</pre>';
    }
    elsif ($style eq 'html')
    {
        chomp ($text);
        return $text;
    }
    else
    {
        main::echo_warn ("Raw style $style not handled");
        return &$protect_text($text);
    }
}

# raw environment when removing texi (in comments) 
sub t2h_default_raw_no_texi($$)
{
    my $style = shift;
    my $text = shift;
    return $text;
}

# 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;
    
    if ($document_file eq $footnote_file)
    {
        $document_file = $footnote_file = '';
    }
    unshift (@$lines, '<h3>' . 
          &$anchor($footnote_id, $document_file . "#$place_id",
                   "($number_in_doc)")
          . "</h3>\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'});
    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 t2h_default_foot_section($)
{
    my $lines = shift;
    unshift (@$lines, "<div class=\"footnote\">\n" ,"$DEFAULT_RULE\n", "<h3>" . &$I('Footnotes') . "</h3>\n");
    push (@$lines, "</div>\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;
 
    if (!defined($file_path) or $file_path eq '')
    {
        if (defined($extension) and $extension ne '')
        {
            $file = "$base.$extension";
        }
        else
        {
            $file = "$base.jpg";
        }
        main::echo_warn ("no image file for $base, (using $file)");
    }
    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 "<img src=\"$file\" alt=\"$alt\">";
}

# address put in footer describing when was generated and who did the manual
sub t2h_default_address($$)
{
    my $user = shift;
    my $date = shift;
    $user = '' if (!defined($user));
    $date = '' if (!defined($date));
    if (($user ne '') and ($date ne ''))
    {
        return &$I('by @emph{%{user}} on @emph{%{date}}', { 'user' => $user,
            'date' => $date });
    }
    elsif ($user ne '')
    {
        return &$I('by @emph{%{user}}', { 'user' => $user });
    }
    elsif ($date ne '')
    {
        return &$I('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
# FIXME document the remaining 
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;

    return '' if (!defined($identifier) or ($identifier !~ /\S/));
    my $label = &$anchor($identifier);
    return $label . "\n" if (!$preformatted);
    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;

   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;

   $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 = '<i>' . $arguments . '</i>';
   }
   my $type_name = '';
   $type_name = " $type" if ($type ne '');
   $type_name .= ' <b>' . $name . '</b>' if ($name ne '');
   $type_name .= $arguments;
   if (! $DEF_TABLE)
   {
       return '<dt>'. $index_label. '<u>' . $category_prepared . ':</u>' . $type_name . "</dt>\n";
   }
   else
   {
       
       return "<tr><td align=\"left\">" . $type_name . 
       "</td><td align=\"right\">" . $category_prepared . $index_label . "</td></tr>\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 "<table class=\"cartouche\" border=\"1\"><tr><td>\n" . $text . "</td></tr></table>\n";
    }
    return '';
} 

# 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;

    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;

    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 "<br>\n" x $number if (!$preformatted);
   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;
    
    my $attribute = $command;
    my $opening = "<$attribute>";
    if (defined($explanation_simply_formatted)) 
    {
        $opening = "<$attribute title=\"$explanation_simply_formatted\">";
    }
    if ($with_explanation)
    {
        return &$I('%{acronym_like} (%{explanation})', {'acronym_like' => $opening . $acronym_text . "</$attribute>", 'explanation' => $explanation_text},{'duplicate'=>1})
    }
    else
    {
        return  $opening . $acronym_text . "</$attribute>";
    }
}

sub t2h_default_quotation_prepend_text($$)
{
    my $command = shift;
    my $text = shift;
    return undef if (!defined($text) or $text =~ /^$/);
    $text =~ s/^\s*//;
# FIXME if there is a @ protecting the end of line the result is
# @b{some text @:}
# It is likely not to be what was intended
    chomp($text);
    return &$I('@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 $class_text = '';
    $class_text = " class=\"$command\"" if ($command ne 'quotation');
    return "<blockquote$class_text>" . $text . "</blockquote>\n";
}

# 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 "<table border=\"0\" class=\"index-$name\">\n" .
    "<tr><td></td><th align=\"left\">" . &$I('Index Entry') . "</th><th align=\"left\"> " . &$I('Section') . "</th></tr>\n"
    . "<tr><td colspan=\"3\"> $DEFAULT_RULE</td></tr>\n" . $text .
    "</table>\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 t2h_default_index_letter($$$)
{
     my $letter = shift;
     my $id = shift;
     my $text = shift;
     return '<tr><th>' . &$anchor($id,'',&$protect_text($letter)) . 
     "</th><td></td><td></td></tr>\n" . $text . 
     "<tr><td colspan=\"3\"> $DEFAULT_RULE</td></tr>\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 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;
    
    return '<tr><td></td><td valign="top">' . &$anchor('', $text_href, $entry)
    . '</td><td valign="top">' .  &$anchor('', $element_href, $element_text)
    . "</td></tr>\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 = '';
    $join = " &nbsp; \n<br>\n" if (@$nonalpha and @$alpha);
    if (@$nonalpha)
    {
       $nonalpha_text = join("\n &nbsp; \n", @$nonalpha) . "\n";
    }
    if (@$alpha)
    {
       $alpha_text = join("\n &nbsp; \n", @$alpha) . "\n &nbsp; \n";
    }
    return "<table><tr><th valign=\"top\">" . &$I('Jump to') .": &nbsp; </th><td>" .
    $nonalpha_text . $join . $alpha_text . "</td></tr></table>\n";
}

# 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 =~ s/\s*$//;
    $texi =~ s/^\s*//;
    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) . "\n";
}

sub t2h_default_misc_element_label($$)
{
    my $id = shift;
    my $misc_page_name = shift;
    return &$anchor($id) . "\n";
}

sub t2h_default_anchor_label($$$)
{
    my $id = shift;
    my $anchor_text = shift;
    my $anchor_reference = 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;
}

sub t2h_default_tab_item_texi($$$$$$)
{
   my $comand = shift;
   my $commands_stack = shift;
   my $state = shift;
   my $stack = shift;
   my $line = shift;
   my $line_nr = shift;

   if (defined($commands_stack) and @$commands_stack and $commands_stack->[-1] eq 'multitable' and @t2h_default_multitable_stack)
   {
      $t2h_default_multitable_stack[-1]->[1] = -1;
   }
   return undef;
}

1;
