texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

branch master updated: * tp/Texinfo/Common.pm, tp/Texinfo/Convert/Conver


From: Patrice Dumas
Subject: branch master updated: * tp/Texinfo/Common.pm, tp/Texinfo/Convert/Converter.pm (float_name_caption), tp/Texinfo/Convert/Utils.pm (@MONTH_NAMES, expand_verbatiminclude) (definition_category, expand_today, translated_command_tree) (numbered_heading, definition_arguments_content) (find_innermost_accent_contents), tp/Texinfo/Convert/NodeNameNormalization.pm (set_nodes_list_labels), tp/Texinfo/Transformations.pm (protect_hashchar_at_line_beginning), tp/Texinfo/Translations.pm (complete_indices), tp/Texinfo/XS/parsete [...]
Date: Sat, 04 Sep 2021 08:18:00 -0400

This is an automated email from the git hooks/post-receive script.

pertusus pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new a5bbbd3  * tp/Texinfo/Common.pm, tp/Texinfo/Convert/Converter.pm 
(float_name_caption), tp/Texinfo/Convert/Utils.pm (@MONTH_NAMES, 
expand_verbatiminclude) (definition_category, expand_today, 
translated_command_tree) (numbered_heading, definition_arguments_content) 
(find_innermost_accent_contents), tp/Texinfo/Convert/NodeNameNormalization.pm 
(set_nodes_list_labels), tp/Texinfo/Transformations.pm 
(protect_hashchar_at_line_beginning), tp/Texinfo/Translations.pm 
(complete_indices), tp [...]
a5bbbd3 is described below

commit a5bbbd3a859fda73980684bc5228bbb542a29691
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sat Sep 4 14:16:07 2021 +0200

    * tp/Texinfo/Common.pm,
    tp/Texinfo/Convert/Converter.pm (float_name_caption),
    tp/Texinfo/Convert/Utils.pm (@MONTH_NAMES, expand_verbatiminclude)
    (definition_category, expand_today, translated_command_tree)
    (numbered_heading, definition_arguments_content)
    (find_innermost_accent_contents),
    tp/Texinfo/Convert/NodeNameNormalization.pm (set_nodes_list_labels),
    tp/Texinfo/Transformations.pm (protect_hashchar_at_line_beginning),
    tp/Texinfo/Translations.pm (complete_indices),
    tp/Texinfo/XS/parsetexi/Parsetexi.pm,
    tp/Texinfo/Convert/DocBook.pm, tp/Texinfo/Convert/HTML.pm,
    tp/Texinfo/Convert/LaTeX.pm, tp/Texinfo/Convert/Plaintext.pm,
    tp/Texinfo/Convert/Text.pm, tp/Texinfo/Convert/TextContent.pm,
    tp/Texinfo/ParserNonXS.pm, Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.pm,
    tp/init/chm.pm : move methods from Texinfo::Common to other files, to avoid
    dependencies on other modules and group code more logically.
    Most of the functions are moved to the newly created
    Texinfo::Convert::Utils file which groups miscellaneous functions
    usable in simple converters, in practice functions used by
    Texinfo::Convert::Text and other converters.  Exceptions are
    set_nodes_list_labels() moved to Texinfo::Convert::NodeNameNormalization
    because it uses that module, float_name_caption() moved to
    Texinfo::Convert::Converter, protect_hashchar_at_line_beginning()
    moved to Texinfo::Transformations and complete_indices() moved
    to Texinfo::Translations as it is mostly about translations.
    Add to, simplify and reorder loading of packages with use.
    
    * tp/Texinfo/Convert/Converter.pm (float_type_number),
    tp/Texinfo/Convert/HTML.pm, tp/Texinfo/Convert/Plaintext.pm:
    rename _float_type_number() as float_type_number().
    
    * tp/Makefile.am (dist_converters_DATA), po/POTFILES.in,
    po_document/POTFILES.in: add Texinfo/Convert/Utils.pm.
---
 ChangeLog                                      |  36 ++
 Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.pm   |   5 +-
 po/POTFILES.in                                 |   1 +
 po_document/POTFILES.in                        |   1 +
 tp/Makefile.am                                 |   3 +-
 tp/TODO                                        |  39 +-
 tp/Texinfo/Common.pm                           | 812 ++++---------------------
 tp/Texinfo/Convert/Converter.pm                | 134 +++-
 tp/Texinfo/Convert/DocBook.pm                  |  20 +-
 tp/Texinfo/Convert/HTML.pm                     |  27 +-
 tp/Texinfo/Convert/LaTeX.pm                    |   5 +-
 tp/Texinfo/Convert/NodeNameNormalization.pm    |  76 +++
 tp/Texinfo/Convert/Plaintext.pm                |  21 +-
 tp/Texinfo/Convert/Text.pm                     |  29 +-
 tp/Texinfo/Convert/TextContent.pm              |   7 +-
 tp/Texinfo/Convert/Unicode.pm                  |   4 +-
 tp/Texinfo/Convert/Utils.pm                    | 368 +++++++++++
 tp/Texinfo/ParserNonXS.pm                      |  13 +-
 tp/Texinfo/Transformations.pm                  | 100 +++
 tp/Texinfo/Translations.pm                     |  82 +++
 tp/Texinfo/XS/parsetexi/Parsetexi.pm           |  12 +-
 tp/init/chm.pm                                 |   3 +-
 tp/t/accents.t                                 |  12 +-
 tp/t/automatic_menus.t                         |   2 +-
 tp/t/automatic_nodes.t                         |   2 +-
 tp/t/do_master_menu.t                          |   3 +-
 tp/t/nodenormalization.t                       |   5 +-
 tp/t/reference_to_text_in_tree.t               |   4 +-
 tp/t/test_protect_hashchar_at_line_beginning.t |   6 +-
 29 files changed, 1003 insertions(+), 829 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e29b579..2d87a35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2021-09-04  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Common.pm,
+       tp/Texinfo/Convert/Converter.pm (float_name_caption),
+       tp/Texinfo/Convert/Utils.pm (@MONTH_NAMES, expand_verbatiminclude)
+       (definition_category, expand_today, translated_command_tree)
+       (numbered_heading, definition_arguments_content)
+       (find_innermost_accent_contents),
+       tp/Texinfo/Convert/NodeNameNormalization.pm (set_nodes_list_labels),
+       tp/Texinfo/Transformations.pm (protect_hashchar_at_line_beginning),
+       tp/Texinfo/Translations.pm (complete_indices),
+       tp/Texinfo/XS/parsetexi/Parsetexi.pm,
+       tp/Texinfo/Convert/DocBook.pm, tp/Texinfo/Convert/HTML.pm,
+       tp/Texinfo/Convert/LaTeX.pm, tp/Texinfo/Convert/Plaintext.pm,
+       tp/Texinfo/Convert/Text.pm, tp/Texinfo/Convert/TextContent.pm,
+       tp/Texinfo/ParserNonXS.pm, Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.pm,
+       tp/init/chm.pm : move methods from Texinfo::Common to other files, to 
avoid
+       dependencies on other modules and group code more logically.
+       Most of the functions are moved to the newly created
+       Texinfo::Convert::Utils file which groups miscellaneous functions
+       usable in simple converters, in practice functions used by
+       Texinfo::Convert::Text and other converters.  Exceptions are
+       set_nodes_list_labels() moved to Texinfo::Convert::NodeNameNormalization
+       because it uses that module, float_name_caption() moved to
+       Texinfo::Convert::Converter, protect_hashchar_at_line_beginning()
+       moved to Texinfo::Transformations and complete_indices() moved
+       to Texinfo::Translations as it is mostly about translations.
+       Add to, simplify and reorder loading of packages with use.
+
+       * tp/Texinfo/Convert/Converter.pm (float_type_number),
+       tp/Texinfo/Convert/HTML.pm, tp/Texinfo/Convert/Plaintext.pm:
+       rename _float_type_number() as float_type_number().
+
+       * tp/Makefile.am (dist_converters_DATA), po/POTFILES.in,
+       po_document/POTFILES.in: add Texinfo/Convert/Utils.pm.
+
 2021-09-03  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Config.pm (texinfo_register_no_arg_command_formatting)
diff --git a/Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.pm 
b/Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.pm
index a53f7db..233ac84 100644
--- a/Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.pm
+++ b/Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.pm
@@ -32,9 +32,8 @@ use Texinfo::Convert::NodeNameNormalization 
qw(normalize_node);
 use Texinfo::Parser qw(parse_texi_line parse_texi_text);
 use Texinfo::Convert::Texinfo;
 use Texinfo::Convert::TextContent;
