texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Wed, 17 Jan 2024 14:23:42 -0500 (EST)

branch: master
commit c61bcafb7e0d80c9458bc247f5509e99b99dacec
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Jan 17 20:18:13 2024 +0100

    Add initialization and finalization of conversion, separate document
    from converter
    
    * tp/Texinfo/Convert/Converter.pm (conversion_initialization)
    (conversion_finalization, output), tp/Texinfo/Convert/DocBook.pm
    (converter_initialize, conversion_initialization, convert)
    (conversion_initialization, output), tp/Texinfo/Convert/HTML.pm
    (%XS_conversion_overrides, _XS_html_converter_initialize)
    (converter_initialize, conversion_initialization)
    (conversion_finalization, convert, output), tp/Texinfo/Convert/IXIN.pm
    (output_ixin), tp/Texinfo/Convert/Info.pm (output),
    tp/Texinfo/Convert/LaTeX.pm (conversion_initialization, output)
    (convert, convert_to_latex_math), tp/Texinfo/Convert/Plaintext.pm
    (conversion_initialization, converter_initialize, convert_output_unit)
    (convert), tp/Texinfo/Convert/TexinfoMarkup.pm (converter_initialize)
    (conversion_initialization, output, convert),
    tp/Texinfo/XS/convert/ConvertXS.xs (html_converter_initialize_sv)
    (html_initialize_output_state, html_conversion_finalization),
    tp/Texinfo/XS/convert/convert_html.c (html_initialize_output_state),
    tp/Texinfo/XS/convert/get_html_perl_info.c
    (html_converter_initialize_sv, html_conversion_initialization_sv),
    tp/t/accents.t: use systematically conversion_initialization and
    conversion_finalization at the beginning and end of output and convert
    to initialize and finalize the conversion of one document.  Keep in
    converter_initialize only the code that do not depend on a document.
    In HTML.pm rename existing functions,
    _initialize_XS_NonXS_output_state as conversion_initialization and
    _finalize_output_state as conversion_finalization, and move code from
    converter_initialize.  In Plaintext.pm, this replaces
    _initialize_converter_state.
    
    * tp/Texinfo/Convert/Converter.pm (set_document),
    tp/Texinfo/Convert/HTML.pm (get_value): rename 'value' key in
    converter as 'document_values'.
    
    * tp/Texinfo/Convert/Converter.pm (%XS_overrides, set_document)
    (_XS_set_document, converter), tp/Texinfo/XS/convert/ConvertXS.xs
    (converter_set_document), tp/Texinfo/XS/main/get_perl_info.c
    (converter_set_document, converter_initialize): move setting the
    document of a converter to a separate function, for now called from
    converter.
    
    * tp/Texinfo/XS/convert/convert_html.c (html_initialize_output_state),
    tp/Texinfo/XS/main/get_perl_info.c
    (find_element_extra_index_entry_sv): handle NUL document.
    
    * tp/Texinfo/Convert/Plaintext.pm (pop_top_formatter)
    (process_footnotes, conversion_finalization): add a function to pop
    the top formatter and use it in conversion_finalization.
    
    * tp/Texinfo/Convert/DocBook.pm (convert_tree): minor change in code.
    
    * tp/Texinfo/Convert/IXINSXML.pm (converter_initialize): pass
    document, not tree.
---
 ChangeLog                                  |  57 ++++
 tp/Texinfo/Convert/Converter.pm            | 109 +++++--
 tp/Texinfo/Convert/DocBook.pm              |  53 ++--
 tp/Texinfo/Convert/HTML.pm                 | 443 +++++++++++++++--------------
 tp/Texinfo/Convert/IXIN.pm                 |  18 +-
 tp/Texinfo/Convert/IXINSXML.pm             |   7 +-
 tp/Texinfo/Convert/Info.pm                 |  15 +-
 tp/Texinfo/Convert/LaTeX.pm                |  18 +-
 tp/Texinfo/Convert/Plaintext.pm            | 138 +++++----
 tp/Texinfo/Convert/TexinfoMarkup.pm        |  13 +-
 tp/Texinfo/XS/convert/ConvertXS.xs         |  16 +-
 tp/Texinfo/XS/convert/IndicesXS.xs         |   1 +
 tp/Texinfo/XS/convert/convert_html.c       |   9 +-
 tp/Texinfo/XS/convert/convert_html.h       |   2 +-
 tp/Texinfo/XS/convert/get_html_perl_info.c | 286 +++++++++++--------
 tp/Texinfo/XS/convert/get_html_perl_info.h |   4 +
 tp/Texinfo/XS/main/get_perl_info.c         |  61 ++--
 tp/Texinfo/XS/main/get_perl_info.h         |   1 +
 tp/t/accents.t                             |   2 +-
 19 files changed, 742 insertions(+), 511 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2a439877ca..01976f7b0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2024-01-17  Patrice Dumas  <pertusus@free.fr>
+
+       Add initialization and finalization of conversion, separate document
+       from converter
+
+       * tp/Texinfo/Convert/Converter.pm (conversion_initialization)
+       (conversion_finalization, output), tp/Texinfo/Convert/DocBook.pm
+       (converter_initialize, conversion_initialization, convert)
+       (conversion_initialization, output), tp/Texinfo/Convert/HTML.pm
+       (%XS_conversion_overrides, _XS_html_converter_initialize)
+       (converter_initialize, conversion_initialization)
+       (conversion_finalization, convert, output), tp/Texinfo/Convert/IXIN.pm
+       (output_ixin), tp/Texinfo/Convert/Info.pm (output),
+       tp/Texinfo/Convert/LaTeX.pm (conversion_initialization, output)
+       (convert, convert_to_latex_math), tp/Texinfo/Convert/Plaintext.pm
+       (conversion_initialization, converter_initialize, convert_output_unit)
+       (convert), tp/Texinfo/Convert/TexinfoMarkup.pm (converter_initialize)
+       (conversion_initialization, output, convert),
+       tp/Texinfo/XS/convert/ConvertXS.xs (html_converter_initialize_sv)
+       (html_initialize_output_state, html_conversion_finalization),
+       tp/Texinfo/XS/convert/convert_html.c (html_initialize_output_state),
+       tp/Texinfo/XS/convert/get_html_perl_info.c
+       (html_converter_initialize_sv, html_conversion_initialization_sv),
+       tp/t/accents.t: use systematically conversion_initialization and
+       conversion_finalization at the beginning and end of output and convert
+       to initialize and finalize the conversion of one document.  Keep in
+       converter_initialize only the code that do not depend on a document.
+       In HTML.pm rename existing functions,
+       _initialize_XS_NonXS_output_state as conversion_initialization and
+       _finalize_output_state as conversion_finalization, and move code from
+       converter_initialize.  In Plaintext.pm, this replaces
+       _initialize_converter_state.
+
+       * tp/Texinfo/Convert/Converter.pm (set_document),
+       tp/Texinfo/Convert/HTML.pm (get_value): rename 'value' key in
+       converter as 'document_values'.
+
+       * tp/Texinfo/Convert/Converter.pm (%XS_overrides, set_document)
+       (_XS_set_document, converter), tp/Texinfo/XS/convert/ConvertXS.xs
+       (converter_set_document), tp/Texinfo/XS/main/get_perl_info.c
+       (converter_set_document, converter_initialize): move setting the
+       document of a converter to a separate function, for now called from
+       converter.
+
+       * tp/Texinfo/XS/convert/convert_html.c (html_initialize_output_state),
+       tp/Texinfo/XS/main/get_perl_info.c
+       (find_element_extra_index_entry_sv): handle NUL document.
+
+       * tp/Texinfo/Convert/Plaintext.pm (pop_top_formatter)
+       (process_footnotes, conversion_finalization): add a function to pop
+       the top formatter and use it in conversion_finalization.
+
+       * tp/Texinfo/Convert/DocBook.pm (convert_tree): minor change in code.
+
+       * tp/Texinfo/Convert/IXINSXML.pm (converter_initialize): pass
+       document, not tree.
+
 2024-01-16  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/Converter.pm (determine_files_and_directory):
diff --git a/tp/Texinfo/Convert/Converter.pm b/tp/Texinfo/Convert/Converter.pm
index e056a9dab7..0252a7b722 100644
--- a/tp/Texinfo/Convert/Converter.pm
+++ b/tp/Texinfo/Convert/Converter.pm
@@ -94,6 +94,8 @@ my %XS_overrides = (
    => "Texinfo::Convert::ConvertXS::force_conf",
   "Texinfo::Convert::Converter::_XS_get_conf"
    => "Texinfo::Convert::ConvertXS::get_conf",
+  "Texinfo::Convert::Converter::_XS_set_document"
+   => "Texinfo::Convert::ConvertXS::converter_set_document",
 
   # fully overriden for all the converters
   "Texinfo::Convert::Converter::get_converter_errors"
@@ -223,7 +225,18 @@ sub converter_initialize($)
 {
 }
 
-# generic XS converter initialization
+sub conversion_initialization($;$)
+{
+  #my $converter = shift;
+  #my $document = shift;
+}
+
+sub conversion_finalization($)
+{
+  #my $converter = shift;
+}
+
+# initialize generic XS converter
 sub _XS_converter_initialize($)
 {
 }
@@ -234,6 +247,48 @@ sub output_internal_links($)
   return undef;
 }
 
