texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Tue, 8 Nov 2022 03:29:24 -0500 (EST)

branch: master
commit d6513b969b796c14cbe96f70e43a6d5c0d36ee69
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sun Oct 30 18:38:39 2022 +0100

    * tp/Texinfo/Translations.pm (gdt, replace_convert_substrings):
    Split replace_convert_substrings out of gdt, corresponding to the
    substitution of replaced_substrings and conversion to Texinfo
    tree.
    
    * doc/texi2any_api.texi (Internationalization of Strings Function)
    (Translations Output and Customization)
    (Translated Strings Customization): add a whole chapter on
    strings internationalization, grouping Internationalization of Strings
    Function and information formerly in Basic Formatting Customization.
    
    * tp/t/test_utils.pl (test), tp/Texinfo/Config.pm
    (_GNUT_initialize_stage_handlers)
    (_GNUT_initialize_no_arg_commands_formatting_strings)
    (_GNUT_initialize_style_commands_formatting_info)
    (GNUT_reinitialize_init_files): add initialization of init files
    information in Texinfo::Config to isolate tests.
---
 ChangeLog                                          |  26 +
 doc/texi2any_api.texi                              | 267 +++---
 tp/Texinfo/Config.pm                               |  56 +-
 tp/Texinfo/Translations.pm                         |  73 +-
 tp/t/init/translated_strings_customization.pm      |  54 ++
 tp/t/init_files_tests.t                            |  28 +
 .../init_files_tests/customize_translations.pl     | 909 +++++++++++++++++++++
 tp/t/test_utils.pl                                 |   2 +
 8 files changed, 1286 insertions(+), 129 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 28d60799fc..31e6d90faf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2022-10-30  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Translations.pm (gdt, replace_convert_substrings):
+       Split replace_convert_substrings out of gdt, corresponding to the
+       substitution of replaced_substrings and conversion to Texinfo
+       tree.
+
+       * doc/texi2any_api.texi (Internationalization of Strings Function)
+       (Translations Output and Customization)
+       (Translated Strings Customization): add a whole chapter on
+       strings internationalization, grouping Internationalization of Strings
+       Function and information formerly in Basic Formatting Customization.
+
+       * tp/t/test_utils.pl (test), tp/Texinfo/Config.pm
+       (_GNUT_initialize_stage_handlers)
+       (_GNUT_initialize_no_arg_commands_formatting_strings)
+       (_GNUT_initialize_style_commands_formatting_info)
+       (GNUT_reinitialize_init_files): add initialization of init files
+       information in Texinfo::Config to isolate tests.
+
 2022-10-29  Patrice Dumas  <pertusus@free.fr>
 
        Add customization of translated strings
@@ -64,3 +84,9 @@
 2022-11-07  Gavin Smith  <gavinsmith0123@gmail.com>
 
        * README-hacking: new ChangeLog file done
+
+Copyright 2022 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/doc/texi2any_api.texi b/doc/texi2any_api.texi
index eaaaf3f356..1491b5e13b 100644
--- a/doc/texi2any_api.texi
+++ b/doc/texi2any_api.texi
@@ -510,7 +510,7 @@ texinfo_register_no_arg_command_formatting('error', undef, 
undef, undef,
                                            'error--&gt;');
 @end example
 
-@xref{@code{format_translate_string}} for
+@xref{Translated Strings Customization} for
 customization of translated strings.
 
 
@@ -1303,84 +1303,6 @@ according to the arguments.
 a Texinfo tree conversion.
 
 
-@node Internationalization of Strings Function
-@subsection Internationalization of Strings Function
-
-@vindex texinfo_document @r{Gettext domain}
-The subroutines @code{gdt} or @code{pgdt}, are used for translated strings:
-
-@deftypefun {@var{$translated_tree} =} @var{$converter}->gdt (@var{$string}, 
@var{\%variables_hash}, @var{$translation_context}, @var{$mode})
-@deftypefunx {@var{$translated_tree} =} @var{$converter}->pgdt 
(@var{$translation_context}, @var{$string}, @var{\%variables_hash}, @var{$mode})
-@var{$string} is the string to be translated, @var{\%variables_hash}
-is a hash reference holding the variable parts of the translated
-string.   @var{$translation_context} is an optional translation context
-that limits the search of the translated string to that context
-(@pxref{Contexts,,,gettext,GNU gettext tools}).
-The result returned is a perl Texinfo tree in the default case.
-
-@var{$mode} is an optional string which may modify how the function behaves. 
The
-possible values are:
-@table @code
-@item translated_text
-In that case the string is not considered to be Texinfo, a plain string
-that is returned after translation and substitution. The substitutions
-may only be strings in that case.
-@end table
-
-If called as @code{pgdt}, @var{$translation_context} is not optional
-and is the first argument.  @code{pgdt} is used to mark
-that the translated string has a context for tools extracting
-translatable strings to produce template files, which is not the case for
-@code{gdt}.  Since it is unlikely that marking a string for translation
-is of use in user-defined code, @code{gdt} should be usable in most
-cases.
-@end deftypefun
-
-When the string is expanded as Texinfo, and converted to a
-Texinfo tree in perl, the arguments are substituted; for
-example, @samp{@{arg_name@}} is replaced by the corresponding
-actual argument, which should be Texinfo perl trees, Texinfo
-perl tree contents arrays or strings.
-
-In the following example, @samp{@{date@}}, @samp{@{program_homepage@}}
-and @samp{@{program@}} are the arguments of the string.  Since they
-are used in @code{@@uref}, their order in the formatted output depends on
-the formatting and is not predictable.
-@samp{@{date@}}, @samp{@{program_homepage@}} and @samp{@{program@}} are
-substituted after the expansion, which means that they should already be
-Texinfo perl trees, Texinfo perl tree contents.  A string is turned
-into a Texinfo text element without type, with the string as @code{text}.
-
-@example
-  $converter->gdt('Generated @@emph@{@@today@{@}@} using '
-   .'@@uref@{@{program_homepage@}, @@emph@{@{program@}@}@}.',
-      @{ 'program_homepage' => $converter->get_conf('PACKAGE_URL'),
-        'program' => @{ 'text' => $converter->get_conf('PROGRAM') @}@}));
-@end example
-
-In the example, the @code{$converter->get_conf('PACKAGE_URL')} string is turned
-into @code{@{ 'text' => $converter->get_conf('PACKAGE_URL')  @}}.
-
-An example of combining conversion with translation:
-@example
-$converter->convert_tree($converter->gdt(
-       '@{explained_string@} (@{explanation@})',
-       @{'explained_string' => @{'type' => '_converted',
-                               'text' => $result@},
-        'explanation' => @{'type' => '_converted',
-                          'text' => $explanation_result@}@}),
-                         "convert explained $cmdname");
-@end example
-
-In the default case, the @code{gdt} function from the 
@code{Texinfo::Translations}
-module is used for translated strings.  It is possible to use a user-defined
-function instead (@pxref{@code{format_translate_string}}).
-@xref{Texinfo::Translations,,,texi2any_internals} for more
-on @code{Texinfo::Translations}.
-@xref{Internationalization of Document Strings,,, texinfo, Texinfo} for 
additional
-information on the default case.
-
-
 @node Error Reporting in User Defined Functions
 @subsection Error Reporting in User Defined Functions
 