-use Texinfo::Common qw(protect_comma_in_tree protect_first_parenthesis
-                       protect_hashchar_at_line_beginning);
-use Texinfo::Transformations;
+use Texinfo::Common qw(protect_comma_in_tree protect_first_parenthesis);
+use Texinfo::Transformations qw(protect_hashchar_at_line_beginning);
 
 use vars qw(
   @ISA $VERSION
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 56f828f..9612502 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -44,6 +44,7 @@ tp/Texinfo/Convert/LaTeX.pm
 tp/Texinfo/Convert/Plaintext.pm
 tp/Texinfo/Convert/Text.pm
 tp/Texinfo/Convert/TexinfoXML.pm
+tp/Texinfo/Convert/Utils.pm
 tp/Texinfo/ParserNonXS.pm
 tp/Texinfo/Report.pm
 tp/Texinfo/Structuring.pm
diff --git a/po_document/POTFILES.in b/po_document/POTFILES.in
index 60a5bd3..6e1c92e 100644
--- a/po_document/POTFILES.in
+++ b/po_document/POTFILES.in
@@ -16,3 +16,4 @@ tp/Texinfo/Convert/Info.pm
 tp/Texinfo/Convert/LaTeX.pm
 tp/Texinfo/Convert/Plaintext.pm
 tp/Texinfo/Convert/HTML.pm
+tp/Texinfo/Convert/Utils.pm
diff --git a/tp/Makefile.am b/tp/Makefile.am
index 53dfcf4..a5685e2 100644
--- a/tp/Makefile.am
+++ b/tp/Makefile.am
@@ -104,7 +104,8 @@ dist_converters_DATA = \
  Texinfo/Convert/Text.pm \
  Texinfo/Convert/TextContent.pm \
  Texinfo/Convert/UnFilled.pm \
- Texinfo/Convert/Unicode.pm
+ Texinfo/Convert/Unicode.pm \
+ Texinfo/Convert/Utils.pm
 
 debugmodulesdir = $(pkgdatadir)/DebugTexinfo
 dist_debugmodules_DATA = \
diff --git a/tp/TODO b/tp/TODO
index adab38e..1f8c343 100644
--- a/tp/TODO
+++ b/tp/TODO
@@ -22,41 +22,14 @@ check @{$converter_options->{'INCLUDE_DIRECTORIES'}} with 
more
 than one output file
 FIXME isn't that done for each output file?
 
-Move code around:
-
-Common.pm float_name_caption to Convert::Common
- sub definition_category($$) to Convert::Common
-    expand_today to Convert::Common
-translated_command_tree Convert::Common
-numbered_heading Convert::Common
-definition_arguments_content Convert::Common
-find_innermost_accent_contents Convert::Common
-
-float_name_caption Convert::Converter
-
-trim_spaces_comment_from_content ?
-
-count_bytes ?
-
-_count_opened_tree_braces _find_end_brace parse_node_manual remains in Common
-enumerate_item_representation
-is_content_empty
-normalize_top_node_name
-_convert_text_options
-
-protect_colon_in_tree modify_tree substitute_references 
collect_commands_list_in_tree collect_commands_in_tree _copy_tree copy_tree 
remains in Common
-need _new_asis_command_with_text or _protect_text
-protect_node_after_label_in_tree 
-protect_first_parenthesis
-
-
-protect_hashchar_at_line_beginning Transformations
-
-set_nodes_list_labels to NodeNameNormalization
-
+Verify that Texinfo::Convert::TextContent really needs
+use Texinfo::Convert::Converter;
 
 complete_indices, gdt, some code in Text: add documentlanguage arg to gdt
-move complete_indices to Translations
+
+Texinfo/Convert/DocBook.pm
+use Texinfo::Convert::Plaintext;
+# FIXME use _image_text
 
 Bugs
 ====
diff --git a/tp/Texinfo/Common.pm b/tp/Texinfo/Common.pm
index 3cc0505..7ad70df 100644
--- a/tp/Texinfo/Common.pm
+++ b/tp/Texinfo/Common.pm
@@ -31,13 +31,6 @@ use File::Spec;
 use Encode;
 
 use Texinfo::Documentlanguages;
-# used in functions, but Texinfo::Convert::Texinfo uses
-# Texinfo::Common in main module, so needs to be loaded after
-#use Texinfo::Convert::Texinfo;
-# same reason as above, and in addition Texinfo::Convert::NodeNameNormalization
-# loads most of the other modules, we may not want to load those modules
-# early.
-#use Texinfo::Convert::NodeNameNormalization;
 
 # debugging
 use Carp qw(cluck);
@@ -49,17 +42,11 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 %EXPORT_TAGS = ( 'all' => [ qw(
 debug_hash
 debug_list
-definition_category
-expand_verbatiminclude
-expand_today
-float_name_caption
 is_content_empty
 move_index_entries_after_items_in_tree
 normalize_top_node_name
-numbered_heading
 protect_comma_in_tree
 protect_first_parenthesis
-protect_hashchar_at_line_beginning
 protect_colon_in_tree
 protect_node_after_label_in_tree
 trim_spaces_comment_from_content
@@ -266,7 +253,7 @@ our %default_converter_customization = (
 # some converters, for example CLOSE_QUOTE_SYMBOL and many
 # for HTML.  Could be added to %default_converter_customization.
 # Defaults are documented in manual and set in the various converters.
-our @variable_string_settables = (
+my @variable_string_settables = (
 'AFTER_ABOUT',
 'AFTER_BODY_OPEN',
 'AFTER_OVERVIEW',
@@ -660,7 +647,7 @@ foreach my $index_name (keys (%index_names)) {
 }
 
 # command with braces. Value is the max number of arguments.
-our %brace_commands;    
+our %brace_commands;
 
 our %letter_no_arg_commands;
 foreach my $letter_no_arg_command ('aa','AA','ae','oe','AE','OE','o','O',
@@ -809,6 +796,8 @@ our %block_commands;
 # commands that have a possible content before an item
 our %block_item_commands;
 
+# Do nothing, used to mark translations for gettext.  The strings
+# are marked to be translated in the parsers with type 'untranslated'.
 sub gdt($)
 {
   return $_[0];
@@ -1109,13 +1098,6 @@ foreach my $command (
   $all_commands{$command} = 1;
 } 
 
-our @MONTH_NAMES =
-    (
-     'January', 'February', 'March', 'April', 'May',
-     'June', 'July', 'August', 'September', 'October',
-     'November', 'December'
-    );
-
 # file:        file name to locate. It can be a file path.
 # directories: a reference on a array containing a list of directories to
 #              search the file in. 
@@ -1231,7 +1213,7 @@ sub output_files_open_out($$$;$)
   }
   my $filehandle = do { local *FH };
   if (!open ($filehandle, '>', $file)) {
-    return undef; 
+    return undef;
   }
   # We run binmode to turn off outputting LF as CR LF under MS-Windows,
   # so that Info tag tables will have correct offsets.  This must be done
@@ -1342,230 +1324,6 @@ sub set_output_encodings($$)
   }
 }
 
-# This should do the job, or at least don't do wrong if $self
-# is not defined, as could be the case if called from 
-# Texinfo::Convert::Text.
-sub expand_verbatiminclude($$$)
-{
-  my $registrar = shift;
-  my $configuration_informations = shift;
-  my $current = shift;
-
-  return unless ($current->{'extra'} and 
defined($current->{'extra'}->{'text_arg'}));
-  my $text = $current->{'extra'}->{'text_arg'};
-  my $file = locate_include_file($configuration_informations, $text);
-
-  my $verbatiminclude;
-
-  if (defined($file)) {
-    if (!open(VERBINCLUDE, $file)) {
-      if ($registrar) {
-        $registrar->line_error($configuration_informations,
-                               sprintf(__("could not read %s: %s"), $file, $!),
-                               $current->{'line_nr'});
-      }
-    } else {
-      if (defined $current->{'extra'}->{'input_perl_encoding'}) {
-        binmode(VERBINCLUDE, ":encoding("
-                             . $current->{'extra'}->{'input_perl_encoding'}
-                             . ")");
-      }
-      $verbatiminclude = { 'cmdname' => 'verbatim',
-                           'parent' => $current->{'parent'},
-                           'extra' => 
-                        {'text_arg' => $current->{'extra'}->{'text_arg'}} };
-      while (<VERBINCLUDE>) {
-        push @{$verbatiminclude->{'contents'}}, 
-                  {'type' => 'raw', 'text' => $_ };
-      }
-      if (!close (VERBINCLUDE)) {
-        if ($registrar) {
-          $registrar->document_warn(
-                 $configuration_informations, sprintf(__(
-                      "error on closing \@verbatiminclude file %s: %s"),
-                             $file, $!));
-        }
-      }
-    }
-  } elsif ($registrar) {
-    $registrar->line_error($configuration_informations,
-                           sprintf(__("\@%s: could not find %s"),
-                                        $current->{'cmdname'}, $text),
-                           $current->{'line_nr'});
-  }
-  return $verbatiminclude;
-}
-
-sub definition_category($$)
-{
-  my $self = shift;
-  my $current = shift;
-
-  return undef if (!$current->{'extra'}
-      or !$current->{'extra'}->{'def_parsed_hash'});
-
-  my $arg_category = $current->{'extra'}->{'def_parsed_hash'}->{'category'};
-  my $arg_class = $current->{'extra'}->{'def_parsed_hash'}->{'class'};
-
-  return $arg_category
-    if (!defined($arg_class));
-  
-  my $style = $command_index{$current->{'extra'}->{'def_command'}};
-  if ($style eq 'fn') {
-    if ($self) {
-      return $self->gdt('{category} on {class}', { 'category' => $arg_category,
-                                          'class' => $arg_class });
-    } else {
-      return {'contents' => [$arg_category, {'text' => ' on '}, $arg_class]};
-    }
-  } elsif ($style eq 'vr') {
-    if ($self) {
-      return $self->gdt('{category} of {class}', { 'category' => $arg_category,
-                                          'class' => $arg_class });
-    } else {
-      return {'contents' => [$arg_category, {'text' => ' of '}, $arg_class]};
-    }
-  }
-}
-
-sub expand_today($)
-{
-  my $self = shift;
-  if ($self->get_conf('TEST')) {
-    return {'text' => 'a sunny day'};
-  }
-
-  my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
-    = ($ENV{SOURCE_DATE_EPOCH}
-        ? gmtime($ENV{SOURCE_DATE_EPOCH})
-        : localtime(time));
-  # See https://reproducible-builds.org/specs/source-date-epoch/.
-
-  $year += ($year < 70) ? 2000 : 1900;
-  return $self->gdt('{month} {day}, {year}',
-          { 'month' => $self->gdt($MONTH_NAMES[$mon]),
-            'day' => $mday, 'year' => $year });
-}
-
-sub translated_command_tree($$)
-{
-  my $self = shift;
-  my $cmdname = shift;
-  if ($self->{'translated_commands'}->{$cmdname}) {
-    return $self->gdt($self->{'translated_commands'}->{$cmdname});
-  }
-  return undef;
-}
-
-sub numbered_heading($$$;$)
-{
-  my $self = shift;
-  my $current = shift;
-  my $text = shift;
-  my $numbered = shift;
-
-  my $number;
-  if (defined($current->{'number'}) and ($numbered or !defined($numbered))) {
-    $number = $current->{'number'};
-  }
-
-  my $result;
-  if ($self) {
-    if (defined($number)) {
-      if ($current->{'cmdname'} eq 'appendix' and $current->{'level'} == 1) {
-        $result = $self->gdt('Appendix {number} {section_title}',
-                   {'number' => $number, 'section_title' => $text}, 
-                   'translated_text');
-      } else {
-        $result = $self->gdt('{number} {section_title}',
-                   {'number' => $number, 'section_title' => $text},
-                   'translated_text');
-      }
-    } else {
-      $result = $text;
-    }
-  } else {
-    $result = $text;
-    $result = $number.' '.$result if (defined($number));
-    if ($current->{'cmdname'} eq 'appendix' and $current->{'level'} == 1) {
-      $result = 'Appendix '.$result;
-    }
-  }
-  chomp ($result);
-  return $result;
-}
-
-sub definition_arguments_content($)
-{
-  my $root = shift;
-  my $result;
-
-  return undef if (!defined($root->{'extra'}) 
-                    or !defined($root->{'extra'}->{'def_parsed_hash'}));
-  my @args = @{$root->{'args'}->[0]->{'contents'}};
-  while (@args) {
-    last if (defined($args[0]->{'extra'})
-             and defined($args[0]->{'extra'}->{'def_role'})
-             and $args[0]->{'extra'}->{'def_role'} ne 'spaces'
-             and !$root->{'extra'}->{'def_parsed_hash'}
-                       ->{$args[0]->{'extra'}->{'def_role'}});
-    shift @args;
-  }
-  if (scalar(@args) > 0) {
-    return \@args;
-  } else {
-    return undef;
-  }
-}
-
-# find the accent commands stack and the innermost text contents
-sub find_innermost_accent_contents($;$)
-{
-  my $current = shift;
-  my $encoding = shift;
-  my @accent_commands = ();
-  my $debug = 0;
- ACCENT:
-  while (1) {
-    # the following can happen if called with a bad tree
-    if (!$current->{'cmdname'} 
-        or !$accent_commands{$current->{'cmdname'}}) {
-      #print STDERR "BUG: Not an accent command in accent\n";
-      cluck "BUG: Not an accent command in accent\n";
-      #print STDERR 
Texinfo::Convert::Texinfo::convert_to_texinfo($current)."\n";
-      #print STDERR Data::Dumper->Dump([$current]);
-      last;
-    }
-    push @accent_commands, $current;
-    # A bogus accent, that may happen
-    if (!$current->{'args'}) {
-      return ([], \@accent_commands);
-    }
-    my $arg = $current->{'args'}->[0];
-    if (!$arg->{'contents'}) {
-      print STDERR "BUG: No content in accent command\n";
-      #print STDERR Data::Dumper->Dump([$current]);
-      #print STDERR 
Texinfo::Convert::Texinfo::convert_to_texinfo($current)."\n";
-      return ([], \@accent_commands);
-    }
-    # inside the argument of an accent
-    my $text_contents = [];
-    foreach my $content (@{$arg->{'contents'}}) {
-      if (!($content->{'cmdname'} and ($content->{'cmdname'} eq 'c'
-                                  or $content->{'cmdname'} eq 'comment'))) {
-        if ($content->{'cmdname'} and $accent_commands{$content->{'cmdname'}}) 
{
-          $current = $content;
-          next ACCENT;
-        } else {
-          push @$text_contents, $content;
-        }
-      }
-    }
-    # we go here if there was no nested accent
-    return ($text_contents, \@accent_commands);
-  }
-}
-
 sub trim_spaces_comment_from_content($)
 {
   my $contents = shift;
@@ -1713,60 +1471,6 @@ sub parse_node_manual($)
   return $result;
 }
 
-sub float_name_caption($$)
-{
-  my $self = shift;
-  my $root = shift;
-
-  my $caption;
-  if ($root->{'extra'}->{'caption'}) {
-    $caption = $root->{'extra'}->{'caption'};
-  } elsif ($root->{'extra'}->{'shortcaption'}) {
-    $caption = $root->{'extra'}->{'shortcaption'};
-  }
-  #if ($self->get_conf('DEBUG')) {
-  #  my $caption_texi = 
-  #    Texinfo::Convert::Texinfo::convert_to_texinfo({ 'contents' => 
$caption->{'contents'}});
-  #  print STDERR "  CAPTION: $caption_texi\n";
-  #}
-  my $type;
-  if ($root->{'extra'}->{'type'}->{'normalized'} ne '') {
-    $type = {'contents' => $root->{'extra'}->{'type'}->{'content'}};
-  }
-
-  my $prepended;
-  if ($type) {
-    if ($caption) {
-      if (defined($root->{'number'})) {
-        $prepended = $self->gdt('{float_type} {float_number}: ',
-            {'float_type' => $type,
-             'float_number' => $root->{'number'}});
-      } else {
-        $prepended = $self->gdt('{float_type}: ',
-          {'float_type' => $type});
-      }
-    } else {
-      if (defined($root->{'number'})) {
-        $prepended = $self->gdt("{float_type} {float_number}\n",
-            {'float_type' => $type,
-              'float_number' => $root->{'number'}});
-      } else {
-        $prepended = $self->gdt("{float_type}\n",
-            {'float_type' => $type});
-      }
-    }
-  } elsif (defined($root->{'number'})) {
-    if ($caption) {
-      $prepended = $self->gdt('{float_number}: ',
-          {'float_number' => $root->{'number'}});
-    } else {
-      $prepended = $self->gdt("{float_number}\n",
-           {'float_number' => $root->{'number'}});
-    }
-  }
-  return ($caption, $prepended);
-}
-
 # decompose a decimal number on a given base.
 sub _decompose_integer($$)
 {
@@ -2348,98 +2052,6 @@ sub protect_node_after_label_in_tree($)
   return modify_tree(undef, $tree, \&_protect_node_after_label);
 }
 
-sub _is_cpp_line($)
-{
-  my $text = shift;
-  return 1 if ($text =~ /^\s*#\s*(line)? (\d+)(( "([^"]+)")(\s+\d+)*)?\s*$/);
-  return 0;
-}
-
-sub _protect_hashchar_at_line_beginning($$$)
-{
-  my $self = shift;
-  my $type = shift;
-  my $current = shift;
-
-  my ($registrar, $configuration_informations) = @$self;
-
-  #print STDERR "$type $current "._print_current($current)."\n";
-  # if the next is a hash character at line beginning, mark it
-  if (defined($current->{'text'}) and $current->{'text'} =~ /\n$/
-      and $current->{'parent'} and $current->{'parent'}->{'contents'}) {
-    my $parent = $current->{'parent'};
-    #print STDERR "End of line in $current, parent $parent: 
(@{$parent->{'contents'}})\n";
-    my $current_found = 0;
-    foreach my $content (@{$parent->{'contents'}}) {
-      if ($current_found) {
-        #print STDERR "after $current: $content $content->{'text'}\n";
-        if ($content->{'text'} and _is_cpp_line($content->{'text'})) {
-          $content->{'extra'}->{'_protect_hashchar'} = 1;
-        }
-        last;
-      } elsif ($content eq $current) {
-        $current_found = 1;
-      }
-    }
-  }
-
-  my $protect_hash = 0;
-  # if marked, or first and a cpp_line protect a leading hash character
-  if ($current->{'extra'} and $current->{'extra'}->{'_protect_hashchar'}) {
-    delete $current->{'extra'}->{'_protect_hashchar'};
-    if (!scalar(keys(%{$current->{'extra'}}))) {
-      delete $current->{'extra'};
-    }
-    $protect_hash = 1;
-  } elsif ($current->{'parent'} and $current->{'parent'}->{'contents'}
-           and $current->{'parent'}->{'contents'}->[0]
-           and $current->{'parent'}->{'contents'}->[0] eq $current
-           and $current->{'text'}
-           and _is_cpp_line($current->{'text'})) {
-    $protect_hash = 1;
-  }
-  if ($protect_hash) {
-    my @result = ();
-    if ($current->{'type'} and $current->{'type'} eq 'raw') {
-      if ($self) {
-        my $parent = $current->{'parent'};
-        while ($parent) {
-          if ($parent->{'cmdname'} and $parent->{'line_nr'}) {
-            if ($registrar) {
-              $registrar->line_warn($configuration_informations, sprintf(__(
-                  "could not protect hash character in \@%s"), 
-                             $parent->{'cmdname'}), $parent->{'line_nr'});
-            }
-            last;
-          }
-          $parent = $parent->{'parent'};
-        }
-      }
-    } else {
-      $current->{'text'} =~ s/^(\s*)#//;
-      if ($1 ne '') {
-        push @result, {'text' => $1, 'parent' => $current->{'parent'}};
-      }
-      push @result, {'cmdname' => 'hashchar', 'parent' => $current->{'parent'},
-                     'args' => [{'type' => 'brace_command_arg'}]};
-    }
-    push @result, $current;
-    return @result;
-  } else {
-    return ($current);
-  }
-}
-
-sub protect_hashchar_at_line_beginning($$$)
-{
-  my $registrar = shift;
-  my $configuration_informations = shift;
-  my $tree = shift;
-
-  my $self = [$registrar, $configuration_informations];
-  return modify_tree($self, $tree, \&_protect_hashchar_at_line_beginning);
-}
-
 sub protect_first_parenthesis($)
 {
   my $contents = shift;
@@ -2711,7 +2323,7 @@ sub _relate_index_entries_to_table_entries_in_tree($$$)
 
 sub relate_index_entries_to_table_entries_in_tree($)
 {
-  my $tree = shift;  
+  my $tree = shift;
   return modify_tree(undef, $tree,
                      \&_relate_index_entries_to_table_entries_in_tree);
 }
@@ -2775,8 +2387,6 @@ sub print_tree($)
   return Data::Dumper->Dump([$tree]);
 }
 
-# common parser functions
-
 # register a label, that is something that may be the target of a reference
 # and must be unique in the document.  Corresponds to @node, @anchor and
 # @float second arg.
@@ -2790,162 +2400,6 @@ sub register_label($$$)
   }
 }
 
-sub _non_bracketed_contents($) {
-  my $current = shift;
-
-  if ($current->{'type'} and $current->{'type'} eq 'bracketed') {
-    my $new = {};
-    $new->{'contents'} = $current->{'contents'} if ($current->{'parent'});
-    $new->{'parent'} = $current->{'parent'} if ($current->{'parent'});
-    return $new;
-  } else {
-    return $current;
-  }
-}
-
-# In a handful of cases, we delay storing the contents of the
-# index entry until now to avoid needing Texinfo::Report::gdt
-# in the main code of Parser.pm.  Also set 'in_code' value on
-# index entries.
-
-sub complete_indices {
-  my $self = shift;
-
-  my ($index_entry, $index_contents_normalized);
-    
-  my $save_lang = $self->get_conf('documentlanguage');
-
-  foreach my $index_name (keys(%{$self->{'index_names'}})) {
-    next if !defined $self->{'index_names'}->{$index_name}->{'index_entries'};
-    foreach my $entry 
(@{$self->{'index_names'}->{$index_name}->{'index_entries'}}) {
-      $entry->{'in_code'} = $self->{'index_names'}->{$index_name}->{'in_code'};
-      
-      if (!defined $entry->{'content'}) {
-        my $def_command = $entry->{'command'}->{'extra'}->{'def_command'};
-
-        my $def_parsed_hash = 
$entry->{'command'}->{'extra'}->{'def_parsed_hash'}; 
-        if ($def_parsed_hash and $def_parsed_hash->{'class'}
-            and $def_command) {
-          # Use the document language that was current when the command was
-          # used for getting the translation.
-          $self->{'documentlanguage'}
-             = $entry->{'command'}->{'extra'}->{'documentlanguage'};
-          delete $entry->{'command'}->{'extra'}->{'documentlanguage'};
-          if ($def_command eq 'defop'
-              or $def_command eq 'deftypeop'
-              or $def_command eq 'defmethod'
-              or $def_command eq 'deftypemethod') {
-            $index_entry = $self->gdt('{name} on {class}',
-                                  {'name' => $def_parsed_hash->{'name'},
-                                   'class' => $def_parsed_hash->{'class'}});
-           $index_contents_normalized
-             = [_non_bracketed_contents($def_parsed_hash->{'name'}),
-                { 'text' => ' on '},
-                _non_bracketed_contents($def_parsed_hash->{'class'})];
-          } elsif ($def_command eq 'defivar'
-                   or $def_command eq 'deftypeivar'
-                   or $def_command eq 'deftypecv') {
-            $index_entry = $self->gdt('{name} of {class}',
-                                     {'name' => $def_parsed_hash->{'name'},
-                                     'class' => $def_parsed_hash->{'class'}});
-            $index_contents_normalized
-              = [_non_bracketed_contents($def_parsed_hash->{'name'}),
-                 { 'text' => ' of '},
-                 _non_bracketed_contents($def_parsed_hash->{'class'})];
-          }
-        }
-        # 'root_line' is the container returned by gdt.
-        if ($index_entry->{'type'} and $index_entry->{'type'} eq 'root_line') {
-          for my $child (@{$index_entry->{'contents'}}) {
-            delete $child->{'parent'};
-          }
-        }
-        if ($index_entry->{'contents'}) {
-          $entry->{'content'} = [@{$index_entry->{'contents'}}];
-          $entry->{'content_normalized'} = $index_contents_normalized;
-        }
-      }
-    }
-  }
-  $self->{'documentlanguage'} = $save_lang;
-}
-
-# Called from Texinfo::ParserNonXS and Texinfo::XS::parsetexi::Parsetexi.
-# This should be considered an internal function of the parsers for all
-# purposes, it is here to avoid code duplication.
-# Sets $self->{'nodes'} and $self->{'labels'} based on $self->{'targets'}.
-sub set_nodes_list_labels($$$)
-{
-  my $self = shift;
-  my $registrar = shift;
-  my $configuration_informations = shift;
-
-  $self->{'nodes'} = [];
-  my %labels = ();
-  if (defined $self->{'targets'}) {
-    for my $target (@{$self->{'targets'}}) {
-      if ($target->{'cmdname'} eq 'node') {
-        if ($target->{'extra'}->{'nodes_manuals'}) {
-          for my $node_manual (@{$target->{'extra'}{'nodes_manuals'}}) {
-            if (defined $node_manual
-                  and defined $node_manual->{'node_content'}) {
-              my $normalized = 
Texinfo::Convert::NodeNameNormalization::normalize_node(
-                                    {'contents' => 
$node_manual->{'node_content'}});
-              $node_manual->{'normalized'} = $normalized;
-            }
-          }
-        }
-      }
-      if (defined $target->{'extra'}
-            and defined $target->{'extra'}->{'node_content'}) {
-        my $normalized = 
Texinfo::Convert::NodeNameNormalization::normalize_node(
-                             {'contents' => 
$target->{'extra'}->{'node_content'}});
-
-        if ($normalized !~ /[^-]/) {
-          $registrar->line_error($configuration_informations,
-               sprintf(__("empty node name after expansion `%s'"),
-                     Texinfo::Convert::Texinfo::convert_to_texinfo({'contents'
-                                   => $target->{'extra'}->{'node_content'}})),
-                            $target->{'line_nr'});
-          delete $target->{'extra'}->{'node_content'};
-        } else {
-          if (defined $labels{$normalized}) {
-            $registrar->line_error($configuration_informations,
-              sprintf(__("\@%s `%s' previously defined"), 
-                         $target->{'cmdname'}, 
-                   Texinfo::Convert::Texinfo::convert_to_texinfo({'contents'
-                                    => $target->{'extra'}->{'node_content'}})),
-                               $target->{'line_nr'});
-            $registrar->line_error($configuration_informations,
-              sprintf(__("here is the previous definition as \@%s"),
-                               $labels{$normalized}->{'cmdname'}),
-                       $labels{$normalized}->{'line_nr'});
-            delete $target->{'extra'}->{'node_content'};
-          } else {
-            $labels{$normalized} = $target;
-            $target->{'extra'}->{'normalized'} = $normalized;
-            if ($target->{'cmdname'} eq 'node') {
-              if ($target->{'extra'}
-                  and $target->{'extra'}{'node_argument'}) {
-                $target->{'extra'}{'node_argument'}{'normalized'}
-                  = $normalized;
-              }
-              push @{$self->{'nodes'}}, $target;
-            }
-          }
-        }
-      } else {
-        if ($target->{'cmdname'} eq 'node') {
-          $registrar->line_error($configuration_informations,
-               sprintf(__("empty argument in \@%s"),
-                  $target->{'cmdname'}), $target->{'line_nr'});
-          delete $target->{'extra'}->{'node_content'};
-        }
-      }
-    }
-  }
-  $self->{'labels'} = \%labels;
-}
 
 1;
 
@@ -2957,231 +2411,213 @@ Texinfo::Common - Classification of commands and 
miscellaneous methods
 
 =head1 SYNOPSIS
 
-  use Texinfo::Common qw(expand_today expand_verbatiminclude);
+  use Texinfo::Common;
   if ($Texinfo::Common::accent_commands{$a_command}) {
     print STDERR "$a_command is an accent command\n";
   }
-  
-  my $today_tree = expand_today($converter);
-  my $verbatiminclude_tree 
-     = expand_verbatiminclude(undef, $converter, $verbatiminclude);
 
 =head1 DESCRIPTION
 
 Texinfo::Common holds interesting hashes classifying Texinfo @-commands,
-as well as miscellaneous methods that may be useful for any backend
+as well as miscellaneous methods that may be useful for backends
 converting texinfo trees.
 
-It also defines, as our variable a hash for default indices,
-named C<%index_names>.  The format of this hash is described in 
-L<Texinfo::Parser/indices_information>.
-
-=head1 COMMAND CLASSES
+=head1 MISC INFORMATIONS
 
 Hashes are defined as C<our> variables, and are therefore available
 outside of the module.
 
-The key of the hashes are @-command names without the @.  The 
-following hashes are available:
+TODO: undocumented
 
-=over
+%null_device_file %default_parser_customization_values 
%document_settable_multiple_at_commands %document_settable_unique_at_commands 
%default_converter_command_line_options 
%default_main_program_customization_options %default_converter_customization 
@variable_string_settables %document_settable_at_commands %def_map 
%command_index %close_paragraph_commands %command_structuring_level 
%level_to_structuring_command
 
-=item %all_commands
+=over
 
-All the @-commands.
+=item %index_names
 
-=item %no_brace_commands
+Hash describing the default Texinfo indices.  The format of this hash is
+described in L<Texinfo::Parser/indices_information>.
 
-Commands without brace with a single character as name, like C<*>
-or C<:>.  The value is an ascii representation of the command.  It
-may be an empty string.
+=item %texinfo_output_formats
 
-=item %misc_commands
+Cannonical output formats that have associated conditionals.  In
+practice corresponds to C<%format_raw_commands> plus C<info>
+and C<plaintext>.
 
-Command that do not take braces and are not block commands either, like
-C<@node>, C<@chapter>, C<@cindex>, C<@deffnx>, C<@end>, C<@footnotestyle>, 
-C<@set>, C<@settitle>, C<@indent>, C<@definfoenclose>, C<@comment> and many 
-others.
+=back
 
-=item %default_index_commands
+=head1 COMMAND CLASSES
 
-Index entry commands corresponding to default indices. For example 
-C<@cindex>.
+Hashes are defined as C<our> variables, and are therefore available
+outside of the module.
 
-=item %root_commands
+The key of the hashes are @-command names without the @.  The
+following hashes are available:
 
-Commands that are at the root of a Texinfo document, namely
-C<@node> and sectioning commands, except heading commands.
+=over
 
-=item %sectioning_commands
+=item %all_commands
 
-All the sectioning and heading commands.
+All the @-commands.
 
-=item %brace_commands
+=item %accent_commands
 
-The commands that take braces.  The associated value is the maximum
-number of arguments.
+Accent @-commands taking an argument, like C<@'> or C<@ringaccent>
+including C<@dotless> and C<@tieaccent>.
 
-=item %letter_no_arg_commands
+=item %align_commands
 
-@-commands with braces but no argument corresponding to letters, 
-like C<@AA{}> or C<@ss{}> or C<@o{}>.
+@-commands related with alignement of text.
 
-=item %accent_commands
+=item %block_commands
 
-Accent @-commands taking an argument, like C<@'> or C<@ringaccent> 
-including C<@dotless> and C<@tieaccent>.
+Commands delimiting a block with a closing C<@end>.  The value
+is I<conditional> for C<@if> commands, I<def> for definition
+commands like C<@deffn>, I<raw> for @-commands that have no expansion
+of @-commands in their bodies and I<multitable> for C<@multitable>.
+Otherwise it is set to the number of arguments separated by commas
+that may appear on the @-command line. That means 0 in most cases,
+1 for C<@quotation> and 2 for C<@float>.
 
-=item %style_commands
+=item %brace_commands
 
-Commands that mark a fragment of texinfo, like C<@strong>,
-C<@cite>, C<@code> or C<@asis>.
+The commands that take braces.  The associated value is the maximum
+number of arguments.
 
 =item %code_style_commands
 
-I<style_commands> that have their argument in code style, like 
+I<style_commands> that have their argument in code style, like
 C<@code>.
 
-=item %regular_font_style_commands
-
-I<style_commands> that have their argument in regular font, like
-C<@r> or C<@slanted>.
-
 =item %context_brace_commands
 
 @-commands with brace like C<@footnote>, C<@caption> and C<@math>
 whose argument is outside of the main text flow in one way or another.
 
-=item %ref_commands
+=item %def_commands
 
-Cross reference @-command referencing nodes, like C<@xref>.
+=item %def_aliases
+
+Definition commands.  C<%def_aliases> associates an aliased command
+to the original command, for example C<defun> is associated to C<deffn>.
+
+=item %default_index_commands
+
+Index entry commands corresponding to default indices. For example
+C<@cindex>.
 
 =item %explained_commands
 
 @-commands whose second argument explain first argument and further
 @-command call without first argument, as C<@abbr> and C<@acronym>.
 
-=item %block commands
+=item %format_raw_commands
 
-Commands delimiting a block with a closing C<@end>.  The value
-is I<conditional> for C<@if> commands, I<def> for definition
-commands like C<@deffn>, I<raw> for @-commands that have no expansion
-of @-commands in their bodies and I<multitable> for C<@multitable>.  
-Otherwise it is set to the number of arguments separated by commas 
-that may appear on the @-command line. That means 0 in most cases, 
-1 for C<@quotation> and 2 for C<@float>.
+@-commands associated with raw output format, like C<@html>, or
+C<@docbook>.
 
-=item %raw_commands
+=item %inline_commands
 
-@-commands that have no expansion of @-commands in their bodies,
-as C<@macro>, C<@verbatim> or C<@ignore>.
+=item %inline_conditional_commands
 
-=item %format_raw_commands
+=item %inline_format_commands
 
-@-commands associated with raw output format, like C<@html>, or
-C<@docbook>.
+Inline conditional commands, like C<@inlineifclear>, and inline format
+commands like C<inlineraw> and C<inlinefmt>.
 
-=item %math_commands
+=item %item_container_commands
 
-@-commands which contains math, like C<@math> or C<@displaymath>.
+Commands holding C<@item> with C<@item> that contains blocks of text,
+like C<@itemize>.
 
-=item %texinfo_output_formats
+=item %item_line_commands
 
-Cannonical output formats that have associated conditionals.  In
-practice C<%format_raw_commands> plus C<info> and C<plaintext>.
+Commands with C<@item> that have their arguments on their lines, like
+C<@ftable>.
 
-=item %def_commands
+=item %letter_no_arg_commands
 
-=item %def_aliases
+@-commands with braces but no argument corresponding to letters,
+like C<@AA{}> or C<@ss{}> or C<@o{}>.
 
-Definition commands.  C<%def_aliases> associates an aliased command
-to the original command, for example C<defun> is associated to C<deffn>.
+=item %math_commands
+
+@-commands which contains math, like C<@math> or C<@displaymath>.
 
 =item %menu_commands
 
 @-commands with menu entries.
 
-=item %align_commands
+=item %misc_commands
 
-@-commands related with alignement of text.
+Command that do not take braces and are not block commands either, like
+C<@node>, C<@chapter>, C<@cindex>, C<@deffnx>, C<@end>, C<@footnotestyle>,
+C<@set>, C<@settitle>, C<@indent>, C<@definfoenclose>, C<@comment> and many
+others.
 
-=item %region_commands
+=item %no_brace_commands
 
-Block @-commands that enclose full text regions, like C<@titlepage>.
+Commands without brace with a single character as name, like C<*>
+or C<:>.  The value is an ascii representation of the command.  It
+may be an empty string.
 
 =item %preformatted_commands
 
 =item %preformatted_code_commands
 
-I<%preformatted_commands> is for commands whose content should not 
-be filled, like C<@example> or C<@display>.  If the command is meant 
+I<%preformatted_commands> is for commands whose content should not
+be filled, like C<@example> or C<@display>.  If the command is meant
 for code, it is also in I<%preformatted_code_commands>, like C<@example>.
 
-=item %item_container_commands
+=item %raw_commands
 
-Commands holding C<@item> with C<@item> that contains blocks of text, 
-like C<@itemize>.
+@-commands that have no expansion of @-commands in their bodies,
+as C<@macro>, C<@verbatim> or C<@ignore>.
 
-=item %item_line_commands
+=item %ref_commands
 
-Commands with C<@item> that have their arguments on their lines, like
-C<@ftable>.
+Cross reference @-command referencing nodes, like C<@xref>.
 
-=back
+=item %region_commands
 
-=head1 METHODS
+Block @-commands that enclose full text regions, like C<@titlepage>.
 
-No method is exported in the default case.
+=item %regular_font_style_commands
 
-Most methods takes a I<$converter> as argument, sometime optionally, 
-to get some information and use methods for error reporting, 
-see L<Texinfo::Convert::Converter> and L<Texinfo::Report>.
+I<style_commands> that have their argument in regular font, like
+C<@r> or C<@slanted>.
 
-=over
+=item %root_commands
 
-=item $tree = expand_today($converter)
+Commands that are at the root of a Texinfo document, namely
+C<@node> and sectioning commands, except heading commands.
 
-Expand today's date, as a texinfo tree with translations.
+=item %sectioning_commands
 
-=item $tree = expand_verbatiminclude($registrar, $configuration_informations, 
$verbatiminclude)
+All the sectioning and heading commands.
 
-The I<$registrar> argument may be undef.  I<$verbatiminclude> is a
-C<@verbatiminclude> tree element.  This function returns a 
-C<@verbatim> tree elements after finding the included file and
-reading it.  If I<$registrar> is not defined, errors messages are
-not registered.
+=item %style_commands
 
-=item $tree = definition_category($converter, $def_line)
+Commands that mark a fragment of texinfo, like C<@strong>,
+C<@cite>, C<@code> or C<@asis>.
 
-The I<$converter> argument may be undef.  I<$def_line> is a 
-C<def_line> texinfo tree container.  This function
-returns a texinfo tree corresponding to the category of the
-I<$def_line> taking the class into account, if there is one.
-If I<$converter> is not defined, the resulting string won't be
-translated.
+=back
 
-=item $result = is_content_empty($tree, $do_not_ignore_index_entries)
+=head1 METHODS
 
-Return true if the C<$tree> has content that could be formatted.
-C<$do_not_ignore_index_entries> is optional.  If set, index entries
-are considered to be formatted.
+No method is exported in the default case.
 
-=item $result = numbered_heading ($converter, $heading_element, $heading_text, 
$do_number)
+Most methods takes a I<$converter> as argument, sometime optionally,
+to get some information and use methods for error reporting,
+see L<Texinfo::Convert::Converter> and L<Texinfo::Report>.
 
-The I<$converter> argument may be undef.  I<$heading_element> is 
-a heading command tree element.  I<$heading_text> is the already 
-formatted heading text.  if the I<$do_number> optional argument is 
-defined and false, no number is used and the text is returned as is.
-This function returns the heading with a number and the appendix 
-part if needed.  If I<$converter> is not defined, the resulting 
-string won't be translated.
+=over
 
-=item ($caption, $prepended) = float_name_caption ($converter, $float)
+=item $result = is_content_empty($tree, $do_not_ignore_index_entries)
 
-I<$float> is a texinfo tree C<@float> element.  This function 
-returns the caption that should be used for the float formatting 
-and the I<$prepended> texinfo tree combining the type and label
-of the float.
+Return true if the C<$tree> has content that could be formatted.
+C<$do_not_ignore_index_entries> is optional.  If set, index entries
+are considered to be formatted.
 
 =item $text = enumerate_item_representation($specification, $number)
 
@@ -3211,35 +2647,35 @@ Protect comma characters, replacing C<,> with @comma{} 
in tree.
 
 =item protect_node_after_label_in_tree($tree)
 
-Protect colon with C<protect_colon_in_tree> and characters that 
+Protect colon with C<protect_colon_in_tree> and characters that
 are special in node names after a label in menu entries (tab
-dot and comma) with C<protect_node_after_label_in_tree>.  
-The protection is achieved by putting protected characters 
+dot and comma) with C<protect_node_after_label_in_tree>.
+The protection is achieved by putting protected characters
 in C<@asis{}>.
 
 =item $contents_result = protect_first_parenthesis ($contents)
 
-Return a contents array reference with first parenthesis in the 
+Return a contents array reference with first parenthesis in the
 contents array reference protected.
 
 =item protect_hashchar_at_line_beginning($registrar, 
$configuration_informations, $tree)
 
 Protect hash character at beginning of line if the line is a cpp
 line directive.  The I<$registrar> and I<$configuration_informations>
-arguments maybe undef, if they are defined they are used for
+arguments may be undef, if they are defined they are used for
 error reporting in case an hash character could not be protected
 because it appeared in a raw environment.
 
 =item move_index_entries_after_items_in_tree($tree)
 
-In C<@enumerate> and C<@itemize> from the tree, move index entries 
-appearing just before C<@item> after the C<@item>.  Comment lines 
+In C<@enumerate> and C<@itemize> from the tree, move index entries
+appearing just before C<@item> after the C<@item>.  Comment lines
 between index entries are moved too.
 
 =item $command = find_parent_root_command($parser, $tree_element)
 
 Find the parent root command of a tree element (sectioning command or node).
-The C<$parser> argument is optional, it is used to continue 
+The C<$parser> argument is optional, it is used to continue
 through C<@insertcopying> if in a C<@copying>.
 
 =item valid_tree_transformation($name)
@@ -3266,7 +2702,7 @@ should be kept.
 
 =head1 SEE ALSO
 
-L<Texinfo::Parser>, L<Texinfo::Convert::Converter> and L<Texinfo::Report>. 
+L<Texinfo::Parser>, L<Texinfo::Convert::Converter> and L<Texinfo::Report>.
 
 =head1 AUTHOR
 
diff --git a/tp/Texinfo/Convert/Converter.pm b/tp/Texinfo/Convert/Converter.pm
index 2b0ba6b..ea17c20 100644
--- a/tp/Texinfo/Convert/Converter.pm
+++ b/tp/Texinfo/Convert/Converter.pm
@@ -29,15 +29,15 @@ use File::Spec;
 use Encode;
 
 use Texinfo::Common;
-use Texinfo::Structuring;
 
 use Texinfo::Report;
 use Texinfo::Translations;
 
-use Texinfo::Convert::NodeNameNormalization;
-use Texinfo::Structuring;
+use Texinfo::Convert::Utils;
 use Texinfo::Convert::Unicode;
 use Texinfo::Convert::Text;
+use Texinfo::Convert::NodeNameNormalization;
+use Texinfo::Structuring;
 
 use Carp qw(cluck);
 
@@ -932,7 +932,7 @@ sub _create_destination_directory($)
   return 1;
 }
 
-sub _float_type_number($$)
+sub float_type_number($$)
 {
   my $self = shift;
   my $float = shift;
@@ -960,6 +960,60 @@ sub _float_type_number($$)
   return $tree;
 }
 
+sub float_name_caption($$)
+{
+  my $self = shift;
+  my $root = shift;
+
+  my $caption;
+  if ($root->{'extra'}->{'caption'}) {
+    $caption = $root->{'extra'}->{'caption'};
+  } elsif ($root->{'extra'}->{'shortcaption'}) {
+    $caption = $root->{'extra'}->{'shortcaption'};
+  }
+  #if ($self->get_conf('DEBUG')) {
+  #  my $caption_texi =
+  #    Texinfo::Convert::Texinfo::convert_to_texinfo({ 'contents' => 
$caption->{'contents'}});
+  #  print STDERR "  CAPTION: $caption_texi\n";
+  #}
+  my $type;
+  if ($root->{'extra'}->{'type'}->{'normalized'} ne '') {
+    $type = {'contents' => $root->{'extra'}->{'type'}->{'content'}};
+  }
+
+  my $prepended;
+  if ($type) {
+    if ($caption) {
+      if (defined($root->{'number'})) {
+        $prepended = $self->gdt('{float_type} {float_number}: ',
+            {'float_type' => $type,
+             'float_number' => $root->{'number'}});
+      } else {
+        $prepended = $self->gdt('{float_type}: ',
+          {'float_type' => $type});
+      }
+    } else {
+      if (defined($root->{'number'})) {
+        $prepended = $self->gdt("{float_type} {float_number}\n",
+            {'float_type' => $type,
+              'float_number' => $root->{'number'}});
+      } else {
+        $prepended = $self->gdt("{float_type}\n",
+            {'float_type' => $type});
+      }
+    }
+  } elsif (defined($root->{'number'})) {
+    if ($caption) {
+      $prepended = $self->gdt('{float_number}: ',
+          {'float_number' => $root->{'number'}});
+    } else {
+      $prepended = $self->gdt("{float_number}\n",
+           {'float_number' => $root->{'number'}});
+    }
+  }
+  return ($caption, $prepended);
+}
+
 # This is used when the formatted text has no comment nor new line, but
 # one want to add the comment or new line from the original arg
 sub _end_line_or_comment($$)