+sub _XS_set_document($$)
+{
+}
+
+sub set_document($$)
+{
+  my $converter = shift;
+  my $document = shift;
+
+  if ($converter->{'converter_descriptor'} and $XS_convert) {
+    _XS_set_document($converter, $document);
+  }
+
+  $converter->{'document'} = $document;
+  if (defined($document)) {
+    $converter->{'global_commands'}
+     = $document->global_commands_information();
+    $converter->{'document_info'} = $document->global_information();
+    my $floats = $document->floats_information();
+    my $identifier_target = $document->labels_information();
+    my $sections_list = $document->sections_list();
+
+    $converter->{'floats'} = $floats if ($floats);
+    $converter->{'identifiers_target'} = $identifier_target
+                                           if ($identifier_target);
+    $converter->{'sections_list'} = $sections_list if ($sections_list);
+    $converter->{'indices_information'}
+           = $document->indices_information();
+    $converter->{'document_values'} = $document->{'values'};
+    # From and for XS
+    $converter->{'document_descriptor'}
+      = $document->document_descriptor();
+  }
+  Texinfo::Common::set_output_encodings($converter,
+                                        $converter->{'document_info'});
+  # TODO should be done here, but need to split converter_initialize
+  # in document specifc and not document specific
+  #$converter->{'convert_text_options'}
+  # = Texinfo::Convert::Text::copy_options_for_convert_text($converter);
+
+}
+
 # this function is designed so as to be used in specific Converters
 sub converter($;$)
 {
@@ -244,6 +299,9 @@ sub converter($;$)
 
   bless $converter, $class;
 
+  # TODO set using set_document only
+  my $document;
+
   my %defaults = $converter->converter_defaults($conf);
   foreach my $key (keys(%all_converters_defaults)) {
     $defaults{$key} = $all_converters_defaults{$key}
@@ -259,24 +317,7 @@ sub converter($;$)
   }
   if (defined($conf)) {
     if ($conf->{'document'}) {
-      $converter->{'global_commands'}
-         = $conf->{'document'}->global_commands_information();
-      $converter->{'document_info'} = 
$conf->{'document'}->global_information();
-      my $floats = $conf->{'document'}->floats_information();
-      my $identifier_target = $conf->{'document'}->labels_information();
-      my $sections_list = $conf->{'document'}->sections_list();
-
-      $converter->{'floats'} = $floats if ($floats);
-      $converter->{'identifiers_target'} = $identifier_target
-                                             if ($identifier_target);
-      $converter->{'sections_list'} = $sections_list if ($sections_list);
-      $converter->{'indices_information'}
-             = $conf->{'document'}->indices_information();
-      $converter->{'values'} = $conf->{'document'}->{'values'};
-      # From and for XS
-      $converter->{'document_descriptor'}
-        = $conf->{'document'}->document_descriptor();
-      $converter->{'document'} = $conf->{'document'};
+      $document = $conf->{'document'};
       delete $conf->{'document'};
     }
     foreach my $key (keys(%$conf)) {
@@ -297,11 +338,6 @@ sub converter($;$)
   # options obtained after setting the defaults and applying
   # the customization passed as argument.
   $converter->{'converter_init_conf'} = { %{$converter->{'conf'}} };
-  foreach my $key (keys (%defaults)) {
-    if (defined($converter->{$key})) {
-      $converter->{'converter_init_conf'}->{$key} = $converter->{$key};
-    }
-  }
 
   # turn the array to a hash.
   my $expanded_formats = $converter->{'conf'}->{'EXPANDED_FORMATS'};
@@ -327,14 +363,13 @@ sub converter($;$)
   # information can be passed to C.
   _XS_converter_initialize($converter);
 
-  Texinfo::Common::set_output_encodings($converter,
-                                        $converter->{'document_info'});
+  if ($document) {
+    set_document($converter, $document);
+  }
 
   $converter->converter_initialize();
-
   $converter->{'convert_text_options'}
-      = Texinfo::Convert::Text::copy_options_for_convert_text($converter);
-
+   = Texinfo::Convert::Text::copy_options_for_convert_text($converter);
 
   return $converter;
 }
@@ -360,6 +395,8 @@ sub output($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
   my $output_units;
@@ -387,7 +424,10 @@ sub output($$)
   my $succeeded
     = $self->create_destination_directory($encoded_destination_directory,
                                           $destination_directory);
-  return undef unless $succeeded;
+  unless ($succeeded) {
+    $self->conversion_finalization();
+    return undef;
+  }
 
   if ($self->get_conf('USE_NODES')) {
     $output_units = Texinfo::Structuring::split_by_node($root);
@@ -441,6 +481,7 @@ sub output($$)
         $self->converter_document_error(
                  sprintf(__("could not open %s for writing: %s"),
                                       $outfile_name, $error_message));
+        $self->conversion_finalization();
         return undef;
       }
     } else {
@@ -471,7 +512,10 @@ sub output($$)
                                       $outfile_name, $!));
       }
     }
-    return $output if ($output_file eq '');
+    if ($output_file eq '') {
+      $self->conversion_finalization();
+      return $output;
+    }
   } else {
     # output with pages
     print STDERR "DO Elements with filenames\n"
@@ -492,6 +536,7 @@ sub output($$)
           $self->converter_document_error(
                 sprintf(__("could not open %s for writing: %s"),
                        $out_filepath, $error_message));
+          $self->conversion_finalization();
           return undef;
         }
         $files_filehandle{$output_unit_filename} = $file_fh;
@@ -510,12 +555,14 @@ sub output($$)
             $self->converter_document_error(
                      sprintf(__("error on closing %s: %s"),
                                   $out_filepath, $!));
+            $self->conversion_finalization();
             return undef;
           }
         }
       }
     }
   }
+  $self->conversion_finalization();
   return undef;
 }
 
diff --git a/tp/Texinfo/Convert/DocBook.pm b/tp/Texinfo/Convert/DocBook.pm
index 1e0de3d849..e03ea66eeb 100644
--- a/tp/Texinfo/Convert/DocBook.pm
+++ b/tp/Texinfo/Convert/DocBook.pm
@@ -284,8 +284,6 @@ sub converter_initialize($)
 {
   my $self = shift;
 
-  $self->{'document_context'} = [];
-  $self->_new_document_context();
   $self->{'context_block_commands'} = {%default_context_block_commands};
   foreach my $raw (grep {$Texinfo::Commands::block_commands{$_} eq 
'format_raw'}
                         keys(%Texinfo::Commands::block_commands)) {
@@ -294,22 +292,41 @@ sub converter_initialize($)
   }
 }
 
+sub conversion_initialization($;$)
+{
+  my $self = shift;
+  my $document = shift;
+
+  $self->{'document_context'} = [];
+  $self->_new_document_context();
+  $self->{'lang_stack'} = [];
+  $self->{'in_skipped_node_top'} = 0;
+  %sectioning_commands_done = ();
+}
+
+sub conversion_finalization($)
+{
+  my $self = shift;
+
+  pop @{$self->{'document_context'}};
+}
+
 sub convert($$)
 {
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
-  if (! defined($self->{'lang_stack'})) {
-    $self->{'lang_stack'} = [''];
-  }
-  # could even set to 0 if defined?
-  $self->{'in_skipped_node_top'} = 0
-    if (! defined($self->{'in_skipped_node_top'}));
+  push @{$self->{'lang_stack'}}, '';
 
-  %sectioning_commands_done = ();
-  return $self->convert_tree($root);
+  my $result = $self->convert_tree($root);
+
+  $self->conversion_finalization();
+
+  return $result;
 }
 
 sub convert_tree($$)
@@ -317,8 +334,8 @@ sub convert_tree($$)
   my $self = shift;
   my $root = shift;
 
-  if (! defined($self->{'lang_stack'})) {
-    $self->{'lang_stack'} = [''];
+  if (scalar(@{$self->{'lang_stack'}}) == 0) {
+    push @{$self->{'lang_stack'}}, '';
   }
   return $self->_convert($root);
 }
@@ -332,6 +349,8 @@ sub output($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
   my ($output_file, $destination_directory, $output_filename)
@@ -342,7 +361,10 @@ sub output($$)
   my $succeeded
     = $self->create_destination_directory($encoded_destination_directory,
                                           $destination_directory);
-  return undef unless $succeeded;
+  unless ($succeeded) {
+    $self->conversion_finalization();
+    return undef;
+  }
 
   my $fh;
   my $encoded_output_file;
@@ -358,6 +380,7 @@ sub output($$)
       $self->converter_document_error(
            sprintf(__("could not open %s for writing: %s"),
                                     $output_file, $error_message));
+      $self->conversion_finalization();
       return undef;
     }
   }
@@ -375,8 +398,6 @@ sub output($$)
     $id = '';
   }
 
-  $self->{'lang_stack'} = [];
-  $self->{'in_skipped_node_top'} = 0;
   my $lang = $DEFAULT_LANG;
   $self->set_global_document_commands('preamble', ['documentlanguage']);
   if (defined($self->get_conf('documentlanguage'))) {
@@ -511,7 +532,6 @@ sub output($$)
     $header .= "<bookinfo>$document_info</bookinfo>\n";
   }
 
-  %sectioning_commands_done = ();
   my $result = '';
   $result .= $self->write_or_return($header, $fh);
   $result .= $self->write_or_return($self->convert_tree($root), $fh);
@@ -525,6 +545,7 @@ sub output($$)
                                     $output_file, $!));
     }
   }
