1# -*-perl-*-
2# vim: set filetype=perl:
3######################################################################
4# File: texi2html.init
5#
6# Default values for command-line arguments and for various customizable
7# procedures are set in this file.
8#
9# A copy of this file is pasted into the beginning of texi2html by
10# running './configure'.
11#
12# Copy this file, rename it and make changes to it, if you like.
13# Afterwards, load the file with command-line
14# option --init-file <your_init_file>
15#
16# $Id: texi2html.init,v 1.272 2010/06/26 09:54:22 pertusus Exp $
17
18######################################################################
19# The following variables can also be set by command-line options
20#
21#
22# The default values are set in this file, texi2html.init and the content
23# of this file is included at the beginning of the texi2html script file.
24# Those values may be overrided by values set in $sysconfdir/texi2html/Config
25# and then by values set in $HOME/texi2html/Config.
26#
27# command line switches may override these values, and values set in files
28# specified by --init-file are also taken into account.
29# values set in these files overwrite values set by the command-line
30# options appearing before --init-file and might still be overwritten by
31# command-line arguments following the --init-file option.
32
33##################################################################
34# options common with makeinfo
35# -I
36# add a directory to the list of directories where @include files are
37# searched for (besides the directory of the file). additional '-I'
38# args are appended to this list.
39# (APA: Don't implicitely search ., to conform with the docs!)
40# my @INCLUDE_DIRS = (".");
41
42#use strict;
43
44@INCLUDE_DIRS = ();
45
46# -P
47# prepend a directory to the list of directories where @include files are
48# searched for before the directory of the file. additional '-P'
49# args are prepended to this list.
50@PREPEND_DIRS = ();
51
52# --split section|chapter|node|none
53# if $SPLIT is set to 'section' (resp. 'chapter') one html file per section
54# (resp. chapter) is generated. If $SPLIT is set to 'node' one html file per
55# node or sectioning element is generated. In all these cases separate pages
56# for Top, Table of content (Toc), Overview and About are generated.
57# Otherwise a monolithic html file that contains the whole document is
58# created.
59#$SPLIT = 'section';
60$SPLIT = '';
61
62# --separated-footnotes
63# if this is set footnotes are on a separated page. Otherwise they are at
64# the end of each file (if the document is split).
65$FOOTNOTESTYLE = 'end';
66
67# --fill-column
68$FILLCOLUMN = 72;
69
70# --number | --no-number
71# if this is set the sections are numbered, and section names and numbers
72# are used in references and menus (instead of node names).
73$NUMBER_SECTIONS = 1;
74
75# --headers
76# if this is set then navigation panels are printed at the beginning of each
77# section.
78# If the document is split at nodes then navigation panels are
79# printed at the end if there were more than $WORDS_IN_PAGE words on page.
80#
81# Navigation panels are always printed at the beginning of output files.
82#
83# This is most useful if you do not want to have section navigation
84# with --split chapter. There will be chapter navigation panel at the
85# beginning and at the end of chapters anyway.
86# this is mostly not used in the default case, important for html.
87$HEADERS = 0;
88
89# -o filename
90# If this is set a monolithic document is outputted into $filename.
91$OUT = undef;
92
93# --split-size
94# if undef, the info output is not split
95$SPLIT_SIZE = 300000;
96
97# --internal-links
98$INTERNAL_LINKS = undef;
99
100# --no-validate
101# suppress node cross-reference validation
102$NOVALIDATE = 0;
103
104# --documentlanguage
105# use gdt('my string') if you want to have translations of 'my string'
106# and provide the translations in $LANGUAGES->{$DOCUMENTLANGUAGE} with
107# 'my string' as key.
108# To add a new language use ISO 639 language codes (see e.g. perl module
109# Locale-Codes-1.02 for  definitions). Supply translations in the
110# $LANGUAGES hash and put it in a file with $LANG as name in an i18n
111# directory.
112# This is used for the initial language, it is overriden during
113# document processing if there is a @documentlanguage.
114# It is ignored if the language is passed on the command line.
115$DOCUMENTLANGUAGE = 'en';
116
117# --transliterate-file-names
118# transliterate node names for external refs (and internal if NODE_FILES)
119$TRANSLITERATE_FILE_NAMES = 1;
120
121# --error-limit
122# quit after NUM errors (default 1000).
123$ERROR_LIMIT = 1000;
124
125# --css-include
126# All the specified css files are used. More precisely the @import sections
127# are added to the beginning of the CSS_LINES the remaining is added at
128# the end of the CSS_LINES (after the css rules generated by the program).
129# cf texinfo manual for more info.
130# - means STDIN
131@CSS_FILES = ();
132
133# --css-ref
134# the specified url are used as stylesheet links
135@CSS_REFS = ();
136
137# --paragraph-indent
138$PARAGRAPHINDENT = 3;
139
140# --enable-encoding
141$ENABLE_ENCODING = 0;
142
143# --force
144$FORCE = 0;
145
146# --no-warn
147$NO_WARN = 0;
148
149# --number-footnotes
150$NUMBER_FOOTNOTES = 1;
151
152# not in makeinfo but in texi2dvi
153# --command
154@COMMANDS = ();
155
156##################################################################
157# option specific of texi2html
158# --debug
159# The integer value specifies what kind of debugging output is generated.
160$DEBUG = 0;
161
162# --doctype
163# The value is the 'SystemLiteral' which identifies the canonical DTD
164# for the document.
165# Definition: The SystemLiteral is called the entity's system
166# identifier. It is a URI, which may be used to retrieve the entity.
167# See http://www.xml.com/axml/target.html#NT-ExternalID
168$DOCTYPE = '';
169
170# --frameset-doctype
171# When frames are used, this SystemLiteral identifies the DTD used for
172# the file containing the frame description.
173$FRAMESET_DOCTYPE = '';
174
175# --test
176# If this value is true, some variables which should be dynamically generated
177# (the date, the user running texi2html, the version of texi2html) are set to
178# fix and given values. This is usefull in case the resulting manual is
179# compared with a reference. For example this is used in the tests.
180$TEST = 0;
181
182# --dump-texi
183# This value is usefull for debugging purposes. The result of the first pass is
184# put in <document name>.passtexi, the result of the second pass is put in
185# <document name>.passfirst.
186$DUMP_TEXI = 0;
187
188# --expand
189# the @EXPAND array contains the expanded section names.
190@EXPAND = ();
191
192# --invisible
193# This seems obsolete and is not used anywhere.
194# This was a workaround for a known bug of many WWW browsers, including
195# netscape. This was used to create invisible destination in anchors.
196$INVISIBLE_MARK = '';
197# $INVISIBLE_MARK = '&#160;';
198
199# --iso
200# if this value is true, ISO8859 characters are used for quotes.
201# --iso does more than what USE_ISO does.
202$USE_ISO = 0;
203
204# --conf-dir
205# append to the files searched for init files.
206@CONF_DIRS = ();
207
208# --top-file
209# This file name is used for the top-level file.
210# The extension is set appropriately, if necessary.
211# If empty, <basename of document>.html is used.
212# Typically, you would set this to "index.html".
213$TOP_FILE = '';
214
215# --toc-file
216# This file name is used for the table of contents.  The
217# extension is set appropriately, if necessary.
218# If empty, <basename of document>_toc.html is used.
219$TOC_FILE = '';
220
221# --frames
222# if the value is true, HTML 4.0 "frames" are used.
223# A file describing the frame layout is generated, together with a file
224# with the short table of contents.
225$FRAMES = 0;
226
227# --menu | --no-menu
228# if the value is true the Texinfo menus are shown.
229# this is defined in all the formats
230$SHOW_MENU = 1;
231
232# --use-nodes
233# if this is set the nodes are used as sectioning elements.
234# Otherwise the nodes are incorporated in sections.
235$USE_NODES = 1;
236
237# --node-files
238# if this is set one file per node is generated, which can be a target for
239# cross manual references.
240$NODE_FILES = 0;
241
242# --toc-links
243# if this is set, links from headings to toc entries are created.
244$TOC_LINKS = 0;
245
246# --subdir
247# If this is set, then put result files into the specified directory.
248# If not set, then result files are put into the current directory.
249#$SUBDIR = 'html';
250$SUBDIR = '';
251
252# --short-extn
253# If this is set, then all HTML files will have extension ".htm" instead of
254# ".html". This is helpful when shipping the document to DOS-based systems.
255$SHORTEXTN = 0;
256
257# --prefix
258# This set the output file prefix, prepended to all .html, .gif and .pl files.
259# By default, this is the basename of the document.
260$PREFIX = '';
261
262# --short-ref
263# if this is set cross-references are given without section.
264$SHORT_REF = 1;
265
266# --idx-sum
267# if value is set, then for each @printindex <index name>
268# <document name>_<index name>.idx is created which contains lines of the form
269# key ref sorted alphabetically (case matters).
270$IDX_SUMMARY = 0;
271
272# --def-table
273# If this is set a table construction for @def.... instead of definition
274# lists.
275# (New Option: 27.07.2000 Karl Heinz Marbaise)
276$DEF_TABLE = 0;
277
278# --verbose
279# if this is set chatter about what we are doing.
280$VERBOSE = '';
281
282# --ignore-preamble-text
283# If this is set the text before @node and sectioning commands is ignored.
284$IGNORE_PREAMBLE_TEXT = 0;
285
286# --html-xref-prefix
287# base directory for external manuals.
288#$EXTERNAL_DIR = '../';
289$EXTERNAL_DIR = undef;
290
291# --l2h
292# if this is set, latex2html is used for generation of math content.
293$L2H = '';
294
295# --monolithic
296# output only one file including ToC. It only makes sense when not split
297$MONOLITHIC = 1;
298
299######################
300# The following options are only relevant if $L2H is set
301#
302# --l2h-l2h
303# name/location of latex2html program
304$L2H_L2H = "latex2html";
305
306# --l2h-skip
307# If this is set the actual call to latex2html is skipped. The previously
308# generated content is reused, instead.
309# If set to 0, the cache is not used.
310# If undef the cache is used for as many tex fragments as possible
311# and for the remaining the command is run.
312$L2H_SKIP = undef;
313
314# --l2h-tmp
315# If this is set l2h uses the specified directory for temporary files. The path
316# leading to this directory may not contain a dot (i.e., a ".");
317# otherwise, l2h will fail.
318$L2H_TMP = '';
319
320# --l2h-file
321# If set, l2h uses the file as latex2html init file
322$L2H_FILE = 'l2h.init';
323
324# --l2h-clean
325# if this is set the intermediate files generated by texi2html in relation with
326# latex2html are cleaned (they all have the prefix <document name>_l2h_).
327$L2H_CLEAN = 1;
328
329##############################################################################
330#
331# The following can only be set in the init file
332#
333##############################################################################
334
335@INPUT_FILE_SUFFIXES = ('.txi','.texinfo','.texi','.txinfo','');
336
337$FIRSTPARAGRAPHINDENT = 'none';
338
339@T2H_FORMAT_EXPAND = ('plaintext');
340
341# simple headers formatting, not in a table and using node names.
342$HEADER_IN_TABLE = 0;
343
344# output the generation date in the header.
345$DATE_IN_HEADER = 0;
346
347# use table for indentation of complex formats
348$COMPLEX_FORMAT_IN_TABLE = 0;
349
350# if set, node names are used to construct file names
351# if undef, it is set if split at node, or $NODE_FILES is set.
352$NODE_FILENAMES = undef;
353
354# If true do table of contents even if there is no @content
355$CONTENTS = undef;
356
357# If true do short table of contents even if there is no @shortcontent
358$SHORTCONTENTS = undef;
359
360# set by @setcontentsaftertitlepage/@setshortcontentsaftertitlepage
361$SETCONTENTSAFTERTITLEPAGE = undef;
362$SETSHORTCONTENTSAFTERTITLEPAGE = undef;
363
364# corresponds with @kbdinputstyle
365$KBDINPUTSTYLE = 'distinct';
366
367# corresponds with @frenchspacing
368$FRENCHSPACING = 'off';
369
370# correspond with @allowcodebreaks
371$ALLOWCODEBREAKS = 'true';
372
373# corresponds with @setfilename. Set with caution.
374$SETFILENAME = undef;
375
376# if unset, don't show a title
377$SHOW_TITLE = 1;
378
379# if set style is added in attribute.
380$INLINE_CSS_STYLE = 0;
381
382# if set, no css is used.
383$NO_CSS = 0;
384
385# if set, the image files are completed to be relative from the
386# document directory, to the source manual directory and then to
387# the image
388$COMPLETE_IMAGE_PATHS = 0;
389
390# if true, begin outputting at @setfilename, if this command is present.
391$IGNORE_BEFORE_SETFILENAME = 1;
392
393# if true the link in Overview link to the corresponding Toc entry.
394$OVERVIEW_LINK_TO_TOC = 1;
395
396# if set, use node anchors for sections targets
397$USE_NODE_TARGET = 1;
398
399# new style for crossrefs
400$NEW_CROSSREF_STYLE = 1;
401
402# top heading is always at the beginning of the element.
403$TOP_HEADING_AT_BEGINNING = 0;
404
405# use titlepage for the title instead of a simplest title
406$USE_TITLEPAGE_FOR_TITLE = 0;
407
408# if set, center @image by default
409# otherwise, do not center by default
410# Deprecated and not used anymore
411$CENTER_IMAGE = 1;
412
413# used as identation for block enclosing command @example, etc
414# If not empty, must be enclosed in <td></td>
415$EXAMPLE_INDENT_CELL = '';
416
417# same as above, only for @small
418$SMALL_EXAMPLE_INDENT_CELL = '';
419
420# unused
421$SMALL_FONT_SIZE = '-1';
422
423# horizontal rules
424# not used
425$SMALL_RULE = '';
426$MIDDLE_RULE = '';
427# used in html
428$DEFAULT_RULE = '';
429$BIG_RULE = '';
430
431# output the program name in the footer
432$PROGRAM_NAME_IN_FOOTER = 0;
433
434# if non-empty, and no @..heading appeared in Top node, then
435# use this as header for top node/section, otherwise use value of
436# @settitle or @shorttitle (in that order)
437$TOP_HEADING = '';
438
439# if set, use this chapter for 'Index' button, else
440# use first chapter with @printindex
441$INDEX_CHAPTER = '';
442
443$SIMPLE_MENU = 1;
444
445$OPEN_QUOTE_SYMBOL = "\`";
446$CLOSE_QUOTE_SYMBOL = "'";
447
448$NO_NUMBER_FOOTNOTE_SYMBOL = '*';
449
450# if true put a $MENU_SYMBOL before unnumbered in menus
451$UNNUMBERED_SYMBOL_IN_MENU = 0;
452
453# extension for nodes files when NODE_FILES is true
454$NODE_FILE_EXTENSION = 'txt';
455
456# extension
457$EXTENSION = 'txt';
458
459# file name used for Top node when NODE_FILES is true
460#$TOP_NODE_FILE = 'index';
461$TOP_NODE_FILE = undef;
462
463# file name used for Top node in references
464$TOP_NODE_FILE_TARGET = 'index';
465
466# file used as document basename, when input file is -
467$STDIN_DOCU_NAME = 'stdin';
468
469# file used as document output basename, when output file is -
470$STDOUT_DOCU_NAME = 'stdout';
471
472# node name used for Top node when automatic node directions are used
473$TOP_NODE_UP = '(dir)';
474
475# this controls the pre style for menus
476$MENU_PRE_STYLE = 'font-family: serif';
477
478# on bug-texinfo is has been said the the style is not code_style
479# for menus (except for the node name).
480# this controls the menu preformatted format
481# FIXME this is not dynamic, so change in MENU_PRE_STYLE is not taken
482# into account.
483# This is used if the menu appears within a preformatted format (which
484# is certainly an invalid construct), and SIMPLE_MENU is not set.
485$MENU_PRE_COMPLEX_FORMAT = {
486              'class' => 'menu-preformatted',
487#              'style' => 'code'
488   };
489
490# This controls the ul style for toc
491$NO_BULLET_LIST_STYLE = '';
492$NO_BULLET_LIST_ATTRIBUTE = '';
493
494# These lines are inserted before and after the shortcontents
495$BEFORE_OVERVIEW = "";
496$AFTER_OVERVIEW = "";
497
498# These lines are inserted before and after the contents
499$BEFORE_TOC_LINES = "";
500$AFTER_TOC_LINES = "";
501
502# if set (e.g., to index.html) replace hrefs to this file
503# (i.e., to index.html) by ./
504# Obsolete. Worked around a bug that is fixed now.
505$HREF_DIR_INSTEAD_FILE = '';
506
507# text inserted after <body ...>
508$AFTER_BODY_OPEN = '';
509
510# text inserted before </body>, this will be automatically inside <p></p>
511$PRE_BODY_CLOSE = '';
512
513# this is added inside <head></head> after <title> and some <meta name>
514# stuff, it can be used for eg. <style>, <script>, <meta> etc. tags.
515$EXTRA_HEAD = '';
516
517# Specifies the minimum page length required before a navigation panel
518# is placed at the bottom of a page
519# FIXME this is not true:
520# THIS_WORDS_IN_PAGE holds number of words of current page
521$WORDS_IN_PAGE = 300;
522
523# if this is set a vertical navigation panel is used.
524$VERTICAL_HEAD_NAVIGATION = 0;
525
526# html version for latex2html
527$L2H_HTML_VERSION = "4.0";
528
529# use icons.
530$ICONS = 0;
531
532# use old framework for translations
533$I18N_PERL_HASH = 0;
534
535
536# this resets some defaults, those that are also set in formats and
537# not set in every formats.
538#
539# this is called below after %default_style_map_texi is defined
540sub t2h_default_set_variables_default()
541{
542  $CAPTION_STYLE = 'strong';
543
544# if this variable is true, @setfilename is used if found to determine the
545# out file name
546  $USE_SETFILENAME = 1;
547
548# if true, use the filename and extension from setfilename. For Info.
549  $USE_SETFILENAME_EXTENSION = 0;
550
551# FIXME is this right?
552# default used in init_out for the setting of the ENCODING_NAME variable
553  $DEFAULT_ENCODING = 'utf8';
554
555# if set and menu entry equals menu description, then do not print
556# menu description.
557# Likewise, if node name equals entry name, do not print entry name.
558  $AVOID_MENU_REDUNDANCY = 0;
559
560# if true, use the original command if the result is an entity
561  $ENABLE_ENCODING_USE_ENTITY = 0;
562
563# if set, output the contents where the command is located
564# This is ignored if set*contentsaftertitlepage is set
565  $INLINE_CONTENTS = 1;
566
567# symbol put at the beginning of nodes entry in menu (and optionnaly of
568# unnumbered in menus, see UNNUMBERED_SYMBOL_IN_MENU variable)
569  $MENU_SYMBOL = '*';
570
571# symbol put at the end of nodes entry in menu
572  $MENU_ENTRY_COLON = ':';
573
574# symbol put at the end of index entries
575  $INDEX_ENTRY_COLON = ':';
576
577# if set, then use node names in menu entries, instead of section names
578  $NODE_NAME_IN_MENU = 1;
579
580# if set use the node names in index entry, instead of section names
581# if not set, it is set to the same value than NODE_NAME_IN_MENU
582  $NODE_NAME_IN_INDEX = undef;
583
584# if set always separate description and menu link, even in
585# preformatted environment
586  $SEPARATE_DESCRIPTION = 0;
587
588# try up sections to complete the node directions
589  $USE_UP_FOR_ADJACENT_NODES = 0;
590
591# use accesskey in hrefs
592  $USE_ACCESSKEY = 1;
593
594# use rel= and rev= in hrefs. Currently only rel is used
595  $USE_REL_REV = 1;
596
597# generate <link> elements in head
598  $USE_LINKS = 1;
599
600# if this variable is true, numeric entities are used when there is no
601# corresponding textual entity.
602  $USE_NUMERIC_ENTITY = 0;
603
604# if set and $SPLIT is set, then split index pages at the next letter
605# after they have more than that many entries
606  $SPLIT_INDEX = 0;
607
608# file name used for Top node when NODE_FILES is true
609  $TOP_NODE_FILE = undef;
610
611# extensions used for images
612  @IMAGE_EXTENSIONS = ('png','jpg', 'txt');
613
614  $USE_NODES = 1;
615
616  $USE_SECTIONS = 1;
617
618# also set by command line options
619  $FOOTNOTESTYLE = 'end';
620
621  $DOCTYPE = '';
622
623  $USE_ISO = 0;
624
625  $NUMBER_SECTIONS = 1;
626
627  $TOP_FILE = '';
628
629  $ENABLE_ENCODING = 0;
630
631#
632# Formatting functions
633#
634# They will be reset here between formats switch
635# if they are defined in this function.
636#
637
638# these are more or less the documented vanilla versions, so they
639# are reset
640$unknown           = \&t2h_default_unknown;
641$unknown_style     = \&t2h_default_unknown_style;
642$external_ref      = \&t2h_default_external_ref;
643$internal_ref      = \&t2h_default_internal_ref;
644$tab_item_texi     = \&t2h_default_tab_item_texi;
645$complex_format    = \&t2h_default_complex_format;
646$toc_body          = \&T2H_DEFAULT_toc_body;
647$misc_command_line = \&t2h_default_misc_command_line;
648$misc_command_line_texi = \&t2h_default_misc_command_line;
649$print_title               = \&T2H_DEFAULT_print_title;
650# reset in info and xml
651$element_heading = \&t2h_default_element_heading;
652# reset in html
653$inline_contents    = \&T2H_DEFAULT_inline_contents;
654# reset in docbook and info.
655$style                    = \&T2H_GPL_style;
656$format                   = \&T2H_GPL_format;
657# reset in info
658$simple_command             = \&t2h_default_simple_command;
659# reset in info
660$thing_command              = \&t2h_default_thing_command;
661# reset in html and xml
662$caption_shortcaption     = \&t2h_default_caption_shortcaption;
663$caption_shortcaption_command  = \&t2h_default_caption_shortcaption_command;
664# reset in docbook and xml. Not really vanilla, but documented.
665$printindex        = \&t2h_GPL_default_printindex;
666# reset by xml and html
667$misc_element_label         = \&t2h_default_misc_element_label;
668# set in html
669$init_out    = \&t2h_default_init_out;
670# set in info and xml
671$paragraph_style_command  = \&t2h_default_paragraph_style_command;
672# set in info
673$colon_command            = \&t2h_default_colon_command;
674# set in docbook
675$quotation_prepend_text   = \&t2h_default_quotation_prepend_text;
676# set in info
677$copying_comment = \&t2h_default_copying_comment;
678
679# set in html and info
680$print_section            = \&T2H_DEFAULT_print_section;
681
682# set in docbook and xml
683%colon_command_punctuation_characters = (
684   '.' => '.',
685   ':' => ':',
686   '?' => '?',
687   '!' => '!'
688);
689
690
691
692# in info
693$footnote_texi = undef;
694$begin_paragraph_texi = undef;
695$begin_style_texi = undef;
696$begin_special_region = undef;
697$end_special_region = undef;
698$empty_preformatted = undef;
699
700%line_command_map = (
701       'title'    => '',
702       'subtitle' => '',
703       'author'   => '',
704);
705
706%format_in_paragraph = (
707);
708# map mapping css specification to style
709
710%css_map =
711     (
712     );
713
714@text_substitutions_normal = ();
715@text_substitutions_texi = ();
716@text_substitutions_simple_format = ();
717@text_substitutions_pre = ();
718
719%region_formats_kept = ();
720
721%style_map_texi = ();
722t2h_default_copy_style_map (\%default_style_map_texi, \%style_map_texi);
723
724# reset in info
725%simple_map_texi = %default_simple_map;
726
727# modified in docbook
728%special_accents = (
729      'ringaccent' => 'aA',
730      "'"          => 'aeiouyAEIOUY',
731      ','          => 'cC',
732      '^'          => 'aeiouAEIOU',
733      '`'          => 'aeiouAEIOU',
734      '~'          => 'nNaoAO',
735      '"'          => 'aeiouyAEIOU',
736# according to http://www2.lib.virginia.edu/small/vhp/download/ISO.txt
737# however this doesn't seems to work in firefox
738#      'ogonek'     => 'aeiuAEIU',
739);
740
741# modified by info, xml, docbook
742# %no_paragraph_commands should not be reset since it has been
743# filled with defaults for many other commands.
744
745# FIXME this prevents the user from setting those entries.
746$no_paragraph_commands{'cindex'} = 1;
747$no_paragraph_commands{'float'} = 1;
748delete $no_paragraph_commands{'anchor'};
749
750# modified in docbook and xml
751%stop_paragraph_command = (
752 'titlefont' => 1,
753 'insertcopying' => 1,
754 'sp' => 1,
755 'verbatiminclude' => 1,
756 'page' => 1,
757# FIXME they also stop preformatted, so cannot be here.
758# 'printindex' => 1,
759# 'listoffloats' => 1
760);
761
762}
763
764sub t2h_default_raw_text_load()
765{
766  $SPLIT = '';
767  # extension for nodes files when NODE_FILES is true
768  $NODE_FILE_EXTENSION = 'txt';
769
770  # extension
771  $EXTENSION = 'txt';
772  @T2H_FORMAT_EXPAND = ('plaintext');
773  $USE_TITLEPAGE_FOR_TITLE = 0;
774  $HEADERS = 0;
775  $SIMPLE_MENU = 1;
776  $INLINE_INSERTCOPYING = 0;
777  $NODE_FILENAMES = undef;
778
779  %simple_map = %default_simple_map;
780  %simple_map_pre = %simple_map;
781
782  %things_map = %default_things_map;
783  %pre_map = %things_map;
784
785  %style_map = ();
786  %style_map_pre = ();
787  t2h_default_copy_style_map (\%default_style_map, \%style_map);
788  t2h_default_copy_style_map (\%default_style_map_pre, \%style_map_pre);
789
790  # could also be t2h_default_set_iso_symbols()
791  t2h_remove_text_substitutions("'", 1, 0, 0, 1);
792  t2h_remove_text_substitutions('`', 1, 0, 0, 1);
793  $OPEN_QUOTE_SYMBOL = '`';
794  $CLOSE_QUOTE_SYMBOL = "'";
795
796  $BEFORE_OVERVIEW = "";
797  $AFTER_OVERVIEW = "";
798
799  $BEFORE_TOC_LINES = "";
800  $AFTER_TOC_LINES = "";
801
802
803  foreach my $complex_format ('example', 'smallexample', 'display',
804  'smalldisplay', 'lisp', 'smalllisp', 'format', 'smallformat',
805  'menu', 'detailmenu', 'direntry', 'menu_comment')
806  {
807    $complex_format_map{$complex_format}->{'begin'} = '';
808    $complex_format_map{$complex_format}->{'end'} = '';
809  }
810
811  %format_map = (
812#       'quotation'   =>  'blockquote',
813       # lists
814#       'itemize'     =>  'ul',
815       'enumerate'   =>  '',
816#       'multitable'  =>  'table',
817       'table'       =>  '',
818       'vtable'      =>  '',
819       'ftable'      =>  '',
820       'group'       =>  '',
821       'raggedright'       =>  '',
822#       'detailmenu'  =>  '',
823       );
824
825  #
826  # Controls the layout
827  #
828
829  $print_page_head              = \&T2H_DEFAULT_print_page_head;
830  $contents                 = \&T2H_DEFAULT_contents;
831  $shortcontents            = \&T2H_DEFAULT_shortcontents;
832  $one_section              = \&T2H_DEFAULT_one_section;
833  $print_Top                = \&T2H_DEFAULT_print_Top;
834  $print_Top_footer             = \&T2H_DEFAULT_print_Top_footer;
835  $print_misc_header            = \&T2H_DEFAULT_print_misc_header;
836  $print_misc_footer            = \&T2H_DEFAULT_print_misc_footer;
837  $print_section_footer     = \&T2H_DEFAULT_print_section_footer;
838  $print_chapter_header     = \&T2H_DEFAULT_print_chapter_header;
839  $print_section_header     = \&T2H_DEFAULT_print_section_header;
840  $print_chapter_footer     = \&T2H_DEFAULT_print_chapter_footer;
841  $print_page_foot              = \&T2H_DEFAULT_print_page_foot;
842  $print_head_navigation    = \&T2H_DEFAULT_print_head_navigation;
843  $print_foot_navigation    = \&T2H_DEFAULT_print_foot_navigation;
844  $end_section              = \&T2H_DEFAULT_end_section;
845  # changed in info
846  $print_Footnotes              = \&T2H_DEFAULT_print_Footnotes;
847  # used if split
848  $about_body                 = \&T2H_DEFAULT_about_body;
849  $print_navigation           = \&T2H_DEFAULT_print_navigation;
850
851  #
852  # Controls the formatting
853  #
854
855  $empty_line               = \&t2h_default_empty_line;
856  $anchor            = \&t2h_default_anchor;
857  $anchor_label               = \&t2h_default_anchor_label;
858  $image             = \&t2h_default_image;
859  $heading           = \&t2h_default_heading;
860  $heading_text      = \&t2h_default_heading_text;
861  $heading_text_preformatted      = \&t2h_default_heading_text_preformatted;
862  $element_label              = \&t2h_default_element_label;
863  $index_entry_label = \&t2h_default_index_entry_label;
864  #$menu_command      = \&t2h_default_menu_command;
865  $menu_link         = \&t2h_default_menu_link;
866  #$menu_description  = \&t2h_default_menu_description;
867  $paragraph         = \&t2h_default_paragraph;
868  $preformatted      = \&t2h_default_preformatted;
869  $protect_text      = \&t2h_default_protect_text;
870  $normal_text       = \&t2h_default_normal_text;
871  $acronym_like             = \&t2h_default_acronym_like;
872  $sp                = \&t2h_default_sp;
873  $quotation                = \&t2h_default_quotation;
874  $table_list        = \&t2h_default_table_list;
875  $list_item         = \&t2h_default_list_item;
876  $table_line        = \&t2h_default_table_line;
877  $table_item        = \&t2h_default_table_item;
878  $cell              = \&t2h_default_cell;
879  $row               = \&t2h_default_row;
880  $def_item          = \&t2h_default_def_item;
881  $def               = \&t2h_default_def;
882  $def_line          = \&t2h_default_def_line;
883  $cartouche         = \&t2h_default_cartouche;
884  $raw               = \&t2h_default_raw;
885  $format_list_item_texi      = \&t2h_default_format_list_item_texi;
886  $print_index       = \&t2h_default_print_index;
887  $index_summary     = \&t2h_default_index_summary;
888  $index_entry       = \&t2h_default_index_entry;
889  $index_letter      = \&t2h_default_index_letter;
890  $foot_line_and_ref = \&t2h_default_foot_line_and_ref;
891  $foot_section      = \&t2h_default_foot_section;
892  $tab_item_texi     = \&t2h_default_tab_item_texi;
893  $listoffloats             = \&t2h_default_listoffloats;
894  $listoffloats_entry       = \&t2h_default_listoffloats_entry;
895  $float                     = \&t2h_default_float;
896
897  t2h_default_set_variables_default();
898}
899
900my %things_map_xml;
901my %pre_map_xml;
902
903sub t2h_default_set_variables_xml()
904{
905  t2h_default_set_variables_default();
906  $ENABLE_ENCODING_USE_ENTITY = 1;
907  $EXTENSION = 'xml';
908  t2h_default_set_iso_symbols(1);
909
910  $empty_line = \&t2h_default_empty_line;
911  $comment = \&xml_default_comment;
912  $line_command = \&xml_default_line_command;
913
914  %things_map = %things_map_xml;
915  %pre_map = %pre_map_xml;
916  %simple_format_texi_map = %pre_map;
917
918  %simple_format_style_map_texi = ();
919  t2h_default_copy_style_map (\%default_style_map_texi, \%simple_format_style_map_texi);
920  foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents))
921  {
922#    $simple_format_style_map_texi{$accent_command}->{'args'} = ['normal'];
923    $simple_format_style_map_texi{$accent_command}->{'function'} = \&xml_default_accent;
924  }
925}
926
927sub t2h_default_set_variables_texi2html()
928{
929  $USE_SETFILENAME = 0;
930  $USE_SETFILENAME_EXTENSION = 0;
931  $FOOTNOTESTYLE = 'separate';
932  $INLINE_CONTENTS = 0;
933  $FORCE = 1;
934  $AVOID_MENU_REDUNDANCY = 1;
935  $TOP_HEADING_AT_BEGINNING = 1;
936  $TOP_FILE = '';
937  $USE_ACCESSKEY = 0;
938  $NODE_NAME_IN_MENU = 0;
939  $OVERVIEW_LINK_TO_TOC = 0;
940  $USE_UP_FOR_ADJACENT_NODES = 1;
941  $USE_ACCESSKEY = 0;
942  $USE_REL_REV = 0;
943  $USE_LINKS = 0;
944  $USE_NODES = undef;
945  $USE_SECTIONS = 1;
946  $NODE_FILENAMES = 0;
947  $USE_NUMERIC_ENTITY = 1;
948  $SPLIT = '';
949  $SPLIT_INDEX = 100;
950  $PROGRAM_NAME_IN_FOOTER = 1;
951  $HEADER_IN_TABLE = 1;
952  $SHORT_REF = 0;
953  $USE_TITLEPAGE_FOR_TITLE = 1;
954  $MENU_ENTRY_COLON = '';
955  $INDEX_ENTRY_COLON = '';
956
957  $ENABLE_ENCODING_USE_ENTITY = 1;
958}
959
960# specify in this array which "buttons" should appear in which order
961# in the navigation panel for sections; use ' ' for empty buttons (space)
962@SECTION_BUTTONS =
963    (
964     'FastBack', 'Back', 'Up', 'Forward', 'FastForward',
965     ' ', ' ', ' ', ' ',
966     'Top', 'Contents', 'Index', 'About',
967    );
968
969# buttons for misc stuff
970@MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About');
971
972@TOP_BUTTONS = ( 'Back', 'Forward', ' ','Contents', 'Index', 'About');
973#@TOP_BUTTONS = ('Top', 'Contents', 'Index', 'About');
974
975
976# buttons for chapter file footers
977# (and headers but only if HEADERS is false)
978@CHAPTER_BUTTONS =
979    (
980     'FastBack', 'FastForward', ' ',
981     ' ', ' ', ' ', ' ',
982     'Top', 'Contents', 'Index', 'About',
983    );
984
985# buttons for section file footers
986@SECTION_FOOTER_BUTTONS =
987    (
988     'FastBack', 'Back', 'Up', 'Forward', 'FastForward',
989    );
990
991@NODE_FOOTER_BUTTONS = @SECTION_BUTTONS;
992
993@LINKS_BUTTONS =
994    (
995      'Top', 'Index', 'Contents', 'About', 'Up', 'NextFile', 'PrevFile'
996    );
997
998
999# insert here name of icon images for buttons
1000# Icons are used, if $ICONS and resp. value are set
1001%ACTIVE_ICONS =
1002    (
1003     'Top',         '',
1004     'Contents',    '',
1005     'Overview',    '',
1006     'Index',       '',
1007     'This',        '',
1008     'Back',        '',
1009     'FastBack',    '',
1010     'Prev',        '',
1011     'Up',          '',
1012     'Next',        '',
1013     'NodeUp',      '',
1014     'NodeNext',    '',
1015     'NodePrev',    '',
1016     'Following',   '',
1017     'Forward',     '',
1018     'FastForward', '',
1019     'About' ,      '',
1020     'First',       '',
1021     'Last',        '',
1022     'NextFile',    '',
1023     'PrevFile',    '',
1024     ' ',           '',
1025    );
1026
1027# insert here name of icon images for these, if button is inactive
1028%PASSIVE_ICONS =
1029    (
1030     'Top',         '',
1031     'Contents',    '',
1032     'Overview',    '',
1033     'Index',       '',
1034     'This',        '',
1035     'Back',        '',
1036     'FastBack',    '',
1037     'Prev',        '',
1038     'Up',          '',
1039     'Next',        '',
1040     'NodeUp',      '',
1041     'NodeNext',    '',
1042     'NodePrev',    '',
1043     'Following',   '',
1044     'Forward',     '',
1045     'FastForward', '',
1046     'About',       '',
1047     'First',       '',
1048     'Last',        '',
1049     'NextFile',    '',
1050     'PrevFile',    '',
1051    );
1052
1053%misc_pages_targets = (
1054   'Overview' => 'SEC_Overview',
1055   'Contents' => 'SEC_Contents',
1056   'Footnotes' => 'SEC_Foot',
1057   'About' => 'SEC_About'
1058);
1059
1060# determine the null devices
1061my $default_null_device = File::Spec->devnull();
1062%null_device_file = (
1063 $default_null_device => 1
1064);
1065# special case, djgpp recognizes both null devices
1066if ($Config{osname} eq 'dos' and $Config{osvers} eq 'djgpp')
1067{
1068  $null_device_file{'/dev/null'} = 1;
1069  $null_device_file{'NUL'} = 1;
1070}
1071
1072$finish_out    = \&t2h_default_finish_out;
1073$translate_names = \&t2h_default_translate_names;
1074
1075sub t2h_default_translate_names()
1076{
1077# Names of text as alternative for icons
1078# FIXME maybe get those in simple_format?
1079    %NAVIGATION_TEXT =
1080    (
1081     'Top',         gdt('Top'),
1082     'Contents',    gdt('Contents'),
1083     'Overview',    gdt('Overview'),
1084     'Index',       gdt('Index'),
1085     ' ',           ' ',
1086     'This',        gdt('Current'),
1087     'Back',        ' < ',
1088     'FastBack',    ' << ',
1089     'Prev',        gdt('Previous'),
1090     'Up',          gdt('Up'),
1091     'Next',        gdt('Next'),
1092     'NodeUp',      gdt('Up'),
1093     'NodeNext',    gdt('Next'),
1094     'NodePrev',    gdt('Previous'),
1095     'Following',   gdt('Following'),
1096     'Forward',     ' > ',
1097     'FastForward', ' >> ',
1098     'About',       ' ? ',
1099     'First',       ' |< ',
1100     'Last',        ' >| ',
1101     'NextFile',    gdt('Next file'),
1102     'PrevFile',    gdt('Previous file'),
1103    );
1104    %BUTTONS_TEXT = %NAVIGATION_TEXT;
1105
1106    %BUTTONS_GOTO =
1107    (
1108     'Top',         gdt('Cover (top) of document'),
1109     'Contents',    gdt('Table of contents'),
1110     'Overview',    gdt('Short table of contents'),
1111     'Index',       gdt('Index'),
1112     'This',        gdt('Current section'),
1113     'Back',        gdt('Previous section in reading order'),
1114     'FastBack',    gdt('Beginning of this chapter or previous chapter'),
1115     'Prev',        gdt('Previous section on same level'),
1116     'Up',          gdt('Up section'),
1117     'Next',        gdt('Next section on same level'),
1118     'NodeUp',      gdt('Up node'),
1119     'NodeNext',    gdt('Next node'),
1120     'NodePrev',    gdt('Previous node'),
1121     'Following',   gdt('Node following in node reading order'),
1122     'Forward',     gdt('Next section in reading order'),
1123     'FastForward', gdt('Next chapter'),
1124     'About' ,      gdt('About (help)'),
1125     'First',       gdt('First section in reading order'),
1126     'Last',        gdt('Last section in reading order'),
1127     'NextFile',    gdt('Forward section in next file'),
1128     'PrevFile',    gdt('Back section in previous file'),
1129    );
1130
1131    %BUTTONS_NAME =
1132    (
1133     'Top',         gdt('Top'),
1134     'Contents',    gdt('Contents'),
1135     'Overview',    gdt('Overview'),
1136     'Index',       gdt('Index'),
1137     ' ',           ' ',
1138     'This',        gdt('This'),
1139     'Back',        gdt('Back'),
1140     'FastBack',    gdt('FastBack'),
1141     'Prev',        gdt('Prev'),
1142     'Up',          gdt('Up'),
1143     'Next',        gdt('Next'),
1144     'NodeUp',      gdt('NodeUp'),
1145     'NodeNext',    gdt('NodeNext'),
1146     'NodePrev',    gdt('NodePrev'),
1147     'Following',   gdt('Following'),
1148     'Forward',     gdt('Forward'),
1149     'FastForward', gdt('FastForward'),
1150     'About',       gdt('About'),
1151     'First',       gdt('First'),
1152     'Last',        gdt('Last'),
1153     'NextFile',    gdt('NextFile'),
1154     'PrevFile',    gdt('PrevFile'),
1155    );
1156
1157}
1158
1159sub t2h_default_set_iso_symbols($)
1160{
1161    my $value = shift;
1162    $USE_ISO = $value;
1163    if ($value)
1164    {
1165       foreach my $association ([\%things_map, \%things_map_xml],
1166                         [\%pre_map, \%pre_map_xml],
1167                        [\%simple_format_simple_map_texi, \%pre_map_xml])
1168       {
1169          foreach my $thing (keys(%{$association->[0]}))
1170          {
1171              if (defined($association->[0]->{$thing}) and $association->[0]->{$thing} !~ /^\&\w+\;$/ and defined($association->[1]->{$thing}) and $association->[1]->{$thing} =~ /^\&\w+\;$/)
1172              {
1173                  $association->[0]->{$thing} = $association->[1]->{$thing};
1174              }
1175          }
1176       }
1177       t2h_add_text_substitutions(["'", '&rsquo;'], 1, 0, 0, 1);
1178       t2h_add_text_substitutions(['`', '&lsquo;'], 1, 0, 0, 1);
1179       $OPEN_QUOTE_SYMBOL = '&lsquo;';
1180       $CLOSE_QUOTE_SYMBOL = '&rsquo;';
1181    }
1182    else
1183    {
1184       foreach my $association ([\%things_map, \%default_things_map],
1185                         [\%pre_map, \%default_things_map],
1186                        [\%simple_format_simple_map_texi, \%default_things_map])
1187       {
1188          foreach my $thing (keys(%{$association->[0]}))
1189          {
1190              if (defined($association->[0]->{$thing}) and $association->[0]->{$thing} =~ /^\&\w+\;$/ and defined($association->[1]->{$thing}) and $association->[1]->{$thing} !~ /^\&\w+\;$/)
1191              {
1192                  $association->[0]->{$thing} = &$protect_text($association->[1]->{$thing});
1193              }
1194          }
1195       }
1196       t2h_remove_text_substitutions("'", 1, 0, 0, 1);
1197       t2h_remove_text_substitutions('`', 1, 0, 0, 1);
1198       $OPEN_QUOTE_SYMBOL = '`';
1199       $CLOSE_QUOTE_SYMBOL = "'";
1200    }
1201}
1202
1203# is used in main program for dumping texi too.
1204sub t2h_default_set_out_encoding()
1205{
1206    # these variables are used for the corresponding
1207    # $Texi2HTML::THISDOC{'*_ENCODING'} to keep code shorter
1208    my ($out_encoding, $encoding_name, $document_encoding);
1209
1210    $document_encoding = get_conf('DOCUMENT_ENCODING');
1211
1212    if (defined($OUT_ENCODING))
1213    {
1214        $out_encoding = $OUT_ENCODING;
1215    }
1216
1217    if (defined($ENCODING_NAME))
1218    {
1219        $encoding_name = $ENCODING_NAME;
1220    }
1221
1222    if (!defined($out_encoding) and (defined($encoding_name)))
1223    {
1224        my $possible_out_encoding = main::encoding_alias ($encoding_name, undef, 'determining encoding from default encoding');
1225        $out_encoding = $possible_out_encoding if (defined($possible_out_encoding));
1226    }
1227    if (!defined($out_encoding) and (defined(get_conf('IN_ENCODING'))))
1228    {
1229        $out_encoding = get_conf('IN_ENCODING');
1230    }
1231    if (!defined($out_encoding) and (defined($document_encoding)))
1232    {
1233        my $possible_out_encoding = main::encoding_alias ($document_encoding, undef, 'determining encoding from documentencoding');
1234        $out_encoding = $possible_out_encoding if (defined($possible_out_encoding));
1235    }
1236
1237    if (!defined($encoding_name))
1238    {
1239         if (defined($out_encoding) and defined($perl_charset_to_html{$out_encoding}))
1240         {
1241             $encoding_name = $perl_charset_to_html{$out_encoding};
1242         }
1243         elsif (defined(get_conf('IN_ENCODING')) and defined($perl_charset_to_html{get_conf('IN_ENCODING')}))
1244         {
1245             $encoding_name = $perl_charset_to_html{get_conf('IN_ENCODING')};
1246         }
1247         elsif (defined($document_encoding) and defined($perl_charset_to_html{$document_encoding}))
1248         {
1249             $encoding_name = $perl_charset_to_html{$document_encoding};
1250         }
1251         elsif (defined($out_encoding))
1252         {
1253             $encoding_name = $out_encoding;
1254         }
1255         elsif (defined(get_conf('IN_ENCODING')))
1256         {
1257             $encoding_name = get_conf('IN_ENCODING');
1258         }
1259         elsif (defined($document_encoding))
1260         {
1261             $encoding_name = $document_encoding;
1262         }
1263         elsif (defined($perl_charset_to_html{$DEFAULT_ENCODING}))
1264         {
1265             $encoding_name = $perl_charset_to_html{$DEFAULT_ENCODING};
1266         }
1267         else
1268         {
1269             $encoding_name = 'us-ascii';
1270         }
1271    }
1272
1273    $Texi2HTML::THISDOC{'OUT_ENCODING'} = $out_encoding;
1274    $Texi2HTML::THISDOC{'ENCODING_NAME'} = $encoding_name;
1275
1276    $out_encoding = 'UNDEF' if (!defined($out_encoding));
1277    my $in_encoding = get_conf('IN_ENCODING');
1278    $in_encoding = 'UNDEF' if (!defined($in_encoding));
1279    $document_encoding = 'UNDEF' if (!defined($document_encoding));
1280    print STDERR "# Encodings: doc $document_encoding, in $in_encoding out $out_encoding, name $encoding_name\n" if ($VERBOSE);
1281}
1282
1283sub t2h_default_init_out()
1284{
1285    &$translate_names;
1286    # set external cross ref splitting like splitting.
1287    if (!defined($EXTERNAL_CROSSREF_SPLIT))
1288    {
1289        if (get_conf('SPLIT'))
1290        {
1291            $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 1;
1292        }
1293        else
1294        {
1295            $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 0;
1296        }
1297    }
1298    else
1299    {
1300        $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = $EXTERNAL_CROSSREF_SPLIT;
1301    }
1302
1303
1304}
1305
1306my %t2h_default_formats_load_table = (
1307  'html' => \&html_default_load,
1308  'info' => \&info_default_load,
1309  'docbook' => \&docbook_default_load,
1310  'xml' => \&xml_default_load,
1311  'plaintext' => \&plaintext_default_load,
1312  'raw-text' => \&t2h_default_raw_text_load,
1313);
1314
1315sub t2h_default_load_format($;$)
1316{
1317  my $format = shift;
1318  my $from_command_line = shift;
1319  if (defined($t2h_default_formats_load_table{$format}))
1320  {
1321     $OUTPUT_FORMAT = $format;
1322     &{$t2h_default_formats_load_table{$format}}($from_command_line);
1323     $Texi2HTML::THISDOC{'format_from_command_line'} = $format if ($from_command_line);
1324     return 1;
1325  }
1326  else
1327  {
1328     return 0;
1329  }
1330}
1331
1332sub t2h_encoding_is_entity($)
1333{
1334  my $text = shift;
1335  return 0 if (!$ENABLE_ENCODING_USE_ENTITY);
1336  return 1 if ($text =~ /^&/ and $text =~ /;$/);
1337}
1338
1339# this is for info.init
1340use vars qw(%t2h_enable_encoding_default_accent);
1341my @t2h_enable_encoding_accents_stack;
1342my %t2h_enable_encoding_default_commands;
1343
1344sub t2h_enable_encoding_load()
1345{
1346   t2h_default_push_handler(\&t2h_enable_encoding_init, \@command_handler_names);
1347   t2h_default_push_handler(\&t2h_enable_encoding_finish, \@command_handler_finish);
1348   #push @command_handler_process, \&t2h_enable_encoding_init;
1349   #push @command_handler_finish, \&t2h_enable_encoding_finish;
1350   foreach my $key (keys(%unicode_accents), 'dotless')
1351   {
1352     $t2h_enable_encoding_default_accent{'normal'}->{$key} = $style_map{$key}->{'function'};
1353     $t2h_enable_encoding_default_accent{'texi'}->{$key} = $style_map_texi{$key}->{'function'};
1354     $t2h_enable_encoding_default_accent{'pre'}->{$key} = $style_map_pre{$key}->{'function'};
1355     $style_map{$key}->{'function'} = \&t2h_enable_encoding_normal_accent;
1356     $style_map_texi{$key}->{'function'} = \&t2h_enable_encoding_texi_accent;
1357     $style_map_pre{$key}->{'function'} = \&t2h_enable_encoding_pre_accent;
1358   }
1359   foreach my $key (%things_map)
1360   {
1361     if (exists($unicode_map{$key}) and ($unicode_map{$key} ne ''))
1362     {
1363       $t2h_enable_encoding_default_commands{'normal'}->{$key} = $things_map{$key};
1364       $t2h_enable_encoding_default_commands{'texi'}->{$key} = $texi_map{$key};
1365       $t2h_enable_encoding_default_commands{'sorting'}->{$key} = $sorting_things_map{$key};
1366       $t2h_enable_encoding_default_commands{'pre'}->{$key} = $pre_map{$key};
1367     }
1368   }
1369}
1370
1371sub t2h_enable_encoding_finish()
1372{
1373   foreach my $key (%things_map)
1374   {
1375     if (exists($unicode_map{$key}) and ($unicode_map{$key} ne ''))
1376     {
1377       $things_map{$key} = $t2h_enable_encoding_default_commands{'normal'}->{$key};
1378       $texi_map{$key} = $t2h_enable_encoding_default_commands{'texi'}->{$key};
1379       $sorting_things_map{$key} = $t2h_enable_encoding_default_commands{'sorting'}->{$key};
1380       $pre_map{$key} = $t2h_enable_encoding_default_commands{'pre'}->{$key};
1381     }
1382   }
1383}
1384
1385sub t2h_enable_encoding_init()
1386{
1387  if ($Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8')
1388  {
1389    foreach my $key (%things_map)
1390    {
1391      if (exists($unicode_map{$key}) and ($unicode_map{$key} ne ''))
1392      {
1393        $things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($things_map{$key}));
1394        $texi_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($texi_map{$key}));
1395        $sorting_things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($sorting_things_map{$key}));
1396        $pre_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($pre_map{$key}));
1397      }
1398    }
1399  }
1400  elsif (exists($makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}}))
1401  {
1402    my $enc_map = $makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}};
1403
1404    foreach my $key (%things_map)
1405    {
1406      if (exists($unicode_map{$key}) and ($unicode_map{$key} ne '') and
1407        exists($makeinfo_unicode_to_eight_bit{$enc_map}->{$unicode_map{$key}}))
1408      { # we let perl handle the conversion
1409        $things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($things_map{$key}));
1410        $texi_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($texi_map{$key}));
1411        $sorting_things_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($sorting_things_map{$key}));
1412        $pre_map{$key} = chr(hex($unicode_map{$key})) unless (t2h_encoding_is_entity($pre_map{$key}));
1413      }
1414    }
1415    @t2h_enable_encoding_accents_stack = ();
1416  }
1417}
1418
1419sub t2h_default_string_width($)
1420{
1421   my $string = shift;
1422   if ($USE_UNICODE)
1423   {
1424       my $width = 0;
1425       foreach my $character(split '', $string)
1426       {
1427          if ($character =~ /\p{Unicode::EastAsianWidth::InFullwidth}/)
1428          {
1429             $width += 2;
1430          }
1431          else
1432          {
1433             $width += 1;
1434          }
1435       }
1436       return $width;
1437   }
1438   else
1439   {
1440       return length($string);
1441   }
1442}
1443
1444sub t2h_default_finish_out()
1445{
1446}
1447
1448#######################################################################
1449#
1450# Values guessed if not set here. The value used is in
1451# $Texi2HTML::THISDOC{'VARNAME'}
1452#
1453#######################################################################
1454
1455# In file encoding. The @documentencoding allows autodetection of
1456# that variable.
1457$DOCUMENT_ENCODING = undef;
1458
1459# In file encoding, understandable by perl. Set according to DOCUMENT_ENCODING
1460$IN_ENCODING = undef;
1461
1462# Formatted document encoding name. If undef, set in init_out based on
1463# $OUT_ENCODING or $DOCUMENT_ENCODING if they are defined
1464$ENCODING_NAME = undef;
1465
1466# Out files encoding, understandable by perl. If undef, set in init_out
1467# using $ENCODING_NAME or $IN_ENCODING if they are defined
1468$OUT_ENCODING = undef;
1469
1470# Used to set $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'}.
1471# if undef set to @documentdescription. If there is no @documentdescription,
1472# set in page_head.
1473$DOCUMENT_DESCRIPTION = undef;
1474
1475# if undef $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} set 1 if SPLIT,
1476# to 0 otherwise
1477$EXTERNAL_CROSSREF_SPLIT = undef;
1478
1479$DATE = undef;
1480
1481
1482########################################################################
1483# Control of Page layout:
1484# You can make changes of the Page layout at two levels:
1485# 1.) For small changes, it is often enough to change the value of
1486#     some global string/hash/array variables
1487# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines,
1488#     give them another name, and assign them to the respective
1489#     $<fnc> variable.
1490
1491# As a general interface, the hashes Texi2HTML::HREF, Texi2HTML::NAME, Texi2HTML::NODE, Texi2HTML::NO_TEXI, Texi2HTML::SIMPLE_TEXT hold
1492# href, html-name, node-name, name after removal of texi commands of
1493# This     -- current section (resp. html page)
1494# Top      -- top element
1495# Contents -- Table of contents element
1496# Overview -- Short table of contents element
1497# Index    -- Index page element
1498# About    -- page which explain "navigation buttons" element
1499# First    -- first node element
1500# Last     -- last node element
1501#
1502# Whether or not the following hash values are set, depends on the context
1503# (all values are w.r.t. 'This' section)
1504# Next        -- next element of texinfo
1505# Prev        -- previous element of texinfo
1506# NodeUp      -- up node of texinfo
1507# Following   -- following node in node reading order, taking menu into account
1508# Forward     -- next node in reading order
1509# Back        -- previous node in reading order
1510# Up          -- parent given by sectioning commands
1511# FastForward -- if leave node, up and next, else next node
1512# FastBackward-- if leave node, up and prev, else prev node
1513#
1514# Furthermore, the following global variabels are set:
1515# $Texi2HTML::THISDOC{title}          -- title as set by @title...
1516# $Texi2HTML::THISDOC{title_no_texi}  -- title without texi (without html elements)
1517# $Texi2HTML::THISDOC{title_texi}     -- title with texinfo @-commands
1518# $Texi2HTML::THISDOC{fulltitle}      -- full title as set by @title...
1519# $Texi2HTML::THISDOC{subtitle}       -- subtitle as set by @subtitle
1520# $Texi2HTML::THISDOC{author}         -- author as set by @author
1521# $Texi2HTML::THISDOC{copying_comment}  -- text of @copying and @end copying in comment
1522#
1523# $Texi2HTML::THISDOC{program}          -- name and version of texi2html
1524# $Texi2HTML::THISDOC{program_homepage} -- homepage for texi2html
1525# $Texi2HTML::THISDOC{program_authors}  -- authors of texi2html
1526# $Texi2HTML::THISDOC{today}            -- date formatted with pretty_date
1527# $Texi2HTML::THISDOC{toc_file}         -- table of contents file
1528# $Texi2HTML::THISDOC{file_base_name}   -- base name of the texinfo manual file
1529# $Texi2HTML::THISDOC{input_file_name}  -- name of the texinfo manual file
1530# $Texi2HTML::THISDOC{destination_directory}
1531                                 #      -- directory for the resulting files
1532# $Texi2HTML::THISDOC{user}             -- user running the script
1533# $Texi2HTML::THISDOC{css_import_lines} -- ref on @import lines in css files
1534# $Texi2HTML::THISDOC{css_rule_lines}   -- ref on css rules lines
1535# other $Texi2HTML::THISDOC keys corresponds with texinfo commands, the value
1536# being the command arg, for the following commands:
1537# kbdinputstyle, paragraphindent, setchapternewpage, headings, footnotestyle,
1538# exampleindent, firstparagraphindent, everyheading, everyfooting,
1539# evenheading, evenfooting, oddheading, oddfooting
1540#
1541# and pointer to arrays of lines which need to be printed by main::print_lines
1542# $Texi2HTML::THIS_SECTION  -- lines of 'This' section
1543# $Texi2HTML::OVERVIEW      -- lines of short table of contents
1544# $Texi2HTML::TOC_LINES     -- lines of table of contents
1545# $Texi2HTML::TITLEPAGE     -- lines of title page
1546#
1547# $Texi2HTML::THIS_ELEMENT  holds the element reference.
1548
1549# most of the functions are either reset when switching format, in
1550# t2h_default_set_variables_default, or set in format, the simplest
1551# one being setup above in t2h_default_raw_text_load
1552
1553#
1554# The following generic subs control the layout:
1555#
1556# misc element formatting functions. They are rather generic,
1557# their call is controlled by other variables (separate or not
1558# footnotes, about_body, handling of table of contents...).
1559# print_Footnotes is the only to be redefined, in info
1560$print_Toc		      = \&T2H_DEFAULT_print_Toc;
1561$print_Overview	      = \&T2H_DEFAULT_print_Overview;
1562$print_About	      = \&T2H_DEFAULT_print_About;
1563$print_misc		      = \&T2H_DEFAULT_print_misc;
1564# generic enough (call print_page_head if needed)
1565$print_Top_header         = \&T2H_DEFAULT_print_Top_header;
1566
1567# the following are less generic, but in case a specific format
1568# doesn't redefine them, the raw text functions are always defined.
1569$print_page_head              = \&T2H_DEFAULT_print_page_head;
1570$contents                 = \&T2H_DEFAULT_contents;
1571$shortcontents            = \&T2H_DEFAULT_shortcontents;
1572$one_section              = \&T2H_DEFAULT_one_section;
1573$print_Top                = \&T2H_DEFAULT_print_Top;
1574$print_Top_footer             = \&T2H_DEFAULT_print_Top_footer;
1575$print_misc_header            = \&T2H_DEFAULT_print_misc_header;
1576$print_misc_footer            = \&T2H_DEFAULT_print_misc_footer;
1577$print_section_footer     = \&T2H_DEFAULT_print_section_footer;
1578$print_chapter_header     = \&T2H_DEFAULT_print_chapter_header;
1579$print_section_header     = \&T2H_DEFAULT_print_section_header;
1580$print_chapter_footer     = \&T2H_DEFAULT_print_chapter_footer;
1581$print_page_foot              = \&T2H_DEFAULT_print_page_foot;
1582$print_head_navigation    = \&T2H_DEFAULT_print_head_navigation;
1583$print_foot_navigation    = \&T2H_DEFAULT_print_foot_navigation;
1584$end_section              = \&T2H_DEFAULT_end_section;
1585# changed in info
1586$print_Footnotes              = \&T2H_DEFAULT_print_Footnotes;
1587# used if split
1588$about_body                 = \&T2H_DEFAULT_about_body;
1589$print_navigation           = \&T2H_DEFAULT_print_navigation;
1590
1591#
1592# generic formatting functions
1593#
1594
1595$button_icon_img	      = \&T2H_DEFAULT_button_icon_img;
1596# not really needed nor relevant except for html
1597$print_frame              = \&T2H_DEFAULT_print_frame;
1598$print_toc_frame          = \&T2H_DEFAULT_print_toc_frame;
1599# generic
1600$titlepage                 = \&T2H_DEFAULT_titlepage;
1601$css_lines                 = \&T2H_DEFAULT_css_lines;
1602$print_redirection_page    = \&T2H_DEFAULT_print_redirection_page;
1603$node_file_name            = \&T2H_DEFAULT_node_file_name;
1604$inline_contents           = \&T2H_DEFAULT_inline_contents;
1605$program_string            = \&T2H_DEFAULT_program_string;
1606$element_file_name         = \&t2h_default_element_file_name;
1607
1608########################################################################
1609# Layout for every sections
1610#
1611
1612sub T2H_DEFAULT_print_section($$$$)
1613{
1614    my $fh = shift;
1615    my $first_in_page = shift;
1616    my $previous_is_top = shift;
1617    my $element = shift;
1618
1619    my $nw = main::print_lines($fh);
1620}
1621
1622sub T2H_DEFAULT_one_section($$)
1623{
1624    my $fh = shift;
1625    my $element = shift;
1626    main::print_lines($fh);
1627    &$print_page_foot($fh);
1628}
1629
1630###################################################################
1631# Layout of top-page. It is possible to use @ifnothtml, @ifhtml,
1632# @html within the Top texinfo node to specify content of top-level
1633# page.
1634#
1635sub T2H_DEFAULT_print_Top_header($$)
1636{
1637    my $fh = shift;
1638    my $do_page_head = shift;
1639    &$print_page_head($fh) if ($do_page_head);
1640}
1641sub T2H_DEFAULT_print_Top_footer($$$)
1642{
1643    my $fh = shift;
1644    my $end_page = shift;
1645    my $element = shift;
1646    if ($end_page)
1647    {
1648        &$print_page_foot($fh);
1649    }
1650}
1651
1652sub T2H_DEFAULT_print_Top($$$)
1653{
1654    my $fh = shift;
1655    my $has_top_heading = shift;
1656    my $element = shift;
1657
1658    if ($Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'})
1659    {
1660        my $shortcontents = &$inline_contents($fh, 'shortcontents');
1661        print $fh "".join('',@$shortcontents) if (defined($shortcontents));
1662    }
1663    if ($Texi2HTML::THISDOC{'setcontentsaftertitlepage'})
1664    {
1665        my $contents = &$inline_contents($fh, 'contents');
1666        print $fh "".join('',@$contents) if (defined($contents));
1667    }
1668
1669    main::print_lines($fh, $Texi2HTML::THIS_SECTION);
1670}
1671
1672###################################################################
1673# Layout of Toc, Overview, and Footnotes pages
1674# By default, we use "normal" layout
1675# Texi2HTML::HREF of Next, Prev, Up, Forward, Back, etc are not defined
1676# redefine \@MISC_BUTTONS to change the navigation
1677sub T2H_DEFAULT_print_Toc
1678{
1679    return &$print_misc(@_);
1680}
1681sub T2H_DEFAULT_print_Overview
1682{
1683    return &$print_misc(@_);
1684}
1685sub T2H_DEFAULT_print_Footnotes
1686{
1687    return &$print_misc(@_);
1688}
1689sub T2H_DEFAULT_print_About
1690{
1691    return &$print_misc(@_);
1692}
1693
1694sub T2H_DEFAULT_print_misc_header($$$$)
1695{
1696    my $fh = shift;
1697    my $buttons = shift;
1698    my $new_file = shift;
1699    my $misc_page = shift;
1700    &$print_page_head($fh) if ($new_file);
1701}
1702
1703sub T2H_DEFAULT_print_misc_footer($$$)
1704{
1705    my $fh = shift;
1706    my $buttons = shift;
1707    my $new_file = shift;
1708    if ($new_file)
1709    {
1710        &$print_page_foot($fh);
1711    }
1712}
1713
1714use vars qw(
1715%t2h_default_underline_symbol
1716);
1717
1718%t2h_default_underline_symbol = (
1719  0 => '*',
1720  1 => '*',
1721  2 => '=',
1722  3 => '-',
1723  4 => '.'
1724);
1725
1726sub t2h_default_heading_text($$$)
1727{
1728    my $command = shift;
1729    my $text = shift;
1730    my $level = shift;
1731
1732    return '' if ($text !~ /\S/);
1733    my $result = $text ."\n";
1734    # as seen in encodings/nodetest_utf8_no_unicode, the length can be in
1735    # bytes (certainly) when there hasn't been a require Encode
1736    #$result .=($t2h_default_underline_symbol{$level} x length($text))."\n";
1737    $result .=($t2h_default_underline_symbol{$level} x t2h_default_string_width($text))."\n";
1738    return $result;
1739}
1740
1741sub t2h_default_heading_text_preformatted($$$)
1742{
1743    my $command = shift;
1744    my $text = shift;
1745    my $level = shift;
1746
1747    return t2h_default_heading_text($command, $text, $level);
1748}
1749
1750sub T2H_DEFAULT_print_misc($$$)
1751{
1752    my $fh = shift;
1753    my $new_file = shift;
1754    my $misc_page = shift;
1755    my $buttons = \@MISC_BUTTONS;
1756    &$print_misc_header($fh, $buttons, $new_file, $misc_page);
1757    print $fh "".&$heading_text('misc heading', $Texi2HTML::NAME{This}, 1) . "\n";
1758    main::print_lines($fh);
1759    &$print_misc_footer($fh, $buttons, $new_file);
1760}
1761##################################################################
1762# section_footer is only called if SPLIT eq 'section'
1763# section_footer: after print_section of last section, before print_page_foot
1764#
1765
1766sub T2H_DEFAULT_print_section_footer
1767{
1768    my $fh = shift;
1769    my $element = shift;
1770}
1771
1772###################################################################
1773# chapter_header and chapter_footer are only called if
1774# SPLIT eq 'chapter'
1775# chapter_header: after print_page_head, before print_section
1776# chapter_footer: after print_section of last section, before print_page_foot
1777
1778sub T2H_DEFAULT_print_chapter_header
1779{
1780    my $fh = shift;
1781    my $element = shift;
1782}
1783
1784sub T2H_DEFAULT_print_chapter_footer
1785{
1786    my $fh = shift;
1787    my $element = shift;
1788}
1789
1790sub T2H_DEFAULT_print_section_header
1791{
1792    my $fh = shift;
1793}
1794
1795
1796###################################################################
1797# Layout of standard header and footer
1798#
1799
1800sub T2H_DEFAULT_print_page_head($)
1801{
1802    my $fh = shift;
1803}
1804
1805sub T2H_DEFAULT_program_string()
1806{
1807    my $date = $Texi2HTML::THISDOC{'today'};
1808    $date = '' if (!defined($date));
1809    if ($date ne '')
1810    {
1811        return gdt('This document was generated on @i{{date}} using @uref{{program_homepage}, @i{{program}}}.', {
1812           'date' => $date, 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' => $Texi2HTML::THISDOC{'program'} },{'duplicate'=>1});
1813    }
1814    return gdt('This document was generated using @uref{{program_homepage}, @emph{{program}}}.', {
1815       'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program'
1816=> $Texi2HTML::THISDOC{'program'} },{'duplicate'=>1});
1817}
1818
1819sub T2H_DEFAULT_end_section($$$)
1820{
1821    my $fh = shift;
1822    my $misc_or_top_and_section_separation = shift;
1823    my $element = shift;
1824}
1825
1826sub T2H_DEFAULT_print_page_foot($)
1827{
1828    my $fh = shift;
1829}
1830
1831###################################################################
1832# Layout of navigation panel
1833
1834sub T2H_DEFAULT_print_head_navigation($$$$$)
1835{
1836    my $fh = shift;
1837    my $buttons = shift;
1838    my $first_in_page = shift;
1839    my $previous_is_top = shift;
1840    my $element = shift;
1841
1842    return '';
1843}
1844
1845sub T2H_DEFAULT_print_foot_navigation
1846{
1847    my $fh = shift;
1848    my $buttons = shift;
1849    my $rule = shift;
1850    my $print_navigation_panel = shift;
1851    my $element = shift;
1852
1853    $rule = '' if (!defined($rule));
1854    print $fh "$rule\n" if ($rule ne '');
1855}
1856
1857######################################################################
1858# navigation panel
1859#
1860# how to create IMG tag
1861# this is only used in html, and only if ICONS is set and the button
1862# is active.
1863sub T2H_DEFAULT_button_icon_img
1864{
1865    my $button = shift;
1866    my $icon = shift;
1867    my $name = shift;
1868    return '' if (!defined($icon));
1869    $button = "" if (!defined ($button));
1870    $name = '' if (!defined($name));
1871    my $alt = '';
1872    if ($name ne '')
1873    {
1874        if ($button ne '')
1875        {
1876            $alt = "$button: $name";
1877        }
1878        else
1879        {
1880            $alt = $name;
1881        }
1882    }
1883    else
1884    {
1885        $alt = $button;
1886    }
1887    return "$icon $alt";
1888}
1889
1890sub T2H_DEFAULT_print_navigation
1891{
1892    my $buttons = shift;
1893    my $vertical = shift;
1894
1895    return '';
1896}
1897
1898######################################################################
1899# Frames: this is from "Richard Y. Kim" <ryk@coho.net>
1900# Should be improved to be more conforming to other _print* functions
1901# toc_file and main_file passed as args are relative to the texinfo manual
1902# location, and therefore are not used.
1903
1904# no-ops in the default case, doesn't really make sense if output is
1905# not html
1906
1907sub T2H_DEFAULT_print_frame
1908{
1909    my $fh = shift;
1910    my $toc_file = shift;
1911    my $main_file = shift;
1912    $main_file = $Texi2HTML::THISDOC{'filename'}->{'top'};
1913    $toc_file = $Texi2HTML::THISDOC{'filename'}->{'toc_frame'};
1914}
1915
1916sub T2H_DEFAULT_print_toc_frame
1917{
1918    my $fh = shift;
1919    my $stoc_lines = shift;
1920}
1921
1922# This subroutine is intended to fill @Texi2HTML::TOC_LINES and
1923# @Texi2HTML::OVERVIEW with the table of contents and short table of
1924# contents.
1925#
1926# arguments:
1927# ref on an array containing all the elements
1928
1929# each element is a reference on a hash. The following keys might be of
1930# use:
1931# 'top': true if this is the top element
1932# 'toc_level': level of the element in the table of content. Highest level
1933#              is 1 for the @top element and for chapters, appendix and so on,
1934#              2 for section, unnumberedsec and so on...
1935# 'tocid': label used for reference linking to the element in table of
1936#          contents
1937# 'file': the file containing the element, usefull to do href to that file
1938#         in case the document is split.
1939# 'text': text of the element, with section number
1940# 'text_nonumber': text of the element, without section number
1941
1942# Relevant configuration variables are:
1943# $NO_BULLET_LIST_ATTRIBUTE: usefull in case a list is used
1944# $FRAMES: @Texi2HTML::OVERVIEW is used in one of the frames.
1945# $BEFORE_OVERVIEW
1946# $AFTER_OVERVIEW
1947# $BEFORE_TOC_LINES
1948# $AFTER_TOC_LINES
1949# get_conf('contents')
1950# get_conf('shortcontents')
1951
1952sub T2H_DEFAULT_contents($$)
1953{
1954   my $elements = shift;
1955   my $toc_file = shift;
1956   my @result;
1957   return unless (get_conf('contents'));
1958   foreach my $element (@$elements)
1959   {
1960      my $level = $element->{'toc_level'};
1961      $level = 1 if ($level < 1);
1962      my $text =  $element->{'text'};
1963      my $result =  (' ' x ($level - 1)) . $text ."\n";
1964      push @result, $result;
1965   }
1966   if (@result)
1967   {
1968      unshift @result, $BEFORE_TOC_LINES;
1969      push @result, $AFTER_TOC_LINES;
1970   }
1971   return \@result;
1972}
1973
1974sub T2H_DEFAULT_shortcontents($$)
1975{
1976   my $elements = shift;
1977   my $stoc_file = shift;
1978   my @result;
1979   return unless (get_conf('shortcontents'));
1980   foreach my $element (@$elements)
1981   {
1982      my $level = $element->{'toc_level'};
1983      next if ($level > 1);
1984      $level = 1 if ($level < 1);
1985      my $text = $element->{'text'};
1986      push @result, $text ."\n";
1987   }
1988   if (@result)
1989   {
1990      unshift @result, $BEFORE_OVERVIEW;
1991      push @result, $AFTER_OVERVIEW;
1992   }
1993   return \@result;
1994}
1995
1996sub T2H_DEFAULT_print_title()
1997{
1998    my $element = shift;
1999    return undef unless ($SHOW_TITLE);
2000    if ($USE_TITLEPAGE_FOR_TITLE)
2001    {
2002        my ($titlepage_text, $titlepage_no_texi, $titlepage_simple_format) = main::do_special_region_lines('titlepage',$Texi2HTML::THISDOC{'state'});
2003
2004        &$titlepage([],$titlepage_text, $titlepage_no_texi, $titlepage_simple_format);
2005        return $Texi2HTML::TITLEPAGE;
2006    }
2007    else
2008    {
2009       my $title = '';
2010       $title = $Texi2HTML::THISDOC{'simpletitle'} if (defined($Texi2HTML::THISDOC{'simpletitle'}) and $Texi2HTML::THISDOC{'simpletitle'} !~ /^\s*$/);
2011       if ($title ne '')
2012       {
2013           return &$heading_text('@settitle', $title, 0) . "\n";
2014       }
2015    }
2016}
2017
2018sub T2H_DEFAULT_toc_body($)
2019{
2020    my $elements_list = shift;
2021    my $toc_lines = &$contents($elements_list, $Texi2HTML::THISDOC{'toc_file'});
2022    @{$Texi2HTML::TOC_LINES} = @$toc_lines if ($toc_lines);
2023    my $stoc_lines = &$shortcontents($elements_list, $Texi2HTML::THISDOC{'stoc_file'});
2024    @{$Texi2HTML::OVERVIEW} = @$stoc_lines if ($stoc_lines);
2025}
2026
2027# element and elements_list may not be undef when called from the
2028# main program, but may be if called from other customization function,
2029# for example, here, print_Top.
2030sub T2H_DEFAULT_inline_contents($$$$)
2031{
2032    my $fh = shift;
2033    my $command = shift;
2034    my $element = shift;
2035    my $elements_list = shift;
2036    my $name;
2037    my $lines;
2038
2039    my $toc_file;
2040    $toc_file = $element->{'file'} if (defined($element));
2041
2042    my $result = undef;
2043
2044    if ($command eq 'contents')
2045    {
2046        $name = $Texi2HTML::NAME{'Contents'};
2047        $toc_file = $Texi2HTML::THISDOC{'toc_file'} if (!defined($toc_file));
2048        if (defined($elements_list))
2049        {
2050            $lines = &$contents($elements_list, $toc_file);
2051        }
2052        else
2053        {
2054            $lines = $Texi2HTML::TOC_LINES;
2055        }
2056    }
2057    else
2058    {
2059        $name = $Texi2HTML::NAME{'Overview'};
2060        $toc_file = $Texi2HTML::THISDOC{'stoc_file'} if (!defined($toc_file));
2061        if (defined($elements_list))
2062        {
2063            $lines = &$shortcontents($elements_list, $toc_file);
2064        }
2065        else
2066        {
2067            $lines = $Texi2HTML::OVERVIEW;
2068        }
2069    }
2070    if ($lines and @{$lines})
2071    {
2072         $result = [ &$heading_text("\@$command", $name, 1), "\n" ];
2073         my $contents_anchor = &$anchor($element->{'id'});
2074         if (defined($contents_anchor) and $contents_anchor =~ /\S/)
2075         {
2076             unshift @$result, $contents_anchor."\n";
2077         }
2078         push @$result, (@$lines, "\n");
2079    }
2080    return $result;
2081}
2082
2083
2084sub T2H_DEFAULT_css_lines ($$)
2085{
2086    my $import_lines = shift;
2087    my $rule_lines = shift;
2088#    return if (defined($CSS_LINES) or (!@$rule_lines and !@$import_lines and (! keys(%css_map))));
2089    if (defined($CSS_LINES))
2090    { # if predefined, use CSS_LINES.
2091       $Texi2HTML::THISDOC{'CSS_LINES'} = $CSS_LINES;
2092       return;
2093    }
2094    return if ((!@$rule_lines and !@$import_lines and !keys(%css_map) and !@CSS_REFS) or $NO_CSS);
2095    my $css_text = "<style type=\"text/css\">\n<!--\n";
2096    $css_text .= join('',@$import_lines) . "\n" if (@$import_lines);
2097    foreach my $css_rule (sort(keys(%css_map)))
2098    {
2099        next unless ($css_map{$css_rule});
2100        $css_text .= "$css_rule {$css_map{$css_rule}}\n";
2101    }
2102    $css_text .= join('',@$rule_lines) . "\n" if (@$rule_lines);
2103    $css_text .= "-->\n</style>\n";
2104    foreach my $ref (@CSS_REFS)
2105    {
2106        $css_text .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$ref\">\n";
2107    }
2108    $Texi2HTML::THISDOC{'CSS_LINES'} = $css_text;
2109}
2110
2111######################################################################
2112# About page
2113#
2114
2115# PRE_ABOUT can be a function reference or a scalar.
2116# Note that if it is a scalar, T2H_InitGlobals has not been called,
2117# and all global variables like $ADDRESS are not available.
2118$PRE_ABOUT = sub
2119{
2120    return '  ' . &$program_string() .  "\n";
2121};
2122
2123# If customizing $AFTER_ABOUT, be sure to put the content inside <p></p>.
2124$AFTER_ABOUT = '';
2125
2126%BUTTONS_EXAMPLE =
2127    (
2128     'Top',         ' ',
2129     'Contents',    ' ',
2130     'Overview',    ' ',
2131     'Index',       ' ',
2132     'This',        '1.2.3',
2133     'Back',        '1.2.2',
2134     'FastBack',    '1',
2135     'Prev',        '1.2.2',
2136     'Up',          '1.2',
2137     'Next',        '1.2.4',
2138     'NodeUp',      '1.2',
2139     'NodeNext',    '1.2.4',
2140     'NodePrev',    '1.2.2',
2141     'Following',   '1.2.4',
2142     'Forward',     '1.2.4',
2143     'FastForward', '2',
2144     'About',       ' ',
2145     'First',       '1.',
2146     'Last',        '1.2.4',
2147     'NextFile',    ' ',
2148     'PrevFile',    ' ',
2149    );
2150
2151sub T2H_DEFAULT_about_body
2152{
2153    my $about = "";
2154    if (ref($PRE_ABOUT) eq 'CODE')
2155    {
2156        $about .= &$PRE_ABOUT();
2157    }
2158    else
2159    {
2160        $about .= $PRE_ABOUT;
2161    }
2162    return $about;
2163}
2164
2165# return value is currently ignored
2166sub T2H_DEFAULT_titlepage($$$$)
2167{
2168    my $titlepage_lines = shift;
2169    my $titlepage_text = shift;
2170    my $titlepage_no_texi = shift;
2171    my $titlepage_simple_format = shift;
2172
2173    $Texi2HTML::TITLEPAGE = $titlepage_text;
2174    if ($titlepage_text eq '')
2175    {
2176       my $title = '';
2177       $title = $Texi2HTML::THISDOC{'simpletitle'} if (defined($Texi2HTML::THISDOC{'simpletitle'}) and $Texi2HTML::THISDOC{'simpletitle'} !~ /^\s*$/);
2178       if ($title ne '')
2179       {
2180           $Texi2HTML::TITLEPAGE = &$heading_text('@settitle', $title, 0);
2181           $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n";
2182       }
2183    }
2184    else
2185    {
2186        $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n";
2187    }
2188
2189    if ($Texi2HTML::THISDOC{'setcontentsaftertitlepage'} and (defined($Texi2HTML::THISDOC{'inline_contents'}->{'contents'})) and @{$Texi2HTML::THISDOC{'inline_contents'}->{'contents'}})
2190    {
2191        foreach my $line(@{$Texi2HTML::THISDOC{'inline_contents'}->{'contents'}})
2192        {
2193            $Texi2HTML::TITLEPAGE .= $line;
2194        }
2195        $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n";
2196    }
2197    if ($Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'} and (defined($Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'})) and @{$Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'}})
2198    {
2199        foreach my $line(@{$Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'}})
2200        {
2201            $Texi2HTML::TITLEPAGE .= $line;
2202        }
2203        $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n";
2204    }
2205    return $Texi2HTML::TITLEPAGE;
2206}
2207
2208
2209sub T2H_DEFAULT_print_redirection_page()
2210{
2211    #return "Redirection files are not of use for the current format.\n";
2212    return undef;
2213}
2214
2215sub T2H_DEFAULT_node_file_name($$)
2216{
2217    my $node = shift;
2218    my $type = shift;
2219    return undef if ($node->{'external_node'}
2220       or ($type eq 'top' and !$NEW_CROSSREF_STYLE));
2221    my $node_file_base;
2222    if ($type eq 'top' and defined($TOP_NODE_FILE))
2223    {
2224        $node_file_base = $TOP_NODE_FILE;
2225    }
2226    elsif ($NEW_CROSSREF_STYLE)
2227    {
2228        if ($TRANSLITERATE_FILE_NAMES)
2229        {
2230            $node_file_base = $node->{'cross_manual_file'};
2231        }
2232        else
2233        {
2234            $node_file_base = $node->{'cross_manual_target'};
2235        }
2236    }
2237    else
2238    {
2239         $node_file_base = main::remove_texi($node->{'texi'});
2240         $node_file_base =~ s/[^\w\.\-]/-/g;
2241    }
2242    if (defined($NODE_FILE_EXTENSION) and $NODE_FILE_EXTENSION ne '')
2243    {
2244        return ($node_file_base . ".$NODE_FILE_EXTENSION");
2245    }
2246    return $node_file_base;
2247}
2248
2249########################################################################
2250# Control of formatting:
2251# 1.) For some changes, it is often enough to change the value of
2252#     some global map. It might necessitate building a little
2253#     function along with the change in hash, if the change is the use
2254#     of another function (in style_map).
2255# 2.) For other changes, reimplement one of the t2h_default_<fnc>* routines,
2256#     give them another name, and assign them to the respective
2257#     $<fnc> variable (below).
2258
2259%deprecated_commands = (
2260  'ctrl' => '',
2261  'allow-recursion' => N__('recursion is always allowed'),
2262  'quote-arg' => N__('arguments are quoted by default'),
2263);
2264
2265#
2266# This hash should have keys corresponding with the nonletter command accent
2267# whose following character is considered to be the argument
2268# This hash associates an accent macro to the ISO name for the accent if any.
2269# The customary use of this map is to find the ISO name appearing in html
2270# entity (like &eacute;) associated with a texinfo accent macro.
2271#
2272# The keys of the hash are
2273# ": umlaut
2274# ~: tilda accent
2275# ^: circumflex accent
2276# `: grave accent
2277# ': acute accent
2278# =: macron accent
2279%accent_map = (
2280          '"',  'uml',
2281          '~',  'tilde',
2282          '^',  'circ',
2283          '`',  'grave',
2284          "'", 'acute',
2285          ",", 'cedil',
2286          '=', '',
2287          'ringaccent', 'ring',
2288          'H', '',
2289          'dotaccent', '',
2290          'u', '',
2291          'ubaraccent', '',
2292          'udotaccent', '',
2293          'v', '',
2294          'ogonek', 'ogon',
2295         );
2296
2297#
2298# ascii representation of texinfo "simple things" @-commands
2299%default_simple_map = (
2300           '*', "\n",
2301           ' ', ' ',
2302           "\t", ' ',
2303           "\n", ' ',
2304           '-', '',  # hyphenation hint
2305           '|', '',  # used in formatting commands @evenfooting and friends
2306           '/', '',
2307           ':', '',
2308           '!', '!',
2309           '?', '?',
2310           '.', '.',
2311           '@', '@',
2312           '}', '}',
2313           '{', '{',
2314);
2315
2316# texinfo "simple things" @-commands
2317%simple_map = %default_simple_map;
2318
2319# this map is used in preformatted text
2320%simple_map_pre = %simple_map;
2321
2322# This map is used when texi elements are removed and replaced
2323# by simple text
2324%simple_map_texi = %default_simple_map;
2325
2326# maps for the math specific commands
2327%simple_map_math = (
2328           '\\', '\\'
2329           );
2330
2331#%simple_map_pre_math = %simple_map_math;
2332#%simple_map_texi_math = %simple_map_math;
2333
2334$punctuation_characters = '.?!';
2335$after_punctuation_characters = '"\')]';
2336
2337
2338%default_things_map = (
2339               'TeX'          => 'TeX',
2340               'LaTeX'          => 'LaTeX',
2341               'bullet'       => '*',
2342               'copyright' => '(C)',
2343               'registeredsymbol'   => '(R)',
2344               'dots'         => '...',
2345               'enddots'      => '...',
2346               'equiv'        => '==',
2347# FIXME i18n
2348               'error'        => 'error-->',
2349               'expansion'    => '==>',
2350               'arrow'        => '->',
2351               'minus'        => '-',
2352               'point'        => '-!-',
2353               'print'        => '-|',
2354               'result'       => '=>',
2355               'today'        => '',
2356               'aa'           => 'aa',
2357               'AA'           => 'AA',
2358               'ae'           => 'ae',
2359               'oe'           => 'oe',
2360               'AE'           => 'AE',
2361               'OE'           => 'OE',
2362               'o'            => '/o',
2363               'O'            => '/O',
2364               'ss'           => 'ss',
2365               'l'            => '/l',
2366               'L'            => '/L',
2367               'DH'           => 'D',
2368               'dh'           => 'd',
2369               'TH'           => 'TH', # http://www.evertype.com/standards/wynnyogh/thorn.html
2370
2371               'th'           => 'th',
2372               'exclamdown'   => '!',
2373               'questiondown' => '?',
2374               'pounds'       => '#',
2375               'ordf'         => 'a',
2376               'ordm'         => 'o',
2377               'comma'        => ',',
2378               'euro'         => 'Euro',
2379               'geq'          => '>=',
2380               'leq'          => '<=',
2381               'tie'          => ' ',
2382               'textdegree'          => 'o',
2383               'quotedblleft'          => '``',
2384               'quotedblright'          => "''",
2385               'quoteleft'          => '`',
2386               'quoteright'          => "'",
2387               'quotedblbase'          => ',,',
2388               'quotesinglbase'          => ',',
2389               'guillemetleft'          => '<<',
2390               'guillemetright'          => '>>',
2391               'guillemotleft'          => '<<',
2392               'guillemotright'          => '>>',
2393               'guilsinglleft'          => '<',
2394               'guilsinglright'          => '>',
2395);
2396
2397%things_map = %default_things_map;
2398
2399# This map is used in preformatted environments
2400%pre_map = %things_map;
2401
2402# used in math. If not found, pre_map is used.
2403%math_map = ();
2404
2405# text replacing macros when texi commands are removed and plain text is
2406# produced.
2407%texi_map = %default_things_map;
2408
2409# used for index sorting.
2410%sorting_things_map = %default_things_map;
2411foreach my $accent_letter ('o','O','l','L')
2412{
2413  $sorting_things_map{$accent_letter} = $accent_letter;
2414}
2415$sorting_things_map{'copyright'} = 'C';
2416$sorting_things_map{'registeredsymbol'} = 'R';
2417$sorting_things_map{'today'} = 't';
2418
2419%default_texi_map = %texi_map;
2420
2421#
2422# texinfo "things" (@foo{}) to XML ones
2423#
2424%things_map_xml = (
2425               'TeX'          => 'TeX',
2426               'LaTeX'          => 'LaTeX',
2427# pertusus: unknown by makeinfo, not in texinfo manual (@* is the right thing)
2428#               'br', '<br>',     # paragraph break
2429               'bullet'       => '&bull;',
2430#               #'copyright' => '(C)',
2431               'copyright'    => '&copy;',
2432               'registeredsymbol'   => '&reg;',
2433               'dots'         => '&hellip;',
2434               'enddots'      => '...',
2435               'equiv'        => '&equiv;',
2436# FIXME i18n
2437               'error'        => 'error--&gt;',
2438               'expansion'    => '&rarr;',
2439               'arrow'        => '&rarr;',
2440               'minus'        => '-',
2441               'point'        => '&lowast;',
2442               'print'        => '-|',
2443               'result'       => '&rArr;',
2444               # set in code using the language
2445               # 'today', &pretty_date,
2446               'today'        => '',
2447               'aa'           => '&aring;',
2448               'AA'           => '&Aring;',
2449               'ae'           => '&aelig;',
2450               'oe'           => '&oelig;', #pertusus: also &#156;. &oelig; not in html 3.2
2451               'AE'           => '&AElig;',
2452               'OE'           => '&OElig;', #pertusus: also &#140;. &OElig; not in html 3.2
2453               'o'            =>  '&oslash;',
2454               'O'            =>  '&Oslash;',
2455               'ss'           => '&szlig;',
2456               'DH'           => '&ETH;',
2457               'dh'           => '&eth;',
2458               'TH'           => '&THORN;',
2459               'th'           => '&thorn;',
2460               'l'            => '&#322;',
2461               'L'            => '&#321;',
2462               'exclamdown'   => '&iexcl;',
2463               'questiondown' => '&iquest;',
2464               'pounds'       => '&pound;',
2465               'ordf'         => '&ordf;',
2466               'ordm'         => '&ordm;',
2467               'comma'        => ',',
2468               'euro'         => '&euro;',
2469               'geq'          => '&ge;',
2470               'leq'          => '&le;',
2471               'tie'          => '&nbsp;',
2472               'textdegree'          => '&deg;',
2473               'quotedblleft'          => '&ldquo;',
2474               'quotedblright'          => '&rdquo;',
2475               'quoteleft'          => '&lsquo;',
2476               'quoteright'          => '&rsquo;',
2477               'quotedblbase'          => '&bdquo;',
2478               'quotesinglbase'          => '&sbquo;',
2479               'guillemetleft'          => '&laquo;',
2480               'guillemetright'          => '&raquo;',
2481               'guillemotleft'          => '&laquo;',
2482               'guillemotright'          => '&raquo;',
2483               'guilsinglleft'          => '&lsaquo;',
2484               'guilsinglright'          => '&rsaquo;',
2485             );
2486
2487# This map is used in preformatted environments
2488%pre_map_xml = %things_map_xml;
2489
2490# taken from
2491#Latin extended additionnal
2492#http://www.alanwood.net/unicode/latin_extended_additional.html
2493#C1 Controls and Latin-1 Supplement
2494#http://www.alanwood.net/unicode/latin_1_supplement.html
2495#Latin Extended-A
2496#http://www.alanwood.net/unicode/latin_extended_a.html
2497#Latin Extended-B
2498#http://www.alanwood.net/unicode/latin_extended_b.html
2499#dotless i: 0131
2500
2501#http://www.alanwood.net/unicode/arrows.html 21**
2502#http://www.alanwood.net/unicode/general_punctuation.html 20**
2503#http://www.alanwood.net/unicode/mathematical_operators.html 22**
2504
2505%unicode_map = (
2506               'bullet'       => '2022',
2507               'copyright'    => '00A9',
2508               'registeredsymbol'   => '00AE',
2509               'dots'         => '2026',
2510               'enddots'      => '',
2511               'equiv'        => '2261',
2512               'error'        => '',
2513               'expansion'    => '2192',
2514               'arrow'        => '2192',
2515               'minus'        => '2212', # in mathematical operators
2516#               'minus'        => '002D', # in latin1
2517               'point'        => '2605',
2518               'print'        => '22A3',
2519               'result'       => '21D2',
2520               'today'        => '',
2521               'aa'           => '00E5',
2522               'AA'           => '00C5',
2523               'ae'           => '00E6',
2524               'oe'           => '0153',
2525               'AE'           => '00C6',
2526               'OE'           => '0152',
2527               'o'            => '00F8',
2528               'O'            => '00D8',
2529               'ss'           => '00DF',
2530               'DH'           => '00D0',
2531               'dh'           => '00F0',
2532               'TH'           => '00DE',
2533               'th'           => '00FE',
2534               'l'            => '0142',
2535               'L'            => '0141',
2536               'exclamdown'   => '00A1',
2537               'questiondown' => '00BF',
2538               'pounds'       => '00A3',
2539               'ordf'         => '00AA',
2540               'ordm'         => '00BA',
2541               'comma'        => '002C',
2542               'euro'         => '20AC',
2543               'geq'          => '2265',
2544               'leq'          => '2264',
2545               'tie'          => '',
2546#               'tie'          => '0020',
2547               'textdegree'          => '00B0',
2548               'quotedblleft'          => '201C',
2549               'quotedblright'          => '201D',
2550               'quoteleft'          => '2018',
2551               'quoteright'          => '2019',
2552               'quotedblbase'          => '201E',
2553               'quotesinglbase'          => '201A',
2554               'guillemetleft'          => '00AB',
2555               'guillemetright'          => '00BB',
2556               'guillemotleft'          => '00AB',
2557               'guillemotright'          => '00BB',
2558               'guilsinglleft'          => '2039',
2559               'guilsinglright'          => '203A',
2560             );
2561
2562%makeinfo_encoding_to_map = (
2563  "iso-8859-1",  'iso8859_1',
2564  "iso-8859-2",  'iso8859_2',
2565  "iso-8859-15", 'iso8859_15',
2566  "koi8-r",      'koi8',
2567  "koi8-u",      'koi8',
2568);
2569
2570foreach my $encoding (keys(%makeinfo_encoding_to_map))
2571{
2572   $t2h_encoding_aliases{$encoding} = $encoding;
2573   $t2h_encoding_aliases{$makeinfo_encoding_to_map{$encoding}} = $encoding;
2574}
2575
2576# cut and pasted from eigth_bit_makeinfo_maps.pl, in turn generated with
2577# ./parse_8bit_makeinfo_maps.pl
2578
2579%makeinfo_unicode_to_eight_bit = (
2580   'iso8859_1' => {
2581      '00A0' => 'A0',
2582      '00A1' => 'A1',
2583      '00A2' => 'A2',
2584      '00A3' => 'A3',
2585      '00A4' => 'A4',
2586      '00A5' => 'A5',
2587      '00A6' => 'A6',
2588      '00A7' => 'A7',
2589      '00A8' => 'A8',
2590      '00A9' => 'A9',
2591      '00AA' => 'AA',
2592      '00AB' => 'AB',
2593      '00AC' => 'AC',
2594      '00AD' => 'AD',
2595      '00AE' => 'AE',
2596      '00AF' => 'AF',
2597      '00B0' => 'B0',
2598      '00B1' => 'B1',
2599      '00B2' => 'B2',
2600      '00B3' => 'B3',
2601      '00B4' => 'B4',
2602      '00B5' => 'B5',
2603      '00B6' => 'B6',
2604      '00B7' => 'B7',
2605      '00B8' => 'B8',
2606      '00B9' => 'B9',
2607      '00BA' => 'BA',
2608      '00BB' => 'BB',
2609      '00BC' => 'BC',
2610      '00BD' => 'BD',
2611      '00BE' => 'BE',
2612      '00BF' => 'BF',
2613      '00C0' => 'C0',
2614      '00C1' => 'C1',
2615      '00C2' => 'C2',
2616      '00C3' => 'C3',
2617      '00C4' => 'C4',
2618      '00C5' => 'C5',
2619      '00C6' => 'C6',
2620      '00C7' => 'C7',
2621      '00C7' => 'C7',
2622      '00C8' => 'C8',
2623      '00C9' => 'C9',
2624      '00CA' => 'CA',
2625      '00CB' => 'CB',
2626      '00CC' => 'CC',
2627      '00CD' => 'CD',
2628      '00CE' => 'CE',
2629      '00CF' => 'CF',
2630      '00D0' => 'D0',
2631      '00D1' => 'D1',
2632      '00D2' => 'D2',
2633      '00D3' => 'D3',
2634      '00D4' => 'D4',
2635      '00D5' => 'D5',
2636      '00D6' => 'D6',
2637      '00D7' => 'D7',
2638      '00D8' => 'D8',
2639      '00D9' => 'D9',
2640      '00DA' => 'DA',
2641      '00DB' => 'DB',
2642      '00DC' => 'DC',
2643      '00DD' => 'DD',
2644      '00DE' => 'DE',
2645      '00DF' => 'DF',
2646      '00E0' => 'E0',
2647      '00E1' => 'E1',
2648      '00E2' => 'E2',
2649      '00E3' => 'E3',
2650      '00E4' => 'E4',
2651      '00E5' => 'E5',
2652      '00E6' => 'E6',
2653      '00E7' => 'E7',
2654      '00E8' => 'E8',
2655      '00E9' => 'E9',
2656      '00EA' => 'EA',
2657      '00EB' => 'EB',
2658      '00EC' => 'EC',
2659      '00ED' => 'ED',
2660      '00EE' => 'EE',
2661      '00EF' => 'EF',
2662      '00F0' => 'F0',
2663      '00F1' => 'F1',
2664      '00F2' => 'F2',
2665      '00F3' => 'F3',
2666      '00F4' => 'F4',
2667      '00F5' => 'F5',
2668      '00F6' => 'F6',
2669      '00F7' => 'F7',
2670      '00F8' => 'F8',
2671      '00F9' => 'F9',
2672      '00FA' => 'FA',
2673      '00FB' => 'FB',
2674      '00FC' => 'FC',
2675      '00FD' => 'FD',
2676      '00FE' => 'FE',
2677      '00FF' => 'FF',
2678   },
2679   'iso8859_15' => {
2680      '00A0' => 'A0',
2681      '00A1' => 'A1',
2682      '00A2' => 'A2',
2683      '00A3' => 'A3',
2684      '20AC' => 'A4',
2685      '00A5' => 'A5',
2686      '0160' => 'A6',
2687      '00A7' => 'A7',
2688      '0161' => 'A8',
2689      '00A9' => 'A9',
2690      '00AA' => 'AA',
2691      '00AB' => 'AB',
2692      '00AC' => 'AC',
2693      '00AD' => 'AD',
2694      '00AE' => 'AE',
2695      '00AF' => 'AF',
2696      '00B0' => 'B0',
2697      '00B1' => 'B1',
2698      '00B2' => 'B2',
2699      '00B3' => 'B3',
2700      '017D' => 'B4',
2701      '00B5' => 'B5',
2702      '00B6' => 'B6',
2703      '00B7' => 'B7',
2704      '017E' => 'B8',
2705      '00B9' => 'B9',
2706      '00BA' => 'BA',
2707      '00BB' => 'BB',
2708      '0152' => 'BC',
2709      '0153' => 'BD',
2710      '0178' => 'BE',
2711      '00BF' => 'BF',
2712      '00C0' => 'C0',
2713      '00C1' => 'C1',
2714      '00C2' => 'C2',
2715      '00C3' => 'C3',
2716      '00C4' => 'C4',
2717      '00C5' => 'C5',
2718      '00C6' => 'C6',
2719      '00C7' => 'C7',
2720      '00C8' => 'C8',
2721      '00C9' => 'C9',
2722      '00CA' => 'CA',
2723      '00CB' => 'CB',
2724      '00CC' => 'CC',
2725      '00CD' => 'CD',
2726      '00CE' => 'CE',
2727      '00CF' => 'CF',
2728      '00D0' => 'D0',
2729      '00D1' => 'D1',
2730      '00D2' => 'D2',
2731      '00D3' => 'D3',
2732      '00D4' => 'D4',
2733      '00D5' => 'D5',
2734      '00D6' => 'D6',
2735      '00D7' => 'D7',
2736      '00D8' => 'D8',
2737      '00D9' => 'D9',
2738      '00DA' => 'DA',
2739      '00DB' => 'DB',
2740      '00DC' => 'DC',
2741      '00DD' => 'DD',
2742      '00DE' => 'DE',
2743      '00DF' => 'DF',
2744      '00E0' => 'E0',
2745      '00E1' => 'E1',
2746      '00E2' => 'E2',
2747      '00E3' => 'E3',
2748      '00E4' => 'E4',
2749      '00E5' => 'E5',
2750      '00E6' => 'E6',
2751      '00E7' => 'E7',
2752      '00E8' => 'E8',
2753      '00E9' => 'E9',
2754      '00EA' => 'EA',
2755      '00EB' => 'EB',
2756      '00EC' => 'EC',
2757      '00ED' => 'ED',
2758      '00EE' => 'EE',
2759      '00EF' => 'EF',
2760      '00F0' => 'F0',
2761      '00F1' => 'F1',
2762      '00F2' => 'F2',
2763      '00F3' => 'F3',
2764      '00F4' => 'F4',
2765      '00F5' => 'F5',
2766      '00F6' => 'F6',
2767      '00F7' => 'F7',
2768      '00F8' => 'F8',
2769      '00F9' => 'F9',
2770      '00FA' => 'FA',
2771      '00FB' => 'FB',
2772      '00FC' => 'FC',
2773      '00FD' => 'FD',
2774      '00FE' => 'FE',
2775      '00FF' => 'FF',
2776   },
2777   'iso8859_2' => {
2778      '00A0' => 'A0',
2779      '0104' => 'A1',
2780      '02D8' => 'A2',
2781      '0141' => 'A3',
2782      '00A4' => 'A4',
2783      '013D' => 'A5',
2784      '015A' => 'A6',
2785      '00A7' => 'A7',
2786      '00A8' => 'A8',
2787      '015E' => 'AA',
2788      '0164' => 'AB',
2789      '0179' => 'AC',
2790      '00AD' => 'AD',
2791      '017D' => 'AE',
2792      '017B' => 'AF',
2793      '00B0' => 'B0',
2794      '0105' => 'B1',
2795      '02DB' => 'B2',
2796      '0142' => 'B3',
2797      '00B4' => 'B4',
2798      '013E' => 'B5',
2799      '015B' => 'B6',
2800      '02C7' => 'B7',
2801      '00B8' => 'B8',
2802      '0161' => 'B9',
2803      '015F' => 'BA',
2804      '0165' => 'BB',
2805      '017A' => 'BC',
2806      '02DD' => 'BD',
2807      '017E' => 'BE',
2808      '017C' => 'BF',
2809      '0154' => 'C0',
2810      '00C1' => 'C1',
2811      '00C2' => 'C2',
2812      '0102' => 'C3',
2813      '00C4' => 'C4',
2814      '0139' => 'C5',
2815      '0106' => 'C6',
2816      '00C7' => 'C7',
2817      '010C' => 'C8',
2818      '00C9' => 'C9',
2819      '0118' => 'CA',
2820      '00CB' => 'CB',
2821      '011A' => 'CC',
2822      '00CD' => 'CD',
2823      '00CE' => 'CE',
2824      '010E' => 'CF',
2825      '0110' => 'D0',
2826      '0143' => 'D1',
2827      '0147' => 'D2',
2828      '00D3' => 'D3',
2829      '00D4' => 'D4',
2830      '0150' => 'D5',
2831      '00D6' => 'D6',
2832      '00D7' => 'D7',
2833      '0158' => 'D8',
2834      '016E' => 'D9',
2835      '00DA' => 'DA',
2836      '0170' => 'DB',
2837      '00DC' => 'DC',
2838      '00DD' => 'DD',
2839      '0162' => 'DE',
2840      '00DF' => 'DF',
2841      '0155' => 'E0',
2842      '00E1' => 'E1',
2843      '00E2' => 'E2',
2844      '0103' => 'E3',
2845      '00E4' => 'E4',
2846      '013A' => 'E5',
2847      '0107' => 'E6',
2848      '00E7' => 'E7',
2849      '010D' => 'E8',
2850      '00E9' => 'E9',
2851      '0119' => 'EA',
2852      '00EB' => 'EB',
2853      '011B' => 'EC',
2854      '00ED' => 'ED',
2855      '00EE' => 'EE',
2856      '010F' => 'EF',
2857      '0111' => 'F0',
2858      '0144' => 'F1',
2859      '0148' => 'F2',
2860      '00F3' => 'F3',
2861      '00F4' => 'F4',
2862      '0151' => 'F5',
2863      '00F6' => 'F6',
2864      '00F7' => 'F7',
2865      '0159' => 'F8',
2866      '016F' => 'F9',
2867      '00FA' => 'FA',
2868      '0171' => 'FB',
2869      '00FC' => 'FC',
2870      '00FD' => 'FD',
2871      '0163' => 'FE',
2872      '02D9' => 'FF',
2873   },
2874   'koi8' => {
2875      '0415' => 'A3',
2876      '0454' => 'A4',
2877      '0456' => 'A6',
2878      '0457' => 'A7',
2879      '04D7' => 'B3',
2880      '0404' => 'B4',
2881      '0406' => 'B6',
2882      '0407' => 'B7',
2883      '042E' => 'C0',
2884      '0430' => 'C1',
2885      '0431' => 'C2',
2886      '0446' => 'C3',
2887      '0434' => 'C4',
2888      '0435' => 'C5',
2889      '0444' => 'C6',
2890      '0433' => 'C7',
2891      '0445' => 'C8',
2892      '0438' => 'C9',
2893      '0439' => 'CA',
2894      '043A' => 'CB',
2895      '043B' => 'CC',
2896      '043C' => 'CD',
2897      '043D' => 'CE',
2898      '043E' => 'CF',
2899      '043F' => 'D0',
2900      '044F' => 'D1',
2901      '0440' => 'D2',
2902      '0441' => 'D3',
2903      '0442' => 'D4',
2904      '0443' => 'D5',
2905      '0436' => 'D6',
2906      '0432' => 'D7',
2907      '044C' => 'D8',
2908      '044B' => 'D9',
2909      '0437' => 'DA',
2910      '0448' => 'DB',
2911      '044D' => 'DC',
2912      '0449' => 'DD',
2913      '0447' => 'DE',
2914      '044A' => 'DF',
2915      '042D' => 'E0',
2916      '0410' => 'E1',
2917      '0411' => 'E2',
2918      '0426' => 'E3',
2919      '0414' => 'E4',
2920      '0415' => 'E5',
2921      '0424' => 'E6',
2922      '0413' => 'E7',
2923      '0425' => 'E8',
2924      '0418' => 'E9',
2925      '0419' => 'EA',
2926      '041A' => 'EB',
2927      '041B' => 'EC',
2928      '041C' => 'ED',
2929      '041D' => 'EE',
2930      '041E' => 'EF',
2931      '041F' => 'F0',
2932      '042F' => 'F1',
2933      '0420' => 'F2',
2934      '0421' => 'F3',
2935      '0422' => 'F4',
2936      '0423' => 'F5',
2937      '0416' => 'F6',
2938      '0412' => 'F7',
2939      '042C' => 'F8',
2940      '042B' => 'F9',
2941      '0417' => 'FA',
2942      '0428' => 'FB',
2943      '042D' => 'FC',
2944      '0429' => 'FD',
2945      '0427' => 'FE',
2946      '042A' => 'FF',
2947   },
2948);
2949
2950%eight_bit_to_unicode = ();
2951foreach my $encoding (keys(%makeinfo_encoding_to_map))
2952{
2953   my $unicode_to_eight = $makeinfo_unicode_to_eight_bit{$makeinfo_encoding_to_map{$encoding}};
2954#print STDERR "$encoding, $makeinfo_encoding_to_map{$encoding}, $unicode_to_eight\n";
2955   foreach my $utf8_key (keys(%{$unicode_to_eight}))
2956   {
2957      $eight_bit_to_unicode{$encoding}->{$unicode_to_eight->{$utf8_key}} =
2958         $utf8_key;
2959   }
2960}
2961
2962# currently unused
2963my %makeinfo_transliterate_map = (
2964  '0416' => 'ZH',
2965  '0447' => 'ch',
2966  '00EB' => 'e',
2967  '0414' => 'D',
2968  '0159' => 'r',
2969  '00E6' => 'ae',
2970  '042B' => 'Y',
2971  '00FA' => 'u',
2972  '043B' => 'l',
2973  '00DE' => 'TH',
2974  '00D9' => 'U',
2975  '00C4' => 'A',
2976  '0148' => 'n',
2977  '00F6' => 'o',
2978  '0434' => 'd',
2979  '041E' => 'O',
2980  '041B' => 'L',
2981  '044B' => 'y',
2982  '0107' => 'c',
2983  '0415' => 'E',
2984  '00C1' => 'A',
2985  '00D3' => 'O',
2986  '00DB' => 'U',
2987  '016E' => 'U',
2988  '013A' => 'l',
2989  '017B' => 'Z',
2990  '00F1' => 'n',
2991  '0428' => 'SH',
2992  '0153' => 'oe',
2993  '00F4' => 'o',
2994  '0144' => 'n',
2995  '0404' => 'IE',
2996  '0427' => 'CH',
2997  '0162' => 'T',
2998  '017A' => 'z',
2999  '0448' => 'sh',
3000  '0436' => 'zh',
3001  '00F9' => 'u',
3002  '0406' => 'I',
3003  '0103' => 'a',
3004  '0422' => 'T',
3005  '0160' => 'S',
3006  '0165' => 't',
3007  '017E' => 'z',
3008  '00F0' => 'd',
3009  '043E' => 'o',
3010  '043D' => 'n',
3011  '013E' => 'l',
3012  '0412' => 'V',
3013  '0111' => 'd',
3014  '0155' => 's',
3015  '017C' => 'z',
3016  '00CE' => 'I',
3017  '042D' => 'E',
3018  '00C8' => 'E',
3019  '00F8' => 'oe',
3020  '00F2' => 'o',
3021  '00FF' => 'y',
3022  '0420' => 'R',
3023  '0119' => 'e',
3024  '00D2' => 'O',
3025  '043C' => 'm',
3026  '00D0' => 'DH',
3027  '0179' => 'Z',
3028  '0110' => 'D',
3029  '043F' => 'p',
3030  '0170' => 'U',
3031  '011A' => 'E',
3032  '010C' => 'C',
3033  '015A' => 'S',
3034  '0433' => 'g',
3035  '00E1' => 'a',
3036  '010D' => 'c',
3037  '00CC' => 'I',
3038  '016F' => 'u',
3039  '0457' => 'yi',
3040  '00C2' => 'A',
3041  '0438' => 'i',
3042  '00E3' => 'a',
3043  '0435' => 'e',
3044  '0440' => 'r',
3045  '042A' => 'W',
3046  '0431' => 'b',
3047  '00EE' => 'i',
3048  '0150' => 'O',
3049  '00E8' => 'e',
3050  '0418' => 'I',
3051  '00CF' => 'I',
3052  '015F' => 's',
3053  '0142' => 'l',
3054  '0147' => 'N',
3055  '00DF' => 'ss',
3056  '00E5' => 'aa',
3057  '00C3' => 'A',
3058  '0106' => 'C',
3059  '0141' => 'L',
3060  '0164' => 'T',
3061  '017D' => 'Z',
3062  '00EC' => 'i',
3063  '041C' => 'M',
3064  '00C9' => 'E',
3065  '00E0' => 'a',
3066  '043A' => 'k',
3067  '00F5' => 'o',
3068  '042C' => 'X',
3069  '0449' => 'shch',
3070  '0444' => 'f',
3071  '0139' => 'L',
3072  '0158' => 'R',
3073  '00F3' => 'o',
3074  '00FB' => 'u',
3075  '0424' => 'F',
3076  '0446' => 'c',
3077  '0423' => 'U',
3078  '0442' => 't',
3079  '00FD' => 'y',
3080  '0102' => 'A',
3081  '0104' => 'A',
3082  '00CB' => 'E',
3083  '0426' => 'C',
3084  '00CD' => 'I',
3085  '0437' => 'z',
3086  '0178' => 'y',
3087  '00D4' => 'O',
3088  '044D' => 'e',
3089  '0432' => 'v',
3090  '013D' => 'L',
3091  '0163' => 't',
3092  '0456' => 'i',
3093  '011B' => 'e',
3094  '044F' => 'ya',
3095  '0429' => 'SHCH',
3096  '0411' => 'B',
3097  '044A' => 'w',
3098  '00C6' => 'AE',
3099  '041D' => 'N',
3100  '00DA' => 'U',
3101  '00C0' => 'A',
3102  '0152' => 'OE',
3103  '00DD' => 'Y',
3104  '0154' => 'R',
3105  '00E9' => 'e',
3106  '00D5' => 'O',
3107  '041F' => 'P',
3108  '0161' => 's',
3109  '0430' => 'a',
3110  '0445' => 'h',
3111  '00E2' => 'a',
3112  '00D6' => 'O',
3113  '0407' => 'YI',
3114  '00CA' => 'E',
3115  '0439' => 'i',
3116  '0171' => 'u',
3117  '00DC' => 'U',
3118  '042F' => 'YA',
3119  '0425' => 'H',
3120  '00FE' => 'th',
3121  '00D1' => 'N',
3122  '044C' => 'x',
3123  '010F' => 'd',
3124  '0410' => 'A',
3125  '0443' => 'u',
3126  '00EF' => 'i',
3127  '0105' => 'a',
3128  '00EA' => 'e',
3129  '00E4' => 'a',
3130  '015E' => 'S',
3131  '0417' => 'Z',
3132  '00ED' => 'i',
3133  '00FC' => 'u',
3134  '04D7' => 'IO',
3135  '00D8' => 'OE',
3136  '0419' => 'I',
3137  '0421' => 'S',
3138  '0143' => 'N',
3139  '010E' => 'D',
3140  '0413' => 'G',
3141  '015B' => 's',
3142  '0151' => 'o',
3143  '00E7' => 'c',
3144  '00C5' => 'AA',
3145  '0441' => 's',
3146  '0118' => 'E',
3147  '00C7' => 'C',
3148  '041A' => 'K',
3149  '0454' => 'ie',
3150  '042E' => 'yu',
3151);
3152
3153
3154%transliterate_map = (
3155               '00C5'  => 'AA',
3156               '00E5'  => 'aa',
3157               '00D8'  => 'O',
3158               '00F8'  => 'o',
3159               '00E6' => 'ae',
3160               '0153' => 'oe',
3161               '00C6' => 'AE',
3162               '0152' => 'OE',
3163               '00DF' => 'ss',
3164               '0141' => 'L',
3165               '0142' => 'l',
3166               '00D0' => 'D',
3167               '00F0' => 'd',
3168               '00DE' => 'TH',
3169               '00FE' => 'th',
3170               '0415'  => 'E',
3171               '0435'  => 'e',
3172               '0426'  => 'C',
3173               '042A'  => 'W',
3174               '044A'  => 'w',
3175               '042C'  => 'X',
3176               '044C'  => 'x',
3177               '042E'  => 'yu',
3178               '042F'  => 'YA',
3179               '044F'  => 'ya',
3180               '0433'  => 'g',
3181               '0446'  => 'c',
3182               '04D7'  => 'IO',
3183               '00DD'  => 'Y', # unidecode gets this wrong ?
3184               # following appears in tests, this is required to have
3185               # the same output with and without unidecode
3186               '4E2D'  => 'Zhong',
3187               '6587'  => 'Wen',
3188               '793A'  => 'Shi',
3189               '4F8B'  => 'Li',
3190               '7B2C'  => 'Di',
3191               '7AE0'  => 'Zhang',
3192               '53E6'  => 'Ling',
3193               '4E2A'  => 'Ge',
3194               # in http://www.cantonese.sheik.co.uk/dictionary/characters/7/
3195               # unidecode certainly gets it wrong
3196               '4E00'  => 'Yi',
3197               'FF08' => '(',
3198               'FF09' => ')',
3199               'FF0C' => ',',
3200               '5B66' => 'Xue',
3201               '7FD2' => 'Xi',
3202               '30DE' => 'ma',
3203               '30CB' => 'ni',
3204               '30E5' => 'yu',
3205               '30A2' => 'a',
3206               '30EB' => 'ru',
3207          );
3208
3209foreach my $symbol(keys(%unicode_map))
3210{
3211    if ($unicode_map{$symbol} ne '' and !exists($transliterate_map{$symbol}))
3212    {
3213         $no_transliterate_map{$unicode_map{$symbol}} = 1;
3214    }
3215}
3216
3217%ascii_character_map = (
3218            ' ' => '0020',
3219            '!' => '0021',
3220            '"' => '0022',
3221            '#' => '0023',
3222            '$' => '0024',
3223            '%' => '0025',
3224            '&' => '0026',
3225            "'" => '0027',
3226            '(' => '0028',
3227            ')' => '0029',
3228            '*' => '002A',
3229            '+' => '002B',
3230            ',' => '002C',
3231            '-' => '002D',
3232            '.' => '002E',
3233            '/' => '002F',
3234            ':' => '003A',
3235            ';' => '003B',
3236            '<' => '003C',
3237            '=' => '003D',
3238            '>' => '003E',
3239            '?' => '003F',
3240            '@' => '0040',
3241            '[' => '005B',
3242            '\\' => '005C',
3243            ']' => '005D',
3244            '^' => '005E',
3245            '_' => '005F',
3246            '`' => '0060',
3247            '{' => '007B',
3248            '|' => '007C',
3249            '}' => '007D',
3250            '~' => '007E',
3251);
3252
3253%perl_charset_to_html = (
3254              'utf8'       => 'utf-8',
3255              'utf-8-strict'       => 'utf-8',
3256              'ascii'      => 'us-ascii',
3257              'shiftjis'      => 'shift_jis',
3258);
3259
3260%t2h_encoding_aliases = (
3261              'latin1' => 'iso-8859-1',
3262);
3263
3264foreach my $perl_charset (keys(%perl_charset_to_html))
3265{
3266   $t2h_encoding_aliases{$perl_charset} = $perl_charset_to_html{$perl_charset};
3267   $t2h_encoding_aliases{$perl_charset_to_html{$perl_charset}} = $perl_charset_to_html{$perl_charset};
3268}
3269
3270# These are the encodings from the texinfo manual
3271foreach my $canonical_encoding('us-ascii', 'utf-8', 'iso-8859-1',
3272  'iso-8859-15','iso-8859-2','koi8-r', 'koi8-u')
3273{
3274  $canonical_texinfo_encodings{$canonical_encoding} = 1;
3275}
3276
3277# not used currently for html, but used in chm.init
3278%numeric_entity_map = ();
3279
3280foreach my $symbol (keys(%unicode_map))
3281{
3282    if ($symbol ne '')
3283    {
3284        $numeric_entity_map{$symbol} = '&#' . hex($unicode_map{$symbol}) . ';';
3285    }
3286}
3287
3288# When the value begins with & the function with that name is used to do the
3289# html. The first argument is the text enclosed within {}, the second is the
3290# style name (which is also the key of the hash)
3291#
3292# Otherwithe the value is the html element used to enclose the text, and if
3293# there is a " the resulting text is also enclosed within `'
3294my %old_style_map = (
3295      'acronym',    '',
3296      'asis',       '',
3297      'b',          'b',
3298      'cite',       'cite',
3299      'clicksequence', '',
3300      'code',       'code',
3301      'command',    'code',
3302      'ctrl',       '&default_ctrl',
3303      'dfn',        'em',
3304      'dmn',        '',
3305      'email',      '&default_email',
3306      'emph',       'em',
3307      'env',        'code',
3308      'file',       '"tt',
3309      'i',          'i',
3310      'kbd',        'kbd',
3311      'key',        'kbd',
3312      'math',       'em',
3313      'option',     '"samp',
3314      'r',          '',
3315      'samp',       '"samp',
3316      'sc',         '&default_sc',
3317      'strong',     'strong',
3318      't',          'tt',
3319      'uref',       '&default_uref',
3320      'url',        '&default_url',
3321      'var',        'var',
3322      'verb',       'tt',
3323      'titlefont',  '&default_titlefont',
3324      'w',          '',
3325     );
3326
3327sub t2h_default_copy_style_map ($$;$)
3328{
3329  my $from = shift;
3330  my $to = shift;
3331  my $merge = shift;
3332
3333  foreach my $command (keys(%$from))
3334  {
3335     $to->{$command} = {} if (!exists($to->{$command}));
3336     foreach my $key (keys(%{$from->{$command}}))
3337     {
3338        next if (exists($to->{$command}->{$key}) and $merge);
3339        if ($key eq 'args')
3340        {
3341           $to->{$command}->{$key} = [ @{$from->{$command}->{$key}} ];
3342        }
3343        else
3344        {
3345           $to->{$command}->{$key} = $from->{$command}->{$key};
3346        }
3347     }
3348  }
3349}
3350
3351# default is {'args' => ['normal'], 'attribute' => ''},
3352%style_map = (
3353      'asis',       {},
3354      'b',          {},
3355      'cite',       {},
3356      'clicksequence', {},
3357      'click',      {'function' => \&t2h_default_click_normal, 'type' => 'simple_style'},
3358      'code',       {'args' => ['code']},
3359      'command',    {'args' => ['code']},
3360      'ctrl',       {'function' => \&t2h_default_ctrl,'type' => 'simple_style'},
3361      'dfn',        {},
3362      'dmn',        {'type' => 'simple_style'},
3363      'email',      {'args' => ['code', 'normal'],
3364                       'function' => \&t2h_default_email,
3365                       'type' => 'simple_style'},
3366      #'email',      {'args' => ['normal', 'normal'],
3367      #                 'function' => \&t2h_default_email},
3368      'emph',       {},
3369      'env',        {'args' => ['code']},
3370      'file',       {'args' => ['code'], 'quote' => '"'},
3371      'headitemfont', {},
3372      'i',          {},
3373      'slanted',    {},
3374      'sansserif',  {},
3375      'kbd',        {'args' => ['code'], },
3376      'key',        {'args' => ['code'], 'begin' => '<', 'end' => '>'},
3377      'math',       {'function' => \&t2h_default_math, 'args' => ['math'] },
3378      'option',     {'args' => ['code'], 'quote' => '"'},
3379      'r',          {},
3380      'samp',       {'args' => ['code'],  'quote' => '"'},
3381#      'sc',         {'function' => \&t2h_default_sc},
3382      'sc',         {},
3383      'strong',     {},
3384      't',          {},
3385      'uref',       {'function' => \&t2h_default_uref,
3386                      'args' => ['code', 'normal', 'normal'],
3387                      'type' => 'simple_style' },
3388      #'uref',       {'function' => \&t2h_default_uref,
3389      #                'args' => ['normal', 'normal', 'normal']},
3390      'url',        {'function' => \&t2h_default_uref,
3391                      'args' => ['code', 'normal', 'normal'],
3392                      'type' => 'simple_style'},
3393      'indicateurl', {'args' => ['code'], 'begin' => '<', 'end' => '>','type' => 'simple_style'},
3394      'var',        {},
3395      'verb',       {'args' => ['code'], },
3396      'titlefont',  {'function' => \&t2h_default_titlefont,
3397            'type' => 'simple_style'},
3398      'w',          {},
3399      'hyphenation', {'function' => \&t2h_default_hyphenation, 'args' => ['keep']},
3400     );
3401
3402%command_type = ();
3403
3404foreach my $style (keys(%style_map))
3405{
3406   if (exists($style_map{$style}->{'type'}))
3407   {
3408       $command_type{$style} = $style_map{$style}->{'type'};
3409   }
3410   else
3411   {
3412       $command_type{$style} = 'style';
3413   }
3414}
3415
3416
3417sub t2h_default_select_substitution($$$)
3418{
3419   my $in_raw_text = shift;
3420   my $in_preformatted = shift;
3421   my $in_simple = shift;
3422
3423   my $substitutions = \@text_substitutions_normal;
3424   if ($in_raw_text)
3425   {
3426      $substitutions = \@text_substitutions_texi;
3427   }
3428   elsif ($in_simple)
3429   {
3430      $substitutions = \@text_substitutions_simple_format;
3431   }
3432   elsif ($in_preformatted)
3433   {
3434      $substitutions = \@text_substitutions_pre;
3435   }
3436   return $substitutions;
3437}
3438
3439sub t2h_text_substitutions($$$$)
3440{
3441   my $text = shift;
3442   my $in_raw_text = shift;
3443   my $in_preformatted = shift;
3444   my $in_simple = shift;
3445
3446   my $substitutions = t2h_default_select_substitution($in_raw_text, $in_preformatted, $in_simple);
3447   foreach my $substitution_entry (@$substitutions)
3448   {
3449      my $from = quotemeta($substitution_entry->[0]);
3450      my $to = $substitution_entry->[1];
3451      $text =~ s/$from/$to/g;
3452   }
3453   return $text;
3454}
3455
3456sub t2h_add_text_substitutions($$$$$)
3457{
3458   my $entry = shift;
3459   my $in_normal = shift;
3460   my $in_raw_text = shift;
3461   my $in_preformatted = shift;
3462   my $in_simple = shift;
3463
3464   my @formats_to_be_done = ($in_normal, $in_raw_text, $in_preformatted, $in_simple);
3465
3466   for (my $index = 0; $index < scalar(@formats_to_be_done); $index++)
3467   {
3468       next unless ($formats_to_be_done[$index]);
3469       my @args = (0, 0, 0);
3470       my $found = 0;
3471       $args[$index -1] = 1 if ($index > 0);
3472       my $substitutions = &t2h_default_select_substitution(@args);
3473       foreach my $substitution_entry (@$substitutions)
3474       {
3475           if ($substitution_entry->[0] eq $entry->[0])
3476           {
3477               $found = 1;
3478               $substitution_entry->[1] = $entry->[1];
3479           }
3480       }
3481       push @$substitutions, $entry unless ($found);
3482   }
3483}
3484
3485sub t2h_remove_text_substitutions($$$$$)
3486{
3487   my $entry = shift;
3488   my $in_normal = shift;
3489   my $in_raw_text = shift;
3490   my $in_preformatted = shift;
3491   my $in_simple = shift;
3492
3493   my @formats_to_be_done = ($in_normal, $in_raw_text, $in_preformatted, $in_simple);
3494
3495   for (my $index = 0; $index < scalar(@formats_to_be_done); $index++)
3496   {
3497       next unless ($formats_to_be_done[$index]);
3498       my @args = (0, 0, 0);
3499       $args[$index -1] = 1 if ($index > 0);
3500       my $substitutions = &t2h_default_select_substitution(@args);
3501
3502       @$substitutions = grep {$_->[0] ne $entry} @$substitutions;
3503   }
3504}
3505
3506
3507%unicode_diacritical = (
3508       'H'          => '030B',
3509       'ringaccent' => '030A',
3510       "'"          => '0301',
3511       'v'          => '030C',
3512       ','          => '0327',
3513       '^'          => '0302',
3514       'dotaccent'  => '0307',
3515       '`'          => '0300',
3516       '='          => '0304',
3517       '~'          => '0303',
3518       '"'          => '0308',
3519       'udotaccent' => '0323',
3520       'ubaraccent' => '0332',
3521       'u'          => '0306',
3522       'tieaccent'  => '0361',
3523       'ogonek'     => '0328'
3524);
3525
3526%unicode_accents = (
3527    'dotaccent' => { # dot above
3528        'A' => '0226', #C moz-1.2
3529        'a' => '0227', #c moz-1.2
3530        'B' => '1E02',
3531        'b' => '1E03',
3532        'C' => '010A',
3533        'c' => '010B',
3534        'D' => '1E0A',
3535        'd' => '1E0B',
3536        'E' => '0116',
3537        'e' => '0117',
3538        'F' => '1E1E',
3539        'f' => '1E1F',
3540        'G' => '0120',
3541        'g' => '0121',
3542        'H' => '1E22',
3543        'h' => '1E23',
3544        'i' => '0069',
3545        'I' => '0130',
3546        'N' => '1E44',
3547        'n' => '1E45',
3548        'O' => '022E', #Y moz-1.2
3549        'o' => '022F', #v moz-1.2
3550        'P' => '1E56',
3551        'p' => '1E57',
3552        'R' => '1E58',
3553        'r' => '1E59',
3554        'S' => '1E60',
3555        's' => '1E61',
3556        'T' => '1E6A',
3557        't' => '1E6B',
3558        'W' => '1E86',
3559        'w' => '1E87',
3560        'X' => '1E8A',
3561        'x' => '1E8B',
3562        'Y' => '1E8E',
3563        'y' => '1E8F',
3564        'Z' => '017B',
3565        'z' => '017C',
3566    },
3567    'udotaccent' => { # dot below
3568        'A' => '1EA0',
3569        'a' => '1EA1',
3570        'B' => '1E04',
3571        'b' => '1E05',
3572        'D' => '1E0C',
3573        'd' => '1E0D',
3574        'E' => '1EB8',
3575        'e' => '1EB9',
3576        'H' => '1E24',
3577        'h' => '1E25',
3578        'I' => '1ECA',
3579        'i' => '1ECB',
3580        'K' => '1E32',
3581        'k' => '1E33',
3582        'L' => '1E36',
3583        'l' => '1E37',
3584        'M' => '1E42',
3585        'm' => '1E43',
3586        'N' => '1E46',
3587        'n' => '1E47',
3588        'O' => '1ECC',
3589        'o' => '1ECD',
3590        'R' => '1E5A',
3591        'r' => '1E5B',
3592        'S' => '1E62',
3593        's' => '1E63',
3594        'T' => '1E6C',
3595        't' => '1E6D',
3596        'U' => '1EE4',
3597        'u' => '1EE5',
3598        'V' => '1E7E',
3599        'v' => '1E7F',
3600        'W' => '1E88',
3601        'w' => '1E89',
3602        'Y' => '1EF4',
3603        'y' => '1EF5',
3604        'Z' => '1E92',
3605        'z' => '1E93',
3606    },
3607    'ubaraccent' => { # line below
3608        'B' => '1E06',
3609        'b' => '1E07',
3610        'D' => '1E0E',
3611        'd' => '1E0F',
3612        'h' => '1E96',
3613        'K' => '1E34',
3614        'k' => '1E35',
3615        'L' => '1E3A',
3616        'l' => '1E3B',
3617        'N' => '1E48',
3618        'n' => '1E49',
3619        'R' => '1E5E',
3620        'r' => '1E5F',
3621        'T' => '1E6E',
3622        't' => '1E6F',
3623        'Z' => '1E94',
3624        'z' => '1E95',
3625    },
3626    ',' => { # cedilla
3627        'C' => '00C7',
3628        'c' => '00E7',
3629        'D' => '1E10',
3630        'd' => '1E11',
3631        'E' => '0228', #C moz-1.2
3632        'e' => '0229', #c moz-1.2
3633        'G' => '0122',
3634        'g' => '0123',
3635        'H' => '1E28',
3636        'h' => '1E29',
3637        'K' => '0136',
3638        'k' => '0137',
3639        'L' => '013B',
3640        'l' => '013C',
3641        'N' => '0145',
3642        'n' => '0146',
3643        'R' => '0156',
3644        'r' => '0157',
3645        'S' => '015E',
3646        's' => '015F',
3647        'T' => '0162',
3648        't' => '0163',
3649    },
3650    '=' => { # macron
3651        'A' => '0100',
3652        'a' => '0101',
3653        'E' => '0112',
3654        'e' => '0113',
3655        'I' => '012A',
3656        'i' => '012B',
3657        'G' => '1E20',
3658        'g' => '1E21',
3659        'O' => '014C',
3660        'o' => '014D',
3661        'U' => '016A',
3662        'u' => '016B',
3663        'Y' => '0232', #? moz-1.2
3664        'y' => '0233', #? moz-1.2
3665    },
3666    '"' => { # diaeresis
3667        'A' => '00C4',
3668        'a' => '00E4',
3669        'E' => '00CB',
3670        'e' => '00EB',
3671        'H' => '1E26',
3672        'h' => '1E27',
3673        'I' => '00CF',
3674        'i' => '00EF',
3675        'O' => '00D6',
3676        'o' => '00F6',
3677        't' => '1E97',
3678        'U' => '00DC',
3679        'u' => '00FC',
3680        'W' => '1E84',
3681        'w' => '1E85',
3682        'X' => '1E8C',
3683        'x' => '1E8D',
3684        'y' => '00FF',
3685        'Y' => '0178',
3686    },
3687    'u' => { # breve
3688        'A' => '0102',
3689        'a' => '0103',
3690        'E' => '0114',
3691        'e' => '0115',
3692        'G' => '011E',
3693        'g' => '011F',
3694        'I' => '012C',
3695        'i' => '012D',
3696        'O' => '014E',
3697        'o' => '014F',
3698        'U' => '016C',
3699        'u' => '016D',
3700    },
3701    "'" => { # acute
3702        'A' => '00C1',
3703        'a' => '00E1',
3704        'C' => '0106',
3705        'c' => '0107',
3706        'E' => '00C9',
3707        'e' => '00E9',
3708        'G' => '01F4',
3709        'g' => '01F5',
3710        'I' => '00CD',
3711        'i' => '00ED',
3712        'K' => '1E30',
3713        'k' => '1E31',
3714        'L' => '0139',
3715        'l' => '013A',
3716        'M' => '1E3E',
3717        'm' => '1E3F',
3718        'N' => '0143',
3719        'n' => '0144',
3720        'O' => '00D3',
3721        'o' => '00F3',
3722        'P' => '1E54',
3723        'p' => '1E55',
3724        'R' => '0154',
3725        'r' => '0155',
3726        'S' => '015A',
3727        's' => '015B',
3728        'U' => '00DA',
3729        'u' => '00FA',
3730        'W' => '1E82',
3731        'w' => '1E83',
3732        'Y' => '00DD',
3733        'y' => '00FD',
3734        'Z' => '0179',
3735        'z' => '018A',
3736    },
3737    '~' => { # tilde
3738        'A' => '00C3',
3739        'a' => '00E3',
3740        'E' => '1EBC',
3741        'e' => '1EBD',
3742        'I' => '0128',
3743        'i' => '0129',
3744        'N' => '00D1',
3745        'n' => '00F1',
3746        'O' => '00D5',
3747        'o' => '00F5',
3748        'U' => '0168',
3749        'u' => '0169',
3750        'V' => '1E7C',
3751        'v' => '1E7D',
3752        'Y' => '1EF8',
3753        'y' => '1EF9',
3754    },
3755    '`' => { # grave
3756        'A' => '00C0',
3757        'a' => '00E0',
3758        'E' => '00C8',
3759        'e' => '00E8',
3760        'I' => '00CC',
3761        'i' => '00EC',
3762        'N' => '01F8',
3763        'n' => '01F9',
3764        'O' => '00D2',
3765        'o' => '00F2',
3766        'U' => '00D9',
3767        'u' => '00F9',
3768        'W' => '1E80',
3769        'w' => '1E81',
3770        'Y' => '1EF2',
3771        'y' => '1EF3',
3772    },
3773    '^' => { # circumflex
3774        'A' => '00C2',
3775        'a' => '00E2',
3776        'C' => '0108',
3777        'c' => '0109',
3778        'E' => '00CA',
3779        'e' => '00EA',
3780        'G' => '011C',
3781        'g' => '011D',
3782        'H' => '0124',
3783        'h' => '0125',
3784        'I' => '00CE',
3785        'i' => '00EE',
3786        'J' => '0134',
3787        'j' => '0135',
3788        'O' => '00D4',
3789        'o' => '00F4',
3790        'S' => '015C',
3791        's' => '015D',
3792        'U' => '00DB',
3793        'u' => '00FB',
3794        'W' => '0174',
3795        'w' => '0175',
3796        'Y' => '0176',
3797        'y' => '0177',
3798        'Z' => '1E90',
3799        'z' => '1E91',
3800    },
3801    'ringaccent' => { # ring
3802        'A' => '00C5',
3803        'a' => '00E5',
3804        'U' => '016E',
3805        'u' => '016F',
3806        'w' => '1E98',
3807        'y' => '1E99',
3808    },
3809    'v' => { # caron
3810        'A' => '01CD',
3811        'a' => '01CE',
3812        'C' => '010C',
3813        'c' => '010D',
3814        'D' => '010E',
3815        'd' => '010F',
3816        'E' => '011A',
3817        'e' => '011B',
3818        'G' => '01E6',
3819        'g' => '01E7',
3820        'H' => '021E', #K with moz-1.2
3821        'h' => '021F', #k with moz-1.2
3822        'I' => '01CF',
3823        'i' => '01D0',
3824        'K' => '01E8',
3825        'k' => '01E9',
3826        'L' => '013D', #L' with moz-1.2
3827        'l' => '013E', #l' with moz-1.2
3828        'N' => '0147',
3829        'n' => '0148',
3830        'O' => '01D1',
3831        'o' => '01D2',
3832        'R' => '0158',
3833        'r' => '0159',
3834        'S' => '0160',
3835        's' => '0161',
3836        'T' => '0164',
3837        't' => '0165',
3838        'U' => '01D3',
3839        'u' => '01D4',
3840        'Z' => '017D',
3841        'z' => '017E',
3842    },
3843    'H' => { # double acute
3844        'O' => '0150',
3845        'o' => '0151',
3846        'U' => '0170',
3847        'u' => '0171',
3848    },
3849    'ogonek' => {
3850        'A' => '0104',
3851        'a' => '0105',
3852        'E' => '0118',
3853        'e' => '0119',
3854        'I' => '012E',
3855        'i' => '012F',
3856        'U' => '0172',
3857        'u' => '0173',
3858        'O' => '01EA',
3859        'o' => '01EB',
3860    },
3861);
3862
3863foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents))
3864{
3865     $style_map{$accent_command} = { 'function' => \&t2h_default_accent };
3866     $old_style_map{$accent_command} = '&default_accent';
3867     $style_map_texi{$accent_command} = { 'function' => \&t2h_default_accent };
3868}
3869
3870
3871%transliterate_accent_map = ();
3872foreach my $command (keys(%unicode_accents))
3873{
3874    foreach my $letter(keys (%{$unicode_accents{$command}}))
3875    {
3876        $transliterate_accent_map{$unicode_accents{$command}->{$letter}}
3877            = $letter
3878          unless (exists($transliterate_map{$unicode_accents{$command}->{$letter}}));
3879    }
3880}
3881
3882sub default_accent($$)
3883{
3884    my $text = shift;
3885    my $accent = shift;
3886    return "&${text}$accent_map{$accent};" if (defined($accent_map{$accent}) and defined($special_accents{$accent}) and ($text =~ /^[$special_accents{$accent}]$/));
3887    return '&' . $text . 'ring;' if (($accent eq 'ringaccent') and (defined($special_accents{$accent})) and ($text =~ /^[$special_accents{$accent}]$/));
3888    return $text . '&lt;' if ($accent eq 'v');
3889    return ascii_accents($text, $accent);
3890}
3891
3892sub t2h_default_accent($$)
3893{
3894    my $accent = shift;
3895    my $args = shift;
3896
3897    my $text = $args->[0];
3898
3899    return ascii_accents($text, $accent);
3900}
3901
3902####################################################################
3903# special accent/encoding commands
3904#
3905# Some functions used to override normal formatting functions in specific
3906# cases. The user shouldn't want to change them, but can use them.
3907#
3908
3909sub ascii_accents($$)
3910{
3911    my $text = shift;
3912    my $accent = shift;
3913    return $text if ($accent eq 'dotless');
3914    return $text . "''" if ($accent eq 'H');
3915    return $text . '.' if ($accent eq 'dotaccent');
3916    return $text . '*' if ($accent eq 'ringaccent');
3917    return $text . '[' if ($accent eq 'tieaccent');
3918    return $text . '(' if ($accent eq 'u');
3919    return $text . '_' if ($accent eq 'ubaraccent');
3920    return '.' . $text  if ($accent eq 'udotaccent');
3921    return $text . '<' if ($accent eq 'v');
3922    return $text . ';' if ($accent eq 'ogonek');
3923    return $text . $accent if (defined($accent_map{$accent}));
3924}
3925
3926sub xml_default_accent($$)
3927{
3928    my $accent = shift;
3929    my $args = shift;
3930
3931    my $text = $args->[0];
3932
3933    return "&${text}$accent_map{$accent};" if (defined($accent_map{$accent}) and defined($special_accents{$accent}) and ($text =~ /^[$special_accents{$accent}]$/));
3934    return '&' . $text . 'ring;' if (($accent eq 'ringaccent') and (defined($special_accents{$accent})) and ($text =~ /^[$special_accents{$accent}]$/));
3935    return $text . '&lt;' if ($accent eq 'v');
3936# FIXME here there could be a conversion to the character in the right
3937# encoding, like
3938#    if ($USE_UNICODE and defined($OUT_ENCODING) and $OUT_ENCODING ne ''
3939#        and exists($unicode_accents{$accent}) and  exists($unicode_accents{$accent}->{$text}))
3940#    {
3941#          my $encoded_char =  Encode::encode($OUT_ENCODING, chr(hex($unicode_map{$thing})), Encode::FB_QUIET);
3942#          return $encoded_char if ($encoded_char ne '');
3943#    }
3944    if ($USE_NUMERIC_ENTITY)
3945    {
3946        if (exists($unicode_accents{$accent}) and exists($unicode_accents{$accent}->{$text}))
3947        {
3948             return ('&#' . hex($unicode_accents{$accent}->{$text}) . ';');
3949        }
3950    }
3951    return ascii_accents($text, $accent);
3952}
3953
3954# used to utf8 encode the result
3955sub t2h_utf8_accent($$$)
3956{
3957    my $accent = shift;
3958    my $args = shift;
3959    my $style_stack = shift;
3960
3961    my $text = $args->[0];
3962    #print STDERR "$accent\[".scalar(@$style_stack) ."\] (@$style_stack)\n";
3963
3964    # special handling of @dotless{i}
3965    if ($accent eq 'dotless')
3966    {
3967        if (($text eq 'i') and (!defined($style_stack->[-1]) or (!defined($unicode_accents{$style_stack->[-1]})) or ($style_stack->[-1] eq 'tieaccent')))
3968        {
3969             return "\x{0131}";
3970        }
3971        #return "\x{}" if ($text eq 'j'); # not found !
3972        return $text;
3973    }
3974
3975    # FIXME \x{0131}\x{0308} for @dotless{i} @" doesn't lead to NFC 00ef.
3976    return Unicode::Normalize::NFC($text . chr(hex($unicode_diacritical{$accent})))
3977        if (defined($unicode_diacritical{$accent}));
3978    return ascii_accents($text, $accent);
3979}
3980
3981sub t2h_utf8_normal_text($$$$$$$;$)
3982{
3983    my $text = shift;
3984    my $in_raw_text = shift;
3985    my $in_preformatted = shift;
3986    my $in_code = shift;
3987    my $in_math = shift;
3988    my $in_simple = shift;
3989    my $style_stack = shift;
3990    my $state = shift;
3991
3992    $text = &$protect_text($text) unless($in_raw_text);
3993    $text = uc($text) if (in_small_caps($style_stack));
3994
3995    if (!$in_code and !$in_preformatted)
3996    {
3997        $text =~ s/---/\x{2014}/g;
3998        $text =~ s/--/\x{2013}/g;
3999        $text =~ s/``/\x{201C}/g;
4000        $text =~ s/''/\x{201D}/g;
4001    }
4002    $text = t2h_text_substitutions($text, $in_raw_text, ($in_preformatted or $in_code), $in_simple);
4003    return Unicode::Normalize::NFC($text);
4004}
4005
4006sub t2h_enable_encoding_normal_accent($$$)
4007{
4008  return t2h_enable_encoding_accent ('normal', @_);
4009}
4010sub t2h_enable_encoding_texi_accent($$$)
4011{
4012  return t2h_enable_encoding_accent ('texi', @_);
4013}
4014sub t2h_enable_encoding_pre_accent($$$)
4015{
4016  return t2h_enable_encoding_accent ('pre', @_);
4017}
4018
4019sub t2h_enable_encoding_accent($$$$)
4020{
4021  my $context = shift;
4022  my @other_args = @_;
4023
4024  my $accent = shift;
4025  my $args = shift;
4026  my $style_stack = shift;
4027  my $text = $args->[0];
4028
4029#print STDERR "enable_encoding_accent called($context) $accent (@$style_stack)\n";
4030
4031  # in case ENCODING_NAME is not known, the accent functions saved previously
4032  # are used.
4033  # This should happen rarely, like during @setfilename parsing.
4034  return &{$t2h_enable_encoding_default_accent{$context}->{$accent}}(@other_args) if (!defined($Texi2HTML::THISDOC{'ENCODING_NAME'}));
4035
4036  return t2h_utf8_accent($accent,[$text],$style_stack) if ($Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8');
4037
4038  # use the saved default handling if this is not a known 8 bit encoding
4039  return &{$t2h_enable_encoding_default_accent{$context}->{$accent}}(@other_args) if (!exists($makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}}));
4040
4041  # the following is for the handling of known 8 bit encodings.
4042  if (scalar(@t2h_enable_encoding_accents_stack))
4043  {
4044    # in that case, we already have a result ready that corresponds with the
4045    # formatting of a part of the stack mapped to
4046    # t2h_enable_encoding_accents_stack, so it is emptied and the innermost
4047    # $text is returned as is, such that the unmodified already formatted
4048    # innermost formatted accented text is returned.
4049
4050    #print STDERR " doing nothing, still in stack (@t2h_enable_encoding_accents_stack), accent: $accent";
4051    my $stack_accent = shift @t2h_enable_encoding_accents_stack;
4052    #print STDERR " stack_accent $stack_accent\n";
4053    return $text;
4054  }
4055
4056  # in that case there is no t2h_enable_encoding_accents_stack, so we are
4057  # at the closing of the innermost accented command. We will try to format
4058  # all the stack in reverse(@$style_stack) that coresponds with
4059  # accent commands
4060  my @accents_stack = ();
4061  my @styles = reverse(@$style_stack);
4062
4063  # accents are formatted and the intermediate results are kept, such
4064  # that we can return the maximum of multiaccented letters that can be
4065  # rendered with a given eight bit formatting.
4066
4067  # first put the letter in the stack
4068  my @utf8_partial_results = { 'result' => $text,
4069      'accents_stack' => [ @accents_stack ]};
4070
4071  # then the accent that is associated with the function call
4072  my $current_accent = t2h_utf8_accent($accent,[$text],$style_stack);
4073  @accents_stack = ($accent);
4074  push @utf8_partial_results, { 'result' => $current_accent,
4075       'accents_stack' => [ @accents_stack ]};
4076
4077  # and then all the other accents on the stack
4078  while (scalar(@styles) and (defined($unicode_accents{$styles[0]}) or $styles[0] eq 'dotless'))
4079  {
4080    my $next_style = shift @styles;
4081    my @new_stack = reverse(@styles);
4082    $current_accent = t2h_utf8_accent($next_style,[$current_accent],\@new_stack);
4083    push @accents_stack, $next_style;
4084    push @utf8_partial_results, { 'result' => $current_accent,
4085       'accents_stack' => [ @accents_stack ]}
4086        ;
4087  }
4088
4089  my $enc_map = $makeinfo_encoding_to_map{$Texi2HTML::THISDOC{'ENCODING_NAME'}};
4090  my $eight_bit;
4091  my $result;
4092  # At this point we have the utf8 encoded results for the accent
4093  # commands stack, with all the intermediate results.
4094  # For each one we'll check if it is possible to encode it in the
4095  # current eight bit output encoding table
4096  foreach my $partial_result (@utf8_partial_results)
4097  {
4098    my $char = $partial_result->{'result'};
4099    my $new_eight_bit = '';
4100    my $new_codepoint;
4101
4102    if (ord($char) <= 128)
4103    {
4104      $new_eight_bit =  uc(sprintf("%02x",ord($char)));
4105      $new_codepoint = uc(sprintf("%04x",ord($char)));
4106    }
4107    elsif (ord($char) <= hex(0xFFFF))
4108    {
4109      $new_codepoint = uc(sprintf("%04x",ord($char)));
4110      if (exists($makeinfo_unicode_to_eight_bit{$enc_map}->{$new_codepoint}))
4111      {
4112         $new_eight_bit = $makeinfo_unicode_to_eight_bit{$enc_map}->{$new_codepoint};
4113      }
4114    }
4115    #my $eight_bit_txt = 'undef';
4116    #$eight_bit_txt = $eight_bit if (defined($eight_bit));
4117    #print STDERR "" . Encode::encode('utf8', "$char") . " (@{$partial_result->{'accents_stack'}}), new_codepoint: $new_codepoint 8bit: $new_eight_bit old:$eight_bit_txt\n";
4118    # no corresponding eight bit character found
4119    last if ($new_eight_bit eq '');
4120
4121    # in that case, the new eight bit character is the same than the one
4122    # found with one less character (and it isnt a @dotless{i}). It may
4123    # mean 2 things
4124    # -> there are 2 characters in accent. This could happen, for example
4125    #    if an accent that cannot be rendered is found and it leads to
4126    #    appending or prepending a character. For example this happens for
4127    #    @={@,{@~{n}}}, where @,{@~{n}} is expanded to a 2 character:
4128    #    n with a tilde, followed by a ,
4129    #    In nthat case, the additional utf8 accent is prepended, which
4130    #    means that it is composed with the , and leaves n with a tilde
4131    #    untouched.
4132    # -> ord(char) leads to the same for the more inner character.
4133    #    this, for example, happens for @ubaraccent{a}, where ord(a) is
4134    #    the same than ord(a with underbar).
4135    last if (defined($eight_bit) and (($new_eight_bit eq $eight_bit)
4136       and !($partial_result->{'accents_stack'}[0] eq 'dotless' and $char eq 'i')));
4137    $result = $partial_result;
4138    $eight_bit = $new_eight_bit;
4139  }
4140  if (defined($result) and scalar(@{$result->{'accents_stack'}}))
4141  {
4142     # we got a result, return it and put in t2h_enable_encoding_accents_stack
4143     # the stack of accent commands that were processed. They wont be used
4144     # further, but only unshifted.
4145
4146  #print STDERR "Result: ".Encode::encode('utf8', $result->{'result'}) ." '$eight_bit' (@{$result->{'accents_stack'}})\n" if defined($result);
4147     @t2h_enable_encoding_accents_stack = @{$result->{'accents_stack'}};
4148     # remove the first, it is the accent being processed
4149     shift @t2h_enable_encoding_accents_stack;
4150     # it should be noted that we return the 'utf8' accent (which is really
4151     # a codepoint, and not the eight bit representation, we leave the
4152     # conversion to perl, which should handle it fine
4153     return $result->{'result'};
4154  }
4155
4156  return &{$t2h_enable_encoding_default_accent{$context}->{$accent}}(@other_args);
4157}
4158
4159# end special accent/encoding commands
4160####################################################################
4161
4162####################################################################
4163# TeX/LaTeX, that can especially be used in @math
4164# To load the appropriate hash, use
4165# default_load_tex_math
4166
4167my %tex_default_simple_map_math = (
4168 '{' => '\{',
4169 '}' => '\}',
4170 '\\' => '\\'
4171);
4172
4173my %tex_default_math_things_map = %default_things_map;
4174
4175$tex_default_math_things_map{'bullet'} = '\bullet';
4176$tex_default_math_things_map{'copyright'} = '\copyright';
4177$tex_default_math_things_map{'registeredsymbol'} = '\circledR';
4178$tex_default_math_things_map{'dots'} = '\dots';
4179$tex_default_math_things_map{'endots'} = '\dots';
4180$tex_default_math_things_map{'equiv'} = '\equiv';
4181$tex_default_math_things_map{'expansion'} = '\mapsto';
4182$tex_default_math_things_map{'arrow'} = '\rightarrow';
4183$tex_default_math_things_map{'point'} = '\star';
4184$tex_default_math_things_map{'print'} = '\dashv';
4185$tex_default_math_things_map{'result'} = '\Rightarrow';
4186$tex_default_math_things_map{'pounds'} = '\pounds';
4187$tex_default_math_things_map{'geq'} = '\geq';
4188$tex_default_math_things_map{'leq'} = '\leq';
4189$tex_default_math_things_map{'textdegree'} = '^\circ';
4190
4191my %latex_default_math_things_map = %tex_default_math_things_map;
4192
4193$latex_default_math_things_map{'aa'} = '\mathring{a}';
4194$latex_default_math_things_map{'AA'} = '\mathring{A}';
4195
4196# FIXME Maybe this should not be there since it is not for math but
4197# more for a completly separate format.
4198my %latex_default_things_map;
4199
4200foreach my $thing (keys(%default_things_map))
4201{
4202    $latex_default_things_map{$thing} = '\\'.$thing;
4203}
4204
4205$latex_default_things_map{'error'} = '\fbox{error}';
4206$latex_default_things_map{'enddots'} = '\dots\@';
4207$latex_default_things_map{'exclamdown'} = '\textexclamdown';
4208$latex_default_things_map{'questiondown'} = '\textquestiondown';
4209$latex_default_things_map{'tie'} = '~';
4210$latex_default_things_map{'registeredsymbol'} = '\textregistered';
4211$latex_default_things_map{'ordf'} = '\textordfeminine';
4212$latex_default_things_map{'ordm'} = '\textordmasculine';
4213$latex_default_things_map{'guillemetleft'} = '\guillemotleft';
4214$latex_default_things_map{'guillemetright'} = '\guillemotright';
4215
4216foreach my $text_prefixed_symbols ('bullet', 'exclamdown', 'questiondown',
4217   'quotedblleft', 'quotedblright', 'quoteleft', 'quoteright')
4218{
4219   $latex_default_things_map{$text_prefixed_symbols} = '\text'.$text_prefixed_symbols;
4220}
4221
4222foreach my $math_only ('equiv', 'expansion', 'arrow', 'minus', 'point',
4223   'print', 'result', 'geq', 'leq')
4224{
4225   $latex_default_things_map{$math_only} = '$'.$latex_default_math_things_map{$math_only}.'$';
4226}
4227
4228
4229# End TeX/LaTeX
4230#############################################################
4231
4232sub default_sc($$)
4233{
4234    return uc($_[0]);
4235}
4236
4237sub default_ctrl($$)
4238{
4239   return "^$_[0]";
4240}
4241
4242# obsolete, no warning, but noop
4243sub t2h_default_ctrl($$$)
4244{
4245    shift;
4246    my $args = shift;
4247    #return "^$args->[0]";
4248    return "$args->[0]";
4249}
4250
4251sub default_sc_pre($$)
4252{
4253    return uc($_[0]);
4254}
4255
4256sub default_titlefont($$)
4257{
4258    return "<h1 class=\"titlefont\">$_[0]</h1>" if ($_[0] =~ /\S/);
4259    return '';
4260}
4261
4262# Return nothing if the text is empty
4263sub t2h_default_titlefont($$$)
4264{
4265    shift;
4266    my $args = shift;
4267    my $heading = $args->[0];
4268    return '' unless ($heading =~ /\S/);
4269    return &$heading_text('@titlefont', $heading, 0);
4270}
4271
4272# At some point in time (before 4.7?) according to the texinfo
4273# manual, url shouldn't lead to a link but rather be formatted
4274# like text. It is now what indicateurl do, url is the same that
4275# uref with one arg. If we did like makeinfo did it would have been
4276#sub url($$)
4277#{
4278#    return '&lt;<code>' . $_[0] . '</code>&gt;';
4279#}
4280#
4281# This is unused, t2h_default_uref is used instead
4282sub t2h_default_url ($$)
4283{
4284    shift;
4285    my $args = shift;
4286    my $url = shift @$args;
4287    $url = main::normalise_space($url);
4288    return '' unless ($url =~ /\S/);
4289    return t2h_default_url_and_text($url);
4290}
4291
4292sub default_url ($$)
4293{
4294    my $url = shift;
4295    my $command = shift;
4296    $url =~ s/\s*$//;
4297    $url =~ s/^\s*//;
4298    return t2h_default_url_and_text($url);
4299}
4300
4301sub default_uref($$)
4302{
4303    my $arg = shift;
4304    my $command = shift;
4305    my ($url, $text, $replacement);
4306    ($url, $text, $replacement) = split /,\s*/, $arg;
4307    $url =~ s/\s*$//;
4308    $url =~ s/^\s*//;
4309    $text = $replacement if (defined($replacement));
4310    return t2h_default_url_and_text($url, $text);
4311}
4312
4313sub t2h_default_uref($$)
4314{
4315    shift;
4316    my $args = shift;
4317    my $url = shift @$args;
4318    my $text = shift @$args;
4319    my $replacement = shift @$args;
4320    $url = main::normalise_space($url);
4321    $replacement = '' if (!defined($replacement));
4322    $replacement = main::normalise_space($replacement);
4323    $text = '' if (!defined($text));
4324    $text = main::normalise_space($text);
4325    $text = $replacement if ($replacement ne '');
4326    return t2h_default_url_and_text($url, $text);
4327}
4328
4329sub t2h_default_math($$)
4330{
4331    shift;
4332    my $args = shift;
4333    my $text = shift @$args;
4334    return "$text";
4335}
4336
4337sub default_email($$)
4338{
4339    my $arg = shift;
4340    my $command = shift;
4341    my ($mail, $text);
4342    ($mail, $text) = split /,\s*/, $arg;
4343    $mail =~ s/\s*$//;
4344    $mail =~ s/^\s*//;
4345    return t2h_default_url_and_text("mailto:$mail", $text);
4346}
4347
4348sub t2h_default_email($$)
4349{
4350    my $command = shift;
4351    my $args = shift;
4352    my $mail = shift @$args;
4353    my $text = shift @$args;
4354    $mail = main::normalise_space($mail);
4355    if (defined($text))
4356    {
4357       #$text =~ s/^\s*//;
4358       #$text =~ s/^\s*$//;
4359        $text = main::normalise_space($text);
4360    }
4361    my $mailto = '';
4362    $mailto = "mailto:$mail" if ($mail ne '');
4363    return t2h_default_url_and_text($mailto, $text);
4364}
4365
4366sub t2h_default_click_normal($$$)
4367{
4368    return t2h_default_click('normal', @_);
4369}
4370
4371sub t2h_default_click_pre($$$)
4372{
4373    return t2h_default_click('pre', @_);
4374}
4375
4376sub t2h_default_click_texi($$$)
4377{
4378    return t2h_default_click('texi', @_);
4379}
4380
4381sub t2h_default_click($$$$$)
4382{
4383    my $context = shift;
4384    my $command = shift;
4385    my $args = shift;
4386    my $arg = shift @$args;
4387    my $cmd = $Texi2HTML::THISDOC{'clickstyle'};
4388    $cmd = 'arrow' if (!defined($cmd) or ($cmd eq ''));
4389
4390    my $hash = \%things_map;
4391    if ($context eq 'pre')
4392    {
4393        $hash = \%pre_map;
4394    }
4395    elsif ($context eq 'texi')
4396    {
4397        $hash = \%texi_map;
4398    }
4399    return $hash->{$cmd} . $arg if (exists($hash->{$cmd}));
4400    return $arg;
4401}
4402
4403sub t2h_default_hyphenation($$)
4404{
4405    my $command = shift;
4406    my $args = shift;
4407    my $text = shift @$args;
4408    $text =~ s/^\s*//;
4409    $text =~ s/\s*$//;
4410    my @list = split /\s+/, $text;
4411    foreach my $entry (@list)
4412    {
4413         my $word = $entry;
4414         $word =~ s/-//g;
4415         $Texi2HTML::THISDOC{'hyphenation'}->{$word} = $entry;
4416    }
4417}
4418
4419sub t2h_default_no_texi_email
4420{
4421    my $command = shift;
4422    my $args = shift;
4423    my $mail = shift @$args;
4424    my $text = shift @$args;
4425    $mail = main::normalise_space($mail);
4426    return $text if (defined($text) and ($text ne ''));
4427    return $mail;
4428}
4429
4430sub t2h_default_no_texi_image($$$$)
4431{
4432    my $command = shift;
4433    my $args = shift;
4434    my $file = $args->[0];
4435    $file = main::trim_around_spaces($file);
4436    return main::substitute_line($file, "\@$command", {'remove_texi' => 1, 'code_style' => 1});
4437}
4438
4439sub t2h_default_no_texi_acronym_like($$)
4440{
4441    my $command = shift;
4442    my $args = shift;
4443    my $acronym_texi = $args->[0];
4444    return (main::remove_texi($acronym_texi));
4445}
4446
4447sub t2h_remove_command($$$$)
4448{
4449    return '';
4450}
4451
4452# This is used for style in preformatted sections
4453my %old_style_map_pre = %old_style_map;
4454$old_style_map_pre{'sc'} = '&default_sc_pre';
4455$old_style_map_pre{'titlefont'} = '';
4456
4457foreach my $command (keys(%style_map))
4458{
4459    $style_map_texi{$command} = {} if (!exists($style_map_texi{$command}));
4460    $style_map_texi{$command}->{'args'} = [ @{$style_map{$command}->{'args'}} ]
4461        if (exists($style_map{$command}->{'args'}));
4462 #print STDERR "COMMAND $command";
4463}
4464
4465%style_map_pre = ();
4466
4467t2h_default_copy_style_map(\%style_map, \%style_map_pre);
4468
4469$style_map_pre{'sc'} = {};
4470$style_map_pre{'titlefont'} = {};
4471$style_map_pre{'click'}->{'function'} = \&t2h_default_click_pre;
4472
4473$style_map_texi{'sc'} = {};
4474$style_map_texi{'email'}->{'function'} = \&t2h_default_no_texi_email;
4475$style_map_texi{'click'}->{'function'} = \&t2h_default_click_texi;
4476
4477####### special styles. You shouldn't need to change them
4478%special_style = (
4479           #'xref'      => ['keep','normal','normal','keep','normal'],
4480           'xref'         => { 'args' => ['keep','keep','keep','keep','keep'],
4481               'function' => \&main::do_xref },
4482           'ref'         => { 'args' => ['keep','keep','keep','keep','keep'],
4483               'function' => \&main::do_xref },
4484           'pxref'         => { 'args' => ['keep','keep','keep','keep','keep'],
4485               'function' => \&main::do_xref },
4486           'inforef'      => { 'args' => ['keep','keep','keep'],
4487               'function' => \&main::do_xref },
4488           'image'        => { 'args' => ['keep','keep','keep','keep','keep'], 'function' => \&main::do_image },
4489           'anchor'       => { 'args' => ['keep'], 'function' => \&main::do_anchor_label },
4490           'footnote'     => { 'args' => ['keep'], 'function' => \&main::do_footnote },
4491           'shortcaption' => { 'args' => ['keep'], 'function' => \&main::do_caption_shortcaption },
4492           'caption' => { 'args' => ['keep'], 'function' => \&main::do_caption_shortcaption },
4493           'acronym',    {'args' => ['keep','keep'], 'function' => \&main::do_acronym_like},
4494           'abbr',    {'args' => ['keep','keep'], 'function' => \&main::do_acronym_like},
4495);
4496
4497# @image is replaced by the first arg in strings
4498$style_map_texi{'image'} = { 'args' => ['keep','keep','keep','keep','keep'],
4499       'function' => \&t2h_default_no_texi_image };
4500
4501$style_map_texi{'acronym'} = { 'args' => ['keep','keep'],
4502       'function' => \&t2h_default_no_texi_acronym_like };
4503$style_map_texi{'abbr'} = { 'args' => ['keep','keep'],
4504       'function' => \&t2h_default_no_texi_acronym_like };
4505
4506foreach my $special (keys(%special_style))
4507{
4508    $style_map{$special} = $special_style{$special}
4509          unless (defined($style_map{$special}));
4510    $style_map_pre{$special} = $special_style{$special}
4511          unless (defined($style_map_pre{$special}));
4512    $style_map_texi{$special} = { 'args' => ['keep'],
4513        'function' => \&t2h_remove_command }
4514          unless (defined($style_map_texi{$special}));
4515}
4516####### end special styles.
4517
4518
4519#foreach my $command (keys(%style_map))
4520#{
4521#    print STDERR "STYLE_MAP_TEXI $command($style_map_texi{$command}) ";
4522#    print STDERR "ARGS $style_map_texi{$command}->{'args'} " if (defined($style_map_texi{$command}->{'args'}));
4523#    print STDERR "FUN $style_map_texi{$command}->{'function'} " if (defined($style_map_texi{$command}->{'function'}));
4524#    print STDERR "\n";
4525#}
4526
4527# uncomment to use the old interface
4528#%style_map = %old_style_map;
4529#%style_map_pre = %old_style_map_pre;
4530
4531%simple_format_simple_map_texi = %simple_map_pre;
4532%simple_format_texi_map = %pre_map;
4533%simple_format_style_map_texi = ();
4534
4535t2h_default_copy_style_map(\%style_map_texi, \%simple_format_style_map_texi);
4536
4537foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents))
4538{
4539#    $simple_format_style_map_texi{$accent_command}->{'args'} = ['normal'];
4540    $simple_format_style_map_texi{$accent_command}->{'function'} = \&t2h_default_accent;
4541}
4542
4543foreach my $hash (\%style_map, \%style_map_pre, \%style_map_texi, \%simple_format_style_map_texi)
4544{
4545  foreach my $style (keys(%{$hash}))
4546  {
4547    $hash->{$style}->{'args'} = ['normal'] if (!exists($hash->{$style}->{'args'}));
4548  }
4549}
4550
4551%default_style_map = ();
4552%default_style_map_pre = ();
4553%default_style_map_texi = ();
4554%default_simple_format_style_map_texi = ();
4555
4556t2h_default_copy_style_map(\%style_map, \%default_style_map);
4557t2h_default_copy_style_map(\%style_map_pre, \%default_style_map_pre);
4558t2h_default_copy_style_map(\%style_map_texi, \%default_style_map_texi);
4559t2h_default_copy_style_map(\%simple_format_style_map_texi, \%default_simple_format_style_map_texi);
4560
4561# called here because %default_style_map_texi is used.
4562t2h_default_set_variables_default();
4563
4564#################################################################
4565# TeX/LaTeX styles, that can be used in math
4566
4567my %default_style_tex_map;
4568my %default_style_latex_map;
4569
4570t2h_default_copy_style_map(\%default_style_map, \%default_style_tex_map);
4571t2h_default_copy_style_map(\%default_style_map, \%default_style_latex_map);
4572
4573# common in TeX and LaTeX and both for math and normal text
4574
4575$default_style_latex_map{'w'}->{'inline_begin'} = '\mbox{';
4576$default_style_tex_map{'w'}->{'inline_begin'} = '\mbox{';
4577$default_style_latex_map{'dmn'}->{'inline_begin'} = '{\thinspace ';
4578$default_style_tex_map{'dmn'}->{'inline_begin'} = '{\thinspace ';
4579
4580my %default_style_latex_math_map;
4581
4582t2h_default_copy_style_map(\%default_style_latex_map, \%default_style_latex_math_map);
4583
4584my %default_tex_latex_map = (
4585  'bf' => [ 'b', 'strong' ],
4586  'tt' => [ 'code', 'command', 'env', 'file', 'option', 'samp', 't' ],
4587  'it' => [ 'i', 'var', 'emph' ],
4588  'sf' => [ 'sanserif' ],
4589  'rm' => [ 'r' ],
4590  'sl' => [ 'dfn', 'slanted' ],
4591);
4592
4593foreach my $style (keys (%default_tex_latex_map))
4594{
4595   foreach my $command (@{$default_tex_latex_map{$style}})
4596   {
4597      $default_style_tex_map{$command}->{'inline_begin'} = '{\\' . $style .' ';
4598      $default_style_latex_map{$command}->{'inline_begin'} = '\text' . $style .'{';
4599      $style = 'normal' if ($style eq 'sl');
4600      $default_style_latex_math_map{$command}->{'inline_begin'} = '\math' . $style .'{';
4601   }
4602}
4603
4604# only in text
4605
4606$default_style_latex_map{'emph'}->{'inline_begin'} = '\emph{';
4607$default_style_latex_map{'var'}->{'inline_begin'} = '\emph{';
4608$default_style_latex_map{'sc'}->{'inline_begin'} = '\textsc{';
4609
4610foreach my $hash (\%default_style_tex_map, \%default_style_latex_map, \%default_style_latex_math_map)
4611{
4612   foreach my $command (keys(%$hash))
4613   {
4614      $hash->{$command}->{'inline_end'} = '}' if ($hash->{$command}->{'inline_begin'});
4615   }
4616}
4617
4618# no kbd key sc in math
4619#       'kbd'                -                 ?
4620#       'key'                -                 ?
4621
4622my %default_style_tex_math_map;
4623
4624t2h_default_copy_style_map(\%default_style_tex_map, \%default_style_tex_math_map);
4625
4626# We don't want to override special commands in math mode for now, as long
4627# as they are not handled especially. Also we don't want to modify the math
4628# function, it is called to close the @math command and we don't want
4629# it to be the turned to the default one when calling
4630# FIXME maybe it would be even better not to duplicate default styles in
4631# math, like 'email', 'uref'....
4632foreach my $command (keys(%special_style), 'math')
4633{
4634   delete $default_style_tex_math_map{$command};
4635   delete $default_style_latex_math_map{$command};
4636}
4637
4638foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents))
4639{
4640     $default_style_latex_map{$accent_command} = { 'function' => \&default_tex_accent };
4641     $default_style_tex_map{$accent_command} = { 'function' => \&default_tex_accent };
4642     $default_style_tex_math_map{$accent_command} = { 'function' => \&default_tex_math_accent };
4643     $default_style_latex_math_map{$accent_command} = { 'function' => \&default_latex_math_accent };
4644}
4645
4646my %tex_text_accent_map = (
4647 ',' => 'c',
4648 'ringaccent' => 'r',
4649 'dotaccent'  => '.',
4650 'ubaraccent' => 'b',
4651 'udotaccent' => 'd',
4652 'ogonek'     => 'k',
4653 'tieaccent'  => 'tie',
4654);
4655
4656sub default_tex_accent($$)
4657{
4658    my $text = shift;
4659    my $accent = shift;
4660    return "\\$tex_text_accent_map{$accent}\{$text\}" if ($tex_text_accent_map{$accent});
4661    if ($accent eq 'dotless')
4662    {
4663        return "\\$text" if ($text eq 'i' or $text eq 'j');
4664        return $text;
4665    }
4666    return "\\$accent\{$text\}";
4667}
4668
4669my %tex_math_accent_map = (
4670 "'" => 'acute',
4671 '^' => 'hat',
4672 '`' => 'grave',
4673 '~' => 'tilde',
4674 '"' => 'ddot',
4675 '=' => 'bar',
4676 'dotaccent'  => 'dot',
4677 'u' => 'breve',
4678 'ubaraccent' => 'underline',
4679);
4680
4681sub default_latex_math_accent($$)
4682{
4683    my $text = shift;
4684    my $accent = shift;
4685    return '\mathring{'.$text.'}' if ($accent eq 'ringaccent');
4686    return default_tex_math_accent($text, $accent);
4687}
4688
4689sub default_tex_math_accent($$)
4690{
4691    my $text = shift;
4692    my $accent = shift;
4693    return "\\$tex_text_accent_map{$accent}\{$text\}" if ($tex_text_accent_map{$accent});
4694    if ($accent eq 'dotless')
4695    {
4696        return "\\${text}math" if ($text eq 'i' or $text eq 'j');
4697        return $text;
4698    }
4699    return ascii_accent($text, $accent);
4700}
4701
4702my $kept_normal_text;
4703
4704# We assume that in @math the TeX characters have already been
4705# rightly protected and so don't protect once more.
4706sub default_tex_normal_math_text($$$$$$$;$)
4707{
4708   my @initial_args = @_;
4709   my $text = shift;
4710   my $in_raw_text = shift; # remove_texi
4711   my $in_preformatted = shift;
4712   my $in_code = shift;
4713   my $in_math = shift;
4714   my $in_simple = shift;
4715   my $style_stack = shift;
4716   my $state = shift;
4717
4718   # Don't protect text in math
4719   if ($in_math)
4720   {
4721       $text = uc($text) if (in_cmd($style_stack, 'sc'));
4722       return $text;
4723   }
4724   return &kept_normal_text(@initial_args);
4725}
4726
4727# This is the entry point to be used by users.
4728sub default_load_tex_math(;$)
4729{
4730   my $style = shift;
4731   $style = 'latex' if (!defined($style));
4732   %simple_map_math = %tex_default_simple_map_math;
4733   if ($style eq 'tex')
4734   {
4735      %math_map = %tex_default_math_things_map;
4736      t2h_default_copy_style_map(\%default_style_tex_math_map, \%style_map_math);
4737   }
4738   else
4739   {
4740      %math_map = %latex_default_math_things_map;
4741      t2h_default_copy_style_map(\%default_style_latex_math_map, \%style_map_math);
4742   }
4743   $kept_normal_text = $normal_text;
4744   $normal_text = \&default_tex_normal_math_text;
4745}
4746
4747# End TeX/LaTeX styles
4748#################################################################
4749
4750# regions expanded or not depending on the value of this hash.
4751# @EXPAND sets entries in this hash, and you should better use
4752# @EXPAND unless you know what you are doing.
4753%texi_formats_map = (
4754     'iftex' => 0,
4755     'ignore' => 0,
4756     'menu' => 0,
4757     'ifplaintext' => 0,
4758     'ifinfo' => 0,
4759     'ifxml' => 0,
4760     'ifhtml' => 0,
4761     'ifdocbook' => 0,
4762#     'html' => 0,
4763#     'tex' => 0,
4764#     'xml' => 0,
4765#     'docbook' => 0,
4766     'titlepage' => 1,
4767     'documentdescription' => 1,
4768     'copying' => 1,
4769     'ifnothtml' => 1,
4770     'ifnottex' => 1,
4771     'ifnotplaintext' => 1,
4772     'ifnotinfo' => 1,
4773     'ifnotxml' => 1,
4774     'ifnotdocbook' => 1,
4775     'direntry' => 'normal',
4776     'verbatim' => 'raw',
4777     'macro' => 'raw',
4778     'ifclear' => 'value',
4779     'ifset' => 'value' ,
4780     );
4781
4782%format_map = (
4783#       'quotation'   =>  'blockquote',
4784       # lists
4785#       'itemize'     =>  'ul',
4786       'enumerate'   =>  '',
4787#       'multitable'  =>  'table',
4788       'table'       =>  '',
4789       'vtable'      =>  '',
4790       'ftable'      =>  '',
4791       'group'       =>  '',
4792       'raggedright'       =>  '',
4793#       'detailmenu'  =>  '',
4794       );
4795
4796%special_list_commands = (
4797       'table'        =>  {},
4798       'vtable'       =>  {},
4799       'ftable'       =>  {},
4800#       'itemize'      =>  { 'bullet'  => '' }
4801       'itemize'      =>  {},
4802       );
4803
4804%inter_item_commands = (
4805  'c' => 1,
4806  'comment' => 1,
4807  'cindex' => 1
4808);
4809#
4810# texinfo format to align attribute of paragraphs
4811#
4812
4813%paragraph_style = (
4814      'center'     => 'center',
4815      'flushleft'  => 'left',
4816      'flushright' => 'right',
4817      );
4818
4819# complex formats (preformatted)
4820%complex_format_map = ();
4821foreach my $complex_format ('example', 'smallexample', 'display',
4822  'smalldisplay', 'lisp', 'smalllisp', 'format', 'smallformat',
4823  'menu', 'detailmenu', 'direntry', 'menu_comment')
4824{
4825    $complex_format_map{$complex_format} = { 'begin' => '', 'end' => '' };
4826}
4827foreach my $code_complex_format ('example', 'smallexample', 'lisp', 'smalllisp')
4828{
4829    $complex_format_map{$code_complex_format}->{'style'} = 'code';
4830}
4831
4832# not in code_style, according to post on bug-texinfo
4833foreach my $format ('menu', 'detailmenu', 'direntry')
4834{
4835   $complex_format_map{$format}->{'class'} = 'menu-preformatted';
4836}
4837
4838# not in code_style, according to post on bug-texinfo
4839$complex_format_map{'menu_comment'}->{'class'} = 'menu-comment';
4840
4841%def_map = (
4842    # basic commands
4843    'deffn', [ 'f', 'category', 'name', 'arg' ],
4844    'defvr', [ 'v', 'category', 'name' ],
4845    'deftypefn', [ 'f', 'category', 'type', 'name', 'argtype' ],
4846    'deftypeop', [ 'f', 'category', 'class' , 'type', 'name', 'argtype' ],
4847    'deftypevr', [ 'v', 'category', 'type', 'name' ],
4848    'defcv', [ 'v', 'category', 'class' , 'name' ],
4849    'deftypecv', [ 'v', 'category', 'class' , 'type', 'name' ],
4850    'defop', [ 'f', 'category', 'class' , 'name', 'arg' ],
4851    'deftp', [ 't', 'category', 'name', 'argtype' ],
4852    # shortcuts
4853    # FIXME i18n
4854    'defun', 'deffn Function',
4855    'defmac', 'deffn Macro',
4856    'defspec', 'deffn {Special Form}',
4857    'defvar', 'defvr Variable',
4858    'defopt', 'defvr {User Option}',
4859    'deftypefun', 'deftypefn {Function}',
4860    'deftypevar', 'deftypevr Variable',
4861    'defivar', 'defcv {Instance Variable}',
4862    'deftypeivar', 'deftypecv {Instance Variable}',
4863    'defmethod', 'defop Method',
4864    'deftypemethod', 'deftypeop Method',
4865         );
4866
4867$def_always_delimiters = "()[]";
4868$def_in_type_delimiters = ",;";
4869$def_argument_separator_delimiters = "()[],";
4870
4871# basic x commands
4872foreach my $key (keys(%def_map))
4873{
4874    $def_map{$key . 'x'} = $def_map{$key};
4875}
4876
4877#
4878# miscalleneous commands
4879#
4880# Depending on the value, the command arg or spaces following the command
4881#     are handled differently:
4882#
4883# the value is a reference on a hash.
4884# the hash keys are
4885#    'arg'  if the value is 'line' then the remaining of the line is the arg
4886#           if it is a number it is the number of args (separated by spaces)
4887#    'skip' if the value is 'line' then the remaining of the line is skipped
4888#           if the value is 'space' space but no newline is skipped
4889#           if the value is 'whitespace' space is skipped
4890#           if the value is 'linewhitespace' space is skipped if there are
4891#                 only spaces remaining on the line
4892#           if the value is 'linespace' space but no newline is skipped if
4893#                 there are only spaces remaining on the line
4894#    'keep' if true the args and the macro are kept, otherwise the macro
4895#          args and skipped stuffs are removed
4896%misc_command = (
4897        'bye' => {'skip' => 'line'}, # no arg
4898        # set, clear
4899        'set' => {'skip' => 'line'}, # special arg
4900        'clear' => {'skip' => 'line'}, # special arg
4901        'alias' => {'args' => 3, 'skip' => 'line'}, # special arg
4902        # comments
4903        'comment' => {'arg' => 'line'},
4904        'c' => {'arg' => 'line'},
4905
4906        # not needed for formatting
4907        'raisesections' => {'skip' => 'line'},  # no arg
4908        'lowersections' => {'skip' => 'line'}, # no arg
4909        'contents' => {}, # no arg
4910        'shortcontents' => {}, # no arg
4911        'summarycontents'=> {}, # no arg
4912        'setcontentsaftertitlepage' => {}, # no arg
4913        'setshortcontentsaftertitlepage' => {}, # no arg
4914#        'detailmenu' => {'skip' => 'whitespace'}, # no arg
4915#        'end detailmenu' => {'skip' => 'whitespace'}, # no arg
4916        'clickstyle' => {'skip' => 'line'}, # arg should be an @-command
4917        # in preamble
4918        'novalidate' => {}, # no arg
4919        'dircategory'=> {'arg' => 'line'}, # line. Position with regard
4920                         # with direntry is significant
4921        'pagesizes' => {'skip' => 'line', 'arg' => 'line'}, # can have 2 args
4922                                 # or one? 200mm,150mm 11.5in
4923        'finalout' => {'skip' => 'line'}, # no arg
4924        'paragraphindent' => {'skip' => 'line', 'arg' => 1}, # arg none asis
4925                             # or a number and forbids anything else on the line
4926        'firstparagraphindent' => {'skip' => 'line', 'arg' => 1}, # none insert
4927        'frenchspacing' => {'arg' => 1, 'skip' => 'line'}, # on off
4928                                       # not so sure about 'skip' => 'line'
4929        'fonttextsize' => {'arg' => 1}, # 10 11
4930        'allowcodebreaks' => {'arg' => 1, 'skip' => 'line'}, # false or true
4931        'exampleindent' => {'skip' => 'line', 'arg' => 1}, # asis or a number
4932        'footnotestyle'=> {'skip' => 'line', 'arg' => 1}, # end and separate
4933                                 # and nothing else on the line
4934        'afourpaper' => {'skip' => 'line'}, # no arg
4935        'afivepaper' => {'skip' => 'line'}, # no arg
4936        'afourlatex' => {'skip' => 'line'}, # no arg
4937        'afourwide' => {'skip' => 'line'}, # no arg
4938        'headings'=> {'skip' => 'line', 'arg' => 1},
4939                    #off on single double singleafter doubleafter
4940                    # interacts with setchapternewpage
4941        'setchapternewpage' => {'skip' => 'line', 'arg' => 1}, # off on odd
4942        'everyheading' => {'arg' => 'line'},
4943        'everyfooting' => {'arg' => 'line'},
4944        'evenheading' => {'arg' => 'line'},
4945        'evenfooting' => {'arg' => 'line'},
4946        'oddheading' => {'arg' => 'line'},
4947        'oddfooting' => {'arg' => 'line'},
4948        'smallbook' => {'skip' => 'line'}, # no arg
4949        'setfilename' => {'arg' => 'line'},
4950        'definfoenclose' => {'arg' => 'line'},
4951        #'shorttitle' => {'arg' => 'line', 'texi' => 1},
4952        #'shorttitlepage' => {'arg' => 'line', 'texi' => 1},
4953        #'settitle' => {'arg' => 'line', 'texi' => 1},
4954        #'author' => {'arg' => 'line', 'texi' => 1},
4955        #'subtitle' => {'arg' => 'line', 'texi' => 1},
4956        #'title' => {'arg' => 'line', 'texi' => 1},
4957        'shorttitle' => {'arg' => 'line'},
4958        'shorttitlepage' => {'arg' => 'line'},
4959        'settitle' => {'arg' => 'line'},
4960        'author' => {'arg' => 'line'},
4961        'subtitle' => {'arg' => 'line'},
4962        'title' => {'arg' => 'line'},
4963        'syncodeindex' => {'skip' => 'line', 'arg' => 2},
4964                          # args are index identifiers
4965        'synindex' => {'skip' => 'line', 'arg' => 2},
4966        'defindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg
4967        'defcodeindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg
4968        #'documentlanguage' => {'skip' => 'whitespace', 'arg' => 1},
4969        'documentlanguage' => {'skip' => 'line', 'arg' => 1},
4970                                                       # language code arg
4971        'kbdinputstyle' => {'skip' => 'whitespace', 'arg' => 1}, # code
4972                                                        #example distinct
4973        'everyheadingmarks' => {'skip' => 'line', 'arg' => 1}, # top bottom
4974        'everyfootingmarks' => {'skip' => 'whitespace', 'arg' => 1},
4975        'evenheadingmarks' => {'skip' => 'whitespace', 'arg' => 1},
4976        'oddheadingmarks' => {'skip' => 'whitespace', 'arg' => 1},
4977        'evenfootingmarks' => {'skip' => 'whitespace', 'arg' => 1},
4978        'oddfootingmarks' => {'skip' => 'whitespace', 'arg' => 1},
4979        'sp' => {'skip' => 'line', 'arg' => 1}, # no arg
4980                                    # at the end of line or a numerical arg
4981        # formatting
4982        'page' => {}, # no arg (pagebreak)
4983        'refill' => {}, # no arg (obsolete, to be ignored)
4984        'noindent' => {'skip' => 'whitespace'}, # no arg
4985        'indent' => {'skip' => 'whitespace'},
4986        'need' => {'skip' => 'line', 'arg' => 1}, # one numerical/real arg
4987        'exdent' => {'skip' => 'space'},
4988        # not valid for info (should be in @iftex)
4989        'vskip' => {'arg' => 'line'}, # arg line in TeX
4990        'cropmarks' => {}, # no arg
4991        # miscalleneous
4992        'verbatiminclude'=> {'skip' => 'line'},
4993        'documentencoding' => {'arg' => 1, 'skip' => 'line'},
4994        # ???
4995        'filbreak' => {},
4996        # obsolete @-commands. Remove spaces and end of lines after the
4997        # commands? If no, they can lead to empty lines
4998        'quote-arg' => {'skip' => 'line'},
4999        'allow-recursion' => {'skip' => 'line'},
5000     );
5001
5002my %misc_command_old = (
5003        # not needed for formatting
5004        'raisesections', 'line',  # no arg
5005        'lowersections', 'line', # no arg
5006        'contents', 1, # no arg
5007        'shortcontents', 1, # no arg
5008        'summarycontents', 1, # no arg
5009        'detailmenu', 'whitespace', # no arg
5010        'end detailmenu', 'whitespace', # no arg
5011        #'end detailmenu', 1, # no arg
5012        'novalidate', 1, # no arg
5013        'bye', 'line', # no arg
5014        # comments
5015        'comment', 'line',
5016        'c', 'line',
5017        # in preamble
5018        'dircategory', 'line', # line. Position with regard with direntry is
5019                               # significant
5020        'pagesizes', 'line arg2', # can have 2 args
5021        'finalout', 1, # no arg
5022        'paragraphindent', 'line arg1', # in fact accepts only none asis
5023                             # or a number and forbids anything else on the line
5024        'firstparagraphindent', 'line arg1', # in fact accepts only none insert
5025        'exampleindent', 'line arg1', # in fact accepts only asis or a number
5026        'footnotestyle', 'line arg1', # in fact accepts only end and separate
5027                                 # and nothing else on the line
5028        'afourpaper', 'line', # no arg
5029        'afourlatex', 'line', # no arg
5030        'afourwide', 'line',  # no arg
5031        'headings', 'line', # one arg, possibilities are
5032                    #off on single double singleafter doubleafter
5033                    # interacts with setchapternewpage
5034        'setchapternewpage', 'line', # no arg
5035        'everyheading', 'line',
5036        'everyfooting', 'line',
5037        'evenheading', 'line',
5038        'evenfooting', 'line',
5039        'oddheading', 'line',
5040        'oddfooting', 'line',
5041        'smallbook', 'line', # no arg
5042        'setfilename', 'line',
5043        'shorttitle', 'linetexi',
5044        'shorttitlepage', 'linetexi',
5045        'settitle', 'linetexi',
5046        'author', 'linetexi',
5047        'subtitle', 'linetexi',
5048        'title','linetexi',
5049        'syncodeindex','linespace arg2', # args are
5050        'synindex','linespace arg2',
5051        'defindex', 'line arg1', # one identifier arg
5052        'defcodeindex', 'line arg1', # one identifier arg
5053        'documentlanguage', 'whitespace arg1', # one language code arg
5054        'kbdinputstyle', 'whitespace arg1', # one arg within
5055                                 #code example distnct
5056        'sp', 'whitespace arg1', # no arg at the en of line or a numerical arg
5057        # formatting
5058        'page', 1, # no arg (pagebreak)
5059        'refill', 1, # no arg (obsolete, to be ignored))
5060        'noindent', 'space', # no arg
5061        'need', 'line arg1', # one numerical/real arg
5062        'exdent', 'space',
5063        # not valid for info (should be in @iftex)
5064        'vskip', 'line', # arg line in TeX
5065        'cropmarks', 1, # no arg
5066        # miscalleneous
5067        'verbatiminclude', 'line',
5068        'documentencoding', 'arg1',
5069        # ???
5070        'filbreak', 1,
5071     );
5072
5073# The command_handler arrays are for commands formatted externally.
5074# The function references in @command_handler_init are called
5075# before the second pass, before the @-commands text collection.
5076# Those in @command_handler_process are called between the second pass
5077# and the third pass, after collection of @-commands text and before their
5078# expansion.
5079# Those in @command_handler_process are called after the third pass,
5080# after the document generation.
5081@command_handler_setup = ();
5082@command_handler_init = ();
5083@command_handler_names = ();
5084@command_handler_process = ();
5085@command_handler_output = ();
5086@command_handler_finish = ();
5087
5088
5089sub t2h_default_push_handler($$)
5090{
5091   my $function = shift;
5092   my $handlers = shift;
5093   push @$handlers, $function unless (grep {$_ eq $function} @$handlers);
5094}
5095
5096# the keys of %command_handler are @-command names and the value
5097# is a hash reference with the following keys:
5098# 'init'          function reference used to collect the @-command text
5099# 'expand'        function reference used when expanding the @-command text
5100%command_handler = ();
5101
5102
5103# formatting functions
5104
5105$anchor            = \&t2h_default_anchor;
5106$def_item          = \&t2h_default_def_item;
5107$def               = \&t2h_default_def;
5108$menu_command      = \&t2h_default_menu_command;
5109$menu_link         = \&t2h_default_menu_link;
5110#$menu_comment      = \&t2h_default_menu_comment;
5111$menu_description  = \&t2h_default_menu_description;
5112#$simple_menu_link  = \&t2h_default_simple_menu_link;
5113$table_item        = \&t2h_default_table_item;
5114$table_line        = \&t2h_default_table_line;
5115$table_list        = \&t2h_default_table_list;
5116$row               = \&t2h_default_row;
5117$cell              = \&t2h_default_cell;
5118$list_item         = \&t2h_default_list_item;
5119$comment           = \&t2h_default_comment;
5120$def_line          = \&t2h_default_def_line;
5121$def_line_no_texi  = \&t2h_default_def_line_no_texi;
5122$raw               = \&t2h_default_raw;
5123$raw_no_texi       = \&t2h_default_raw_no_texi;
5124$heading           = \&t2h_default_heading;
5125$heading_text      = \&t2h_default_heading_text;
5126$heading_text_preformatted      = \&t2h_default_heading_text_preformatted;
5127$element_heading   = \&t2h_default_element_heading;
5128$heading_no_texi   = \&t2h_default_heading_no_texi;
5129$external_href     = \&t2h_default_external_href;
5130$paragraph         = \&t2h_default_paragraph;
5131$preformatted      = \&t2h_default_preformatted;
5132$foot_line_and_ref = \&t2h_default_foot_line_and_ref;
5133$foot_section      = \&t2h_default_foot_section;
5134$image_files       = \&t2h_default_image_files;
5135$image             = \&t2h_default_image;
5136$index_entry_label = \&t2h_default_index_entry_label;
5137$index_summary     = \&t2h_default_index_summary;
5138$summary_letter    = \&t2h_default_summary_letter;
5139$index_entry       = \&t2h_default_index_entry;
5140$index_entry_command = \&t2h_default_index_entry_command;
5141$index_letter      = \&t2h_default_index_letter;
5142#$printindex       = \&t2h_default_printindex;
5143$print_index       = \&t2h_default_print_index;
5144$protect_text      = \&t2h_default_protect_text;
5145$normal_text       = \&t2h_default_normal_text;
5146$cartouche         = \&t2h_default_cartouche;
5147$sp                = \&t2h_default_sp;
5148$definition_category      = \&t2h_default_definition_category;
5149$definition_index_entry   = \&t2h_default_definition_index_entry;
5150$copying_comment          = \&t2h_default_copying_comment;
5151$documentdescription      = \&t2h_default_documentdescription;
5152$index_summary_file_entry = \&t2h_default_index_summary_file_entry;
5153$index_summary_file_end   = \&t2h_default_index_summary_file_end;
5154$index_summary_file_begin = \&t2h_default_index_summary_file_begin;
5155$empty_line               = \&t2h_default_empty_line;
5156$float                     = \&t2h_default_float;
5157$listoffloats             = \&t2h_default_listoffloats;
5158$listoffloats_entry       = \&t2h_default_listoffloats_entry;
5159$listoffloats_caption     = \&t2h_default_listoffloats_caption;
5160$listoffloats_float_style = \&t2h_default_listoffloats_float_style;
5161$listoffloats_style       = \&t2h_default_listoffloats_style;
5162$acronym_like             = \&t2h_default_acronym_like;
5163$quotation                = \&t2h_default_quotation;
5164$paragraph_style_command  = \&t2h_default_paragraph_style_command;
5165$heading_texi             = \&t2h_default_heading_texi;
5166$index_element_heading_texi = \&t2h_default_index_element_heading_texi;
5167$element_label              = \&t2h_default_element_label;
5168$anchor_label               = \&t2h_default_anchor_label;
5169$preserve_misc_command      = \&t2h_default_preserve_misc_command;
5170$format_list_item_texi      = \&t2h_default_format_list_item_texi;
5171$begin_format_texi          = \&t2h_default_begin_format_texi;
5172$insertcopying              = \&t2h_default_insertcopying;
5173$simple_command             = \&t2h_default_simple_command;
5174$thing_command              = \&t2h_default_thing_command;
5175$line_command               = \&t2h_default_line_command;
5176$internal_links             = \&t2h_default_internal_links;
5177
5178# address is not used anymore
5179$address           = \&t2h_default_address;
5180
5181# return the line after preserving things according to misc_command map.
5182# You should not change it. It is here, nevertheless, to be used
5183# in other function references if needed.
5184sub t2h_default_preserve_misc_command($$)
5185{
5186    my $line = shift;
5187    my $macro = shift;
5188    my $text = '';
5189    my $args = [];
5190    my $skip_spec = '';
5191    my $arg_spec = '';
5192
5193#print STDERR "HHHHHHHHH $line $macro\n";
5194    $skip_spec = $misc_command{$macro}->{'skip'}
5195        if (defined($misc_command{$macro}->{'skip'}));
5196    $arg_spec = $misc_command{$macro}->{'arg'}
5197        if (defined($misc_command{$macro}->{'arg'}));
5198
5199    if ($arg_spec eq 'line')
5200    {
5201        $text .= $line;
5202        $args = [ $line ];
5203        $line = '';
5204    }
5205    elsif ($arg_spec)
5206    {
5207        my $arg_nr = $misc_command{$macro}->{'arg'};
5208        while ($arg_nr)
5209        {
5210            $line =~ s/(\s+\S*)//o;
5211            my $argument = $1;
5212            if (defined($argument))
5213            {
5214                $text .= $argument;
5215                push @$args, $argument;
5216            }
5217            $arg_nr--;
5218        }
5219    }
5220
5221    if ($macro eq 'bye')
5222    {
5223        $line = '';
5224        $text = "\n";
5225    }
5226    elsif ($skip_spec eq 'linespace')
5227    {
5228        if ($line =~ /^\s*$/o)
5229        {
5230            $line =~ s/([ \t]*)//o;
5231            $text .= $1;
5232        }
5233    }
5234    elsif ($skip_spec eq 'linewhitespace')
5235    {
5236        if ($line =~ /^\s*$/o)
5237        {
5238            $text .= $line;
5239            $line = '';
5240        }
5241    }
5242    elsif ($skip_spec eq 'line')
5243    {
5244        $text .= $line;
5245        $line = '';
5246    }
5247    elsif ($skip_spec eq 'whitespace')
5248    {
5249        $line =~ s/(\s*)//o;
5250        $text .=  $1;
5251    }
5252    elsif ($skip_spec eq 'space')
5253    {
5254        $line =~ s/([ \t]*)//o;
5255        $text .= $1;
5256    }
5257    $line = '' if (!defined($line));
5258    return ($line, $text, $args);
5259}
5260
5261sub t2h_default_simple_command($$$$$)
5262{
5263    my $command = shift;
5264    my $in_preformatted = shift;
5265    my $in_math = shift;
5266    my $line_nr = shift;
5267    my $state = shift;
5268
5269    if ($in_math)
5270    {
5271        my $result = $simple_map_pre{$command};
5272        $result = $simple_map_math{$command} if (defined($simple_map_math{$command}));
5273        return $result;
5274    }
5275    elsif ($in_preformatted)
5276    {
5277        return $simple_map_pre{$command};
5278    }
5279    else
5280    {
5281        return $simple_map{$command};
5282    }
5283}
5284
5285sub t2h_default_thing_command($$$$$$)
5286{
5287    my $command = shift;
5288    my $text = shift;
5289    my $in_preformatted = shift;
5290    my $in_math = shift;
5291    my $line_nr = shift;
5292    my $state = shift;
5293
5294    my $result;
5295    if ($in_math)
5296    {
5297        $result = $pre_map{$command};
5298        $result = $math_map{$command} if (defined($math_map{$command}));
5299    }
5300    elsif ($in_preformatted)
5301    {
5302        $result = $pre_map{$command};
5303    }
5304    else
5305    {
5306        $result = $things_map{$command};
5307    }
5308    return $result . $text;
5309}
5310
5311# this is called each time a format begins. Here it is used to keep a
5312# record of the multitables to have a faithful count of the cell nr.
5313sub t2h_default_begin_format_texi($$$)
5314{
5315    my $command = shift;
5316    my $line = shift;
5317    my $state = shift;
5318
5319   # remove space in front of center, unless it removes the end of line!
5320    $line =~ s/^\s*// if ($command eq 'center' and $line =~ /\S/);
5321    return $line;
5322}
5323
5324# This function is called whenever a complex format is processed
5325#
5326# arguments:
5327# name of the format
5328# text appearing inside the format
5329#
5330# an eval of $complex_format->{format name}->{'begin'} should lead to the
5331# beginning of the complex format, an eval of
5332# $complex_format->{format name}->{'end'}  should lead to the end of the
5333# complex format.
5334sub t2h_default_complex_format($$)
5335{
5336    my $name = shift;
5337    my $text = shift;
5338    return '' if ($text eq '');
5339    return '' if ($name eq 'direntry');
5340    my $beginning;
5341    my $end;
5342    # FIXME obsoleted in nov 2009
5343    if (exists($complex_format_map->{$name}))
5344    {
5345        $beginning = eval "$complex_format_map->{$name}->{'begin'}";
5346        if ($@ ne '')
5347        {
5348            main::msg_debug("Evaluation of $complex_format_map->{$name}->{'begin'}: $@");
5349            $beginning = '';
5350
5351        }
5352        $end = eval "$complex_format_map->{$name}->{'end'}";
5353        if ($@ ne '')
5354        {
5355            main::msg_debug("Evaluation of $complex_format_map->{$name}->{'end'}: $@");
5356            $end = '';
5357        }
5358    }
5359    else
5360    {
5361        $beginning = $complex_format_map{$name}->{'begin'};
5362        $beginning = '' if (!defined($beginning));
5363        $end = $complex_format_map{$name}->{'end'};
5364        $end = '' if (!defined($end));
5365    }
5366    return $beginning . $text . $end;
5367}
5368
5369sub t2h_default_empty_line($$)
5370{
5371    my $text = shift;
5372    my $state = shift;
5373    #ignore the line if it just follows a deff
5374    return '' if ($state->{'deff_line'});
5375    return $text;
5376}
5377
5378sub t2h_default_unknown($$$$$)
5379{
5380    my $macro = shift;
5381    my $line = shift;
5382    my $pass = shift;
5383    my $stack = shift;
5384    my $state = shift;
5385
5386    my ($result_line, $result, $result_text, $message);
5387    return ($line, 0, undef, undef);
5388}
5389
5390sub t2h_default_unknown_style($$$$$)
5391{
5392    my $command = shift;
5393    my $text = shift;
5394    my $state = shift;
5395    my $no_close = shift;
5396    my $no_open = shift;
5397
5398    my ($result, $result_text, $message);
5399    return (0, undef, undef);
5400}
5401
5402sub t2h_default_caption_shortcaption($)
5403{
5404    my $float = shift;
5405    my $caption_lines;
5406    my $shortcaption_lines;
5407    my $style = $float->{'style_texi'};
5408    if (defined($float->{'nr'}))
5409    {
5410        my $nr = $float->{'nr'};
5411        if ($style ne '')
5412        {
5413            $style = gdt('{style} {number}', { 'style' => $style, 'number' => $nr});
5414        }
5415        else
5416        {
5417            $style = $nr;
5418        }
5419    }
5420    my $empty_caption = 1;
5421    if (defined($float->{'caption_texi'}) and @{$float->{'caption_texi'}})
5422    {
5423        @$caption_lines = @{$float->{'caption_texi'}};
5424        $caption_lines->[0] =~ s/^\s*//;
5425        if ($caption_lines->[0] =~ /\S/ or @$caption_lines > 2)
5426        {
5427            $empty_caption = 0;
5428        }
5429    }
5430
5431    if (!$empty_caption)
5432    {
5433        if (defined($style))
5434        {
5435            $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . gdt('{style}: {caption_first_line}', { 'style' => $style, 'caption_first_line' => $caption_lines->[0] });
5436        }
5437        else
5438        {
5439            $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' .  $caption_lines->[0];
5440        }
5441        push @$caption_lines, "}\n";
5442    }
5443    elsif (defined($style))
5444    {
5445        $caption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $style . '}' . "\n";
5446    }
5447
5448    my $empty_shortcaption = 1;
5449    if (defined($float->{'shortcaption_texi'}) and @{$float->{'shortcaption_texi'}})
5450    {
5451        @$shortcaption_lines = @{$float->{'shortcaption_texi'}};
5452        $shortcaption_lines->[0] =~ s/^\s*//;
5453        if ($shortcaption_lines->[0] =~ /\S/ or @$shortcaption_lines > 1)
5454        {
5455            $empty_shortcaption = 0;
5456        }
5457    }
5458
5459    if (!$empty_shortcaption)
5460    {
5461         if (defined($style))
5462         {
5463              $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . gdt('{style}: {shortcaption_first_line}', { 'style' => $style, 'shortcaption_first_line' => $shortcaption_lines->[0] });
5464         }
5465         else
5466         {
5467              $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' .  $shortcaption_lines->[0];
5468         }
5469         push @$shortcaption_lines, "}\n";
5470    }
5471    elsif (defined($style))
5472    {
5473         $shortcaption_lines->[0] = '@'.$CAPTION_STYLE.'{' . $style . '}' . "\n";
5474    }
5475    return ($caption_lines, $shortcaption_lines);
5476}
5477
5478# everything is done in &$float
5479sub t2h_default_caption_shortcaption_command($$$$)
5480{
5481   my $command = shift;
5482   my $text = shift;
5483   my $texi_lines = shift;
5484   my $float_element = shift;
5485   return '';
5486}
5487
5488sub t2h_default_float($$$$$)
5489{
5490    my $text = shift;
5491    my $float = shift;
5492    my $caption = shift;
5493    my $shortcaption = shift;
5494
5495    my $label = '';
5496    if (exists($float->{'id'}))
5497    {
5498        $label = &$anchor($float->{'id'});
5499    }
5500    my $caption_text = '';
5501
5502    if (defined($float->{'caption_texi'}))
5503    {
5504        $caption_text = $caption;
5505    }
5506    elsif (defined($float->{'shortcaption_texi'}))
5507    {
5508        $caption_text = $shortcaption;
5509    }
5510    elsif (defined($caption))
5511    {
5512        $caption_text = $caption;
5513    }
5514
5515    return $text . "\n" . $caption_text;
5516}
5517
5518sub t2h_default_listoffloats_style($)
5519{
5520    my $style_texi = shift;
5521    return ($style_texi);
5522}
5523
5524sub t2h_default_listoffloats_float_style($$)
5525{
5526    my $style_texi = shift;
5527    my $float = shift;
5528
5529    my $style = $float->{'style_texi'};
5530    #print STDERR "listoffloat/float style mismatch $style_texi $style\n" if ($style_texi ne $style);
5531    if (defined($float->{'nr'}))
5532    {
5533         my $nr = $float->{'nr'};
5534         if ($style ne '')
5535         {
5536              $style = gdt('{style} {number}', { 'style' => $style, 'number' => $nr});
5537         }
5538         else
5539         {
5540              $style = $nr;
5541         }
5542    }
5543    return $style;
5544}
5545
5546sub t2h_default_listoffloats_caption($)
5547{
5548    my $float = shift;
5549    if (defined($float->{'shortcaption_texi'}))
5550    {
5551         return ([ @{$float->{'shortcaption_texi'}} ], 'shortcaption');
5552    }
5553    elsif (defined($float->{'caption_texi'}))
5554    {
5555         return ([ @{$float->{'caption_texi'}} ], 'caption');
5556    }
5557    return ([ ], undef);
5558}
5559
5560sub t2h_default_listoffloats_entry($$$$)
5561{
5562    my $style_texi = shift;
5563    my $float = shift;
5564    my $float_style = shift;
5565    my $caption = shift;
5566    my $href = shift;
5567
5568    my @lines = split /^/, $caption;
5569    $caption = $lines[0];
5570    $caption = '' if (!defined($caption));
5571    chomp ($caption);
5572
5573    $caption = $float->{'text'} if ($caption eq '' and defined($float->{'text'}) and $float->{'text'} =~ /\S/);
5574
5575    return  "* $float_style: ${caption}\n";
5576}
5577
5578sub t2h_default_listoffloats($$$)
5579{
5580    my $style_texi = shift;
5581    my $style = shift;
5582    my $float_entries = shift;
5583
5584    my $result = "* List of $style:\n";
5585    foreach my $float_entry (@$float_entries)
5586    {
5587         $result .= $float_entry;
5588    }
5589    return $result . "\n";
5590}
5591
5592sub t2h_default_insertcopying($$$)
5593{
5594    my $text = shift;
5595    my $comment = shift;
5596    my $simple_text = shift;
5597    return $text;
5598}
5599
5600sub t2h_default_protect_text($)
5601{
5602   my $text = shift;
5603   return $text;
5604}
5605
5606# This function is used to protect characters which are special in xml
5607# in inline text:  &, ", <, and >.
5608#
5609# argument:
5610# text to be protected
5611sub xml_default_protect_text($)
5612{
5613   my $text = shift;
5614   $text =~ s/&/&amp;/g;
5615   $text =~ s/</&lt;/g;
5616   $text =~ s/>/&gt;/g;
5617   $text =~ s/\"/&quot;/g;
5618   return $text;
5619}
5620
5621sub in_cmd($$)
5622{
5623   my $style_stack = shift;
5624   my $command = shift;
5625   my $result = 0;
5626   if ($style_stack and scalar(@{$style_stack}))
5627   {
5628       my $level = $#$style_stack;
5629       #print STDERR ":::$level ::@{$style_stack}\n";
5630       while ($level >= 0)
5631       {
5632           if ($style_stack->[$level] eq $command)
5633           {
5634               $result = 1;
5635               last;
5636           }
5637           $level--;
5638       }
5639   }
5640   return $result;
5641}
5642#
5643#
5644
5645sub in_small_caps($)
5646{
5647   my $style_stack = shift;
5648   my $in_sc = 0;
5649   if ($style_stack and scalar(@{$style_stack}))
5650   {
5651       my $level = $#$style_stack;
5652       #print STDERR ":::$level ::@{$style_stack}\n";
5653       while ($level >= 0)
5654       {
5655           if ($style_stack->[$level] eq 'sc')
5656           {
5657               $in_sc = 1;
5658               last;
5659           }
5660           $level--;
5661       }
5662   }
5663   return $in_sc;
5664}
5665#
5666#
5667sub t2h_default_normal_text($$$$$$$;$)
5668{
5669   my @initial_args = @_;
5670   my $text = shift;
5671   my $in_raw_text = shift; # remove_texi
5672   my $in_preformatted = shift;
5673   my $in_code = shift;
5674   my $in_math = shift;
5675   my $in_simple = shift;
5676   my $style_stack = shift;
5677   my $state = shift;
5678
5679  # like utf8.init
5680   if ($ENABLE_ENCODING and !$ENABLE_ENCODING_USE_ENTITY and defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and $Texi2HTML::THISDOC{'ENCODING_NAME'} eq 'utf-8' and $USE_UNICODE)
5681   {
5682      return &t2h_utf8_normal_text(@initial_args);
5683   }
5684
5685   $text = uc($text) if (in_cmd($style_stack, 'sc'));
5686   if (! $in_code and !$in_preformatted)
5687   {
5688         $text =~ s/---/\x{1F}/g;
5689         $text =~ s/--/-/g;
5690         $text =~ s/\x{1F}/--/g;
5691         $text =~ s/``/"/g;
5692         $text =~ s/\'\'/"/g;
5693   }
5694   else
5695   {
5696       # to be like tex. This would be wrong, however.
5697#       my $special_code = 0;
5698#       $special_code = 1 if (in_cmd($style_stack, 'code') or
5699#           in_cmd($style_stack, 'example') or in_cmd($style_stack, 'verbatim'));
5700#       $text =~ s/'/\&rsquo\;/g unless ($special_code and exists($main::value{'txicodequoteundirected'}));
5701#       $text =~ s/`/\&lsquo\;/g unless ($special_code and exists($main::value{'txicodequotebacktick'}));
5702   }
5703   $text = t2h_text_substitutions($text, $in_raw_text, ($in_preformatted or $in_code), $in_simple);
5704   return $text;
5705}
5706
5707sub t2h_default_url_and_text($;$)
5708{
5709    my $url = shift;
5710    my $text = shift;
5711    if (!defined($text) or $text eq '')
5712    {
5713       return "<$url>" if (defined($url) and $url ne '');
5714       return '';
5715    }
5716    else
5717    {
5718        return $text if (!defined($url) or $url eq '');
5719        return "$text <$url>";
5720    }
5721}
5722
5723# This function produces an anchor. This need is quite html specific.
5724#
5725# arguments:
5726# $name           :   anchor name
5727# $href           :   anchor href
5728# text            :   text displayed
5729# extra_attribs   :   added to anchor attributes list
5730sub t2h_default_anchor($;$$$)
5731{
5732    my $name = shift;
5733    my $href = shift;
5734    my $text = shift;
5735    my $attributes = shift;
5736    return $text if (defined($text));
5737    return '';
5738}
5739
5740# This function is used to format the text associated with a @deff/@end deff
5741#
5742# argument:
5743# text
5744#
5745# $DEF_TABLE should be used to distinguish between @def formatted as table
5746# and as definition lists.
5747sub t2h_default_def_item($$$)
5748{
5749    my $text = shift;
5750    my $only_inter_item_commands = shift;
5751    my $command = shift;
5752    if ($text =~ /\S/)
5753    {
5754        return $text;
5755    }
5756    return '';
5757}
5758
5759sub t2h_default_definition_category($$$$)
5760{
5761    my $name = shift;
5762    my $class = shift;
5763    my $style = shift;
5764    my $command = shift;
5765    return ($name) if (!defined($class) or $class =~ /^\s*$/);
5766    if ($style eq 'f')
5767    {
5768        return gdt('{name} on {class}', { 'name' => $name, 'class' => $class });
5769    }
5770    elsif ($style eq 'v')
5771    {
5772        return gdt('{name} of {class}', { 'name' => $name, 'class' => $class });
5773    }
5774    else
5775    {
5776        return $name;
5777    }
5778}
5779
5780sub t2h_default_definition_index_entry($$$$)
5781{
5782    my $name = shift;
5783    my $class = shift;
5784    my $style = shift;
5785    my $command = shift;
5786    return ($name) if (!defined($class) or $class =~ /^\s*$/);
5787    if ($style eq 'f')
5788    {
5789        return gdt('{name} on {class}', { 'name' => $name, 'class' => $class });
5790    }
5791    elsif ($style eq 'v' and $command ne 'defcv')
5792    {
5793        return gdt('{name} of {class}', { 'name' => $name, 'class' => $class });
5794    }
5795    else
5796    {
5797        return $name;
5798    }
5799}
5800
5801sub t2h_default_summary_letter($$$$$$$)
5802{
5803   my $letter = shift;
5804   my $file = shift;
5805   my $default_identifier = shift;
5806   my $index_element_id = shift;
5807   my $number = shift;
5808   my $index_element = shift;
5809   my $index_name = shift;
5810
5811   return '';
5812}
5813
5814
5815# format the container for the @deffn line and text
5816#
5817# argument
5818# text of the whole @def, line and associated text.
5819#
5820# $DEF_TABLE should be used.
5821sub t2h_default_def($$)
5822{
5823    my $text = shift;
5824    my $command = shift;
5825    if ($text =~ /\S/)
5826    {
5827        return $text;
5828    }
5829    return '';
5830
5831}
5832
5833# a whole menu
5834#
5835# argument:
5836# the whole menu text (entries and menu comments)
5837#
5838# argument:
5839# whole menu text.
5840# not used since menu is a normal preformatted command with SIMPLE_MENU
5841sub t2h_default_menu_command($$$)
5842{
5843    my $format = shift;
5844    my $text = shift;
5845    my $in_preformatted = shift;
5846    return "* Menu:\n".$text."\n";
5847
5848}
5849
5850# formats a menu entry link pointing to a node or section
5851#
5852# arguments:
5853# the entry text
5854# the state, a hash reference holding informations about the context, with a
5855#     usefull entry, 'preformatted', true if we are in a preformatted format
5856#     (a format keeping space between words). In that case a function
5857#     of the main program, main::do_preformatted($text, $state) might
5858#     be used to format the text with the current format style.
5859# href is optionnal. It is the reference to the section or the node anchor
5860#     which should be used to make the link (typically it is the argument
5861#     of a href= attribute in a <a> element).
5862sub t2h_default_menu_link($$$$$$$$)
5863{
5864    my $entry = shift;
5865    my $state = shift;
5866    my $href = shift;
5867    my $node = shift;
5868    my $title = shift;
5869    my $ending = shift;
5870    my $has_title = shift;
5871    my $command_stack = shift;
5872    my $preformatted = shift;
5873
5874    $title = '' unless ($has_title);
5875    $title .= ':' if ($title ne '');
5876    return "$MENU_SYMBOL$title$node$ending" if ($NODE_NAME_IN_MENU);
5877    return "$MENU_SYMBOL$title$entry$ending";
5878}
5879
5880# formats a menu entry description, ie the text appearing after the node
5881# specification in a menu entry an spanning until there is another
5882# menu entry, an empty line or some text at the very beginning of the line
5883# (we consider that text at the beginning of the line begins a menu comment)
5884#
5885# arguments:
5886# the description text
5887# the state. See menu_entry.
5888# the heading of the element associated with the node.
5889# not usd since in SIMPLE_MENU
5890sub t2h_default_menu_description($$$$)
5891{
5892    my $text = shift;
5893    my $state = shift;
5894    my $element_text = shift;
5895    my $command_stack = shift;
5896    my $preformatted = shift;
5897
5898    return $text;
5899}
5900
5901%htmlxref_entries = (
5902 'node' => [ 'node', 'section', 'chapter', 'mono' ],
5903 'section' => [ 'section', 'chapter','node', 'mono' ],
5904 'chapter' => [ 'chapter', 'section', 'node', 'mono' ],
5905 'mono' => [ 'mono', 'chapter', 'section', 'node' ],
5906);
5907
5908
5909# Construct a href to an external source of information.
5910# node is the node with texinfo @-commands
5911# node_id is the node transliterated and transformed as explained in the
5912#         texinfo manual
5913# node_xhtml_id is the node transformed such that it is unique and can
5914#     be used to make an html cross ref as explained in the texinfo manual
5915# file is the file in '(file)node'
5916# This is used to construct href, so is likely to be ignored oustside of
5917# html.
5918sub t2h_default_external_href($$$)
5919{
5920    my $node = shift;
5921    my $node_id = shift;
5922    my $node_xhtml_id = shift;
5923    my $file = shift;
5924    $file = '' if (!defined($file));
5925    my $default_target_split = $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'};
5926    my $target_split;
5927    #my $target_mono;
5928    #my $href_split;
5929    #my $href_mono;
5930    if ($file ne '')
5931    {
5932         if ($NEW_CROSSREF_STYLE)
5933         {
5934             $file =~ s/\.[^\.]*$//;
5935             $file =~ s/^.*\///;
5936             my $href;
5937             my $document_split = get_conf('SPLIT');
5938             $document_split = 'mono' if (!$document_split);
5939             my $split_found;
5940             if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}))
5941             {
5942                  foreach my $split_ordered (@{$htmlxref_entries{$document_split}})
5943                  {
5944                        if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}->{$split_ordered}))
5945                        {
5946                             $split_found = $split_ordered;
5947                             $href = $Texi2HTML::THISDOC{'htmlxref'}->{$file}->{$split_ordered}->{'href'};
5948                             last;
5949                        }
5950                  }
5951             }
5952             if (defined($split_found))
5953             {
5954                  $target_split = 1 unless ($split_found eq 'mono');
5955             }
5956             else
5957             { # nothing specified for that manual, use default
5958                  $target_split = $default_target_split;
5959             }
5960
5961             if ($target_split)
5962             {
5963                  if (defined($href))
5964                  {
5965                       $file = $href;
5966                  }
5967                  elsif (defined($EXTERNAL_DIR))
5968                  {
5969                       $file = "$EXTERNAL_DIR/$file";
5970                  }
5971                  elsif (get_conf('SPLIT'))
5972                  {
5973                       $file = "../$file";
5974                  }
5975                  $file .= "/";
5976             }
5977             else
5978             {# target not split
5979                  if (defined($href))
5980                  {
5981                       $file = $href;
5982                  }
5983                  else
5984                  {
5985                       if (defined($EXTERNAL_DIR))
5986                       {
5987                            $file = "$EXTERNAL_DIR/$file";
5988                       }
5989                       elsif (get_conf('SPLIT'))
5990                       {
5991                           $file = "../$file";
5992                       }
5993                       $file .= "." . $NODE_FILE_EXTENSION;
5994                  }
5995             }
5996         }
5997         else
5998         {
5999             $file .= "/";
6000             if (defined($EXTERNAL_DIR))
6001             {
6002                 $file = $EXTERNAL_DIR . $file;
6003             }
6004             else
6005             {
6006                 $file = '../' . $file;
6007             }
6008         }
6009    }
6010    else
6011    {
6012        $target_split = $default_target_split;
6013    }
6014    if ($node eq '')
6015    {
6016         if ($NEW_CROSSREF_STYLE)
6017         {
6018             if ($target_split)
6019             {
6020                 if (defined($TOP_NODE_FILE_TARGET))
6021                 {
6022                     return $file . $TOP_NODE_FILE_TARGET . '.' . $NODE_FILE_EXTENSION . '#Top';
6023                 }
6024                 else
6025                 {
6026                     return $file . '#Top';
6027                 }
6028             }
6029             else
6030             {
6031                  return $file . '#Top';
6032             }
6033         }
6034         else
6035         {
6036             return $file;
6037         }
6038    }
6039    my $target;
6040    if ($NEW_CROSSREF_STYLE)
6041    {
6042         $node = $node_id;
6043         $target = $node_xhtml_id;
6044    }
6045    else
6046    {
6047         $node = main::remove_texi($node);
6048         $node =~ s/[^\w\.\-]/-/g;
6049    }
6050    my $file_basename = $node;
6051    $file_basename = $TOP_NODE_FILE_TARGET if ($node =~ /^top$/i and defined($TOP_NODE_FILE_TARGET));
6052    if ($NEW_CROSSREF_STYLE)
6053    {
6054        if ($target_split)
6055        {
6056            return $file . $file_basename . ".$NODE_FILE_EXTENSION" . '#' . $target;
6057        }
6058        else
6059        {
6060            return $file . '#' . $target;
6061        }
6062    }
6063    else
6064    {
6065        return $file . $file_basename . ".$NODE_FILE_EXTENSION";
6066    }
6067}
6068
6069# format a reference external to the generated manual. This produces a full
6070# reference with introductive words and the reference itself.
6071#
6072# arguments:
6073# type of the reference: xref (reference at the beginning of a sentence),
6074#     pxref (reference in a parenthesis),
6075# section in the book. This might be undef.
6076# book name.
6077# manual file name
6078# href linking to the html page containing the referenced node. A typical
6079#     use for this href is a href attribute in an <a> element
6080# cross reference name
6081# array of texi arguments of the reference
6082# array of the formatted arguments of the reference
6083# node name
6084sub t2h_default_external_ref($$$$$$$$$)
6085{
6086    my $type = shift;
6087    my $section = shift;
6088    my $book = shift;
6089    my $file = shift;
6090    #my $file_node = shift;
6091    my $href = shift;
6092    my $cross_ref = shift;
6093    my $args_texi = shift;
6094    my $formatted_args = shift;
6095    my $node = shift;
6096
6097    my $name = $section;
6098    $name = $cross_ref if ($name eq '');
6099    $name = $node if ($name eq '');
6100
6101    my $reference = $name;
6102
6103    if ($book eq '' and $file ne '')
6104    {
6105       $name = "($file)$name";
6106    }
6107    $reference = &$anchor('', $href, $name) if ($href ne '');
6108
6109    # Yes, this is ugly, yet this helps internationalization
6110    if ($type eq 'pxref')
6111    {
6112         if (($book ne '') and ($href ne ''))
6113         {
6114              return gdt('see {reference} in @cite{{book}}', { 'reference' => $reference, 'book' => $book },{'duplicate'=>1});
6115         }
6116         elsif (($book ne '') and ($reference ne ''))
6117         {
6118              return gdt('see `{section}\' in @cite{{book}}', { 'section' => $reference, 'book' => $book },{'duplicate'=>1});
6119         }
6120         elsif ($book ne '')
6121         { # should seldom or even never happen
6122              return gdt('see @cite{{book}}', { 'book' => $book },{'duplicate'=>1});
6123         }
6124         elsif ($href ne '')
6125         {
6126              return gdt('see {reference}', { 'reference' => $reference },{'duplicate'=>1});
6127         }
6128         elsif ($reference ne '')
6129         {
6130              return gdt('see `{section}\'', { 'section' => $reference },{'duplicate'=>1});
6131         }
6132    }
6133    if ($type eq 'xref' or $type eq 'inforef')
6134    {
6135         if (($book ne '') and ($href ne ''))
6136         {
6137              return gdt('See {reference} in @cite{{book}}', { 'reference' => $reference, 'book' => $book },{'duplicate'=>1});
6138         }
6139         elsif (($book ne '') and ($reference ne ''))
6140         {
6141              return gdt('See `{section}\' in @cite{{book}}', { 'section' => $reference, 'book' => $book },{'duplicate'=>1});
6142         }
6143         elsif ($book ne '')
6144         { # should seldom or even never happen
6145              return gdt('See @cite{{book}}', { 'book' => $book },{'duplicate'=>1});
6146         }
6147         elsif ($href ne '')
6148         {
6149              return gdt('See {reference}', { 'reference' => $reference },{'duplicate'=>1});
6150         }
6151         elsif ($reference ne '')
6152         {
6153              return gdt('See `{section}\'', { 'section' => $reference },{'duplicate'=>1});
6154         }
6155    }
6156    if ($type eq 'ref')
6157    {
6158         if (($book ne '') and ($href ne ''))
6159         {
6160              return gdt('{reference} in @cite{{book}}', { 'reference' => $reference, 'book' => $book },{'duplicate'=>1});
6161         }
6162         elsif (($book ne '') and ($reference ne ''))
6163         {
6164              return gdt('`{section}\' in @cite{{book}}', { 'section' => $reference, 'book' => $book },{'duplicate'=>1});
6165         }
6166         elsif ($book ne '')
6167         { # should seldom or even never happen
6168              return gdt('@cite{{book}}', { 'book' => $book },{'duplicate'=>1});
6169         }
6170         elsif ($href ne '')
6171         {
6172              return gdt('{reference}', { 'reference' => $reference },{'duplicate'=>1});
6173         }
6174         elsif ($reference ne '')
6175         {
6176              return gdt('`{section}\'', { 'section' => $reference },{'duplicate'=>1});
6177         }
6178    }
6179    return '';
6180}
6181
6182# format a reference to a node or a section in the generated manual. This
6183# produces a full reference with introductive words and the reference itself.
6184#
6185# arguments:
6186# type of the reference: xref (reference at the beginning of a sentence),
6187#     pxref (reference in a parenthesis),
6188# href linking to the html page containing the node or the section. A typical
6189#     use for this href is a href attribute in an <a> element
6190# short name for this reference
6191# name for this reference
6192# boolean true if the reference is a reference to a section
6193#
6194# $SHORT_REF should be used.
6195sub t2h_default_internal_ref($$$$$$$$)
6196{
6197    my $type = shift;
6198    my $href = shift;
6199    my $short_name = shift;
6200    my $name = shift;
6201    my $is_section = shift;
6202    my $args_texi = shift;
6203    my $formatted_args = shift;
6204    my $element = shift;
6205
6206    if (! $SHORT_REF)
6207    {
6208        $name = &$anchor('', $href, $name);
6209        if ($type eq 'pxref')
6210        {
6211            return gdt('see section {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section);
6212            return gdt('see {reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
6213        }
6214        elsif ($type eq 'xref' or $type eq 'inforef')
6215        {
6216            return gdt('See section {reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section);
6217            return gdt('See {reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
6218        }
6219        elsif ($type eq 'ref')
6220        {
6221            return gdt('{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
6222        }
6223    }
6224    else
6225    {
6226        $name = &$anchor('', $href, $short_name);
6227        if ($type eq 'pxref')
6228        {
6229            return gdt('see {reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
6230        }
6231        elsif ($type eq 'xref' or $type eq 'inforef')
6232        {
6233            return gdt('See {reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
6234        }
6235        elsif ($type eq 'ref')
6236        {
6237            return gdt('{reference_name}', { 'reference_name' => $name },{'duplicate'=>1});
6238        }
6239    }
6240    return '';
6241}
6242
6243# text after @item in table, vtable and ftable
6244sub t2h_default_table_item($$$$$$$)
6245{
6246    my $text = shift;
6247    my $index_label = shift;
6248    my $format = shift;
6249    my $command = shift;
6250    my $style_stack = shift;
6251    my $item_cmd = shift;
6252    my $formatted_index_entry = shift;
6253
6254    return $text . "\n";
6255}
6256
6257# format text on the line following the @item line (in table, vtable and ftable)
6258sub t2h_default_table_line($$$)
6259{
6260    my $text = shift;
6261    my $only_inter_item_commands = shift;
6262    my $before_items = shift;
6263
6264    $only_inter_item_commands = '' if (!defined($only_inter_item_commands));
6265
6266    if ($text =~ /\S/)
6267    {
6268        return $text;
6269    }
6270    return '';
6271}
6272
6273#my $cell_nr = -1;
6274
6275# row in multitable
6276sub t2h_default_row($$$$$$$$)
6277{
6278    my $text = shift;
6279    my $macro = shift;
6280    my $columnfractions = shift;
6281    my $prototype_row = shift;
6282    my $prototype_lengths = shift;
6283    my $column_number = shift;
6284    my $only_inter_item_commands = shift;
6285    my $before_items = shift;
6286
6287    $only_inter_item_commands = '' if (!defined($only_inter_item_commands));
6288
6289    if ($text =~ /\S/)
6290    {
6291         return $text ."\n";
6292    }
6293    return '';
6294}
6295
6296# cell in multitable
6297sub t2h_default_cell($$$$$$$$)
6298{
6299    my $text = shift;
6300    my $row_macro = shift;
6301    my $columnfractions = shift;
6302    my $prototype_row = shift;
6303    my $prototype_lengths = shift;
6304    my $column_number = shift;
6305    my $only_inter_item_commands = shift;
6306    my $before_items = shift;
6307
6308    $only_inter_item_commands = '' if (!defined($only_inter_item_commands));
6309
6310    $text =~ s/^\s*//;
6311    $text =~ s/\s*$//;
6312
6313    return " $text";
6314}
6315
6316# format an itemize, enumerate or @*table @item line, returning
6317# a texinfo line.
6318sub t2h_default_format_list_item_texi($$$$$)
6319{
6320    my $format = shift;
6321    my $line = shift;
6322    my $prepended = shift;
6323    my $command = shift;
6324    my $number = shift;
6325
6326    my $result_line;
6327    my $open_command = 0;
6328
6329    $command = 'bullet' if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize');
6330    $prepended = "\@$command\{\}" if (defined($command) and $command ne '');
6331    $prepended = "$number." if (defined($number) and $number ne '');
6332
6333    if (defined($command) and $command ne '' and $format ne 'itemize')
6334    {
6335        #@*table
6336        $open_command = 1;
6337        $line =~ s/^\s*//;
6338        $line =~ s/\s*$//;
6339        if (exists ($style_map{$command}))
6340        {
6341           $result_line = "\@$command\{$line\}\n";
6342        }
6343        elsif (exists ($things_map{$command}))
6344        {
6345           $result_line = "\@$command\{\} $line\n";
6346        }
6347        else
6348        {
6349           $result_line = "\@$command $line\n";
6350        }
6351    }
6352    elsif (defined($prepended) and $prepended ne '')
6353    {
6354         $prepended =~ s/^\s*//;
6355         $prepended =~ s/\s*$//;
6356         $line =~ s/^\s*//;
6357         $result_line = $prepended . ' ' . $line;
6358    }
6359    return ($result_line, $open_command);
6360}
6361
6362
6363# format an item in a list
6364#
6365# argument:
6366# text of the item
6367# format of the list (itemize or enumerate)
6368# command passed as argument to the format
6369# formatted_command leading command formatted, if it is a thing command
6370sub t2h_default_list_item($$$$$$$$$$$$)
6371{
6372    my $text = shift;
6373    my $format = shift;
6374    my $command = shift;
6375    my $formatted_command = shift;
6376    my $item_nr = shift;
6377    my $enumerate_style = shift;
6378    my $number = shift;
6379    my $prepended = shift;
6380    my $prepended_formatted = shift;
6381    my $only_inter_item_commands = shift;
6382    my $before_items = shift;
6383    my $item_command = shift;
6384
6385    $only_inter_item_commands = '' if (!defined($only_inter_item_commands));
6386
6387    if ($text =~ /\S/)
6388    {
6389        return $text;
6390    }
6391    return '';
6392}
6393
6394sub t2h_default_table_list($$$$$$$$$)
6395{
6396    my $format_command = shift;
6397    my $text = shift;
6398    my $command = shift;
6399    my $formatted_command = shift;
6400# enumerate
6401    my $item_nr = shift;
6402    my $enumerate_style = shift;
6403# itemize
6404    my $prepended = shift;
6405    my $prepended_formatted = shift;
6406# multitable
6407    my $columnfractions = shift;
6408    my $prototype_row = shift;
6409    my $prototype_lengths = shift;
6410    my $column_number = shift;
6411#    my $number = shift;
6412    return $text;
6413}
6414
6415# an comment
6416sub t2h_default_comment($)
6417{
6418    my $text = shift;
6419    return '';
6420}
6421
6422# an xml comment
6423sub xml_default_comment($)
6424{
6425    my $text = shift;
6426    $text =~ s/--+/-/go;
6427    return '<!-- ' . $text . ' -->' . "\n";
6428}
6429
6430sub t2h_collect_styles($)
6431{
6432    my $cmd_stack = shift;
6433    my @result = ();
6434    foreach my $style (reverse(@$cmd_stack))
6435    {
6436#        last unless (defined($command_type{$style}) and $command_type{$style} eq 'style');
6437        push @result, $style if (defined($command_type{$style}) and $command_type{$style} eq 'style');
6438    }
6439    return @result;
6440}
6441
6442sub html_default_parse_attribute($)
6443{
6444    my $element = shift;
6445    return ('', '', '') if (!defined($element));
6446    my ($class, $attributes) = ('', '');
6447    if ($element =~ /^(\w+)(\s+.*)/)
6448    {
6449        $element = $1;
6450        $attributes = $2;
6451        if ($attributes =~ s/^\s+class=\"([^\"]+)\"//)
6452        {
6453            $class = $1;
6454        }
6455    }
6456    return ($element, $class, $attributes);
6457}
6458
6459sub t2h_get_attribute($;$)
6460{
6461    my $command = shift;
6462    my $map_ref = shift;
6463    $map_ref = \%style_map if (!defined($map_ref));
6464    return  unless (defined($map_ref->{$command}));
6465    my ($element, $class, $attributes) = ('', '', '');
6466    if (defined($map_ref->{$command}))
6467    {
6468        if (ref($map_ref->{$command}) eq 'HASH')
6469        {
6470            ($element, $class, $attributes) = t2h_html_parse_attribute ($map_ref->{$command}->{'attribute'});
6471        }
6472        elsif ($map_ref->{$command} !~ /^&/)
6473        {
6474            $element = $map_ref->{$command};
6475            $element =~ s/^\"//;
6476        }
6477    }
6478    return ($element, $class, $attributes);
6479}
6480
6481# a paragraph
6482# arguments:
6483# $text of the paragraph
6484# $align for the alignement
6485# $indent for the indent style (indent or noindent)
6486# The following is usefull if the paragraph is in an itemize.
6487# $paragraph_command is the leading formatting command (like @minus)
6488# $paragraph_command_formatted is the leading formatting command formatted
6489# $paragraph_number is a reference on the number of paragraphs appearing
6490#    in the format. The value should be increased if a paragraph is done
6491# $format is the format name (@itemize)
6492sub t2h_default_paragraph($$$$$$$$$$$$)
6493{
6494    my $text = shift;
6495    my $align = shift;
6496    my $indent = shift;
6497    my $paragraph_command = shift;
6498    my $paragraph_command_formatted = shift;
6499    my $paragraph_number = shift;
6500    my $format = shift;
6501    my $item_nr = shift;
6502    my $enumerate_style = shift;
6503    my $number = shift;
6504    my $command_stack_at_end = shift;
6505    my $command_stack_at_begin = shift;
6506#print STDERR "format: $format\n" if (defined($format));
6507#print STDERR "paragraph @$command_stack_at_end; @$command_stack_at_begin\n";
6508#    $paragraph_command_formatted = '' if (!defined($paragraph_command_formatted) or
6509#          exists($special_list_commands{$format}->{$paragraph_command}));
6510    return '' if ($text =~ /^\s*$/);
6511
6512    return $text;
6513}
6514
6515# a preformatted region
6516# arguments:
6517# $text of the preformatted region
6518# $pre_style css style
6519# $class identifier for the preformatted region (example, menu-comment)
6520# The following is usefull if the preformatted is in an itemize.
6521# $leading_command is the leading formatting command (like @minus)
6522# $leading_command_formatted is the leading formatting command formatted
6523# $preformatted_number is a reference on the number of preformatteds appearing
6524#    in the format. The value should be increased if a preformatted is done
6525sub t2h_default_preformatted($$$$$$$$$$$$)
6526{
6527    my $text = shift;
6528    my $pre_style = shift;
6529    my $class = shift;
6530    my $leading_command = shift;
6531    my $leading_command_formatted = shift;
6532    my $preformatted_number = shift;
6533    my $format = shift;
6534    my $item_nr = shift;
6535    my $enumerate_style = shift;
6536    my $number = shift;
6537    my $command_stack_at_end = shift;
6538    my $command_stack_at_begin = shift;
6539
6540#print STDERR "preformatted @$command_stack_at_end; @$command_stack_at_begin\n";
6541    return '' if ($text eq '');
6542
6543    my $top_stack = '';
6544    $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin));
6545    if ($top_stack eq 'multitable')
6546    {
6547       $text =~ s/^\s*//;
6548       $text =~ s/\s*$//;
6549    }
6550
6551    # add a new line at the end in case there is none
6552    chomp($text);
6553    return $text . "\n";
6554}
6555
6556# $new_element is set if the element is associated with a different
6557# reference element than the preceding element. This is where we
6558# do the navigation. For example it could be a @node before a @section.
6559#
6560# The heading function is always called, though  -- in the default case
6561# nodes don't lead to an outputted title.
6562sub t2h_default_element_heading($$$$$$$$$$$$)
6563{
6564    my $element = shift;
6565    my $command = shift;
6566    my $texi_line = shift;
6567    my $line = shift;
6568    my $in_preformatted = shift;
6569    my $one_section = shift;
6570    my $element_heading = shift;
6571    my $first_in_page = shift;
6572    my $is_top = shift;
6573    my $previous_is_top = shift;
6574    my $command_line = shift;
6575    my $element_id = shift;
6576    my $new_element = shift;
6577#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";
6578
6579#    my $result = '';
6580    my $result = &$element_label($element_id, $element, $command, $command_line);
6581
6582    # in default case, print_head_navigation and print_navigation are no-ops.
6583    # and $print_element_header is undef, so the following nothing.
6584    if ($new_element and !$one_section)
6585    {
6586       main::msg_debug ("For $element->{'texi'}, element_ref not defined", $element->{'line_nr'}) if (!defined($element->{'element_ref'}));
6587       if (!defined($element->{'element_ref'}->{'top'}))
6588       {
6589           if (defined($print_element_header))
6590           { # FIXME backward compatibility, print_element_header is obsoleted in nov 2009
6591                $result .= &$print_element_header($first_in_page, $previous_is_top);
6592           }
6593           else
6594           {
6595               if (($first_in_page or $previous_is_top) and get_conf('headers'))
6596               {
6597                   $result .= &$print_head_navigation(undef, \@SECTION_BUTTONS, $first_in_page, $previous_is_top, $element);
6598               }
6599               else
6600               { # got to do this here, as it isn't done otherwise sinc
6601                 # print_head_navigation is not called
6602                    $result .= &$print_navigation(\@SECTION_BUTTONS) if (get_conf('headers') or get_conf('SPLIT') eq 'node');
6603               }
6604           }
6605       }
6606       else
6607       { # this is here because we want to always print the head navigation for top
6608         # and use TOP_BUTTONS
6609           $result .= &$print_head_navigation(undef, \@TOP_BUTTONS, $first_in_page, $previous_is_top, $element)
6610              if (get_conf('SPLIT') or get_conf('headers'));
6611       }
6612    }
6613    return $result. &$heading($element, $command, $texi_line, $line, $in_preformatted, $one_section, $element_heading);
6614}
6615
6616# This function formats a heading for an element
6617#
6618# argument:
6619# an element. It is a hash reference for a node or a sectioning command.
6620#             it may be the wrong one in case of headings.
6621# The interesting keys are:
6622# 'text': the heading text
6623# 'text_nonumber': the heading text without section number
6624# 'node': true if it is a node
6625# 'level': level of the element. 0 for @top, 1 for chapter, heading,
6626#      appendix..., 2 for section and so on...
6627# 'tag_level': the sectioning element name, raisesections and lowersections
6628#      taken into account
6629sub t2h_default_heading($$$$$;$$)
6630{
6631    my $element = shift;
6632    my $command = shift;
6633    my $texi_line = shift;
6634    my $line = shift;
6635    my $in_preformatted = shift;
6636    my $one_section = shift;
6637    my $element_heading = shift;
6638
6639    my $level = $element->{'level'};
6640    if ($element->{'node'})
6641    {
6642        if ($element->{'text'} =~ /^top$/i)
6643        {
6644          $level = 0;
6645        }
6646        else
6647        {
6648          $level = 3;
6649        }
6650        return '' if (!$element->{'this'} or $element->{'with_section'})
6651    }
6652    else
6653    {
6654        $command = $element->{'tag_level'};
6655    }
6656    my $text = $element->{'text'};
6657
6658    if ($TOC_LINKS and $command !~ /heading/ and defined($element->{'tocid'}))
6659    {
6660         $text = &$anchor ('', "$Texi2HTML::THISDOC{'toc_file'}#$element->{'tocid'}", $text);
6661    }
6662
6663    my $result;
6664    if ($in_preformatted)
6665    {
6666        $result = &$heading_text_preformatted("\@$command", $text, $level);
6667    }
6668    else
6669    {
6670        $result = &$heading_text("\@$command", $text, $level);
6671    }
6672   #$result .= "\n";
6673   return $result;
6674}
6675
6676sub t2h_default_heading_no_texi($$$)
6677{
6678    my $element = shift;
6679    my $command = shift;
6680    my $line = shift;
6681    return main::remove_texi($line) . "\n";
6682}
6683
6684# formatting of raw regions
6685# if L2H is true another mechanism is used for tex
6686sub t2h_default_raw($$;$)
6687{
6688    my $style = shift;
6689    my $text = shift;
6690    my $line_nr = shift;
6691    my $expanded = 1 if (grep {$style eq $_} @EXPAND);
6692    if ($style eq 'verbatim' or $style eq 'verbatiminclude' or ($style eq 'tex' and $expanded))
6693    {
6694        return $text;
6695    }
6696    elsif ($expanded)
6697    {
6698        main::line_warn (sprintf(__("Raw format %s is not converted"), $style), $line_nr);
6699        return $text;
6700    }
6701    else
6702    {
6703        return '';
6704    }
6705}
6706
6707# raw environment when removing texi (in comments)
6708sub t2h_default_raw_no_texi($$)
6709{
6710    my $style = shift;
6711    my $text = shift;
6712    if ($style eq 'verbatim' or $style eq 'verbatiminclude' or grep {$style eq $_} @EXPAND)
6713    {
6714       return $text;
6715    }
6716    return '';
6717}
6718
6719# This function formats a footnote reference and the footnote text associated
6720# with a given footnote.
6721# The footnote reference is the text appearing in the main document pointing
6722# to the footnote text.
6723#
6724# arguments:
6725# absolute number of the footnote (in the document)
6726# relative number of the footnote (in the page)
6727# identifier for the footnote
6728# identifier for the footnote reference in the main document
6729# main document file
6730# footnote text file
6731# array with the footnote text lines
6732# the state. See menu entry.
6733#
6734# returns:
6735# reference on an array containing the footnote text lines which should
6736#     have been updated
6737# the text for the reference pointing on the footnote text
6738sub t2h_default_foot_line_and_ref($$$$$$$$$)
6739{
6740    my $number_in_doc = shift;
6741    my $number_in_page = shift;
6742    my $footnote_id = shift;
6743    my $place_id = shift;
6744    my $document_file = shift;
6745    my $footnote_file = shift;
6746    my $lines = shift;
6747    my $document_state = shift;
6748
6749    $number_in_doc = $NO_NUMBER_FOOTNOTE_SYMBOL if (!$NUMBER_FOOTNOTES);
6750
6751    if ($document_file eq $footnote_file)
6752    {
6753        $document_file = $footnote_file = '';
6754    }
6755    unshift (@$lines, "($number_in_doc)\n");
6756    push @$lines, "\n";
6757    return ($lines, "($number_in_doc)");
6758}
6759
6760# formats a group of footnotes.
6761#
6762# argument:
6763# array reference on the footnotes texts lines
6764#
6765# returns an array reference on the group of footnotes lines
6766sub t2h_default_foot_section($)
6767{
6768    my $lines = shift;
6769    my $header = &$heading_text('footnotes', gdt('Footnotes'), 3);
6770    unshift (@$lines, "$header\n");
6771    return $lines;
6772}
6773
6774sub t2h_default_image_files($$$$)
6775{
6776    my $base = shift;
6777    my $extension = shift;
6778    my $texi_base = shift;
6779    my $texi_extension = shift;
6780    my @files = ();
6781    return @files if (!defined($base) or ($base eq ''));
6782    if (defined($extension) and ($extension ne ''))
6783    {
6784       push @files,["$base.$extension", "$texi_base.$texi_extension"];
6785    }
6786    foreach my $ext (@IMAGE_EXTENSIONS)
6787    {
6788        push @files,["$base.$ext", "$texi_base.$ext"];
6789    }
6790    return @files;
6791}
6792
6793# format an image
6794#
6795# arguments:
6796# image file name with path
6797# image basename
6798# a boolean true if we are in a preformatted format
6799# image file name without path
6800# alt text
6801# width
6802# height
6803# raw alt
6804# extension
6805# path to working dir
6806# path to file relative from working dir
6807sub t2h_default_image($$$$$$$$$$$$$$$$$)
6808{
6809    my $file = shift;
6810    my $base = shift;
6811    my $preformatted = shift;
6812    my $file_name = shift;
6813    my $alt = shift;
6814    my $width = shift;
6815    my $height = shift;
6816    my $raw_alt = shift;
6817    my $extension = shift;
6818    my $working_dir = shift;
6819    my $file_path = shift;
6820    my $in_paragraph = shift;
6821    my $file_locations = shift;
6822    my $base_simple_format = shift;
6823    my $extension_simple_format = shift;
6824    my $file_name_simple_format = shift;
6825    my $line_nr = shift;
6826
6827    if (!defined($file_path) or $file_path eq '')
6828    {
6829        if (defined($extension) and $extension ne '')
6830        {
6831            $file = "$base.$extension";
6832        }
6833        else
6834        {
6835            $file = "$base.txt";
6836        }
6837    }
6838    elsif (! $COMPLETE_IMAGE_PATHS)
6839    {
6840        $file = $file_name;
6841    }
6842    my $alt_txt = '';
6843    $alt_txt = ": $alt" if (defined($alt) and $alt =~ /\S/);
6844    return "[ $file$alt_txt ]";
6845    # it is possible that $file_name is more correct as it allows the user
6846    # to chose the relative path.
6847}
6848
6849# address put in footer describing when was generated and who did the manual
6850# not used anymore
6851sub t2h_default_address($)
6852{
6853    my $date = shift;
6854    $date = '' if (!defined($date));
6855    if ($date ne '')
6856    {
6857        return gdt('on @emph{{date}}', { 'date' => $date });
6858    }
6859    return '';
6860}
6861
6862# format a target in the main document for an index entry.
6863#
6864# arguments:
6865# target identifier
6866# boolean true if in preformatted format
6867sub t2h_default_index_entry_label($$$$$$$$$)
6868{
6869    my $identifier = shift;
6870    my $preformatted = shift;
6871    my $entry = shift;
6872    my $index_name = shift;
6873    my $index_command = shift;
6874    my $texi_entry = shift;
6875    my $formatted_entry = shift;
6876    my $in_region_not_in_output = shift;
6877    my $index_entry_ref = shift;
6878
6879    return '' if (!defined($identifier) or ($identifier !~ /\S/));
6880    my $label = &$anchor($identifier);
6881    return $label;
6882}
6883
6884sub t2h_default_index_entry_command($$$$$$)
6885{
6886   my $command = shift;
6887   my $index_name = shift;
6888   my $label = shift;
6889   my $entry_texi = shift;
6890   my $entry_formatted = shift;
6891   my $index_entry_ref = shift;
6892
6893   return $label;
6894}
6895
6896# process definition commands line @deffn for example
6897sub t2h_default_def_line($$$$$$$$$$$$$$$$)
6898{
6899   my $category_prepared = shift;
6900   my $name = shift;
6901   my $type = shift;
6902   my $arguments = shift;
6903   my $index_label = shift;
6904   my $arguments_array = shift;
6905   my $arguments_type_array = shift;
6906   my $unformatted_arguments_array = shift;
6907   my $command = shift;
6908   my $class_name = shift;
6909   my $category = shift;
6910   my $class = shift;
6911   my $style = shift;
6912   my $original_command = shift;
6913
6914   $name = '' if (!defined($name) or ($name =~ /^\s*$/));
6915   $type = '' if (!defined($type) or $type =~ /^\s*$/);
6916   $arguments = '' if (!defined($arguments) or $arguments =~ /^\s*$/);
6917
6918   my $type_name = '';
6919   $type_name .= "$type " if ($type ne '');
6920   $type_name .= $name if ($name ne '');
6921
6922   my $result = " -- $category_prepared: ${type_name}$arguments";
6923   $result =~ s/\s*$//;
6924   $result .= "\n";
6925
6926}
6927
6928# process definition commands line @deffn for example while removing texi
6929# commands
6930sub t2h_default_def_line_no_texi($$$$$)
6931{
6932   my $category = shift;
6933   my $name = shift;
6934   my $type = shift;
6935   my $arguments = shift;
6936   $name = '' if (!defined($name) or ($name =~ /^\s*$/));
6937   $type = '' if (!defined($type) or $type =~ /^\s*$/);
6938   if (!defined($arguments) or $arguments =~ /^\s*$/)
6939   {
6940       $arguments = '';
6941   }
6942   my $type_name = '';
6943   $type_name = " $type" if ($type ne '');
6944   $type_name .= ' ' . $name if ($name ne '');
6945   $type_name .= $arguments;
6946   if (! $DEF_TABLE)
6947   {
6948       return $category . ':' . $type_name . "\n";
6949   }
6950   else
6951   {
6952
6953       return $type_name . "    " . $category . "\n";
6954   }
6955}
6956
6957# a cartouche
6958sub t2h_default_cartouche($$)
6959{
6960    my $text = shift;
6961
6962    if ($text =~ /\S/)
6963    {
6964        return $text;
6965    }
6966    return '';
6967}
6968
6969my $IDXFILE;
6970# key:
6971# origin_href:
6972# entry:
6973# texi entry:
6974# element_href:
6975# element_text:
6976sub t2h_default_index_summary_file_entry ($$$$$$$$$)
6977{
6978    my $index_name = shift;
6979    my $key = shift;
6980    my $origin_href = shift;
6981    my $entry = shift;
6982    my $texi_entry = shift;
6983    my $element_href = shift;
6984    my $element_text = shift;
6985    my $is_printed = shift;
6986    my $manual_name = shift;
6987
6988    $element_text = 'UNDEF' if (!defined($element_text));
6989    print $IDXFILE "key: $key\n  origin_href: $origin_href\n  entry: $entry\n"
6990      . "  texi_entry: $texi_entry\n"
6991      . "  element_href: $element_href\n  element_text: $element_text\n";
6992}
6993
6994sub t2h_default_index_summary_file_begin($$$)
6995{
6996    my $name = shift;
6997    my $is_printed = shift;
6998    my $manual_name = shift;
6999
7000    $IDXFILE = main::open_out("$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx");
7001    #open(IDXFILE, ">$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx")
7002    #   || die "Can't open >$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx for writing: $!\n";
7003}
7004
7005sub t2h_default_index_summary_file_end($$$)
7006{
7007    my $name = shift;
7008    my $is_printed = shift;
7009    my $manual_name = shift;
7010
7011    close ($IDXFILE);
7012}
7013
7014sub t2h_default_sp($$)
7015{
7016   my $number = shift;
7017   my $preformatted = shift;
7018   return "\n" x $number;
7019}
7020
7021sub t2h_default_acronym_like($$$$$$)
7022{
7023    my $command = shift;
7024    my $acronym_texi = shift;
7025    my $acronym_text = shift;
7026    my $with_explanation = shift;
7027    my $explanation_lines = shift;
7028    my $explanation_text = shift;
7029    my $explanation_simply_formatted = shift;
7030
7031   if ($with_explanation)
7032   {
7033       #return "$acronym_text ($explanation_text)";
7034       return gdt('{acronym_like} ({explanation})', {'acronym_like' => $acronym_text, 'explanation' => $explanation_text},{'duplicate'=>1});
7035   }
7036   else
7037   {
7038       return "$acronym_text";
7039   }
7040
7041}
7042
7043sub t2h_default_quotation_prepend_text($$)
7044{
7045    my $command = shift;
7046    my $text = shift;
7047    return undef if (!defined($text) or $text =~ /^$/);
7048    # If there is a @ protecting the end of line the result is,
7049    # after the chomp:
7050    # @b{some text @:}
7051    # It is likely not to be what was intended, but it is certainly right.
7052    # this is tested in formatting/quotation.texi
7053    chomp($text);
7054    return gdt('@b{{quotation_arg}:} ', {'quotation_arg' => $text}, {'keep_texi' => 1});
7055}
7056
7057sub t2h_default_quotation($$$$$)
7058{
7059    my $command = shift;
7060    my $text = shift;
7061    my $argument_text = shift;
7062    my $argument_text_texi = shift;
7063    my $authors = shift;
7064    my $class_text = '';
7065    # this allows to add an end of line if there was none, which can happen
7066    # if there is an argument to @quotation, but an empty quotation, like
7067    # @quotation something
7068    # @end quotation
7069    chomp($text);
7070    $text .= "\n";
7071    return $text;
7072}
7073
7074# format the text within a paragraph style format,
7075#
7076# argument:
7077# format name
7078# text within the format
7079sub t2h_default_paragraph_style_command($$)
7080{
7081    my $format = shift;
7082    my $text = shift;
7083    return $text;
7084}
7085
7086# format a whole index
7087#
7088# argument:
7089# index text
7090# index name
7091sub t2h_default_print_index($$)
7092{
7093    my $text = shift;
7094    my $name = shift;
7095    return '' if (!defined($text));
7096    return "* Index:\n" . $text;
7097}
7098
7099# format a letter entry in an index page. The letter entry contains
7100# the index entries for the words beginning with that letter. It is
7101# a target for links pointing from the summary of the index.
7102#
7103# arguments:
7104# the letter
7105# identifier for the letter entry. This should be used to make the target
7106#     identifier
7107# text of the index entries
7108sub t2h_default_index_letter($$$)
7109{
7110     my $letter = shift;
7111     my $id = shift;
7112     my $text = shift;
7113     return $text;
7114}
7115
7116# format an index entry (in a letter entry).
7117#
7118# arguments:
7119# href to the main text, linking to the place where the index entry appears
7120# entry text
7121# href to the main text, linking to the section or node where the index
7122#      entry appears
7123# section or node heading
7124sub t2h_default_index_entry($$$$$$$$$$)
7125{
7126    my $text_href = shift;
7127    my $entry = shift;
7128    my $element_href = shift;
7129    my $element_text = shift;
7130    my $entry_file = shift;
7131    my $current_element_file = shift;
7132    my $entry_target = shift;
7133    my $entry_element_target = shift;
7134    my $in_region_not_in_output = shift;
7135    my $index_entry_ref = shift;
7136
7137    return '' if ($in_region_not_in_output);
7138    #!$index_entry_ref->{'seen_in_output'} and defined($index_entry_ref->{'region'}));
7139    $entry = main::substitute_line($index_entry_ref->{'texi'}, "index entry in \@printindex");
7140    return '' if ($entry =~ /^\s*$/);
7141
7142    my $real_element_text;
7143    my $element = $index_entry_ref->{'real_element'};
7144    # in case $element->{'text'} is not defined, it certainly means that we
7145    # are n a special elemet, most likely the virtual element appearing
7146    # before anything else
7147    if (defined($element->{'text'}))
7148    {
7149       my $element_set = 0;
7150       if ($NODE_NAME_IN_INDEX)
7151       {
7152           if ($element->{'node'})
7153           {
7154               $element_set = 1;
7155           }
7156           elsif ($element->{'with_node'})
7157           {
7158               $element = $element->{'with_node'};
7159               $element_set = 1;
7160           }
7161       }
7162       elsif (defined($NODE_NAME_IN_INDEX))
7163       {
7164           if (!$element->{'node'})
7165           {
7166               $element_set = 1;
7167           }
7168           elsif ($element->{'with_section'})
7169           {
7170               $element = $element->{'with_section'};
7171               $element_set = 1;
7172           }
7173       }
7174       $element = $element->{'element_ref'} if ($element->{'element_ref'} and !$element_set);
7175       $real_element_text = $element->{'text'};
7176    }
7177    else
7178    {
7179       $real_element_text = gdt('(outside of any element)');
7180    }
7181    return "* $entry: ".$real_element_text . '.'."\n";
7182}
7183
7184
7185sub t2h_default_copying_comment($$$$)
7186{
7187    my $copying_lines = shift;
7188    my $copying_text = shift;
7189    my $copying_no_texi = shift;
7190    my $copying_simple_text = shift;
7191    return '' if ($copying_no_texi eq '');
7192    my $text = &$comment($copying_no_texi);
7193    return $text;
7194}
7195
7196# return value is currently ignored
7197sub t2h_default_documentdescription($$$$)
7198{
7199    my $decription_lines = shift;
7200    my $description_text = shift;
7201    my $description_no_texi = shift;
7202    my $description_simple_text = shift;
7203
7204    if (defined($DOCUMENT_DESCRIPTION))
7205    {
7206        $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = $DOCUMENT_DESCRIPTION;
7207        return $DOCUMENT_DESCRIPTION;
7208    }
7209
7210    #return '' if ($description_no_texi eq '');
7211    #my @documentdescription = split (/\n/, $description_no_texi);
7212    if ($description_simple_text eq '')
7213    {
7214        $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = undef;
7215        return undef;
7216    }
7217    my @documentdescription = split (/\n/, $description_simple_text);
7218    my $document_description = shift @documentdescription;
7219    chomp $document_description;
7220    foreach my $line (@documentdescription)
7221    {
7222        chomp $line;
7223        $document_description .= ' ' . $line;
7224    }
7225    $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = $document_description;
7226    return $document_description;
7227}
7228
7229# format an index summary. This is a list of letters linking to the letter
7230# entries.
7231#
7232# arguments:
7233# array reference containing the formatted alphabetical letters
7234# array reference containing the formatted non lphabetical letters
7235sub t2h_default_index_summary($$)
7236{
7237    my $alpha = shift;
7238    my $nonalpha = shift;
7239
7240    my $join = '';
7241    my $nonalpha_text = '';
7242    my $alpha_text = '';
7243    return '';
7244}
7245
7246# return the heading with number texinfo text
7247# also called for nodes.
7248sub t2h_default_heading_texi($$$)
7249{
7250    my $tag = shift;
7251    my $texi = shift;
7252    my $number = shift;
7253    #$texi = main::trim_around_spaces($texi);
7254    return "$number $texi" if ($NUMBER_SECTIONS and defined($number) and ($number !~ /^\s*$/)) ;
7255    return $texi;
7256}
7257
7258# return the heading texinfo text for split index sections
7259sub t2h_default_index_element_heading_texi($$$)
7260{ # FIXME i18n
7261    my $heading_texi = shift;
7262    my $tag = shift;
7263    my $texi = shift;
7264    my $number = shift;
7265    my $first_letter = shift;
7266    my $last_letter = shift;
7267    return "$heading_texi: $first_letter -- $last_letter" if ($last_letter ne $first_letter);
7268    return "$heading_texi: $first_letter";
7269}
7270
7271sub t2h_default_element_label($$$$)
7272{
7273    my $id = shift;
7274    my $element = shift;
7275    my $command = shift;
7276    my $line = shift;
7277
7278    return &$anchor($id);
7279}
7280
7281sub t2h_default_misc_element_label($$)
7282{
7283    my $id = shift;
7284    my $misc_page_name = shift;
7285    return &$anchor($id);
7286}
7287
7288sub t2h_default_anchor_label($$$$)
7289{
7290    my $id = shift;
7291    my $anchor_text = shift;
7292    my $anchor_reference = shift;
7293    my $in_special_region = shift;
7294    return &$anchor($id);
7295}
7296
7297sub t2h_default_colon_command($)
7298{
7299   my $punctuation_character = shift;
7300   return $colon_command_punctuation_characters{$punctuation_character} if defined($colon_command_punctuation_characters{$punctuation_character});
7301   return $punctuation_character;
7302}
7303
7304# called each time a @tab or an @itemx is encountered.
7305# To be noticed that there is another function better suited for
7306# formatting of an @item line: $format_list_item_texi
7307sub t2h_default_tab_item_texi($$$$$$)
7308{
7309   my $command = shift;
7310   my $commands_stack = shift;
7311   my $stack = shift;
7312   my $state = shift;
7313   my $line = shift;
7314   my $line_nr = shift;
7315
7316   return undef;
7317}
7318
7319sub xml_default_line_command($$$$)
7320{
7321    my $command = shift;
7322    my $arg_text = shift;
7323    my $arg_texi = shift;
7324    my $state = shift;
7325
7326    my $style = $line_command_map{$command};
7327    return '' if ($arg_text eq '' and !defined($style) or $style eq '');
7328    if ($style)
7329    {
7330        my $attribute_text = '';
7331        if ($style =~ /^(\w+)(\s+.*)/)
7332        {
7333            $style = $1;
7334            $attribute_text = $2;
7335        }
7336        $arg_text = "<${style}$attribute_text>$arg_text</$style>";
7337    }
7338    $arg_text .= "\n";
7339    return $arg_text;
7340}
7341
7342sub t2h_default_line_command($$$$)
7343{
7344    my $command = shift;
7345    my $arg_text = shift;
7346    my $arg_texi = shift;
7347    my $state = shift;
7348
7349    return $arg_text;
7350}
7351
7352# info is special, since it doesn't use the basename but directly the
7353# setfilename output, contrary to all the other formats
7354sub t2h_default_element_file_name($$$)
7355{
7356    my $element = shift;
7357    my $type = shift;
7358    my $prefix = shift;
7359
7360    my $outname;
7361    return unless ($USE_SETFILENAME_EXTENSION and $PREFIX eq '');
7362    $outname = $OUT if (defined($OUT) and $OUT ne '' and $OUT !~ /\/$/ and $Texi2HTML::THISDOC{'input_file_number'} == 0);
7363    if ($type eq 'doc' or !get_conf('SPLIT'))
7364    {
7365       if (defined($Texi2HTML::THISDOC{'setfilename'}) and !defined($outname))
7366       {
7367          $Texi2HTML::THISDOC{'extension'} = '';
7368          return $Texi2HTML::THISDOC{'setfilename'};
7369       }
7370    }
7371
7372    return undef;
7373}
7374
7375sub t2h_default_misc_command_line($$$$$)
7376{
7377   my $macro = shift;
7378   my $line = shift;
7379   my $args = shift;
7380   my $stack = shift;
7381   my $state = shift;
7382
7383   my $result;
7384   return ($macro, $line, $result);
7385}
7386
7387sub t2h_default_internal_links($$$)
7388{
7389  my $fh = shift;
7390  my $elements_list = shift;
7391  my $indices = shift;
7392
7393  foreach my $element (@$elements_list)
7394  {
7395     my $text = $element->{'no_texi'};
7396     #$text =~ s/^([\w.]+)\. /$1 /;
7397     #$text = "Annexe ".$text if ($element->{'tag'} =~ /appendix/);
7398     print $fh "$element->{'file'}#$element->{'id'}\ttoc\t$text\n";
7399  }
7400  foreach my $index_name (sort(keys(%$indices)))
7401  {
7402     my $entries = $indices->{$index_name};
7403
7404     foreach my $letter_entries (@$entries)
7405     {
7406       foreach my $entry (@{$letter_entries->{'entries'}})
7407       {
7408        #print STDERR "($index_name) key $key, t $entry->{'texi'}: $entry->{'file'}#$entry->{'target'}\n";
7409        print $fh "$entry->{'file'}#$entry->{'target'}\t$index_name\t$entry->{'key'}\n" if ($entry->{'key'} =~ /\S/);
7410       }
7411     }
7412  }
7413}
7414
74151;
7416