@@ -2769,27 +2691,6 @@ add an identifier attribute to.
 Return an anchor with identifier @var{$id}.
 @end deftypefn
 
-@item format_translate_string
-@anchor{@code{format_translate_string}}
-This function reference is not set in the default case, in the default case
-the @code{gdt} method from the @code{Texinfo::Translations} module is
-called (@pxref{Internationalization of Strings Function}).
-
-@deftypefn {Function Reference} @var{$translated_tree} format_translate_string 
@
-  (@var{$converter}, @var{$string}, @var{$lang}, @var{\%variables_hash}, @
-  @var{$translation_context}, @var{$mode})
-@var{$string} is the string to be translated, @var{$lang} is the language.
-@var{$translation_context} is an optional translation context.
-@var{$mode} is an optional string which should modify how the function behaves.
-
-The result returned should be a perl Texinfo tree in the default case, or
-a string if @var{$mode} is set to @code{translated_text}.
-The result returned may also be @samp{undef}, in which case the translation
-is done as if the function reference had not been defined.
-
-@xref{Internationalization of Strings Function} for more information on the
-arguments that are common with @code{gdt}.
-@end deftypefn
 
 @end table
 
@@ -3021,6 +2922,172 @@ $@{$foot_num_reference@}++;
 @end example
 
 
+@node Translations Output and Customization
+@chapter Translations Output and Customization
+
+Translated strings can be specified in customization functions, for
+@@-commands without arguments (@pxref{Simple Customization for Commands
+Without Arguments}), and for direction strings (@pxref{Direction Strings
+Customization}).  Translated strings can also be inserted in the output
+using specific functions for internationalization of strings.
+
+It is possible to customize the translated strings, to
+change the translations of the translated strings used in the default case.
+If new translated strings are added, it is required to use translated strings
+customization to add translations for the strings that are not in the
+default translated strings.
+
+@xref{Internationalization of Document Strings,,, texinfo, Texinfo} for 
additional
+information on the default case.
+
+@node Internationalization of Strings Function
+@section Internationalization of Strings Function
+
+@vindex texinfo_document @r{Gettext domain}
+The subroutines @code{gdt} or @code{pgdt}, are used for translated strings:
+
+@deftypefun {@var{$translated_tree} =} @var{$converter}->gdt (@var{$string}, 
@var{\%variables_hash}, @var{$translation_context}, @var{$mode})
+@deftypefunx {@var{$translated_tree} =} @var{$converter}->pgdt 
(@var{$translation_context}, @var{$string}, @var{\%variables_hash}, @var{$mode})
+@var{$string} is the string to be translated, @var{\%variables_hash}
+is a hash reference holding the variable parts of the translated
+string.   @var{$translation_context} is an optional translation context
+that limits the search of the translated string to that context
+(@pxref{Contexts,,,gettext,GNU gettext tools}).
+The result returned is a perl Texinfo tree in the default case.
+
+@var{$mode} is an optional string which may modify how the function behaves. 
The
+possible values are:
+@table @code
+@item translated_text
+In that case the string is not considered to be Texinfo, a plain string
+that is returned after translation and substitution. The substitutions
+may only be strings in that case.
+@end table
+
+If called as @code{pgdt}, @var{$translation_context} is not optional
+and is the first argument.  @code{pgdt} is used to mark
+that the translated string has a context for tools extracting
+translatable strings to produce template files, which is not the case for
+@code{gdt}.  Since it is unlikely that marking a string for translation
+is of use in user-defined code, @code{gdt} should be usable in most
+cases.
+@end deftypefun
+
+When the string is expanded as Texinfo, and converted to a
+Texinfo tree in perl, the arguments are substituted; for
+example, @samp{@{arg_name@}} is replaced by the corresponding
+actual argument, which should be Texinfo perl trees, Texinfo
+perl tree contents arrays or strings.
+
+In the following example, @samp{@{date@}}, @samp{@{program_homepage@}}
+and @samp{@{program@}} are the arguments of the string.  Since they
+are used in @code{@@uref}, their order in the formatted output depends on
+the formatting and is not predictable.
+@samp{@{date@}}, @samp{@{program_homepage@}} and @samp{@{program@}} are
+substituted after the expansion, which means that they should already be
+Texinfo perl trees, Texinfo perl tree contents.  A string is turned
+into a Texinfo text element without type, with the string as @code{text}.
+
+@example
+  $converter->gdt('Generated @@emph@{@@today@{@}@} using '
+   .'@@uref@{@{program_homepage@}, @@emph@{@{program@}@}@}.',
+      @{ 'program_homepage' => $converter->get_conf('PACKAGE_URL'),
+        'program' => @{ 'text' => $converter->get_conf('PROGRAM') @}@}));
+@end example
+
+In the example, the @code{$converter->get_conf('PACKAGE_URL')} string is turned
+into @code{@{ 'text' => $converter->get_conf('PACKAGE_URL')  @}}.
+
+An example of combining conversion with translation:
+@example
+$converter->convert_tree($converter->gdt(
+       '@{explained_string@} (@{explanation@})',
+       @{'explained_string' => @{'type' => '_converted',
+                               'text' => $result@},
+        'explanation' => @{'type' => '_converted',
+                          'text' => $explanation_result@}@}),
+                         "convert explained $cmdname");
+@end example
+
+In the default case, the @code{gdt} function from the 
@code{Texinfo::Translations}
+module is used for translated strings.  It is possible to use a user-defined
+function instead as seen next.  
@xref{Texinfo::Translations,,,texi2any_internals} for more
+on @code{Texinfo::Translations}.
+
+
+@node Translated Strings Customization
+@section Translated Strings Customization
+
+To translate strings, register the @code{format_translate_string} function 
reference:
+
+@deftypefn {Function Reference} @var{$translated_tree} format_translate_string 
@
+  (@var{$converter}, @var{$string}, @var{$lang}, @var{\%variables_hash}, @
+  @var{$translation_context}, @var{$mode})
+@var{$string} is the string to be translated, @var{$lang} is the language.
+@var{$translation_context} is an optional translation context.
+@var{$mode} is an optional string which should modify how the function behaves.
+
+The result returned should be a perl Texinfo tree in the default case, or
+a string if @var{$mode} is set to @code{translated_text}.
+The result returned may also be @samp{undef}, in which case the translation
+is done as if the function reference had not been defined.
+
+@xref{Internationalization of Strings Function} for more information on the
+arguments that are common with @code{gdt}.
+
+The @code{replace_convert_substrings} method of @code{Texinfo::Translations}
+can be used to substitute @var{\%variables_hash} and return a Texinfo tree
+based on a translated string, taking into account @var{$mode}
+(@pxref{Texinfo@asis{::}Translations $tree = 
$object->replace_convert_substrings($translated_string@comma{} 
$replaced_substrings@comma{} $mode),,
+Texinfo@asis{::}Translations replace_convert_substrings, texi2any_internals}).
+@end deftypefn
+
+This function reference is not set in the default case, in the default case
+the @code{gdt} method from the @code{Texinfo::Translations} module is
+called (@pxref{Internationalization of Strings Function}).
+@xref{Specific formating Functions} for information on how to register and get
+the function reference.
+
+Here is an example with new translated strings added and definition
+of @code{format_translate_string} to translate the strings:
+
+@example
+texinfo_register_no_arg_command_formatting('error', undef, undef,
+                                                undef, 'error--&gt;');
+my %translations = (
+ 'fr' => @{
+           'error--&gt;' => @{'' => 'erreur--&gt;',@},
+           # @dots{}
+         @}
+ 'de' => @{
+           'error--&gt;' => @{'' => 'Fehler--&gt;',@},
+           # @dots{}
+         @}
+ # @dots{}
+);
+
+sub my_format_translate_string($$$;$$$)
+@{
+  my ($self, $string, $lang, $replaced_substrings,
+                              $translation_context, $type) = @_;
+  $translation_context = '' if (!defined($translation_context));
+  if (exists($translations@{$lang@})
+      and exists($translations@{$lang@}->@{$string@})
+      and exists($translations@{$lang@}->@{$string@}
+                                  ->@{$translation_context@})) @{
+    my $translation = $translations@{$lang@}->@{$string@}
+                                      ->@{$translation_context@};
+    return $self->replace_convert_substrings($translation,
+                           $replaced_substrings, $type);
+  @}
+  return undef;
+@}
+
+texinfo_register_formatting_function('format_translate_string',
+                                       \&_my_format_translate_string);
+
+@end example
+
 @node Directions@comma{} Links@comma{} Labels and Files
 @chapter Directions, Links, Labels and Files
 