+  $self->conversion_finalization();
   return $result;
 }
 
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index b522ef24fb..f6063570c1 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -117,8 +117,8 @@ my %XS_conversion_overrides = (
    => "Texinfo::Convert::ConvertXS::html_converter_initialize_sv",
   "Texinfo::Convert::HTML::_initialize_output_state"
    => "Texinfo::Convert::ConvertXS::html_initialize_output_state",
-  "Texinfo::Convert::HTML::_finalize_output_state"
-   => "Texinfo::Convert::ConvertXS::html_finalize_output_state",
+  "Texinfo::Convert::HTML::conversion_finalization"
+   => "Texinfo::Convert::ConvertXS::html_conversion_finalization",
   "Texinfo::Convert::HTML::_XS_reset_output_init_conf"
    => "Texinfo::Convert::ConvertXS::reset_output_init_conf",
   "Texinfo::Convert::HTML::_prepare_simpletitle"
@@ -1957,9 +1957,9 @@ sub get_value($$)
 {
   my $self = shift;
   my $value = shift;
-  if (defined($self->{'values'})
-      and exists ($self->{'values'}->{$value})) {
-    return $self->{'values'}->{$value};
+  if (defined($self->{'document_values'})
+      and exists ($self->{'document_values'}->{$value})) {
+    return $self->{'document_values'}->{$value};
   } else {
     return undef;
   }
@@ -8532,7 +8532,7 @@ my %special_characters = (
   'non_breaking_space' => [undef, '00A0'],
 );
 
-sub _XS_html_converter_initialize($$$$$$$$$$$)
+sub _XS_html_converter_initialize($$$$$$$$$$$$)
 {
 }
 
@@ -8542,147 +8542,8 @@ sub converter_initialize($)
 {
   my $self = shift;
 
-  %{$self->{'css_element_class_styles'}} = %css_element_class_styles;
-
   _load_htmlxref_files($self);
 
-  # duplicate such as not to modify the defaults
-  my $conf_default_no_arg_commands_formatting_normal
-    = Storable::dclone($default_no_arg_commands_formatting{'normal'});
-
-  my %special_characters_set;
-
-  my $output_encoding = $self->get_conf('OUTPUT_ENCODING_NAME');
-
-  foreach my $special_character (keys(%special_characters)) {
-    my ($default_entity, $unicode_point) = 
@{$special_characters{$special_character}};
-    if ($self->get_conf('OUTPUT_CHARACTERS')
-        and Texinfo::Convert::Unicode::unicode_point_decoded_in_encoding(
-                                         $output_encoding, $unicode_point)) {
-      $special_characters_set{$special_character}
-                                    = charnames::vianame("U+$unicode_point");
-    } elsif ($self->get_conf('USE_NUMERIC_ENTITY')) {
-      $special_characters_set{$special_character} = 
'&#'.hex($unicode_point).';';
-    } else {
-      $special_characters_set{$special_character} = $default_entity;
-    }
-  }
-
-  if (defined($special_characters_set{'non_breaking_space'})) {
-    my $non_breaking_space = $special_characters_set{'non_breaking_space'};
-    $self->_set_non_breaking_space($non_breaking_space);
-    foreach my $space_command (' ', "\t", "\n") {
-      
$conf_default_no_arg_commands_formatting_normal->{$space_command}->{'text'}
-        = $self->{'non_breaking_space'};
-    }
-    $conf_default_no_arg_commands_formatting_normal->{'tie'}->{'text'}
-      = $self->substitute_html_non_breaking_space(
-           $default_no_arg_commands_formatting{'normal'}->{'tie'}->{'text'});
-  } else {
-    $self->_set_non_breaking_space($xml_named_entity_nbsp);
-  }
-  $self->{'paragraph_symbol'} = $special_characters_set{'paragraph_symbol'};
-
-  if (not defined($self->get_conf('OPEN_QUOTE_SYMBOL'))) {
-    $self->set_conf('OPEN_QUOTE_SYMBOL', 
$special_characters_set{'left_quote'});
-  }
-  if (not defined($self->get_conf('CLOSE_QUOTE_SYMBOL'))) {
-    $self->set_conf('CLOSE_QUOTE_SYMBOL', 
$special_characters_set{'right_quote'});
-  }
-  if (not defined($self->get_conf('MENU_SYMBOL'))) {
-    $self->set_conf('MENU_SYMBOL', $special_characters_set{'bullet'});
-  }
-
-  if ($self->get_conf('USE_NUMERIC_ENTITY')) {
-    foreach my $command (keys(%Texinfo::Convert::Unicode::unicode_entities)) {
-      $conf_default_no_arg_commands_formatting_normal->{$command}->{'text'}
-       = $Texinfo::Convert::Unicode::unicode_entities{$command};
-    }
-  }
-
-  if ($self->get_conf('USE_XML_SYNTAX')) {
-    foreach my $customization_variable ('BIG_RULE', 'DEFAULT_RULE') {
-      my $variable_value = $self->get_conf($customization_variable);
-      if (defined($variable_value)) {
-        my $closed_lone_element = 
_xhtml_re_close_lone_element($variable_value);
-        if ($closed_lone_element ne $variable_value) {
-          $self->force_conf($customization_variable, $closed_lone_element);
-        }
-      }
-    }
-    $self->{'line_break_element'} = '<br/>';
-  } else {
-    $self->{'line_break_element'} = '<br>';
-  }
-  $conf_default_no_arg_commands_formatting_normal->{'*'}->{'text'}
-    = $self->{'line_break_element'};
-
-  # three types of direction strings:
-  # * strings not translated, already converted
-  # * strings translated
-  #   - strings already converted
-  #   - strings not already converted
-  $self->{'directions_strings'} = {};
-
-  my $customized_direction_strings
-      = Texinfo::Config::GNUT_get_direction_string_info();
-  foreach my $string_type (keys(%default_converted_directions_strings)) {
-    $self->{'directions_strings'}->{$string_type} = {};
-    foreach my $direction
-            (keys(%{$default_converted_directions_strings{$string_type}})) {
-      $self->{'directions_strings'}->{$string_type}->{$direction} = {};
-      my $string_contexts;
-      if ($customized_direction_strings->{$string_type}
-          and $customized_direction_strings->{$string_type}->{$direction}) {
-        if (defined($customized_direction_strings->{$string_type}
-                                              ->{$direction}->{'converted'})) {
-          $string_contexts
-            = $customized_direction_strings->{$string_type}
-                                          ->{$direction}->{'converted'};
-        }
-      } else {
-        my $string
-          = $default_converted_directions_strings{$string_type}->{$direction};
-        $string_contexts
-          = {'normal' => $string};
-      }
-      $string_contexts->{'string'} = $string_contexts->{'normal'}
-        if (not defined($string_contexts->{'string'}));
-      foreach my $context (keys(%$string_contexts)) {
-        $self->{'directions_strings'}->{$string_type}->{$direction}->{$context}
-          = $self->substitute_html_non_breaking_space(
-                                                  
$string_contexts->{$context});
-      }
-    }
-  }
-  $self->{'translated_direction_strings'} = {};
-  foreach my $string_type (keys(%default_translated_directions_strings)) {
-    $self->{'translated_direction_strings'}->{$string_type} = {};
-    foreach my $direction
-           (keys(%{$default_translated_directions_strings{$string_type}})) {
-      if ($customized_direction_strings->{$string_type}
-            and $customized_direction_strings->{$string_type}->{$direction}) {
-        $self->{'translated_direction_strings'}->{$string_type}->{$direction}
-          = $customized_direction_strings->{$string_type}->{$direction};
-      } else {
-        if ($default_translated_directions_strings{$string_type}->{$direction}
-                                                              ->{'converted'}) 
{
-          $self->{'translated_direction_strings'}->{$string_type}
-                  ->{$direction} = {'converted' => {}};
-          foreach my $context ('normal', 'string') {
-            $self->{'translated_direction_strings'}->{$string_type}
-                     ->{$direction}->{'converted'}->{$context}
-               = $default_translated_directions_strings{$string_type}
-                                                 ->{$direction}->{'converted'};
-          }
-        } else {
-          $self->{'translated_direction_strings'}->{$string_type}->{$direction}
-            = 
$default_translated_directions_strings{$string_type}->{$direction};
-        }
-      }
-    }
-  }
-
   $self->{'output_units_conversion'} = {};
   my $customized_output_units_conversion
     = Texinfo::Config::GNUT_get_output_units_conversion();
@@ -8788,63 +8649,6 @@ sub converter_initialize($)
     }
   }
 
-  $self->{'no_arg_commands_formatting'} = {};
-  foreach my $command (keys(%{$default_no_arg_commands_formatting{'normal'}})) 
{
-    $self->{'no_arg_commands_formatting'}->{$command} = {};
-    foreach my $context ('normal', 'preformatted', 'string', 'css_string') {
-      my $no_arg_command_customized_formatting
-        = Texinfo::Config::GNUT_get_no_arg_command_formatting($command, 
$context);
-      if (defined($no_arg_command_customized_formatting)) {
-        $self->{'no_arg_commands_formatting'}->{$command}->{$context}
-           = $no_arg_command_customized_formatting;
-      } else {
-        my $context_default_default_no_arg_commands_formatting
-          = $default_no_arg_commands_formatting{$context};
-        if ($context eq 'normal') {
-          $context_default_default_no_arg_commands_formatting
-           = $conf_default_no_arg_commands_formatting_normal;
-        }
-        if 
(defined($context_default_default_no_arg_commands_formatting->{$command})) {
-          if ($self->get_conf('OUTPUT_CHARACTERS')
-              and Texinfo::Convert::Unicode::brace_no_arg_command(
-                             $command, 
$self->get_conf('OUTPUT_ENCODING_NAME'))) {
-            $self->{'no_arg_commands_formatting'}->{$command}->{$context}
-              = { 'text' => Texinfo::Convert::Unicode::brace_no_arg_command(
-                           $command, $self->get_conf('OUTPUT_ENCODING_NAME'))};
-            # reset CSS for itemize command arguments
-            if ($context eq 'css_string'
-                and exists($brace_commands{$command})
-                and $command ne 'bullet' and $command ne 'w'
-                and not 
$special_list_mark_css_string_no_arg_command{$command}) {
-              my $css_string
-                = $self->{'no_arg_commands_formatting'}
-                                    ->{$command}->{$context}->{'text'};
-              $css_string = '"'.$css_string.'"';
-              $self->{'css_element_class_styles'}->{"ul.mark-$command"}
-                = "list-style-type: $css_string";
-            }
-          } else {
-            $self->{'no_arg_commands_formatting'}->{$command}->{$context}
-              = 
$context_default_default_no_arg_commands_formatting->{$command};
-          }
-        } else {
-          $self->{'no_arg_commands_formatting'}->{$command}->{$context}
-            = {'unset' => 1};
-        }
-      }
-    }
-  }
-
-  # set sane defaults in case there is none and the default formatting
-  # function is used
-  foreach my $command (keys(%{$default_no_arg_commands_formatting{'normal'}})) 
{
-    if ($self->{'commands_conversion'}->{$command}
-        and $self->{'commands_conversion'}->{$command}
-            eq $default_commands_conversion{$command}) {
-      $self->_complete_no_arg_commands_formatting($command);
-    }
-  }
-
   $self->{'style_commands_formatting'} = {};
   foreach my $command (keys(%style_commands_formatting)) {
     $self->{'style_commands_formatting'}->{$command} = {};
@@ -9033,6 +8837,7 @@ sub converter_initialize($)
                              \%default_types_conversion,
                              \%default_css_string_types_conversion,
                              \%default_output_units_conversion,
+                             $default_no_arg_commands_formatting{'normal'},
                              \%defaults_format_special_unit_body_contents);
     delete $self->{'sorted_special_unit_varieties'};
     delete $self->{'simplified_special_unit_info'};
@@ -11636,14 +11441,212 @@ sub _initialize_output_state($$)
 
 # This function initializes states that are initialized both in XS and
 # in perl.
-sub _initialize_XS_NonXS_output_state($$)
+sub conversion_initialization($;$)
 {
   my $self = shift;
-  my $context = shift;
+  my $document = shift;
+
+  # duplicate such as not to modify the defaults
+  my $conf_default_no_arg_commands_formatting_normal
+    = Storable::dclone($default_no_arg_commands_formatting{'normal'});
+
+  my %special_characters_set;
+
+  my $output_encoding = $self->get_conf('OUTPUT_ENCODING_NAME');
+
+  foreach my $special_character (keys(%special_characters)) {
+    my ($default_entity, $unicode_point) = 
@{$special_characters{$special_character}};
+    if ($self->get_conf('OUTPUT_CHARACTERS')
+        and Texinfo::Convert::Unicode::unicode_point_decoded_in_encoding(
+                                         $output_encoding, $unicode_point)) {
+      $special_characters_set{$special_character}
+                                    = charnames::vianame("U+$unicode_point");
+    } elsif ($self->get_conf('USE_NUMERIC_ENTITY')) {
+      $special_characters_set{$special_character} = 
'&#'.hex($unicode_point).';';
+    } else {
+      $special_characters_set{$special_character} = $default_entity;
+    }
+  }
+
+  if (defined($special_characters_set{'non_breaking_space'})) {
+    my $non_breaking_space = $special_characters_set{'non_breaking_space'};
+    $self->_set_non_breaking_space($non_breaking_space);
+    foreach my $space_command (' ', "\t", "\n") {
+      
$conf_default_no_arg_commands_formatting_normal->{$space_command}->{'text'}
+        = $self->{'non_breaking_space'};
+    }
+    $conf_default_no_arg_commands_formatting_normal->{'tie'}->{'text'}
+      = $self->substitute_html_non_breaking_space(
+           $default_no_arg_commands_formatting{'normal'}->{'tie'}->{'text'});
+  } else {
+    $self->_set_non_breaking_space($xml_named_entity_nbsp);
+  }
+  $self->{'paragraph_symbol'} = $special_characters_set{'paragraph_symbol'};
+
+  if (not defined($self->get_conf('OPEN_QUOTE_SYMBOL'))) {
+    $self->set_conf('OPEN_QUOTE_SYMBOL', 
$special_characters_set{'left_quote'});
+  }
+  if (not defined($self->get_conf('CLOSE_QUOTE_SYMBOL'))) {
+    $self->set_conf('CLOSE_QUOTE_SYMBOL', 
$special_characters_set{'right_quote'});
+  }
+  if (not defined($self->get_conf('MENU_SYMBOL'))) {
+    $self->set_conf('MENU_SYMBOL', $special_characters_set{'bullet'});
+  }
+
+  if ($self->get_conf('USE_NUMERIC_ENTITY')) {
+    foreach my $command (keys(%Texinfo::Convert::Unicode::unicode_entities)) {
+      $conf_default_no_arg_commands_formatting_normal->{$command}->{'text'}
+       = $Texinfo::Convert::Unicode::unicode_entities{$command};
+    }
+  }
+
+  if ($self->get_conf('USE_XML_SYNTAX')) {
+    foreach my $customization_variable ('BIG_RULE', 'DEFAULT_RULE') {
+      my $variable_value = $self->get_conf($customization_variable);
+      if (defined($variable_value)) {
+        my $closed_lone_element = 
_xhtml_re_close_lone_element($variable_value);
+        if ($closed_lone_element ne $variable_value) {
+          $self->force_conf($customization_variable, $closed_lone_element);
+        }
+      }
+    }
+    $self->{'line_break_element'} = '<br/>';
+  } else {
+    $self->{'line_break_element'} = '<br>';
+  }
+  $conf_default_no_arg_commands_formatting_normal->{'*'}->{'text'}
+    = $self->{'line_break_element'};
+
+  %{$self->{'css_element_class_styles'}} = %css_element_class_styles;
+
+  $self->{'no_arg_commands_formatting'} = {};
+  foreach my $command (keys(%{$default_no_arg_commands_formatting{'normal'}})) 
{
+    $self->{'no_arg_commands_formatting'}->{$command} = {};
+    foreach my $context ('normal', 'preformatted', 'string', 'css_string') {
+      my $no_arg_command_customized_formatting
+        = Texinfo::Config::GNUT_get_no_arg_command_formatting($command, 
$context);
+      if (defined($no_arg_command_customized_formatting)) {
+        $self->{'no_arg_commands_formatting'}->{$command}->{$context}
+           = $no_arg_command_customized_formatting;
+      } else {
+        my $context_default_default_no_arg_commands_formatting
+          = $default_no_arg_commands_formatting{$context};
+        if ($context eq 'normal') {
+          $context_default_default_no_arg_commands_formatting
+           = $conf_default_no_arg_commands_formatting_normal;
+        }
+        if 
(defined($context_default_default_no_arg_commands_formatting->{$command})) {
+          if ($self->get_conf('OUTPUT_CHARACTERS')
+              and Texinfo::Convert::Unicode::brace_no_arg_command(
+                             $command, 
$self->get_conf('OUTPUT_ENCODING_NAME'))) {
+            $self->{'no_arg_commands_formatting'}->{$command}->{$context}
+              = { 'text' => Texinfo::Convert::Unicode::brace_no_arg_command(
+                           $command, $self->get_conf('OUTPUT_ENCODING_NAME'))};
+            # reset CSS for itemize command arguments
+            if ($context eq 'css_string'
+                and exists($brace_commands{$command})
+                and $command ne 'bullet' and $command ne 'w'
+                and not 
$special_list_mark_css_string_no_arg_command{$command}) {
+              my $css_string
+                = $self->{'no_arg_commands_formatting'}
+                                    ->{$command}->{$context}->{'text'};
+              $css_string = '"'.$css_string.'"';
+              $self->{'css_element_class_styles'}->{"ul.mark-$command"}
+                = "list-style-type: $css_string";
+            }
+          } else {
+            $self->{'no_arg_commands_formatting'}->{$command}->{$context}
+              = 
$context_default_default_no_arg_commands_formatting->{$command};
+          }
+        } else {
+          $self->{'no_arg_commands_formatting'}->{$command}->{$context}
+            = {'unset' => 1};
+        }
+      }
+    }
+  }
+
+  # set sane defaults in case there is none and the default formatting
+  # function is used
+  foreach my $command (keys(%{$default_no_arg_commands_formatting{'normal'}})) 
{
+    if ($self->{'commands_conversion'}->{$command}
+        and $self->{'commands_conversion'}->{$command}
+            eq $default_commands_conversion{$command}) {
+      $self->_complete_no_arg_commands_formatting($command);
+    }
+  }
+
+  # three types of direction strings:
+  # * strings not translated, already converted
+  # * strings translated
+  #   - strings already converted
+  #   - strings not already converted
+  $self->{'directions_strings'} = {};
+
+  # here because substitute_html_non_breaking_space is used
+  my $customized_direction_strings
+      = Texinfo::Config::GNUT_get_direction_string_info();
+  foreach my $string_type (keys(%default_converted_directions_strings)) {
+    $self->{'directions_strings'}->{$string_type} = {};
+    foreach my $direction
+            (keys(%{$default_converted_directions_strings{$string_type}})) {
+      $self->{'directions_strings'}->{$string_type}->{$direction} = {};
+      my $string_contexts;
+      if ($customized_direction_strings->{$string_type}
+          and $customized_direction_strings->{$string_type}->{$direction}) {
+        if (defined($customized_direction_strings->{$string_type}
+                                              ->{$direction}->{'converted'})) {
+          $string_contexts
+            = $customized_direction_strings->{$string_type}
+                                          ->{$direction}->{'converted'};
+        }
+      } else {
+        my $string
+          = $default_converted_directions_strings{$string_type}->{$direction};
+        $string_contexts
+          = {'normal' => $string};
+      }
+      $string_contexts->{'string'} = $string_contexts->{'normal'}
+        if (not defined($string_contexts->{'string'}));
+      foreach my $context (keys(%$string_contexts)) {
+        $self->{'directions_strings'}->{$string_type}->{$direction}->{$context}
+          = $self->substitute_html_non_breaking_space(
+                                                  
$string_contexts->{$context});
+      }
+    }
+  }
+
+  $self->{'translated_direction_strings'} = {};
+  foreach my $string_type (keys(%default_translated_directions_strings)) {
+    $self->{'translated_direction_strings'}->{$string_type} = {};
+    foreach my $direction
+           (keys(%{$default_translated_directions_strings{$string_type}})) {
+      if ($customized_direction_strings->{$string_type}
+            and $customized_direction_strings->{$string_type}->{$direction}) {
+        $self->{'translated_direction_strings'}->{$string_type}->{$direction}
+          = $customized_direction_strings->{$string_type}->{$direction};
+      } else {
+        if ($default_translated_directions_strings{$string_type}->{$direction}
+                                                              ->{'converted'}) 
{
+          $self->{'translated_direction_strings'}->{$string_type}
+                  ->{$direction} = {'converted' => {}};
+          foreach my $context ('normal', 'string') {
+            $self->{'translated_direction_strings'}->{$string_type}
+                     ->{$direction}->{'converted'}->{$context}
+               = $default_translated_directions_strings{$string_type}
+                                                 ->{$direction}->{'converted'};
+          }
+        } else {
+          $self->{'translated_direction_strings'}->{$string_type}->{$direction}
+            = 
$default_translated_directions_strings{$string_type}->{$direction};
+        }
+      }
+    }
+  }
 
   $self->{'shared_conversion_state'} = {};
 
-  $self->_initialize_output_state($context);
+  $self->_initialize_output_state('_convert');
 
   $self->{'multiple_pass'} = [];
 
@@ -11660,7 +11663,7 @@ sub _initialize_XS_NonXS_output_state($$)
   $self->{'global_units_directions'} = {};
 }
 
-sub _finalize_output_state($)
+sub conversion_finalization($)
 {
   my $self = shift;
   $self->_pop_document_context();
@@ -11743,11 +11746,11 @@ sub convert($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $converter_info;
   my $root = $document->tree();
 
-  $self->_initialize_XS_NonXS_output_state('_convert');
-
   # the presence of contents elements in the document is used in diverse
   # places, set it once for all here
   my @contents_elements_options
@@ -11798,7 +11801,7 @@ sub convert($$)
   my $result = $self->_html_convert_convert($root, $output_units,
                                             $special_units);
 
-  $self->_finalize_output_state();
+  $self->conversion_finalization();
   return $result;
 }
 
@@ -12303,14 +12306,14 @@ sub output($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
   # set here early even though actual values are only set later on.  It is
   # therefore set in converter_info early too (using the reference).
   $self->{'current_filename'} = undef;
 
-  $self->_initialize_XS_NonXS_output_state('_output');
-
   # no splitting when writing to the null device or to stdout or returning
   # a string
   if (defined($self->get_conf('OUTFILE'))
@@ -12374,7 +12377,7 @@ sub output($$)
   my $setup_status = $self->run_stage_handlers($root, 'setup');
   unless ($setup_status < $handler_fatal_error_level
           and $setup_status > -$handler_fatal_error_level) {
-    $self->_finalize_output_state();
+    $self->conversion_finalization();
     return undef;
   }
 
@@ -12437,7 +12440,7 @@ sub output($$)
     = $self->create_destination_directory($encoded_destination_directory,
                                           $destination_directory);
   unless ($succeeded) {
-    $self->_finalize_output_state();
+    $self->conversion_finalization();
     return undef;
   }
 
@@ -12482,7 +12485,7 @@ sub output($$)
   my $structure_status = $self->run_stage_handlers($root, 'structure');
   unless ($structure_status < $handler_fatal_error_level
           and $structure_status > -$handler_fatal_error_level) {
-    $self->_finalize_output_state();
+    $self->conversion_finalization();
     return undef;
   }
 
@@ -12507,7 +12510,7 @@ sub output($$)
   my $init_status = $self->run_stage_handlers($root, 'init');
   unless ($init_status < $handler_fatal_error_level
           and $init_status > -$handler_fatal_error_level) {
-    $self->_finalize_output_state();
+    $self->conversion_finalization();
     return undef;
   }
 
@@ -12532,7 +12535,7 @@ sub output($$)
   $self->get_output_files_XS_unclosed_streams();
 
   if (!defined($text_output)) {
-    $self->_finalize_output_state();
+    $self->conversion_finalization();
     return undef;
   }
 
@@ -12543,7 +12546,7 @@ sub output($$)
       # only if formatting is called as convert, which only happens in tests.
       $self->_do_js_files($destination_directory);
     }
-    $self->_finalize_output_state();
+    $self->conversion_finalization();
     return $text_output;
   }
 
@@ -12552,7 +12555,7 @@ sub output($$)
   my $finish_status = $self->run_stage_handlers($root, 'finish');
   unless ($finish_status < $handler_fatal_error_level
           and $finish_status > -$handler_fatal_error_level) {
-    $self->_finalize_output_state();
+    $self->conversion_finalization();
     return undef;
   }
 
@@ -12702,14 +12705,14 @@ sub output($$)
             $self->converter_document_error(sprintf(__(
                              "error on closing redirection node file %s: %s"),
                                     $out_filename, $!));
-            $self->_finalize_output_state();
+            $self->conversion_finalization();
             return undef;
           }
         }
       }
     }
   }