@@ -1244,8 +1298,8 @@ sub convert_accents($$$;$)
   my $in_upper_case = shift;
 
   my ($contents, $stack)
-      = Texinfo::Common::find_innermost_accent_contents($accent);
-  my $result = $self->convert_tree({'contents' => $contents});  
+      = Texinfo::Convert::Utils::find_innermost_accent_contents($accent);
+  my $result = $self->convert_tree({'contents' => $contents});
 
   my $encoded;
   if ($self->get_conf('ENABLE_ENCODING')) {
@@ -1588,7 +1642,7 @@ Texinfo::Convert::Converter - Parent class for Texinfo 
tree converters
 =head1 DESCRIPTION
 
 Texinfo::Convert::Converter is a super class that can be used to
-simplify converters initialization.  The class also provide some 
+simplify converters initialization.  The class also provide some
 useful methods.
 
 In turn, the converter should define some methods.  Two are
@@ -1596,23 +1650,23 @@ optional, C<converter_defaults>, 
C<converter_initialize> and
 used for initialization, to give C<Texinfo::Convert::Converter>
 some informations.
 
-The C<convert_tree> method is more or less mandatory and should 
-convert portions of Texinfo tree.  The C<output> and C<convert> 
-are not required, but customarily used by converters as entry 
-points for conversion to a file with headers and so on, or 
+The C<convert_tree> method is more or less mandatory and should
+convert portions of Texinfo tree.  The C<output> and C<convert>
+are not required, but customarily used by converters as entry
+points for conversion to a file with headers and so on, or
 conversion of a whole Texinfo tree.
 
 Existing backends may be used as examples that implement those
-methods.  C<Texinfo::Convert::Texinfo> together with 
-C<Texinfo::Convert::PlainTexinfo>, as well as 
-C<Texinfo::Convert::TextContent> are trivial examples.  
-C<Texinfo::Convert::Text> is less trivial, although still simplistic, 
+methods.  C<Texinfo::Convert::Texinfo> together with
+C<Texinfo::Convert::PlainTexinfo>, as well as
+C<Texinfo::Convert::TextContent> are trivial examples.
+C<Texinfo::Convert::Text> is less trivial, although still simple,
 while C<Texinfo::Convert::DocBook> is a real converter
-that is also not too complex.  
+that is also not too complex.
 
-L<Texinfo::Common>, L<Texinfo::Convert::Unicode> 
-and L<Texinfo::Report> document modules or additional function 
-that may be useful for backends, while the parsed Texinfo tree is 
+L<Texinfo::Common>, L<Texinfo::Convert::Unicode>
+and L<Texinfo::Report> document modules or additional function
+that may be useful for backends, while the parsed Texinfo tree is
 described in L<Texinfo::Parser>.
 
 
@@ -1621,7 +1675,7 @@ described in L<Texinfo::Parser>.
 =head2 Initialization
 
 A module subclassing C<Texinfo::Convert::Converter> is created by calling
-the C<converter> method that should be inherited from 
+the C<converter> method that should be inherited from
 C<Texinfo::Convert::Converter>.
 
 =over
@@ -1629,12 +1683,12 @@ C<Texinfo::Convert::Converter>.
 =item $converter = MyConverter->converter($options)
 
 The I<$options> hash reference holds options for the converter.  In
-this option hash reference a L<parser object|Texinfo::Parser> 
-may be associated with the I<parser> key.  The other options 
+this option hash reference a L<parser object|Texinfo::Parser>
+may be associated with the I<parser> key.  The other options
 should be configuration options described in the Texinfo manual.
 Those options, when appropriate, override the document content.
 
-The C<converter> function returns a converter object (a blessed hash 
+The C<converter> function returns a converter object (a blessed hash
 reference) after checking the options and performing some initializations,
 especially when a parser is given among the options.  The converter is
 also initialized as a L<Texinfo::Report>.
@@ -1659,8 +1713,13 @@ converter initialization.
 
 =head2 Helper methods
 
-C<Texinfo::Convert::Converter> provides methods
-that may be useful for every converter:
+The module provides methods that may be useful for converter.
+Most methods take a I<$converter> as argument to get some
+information and use methods for error reporting, see L<Texinfo::Report>.  Also
+to translate strings, see L<Texinfo::Translations>.  For
+useful methods that need a converter optionally and can be used
+in converters that do not inherit from Texinfo::Convert::Converter,
+see L<Texinfo::Convert::Utils>.
 
 =over
 
@@ -1682,7 +1741,7 @@ format, like the splitting for example.
 
 =item $result = $converter->convert_document_sections($root, $file_handler)
 
-This method splits the I<$root> Texinfo tree at sections and 
+This method splits the I<$root> Texinfo tree at sections and
 calls C<convert_tree> on the elements.  If the optional I<$file_handler>
 is given in argument, the result are output in I<$file_handler>, otherwise
 the resulting string is returned.
@@ -1694,6 +1753,19 @@ commands nested.  The function returns the accents 
formatted either
 as encoded letters, or formatted using I<\&format_accents>.
 If I<$in_upper_case> is set, the result should be uppercased.
 
+=item ($caption, $prepended) = $converter->float_name_caption ($float)
+
+I<$float> is a texinfo tree C<@float> element.  This function
+returns the caption that should be used for the float formatting
+and the I<$prepended> texinfo tree combining the type and label
+of the float.
+
+=item $tree = $converter->float_type_number($float)
+
+I<$float> is a texinfo tree C<@float> element.  This function
+returns the type and number of the float as a texinfo tree with
+translations.
+
 =back
 
 Other C<Texinfo::Convert::Converter> methods target conversion to XML:
@@ -1713,9 +1785,9 @@ Returns an XML comment for I<$text>.
 I<$text> is the text appearing within an accent command.  I<$accent_command>
 should be a Texinfo tree element corresponding to an accent command taking
 an argument.  I<$in_upper_case> is optional, and, if set, the text is put
-in upper case.  The function returns the accented letter as XML entity 
+in upper case.  The function returns the accented letter as XML entity
 if possible.  I<$use_numeric_entities> is also optional, and, if set, and
-there is no XML entity, the numerical entity corresponding to Unicode 
+there is no XML entity, the numerical entity corresponding to Unicode
 points is preferred to an ASCII transliteration.  If I<$use_numeric_entities>
 is set numerical entities are also used for diacritics instead of ASCII
 characters.
@@ -1723,7 +1795,7 @@ characters.
 =item $result = $converter->xml_accents($accent_command, $in_upper_case)
 
 I<$accent_command> is an accent command, which may have other accent
-commands nested.  If I<$in_upper_case> is set, the result should be 
+commands nested.  If I<$in_upper_case> is set, the result should be
 upper cased.  The function returns the accents formatted as XML.
 
 =back
@@ -1740,8 +1812,8 @@ specification.
 
 =head1 SEE ALSO
 
-L<Texinfo::Common>, L<Texinfo::Convert::Unicode>, L<Texinfo::Report> 
-and L<Texinfo::Parser>.  
+L<Texinfo::Common>, L<Texinfo::Convert::Unicode>, L<Texinfo::Report>,
+L<Texinfo::Translations>, L<Texinfo::Convert::Utils> and L<Texinfo::Parser>.
 
 =head1 AUTHOR
 
diff --git a/tp/Texinfo/Convert/DocBook.pm b/tp/Texinfo/Convert/DocBook.pm
index 5b6d475..d00eaf6 100644
--- a/tp/Texinfo/Convert/DocBook.pm
+++ b/tp/Texinfo/Convert/DocBook.pm
@@ -22,13 +22,16 @@ package Texinfo::Convert::DocBook;
 use 5.00405;
 use strict;
 
-use Texinfo::Convert::Converter;
 use Texinfo::Common;
+
+# for debugging
+use Texinfo::Convert::Texinfo;
+
 use Texinfo::Convert::Unicode;
+use Texinfo::Convert::Utils;
 use Texinfo::Convert::Text;
+use Texinfo::Convert::Converter;
 use Texinfo::Convert::Plaintext;
-# for debugging
-use Texinfo::Convert::Texinfo;
 use Data::Dumper;
 use Carp qw(cluck);
 
@@ -575,14 +578,15 @@ sub _convert($$;$)
       } else {
         $command = $root->{'cmdname'};
       }
-      if ($self->{'translated_commands'}->{$command}) {
-        return $self->_convert(Texinfo::Common::translated_command_tree($self,
-                                                                   $command));
+      my $translated_tree = 
Texinfo::Convert::Utils::translated_command_tree($self,
+                                                                           
$command);
+      if ($translated_tree) {
+        return $self->_convert($translated_tree);
       } else {
         return $docbook_no_arg_commands_formatting{$command};
       }
     } elsif ($root->{'cmdname'} eq 'today') {
-      return $self->_convert(Texinfo::Common::expand_today($self));
+      return $self->_convert(Texinfo::Convert::Utils::expand_today($self));
     } elsif ($Texinfo::Common::accent_commands{$root->{'cmdname'}}) {
       return $self->convert_accents($root, \&docbook_accent,
                $self->{'document_context'}->[-1]->{'upper_case'}->[-1]);
@@ -657,7 +661,7 @@ sub _convert($$;$)
       if ($type eq 'text') {
         if ($root->{'cmdname'} eq 'verbatiminclude') {
           my $verbatim_include_verbatim
-            = Texinfo::Common::expand_verbatiminclude($self, $self, $root);
+            = Texinfo::Convert::Utils::expand_verbatiminclude($self, $self, 
$root);
           if (defined($verbatim_include_verbatim)) {
             $result .= $self->_convert($verbatim_include_verbatim);
           } else {
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index bce4a42..54d6e7e 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -58,10 +58,11 @@ use strict;
 
 use Texinfo::Common;
 use Texinfo::Structuring;
-use Texinfo::Convert::Converter;
+use Texinfo::Convert::Unicode;
+use Texinfo::Convert::Utils;
 use Texinfo::Convert::Texinfo;
 use Texinfo::Convert::Text;
-use Texinfo::Convert::Unicode;
+use Texinfo::Convert::Converter;
 use Texinfo::Convert::NodeNameNormalization;
 
 use Texinfo::Config;
@@ -570,7 +571,7 @@ sub command_text($$;$)
         $tree = {'type' => '_code',
                  'contents' => $command->{'extra'}->{'node_content'}};
       } elsif ($command->{'cmdname'} and ($command->{'cmdname'} eq 'float')) {
-        $tree = $self->_float_type_number($command); 
+        $tree = $self->float_type_number($command);
       } elsif ($command->{'extra'}->{'missing_argument'}) {
         if ($type eq 'tree' or $type eq 'tree_nonumber') {
           return {};
@@ -1368,9 +1369,11 @@ sub _convert_no_arg_command($$$)
   }
 
   my $result;
-  if ($self->{'translated_commands'}->{$cmdname}) {
-    return $self->convert_tree(
-         $self->gdt($self->{'translated_commands'}->{$cmdname}));
+  
+  my $translated_tree = Texinfo::Convert::Utils::translated_command_tree($self,
+                                                                       
$cmdname);
+  if ($translated_tree) {
+    return $self->convert_tree($translated_tree);
   }
   if ($self->in_preformatted() or $self->in_math()) {
     $result = 
$self->{'no_arg_commands_formatting'}->{'preformatted'}->{$cmdname};
@@ -1392,7 +1395,7 @@ sub _convert_today_command($$$)
   my $cmdname = shift;
   my $command = shift;
 
-  my $tree = $self->Texinfo::Common::expand_today();
+  my $tree = $self->Texinfo::Convert::Utils::expand_today();
   return $self->convert_tree($tree);
 }
 
@@ -2839,7 +2842,7 @@ sub _convert_verbatiminclude_command($$$$)
   my $args = shift;
 
   my $verbatim_include_verbatim 
-    = Texinfo::Common::expand_verbatiminclude($self, $self, $command);
+    = Texinfo::Convert::Utils::expand_verbatiminclude($self, $self, $command);
   if (defined($verbatim_include_verbatim)) {
     return $self->convert_tree($verbatim_include_verbatim);
   } else {
@@ -3087,8 +3090,8 @@ sub _convert_float_command($$$$$)
   my $args = shift;
   my $content = shift;
 
-  my ($caption, $prepended) = Texinfo::Common::float_name_caption($self,
-                                                                   $command);
+  my ($caption, $prepended)
+     = Texinfo::Convert::Converter::float_name_caption($self, $command);
   my $caption_text = '';
   my $prepended_text;
   if ($self->in_string()) {
@@ -4364,7 +4367,7 @@ sub _convert_def_line_type($$$$)
     $index_label = " id=\"$index_id\"";
   }
   my $arguments
-    = Texinfo::Common::definition_arguments_content($command);
+    = Texinfo::Convert::Utils::definition_arguments_content($command);
 
   if (!$self->get_conf('DEF_TABLE')) {
     my $tree;
@@ -4568,7 +4571,7 @@ sub _convert_def_line_type($$$$)
     if ($command->{'extra'} and $command->{'extra'}->{'def_parsed_hash'}
         and %{$command->{'extra'}->{'def_parsed_hash'}}) {
       my $parsed_definition_category 
-         = Texinfo::Common::definition_category ($self, $command);
+         = Texinfo::Convert::Utils::definition_category ($self, $command);
       if ($parsed_definition_category) {
         $category_prepared = $self->convert_tree({'type' => '_code',
                    'contents' => [$parsed_definition_category]});
diff --git a/tp/Texinfo/Convert/LaTeX.pm b/tp/Texinfo/Convert/LaTeX.pm
index 19a9f6d..bc14d74 100644
--- a/tp/Texinfo/Convert/LaTeX.pm
+++ b/tp/Texinfo/Convert/LaTeX.pm
@@ -2601,7 +2601,8 @@ sub _convert($$)
       }
       return $result;
     } elsif ($command eq 'verbatiminclude') {
-      my $expansion = Texinfo::Common::expand_verbatiminclude($self, $self, 
$root);
+      my $expansion = Texinfo::Convert::Utils::expand_verbatiminclude($self,
+                                                              $self, $root);
       unshift @{$self->{'current_contents'}->[-1]}, $expansion
         if ($expansion);
       return $result;
@@ -2829,7 +2830,7 @@ sub _convert($$)
     if ($root->{'type'} eq 'def_line') {
       if ($root->{'extra'} and $root->{'extra'}->{'def_parsed_hash'}
              and %{$root->{'extra'}->{'def_parsed_hash'}}) {
-        my $arguments = Texinfo::Common::definition_arguments_content($root);
+        my $arguments = 
Texinfo::Convert::Utils::definition_arguments_content($root);
         my $tree;
         my $command;
         if ($Texinfo::Common::def_aliases{$root->{'extra'}->{'def_command'}}) {
diff --git a/tp/Texinfo/Convert/NodeNameNormalization.pm 
b/tp/Texinfo/Convert/NodeNameNormalization.pm
index 6ff31c4..e757883 100644
--- a/tp/Texinfo/Convert/NodeNameNormalization.pm
+++ b/tp/Texinfo/Convert/NodeNameNormalization.pm
@@ -276,6 +276,82 @@ sub _convert($;$)
   return $result;
 }
 
+# Called from Texinfo::ParserNonXS and Texinfo::XS::parsetexi::Parsetexi.
+# This should be considered an internal function of the parsers for all
+# purposes, it is here to avoid code duplication.
+# Sets $self->{'nodes'} and $self->{'labels'} based on $self->{'targets'}.
+sub set_nodes_list_labels($$$)
+{
+  my $self = shift;
+  my $registrar = shift;
+  my $configuration_informations = shift;
+
+  $self->{'nodes'} = [];
+  my %labels = ();
+  if (defined $self->{'targets'}) {
+    for my $target (@{$self->{'targets'}}) {
+      if ($target->{'cmdname'} eq 'node') {
+        if ($target->{'extra'}->{'nodes_manuals'}) {
+          for my $node_manual (@{$target->{'extra'}{'nodes_manuals'}}) {
+            if (defined $node_manual
+                  and defined $node_manual->{'node_content'}) {
+              my $normalized = 
Texinfo::Convert::NodeNameNormalization::normalize_node(
+                                    {'contents' => 
$node_manual->{'node_content'}});
+              $node_manual->{'normalized'} = $normalized;
+            }
+          }
+        }
+      }
+      if (defined $target->{'extra'}
+            and defined $target->{'extra'}->{'node_content'}) {
+        my $normalized = 
Texinfo::Convert::NodeNameNormalization::normalize_node(
+                             {'contents' => 
$target->{'extra'}->{'node_content'}});
+
+        if ($normalized !~ /[^-]/) {
+          $registrar->line_error($configuration_informations,
+               sprintf(__("empty node name after expansion `%s'"),
+                     Texinfo::Convert::Texinfo::convert_to_texinfo({'contents'
+                                   => $target->{'extra'}->{'node_content'}})),
+                            $target->{'line_nr'});
+          delete $target->{'extra'}->{'node_content'};
+        } else {
+          if (defined $labels{$normalized}) {
+            $registrar->line_error($configuration_informations,
+              sprintf(__("\@%s `%s' previously defined"), 
+                         $target->{'cmdname'}, 
+                   Texinfo::Convert::Texinfo::convert_to_texinfo({'contents'
+                                    => $target->{'extra'}->{'node_content'}})),
+                               $target->{'line_nr'});
+            $registrar->line_error($configuration_informations,
+              sprintf(__("here is the previous definition as \@%s"),
+                               $labels{$normalized}->{'cmdname'}),
+                       $labels{$normalized}->{'line_nr'});
+            delete $target->{'extra'}->{'node_content'};
+          } else {
+            $labels{$normalized} = $target;
+            $target->{'extra'}->{'normalized'} = $normalized;
+            if ($target->{'cmdname'} eq 'node') {
+              if ($target->{'extra'}
+                  and $target->{'extra'}{'node_argument'}) {
+                $target->{'extra'}{'node_argument'}{'normalized'}
+                  = $normalized;
+              }
+              push @{$self->{'nodes'}}, $target;
+            }
+          }
+        }
+      } else {
+        if ($target->{'cmdname'} eq 'node') {
+          $registrar->line_error($configuration_informations,
+               sprintf(__("empty argument in \@%s"),
+                  $target->{'cmdname'}), $target->{'line_nr'});
+          delete $target->{'extra'}->{'node_content'};
+        }
+      }
+    }
+  }
+  $self->{'labels'} = \%labels;
+}
 1;
 
 __END__
diff --git a/tp/Texinfo/Convert/Plaintext.pm b/tp/Texinfo/Convert/Plaintext.pm
index 30c7504..85f8200 100644
--- a/tp/Texinfo/Convert/Plaintext.pm
+++ b/tp/Texinfo/Convert/Plaintext.pm
@@ -26,12 +26,14 @@ use if $] >= 5.012, feature => qw(unicode_strings);
 
 use strict;
 
-use Texinfo::Convert::Converter;
 use Texinfo::Common;
 use Texinfo::Convert::Texinfo;
+use Texinfo::Convert::Utils;
+use Texinfo::Convert::Text;
+use Texinfo::Convert::Utils;
+use Texinfo::Convert::Converter;
 use Texinfo::Convert::Paragraph;
 
-use Texinfo::Convert::Text;
 
 require Exporter;
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
@@ -1699,7 +1701,7 @@ sub _convert($$)
       }
       return $result;
     } elsif ($command eq 'today') {
-      my $today = $self->Texinfo::Common::expand_today();
+      my $today = $self->Texinfo::Convert::Utils::expand_today();
       unshift @{$self->{'current_contents'}->[-1]}, $today;
     } elsif (exists($brace_no_arg_commands{$command})) {
       my $text;
@@ -2037,7 +2039,7 @@ sub _convert($$)
             and $root->{'extra'}->{'label'}->{'cmdname'} eq 'float') {
           my $float = $root->{'extra'}->{'label'};
 
-          my $name = $self->_float_type_number($float);
+          my $name = $self->float_type_number($float);
           $args[1] = $name->{'contents'};
         }
         if ($command eq 'inforef' and scalar(@args) == 3) {
@@ -2605,7 +2607,8 @@ sub _convert($$)
       }
       return $result;
     } elsif ($command eq 'verbatiminclude') {
-      my $expansion = Texinfo::Common::expand_verbatiminclude($self, $self, 
$root);
+      my $expansion = Texinfo::Convert::Utils::expand_verbatiminclude($self,
+                                                               $self, $root);
       unshift @{$self->{'current_contents'}->[-1]}, $expansion
         if ($expansion);
       return '';
@@ -2637,7 +2640,7 @@ sub _convert($$)
                    or !@{$float->{'args'}->[1]->{'contents'}};
           my $float_label_text = $self->convert_line({'type' => '_code',
              'contents' => $float->{'args'}->[1]->{'contents'}});
-          my $float_entry = $self->_float_type_number($float);
+          my $float_entry = $self->float_type_number($float);
           my $float_entry_text = ':';
           if (defined($float_entry)) {
             $float_entry->{'type'} = 'frenchspacing';
@@ -2805,7 +2808,7 @@ sub _convert($$)
     } elsif ($root->{'type'} eq 'def_line') {
       if ($root->{'extra'} and $root->{'extra'}->{'def_parsed_hash'}
              and %{$root->{'extra'}->{'def_parsed_hash'}}) {
-        my $arguments = Texinfo::Common::definition_arguments_content($root);
+        my $arguments = 
Texinfo::Convert::Utils::definition_arguments_content($root);
         my $tree;
         my $command;
         if ($Texinfo::Common::def_aliases{$root->{'extra'}->{'def_command'}}) {
@@ -3245,8 +3248,8 @@ sub _convert($$)
                or $root->{'extra'}->{'caption'} or 
$root->{'extra'}->{'shortcaption'})) {
         
         $result .= _add_newline_if_needed($self);
-        my ($caption, $prepended) = Texinfo::Common::float_name_caption($self,
-                                                                        $root);
+        my ($caption, $prepended)
+             = Texinfo::Convert::Converter::float_name_caption($self, $root);
         if ($prepended) {
           $prepended->{'type'} = 'frenchspacing';
           my $float_number = $self->convert_line ($prepended);
diff --git a/tp/Texinfo/Convert/Text.pm b/tp/Texinfo/Convert/Text.pm
index 0979bda..996543e 100644
--- a/tp/Texinfo/Convert/Text.pm
+++ b/tp/Texinfo/Convert/Text.pm
@@ -27,6 +27,9 @@ use Texinfo::Common;
 use Texinfo::Convert::Unicode;
 # for debugging
 use Texinfo::Convert::Texinfo;
+# misc functions and data
+use Texinfo::Convert::Utils;
+
 use Data::Dumper;
 use Carp qw(cluck carp);
 
@@ -217,7 +220,7 @@ sub text_accents($;$$)
   my $set_case = shift;
   
   my ($contents, $stack)
-      = Texinfo::Common::find_innermost_accent_contents($accent);
+      = Texinfo::Convert::Utils::find_innermost_accent_contents($accent);
 
   my $options = {};
   $options->{'enabled_encoding'} = $encoding if (defined($encoding));
@@ -253,8 +256,9 @@ sub brace_no_arg_command($;$)
                        $command, $encoding);
   }
   if (!defined($result) and $options and $options->{'converter'}) {
-    my $tree = Texinfo::Common::translated_command_tree(
-                  $options->{'converter'}, $command);
+    my $tree
+      = 
Texinfo::Convert::Utils::translated_command_tree($options->{'converter'},
+                                                                         
$command);
     if ($tree) {
       $result = _convert($tree, $options);
     }
@@ -297,8 +301,8 @@ sub heading($$$;$$)
   # REMARK to get the numbering right in case of an indented text, the
   # indentation should be given here.  But this should never happen as
   # the only @-commands allowed in indented context are not numbered.
-  $text = Texinfo::Common::numbered_heading($converter, $current, $text, 
-                                            $numbered);
+  $text = Texinfo::Convert::Utils::numbered_heading($converter, $current, 
$text,
+                                                     $numbered);
   return '' if ($text !~ /\S/);
   my $result = $text ."\n";
   if (defined($indent_length)) {
@@ -405,15 +409,15 @@ sub _convert($;$)
           and $sort_brace_no_arg_commands{$root->{'cmdname'}}) {
         return $sort_brace_no_arg_commands{$root->{'cmdname'}};
       } elsif ($options->{'converter'}) {
-        return _convert(Texinfo::Common::expand_today($options->{'converter'}),
-                       $options);
+        return 
_convert(Texinfo::Convert::Utils::expand_today($options->{'converter'}),
+                        $options);
       } elsif ($options->{'TEST'}) {
         return 'a sunny day';
       } else {
         my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
           = localtime(time);
         $year += ($year < 70) ? 2000 : 1900;
-        return "$Texinfo::Common::MONTH_NAMES[$mon] $mday, $year";
+        return "$Texinfo::Convert::Utils::MONTH_NAMES[$mon] $mday, $year";
       }
     } elsif (defined($text_brace_no_arg_commands{$root->{'cmdname'}})) {
       return brace_no_arg_command($root, $options);
@@ -516,8 +520,8 @@ sub _convert($;$)
         }
       } elsif ($root->{'cmdname'} eq 'verbatiminclude') {
         my $verbatim_include_verbatim
-          = Texinfo::Common::expand_verbatiminclude($options->{'converter'},
-                                                    $options, $root);
+          = Texinfo::Convert::Utils::expand_verbatiminclude(
+                               $options->{'converter'}, $options, $root);
         if (defined($verbatim_include_verbatim)) {
           $result .= _convert($verbatim_include_verbatim, $options);
         }
@@ -545,7 +549,8 @@ sub _convert($;$)
     if ($root->{'extra'} and $root->{'extra'}->{'def_parsed_hash'}
              and %{$root->{'extra'}->{'def_parsed_hash'}}) {
       my $parsed_definition_category
-        = Texinfo::Common::definition_category ($options->{'converter'}, 
$root);
+        = Texinfo::Convert::Utils::definition_category($options->{'converter'},
+                                                       $root);
       my @contents = ($parsed_definition_category, {'text' => ': '});
       if ($root->{'extra'}->{'def_parsed_hash'}->{'type'}) {
         push @contents, ($root->{'extra'}->{'def_parsed_hash'}->{'type'},
@@ -553,7 +558,7 @@ sub _convert($;$)
       }
       push @contents, $root->{'extra'}->{'def_parsed_hash'}->{'name'};
 
-      my $arguments = Texinfo::Common::definition_arguments_content($root);
+      my $arguments = 
Texinfo::Convert::Utils::definition_arguments_content($root);
       if ($arguments) {
         push @contents, {'text' => ' '};
         push @contents, @$arguments;
diff --git a/tp/Texinfo/Convert/TextContent.pm 
b/tp/Texinfo/Convert/TextContent.pm
index 9bac7fd..4533f76 100644
--- a/tp/Texinfo/Convert/TextContent.pm
+++ b/tp/Texinfo/Convert/TextContent.pm
@@ -22,9 +22,10 @@ package Texinfo::Convert::TextContent;
 use 5.00405;
 use strict;
 
-use Texinfo::Convert::Converter;
-use Texinfo::Convert::Text;
 use Texinfo::Common;
+use Texinfo::Convert::Utils;
+use Texinfo::Convert::Text;
+use Texinfo::Convert::Converter;
 
 use vars qw($VERSION @ISA);
 @ISA = qw(Texinfo::Convert::Converter);
@@ -121,7 +122,7 @@ sub _convert($$)
       my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
         = localtime(time);
       $year += ($year < 70) ? 2000 : 1900;
-      return "$Texinfo::Common::MONTH_NAMES[$mon] $mday, $year";
+      return "$Texinfo::Convert::Utils::MONTH_NAMES[$mon] $mday, $year";
     } elsif 
(defined($Texinfo::Convert::Text::text_brace_no_arg_commands{$root->{'cmdname'}}))
 {
       return Texinfo::Convert::Text::brace_no_arg_command($root, undef);
     } elsif ($Texinfo::Common::accent_commands{$root->{'cmdname'}}) {
diff --git a/tp/Texinfo/Convert/Unicode.pm b/tp/Texinfo/Convert/Unicode.pm
index ef711e9..63b0636 100644
--- a/tp/Texinfo/Convert/Unicode.pm
+++ b/tp/Texinfo/Convert/Unicode.pm
@@ -1575,7 +1575,7 @@ Texinfo::Convert::Unicode - Handle conversion to Unicode
                                    unicode_text);
 
   my ($innermost_contents, $stack)
-      = Texinfo::Common::find_innermost_accent_contents($accent);
+      = Texinfo::Convert::Utils::find_innermost_accent_contents($accent);
   
   my $formatted_accents = encoded_accents ($converter,
                  convert_to_text($innermost_contents), $stack, $encoding,
@@ -1613,7 +1613,7 @@ converter object in I<$format_accent> (I<$format_accent> 
described below).
 I<$text> is the text appearing within nested accent commands.  I<$stack> is
 an array reference holding the nested accents texinfo element trees.  For
 example, I<$text> could be the formatted content and I<$stack> the stack 
-returned by C<Texinfo::Common::find_innermost_accent_contents>.  I<$encoding> 
+returned by C<Texinfo::Convert::Utils::find_innermost_accent_contents>.  
I<$encoding> 
 is the encoding the accented characters should be encoded to.  If 
 I<$encoding> not set the I<$result> is set to undef.  I<$format_accent> 
 is a function reference that is used to format the accent commands if 
diff --git a/tp/Texinfo/Convert/Utils.pm b/tp/Texinfo/Convert/Utils.pm
new file mode 100644
index 0000000..08db26c
--- /dev/null
+++ b/tp/Texinfo/Convert/Utils.pm
@@ -0,0 +1,368 @@
+# Utils.pm: miscellaneous functions usable in simple converters
+#
+# Copyright 2010-2021 Free Software Foundation, Inc.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License,
+# or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Original author: Patrice Dumas <pertusus@free.fr>
+#
+# This module contains the methods that can be used in converters
+# even if they do not inherit Texinfo::Convert::Converter.  In practice
+# it means that the converter argument will not be defined and
+# there will be no error reporting nor string translation in that case.
+# Some methods still require a converter, it means that they are used
+# conditionally in some converters that do not inherit
+# Texinfo::Convert::Converter but can have gotten a converter object
+# (case of Texinfo::Convert::Text).
+
+
+package Texinfo::Convert::Utils;
+
+use strict;
+
+use Texinfo::Common;
+use Texinfo::Convert::Texinfo;
+
+# debugging
+use Carp qw(cluck);
+
+require Exporter;
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+@ISA = qw(Exporter);
+
+%EXPORT_TAGS = ( 'all' => [ qw(
+definition_category
+expand_today
+expand_verbatiminclude
+numbered_heading
+) ] );
+
+@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+$VERSION = '6.8dev';
+
+
+our @MONTH_NAMES =
+    (
+     'January', 'February', 'March', 'April', 'May',
+     'June', 'July', 'August', 'September', 'October',
+     'November', 'December'
+    );
+
+# this method requires a converter.
+sub expand_today($)
+{
+  my $self = shift;
+  if ($self->get_conf('TEST')) {
+    return {'text' => 'a sunny day'};
+  }
+
+  my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
+    = ($ENV{SOURCE_DATE_EPOCH}
+        ? gmtime($ENV{SOURCE_DATE_EPOCH})
+        : localtime(time));
+  # See https://reproducible-builds.org/specs/source-date-epoch/.
+
+  $year += ($year < 70) ? 2000 : 1900;
+  return $self->gdt('{month} {day}, {year}',
+          { 'month' => $self->gdt($MONTH_NAMES[$mon]),
+            'day' => $mday, 'year' => $year });
+}
+
+sub definition_arguments_content($)
+{
+  my $root = shift;
+
+  return undef if (!defined($root->{'extra'})
+                    or !defined($root->{'extra'}->{'def_parsed_hash'}));
+  my @args = @{$root->{'args'}->[0]->{'contents'}};
+  while (@args) {
+    last if (defined($args[0]->{'extra'})
+             and defined($args[0]->{'extra'}->{'def_role'})
+             and $args[0]->{'extra'}->{'def_role'} ne 'spaces'
+             and !$root->{'extra'}->{'def_parsed_hash'}
+                       ->{$args[0]->{'extra'}->{'def_role'}});
+    shift @args;
+  }
+  if (scalar(@args) > 0) {
+    return \@args;
+  } else {
+    return undef;
+  }
+}
+
+# $SELF converter argument is optional
+sub definition_category($$)
+{
+  my $self = shift;
+  my $current = shift;
+
+  return undef if (!$current->{'extra'}
+      or !$current->{'extra'}->{'def_parsed_hash'});
+
+  my $arg_category = $current->{'extra'}->{'def_parsed_hash'}->{'category'};
+  my $arg_class = $current->{'extra'}->{'def_parsed_hash'}->{'class'};
+
+  return $arg_category
+    if (!defined($arg_class));
+  
+  my $style = 
$Texinfo::Common::command_index{$current->{'extra'}->{'def_command'}};
+  if ($style eq 'fn') {
+    if ($self) {
+      return $self->gdt('{category} on {class}', { 'category' => $arg_category,
+                                          'class' => $arg_class });
+    } else {
+      return {'contents' => [$arg_category, {'text' => ' on '}, $arg_class]};
+    }
+  } elsif ($style eq 'vr') {
+    if ($self) {
+      return $self->gdt('{category} of {class}', { 'category' => $arg_category,
+                                          'class' => $arg_class });
+    } else {
+      return {'contents' => [$arg_category, {'text' => ' of '}, $arg_class]};
+    }
+  }
+}
+
+# find the accent commands stack and the innermost text contents
+sub find_innermost_accent_contents($;$)
+{
+  my $current = shift;
+  my $encoding = shift;
+  my @accent_commands = ();
+  my $debug = 0;
+ ACCENT:
+  while (1) {
+    # the following can happen if called with a bad tree
+    if (!$current->{'cmdname'}
+        or !$Texinfo::Common::accent_commands{$current->{'cmdname'}}) {
+      #print STDERR "BUG: Not an accent command in accent\n";
+      cluck "BUG: Not an accent command in accent\n";
+      #print STDERR 
Texinfo::Convert::Texinfo::convert_to_texinfo($current)."\n";
+      #print STDERR Data::Dumper->Dump([$current]);
+      last;
+    }
+    push @accent_commands, $current;
+    # A bogus accent, that may happen
+    if (!$current->{'args'}) {
+      return ([], \@accent_commands);
+    }
+    my $arg = $current->{'args'}->[0];
+    if (!$arg->{'contents'}) {
+      print STDERR "BUG: No content in accent command\n";
+      #print STDERR Data::Dumper->Dump([$current]);
+      #print STDERR 
Texinfo::Convert::Texinfo::convert_to_texinfo($current)."\n";
+      return ([], \@accent_commands);
+    }
+    # inside the argument of an accent
+    my $text_contents = [];
+    foreach my $content (@{$arg->{'contents'}}) {
+      if (!($content->{'cmdname'} and ($content->{'cmdname'} eq 'c'
+                                  or $content->{'cmdname'} eq 'comment'))) {
+        if ($content->{'cmdname'} and 
$Texinfo::Common::accent_commands{$content->{'cmdname'}}) {
+          $current = $content;
+          next ACCENT;
+        } else {
+          push @$text_contents, $content;
+        }
+      }
+    }
+    # we go here if there was no nested accent
+    return ($text_contents, \@accent_commands);
+  }
+}
+
+# $REGISTRAR argument (in practice, a converter) is optional.
+# $CONFIGURATION_INFORMATIONS is also optional, but without this
+# argument and the 'INCLUDE_DIRECTORIES' available through
+# get_conf(), the included file can only be found in specific
+# circumstances.
+sub expand_verbatiminclude($$$)
+{
+  my $registrar = shift;
+  my $configuration_informations = shift;
+  my $current = shift;
+
+  return unless ($current->{'extra'} and 
defined($current->{'extra'}->{'text_arg'}));
+  my $text = $current->{'extra'}->{'text_arg'};
+  my $file = Texinfo::Common::locate_include_file($configuration_informations, 
$text);
+
+  my $verbatiminclude;
+
+  if (defined($file)) {
+    if (!open(VERBINCLUDE, $file)) {
+      if ($registrar) {
+        $registrar->line_error($configuration_informations,
+                               sprintf(__("could not read %s: %s"), $file, $!),
+                               $current->{'line_nr'});
+      }
+    } else {
+      if (defined $current->{'extra'}->{'input_perl_encoding'}) {
+        binmode(VERBINCLUDE, ":encoding("
+                             . $current->{'extra'}->{'input_perl_encoding'}
+                             . ")");
+      }
+      $verbatiminclude = { 'cmdname' => 'verbatim',
+                           'parent' => $current->{'parent'},
+                           'extra' =>
+                        {'text_arg' => $current->{'extra'}->{'text_arg'}} };
+      while (<VERBINCLUDE>) {
+        push @{$verbatiminclude->{'contents'}},
+                  {'type' => 'raw', 'text' => $_ };
+      }
+      if (!close (VERBINCLUDE)) {
+        if ($registrar) {
+          $registrar->document_warn(
+                 $configuration_informations, sprintf(__(
+                      "error on closing \@verbatiminclude file %s: %s"),
+                             $file, $!));
+        }
+      }
+    }
+  } elsif ($registrar) {
+    $registrar->line_error($configuration_informations,
+                           sprintf(__("\@%s: could not find %s"),
+                                        $current->{'cmdname'}, $text),
+                           $current->{'line_nr'});
+  }
+  return $verbatiminclude;
+}
+
+sub numbered_heading($$$;$)
+{
+  my $self = shift;
+  my $current = shift;
+  my $text = shift;
+  my $numbered = shift;
+
+  my $number;
+  if (defined($current->{'number'}) and ($numbered or !defined($numbered))) {
+    $number = $current->{'number'};
+  }
+
+  my $result;
+  if ($self) {
+    if (defined($number)) {
+      if ($current->{'cmdname'} eq 'appendix' and $current->{'level'} == 1) {
+        $result = $self->gdt('Appendix {number} {section_title}',
+                   {'number' => $number, 'section_title' => $text},
+                   'translated_text');
+      } else {
+        $result = $self->gdt('{number} {section_title}',
+                   {'number' => $number, 'section_title' => $text},
+                   'translated_text');
+      }
+    } else {
+      $result = $text;
+    }
+  } else {
+    $result = $text;
+    $result = $number.' '.$result if (defined($number));
+    if ($current->{'cmdname'} eq 'appendix' and $current->{'level'} == 1) {
+      $result = 'Appendix '.$result;
+    }
+  }
+  chomp ($result);
+  return $result;
+}
+
+# this requires a converter argument.  It is defined here, in order
+# to hide from the caller the 'translated_commands' converter key
+# that is set by Texinfo::Convert::Converter.  This is especially
+# relevant for converters that do not inherit Texinfo::Convert::Converter
+# and call the method on a converter object they got (case of
+# Texinfo::Convert::Text).
+sub translated_command_tree($$)
+{
+  my $self = shift;
+  my $cmdname = shift;
+  if ($self->{'translated_commands'}->{$cmdname}) {
+    return $self->gdt($self->{'translated_commands'}->{$cmdname});
+  }
+  return undef;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Texinfo::Convert::Utils - miscellaneous functions usable in simple converters
+
+=head1 SYNOPSIS
+
+  use Texinfo::Convert::Utils qw(expand_today expand_verbatiminclude);
+  
+  my $today_tree = expand_today($converter);
+  my $verbatiminclude_tree
+     = expand_verbatiminclude(undef, $converter, $verbatiminclude);
+
+=head1 DESCRIPTION
+
+miscellaneous methods that may be useful for backends converting texinfo
+trees.  This module contains the methods that can be used in converters
+that do not inherit Texinfo::Convert::Converter.
+
+=head1 METHODS
+
+No method is exported in the default case.
+
+Most methods takes a I<$converter> as argument, in general optionally,
+to get some information and use methods for error reporting,
+see L<Texinfo::Convert::Converter> and L<Texinfo::Report>.  Also
+to tranlate strings, see L<Texinfo::Translations>.
+
+=over
+
+=item $tree = definition_category($converter, $def_line)
+
+The I<$converter> argument may be undef.  I<$def_line> is a
+C<def_line> texinfo tree container.  This function
+returns a texinfo tree corresponding to the category of the
+I<$def_line> taking the class into account, if there is one.
+If I<$converter> is not defined, the resulting string won't be
+translated.
+
+=item $tree = expand_today($converter)
+
+Expand today's date, as a texinfo tree with translations.
+
+=item $tree = expand_verbatiminclude($registrar, $configuration_informations, 
$verbatiminclude)
+
+The I<$registrar> argument may be undef.  I<$verbatiminclude> is a
+C<@verbatiminclude> tree element.  This function returns a
+C<@verbatim> tree elements after finding the included file and
+reading it.  If I<$registrar> is not defined, errors messages are
+not registered.
+
+=item $result = numbered_heading ($converter, $heading_element, $heading_text, 
$do_number)
+
+The I<$converter> argument may be undef.  I<$heading_element> is
+a heading command tree element.  I<$heading_text> is the already
+formatted heading text.  if the I<$do_number> optional argument is
+defined and false, no number is used and the text is returned as is.
+This function returns the heading with a number and the appendix
+part if needed.  If I<$converter> is not defined, the resulting
+string won't be translated.
+
+=head1 SEE ALSO
+
+L<Texinfo::Convert::Converter> and L<Texinfo::Translations>.
+
+=head1 AUTHOR
+
+Patrice Dumas, E<lt>pertusus@free.frE<gt>
+
+=cut
diff --git a/tp/Texinfo/ParserNonXS.pm b/tp/Texinfo/ParserNonXS.pm
index 7e462f1..2350a22 100644
--- a/tp/Texinfo/ParserNonXS.pm
+++ b/tp/Texinfo/ParserNonXS.pm
@@ -50,16 +50,18 @@ use Storable qw(dclone); # standard in 5.007003
 
 # commands definitions
 use Texinfo::Common;
-# Error reporting and counting, translation of strings.
+# Error reporting and counting
 use Texinfo::Report;
 # encoding_alias
 use Texinfo::Encoding;
 
-# to normalize node name, anchor, float arg, and first *ref argument.
-use Texinfo::Convert::NodeNameNormalization;
 # in error messages, and for macro body expansion
 use Texinfo::Convert::Texinfo;
 
+# to normalize node name, anchor, float arg, and first *ref argument.
+use Texinfo::Convert::NodeNameNormalization;
+
+# translation of strings.
 use Texinfo::Translations;
 
 require Exporter;
@@ -5474,8 +5476,9 @@ sub _parse_texi($;$)
   }
 
   # Setup labels info and nodes list based on 'targets'
-  Texinfo::Common::set_nodes_list_labels($self, $self->{'registrar'}, $self);
-  Texinfo::Common::complete_indices($self);
+  Texinfo::Convert::NodeNameNormalization::set_nodes_list_labels($self,
+                                              $self->{'registrar'}, $self);
+  Texinfo::Translations::complete_indices($self);
   return $root;
 }
 
diff --git a/tp/Texinfo/Transformations.pm b/tp/Texinfo/Transformations.pm
index 9843455..a6269f7 100644
--- a/tp/Texinfo/Transformations.pm
+++ b/tp/Texinfo/Transformations.pm
@@ -27,6 +27,9 @@ use strict;
 use Texinfo::Common;
 use Texinfo::Structuring;
 
+# Export?
+# protect_hashchar_at_line_beginning
+
 use Carp qw(cluck);
 
 # Add raise/lowersections to be back at the normal level
@@ -747,6 +750,98 @@ sub set_menus_to_simple_menu($)
   }
 }
 
+sub _is_cpp_line($)
+{
+  my $text = shift;
+  return 1 if ($text =~ /^\s*#\s*(line)? (\d+)(( "([^"]+)")(\s+\d+)*)?\s*$/);
+  return 0;
+}
+
+sub _protect_hashchar_at_line_beginning($$$)
+{
+  my $self = shift;
+  my $type = shift;
+  my $current = shift;
+
+  my ($registrar, $configuration_informations) = @$self;
+
+  #print STDERR "$type $current "._print_current($current)."\n";
+  # if the next is a hash character at line beginning, mark it
+  if (defined($current->{'text'}) and $current->{'text'} =~ /\n$/
+      and $current->{'parent'} and $current->{'parent'}->{'contents'}) {
+    my $parent = $current->{'parent'};
+    #print STDERR "End of line in $current, parent $parent: 
(@{$parent->{'contents'}})\n";
+    my $current_found = 0;
+    foreach my $content (@{$parent->{'contents'}}) {
+      if ($current_found) {
+        #print STDERR "after $current: $content $content->{'text'}\n";
+        if ($content->{'text'} and _is_cpp_line($content->{'text'})) {
+          $content->{'extra'}->{'_protect_hashchar'} = 1;
+        }
+        last;
+      } elsif ($content eq $current) {
+        $current_found = 1;
+      }
+    }
+  }
+
+  my $protect_hash = 0;
+  # if marked, or first and a cpp_line protect a leading hash character
+  if ($current->{'extra'} and $current->{'extra'}->{'_protect_hashchar'}) {
+    delete $current->{'extra'}->{'_protect_hashchar'};
+    if (!scalar(keys(%{$current->{'extra'}}))) {
+      delete $current->{'extra'};
+    }
+    $protect_hash = 1;
+  } elsif ($current->{'parent'} and $current->{'parent'}->{'contents'}
+           and $current->{'parent'}->{'contents'}->[0]
+           and $current->{'parent'}->{'contents'}->[0] eq $current
+           and $current->{'text'}
+           and _is_cpp_line($current->{'text'})) {
+    $protect_hash = 1;
+  }
+  if ($protect_hash) {
+    my @result = ();
+    if ($current->{'type'} and $current->{'type'} eq 'raw') {
+      if ($self) {
+        my $parent = $current->{'parent'};
+        while ($parent) {
+          if ($parent->{'cmdname'} and $parent->{'line_nr'}) {
+            if ($registrar) {
+              $registrar->line_warn($configuration_informations, sprintf(__(
+                  "could not protect hash character in \@%s"), 
+                             $parent->{'cmdname'}), $parent->{'line_nr'});
+            }
+            last;
+          }
+          $parent = $parent->{'parent'};
+        }
+      }
+    } else {
+      $current->{'text'} =~ s/^(\s*)#//;
+      if ($1 ne '') {
+        push @result, {'text' => $1, 'parent' => $current->{'parent'}};
+      }
+      push @result, {'cmdname' => 'hashchar', 'parent' => $current->{'parent'},
+                     'args' => [{'type' => 'brace_command_arg'}]};
+    }
+    push @result, $current;
+    return @result;
+  } else {
+    return ($current);
+  }
+}
+
+sub protect_hashchar_at_line_beginning($$$)
+{
+  my $registrar = shift;
+  my $configuration_informations = shift;
+  my $tree = shift;
+
+  my $self = [$registrar, $configuration_informations];
+  return Texinfo::Common::modify_tree($self, $tree, 
\&_protect_hashchar_at_line_beginning);
+}
+
 1;
 
 __END__
@@ -832,6 +927,11 @@ C<$add_section_names_in_entries> argument is set, a menu 
entry
 name is added using the section name.  This function should be
 called after L<sectioning_structure>.
 
+=item protect_hashchar_at_line_beginning($registrar, 
$configuration_informations, $tree)
+
+Protect hash (#) character at the beginning of line such that they would
+not be considered as lines to be processed by the CPP processor.
+
 =item $detailmenu = new_master_menu ($parser, $labels)
 
 Returns a detailmenu tree element formatted as a master node.
diff --git a/tp/Texinfo/Translations.pm b/tp/Texinfo/Translations.pm
index 3fa3c4b..e8c7989 100644
--- a/tp/Texinfo/Translations.pm
+++ b/tp/Texinfo/Translations.pm
@@ -271,6 +271,88 @@ sub _substitute ($$) {
 }
 
 
+sub _non_bracketed_contents($) {
+  my $current = shift;
+
+  if ($current->{'type'} and $current->{'type'} eq 'bracketed') {
+    my $new = {};
+    $new->{'contents'} = $current->{'contents'} if ($current->{'parent'});
+    $new->{'parent'} = $current->{'parent'} if ($current->{'parent'});
+    return $new;
+  } else {
+    return $current;
+  }
+}
+
+# In a handful of cases, we delay storing the contents of the
+# index entry until now to avoid needing Texinfo::Translations::gdt
+# in the main code of Parser.pm.  Also set 'in_code' value on
+# index entries.
+sub complete_indices
+{
+  my $self = shift;
+
+  my ($index_entry, $index_contents_normalized);
+    
+  my $save_lang = $self->get_conf('documentlanguage');
+
+  foreach my $index_name (keys(%{$self->{'index_names'}})) {
+    next if !defined $self->{'index_names'}->{$index_name}->{'index_entries'};
+    foreach my $entry 
(@{$self->{'index_names'}->{$index_name}->{'index_entries'}}) {
+      $entry->{'in_code'} = $self->{'index_names'}->{$index_name}->{'in_code'};
+      
+      if (!defined $entry->{'content'}) {
+        my $def_command = $entry->{'command'}->{'extra'}->{'def_command'};
+
+        my $def_parsed_hash = 
$entry->{'command'}->{'extra'}->{'def_parsed_hash'}; 
+        if ($def_parsed_hash and $def_parsed_hash->{'class'}
+            and $def_command) {
+          # Use the document language that was current when the command was
+          # used for getting the translation.
+          $self->{'documentlanguage'}
+             = $entry->{'command'}->{'extra'}->{'documentlanguage'};
+          delete $entry->{'command'}->{'extra'}->{'documentlanguage'};
+          if ($def_command eq 'defop'
+              or $def_command eq 'deftypeop'
+              or $def_command eq 'defmethod'
+              or $def_command eq 'deftypemethod') {
+            $index_entry = $self->gdt('{name} on {class}',
+                                  {'name' => $def_parsed_hash->{'name'},
+                                   'class' => $def_parsed_hash->{'class'}});
+           $index_contents_normalized
+             = [_non_bracketed_contents($def_parsed_hash->{'name'}),
+                { 'text' => ' on '},
+                _non_bracketed_contents($def_parsed_hash->{'class'})];
+          } elsif ($def_command eq 'defivar'
+                   or $def_command eq 'deftypeivar'
+                   or $def_command eq 'deftypecv') {
+            $index_entry = $self->gdt('{name} of {class}',
+                                     {'name' => $def_parsed_hash->{'name'},
+                                     'class' => $def_parsed_hash->{'class'}});
+            $index_contents_normalized
+              = [_non_bracketed_contents($def_parsed_hash->{'name'}),
+                 { 'text' => ' of '},
+                 _non_bracketed_contents($def_parsed_hash->{'class'})];
+          }
+        }
+        # 'root_line' is the container returned by gdt.
+        if ($index_entry->{'type'} and $index_entry->{'type'} eq 'root_line') {
+          for my $child (@{$index_entry->{'contents'}}) {
+            delete $child->{'parent'};
+          }
+        }
+        if ($index_entry->{'contents'}) {
+          $entry->{'content'} = [@{$index_entry->{'contents'}}];
+          $entry->{'content_normalized'} = $index_contents_normalized;
+        }
+      }
+    }
+  }
+  $self->{'documentlanguage'} = $save_lang;
+}
+
+
+
 1;
 
 __END__
diff --git a/tp/Texinfo/XS/parsetexi/Parsetexi.pm 
b/tp/Texinfo/XS/parsetexi/Parsetexi.pm
index c42842a..e5644b5 100644
--- a/tp/Texinfo/XS/parsetexi/Parsetexi.pm
+++ b/tp/Texinfo/XS/parsetexi/Parsetexi.pm
@@ -24,10 +24,8 @@ use warnings;
 require Exporter;
 
 use Texinfo::Common;
-# no direct use, use through
-# Texinfo::Common::set_nodes_list_labels
-use Texinfo::Convert::NodeNameNormalization;
 use Texinfo::Report;
+use Texinfo::Convert::NodeNameNormalization;
 use Texinfo::Translations;
 
 our @ISA = qw(Exporter Texinfo::Translations);
@@ -216,8 +214,9 @@ sub get_parser_info {
   _get_errors ($self);
 
   # Setup labels info and nodes list based on 'targets'
-  Texinfo::Common::set_nodes_list_labels($self, $self->{'registrar'}, $self);
-  Texinfo::Common::complete_indices ($self);
+  Texinfo::Convert::NodeNameNormalization::set_nodes_list_labels($self,
+                                           $self->{'registrar'}, $self);
+  Texinfo::Translations::complete_indices ($self);
 }
 
 use File::Basename; # for fileparse
@@ -377,7 +376,8 @@ sub parse_texi_line($$;$$$$)
     $self->{'targets'} = $TARGETS;
 
     # Setup labels info and nodes list based on 'targets'
-    Texinfo::Common::set_nodes_list_labels($self, $self->{'registrar'}, $self);
+    Texinfo::Convert::NodeNameNormalization::set_nodes_list_labels($self,
+                                                $self->{'registrar'}, $self);
 
     return $tree;
 }
diff --git a/tp/init/chm.pm b/tp/init/chm.pm
index cdfd675..8479b9f 100644
--- a/tp/init/chm.pm
+++ b/tp/init/chm.pm
@@ -33,6 +33,7 @@ use Texinfo::Common;
 
 # load modules to make sure that they are loaded before use
 use Texinfo::Convert::Unicode;
+use Texinfo::Convert::Utils;
 use Texinfo::Convert::Text;
 use Texinfo::Structuring;
 
@@ -330,7 +331,7 @@ sub chm_init($)
         }
       }
       my $text = convert_tree($self, $section->{'args'}->[0]);
-      $text = $self->Texinfo::Common::numbered_heading($section, $text,
+      $text = Texinfo::Convert::Utils::numbered_heading($self, $section, $text,
                           $self->get_conf('NUMBER_SECTIONS')); 
       my $file = $self->command_filename($section);
       my $anchor = $self->command_target($section);
diff --git a/tp/t/accents.t b/tp/t/accents.t
index 70180be..6297130 100644
--- a/tp/t/accents.t
+++ b/tp/t/accents.t
@@ -7,10 +7,14 @@ use Test::More;
 
 BEGIN { plan tests => 59; }
 
+use Encode;
+
+use Texinfo::Convert::Unicode;
+use Texinfo::Convert::Utils;
 use Texinfo::Convert::Text;
+use Texinfo::Parser;
 use Texinfo::Convert::Converter;
 use Texinfo::Convert::HTML;
-use Texinfo::Parser;
 
 ok(1, "modules loading");
 
@@ -25,7 +29,7 @@ sub test_accent_stack ($)
   my $text_root = $parser->parse_texi_text($texi);
   my $tree = $text_root->{'contents'}->[0]->{'contents'}->[0];
   my ($contents, $commands_stack) = 
-    Texinfo::Common::find_innermost_accent_contents($tree);
+    Texinfo::Convert::Utils::find_innermost_accent_contents($tree);
   my $text = Texinfo::Convert::Text::convert_to_text({'contents' => 
$contents});
   my @stack = map {$_->{'cmdname'}} @$commands_stack;
   if (defined($reference)) {
@@ -75,7 +79,7 @@ sub test_enable_encoding ($)
   my $tree = $text_root->{'contents'}->[0]->{'contents'}->[0];
 
   my ($contents, $commands_stack) = 
-    Texinfo::Common::find_innermost_accent_contents($tree);
+    Texinfo::Convert::Utils::find_innermost_accent_contents($tree);
   my $text = Texinfo::Convert::Text::convert_to_text({'contents' => 
$contents});
 
   my $result = 
@@ -91,7 +95,7 @@ sub test_enable_encoding ($)
       = Texinfo::Convert::Converter::xml_accents($html_converter, $tree);
 
   ($contents, $commands_stack) =
-    Texinfo::Common::find_innermost_accent_contents($tree);
+    Texinfo::Convert::Utils::find_innermost_accent_contents($tree);
   $text = Texinfo::Convert::Text::convert_to_text({'contents' => $contents},
                                {'enabled_encoding' => 'utf-8'});
   my $result_unicode = Texinfo::Convert::Unicode::unicode_accents(undef, 
$text, 
diff --git a/tp/t/automatic_menus.t b/tp/t/automatic_menus.t
index 1c00c4c..c030819 100644
--- a/tp/t/automatic_menus.t
+++ b/tp/t/automatic_menus.t
@@ -7,7 +7,7 @@ use Texinfo::ModulePath (undef, undef, 'updirs' => 2);
 
 BEGIN { plan tests => 8; }
 
-use Texinfo::Parser qw(parse_texi_text);
+use Texinfo::Parser;
 use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
diff --git a/tp/t/automatic_nodes.t b/tp/t/automatic_nodes.t
index 065e18c..f43d2ca 100644
--- a/tp/t/automatic_nodes.t
+++ b/tp/t/automatic_nodes.t
@@ -7,7 +7,7 @@ use Texinfo::ModulePath (undef, undef, 'updirs' => 2);
 
 BEGIN { plan tests => 24; }
 
-use Texinfo::Parser qw(parse_texi_text);
+use Texinfo::Parser;
 use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
diff --git a/tp/t/do_master_menu.t b/tp/t/do_master_menu.t
index 9862949..9b2363a 100644
--- a/tp/t/do_master_menu.t
+++ b/tp/t/do_master_menu.t
@@ -7,9 +7,10 @@ use Test::More;
 
 BEGIN { plan tests => 5; }
 
-use Texinfo::Parser qw(parse_texi_text);
+use Texinfo::Parser;
 use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
+use Texinfo::Structuring;
 
 use Data::Dumper;
 
diff --git a/tp/t/nodenormalization.t b/tp/t/nodenormalization.t
index 66c9eb5..8f34f45 100644
--- a/tp/t/nodenormalization.t
+++ b/tp/t/nodenormalization.t
@@ -7,9 +7,12 @@ use Test::More;
 
 BEGIN { plan tests => 8; }
 
+use Data::Dumper;
+use Locale::Messages;
+
+use Texinfo::Convert::Texinfo;
 use Texinfo::Convert::NodeNameNormalization qw(normalize_node 
transliterate_texinfo);
 use Texinfo::Parser;
-use Data::Dumper;
 
 # Currently, tests check that NodeNameNormalization do not break with complete 
 # Texinfo trees, not that the output is correct.
diff --git a/tp/t/reference_to_text_in_tree.t b/tp/t/reference_to_text_in_tree.t
index e965217..a80227e 100644
--- a/tp/t/reference_to_text_in_tree.t
+++ b/tp/t/reference_to_text_in_tree.t
@@ -7,7 +7,7 @@ use Test::More;
 
 BEGIN { plan tests => 2; }
 
-use Texinfo::Parser qw(parse_texi_text);
+use Texinfo::Parser;
 use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
@@ -20,7 +20,7 @@ sub run_test($$$)
   my $name = shift;
 
   my $parser = Texinfo::Parser::parser();
-  my $tree = parse_texi_text($parser, $in);
+  my $tree = $parser->parse_texi_text($in);
 
   my $corrected_tree 
     = Texinfo::Transformations::reference_to_arg_in_tree($parser, $tree);
diff --git a/tp/t/test_protect_hashchar_at_line_beginning.t 
b/tp/t/test_protect_hashchar_at_line_beginning.t
index 0a7bb97..d8613c3 100644
--- a/tp/t/test_protect_hashchar_at_line_beginning.t
+++ b/tp/t/test_protect_hashchar_at_line_beginning.t
@@ -7,8 +7,8 @@ use Test::More;
 
 BEGIN { plan tests => 6; }
 
-use Texinfo::Parser qw(parse_texi_text);
-use Texinfo::Common qw(protect_hashchar_at_line_beginning);
+use Texinfo::Parser;
+use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
 use Data::Dumper;
@@ -28,7 +28,7 @@ sub run_test($$$;$)
   my $registrar = $parser->registered_errors();
 
   my $corrected_tree = 
-    Texinfo::Common::protect_hashchar_at_line_beginning($registrar, $parser, 
$tree);
+    Texinfo::Transformations::protect_hashchar_at_line_beginning($registrar, 
$parser, $tree);
 
   if (defined($error_message)) {
     my ($errors, $errors_count) = $registrar->errors();



reply via email to

[Prev in Thread] Current Thread [Next in Thread]