diff --git a/tp/Texinfo/Config.pm b/tp/Texinfo/Config.pm
index cc0f51cb7a..e7d46365ec 100644
--- a/tp/Texinfo/Config.pm
+++ b/tp/Texinfo/Config.pm
@@ -355,12 +355,19 @@ my $default_priority = 'default';
 
 # FIXME add another level with format?  Not needed now as HTML is
 # the only customizable format for now.
-my $GNUT_stage_handlers = {};
+my $GNUT_stage_handlers;
 
-foreach my $stage (@possible_stages) {
-  $GNUT_stage_handlers->{$stage} = {};
+sub _GNUT_initialize_stage_handlers()
+{
+  $GNUT_stage_handlers = {};
+
+  foreach my $stage (@possible_stages) {
+    $GNUT_stage_handlers->{$stage} = {};
+  }
 }
 
+_GNUT_initialize_stage_handlers();
+
 sub texinfo_register_handler($$;$)
 {
   my $stage = shift;
@@ -498,12 +505,27 @@ sub GNUT_get_formatting_special_element_body_references()
 }
 
 my $default_formatting_context = 'normal';
-foreach my $possible_formatting_context (($default_formatting_context,
-                       'preformatted', 'string', 'css_string')) {
-  $GNUT_no_arg_commands_formatting_strings->{$possible_formatting_context} = 
{};
-  $GNUT_style_commands_formatting_info->{$possible_formatting_context} = {};
+my @all_possible_formatting_context = ($default_formatting_context,
+                               'preformatted', 'string', 'css_string');
+
+sub _GNUT_initialize_no_arg_commands_formatting_strings()
+{
+  foreach my $possible_formatting_context (@all_possible_formatting_context) {
+    $GNUT_no_arg_commands_formatting_strings->{$possible_formatting_context} = 
{};
+  }
 }
 
+_GNUT_initialize_no_arg_commands_formatting_strings();
+
+sub _GNUT_initialize_style_commands_formatting_info()
+{
+  foreach my $possible_formatting_context (@all_possible_formatting_context) {
+    $GNUT_style_commands_formatting_info->{$possible_formatting_context} = {};
+  }
+}
+
+_GNUT_initialize_style_commands_formatting_info();
+
 # $translated_string is supposed to be already formatted.
 # It may also be relevant to be able to pass a 'tree'
 # directly (it is actually handled by the converter code).
@@ -666,6 +688,26 @@ sub GNUT_get_direction_string_info()
 }
 
 
+# Not needed from the main program, as the init files should affect all
+# the manuals, but needed for tests, to have isolated tests.
+
+sub GNUT_reinitialize_init_files()
+{
+  @init_file_loading_messages = ();
+  foreach my $reference ($init_files_options,
+     $GNUT_file_id_setting_references,
+     $GNUT_formatting_references, $GNUT_formatting_special_element_body,
+     $GNUT_commands_conversion, $GNUT_commands_open, $GNUT_types_conversion,
+     $GNUT_types_open, $GNUT_accent_command_formatting_info,
+     $GNUT_types_formatting_info, $GNUT_direction_string_info) {
+    $reference = {};
+  }
+  _GNUT_initialize_stage_handlers();
+  _GNUT_initialize_no_arg_commands_formatting_strings();
+  _GNUT_initialize_style_commands_formatting_info();
+}
+
+
 #####################################################################
 # the objective of this small package is to be in another
 # scope than init files and setup blessed objects that can call
diff --git a/tp/Texinfo/Translations.pm b/tp/Texinfo/Translations.pm
index c803ca5a34..6bcc7ba06d 100644
--- a/tp/Texinfo/Translations.pm
+++ b/tp/Texinfo/Translations.pm
@@ -99,7 +99,7 @@ sub _switch_messages_locale
 # Return a parsed Texinfo tree
 sub gdt($$;$$$$)
 {
-  my ($self, $message, $replaced_substrings, $message_context, $type, $lang) = 
@_;
+  my ($self, $string, $replaced_substrings, $translation_context, $type, 
$lang) = @_;
 
   # In addition to being settable from the command line,
   # the language needs to be dynamic in case there is an untranslated string
@@ -107,9 +107,6 @@ sub gdt($$;$$$$)
   $lang = $self->get_conf('documentlanguage') if ($self and !defined($lang));
   $lang = $DEFAULT_LANGUAGE if (!defined($lang));
 
-  my $re = join '|', map { quotemeta $_ } keys %$replaced_substrings
-      if (defined($replaced_substrings) and ref($replaced_substrings));
-
   my ($saved_LC_MESSAGES, $saved_LANGUAGE);
 
   # We need to set LC_MESSAGES to a valid locale other than "C" or "POSIX"
@@ -183,13 +180,13 @@ sub gdt($$;$$$$)
 
   Locale::Messages::nl_putenv("LANGUAGE=$locales");
 
-  my $translated_message;
+  my $translated_string;
 
-  if (defined($message_context)) {
-    $translated_message = Locale::Messages::pgettext($message_context,
-                                                     $message);
+  if (defined($translation_context)) {
+    $translated_string = Locale::Messages::pgettext($translation_context,
+                                                     $string);
   } else {
-    $translated_message = Locale::Messages::gettext($message);
+    $translated_string = Locale::Messages::gettext($string);
   }
 
   Locale::Messages::textdomain($messages_textdomain);
@@ -208,10 +205,22 @@ sub gdt($$;$$$$)
     }
   }
 
-  my $translation_result = $translated_message;
+  return replace_convert_substrings($self, $translated_string,
+                                    $replaced_substrings, $type);
+}
+
+sub replace_convert_substrings($$;$$)
+{
+  my $self = shift;
+  my $translated_string = shift;
+  my $replaced_substrings = shift;
+  my $type = shift;
+
+  my $translation_result = $translated_string;
 
   if ($type and $type eq 'translated_text') {
-    if (defined($re)) {
+    if (defined($replaced_substrings) and ref($replaced_substrings)) {
+      my $re = join '|', map { quotemeta $_ } keys %$replaced_substrings;
       # next line taken from libintl perl, copyright Guido. sub __expand
       $translation_result
   =~ s/\{($re)\}/defined $replaced_substrings->{$1} ? 
$replaced_substrings->{$1} : "{$1}"/ge;
@@ -226,7 +235,8 @@ sub gdt($$;$$$$)
   # Using a special command that is invalid unless a special
   # configuration is set means that there should be no clash
   # with @-commands used in translations.
-  if (defined($re)) {
+  if (defined($replaced_substrings) and ref($replaced_substrings)) {
+    my $re = join '|', map { quotemeta $_ } keys %$replaced_substrings;
     # next line taken from libintl perl, copyright Guido. sub __expand
     $translation_result =~ s/\{($re)\}/\@txiinternalvalue\{$1\}/g;
   }
@@ -235,7 +245,7 @@ sub gdt($$;$$$$)
   # is worth it.  The current use case, that is allow to specify the state of
   # clickstyle and kbdinputstyle is relevant (though not implemented in thet XS
   # parser, but could be) but not necessarily determining.  Converters and
-  # users could easily avoid using @kbd and @click in the translated messages.
+  # users could easily avoid using @kbd and @click in the translated strings.
   # FIXME why not use $self->get_conf('clickstyle'), ...?  It would not be used
   # everytime, only if and where the $self object sets 'clickstyle'
   # and 'kbdinputstyle'
@@ -285,7 +295,7 @@ sub gdt($$;$$$$)
   my ($errors, $errors_count) = $registrar->errors();
   if ($errors_count) {
     warn "translation $errors_count error(s)\n";
-    warn "translated message: $translated_message\n";
+    warn "translated string: $translated_string\n";
     warn "Error messages: \n";
     foreach my $error_message (@$errors) {
       warn $error_message->{'error_line'};
@@ -337,9 +347,9 @@ sub _substitute ($$) {
 
 sub pgdt($$$;$$$)
 {
-  my ($self, $message_context, $message, $replaced_substrings, $type, $lang) = 
@_;
+  my ($self, $translation_context, $string, $replaced_substrings, $type, 
$lang) = @_;
   # FIXME would it be better to call $self->gdt?
-  return gdt($self, $message, $replaced_substrings, $message_context, $type, 
$lang);
+  return gdt($self, $string, $replaced_substrings, $translation_context, 
$type, $lang);
 }
 
 
@@ -465,12 +475,16 @@ elements are in L<Texinfo::Common C<__> and 
C<__p>|Texinfo::Common/$translated_s
 
 No method is exported.
 
-The C<gdt> method is used to translate strings to be output in
-converted documents, and returns, in general, a texinfo tree.
+The C<gdt> and C<pgdt> methods are used to translate strings to be output in
+converted documents, and returns, in general, a Texinfo tree.
+
+The C<replace_convert_substrings> method is called by C<gdt> to substitute
+replaced substrings in a translated string and convert to a Texinfo tree.
+It may be especially useful when overriding or reimplementing C<gdt>.
 
 =over
 
-=item $tree = $object->gdt($string, $replaced_substrings, $message_context, 
$mode, $lang)
+=item $tree = $object->gdt($string, $replaced_substrings, 
$translation_context, $mode, $lang)
 X<C<gdt>>
 
 The I<$string> is a string to be translated.  In the default case,
@@ -488,7 +502,7 @@ C<get_conf>, or undefined (C<undef>).  If not undefined, 
the information in the
 I<$object> is used to determine the encoding, the documentlanguage and get some
 customization information.
 
-The I<$message_context> is optional.  If not C<undef> this is a translation
+The I<$translation_context> is optional.  If not C<undef> this is a translation
 context string for I<$string>.  It is the first argument of C<pgettext>
 in the C API of Gettext.  I<$lang> is optional. If set, it overrides the
 documentlanguage.
@@ -528,14 +542,29 @@ may only be strings in that case.
 
 =back
 
-=item $tree = $object->pgdt($message_context, $string, $replaced_substrings, 
$mode, $lang)
+=item $tree = $object->pgdt($translation_context, $string, 
$replaced_substrings, $mode, $lang)
 X<C<pgdt>>
 
-Same to C<gdt> except that the I<$message_context> is not optional.
+Same to C<gdt> except that the I<$translation_context> is not optional.
 Calls C<gdt>.  This function is useful to mark strings with a
 translation context for translation.  This function is similar to pgettext
 in the Gettext C API.
 
+=item $tree = $object->replace_convert_substrings($translated_string, 
$replaced_substrings, $mode)
+X<C<replace_convert_substrings>>
+
+I<$translated_string> is a string already translated.  I<$replaced_substrings>
+is an optional hash reference specifying some substitution to be done.
+I<$mode> is an optional string which may modify how the function behaves, and
+in particular whether the translated string should be converted to a Texinfo
+tree.  I<$object> is typically a converter, but can be any object that
+implements C<get_conf>, or undefined (C<undef>).  If not undefined, the
+information in the I<$object> is used to get some customization information.
+
+The function performs the substitutions of substrings in the translated
+string and converts to a Texinfo tree if needed.  It is called from C<gdt>
+after the retrieval of the translated string.
+
 =back
 
 =head1 AUTHOR
diff --git a/tp/t/init/translated_strings_customization.pm 
b/tp/t/init/translated_strings_customization.pm
new file mode 100644
index 0000000000..1e8695f266
--- /dev/null
+++ b/tp/t/init/translated_strings_customization.pm
@@ -0,0 +1,54 @@
+
+use utf8;
+
+package Texinfo::Config;
+
+use strict;
+
+texinfo_register_direction_string_info('Forward', 'text', undef, 'Forward');
+# register both Next and NodeNext as the one used depends on
+# USE_NODE_DIRECTIONS/USE_NODES
+texinfo_register_direction_string_info('Next', 'text', ' -&gt; ');
+texinfo_register_direction_string_info('NodeNext', 'text', ' -&gt; ');
+
+texinfo_register_no_arg_command_formatting('error', undef, undef, undef,
+                                                            'error--&gt;');
+
+my %translations = (
+  'fr' => {
+           ' &gt; ' => {'' => 'Vers l\'avant &gt;',},
+           ' -&gt; ' => {'' => 'N&oelig; suivant'},
+           'error--&gt;' => {'' => 'Erreur--&gt;',},
+
+           'Table of contents' => {'' => 'La @emph{Table des mati@`eres}',},
+           '{number} {section_title}' => {'' => '{number}@ : {section_title}'},
+          },
+  'de' => {
+           ' &gt; ' => {'' => 'Nach vorne &gt;',},
+           ' -&gt; ' => {'' => 'Nächster Knoten'},
+           'error--&gt;' => {'' => 'Fehler--&gt;',},
+
+           'Table of contents' => {'' => 'Das @emph{Inhaltsverzeichnis}',},
+           '{number} {section_title}' => {'' => '{number}: {section_title}'},
+          },
+);
+
+sub _my_format_translate_string($$$;$$$)
+{
+  my ($self, $string, $lang, $replaced_substrings,
+                              $translation_context, $type) = @_;
+  $translation_context = '' if (!defined($translation_context));
+  if (exists($translations{$lang})
+      and exists($translations{$lang}->{$string})
+      and exists($translations{$lang}->{$string}->{$translation_context})) {
+    my $translation = $translations{$lang}->{$string}->{$translation_context};
+    return $self->replace_convert_substrings($translation, 
$replaced_substrings,
+                                             $type);
+  }
+  return undef;
+}
+
+texinfo_register_formatting_function('format_translate_string',
+                                       \&_my_format_translate_string);
+
+1;
diff --git a/tp/t/init_files_tests.t b/tp/t/init_files_tests.t
index 129e049a66..0749a5316e 100644
--- a/tp/t/init_files_tests.t
+++ b/tp/t/init_files_tests.t
@@ -28,6 +28,34 @@ pt @error{}.
 
 ',{'init_files' => ['translate_txiinternalvalue_macro.init'],
 }],
+['customize_translations',
+'
+@contents
+
+@node Top
+@top top
+
+@node Chapter
+@chapter chap
+
+@error{}.
+
+@documentlanguage fr
+@node Chapter fr
+@chapter chap fr
+
+@error{}.
+
+@documentlanguage de
+@node Chapter de
+@chapter chap de
+
+@error{}.
+
+@node Last chapter
+@chapter Last Chapter
+
+', {'init_files' => ['translated_strings_customization.pm']}],
 );
 
 my @file_tests = (
diff --git a/tp/t/results/init_files_tests/customize_translations.pl 
b/tp/t/results/init_files_tests/customize_translations.pl
new file mode 100644
index 0000000000..653116be3d
--- /dev/null
+++ b/tp/t/results/init_files_tests/customize_translations.pl
@@ -0,0 +1,909 @@
+use vars qw(%result_texis %result_texts %result_trees %result_errors 
+   %result_indices %result_sectioning %result_nodes %result_menus
+   %result_floats %result_converted %result_converted_errors 
+   %result_elements %result_directions_text %result_indices_sort_strings);
+
+use utf8;
+
+$result_trees{'customize_translations'} = {
+  'contents' => [
+    {
+      'contents' => [
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        },
+        {
+          'args' => [
+            {
+              'text' => '
+',
+              'type' => 'misc_arg'
+            }
+          ],
+          'cmdname' => 'contents',
+          'source_info' => {
+            'file_name' => '',
+            'line_nr' => 2,
+            'macro' => ''
+          }
+        },
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        }
+      ],
+      'type' => 'before_node_section'
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'Top'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'node',
+      'extra' => {
+        'node_content' => [
+          {}
+        ],
+        'nodes_manuals' => [
+          {
+            'node_content' => [
+              {}
+            ],
+            'normalized' => 'Top'
+          }
+        ],
+        'normalized' => 'Top',
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 4,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'top'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'top',
+      'contents' => [
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        }
+      ],
+      'extra' => {
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 5,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'Chapter'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'node',
+      'extra' => {
+        'node_content' => [
+          {}
+        ],
+        'nodes_manuals' => [
+          {
+            'node_content' => [
+              {}
+            ],
+            'normalized' => 'Chapter'
+          }
+        ],
+        'normalized' => 'Chapter',
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 7,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'chap'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'chapter',
+      'contents' => [
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        },
+        {
+          'contents' => [
+            {
+              'args' => [
+                {
+                  'type' => 'brace_command_arg'
+                }
+              ],
+              'cmdname' => 'error',
+              'source_info' => {
+                'file_name' => '',
+                'line_nr' => 10,
+                'macro' => ''
+              }
+            },
+            {
+              'text' => '.
+'
+            }
+          ],
+          'type' => 'paragraph'
+        },
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        },
+        {
+          'args' => [
+            {
+              'contents' => [
+                {
+                  'text' => 'fr'
+                }
+              ],
+              'extra' => {
+                'spaces_after_argument' => '
+'
+              },
+              'type' => 'line_arg'
+            }
+          ],
+          'cmdname' => 'documentlanguage',
+          'extra' => {
+            'spaces_before_argument' => ' ',
+            'text_arg' => 'fr'
+          },
+          'source_info' => {
+            'file_name' => '',
+            'line_nr' => 12,
+            'macro' => ''
+          }
+        }
+      ],
+      'extra' => {
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 8,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'Chapter fr'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'node',
+      'extra' => {
+        'node_content' => [
+          {}
+        ],
+        'nodes_manuals' => [
+          {
+            'node_content' => [
+              {}
+            ],
+            'normalized' => 'Chapter-fr'
+          }
+        ],
+        'normalized' => 'Chapter-fr',
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 13,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'chap fr'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'chapter',
+      'contents' => [
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        },
+        {
+          'contents' => [
+            {
+              'args' => [
+                {
+                  'type' => 'brace_command_arg'
+                }
+              ],
+              'cmdname' => 'error',
+              'source_info' => {
+                'file_name' => '',
+                'line_nr' => 16,
+                'macro' => ''
+              }
+            },
+            {
+              'text' => '.
+'
+            }
+          ],
+          'type' => 'paragraph'
+        },
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        },
+        {
+          'args' => [
+            {
+              'contents' => [
+                {
+                  'text' => 'de'
+                }
+              ],
+              'extra' => {
+                'spaces_after_argument' => '
+'
+              },
+              'type' => 'line_arg'
+            }
+          ],
+          'cmdname' => 'documentlanguage',
+          'extra' => {
+            'spaces_before_argument' => ' ',
+            'text_arg' => 'de'
+          },
+          'source_info' => {
+            'file_name' => '',
+            'line_nr' => 18,
+            'macro' => ''
+          }
+        }
+      ],
+      'extra' => {
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 14,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'Chapter de'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'node',
+      'extra' => {
+        'node_content' => [
+          {}
+        ],
+        'nodes_manuals' => [
+          {
+            'node_content' => [
+              {}
+            ],
+            'normalized' => 'Chapter-de'
+          }
+        ],
+        'normalized' => 'Chapter-de',
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 19,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'chap de'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'chapter',
+      'contents' => [
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        },
+        {
+          'contents' => [
+            {
+              'args' => [
+                {
+                  'type' => 'brace_command_arg'
+                }
+              ],
+              'cmdname' => 'error',
+              'source_info' => {
+                'file_name' => '',
+                'line_nr' => 22,
+                'macro' => ''
+              }
+            },
+            {
+              'text' => '.
+'
+            }
+          ],
+          'type' => 'paragraph'
+        },
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        }
+      ],
+      'extra' => {
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 20,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'Last chapter'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'node',
+      'extra' => {
+        'node_content' => [
+          {}
+        ],
+        'nodes_manuals' => [
+          {
+            'node_content' => [
+              {}
+            ],
+            'normalized' => 'Last-chapter'
+          }
+        ],
+        'normalized' => 'Last-chapter',
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 24,
+        'macro' => ''
+      }
+    },
+    {
+      'args' => [
+        {
+          'contents' => [
+            {
+              'text' => 'Last Chapter'
+            }
+          ],
+          'extra' => {
+            'spaces_after_argument' => '
+'
+          },
+          'type' => 'line_arg'
+        }
+      ],
+      'cmdname' => 'chapter',
+      'contents' => [
+        {
+          'text' => '
+',
+          'type' => 'empty_line'
+        }
+      ],
+      'extra' => {
+        'spaces_before_argument' => ' '
+      },
+      'source_info' => {
+        'file_name' => '',
+        'line_nr' => 25,
+        'macro' => ''
+      }
+    }
+  ],
+  'type' => 'document_root'
+};
+$result_trees{'customize_translations'}{'contents'}[1]{'extra'}{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[1]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[1]{'extra'}{'nodes_manuals'}[0]{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[1]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[3]{'extra'}{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[3]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[3]{'extra'}{'nodes_manuals'}[0]{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[3]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[5]{'extra'}{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[5]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[5]{'extra'}{'nodes_manuals'}[0]{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[5]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[7]{'extra'}{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[7]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[7]{'extra'}{'nodes_manuals'}[0]{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[7]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[9]{'extra'}{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[9]{'args'}[0]{'contents'}[0];
+$result_trees{'customize_translations'}{'contents'}[9]{'extra'}{'nodes_manuals'}[0]{'node_content'}[0]
 = 
$result_trees{'customize_translations'}{'contents'}[9]{'args'}[0]{'contents'}[0];
+
+$result_texis{'customize_translations'} = '
+@contents
+
+@node Top
+@top top
+
+@node Chapter
+@chapter chap
+
+@error{}.
+
+@documentlanguage fr
+@node Chapter fr
+@chapter chap fr
+
+@error{}.
+
+@documentlanguage de
+@node Chapter de
+@chapter chap de
+
+@error{}.
+
+@node Last chapter
+@chapter Last Chapter
+
+';
+
+
+$result_texts{'customize_translations'} = '
+
+top
+***
+
+1 chap
+******
+
+error-->.
+
+2 chap fr
+*********
+
+error-->.
+
+3 chap de
+*********
+
+error-->.
+
+4 Last Chapter
+**************
+
+';
+
+$result_sectioning{'customize_translations'} = {
+  'structure' => {
+    'section_childs' => [
+      {
+        'cmdname' => 'top',
+        'extra' => {
+          'associated_node' => {
+            'cmdname' => 'node',
+            'extra' => {
+              'normalized' => 'Top'
+            },
+            'structure' => {}
+          }
+        },
+        'structure' => {
+          'section_childs' => [
+            {
+              'cmdname' => 'chapter',
+              'extra' => {
+                'associated_node' => {
+                  'cmdname' => 'node',
+                  'extra' => {
+                    'normalized' => 'Chapter'
+                  },
+                  'structure' => {}
+                }
+              },
+              'structure' => {
+                'section_level' => 1,
+                'section_number' => 1,
+                'section_up' => {},
+                'toplevel_prev' => {},
+                'toplevel_up' => {}
+              }
+            },
+            {
+              'cmdname' => 'chapter',
+              'extra' => {
+                'associated_node' => {
+                  'cmdname' => 'node',
+                  'extra' => {
+                    'normalized' => 'Chapter-fr'
+                  },
+                  'structure' => {}
+                }
+              },
+              'structure' => {
+                'section_level' => 1,
+                'section_number' => 2,
+                'section_prev' => {},
+                'section_up' => {},
+                'toplevel_prev' => {},
+                'toplevel_up' => {}
+              }
+            },
+            {
+              'cmdname' => 'chapter',
+              'extra' => {
+                'associated_node' => {
+                  'cmdname' => 'node',
+                  'extra' => {
+                    'normalized' => 'Chapter-de'
+                  },
+                  'structure' => {}
+                }
+              },
+              'structure' => {
+                'section_level' => 1,
+                'section_number' => 3,
+                'section_prev' => {},
+                'section_up' => {},
+                'toplevel_prev' => {},
+                'toplevel_up' => {}
+              }
+            },
+            {
+              'cmdname' => 'chapter',
+              'extra' => {
+                'associated_node' => {
+                  'cmdname' => 'node',
+                  'extra' => {
+                    'normalized' => 'Last-chapter'
+                  },
+                  'structure' => {}
+                }
+              },
+              'structure' => {
+                'section_level' => 1,
+                'section_number' => 4,
+                'section_prev' => {},
+                'section_up' => {},
+                'toplevel_prev' => {},
+                'toplevel_up' => {}
+              }
+            }
+          ],
+          'section_level' => 0,
+          'section_up' => {}
+        }
+      }
+    ],
+    'section_level' => -1
+  }
+};
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[0]{'structure'}{'section_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[0]{'structure'}{'toplevel_prev'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[0]{'structure'}{'toplevel_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[1]{'structure'}{'section_prev'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[1]{'structure'}{'section_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[1]{'structure'}{'toplevel_prev'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[1]{'structure'}{'toplevel_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[2]{'structure'}{'section_prev'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[1];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[2]{'structure'}{'section_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[2]{'structure'}{'toplevel_prev'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[1];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[2]{'structure'}{'toplevel_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[3]{'structure'}{'section_prev'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[2];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[3]{'structure'}{'section_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[3]{'structure'}{'toplevel_prev'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[2];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_childs'}[3]{'structure'}{'toplevel_up'}
 = 
$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0];
+$result_sectioning{'customize_translations'}{'structure'}{'section_childs'}[0]{'structure'}{'section_up'}
 = $result_sectioning{'customize_translations'};
+
+$result_nodes{'customize_translations'} = {
+  'cmdname' => 'node',
+  'extra' => {
+    'associated_section' => {
+      'cmdname' => 'top',
+      'extra' => {},
+      'structure' => {}
+    },
+    'normalized' => 'Top'
+  },
+  'structure' => {
+    'node_next' => {
+      'cmdname' => 'node',
+      'extra' => {
+        'associated_section' => {
+          'cmdname' => 'chapter',
+          'extra' => {},
+          'structure' => {
+            'section_number' => 1
+          }
+        },
+        'normalized' => 'Chapter'
+      },
+      'structure' => {
+        'node_next' => {
+          'cmdname' => 'node',
+          'extra' => {
+            'associated_section' => {
+              'cmdname' => 'chapter',
+              'extra' => {},
+              'structure' => {
+                'section_number' => 2
+              }
+            },
+            'normalized' => 'Chapter-fr'
+          },
+          'structure' => {
+            'node_next' => {
+              'cmdname' => 'node',
+              'extra' => {
+                'associated_section' => {
+                  'cmdname' => 'chapter',
+                  'extra' => {},
+                  'structure' => {
+                    'section_number' => 3
+                  }
+                },
+                'normalized' => 'Chapter-de'
+              },
+              'structure' => {
+                'node_next' => {
+                  'cmdname' => 'node',
+                  'extra' => {
+                    'associated_section' => {
+                      'cmdname' => 'chapter',
+                      'extra' => {},
+                      'structure' => {
+                        'section_number' => 4
+                      }
+                    },
+                    'normalized' => 'Last-chapter'
+                  },
+                  'structure' => {
+                    'node_prev' => {},
+                    'node_up' => {}
+                  }
+                },
+                'node_prev' => {},
+                'node_up' => {}
+              }
+            },
+            'node_prev' => {},
+            'node_up' => {}
+          }
+        },
+        'node_prev' => {},
+        'node_up' => {}
+      }
+    }
+  }
+};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_prev'}
 = 
$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_next'};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_up'}
 = $result_nodes{'customize_translations'};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_prev'}
 = 
$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_up'}
 = $result_nodes{'customize_translations'};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_prev'}
 = $result_nodes{'customize_translations'}{'structure'}{'node_next'};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_next'}{'structure'}{'node_up'}
 = $result_nodes{'customize_translations'};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_prev'}
 = $result_nodes{'customize_translations'};
+$result_nodes{'customize_translations'}{'structure'}{'node_next'}{'structure'}{'node_up'}
 = $result_nodes{'customize_translations'};
+
+$result_menus{'customize_translations'} = {
+  'cmdname' => 'node',
+  'extra' => {
+    'normalized' => 'Top'
+  },
+  'structure' => {}
+};
+
+$result_errors{'customize_translations'} = [];
+
+
+$result_floats{'customize_translations'} = {};
+
+
+
+$result_converted{'html'}->{'customize_translations'} = '<!DOCTYPE html>
+<html>
+<!-- Created by texinfo, http://www.gnu.org/software/texinfo/ -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>top</title>
+
+<meta name="description" content="top">
+<meta name="keywords" content="top">
+<meta name="resource-type" content="document">
+<meta name="distribution" content="global">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+
+<link href="#Top" rel="start" title="Top">
+<link href="#SEC_Contents" rel="contents" title="Inhaltsverzeichnis">
+<style type="text/css">
+<!--
+ul.toc-numbered-mark {list-style: none}
+-->
+</style>
+
+
+</head>
+
+<body lang="en">
+
+
+<div class="top-level-extent" id="Top">
+<div class="nav-panel">
+<p>
+ -&gt; : <a href="#Chapter" accesskey="n" rel="next">chap</a> &nbsp; [<a 
href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>]</p>
+</div>
+<h1 class="top" id="top">top</h1>
+
+<div class="element-contents" id="SEC_Contents">
+<h2 class="contents-heading">Table of Contents</h2>
+
+<div class="contents">
+
+<ul class="toc-numbered-mark">
+  <li><a id="toc-chap" href="#Chapter">1 chap</a></li>
+  <li><a id="toc-chap-fr" href="#Chapter-fr">2 chap fr</a></li>
+  <li><a id="toc-chap-de" href="#Chapter-de">3 chap de</a></li>
+  <li><a id="toc-Last-Chapter" href="#Last-chapter">4 Last Chapter</a></li>
+</ul>
+</div>
+</div>
+<hr>
+<div class="chapter-level-extent" id="Chapter">
+<div class="nav-panel">
+<p>
+ -&gt; : <a href="#Chapter-fr" accesskey="n" rel="next">chap fr</a>, Previous: 
<a href="#Top" accesskey="p" rel="prev">top</a>, Up: <a href="#Top" 
accesskey="u" rel="up">top</a> &nbsp; [<a href="#SEC_Contents" title="Table of 
contents" rel="contents">Contents</a>]</p>
+</div>
+<h2 class="chapter" id="chap">1 chap</h2>
+
+<p>error--&gt;.
+</p>
+<hr>
+</div>
+<div class="chapter-level-extent" id="Chapter-fr">
+<div class="nav-panel">
+<p>
+N&oelig; suivant: <a href="#Chapter-de" accesskey="n" rel="next">chap de</a>, 
Pr&eacute;c&eacute;dent: <a href="#Chapter" accesskey="p" rel="prev">chap</a>, 
Monter: <a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a 
href="#SEC_Contents" title="La <em class="emph">Table des mati&egrave;res</em>" 
rel="contents">Table des mati&egrave;res</a>]</p>
+</div>
+<h2 class="chapter" id="chap-fr">2 chap fr</h2>
+
+<p>Erreur--&gt;.
+</p>
+<hr>
+</div>
+<div class="chapter-level-extent" id="Chapter-de">
+<div class="nav-panel">
+<p>
+Nächster Knoten: <a href="#Last-chapter" accesskey="n" rel="next">Last 
Chapter</a>, Vorige: <a href="#Chapter-fr" accesskey="p" rel="prev">chap 
fr</a>, Nach oben: <a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a 
href="#SEC_Contents" title="Das <em class="emph">Inhaltsverzeichnis</em>" 
rel="contents">Inhalt</a>]</p>
+</div>
+<h2 class="chapter" id="chap-de">3 chap de</h2>
+
+<p>Fehler--&gt;.
+</p>
+<hr>
+</div>
+<div class="chapter-level-extent" id="Last-chapter">
+<div class="nav-panel">
+<p>
+Vorige: <a href="#Chapter-de" accesskey="p" rel="prev">chap de</a>, Nach oben: 
<a href="#Top" accesskey="u" rel="up">top</a> &nbsp; [<a href="#SEC_Contents" 
title="Das <em class="emph">Inhaltsverzeichnis</em>" 
rel="contents">Inhalt</a>]</p>
+</div>
+<h2 class="chapter" id="Last-Chapter">4 Last Chapter</h2>
+
+</div>
+</div>
+
+
+
+</body>
+</html>
+';
+
+1;
diff --git a/tp/t/test_utils.pl b/tp/t/test_utils.pl
index b7d1de2923..6942d1dfd9 100644
--- a/tp/t/test_utils.pl
+++ b/tp/t/test_utils.pl
@@ -952,6 +952,8 @@ sub test($$)
     delete $parser_options->{'test_formats'};
   }
 
+  # reset Texinfo::Config informations to have isolated tests
+  Texinfo::Config::GNUT_reinitialize_init_files();
   my $init_file_directories = [$srcdir.'init/', $srcdir.'t/init/'];
   # the init file names are supposed to be binary strings.  Since they
   # are not encoded anywhere, probably only non ascii file names should



reply via email to

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