-  $self->_finalize_output_state();
+  $self->conversion_finalization();
   return undef;
 }
 
diff --git a/tp/Texinfo/Convert/IXIN.pm b/tp/Texinfo/Convert/IXIN.pm
index 7817a03aab..468c2545cf 100644
--- a/tp/Texinfo/Convert/IXIN.pm
+++ b/tp/Texinfo/Convert/IXIN.pm
@@ -321,7 +321,11 @@ my @node_directions = ('Next', 'Prev', 'Up');
 sub output_ixin($$)
 {
   my $self = shift;
-  my $root = shift;
+  my $document = shift;
+
+  $self->conversion_initialization($document);
+
+  my $root = $document->tree();
 
   my ($output_file, $destination_directory, $output_filename)
     = $self->determine_files_and_directory($self->{'output_format'});
@@ -331,7 +335,10 @@ sub output_ixin($$)
   my $succeeded
     = $self->create_destination_directory($encoded_destination_directory,
                                           $destination_directory);
-  return undef unless $succeeded;
+  unless ($succeeded) {
+    $self->conversion_finalization();
+    return undef;
+  }
 
   my $fh;
   my $encoded_output_file;
@@ -347,6 +354,7 @@ sub output_ixin($$)
       $self->converter_document_error(
                 sprintf(__("could not open %s for writing: %s"),
                                     $output_file, $error_message));
+      $self->conversion_finalization();
       return undef;
     }
   }
@@ -441,10 +449,9 @@ sub output_ixin($$)
     my $setting_command = $setting_commands{$setting_command_name};
     $setting_command_name = 'shortcontents'
         if ($setting_command_name eq 'summarycontents');
-    # FIXME should use get_conf instead?
-    my $value = Texinfo::Common::_informative_command_value($setting_command);
+    my $value = Texinfo::Common::informative_command_value($setting_command);
     #print STDERR "$setting_command_name $value\n";
-    # do not register settings if sete at the default value.
+    # do not register settings if set at the default value.
     if (defined($value)
         and !(defined($setting_commands_defaults{$setting_command_name})
               and $setting_commands_defaults{$setting_command_name} eq 
$value)) {
@@ -1006,6 +1013,7 @@ sub output_ixin($$)
                                     $output_file, $!));
     }
   }
+  $self->conversion_finalization();
   return $output;
 }
 
diff --git a/tp/Texinfo/Convert/IXINSXML.pm b/tp/Texinfo/Convert/IXINSXML.pm
index 0bf0bc3914..6a8ae65ed1 100644
--- a/tp/Texinfo/Convert/IXINSXML.pm
+++ b/tp/Texinfo/Convert/IXINSXML.pm
@@ -74,7 +74,8 @@ sub converter_defaults($$)
 # but it could theoretically be needed for a flexible conversion
 # (since the IXIN project is inactive, the corresponding code is not updated
 # actively either, so it is unlikely to change, though).
-sub converter_initialize($) { my $self = shift;
+sub converter_initialize($) {
+  my $self = shift;
 
   $self->{'converted_format'} = $defaults{'converted_format'};
 
@@ -89,9 +90,7 @@ sub output($$)
   my $self = shift;
   my $document = shift;
 
-  my $root = $document->tree();
-
-  return $self->output_ixin($root);
+  return $self->output_ixin($document);
 }
 
 1;
diff --git a/tp/Texinfo/Convert/Info.pm b/tp/Texinfo/Convert/Info.pm
index 6de6f7988b..87f31ffa15 100644
--- a/tp/Texinfo/Convert/Info.pm
+++ b/tp/Texinfo/Convert/Info.pm
@@ -67,6 +67,8 @@ sub output($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
   my $result;
@@ -79,7 +81,10 @@ sub output($$)
   my ($succeeded, $created_directory)
     = $self->create_destination_directory($encoded_destination_directory,
                                           $destination_directory);
-  return undef unless $succeeded;
+  unless ($succeeded) {
+    $self->conversion_finalization();
+    return undef;
+  }
 
   # for format_node
   $self->{'output_filename'} = $output_filename;
@@ -107,6 +112,7 @@ sub output($$)
     }
     $fh = _open_info_file($self, $output_file);
     if (!$fh) {
+      $self->conversion_finalization();
       return undef;
     }
   }
@@ -184,6 +190,7 @@ sub output($$)
             $self->converter_document_error(
                   sprintf(__("error on closing %s: %s"),
                                   $output_file, $close_error));
+            $self->conversion_finalization();
             return undef;
           }
           if ($self->get_conf('VERBOSE')) {
@@ -194,6 +201,7 @@ sub output($$)
             $self->converter_document_error(
                   sprintf(__("rename %s failed: %s"),
                                          $output_file, $!));
+            $self->conversion_finalization();
             return undef;
           }
           # remove the main file from opened files since it was renamed
@@ -212,6 +220,7 @@ sub output($$)
                   sprintf(__("error on closing %s: %s"),
                                   $output_file.'-'.$out_file_nr,
                                   $close_error));
+            $self->conversion_finalization();
             return undef;
           }
         }
@@ -222,6 +231,7 @@ sub output($$)
         }
         $fh = _open_info_file($self, $output_file.'-'.$out_file_nr);
         if (!$fh) {
+          $self->conversion_finalization();
           return undef;
         }
         print $fh $complete_header;
@@ -239,6 +249,7 @@ sub output($$)
       $self->converter_document_error(
                sprintf(__("error on closing %s: %s"),
                             $output_file.'-'.$out_file_nr, $!));
+      $self->conversion_finalization();
       return undef;
     }
     if ($self->get_conf('VERBOSE')) {
@@ -246,6 +257,7 @@ sub output($$)
     }
     $fh = _open_info_file($self, $output_file);
     if (!$fh) {
+      $self->conversion_finalization();
       return undef;
     }
     $tag_text = $complete_header;
@@ -319,6 +331,7 @@ sub output($$)
   } else {
     $result .= $tag_text;
   }
+  $self->conversion_finalization();
   return $result;
 }
 
diff --git a/tp/Texinfo/Convert/LaTeX.pm b/tp/Texinfo/Convert/LaTeX.pm
index 7b033f0159..1f7fff233e 100644
--- a/tp/Texinfo/Convert/LaTeX.pm
+++ b/tp/Texinfo/Convert/LaTeX.pm
@@ -722,7 +722,7 @@ foreach my $typewriter_command (@typewriter_commands) {
 my @quoted_commands = ('samp', 'indicateurl');
 
 my %quotes_map;
-# Quotes are reset in converter_initialize and unicode quotes are used
+# Quotes are reset in conversion_initialization and unicode quotes are used
 # if @documentencoding utf-8 is used.
 foreach my $quoted_command (@quoted_commands) {
   $quotes_map{$quoted_command} = ["`", "'"];
@@ -842,6 +842,13 @@ sub converter_initialize($)
     $self->{'ignored_commands'}->{$format} = 1
        unless ($self->{'expanded_formats'}->{$format});
   }
+  return $self;
+}
+
+sub conversion_initialization($;$)
+{
+  my $self = shift;
+  my $document = shift;
 
   %{$self->{'quotes_map'}} = %quotes_map;
 
@@ -880,8 +887,6 @@ sub converter_initialize($)
   $self->{'output_characters'} = $self->get_conf('OUTPUT_CHARACTERS');
   $self->{'output_encoding_name'} = $self->get_conf('OUTPUT_ENCODING_NAME');
   $self->{'debug'} = $self->get_conf('DEBUG');
-
-  return $self;
 }
 
 my %LaTeX_floats = (
@@ -955,7 +960,6 @@ sub _prepare_indices($)
   }
 }
 
-
 sub _prepare_conversion($;$)
 {
   my $self = shift;
@@ -1050,6 +1054,8 @@ sub output($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
   my ($output_file, $destination_directory, $output_filename)
@@ -1157,6 +1163,8 @@ sub convert($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
   $self->_prepare_conversion($root);
@@ -1227,6 +1235,8 @@ sub convert_to_latex_math($$;$$)
     $self = Texinfo::Convert::LaTeX->converter($options);
   }
 
+  $self->conversion_initialization();
+
   _push_new_context($self, 'convert_to_math');
 
   push @{$self->{'formatting_context'}->[-1]->{'text_context'}}, 'ctx_math';
diff --git a/tp/Texinfo/Convert/Plaintext.pm b/tp/Texinfo/Convert/Plaintext.pm
index 5766691dc9..557313376b 100644
--- a/tp/Texinfo/Convert/Plaintext.pm
+++ b/tp/Texinfo/Convert/Plaintext.pm
@@ -404,14 +404,28 @@ sub push_top_formatter($$)
   $self->{'formatters'}->[-1]->{'_top_formatter'} = 1;
 }
 
+sub pop_top_formatter($)
+{
+  my $self = shift;
+
+  my $old_context = pop @{$self->{'context'}};
+  pop @{$self->{'formatters'}};
+  pop @{$self->{'format_context'}};
+  pop @{$self->{'text_element_context'}};
+  pop @{$self->{'document_context'}};
+
+  return $old_context;
+}
+
 sub converter_defaults($$)
 {
   return %defaults;
 }
 
-sub converter_initialize($)
+sub conversion_initialization($;$)
 {
   my $self = shift;
+  my $document = shift;
 
   $self->{'context'} = [];
   $self->{'format_context'} = [];
@@ -421,40 +435,24 @@ sub converter_initialize($)
                                      'result' => ''
   };
 
-  %{$self->{'ignored_types'}} = %ignored_types;
-  %{$self->{'ignorable_space_types'}} = %ignorable_space_types;
-  %{$self->{'ignored_commands'}} = %ignored_commands;
+  # setting to 1 ensures that nothing is done, as there is
+  # something done (a newline added) if equal to 0.
+  $self->{'empty_lines_count'} = 1;
+  $self->{'seenmenus'} = {};
+  $self->{'index_entries_line_location'} = {};
+
   # this is dynamic because raw formats may either be full commands if
   # isolated, or simple text if in a paragraph
   %{$self->{'format_context_commands'}} = %default_format_context_commands;
   %{$self->{'preformatted_context_commands'}}
      = %default_preformatted_context_commands;
+
   $self->{'footnote_index'} = 0;
   $self->{'pending_footnotes'} = [];
   $self->{'index_entry_node_colon'} = {};
   $self->{'index_entries_no_node'} = {};
   $self->{'seen_node_descriptions'} = {};
 
-  foreach my $format (keys(%format_raw_commands)) {
-    $self->{'ignored_commands'}->{$format} = 1
-       unless ($self->{'expanded_formats'}->{$format});
-  }
-
-  if ($self->get_conf('ASCII_PUNCTUATION')) {
-    $self->set_conf('ASCII_DASHES_AND_QUOTES', 1);
-    $self->set_conf('ASCII_GLYPH', 1);
-    $self->set_conf('OPEN_QUOTE_SYMBOL', '\'');
-    $self->set_conf('CLOSE_QUOTE_SYMBOL', '\'');
-    $self->set_conf('OPEN_DOUBLE_QUOTE_SYMBOL', '"');
-    $self->set_conf('CLOSE_DOUBLE_QUOTE_SYMBOL', '"');
-  }
-  if ($self->get_conf('ASCII_DASHES_AND_QUOTES')) {
-    # cache to avoid calling get_conf
-    $self->{'ascii_dashes_and_quotes'} = 1;
-  } else {
-    $self->{'ascii_dashes_and_quotes'} = 0;
-  }
-
   %{$self->{'style_map'}} = %style_map;
 
   Texinfo::Common::output_files_disable_output_encoding
@@ -500,6 +498,46 @@ sub converter_initialize($)
     }
   }
 
+  # some caching to avoid calling get_conf
+  if (defined($self->get_conf('OUTPUT_PERL_ENCODING'))) {
+    $self->{'output_perl_encoding'} = $self->get_conf('OUTPUT_PERL_ENCODING');
+  } else {
+    $self->{'output_perl_encoding'} = '';
+  }
+  $self->{'enable_encoding'} = $self->get_conf('ENABLE_ENCODING');
+  $self->{'output_encoding_name'} = $self->get_conf('OUTPUT_ENCODING_NAME');
+  $self->{'debug'} = $self->get_conf('DEBUG');
+
+  $self->push_top_formatter('_Root_context');
+}
+
+sub converter_initialize($)
+{
+  my $self = shift;
+
+  %{$self->{'ignored_types'}} = %ignored_types;
+  %{$self->{'ignorable_space_types'}} = %ignorable_space_types;
+  %{$self->{'ignored_commands'}} = %ignored_commands;
+
+  foreach my $format (keys(%format_raw_commands)) {
+    $self->{'ignored_commands'}->{$format} = 1
+       unless ($self->{'expanded_formats'}->{$format});
+  }
+
+  if ($self->get_conf('ASCII_PUNCTUATION')) {
+    $self->set_conf('ASCII_DASHES_AND_QUOTES', 1);
+    $self->set_conf('ASCII_GLYPH', 1);
+    $self->set_conf('OPEN_QUOTE_SYMBOL', '\'');
+    $self->set_conf('CLOSE_QUOTE_SYMBOL', '\'');
+    $self->set_conf('OPEN_DOUBLE_QUOTE_SYMBOL', '"');
+    $self->set_conf('CLOSE_DOUBLE_QUOTE_SYMBOL', '"');
+  }
+  if ($self->get_conf('ASCII_DASHES_AND_QUOTES')) {
+    # cache to avoid calling get_conf
+    $self->{'ascii_dashes_and_quotes'} = 1;
+  } else {
+    $self->{'ascii_dashes_and_quotes'} = 0;
+  }
   if ($self->get_conf('FILLCOLUMN')) {
     $self->{'fillcolumn'} = $self->get_conf('FILLCOLUMN');
     # else it's already set via the defaults
@@ -524,21 +562,16 @@ sub converter_initialize($)
     $self->{'info_special_chars_warning'} = '';
   }
 
-  # This needs to be here to take into account $self->{'fillcolumn'}.
-  $self->push_top_formatter('_Root_context');
-  # some caching to avoid calling get_conf
-  if (defined($self->get_conf('OUTPUT_PERL_ENCODING'))) {
-    $self->{'output_perl_encoding'} = $self->get_conf('OUTPUT_PERL_ENCODING');
-  } else {
-    $self->{'output_perl_encoding'} = '';
-  }
-  $self->{'enable_encoding'} = $self->get_conf('ENABLE_ENCODING');
-  $self->{'output_encoding_name'} = $self->get_conf('OUTPUT_ENCODING_NAME');
-  $self->{'debug'} = $self->get_conf('DEBUG');
-
   return $self;
 }
 
+sub conversion_finalization($)
+{
+  my $self = shift;
+
+  $self->pop_top_formatter();
+}
+
 sub count_context_bug_message($$$)
 {
   my ($self, $precision, $output_unit) = @_;
@@ -558,21 +591,6 @@ sub count_context_bug_message($$$)
   }
 }
 
-sub _initialize_converter_state($)
-{
-  my $self = shift;
-
-  if (!defined($self->{'empty_lines_count'})) {
-    # setting to 1 ensures that nothing is done, as there is
-    # something done (a newline added) if equal to 0.
-    $self->{'empty_lines_count'} = 1;
-  }
-  $self->{'seenmenus'} = {}
-    if (!$self->{'seenmenus'});
-  $self->{'index_entries_line_location'} = {}
-    if (!$self->{'index_entries_line_location'});
-}
-
 # the initialization of module specific state is not done in output()
 # as output() is the generic Converter::Convert function, so it needs
 # to be done here by calling _initialize_converter_state.
@@ -580,8 +598,6 @@ sub convert_output_unit($$)
 {
   my ($self, $output_unit) = @_;
 
-  _initialize_converter_state($self);
-
   $self->{'count_context'}->[-1]->{'result'} = '';
 
   if ($output_unit->{'unit_contents'}) {
@@ -600,14 +616,13 @@ sub convert($$)
 {
   my ($self, $document) = @_;
 
+  $self->conversion_initialization($document);
+
   my $root = $document->tree();
 
   my $result = '';
 
   my $output_units = Texinfo::Structuring::split_by_node($root);
-  $self->{'seenmenus'} = {};
-  $self->{'empty_lines_count'} = 1;
-  $self->{'index_entries_line_location'} = {};
   if (!defined($output_units)) {
     push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0,
                                        'locations' => [],
@@ -627,6 +642,8 @@ sub convert($$)
     }
   }
 
+  $self->conversion_finalization();
+
   return $result;
 }
 
@@ -1159,12 +1176,8 @@ sub process_footnotes($;$)
       $self->_convert($footnote->{'root'}->{'args'}->[0]);
       _add_newline_if_needed($self);
 
-      my $old_context = pop @{$self->{'context'}};
+      my $old_context = $self->pop_top_formatter();
       die if ($old_context ne 'footnote');
-      pop @{$self->{'formatters'}};
-      pop @{$self->{'format_context'}};
-      pop @{$self->{'text_element_context'}};
-      pop @{$self->{'document_context'}};
     }
   }
   $self->{'footnote_index'} = 0;
@@ -1932,6 +1945,9 @@ sub _convert($$)
   # especially
   if ($type and ($type eq 'empty_line'
                  or $type eq 'after_menu_description_line')) {
+    #if (!$self->{'text_element_context'}) {
+    #  cluck;
+    #}
     delete $self->{'text_element_context'}->[-1]->{'counter'};
     $self->{'empty_lines_count'}++;
     if ($self->{'empty_lines_count'} <= 1
diff --git a/tp/Texinfo/Convert/TexinfoMarkup.pm 
b/tp/Texinfo/Convert/TexinfoMarkup.pm
index 135d225551..1d915bbbd2 100644
--- a/tp/Texinfo/Convert/TexinfoMarkup.pm
+++ b/tp/Texinfo/Convert/TexinfoMarkup.pm
@@ -271,7 +271,6 @@ sub converter_initialize($)
 {
   my $self = shift;
 
-  $self->{'document_context'} = [{'monospace' => [0]}];
   $self->{'context_block_commands'} = {%default_context_block_commands};
   foreach my $raw (grep {$Texinfo::Commands::block_commands{$_} eq 
'format_raw'}
                         keys(%Texinfo::Commands::block_commands)) {
@@ -280,12 +279,21 @@ sub converter_initialize($)
   }
 }
 
+sub conversion_initialization($;$)
+{
+  my $self = shift;
+
+  $self->{'document_context'} = [{'monospace' => [0]}];
+}
+
 # Main output function for the Texinfo language markup output files.
 sub output($$)
 {
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization();
+
   my $root = $document->tree();
 
   my ($output_file, $destination_directory, $output_filename)
@@ -298,7 +306,6 @@ sub output($$)
                                           $destination_directory);
   return undef unless $succeeded;
 
-
   my $fh;
   my $encoded_output_file;
   if (! $output_file eq '') {
@@ -435,6 +442,8 @@ sub convert($$)
   my $self = shift;
   my $document = shift;
 
+  $self->conversion_initialization();
+
   my $root = $document->tree();
 
   return $self->convert_tree($root);
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index e5cdeeec9c..f3e152e685 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -70,6 +70,9 @@ init (...)
 void
 converter_initialize (SV *converter_in)
 
+void
+converter_set_document (SV *converter_in, SV *document_in)
+
 
 void
 set_conf (SV *converter_in, conf, SV *value)
@@ -339,7 +342,7 @@ void
 html_format_init ()
 
 void
-html_converter_initialize_sv (SV *converter_in, SV 
*default_formatting_references, SV *default_css_string_formatting_references, 
SV *default_commands_open, SV *default_commands_conversion, SV 
*default_css_string_commands_conversion, SV *default_types_open, SV 
*default_types_conversion, SV *default_css_string_types_conversion, SV 
*default_output_units_conversion, SV *default_special_unit_body)
+html_converter_initialize_sv (SV *converter_in, SV 
*default_formatting_references, SV *default_css_string_formatting_references, 
SV *default_commands_open, SV *default_commands_conversion, SV 
*default_css_string_commands_conversion, SV *default_types_open, SV 
*default_types_conversion, SV *default_css_string_types_conversion, SV 
*default_output_units_conversion, SV *default_no_arg_commands_formatting, SV 
*default_special_unit_body)
 
 void
 html_initialize_output_state (SV *converter_in, char *context)
@@ -348,17 +351,20 @@ html_initialize_output_state (SV *converter_in, char 
*context)
       CODE:
          self = get_sv_converter (converter_in, 
"html_initialize_output_state");
          if (self)
-           html_initialize_output_state (self, context);
+           {
+             html_conversion_initialization_sv (converter_in, self);
+             html_initialize_output_state (self, context);
+           }
 
 void
-html_finalize_output_state (SV *converter_in)
+html_conversion_finalization (SV *converter_in)
       PREINIT:
          CONVERTER *self;
       CODE:
-         self = get_sv_converter (converter_in, "html_finalize_output_state");
+         self = get_sv_converter (converter_in, 
"html_conversion_finalization");
          if (self)
            {
-             html_finalize_output_state (self);
+             html_conversion_finalization (self);
 
              if (self->modified_state)
                {
diff --git a/tp/Texinfo/XS/convert/IndicesXS.xs 
b/tp/Texinfo/XS/convert/IndicesXS.xs
index b20311c12b..94bd73e1ee 100644
--- a/tp/Texinfo/XS/convert/IndicesXS.xs
+++ b/tp/Texinfo/XS/convert/IndicesXS.xs
@@ -89,6 +89,7 @@ setup_index_entry_keys_formatting (SV *customization_info_sv)
     OUTPUT:
          RETVAL
 
+# should only return undef if no document is found
 SV *
 index_entry_element_sort_string (SV *customization_info_sv, SV *main_entry_sv, 
SV *element_sv, SV *options_sv, SV *prefer_reference_element_sv=0)
     PREINIT:
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index 728a4c03e1..3272f6a5c5 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -16432,6 +16432,11 @@ reset_html_targets (CONVERTER *self, HTML_TARGET_LIST 
*targets)
 void
 html_initialize_output_state (CONVERTER *self, char *context)
 {
+  if (!self->document && self->conf->DEBUG.integer > 0)
+    {
+      fprintf (stderr, "REMARK: html_initialize_output_state: no document");
+    }
+
   /* set the htmlxref type split of the document */
   self->document_htmlxref_split_type = htmlxref_split_type_mono;
 
@@ -16461,7 +16466,7 @@ html_initialize_output_state (CONVERTER *self, char 
*context)
 
   html_new_document_context (self, context, 0, 0);
 
-  if (self->document->index_names)
+  if (self->document && self->document->index_names)
     {
       INDEX **i, *idx;
       size_t j;
@@ -16491,7 +16496,7 @@ html_initialize_output_state (CONVERTER *self, char 
*context)
 }
 
 void
-html_finalize_output_state (CONVERTER *self)
+html_conversion_finalization (CONVERTER *self)
 {
   int i;
   for (i = 0; i < self->html_files_information.number; i++)
diff --git a/tp/Texinfo/XS/convert/convert_html.h 
b/tp/Texinfo/XS/convert/convert_html.h
index b86832d745..206acdd78b 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -41,7 +41,7 @@ void html_format_init (void);
 void html_converter_initialize (CONVERTER *self);
 
 void html_initialize_output_state (CONVERTER *self, char *context);
-void html_finalize_output_state (CONVERTER *self);
+void html_conversion_finalization (CONVERTER *self);
 
 void html_converter_prepare_output (CONVERTER* self);
 
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.c 
b/tp/Texinfo/XS/convert/get_html_perl_info.c
index f2405420bc..bae600d7f0 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.c
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.c
@@ -137,6 +137,7 @@ html_converter_initialize_sv (SV *converter_sv,
                               SV *default_types_conversion,
                               SV *default_css_string_types_conversion,
                               SV *default_output_units_conversion,
+                              SV *default_no_arg_commands_formatting,
                               SV *default_special_unit_body)
 {
   int i;
@@ -153,7 +154,6 @@ html_converter_initialize_sv (SV *converter_sv,
   SV **htmlxref_sv;
   SV **formatting_function_sv;
   SV **sorted_special_unit_varieties_sv;
-  SV **no_arg_commands_formatting_sv;
   SV **accent_entities_sv;
   SV **style_commands_formatting_sv;
   SV **types_open_sv;
@@ -164,21 +164,13 @@ html_converter_initialize_sv (SV *converter_sv,
   SV **code_types_sv;
   SV **upper_case_commands_sv;
   SV **pre_class_types_sv;
-  SV **directions_strings_sv;
-  SV **translated_direction_strings_sv;
-  SV **css_element_class_styles_sv;
   HV *formatting_function_hv;
   HV *commands_open_hv;
   HV *commands_conversion_hv;
   HV *types_open_hv;
   HV *types_conversion_hv;
   HV *output_units_conversion_hv;
-  HV *directions_strings_hv;
-  HV *translated_direction_strings_hv;
   CONVERTER *converter;
-  int nr_string_directions;
-  int nr_dir_str_contexts = TDS_context_string +1;
-  enum direction_string_type DS_type;
   int nr_accent_cmd = 0;
 
   dTHX;
@@ -442,6 +434,41 @@ html_converter_initialize_sv (SV *converter_sv,
         output_units_conversion_hv);
     }
 
+  /* gather no_arg_formatted_cmd commands.  The formatting is gathered later
+     as it depends on the document encoding */
+  if (SvOK (default_no_arg_commands_formatting))
+    {
+      I32 hv_number;
+      I32 i;
+
+      HV *default_no_arg_commands_formatting_hv
+        = (HV*) SvRV (default_no_arg_commands_formatting);
+
+      hv_number = hv_iterinit (default_no_arg_commands_formatting_hv);
+      converter->no_arg_formatted_cmd.list = (enum command_id *)
+        malloc (hv_number * sizeof (enum command_id));
+      converter->no_arg_formatted_cmd.number = 0;
+
+      for (i = 0; i < hv_number; i++)
+        {
+          I32 retlen;
+          HE *convert_he = hv_iternext (default_no_arg_commands_formatting_hv);
+          char *cmdname = hv_iterkey (convert_he, &retlen);
+          enum command_id cmd = lookup_builtin_command (cmdname);
+
+          if (!cmd)
+            fprintf (stderr, "ERROR: %s: no arg command not found\n", cmdname);
+          else
+            {
+              converter->no_arg_formatted_cmd.list[
+                           converter->no_arg_formatted_cmd.number] = cmd;
+              converter->no_arg_formatted_cmd.number++;
+            }
+        }
+      qsort (converter->no_arg_formatted_cmd.list, hv_number,
+             sizeof (enum command_id), compare_ints);
+    }
+
   FETCH(sorted_special_unit_varieties)
 
   if (sorted_special_unit_varieties_sv)
@@ -643,51 +670,99 @@ html_converter_initialize_sv (SV *converter_sv,
        }
    }
 
-  FETCH(no_arg_commands_formatting)
+  FETCH(accent_entities)
 
-  if (no_arg_commands_formatting_sv)
+  if (accent_entities_sv)
     {
-      int max_context = HCC_type_css_string;
       I32 hv_number;
       I32 i;
 
-      HV *no_arg_commands_formatting_hv
-        = (HV *)SvRV (*no_arg_commands_formatting_sv);
+      HV *accent_entities_hv
+        = (HV *)SvRV (*accent_entities_sv);
 
-      hv_number = hv_iterinit (no_arg_commands_formatting_hv);
+      hv_number = hv_iterinit (accent_entities_hv);
 
-      converter->no_arg_formatted_cmd.list = (enum command_id *)
+      for (i = 0; i < hv_number; i++)
+        {
+          char *cmdname;
+          I32 retlen;
+          SV *spec_sv = hv_iternextsv (accent_entities_hv,
+                                          &cmdname, &retlen);
+          if (SvOK (spec_sv))
+            {
+              enum command_id cmd = lookup_builtin_command (cmdname);
+              if (!cmd)
+                fprintf (stderr, "ERROR: %s: no accent command\n", cmdname);
+              else
+                {
+                  ACCENT_ENTITY_INFO *accent_info
+                    = &converter->accent_entities[cmd];
+                  AV *spec_av = (AV *)SvRV (spec_sv);
+                  SV **entity_sv = av_fetch (spec_av, 0, 0);
+                  SV **characters_sv = av_fetch (spec_av, 1, 0);
+
+                  if (entity_sv)
+                    {
+                      char *entity = (char *) SvPVutf8_nolen (*entity_sv);
+                      accent_info->entity = strdup (entity);
+                    }
+
+                  if (characters_sv && SvOK (*characters_sv))
+                    {
+                      char *characters
+                        = (char *) SvPVutf8_nolen (*characters_sv);
+                      if (strlen (characters))
+                        accent_info->characters = strdup (characters);
+                    }
+                }
+            }
+        }
+    }
+
+
+  FETCH(style_commands_formatting)
+
+  if (style_commands_formatting_sv)
+    {
+      int max_context = HCC_type_string;
+      I32 hv_number;
+      I32 i;
+
+      HV *style_commands_formatting_hv
+        = (HV *)SvRV (*style_commands_formatting_sv);
+
+      hv_number = hv_iterinit (style_commands_formatting_hv);
+      converter->style_formatted_cmd.list = (enum command_id *)
         malloc (hv_number * sizeof (enum command_id));
-      converter->no_arg_formatted_cmd.number = 0;
+      converter->style_formatted_cmd.number = 0;
 
       for (i = 0; i < hv_number; i++)
         {
           char *cmdname;
           I32 retlen;
-          SV *context_sv = hv_iternextsv (no_arg_commands_formatting_hv,
+          SV *context_sv = hv_iternextsv (style_commands_formatting_hv,
                                           &cmdname, &retlen);
           if (SvOK (context_sv))
             {
               HV *context_hv = (HV *)SvRV (context_sv);
               enum command_id cmd = lookup_builtin_command (cmdname);
-
               if (!cmd)
-                fprintf (stderr, "ERROR: %s: no no arg command\n", cmdname);
+                fprintf (stderr, "ERROR: %s: no style command\n", cmdname);
               else
                 {
                   I32 context_nr;
                   I32 j;
 
-                  converter->no_arg_formatted_cmd.list[
-                               converter->no_arg_formatted_cmd.number] = cmd;
-                  converter->no_arg_formatted_cmd.number++;
+                  converter->style_formatted_cmd.list[
+                                 converter->style_formatted_cmd.number] = cmd;
+                  converter->style_formatted_cmd.number++;
 
                   context_nr = hv_iterinit (context_hv);
                   for (j = 0; j < context_nr; j++)
                     {
                       char *context_name;
                       I32 retlen;
-                      enum conversion_context k;
+                      int k;
                       int context_idx = -1;
                       SV *format_spec_sv = hv_iternextsv (context_hv,
                                                  &context_name, &retlen);
@@ -703,7 +778,7 @@ html_converter_initialize_sv (SV *converter_sv,
                       if (context_idx < 0)
                         {
                           fprintf (stderr,
-                              "ERROR: %s: %s: unknown no arg context\n",
+                              "ERROR: %s: %s: unknown style context\n",
                                          cmdname, context_name);
                           break;
                         }
@@ -732,131 +807,84 @@ html_converter_initialize_sv (SV *converter_sv,
                                     = (char *) SvPVutf8_nolen (spec_sv);
                                   format_spec->element = strdup (tmp_spec);
                                 }
-                              else if (!strcmp (key, "unset"))
-                                format_spec->unset = SvIV (spec_sv);
-                              else if (!strcmp (key, "text"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->text = strdup (tmp_spec);
-                                }
-                              else if (!strcmp (key, "translated_converted"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->translated_converted
-                                    = strdup (tmp_spec);
-                                }
-                              else if (!strcmp (key, "translated_to_convert"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->translated_to_convert
-                                    = strdup (tmp_spec);
-                                }
+                              else if (!strcmp (key, "quote"))
+                                format_spec->quote = SvIV (spec_sv);
                             }
+                            /*
+                          fprintf (stderr, "HHH %d %d %s %d %d %s %d %s\n", i, 
cmd, cmdname, j, context_idx, context_name, format_spec->quote, 
format_spec->element);
+                             */
                         }
                     }
                 }
             }
         }
-      qsort (converter->no_arg_formatted_cmd.list, hv_number,
-             sizeof (enum command_id), compare_ints);
     }
 
-  FETCH(accent_entities)
-
-  if (accent_entities_sv)
-    {
-      I32 hv_number;
-      I32 i;
-
-      HV *accent_entities_hv
-        = (HV *)SvRV (*accent_entities_sv);
-
-      hv_number = hv_iterinit (accent_entities_hv);
+  html_converter_initialize (converter);
 
-      for (i = 0; i < hv_number; i++)
-        {
-          char *cmdname;
-          I32 retlen;
-          SV *spec_sv = hv_iternextsv (accent_entities_hv,
-                                          &cmdname, &retlen);
-          if (SvOK (spec_sv))
-            {
-              enum command_id cmd = lookup_builtin_command (cmdname);
-              if (!cmd)
-                fprintf (stderr, "ERROR: %s: no accent command\n", cmdname);
-              else
-                {
-                  ACCENT_ENTITY_INFO *accent_info
-                    = &converter->accent_entities[cmd];
-                  AV *spec_av = (AV *)SvRV (spec_sv);
-                  SV **entity_sv = av_fetch (spec_av, 0, 0);
-                  SV **characters_sv = av_fetch (spec_av, 1, 0);
+  /* at that point, the format specific informations, in particular the number
+     of special elements is available, such that all the options can be
+     passed to C.  It is important to set the force argument to 1 to get
+     all the configuration, even if the configured field is set */
+  copy_converter_conf_sv (converter_hv, converter,
+                          &converter->conf, "conf", 1);
+}
 
-                  if (entity_sv)
-                    {
-                      char *entity = (char *) SvPVutf8_nolen (*entity_sv);
-                      accent_info->entity = strdup (entity);
-                    }
+void
+html_conversion_initialization_sv (SV *converter_sv, CONVERTER *converter)
+{
+  HV *converter_hv;
+  SV **no_arg_commands_formatting_sv;
+  SV **directions_strings_sv;
+  SV **translated_direction_strings_sv;
+  SV **css_element_class_styles_sv;
+  HV *translated_direction_strings_hv;
+  HV *directions_strings_hv;
+  enum direction_string_type DS_type;
+  int nr_string_directions;
+  int nr_dir_str_contexts = TDS_context_string +1;
 
-                  if (characters_sv && SvOK (*characters_sv))
-                    {
-                      char *characters
-                        = (char *) SvPVutf8_nolen (*characters_sv);
-                      if (strlen (characters))
-                        accent_info->characters = strdup (characters);
-                    }
-                }
-            }
-        }
-    }
+  dTHX;
 
+  converter_hv = (HV *)SvRV (converter_sv);
 
-  FETCH(style_commands_formatting)
+  FETCH(no_arg_commands_formatting)
 
-  if (style_commands_formatting_sv)
+  if (no_arg_commands_formatting_sv)
     {
-      int max_context = HCC_type_string;
+      int max_context = HCC_type_css_string;
       I32 hv_number;
       I32 i;
 
-      HV *style_commands_formatting_hv
-        = (HV *)SvRV (*style_commands_formatting_sv);
+      HV *no_arg_commands_formatting_hv
+        = (HV *)SvRV (*no_arg_commands_formatting_sv);
 
-      hv_number = hv_iterinit (style_commands_formatting_hv);
-      converter->style_formatted_cmd.list = (enum command_id *)
-        malloc (hv_number * sizeof (enum command_id));
-      converter->style_formatted_cmd.number = 0;
+      hv_number = hv_iterinit (no_arg_commands_formatting_hv);
 
       for (i = 0; i < hv_number; i++)
         {
           char *cmdname;
           I32 retlen;
-          SV *context_sv = hv_iternextsv (style_commands_formatting_hv,
+          SV *context_sv = hv_iternextsv (no_arg_commands_formatting_hv,
                                           &cmdname, &retlen);
           if (SvOK (context_sv))
             {
               HV *context_hv = (HV *)SvRV (context_sv);
               enum command_id cmd = lookup_builtin_command (cmdname);
+
               if (!cmd)
-                fprintf (stderr, "ERROR: %s: no style command\n", cmdname);
+                fprintf (stderr, "ERROR: %s: no no arg command\n", cmdname);
               else
                 {
                   I32 context_nr;
                   I32 j;
 
-                  converter->style_formatted_cmd.list[
-                                 converter->style_formatted_cmd.number] = cmd;
-                  converter->style_formatted_cmd.number++;
-
                   context_nr = hv_iterinit (context_hv);
                   for (j = 0; j < context_nr; j++)
                     {
                       char *context_name;
                       I32 retlen;
-                      int k;
+                      enum conversion_context k;
                       int context_idx = -1;
                       SV *format_spec_sv = hv_iternextsv (context_hv,
                                                  &context_name, &retlen);
@@ -872,7 +900,7 @@ html_converter_initialize_sv (SV *converter_sv,
                       if (context_idx < 0)
                         {
                           fprintf (stderr,
-                              "ERROR: %s: %s: unknown style context\n",
+                              "ERROR: %s: %s: unknown no arg context\n",
                                          cmdname, context_name);
                           break;
                         }
@@ -901,12 +929,29 @@ html_converter_initialize_sv (SV *converter_sv,
                                     = (char *) SvPVutf8_nolen (spec_sv);
                                   format_spec->element = strdup (tmp_spec);
                                 }
-                              else if (!strcmp (key, "quote"))
-                                format_spec->quote = SvIV (spec_sv);
+                              else if (!strcmp (key, "unset"))
+                                format_spec->unset = SvIV (spec_sv);
+                              else if (!strcmp (key, "text"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->text = strdup (tmp_spec);
+                                }
+                              else if (!strcmp (key, "translated_converted"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->translated_converted
+                                    = strdup (tmp_spec);
+                                }
+                              else if (!strcmp (key, "translated_to_convert"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->translated_to_convert
+                                    = strdup (tmp_spec);
+                                }
                             }
-                            /*
-                          fprintf (stderr, "HHH %d %d %s %d %d %s %d %s\n", i, 
cmd, cmdname, j, context_idx, context_name, format_spec->quote, 
format_spec->element);
-                             */
                         }
                     }
                 }
@@ -1107,15 +1152,6 @@ html_converter_initialize_sv (SV *converter_sv,
           selector_style->style = strdup (style);
         }
     }
-
-  html_converter_initialize (converter);
-
-  /* at that point, the format specific informations, in particular the number
-     of special elements is available, such that all the options can be
-     passed to C.  It is important to set the force argument to 1 to get
-     all the configuration, even if the configured field is set */
-  copy_converter_conf_sv (converter_hv, converter,
-                          &converter->conf, "conf", 1);
 }
 
 void
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.h 
b/tp/Texinfo/XS/convert/get_html_perl_info.h
index 10d41a9b75..4d09ed8168 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.h
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.h
@@ -19,8 +19,12 @@ void html_converter_initialize_sv (SV *converter_sv,
                                   SV *default_types_conversion,
                                   SV *default_css_string_types_conversion,
                                   SV *default_output_units_conversion,
+                                  SV *default_no_arg_commands_formatting,
                                   SV *default_special_unit_body);
 
+void html_conversion_initialization_sv (SV *converter_sv,
+                                        CONVERTER *converter);
+
 void html_converter_prepare_output_sv (SV *converter_sv, CONVERTER *converter);
 
 ELEMENT *html_find_element_from_sv (CONVERTER *converter, SV *element_sv,
diff --git a/tp/Texinfo/XS/main/get_perl_info.c 
b/tp/Texinfo/XS/main/get_perl_info.c
index 7e31377282..c1c9c09568 100644
--- a/tp/Texinfo/XS/main/get_perl_info.c
+++ b/tp/Texinfo/XS/main/get_perl_info.c
@@ -526,6 +526,33 @@ copy_converter_conf_sv (HV *hv, CONVERTER *converter,
     }
 }
 
+void
+converter_set_document (SV *converter_in, SV *document_in)
+{
+  CONVERTER *converter;
+  DOCUMENT *document;
+
+  dTHX;
+
+  converter = get_sv_converter (converter_in, "converter_set_document");
+  document = get_sv_document_document (document_in, 0);
+
+   /*
+  if (document)
+    {
+      fprintf (stderr, "XS|CONVERTER %d: Document %d\n",
+           converter->converter_descriptor, document->descriptor);
+    }
+    */
+
+  converter->document = document;
+
+  set_output_encoding (converter->conf, converter->document);
+
+  converter->convert_text_options
+    = copy_converter_options_for_convert_text (converter);
+}
+
 /* Texinfo::Convert::Converter generic initialization for all the converters */
 /* Called early, in particuliar before any format specific code has been
    called */
@@ -535,7 +562,6 @@ converter_initialize (SV *converter_sv)
   HV *hv_in;
   SV **configured_sv;
   SV **output_format_sv;
-  DOCUMENT *document;
   int converter_descriptor = 0;
   CONVERTER *converter;
 
@@ -546,32 +572,6 @@ converter_initialize (SV *converter_sv)
 
   hv_in = (HV *)SvRV (converter_sv);
 
-  document = get_sv_document_document (converter_sv, 0);
-  if (!document)
-    {
-      /* happens in tests for PlainTexinfo for example */
-      unregister_converter_descriptor (converter_descriptor);
-      return 0;
-      /*
-      I32 hv_number;
-      I32 i;
-      hv_number = hv_iterinit (hv_in);
-      fprintf (stderr, "REMARK: no document for SV %p HV %p\n", converter_sv,
-                       hv_in);
-      for (i = 0; i < hv_number; i++)
-        {
-          char *key;
-          I32 retlen;
-          SV *value = hv_iternextsv(hv_in, &key, &retlen);
-          if (value && SvOK (value))
-            {
-              fprintf (stderr, "  %s: %p\n", key, value);
-            }
-        }
-       */
-    }
-  converter->document = document;
-
 #define FETCH(key) key##_sv = hv_fetch (hv_in, #key, strlen(#key), 0);
   FETCH(output_format)
 
@@ -607,11 +607,6 @@ converter_initialize (SV *converter_sv)
 
   get_expanded_formats (hv_in, &converter->expanded_formats);
 
-  set_output_encoding (converter->conf, converter->document);
-
-  converter->convert_text_options
-    = copy_converter_options_for_convert_text (converter);
-
   converter->hv = hv_in;
 
   /* store converter_descriptor in perl converter */
@@ -1297,7 +1292,7 @@ find_element_extra_index_entry_sv (DOCUMENT *document,
                                    SV *extra_index_entry_sv)
 {
   INDEX_ENTRY *index_entry;
-  if (!converter || !converter->document->index_names)
+  if (!converter || !converter->document || !converter->document->index_names)
     {
       if (document)
         index_entry
diff --git a/tp/Texinfo/XS/main/get_perl_info.h 
b/tp/Texinfo/XS/main/get_perl_info.h
index 3bbfa5f117..e4a2fe4c90 100644
--- a/tp/Texinfo/XS/main/get_perl_info.h
+++ b/tp/Texinfo/XS/main/get_perl_info.h
@@ -42,6 +42,7 @@ void force_conf (CONVERTER *converter, const char *conf, SV 
*value);
 CONVERTER *get_sv_converter (SV *sv_in, const char *warn_string);
 int converter_initialize (SV *converter_sv);
 void reset_output_init_conf (SV *sv_in);
+void converter_set_document (SV *converter_in, SV *document_in);
 
 INDEX_ENTRY *find_index_entry_sv (const SV *index_entry_sv, INDEX 
**index_names,
                      const char *warn_string, const INDEX **entry_idx,
diff --git a/tp/t/accents.t b/tp/t/accents.t
index a1dffefd34..b522bf9c84 100644
--- a/tp/t/accents.t
+++ b/tp/t/accents.t
@@ -108,7 +108,7 @@ sub test_enable_encoding ($)
   }
   my $html_converter = Texinfo::Convert::HTML->converter($options);
   # NOTE we use a converter outside of output/convert
-  $html_converter->_initialize_XS_NonXS_output_state('_test_accents');
+  $html_converter->conversion_initialization();
   my $result_xml = Texinfo::Convert::Converter::xml_accents($html_converter,
                                                             $accent_tree);
   $html_converter->set_conf('USE_NUMERIC_ENTITY', 1);



reply via email to

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