texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Fri, 4 Oct 2024 06:59:08 -0400 (EDT)

branch: master
commit c078d8d82728d5268d2feddd237bc6ed4485b012
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Aug 14 07:54:17 2024 +0200

    * tp/Texinfo/XS/Makefile.am (libtexinfo_convert_la_SOURCES),
    tp/Texinfo/XS/convert/html_converter_types.h (HTML_COMMAND_STRUCT)
    (,
    tp/Texinfo/XS/convert/html_conversion_state.c (html_in_code)
    (html_in_math, html_in_preformatted_context, html_inside_preformatted)
    (html_in_non_breakable_space, html_in_raw, html_in_space_protected)
    (html_in_string, html_in_upper_case, html_in_verbatim)
    (html_paragraph_number, html_preformatted_number, html_in_align)
    (html_top_block_command, html_preformatted_classes_stack)
    (html_set_code_context, html_pop_code_context)
    (html_set_string_context, html_unset_string_context)
    (html_set_raw_context, html_unset_raw_context, html_in_multi_expanded)
    (find_page_name_number, count_elements_in_file_number)
    (html_count_elements_in_filename, html_register_footnote)
    (html_get_pending_footnotes, destroy_pending_footnotes)
    (html_register_pending_formatted_inline_content)
    (html_cancel_pending_formatted_inline_content)
    (html_get_pending_formatted_inline_content)
    (get_associated_inline_content_number)
    (html_associate_pending_formatted_inline_content)
    (html_get_associated_formatted_inline_content)
    (add_associated_file_info_integer, html_register_file_information)
    (lookup_associated_file_info, html_get_file_information)
    (html_register_opened_section_level)
    (html_close_registered_sections_level, compare_selector_style)
    (sort_css_element_class_styles, find_css_selector_style)
    (html_css_set_selector_style, html_css_get_selector_style)
    (compare_strings, html_get_css_elements_classes, html_css_add_info)
    (html_css_get_info), tp/Texinfo/XS/convert/convert_html.c: split code
    related to setting or getting HTML conversion state information out of
    convert_html.c to a separate file html_conversion_state.c.  Also add
    html_converter_types.h for declarations needed by several files used
    for the conversion to HTML.
---
 ChangeLog                                     |  36 +
 tp/Texinfo/XS/Makefile.am                     |   3 +
 tp/Texinfo/XS/convert/ConvertXS.xs            |   1 +
 tp/Texinfo/XS/convert/convert_html.c          | 956 +------------------------
 tp/Texinfo/XS/convert/convert_html.h          |  77 +-
 tp/Texinfo/XS/convert/get_html_perl_info.c    |   1 +
 tp/Texinfo/XS/convert/get_html_perl_info.h    |   2 +-
 tp/Texinfo/XS/convert/html_conversion_state.c | 977 ++++++++++++++++++++++++++
 tp/Texinfo/XS/convert/html_conversion_state.h |  76 ++
 tp/Texinfo/XS/convert/html_converter_types.h  |  53 ++
 10 files changed, 1152 insertions(+), 1030 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 20f65fa605..0320c8df5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2024-08-14  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/XS/Makefile.am (libtexinfo_convert_la_SOURCES),
+       tp/Texinfo/XS/convert/html_converter_types.h (HTML_COMMAND_STRUCT)
+       (,
+       tp/Texinfo/XS/convert/html_conversion_state.c (html_in_code)
+       (html_in_math, html_in_preformatted_context, html_inside_preformatted)
+       (html_in_non_breakable_space, html_in_raw, html_in_space_protected)
+       (html_in_string, html_in_upper_case, html_in_verbatim)
+       (html_paragraph_number, html_preformatted_number, html_in_align)
+       (html_top_block_command, html_preformatted_classes_stack)
+       (html_set_code_context, html_pop_code_context)
+       (html_set_string_context, html_unset_string_context)
+       (html_set_raw_context, html_unset_raw_context, html_in_multi_expanded)
+       (find_page_name_number, count_elements_in_file_number)
+       (html_count_elements_in_filename, html_register_footnote)
+       (html_get_pending_footnotes, destroy_pending_footnotes)
+       (html_register_pending_formatted_inline_content)
+       (html_cancel_pending_formatted_inline_content)
+       (html_get_pending_formatted_inline_content)
+       (get_associated_inline_content_number)
+       (html_associate_pending_formatted_inline_content)
+       (html_get_associated_formatted_inline_content)
+       (add_associated_file_info_integer, html_register_file_information)
+       (lookup_associated_file_info, html_get_file_information)
+       (html_register_opened_section_level)
+       (html_close_registered_sections_level, compare_selector_style)
+       (sort_css_element_class_styles, find_css_selector_style)
+       (html_css_set_selector_style, html_css_get_selector_style)
+       (compare_strings, html_get_css_elements_classes, html_css_add_info)
+       (html_css_get_info), tp/Texinfo/XS/convert/convert_html.c: split code
+       related to setting or getting HTML conversion state information out of
+       convert_html.c to a separate file html_conversion_state.c.  Also add
+       html_converter_types.h for declarations needed by several files used
+       for the conversion to HTML.
+
 2024-08-14  Patrice Dumas  <pertusus@free.fr>
 
        * tp/t/test_utils.pl (test): call convert_to_texinfo for plaintext
diff --git a/tp/Texinfo/XS/Makefile.am b/tp/Texinfo/XS/Makefile.am
index a5b51b8c28..01dc869f01 100644
--- a/tp/Texinfo/XS/Makefile.am
+++ b/tp/Texinfo/XS/Makefile.am
@@ -388,9 +388,12 @@ C_libtexinfo_convert_sources = \
                        convert/converters_defaults.h \
                        convert/create_buttons.c \
                        convert/create_buttons.h \
+                       convert/html_converter_types.h \
                        convert/html_converter_init_options.c \
                        convert/html_converter_init_options.h \
                        convert/html_converter_finish.h \
+                       convert/html_conversion_state.c \
+                       convert/html_conversion_state.h \
                        convert/texinfo.c \
                        convert/texinfo.h
 
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 3e91d755e8..47132775b2 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -54,6 +54,7 @@
 #include "build_perl_info.h"
 #include "get_converter_perl_info.h"
 #include "build_html_perl_state.h"
+#include "html_conversion_state.h"
 #include "convert_html.h"
 #include "get_converter_perl_info.h"
 #include "get_html_perl_info.h"
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index 18112dccfc..749d6bd492 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -37,6 +37,7 @@
 #include "converter_types.h"
 #include "option_types.h"
 #include "types_data.h"
+#include "html_converter_types.h"
 #include "tree.h"
 #include "builtin_commands.h"
 #include "command_stack.h"
@@ -64,6 +65,7 @@
 /* for new_complete_menu_master_menu */
 #include "structuring.h"
 #include "api_to_perl.h"
+#include "html_conversion_state.h"
 #include "convert_html.h"
 
 typedef struct ROOT_AND_UNIT {
@@ -241,24 +243,7 @@ static HTML_STYLE_COMMAND_CONVERSION 
default_style_commands_formatting
 #define F_AFT_url               0x0080
 #define F_AFT_raw               0x0100
 
-/* HTML command data flags */
-#define HF_composition_context  0x0001
-#define HF_format_context       0x0002
-#define HF_format_raw           0x0004
-#define HF_pre_class            0x0008
-#define HF_small_block_command  0x0010
-#define HF_HTML_align           0x0020
-#define HF_special_variety      0x0040
-#define HF_indented_preformatted 0x0080
-#define HF_style_command         0x0100
-
-typedef struct HTML_COMMAND_STRUCT {
-    unsigned long flags;
-    enum command_id pre_class_cmd;
-    enum command_id upper_case_cmd;
-} HTML_COMMAND_STRUCT;
-
-static HTML_COMMAND_STRUCT html_commands_data[BUILTIN_CMD_NUMBER];
+HTML_COMMAND_STRUCT html_commands_data[BUILTIN_CMD_NUMBER];
 
 /* should correspond to enum html_special_character */
 /* HTML textual entity, UTF-8 encoded, unicode point, HTML numeric entity */
@@ -761,208 +746,6 @@ translate_convert_to_html_internal (const char *string,
 }
 
 
-int
-html_in_code (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return top_integer_stack (&top_document_ctx->monospace);
-}
-
-int
-html_in_math (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return top_document_ctx->math_ctx;
-}
-
-int
-html_in_preformatted_context (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return top_integer_stack (&top_document_ctx->preformatted_context);
-}
-
-int
-html_inside_preformatted (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return top_document_ctx->inside_preformatted;
-}
-
-int
-html_in_non_breakable_space (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  HTML_FORMATTING_CONTEXT *top_formating_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_formating_ctx
-    = html_top_formatting_context (&top_document_ctx->formatting_context);
-  return top_formating_ctx->no_break;
-}
-
-int
-html_in_raw (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return top_document_ctx->raw_ctx;
-}
-
-int
-html_in_space_protected (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  HTML_FORMATTING_CONTEXT *top_formating_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_formating_ctx
-    = html_top_formatting_context (&top_document_ctx->formatting_context);
-  return top_formating_ctx->space_protected;
-}
-
-int
-html_in_string (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return top_document_ctx->string_ctx;
-}
-
-int
-html_in_upper_case (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  HTML_FORMATTING_CONTEXT *top_formating_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_formating_ctx
-    = html_top_formatting_context (&top_document_ctx->formatting_context);
-  return top_formating_ctx->upper_case_ctx;
-}
-
-int
-html_in_verbatim (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return top_document_ctx->verbatim_ctx;
-}
-
-int
-html_paragraph_number (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  HTML_FORMATTING_CONTEXT *top_formating_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_formating_ctx
-    = html_top_formatting_context (&top_document_ctx->formatting_context);
-  return top_formating_ctx->paragraph_number;
-}
-
-int
-html_preformatted_number (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  HTML_FORMATTING_CONTEXT *top_formating_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_formating_ctx
-    = html_top_formatting_context (&top_document_ctx->formatting_context);
-  return top_formating_ctx->preformatted_number;
-}
-
-enum command_id
-html_top_block_command (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  if (top_document_ctx->block_commands.top <= 0)
-    return 0;
-  return top_command (&top_document_ctx->block_commands);
-}
-
-const COMMAND_OR_TYPE_STACK *
-html_preformatted_classes_stack (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  return &top_document_ctx->preformatted_classes;
-}
-
-enum command_id
-html_in_align (const CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  COMMAND_OR_TYPE *context;
-  top_document_ctx = html_top_document_context (self);
-  context = top_command_or_type (&top_document_ctx->composition_context);
-  if (context->variety == CTV_type_command)
-    {
-      enum command_id cmd = context->ct.cmd;
-      if (html_commands_data[cmd].flags & HF_HTML_align)
-        return cmd;
-    }
-  return 0;
-}
-
-void
-html_set_code_context (CONVERTER *self, int code)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  push_integer_stack_integer (&top_document_ctx->monospace, code);
-}
-
-void
-html_pop_code_context (CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  pop_integer_stack (&top_document_ctx->monospace);
-}
-
-void
-html_set_string_context (CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_document_ctx->string_ctx++;
-}
-
-void
-html_unset_string_context (CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_document_ctx->string_ctx--;
-}
-
-void
-html_set_raw_context (CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_document_ctx->raw_ctx++;
-}
-
-void
-html_unset_raw_context (CONVERTER *self)
-{
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-  top_document_ctx = html_top_document_context (self);
-  top_document_ctx->raw_ctx--;
-}
-
-const char *
-html_in_multi_expanded (CONVERTER *self)
-{
-  if (self->multiple_pass.top > 0)
-    return top_string_stack (&self->multiple_pass);
-
-  return 0;
-}
-
 static int
 compare_page_name_number (const void *a, const void *b)
 {
@@ -972,63 +755,6 @@ compare_page_name_number (const void *a, const void *b)
   return strcmp (pnn_a->page_name, pnn_b->page_name);
 }
 
-size_t
-find_page_name_number
-            (const PAGE_NAME_NUMBER_LIST *page_name_number,
-                                          const char *page_name)
-{
-  PAGE_NAME_NUMBER *result = 0;
-  static PAGE_NAME_NUMBER searched_page_name;
-
-  searched_page_name.page_name = page_name;
-  if (page_name_number->number == 0)
-    {
-      char *msg;
-      xasprintf (&msg, "no pages, searching for '%s'\n", page_name);
-      fatal (msg);
-      free (msg);
-    }
-
-  result = (PAGE_NAME_NUMBER *) bsearch (&searched_page_name,
-                page_name_number->list,
-                page_name_number->number, sizeof (PAGE_NAME_NUMBER),
-                compare_page_name_number);
-  if (!result)
-    return 0;
-  return result->number;
-}
-
-size_t
-count_elements_in_file_number (const CONVERTER *self,
-                 enum count_elements_in_filename_type type,
-                 size_t file_number)
-{
-  size_t i = file_number - 1;
-  const FILE_NAME_PATH_COUNTER *file_counter
-            = &self->output_unit_files.list[i];
-
-  if (type == CEFT_total)
-    return file_counter->elements_in_file_count;
-  else if (type == CEFT_remaining)
-    return file_counter->counter;
-  else /* if (type == CEFT_current) */
-    return file_counter->elements_in_file_count - file_counter->counter +1;
-}
-
-/* called from perl */
-size_t
-html_count_elements_in_filename (const CONVERTER *self,
-                 enum count_elements_in_filename_type type,
-                 const char *filename)
-{
-  size_t page_number = find_page_name_number (&self->page_name_number,
-                                              filename);
-
-  if (!page_number)
-    return 0;
-
-  return count_elements_in_file_number (self, type, page_number);
-}
 
 /*
 static const char *xml_named_entity_nbsp = "&nbsp;";
@@ -1117,422 +843,6 @@ special_unit_info (const CONVERTER *self, enum 
special_unit_info_type type,
   return self->special_unit_info[type][i];
 }
 
-void
-html_register_footnote (CONVERTER *self, const ELEMENT *command,
-     const char *footid, const char *docid, int number_in_doc,
-     const char *footnote_location_filename, const char *multi_expanded_region)
-{
-  HTML_PENDING_FOOTNOTE_STACK *stack;
-  HTML_PENDING_FOOTNOTE *pending_footnote;
-
-  if (self->shared_conversion_state.in_skipped_node_top == 1)
-    return;
-
-  stack = &self->pending_footnotes;
-
-  if (stack->top >= stack->space)
-    {
-      stack->stack
-        = realloc (stack->stack,
-                   (stack->space += 5) * sizeof (HTML_PENDING_FOOTNOTE *));
-    }
-  pending_footnote = (HTML_PENDING_FOOTNOTE *)
-                      malloc (sizeof (HTML_PENDING_FOOTNOTE));
-  stack->stack[stack->top] = pending_footnote;
-  stack->top++;
-
-  pending_footnote->command = command;
-  pending_footnote->footid = strdup (footid);
-  pending_footnote->docid = strdup (docid);
-  pending_footnote->number_in_doc = number_in_doc;
-  pending_footnote->footnote_location_filename
-       = strdup (footnote_location_filename);
-
-  if (multi_expanded_region)
-    pending_footnote->multi_expanded_region = strdup (multi_expanded_region);
-  else
-    pending_footnote->multi_expanded_region = 0;
-}
-
-HTML_PENDING_FOOTNOTE_STACK *
-html_get_pending_footnotes (CONVERTER *self)
-{
-  HTML_PENDING_FOOTNOTE_STACK *stack = (HTML_PENDING_FOOTNOTE_STACK *)
-     malloc (sizeof (HTML_PENDING_FOOTNOTE_STACK));
-
-  stack->top = self->pending_footnotes.top;
-  stack->space = self->pending_footnotes.space;
-  stack->stack = self->pending_footnotes.stack;
-
-  memset (&self->pending_footnotes, 0, sizeof (HTML_PENDING_FOOTNOTE_STACK));
-
-  return stack;
-}
-
-void
-destroy_pending_footnotes (HTML_PENDING_FOOTNOTE_STACK *stack)
-{
-  size_t i;
-  for (i = 0; i < stack->top; i++)
-    {
-      free (stack->stack[i]->multi_expanded_region);
-      free (stack->stack[i]->footid);
-      free (stack->stack[i]->docid);
-      free (stack->stack[i]->footnote_location_filename);
-      free (stack->stack[i]);
-    }
-  free (stack->stack);
-  free (stack);
-}
-
-void
-html_register_pending_formatted_inline_content (CONVERTER *self,
-                             const char *category, const char *inline_content)
-{
-  HTML_INLINE_CONTENT *pending_content;
-  HTML_INLINE_CONTENT_STACK *stack;
-
-  if (!inline_content)
-    return;
-
-  stack = &self->pending_inline_content;
-  if (stack->top >= stack->space)
-    {
-      stack->stack
-        = realloc (stack->stack,
-                   (stack->space += 5) * sizeof (HTML_INLINE_CONTENT));
-    }
-  pending_content = &stack->stack[stack->top];
-
-  pending_content->category = strdup (category);
-  pending_content->string = strdup (inline_content);
-
-  stack->top++;
-}
-
-/* cancel only the first pending content for the category */
-char *
-html_cancel_pending_formatted_inline_content (CONVERTER *self,
-                                              const char *category)
-{
-  HTML_INLINE_CONTENT_STACK *stack = &self->pending_inline_content;
-  if (stack->top)
-    {
-      size_t current_position = stack->top;
-      size_t current_idx;
-      while (current_position > 0)
-        {
-          current_idx = current_position - 1;
-          if (!strcmp (stack->stack[current_idx].category, category))
-            {
-              char *inline_content = stack->stack[current_idx].string;
-              free (stack->stack[current_idx].category);
-              if (current_position < stack->top)
-                {
-                  memmove (&stack->stack[current_idx],
-                           &stack->stack[current_idx+1],
-                           sizeof (HTML_INLINE_CONTENT)
-                               * (stack->top - (current_idx +1)));
-                }
-              stack->top--;
-              return inline_content;
-            }
-        }
-    }
-  return 0;
-}
-
-char *
-html_get_pending_formatted_inline_content (CONVERTER *self)
-{
-  HTML_INLINE_CONTENT_STACK *stack = &self->pending_inline_content;
-  if (stack->top)
-    {
-      TEXT result;
-      size_t i;
-      text_init (&result);
-      for (i = 0; i < stack->top; i++)
-        {
-          text_append (&result, stack->stack[i].string);
-          free (stack->stack[i].string);
-          free (stack->stack[i].category);
-        }
-      stack->top = 0;
-      return result.text;
-    }
-  else
-    return strdup ("");
-}
-
-static size_t
-get_associated_inline_content_number (
-     const HTML_ASSOCIATED_INLINE_CONTENT_LIST *associated_content_list,
-     const ELEMENT *element, const void *hv)
-{
-  size_t i;
-  for (i = 0; i < associated_content_list->number; i++)
-    {
-      const HTML_ASSOCIATED_INLINE_CONTENT *element_associated_content
-        = &associated_content_list->list[i];
-      if ((element && (element_associated_content->element == element
-                       || (element->hv
-                           && element_associated_content->hv == element->hv)))
-          || (hv && (element_associated_content->hv == hv
-                     || (element_associated_content->element
-                         && element_associated_content->element->hv == hv))))
-        {
-          return i +1;
-        }
-    }
-  return 0;
-}
-
-/* API to associate inline content to an element, typically
-   paragraph or preformatted.  Allows to associate the pending
-   content to the first inline element. */
-/* hv is used when called from perl, element when called from C */
-void
-html_associate_pending_formatted_inline_content (CONVERTER *self,
-                                            const ELEMENT *element,
-                                            const void *hv,
-                                            const char *inline_content)
-{
-  HTML_ASSOCIATED_INLINE_CONTENT_LIST *associated_content_list
-    = &self->associated_inline_content;
-  HTML_ASSOCIATED_INLINE_CONTENT *element_associated_content = 0;
-  size_t number = get_associated_inline_content_number 
(associated_content_list,
-                                                                   element, 
hv);
-  if (number > 0)
-    element_associated_content = &associated_content_list->list[number -1];
-
-  if (!element_associated_content)
-    {
-      size_t i;
-      int empty_slot = 0;
-
-      for (i = 0; i < associated_content_list->number; i++)
-        {
-          if (associated_content_list->list[i].inline_content.space == 0)
-            {
-              empty_slot = 1;
-              number = i +1;
-            }
-        }
-
-      if (!empty_slot)
-        {
-          if (associated_content_list->number >= 
associated_content_list->space)
-            {
-              associated_content_list->list
-                = realloc (associated_content_list->list,
-                   (associated_content_list->space += 5)
-                              * sizeof (HTML_ASSOCIATED_INLINE_CONTENT));
-            }
-          associated_content_list->number++;
-          number = associated_content_list->number;
-        }
-      element_associated_content
-        = &associated_content_list->list[number -1];
-      element_associated_content->element = element;
-      element_associated_content->hv = hv;
-      text_init (&element_associated_content->inline_content);
-      /*
-      fprintf (stderr, "NNN (%zu)\n", associated_content_list->number);
-       */
-    }
-  text_append (&element_associated_content->inline_content, inline_content);
-   /*
-  if (element)
-    fprintf (stderr, "RRR-EE %p -> %p %zu\n", element, element->hv, number);
-  if (hv)
-    fprintf (stderr, "RRR-PP %p %zu\n", hv, number);
-    */
-}
-
-/* hv is used when called from perl element when called from C */
-char *
-html_get_associated_formatted_inline_content (CONVERTER *self,
-                                              const ELEMENT *element,
-                                              const void *hv)
-{
-  HTML_ASSOCIATED_INLINE_CONTENT_LIST *associated_content_list
-    = &self->associated_inline_content;
-  HTML_ASSOCIATED_INLINE_CONTENT *element_associated_content = 0;
-  size_t number = get_associated_inline_content_number 
(associated_content_list,
-                                                                   element, 
hv);
-  /*
-  if (element)
-    fprintf (stderr, "GGG-EE %p -> %p %zu (%zu)\n", element, element->hv, 
number, associated_content_list->number);
-  if (hv)
-    fprintf (stderr, "GGG-PP %p %zu (%zu)\n", hv, number, 
associated_content_list->number);
-   */
-  if (number > 0)
-    element_associated_content = &associated_content_list->list[number -1];
-
-  if (element_associated_content)
-    {
-      char *result = element_associated_content->inline_content.text;
-      if (number == associated_content_list->number)
-        associated_content_list->number--;
-      else
-        memset (element_associated_content, 0,
-                sizeof (HTML_ASSOCIATED_INLINE_CONTENT));
-      return result;
-    }
-  return strdup ("");
-}
-
-FILE_INFO_KEY_PAIR *
-add_associated_file_info_integer (FILE_ASSOCIATED_INFO *a,
-                                  const char *key, int value)
-{
-  size_t i;
-  for (i = 0; i < a->info_number; i++)
-    {
-      if (!strcmp (a->info[i].key, key))
-        break;
-    }
-  if (i == a->info_number)
-    {
-      if (a->info_number == a->info_space)
-        {
-          a->info = realloc (a->info,
-                         (a->info_space += 5) * sizeof (FILE_INFO_KEY_PAIR));
-          if (!a->info)
-            fatal ("realloc failed");
-        }
-      a->info_number++;
-
-      a->info[i].key = key;
-    }
-
-  a->info[i].integer = value;
-
-  return &a->info[i];
-}
-
-/* API to register an information to a file and get it.  To be able to
-   set an information during conversion and get it back during headers
-   and footers conversion */
-
-void
-html_register_file_information (CONVERTER *self, const char *key,
-                                int value)
-{
-  FILE_ASSOCIATED_INFO *associated_info
-    = &self->html_files_information.list[self->current_filename.file_number];
-  add_associated_file_info_integer (associated_info, key, value);
-}
-
-const FILE_INFO_KEY_PAIR *
-lookup_associated_file_info (const FILE_ASSOCIATED_INFO *a,
-                             const char *key)
-{
-  size_t i;
-  for (i = 0; i < a->info_number; i++)
-    {
-      if (!strcmp (a->info[i].key, key))
-        return &a->info[i];
-    }
-  return 0;
-}
-
-int
-html_get_file_information (const CONVERTER *self, const char *key,
-                           const char *filename, int *status)
-{
-  size_t page_number;
-  const FILE_ASSOCIATED_INFO *associated_info;
-  const FILE_INFO_KEY_PAIR *k;
-
-  *status = 0;
-  if (filename)
-    {
-      page_number = find_page_name_number (&self->page_name_number,
-                                           filename);
-      if (!page_number)
-        {
-          *status = -1;
-          return 0;
-        }
-    }
-  else
-    page_number = self->current_filename.file_number;
-
-  associated_info = &self->html_files_information.list[page_number];
-  k = lookup_associated_file_info (associated_info, key);
-  if (!k)
-    {
-      *status = -2;
-      return 0;
-    }
-  return k->integer;
-}
-
-void
-html_register_opened_section_level (CONVERTER *self, size_t file_number,
-                                    int level, const char *close_string)
-{
-  STRING_STACK *file_pending_closes
-    = &self->pending_closes.list[file_number -1];
-
-  while ((int) file_pending_closes->top < level)
-    {
-      push_string_stack_string (file_pending_closes, "");
-    }
-  push_string_stack_string (file_pending_closes, close_string);
-}
-
-/* called from Perl */
-void
-html_register_opened_filename_section_level (CONVERTER *self,
-                                    const char *filename,
-                                    int level, const char *close_string)
-{
-  size_t page_number = find_page_name_number (&self->page_name_number,
-                                              filename);
-
-  if (!page_number)
-    return;
-
-  html_register_opened_section_level (self, page_number, level, close_string);
-}
-
-STRING_LIST *
-html_close_registered_sections_level (CONVERTER *self, size_t file_number,
-                                      int level)
-{
-  STRING_STACK *file_pending_closes
-    = &self->pending_closes.list[file_number -1];
-  STRING_LIST *closed_elements = new_string_list ();
-
-  while ((int) file_pending_closes->top > level)
-    {
-      const char *close_string = top_string_stack (file_pending_closes);
-      if (strlen (close_string))
-        {
-          add_string (close_string, closed_elements);
-        }
-      pop_string_stack (file_pending_closes);
-    }
-
-  return closed_elements;
-}
-
-/* called from Perl */
-STRING_LIST *
-html_close_registered_filename_sections_level (CONVERTER *self,
-                                      const char *filename, int level)
-{
-  size_t page_number = find_page_name_number (&self->page_name_number,
-                                              filename);
-
-  if (!page_number)
-    return 0;
-
-  return html_close_registered_sections_level (self, page_number, level);
-}
-
 OUTPUT_UNIT *
 register_special_unit (CONVERTER *self, char *special_unit_variety)
 {
@@ -4593,94 +3903,6 @@ from_element_direction (CONVERTER *self, int direction,
   return 0;
 }
 
-static int
-compare_selector_style (const void *a, const void *b)
-{
-  const CSS_SELECTOR_STYLE *css_a = (const CSS_SELECTOR_STYLE *) a;
-  const CSS_SELECTOR_STYLE *css_b = (const CSS_SELECTOR_STYLE *) b;
-
-  return strcmp (css_a->selector, css_b->selector);
-}
-
-static void
-sort_css_element_class_styles (
-       CSS_SELECTOR_STYLE_LIST *css_element_class_styles)
-{
-  qsort (css_element_class_styles->list,
-         css_element_class_styles->number,
-         sizeof (CSS_SELECTOR_STYLE), compare_selector_style);
-}
-
-/* can be modified if called by html_css_set_selector_style */
-CSS_SELECTOR_STYLE *
-find_css_selector_style
-     (const CSS_SELECTOR_STYLE_LIST *css_element_class_styles,
-                                           const char *selector)
-{
-  CSS_SELECTOR_STYLE *result = 0;
-  static CSS_SELECTOR_STYLE searched_selector;
-  /* remove const with a cast, it is more efficient than duplicating */
-  searched_selector.selector = (char *) selector;
-
-  result = (CSS_SELECTOR_STYLE *) bsearch (&searched_selector,
-                css_element_class_styles->list,
-                css_element_class_styles->number, sizeof (CSS_SELECTOR_STYLE),
-                compare_selector_style);
-
-  return result;
-}
-
-void
-html_css_set_selector_style (CSS_SELECTOR_STYLE_LIST *css_element_class_styles,
-                             const char *css_info,
-                             const char *css_style)
-{
-  CSS_SELECTOR_STYLE *selector_style
-   = find_css_selector_style (css_element_class_styles, css_info);
-
-  if (selector_style)
-    {
-      free (selector_style->style);
-      selector_style->style = 0;
-      if (css_style)
-        selector_style->style = strdup (css_style);
-    }
-  else
-    {
-      CSS_SELECTOR_STYLE_LIST *elt_class_styles
-        = css_element_class_styles;
-      if (elt_class_styles->space <= elt_class_styles->number)
-        {
-          elt_class_styles->list = realloc (elt_class_styles->list,
-             (elt_class_styles->space += 10) * sizeof (CSS_SELECTOR_STYLE));
-        }
-
-      selector_style
-        = &elt_class_styles->list[elt_class_styles->number];
-      selector_style->selector = strdup (css_info);
-      if (css_style)
-        selector_style->style = strdup (css_style);
-      else
-        selector_style->style = 0;
-
-      elt_class_styles->number++;
-
-      sort_css_element_class_styles (css_element_class_styles);
-    }
-}
-
-const char *
-html_css_get_selector_style (CONVERTER* self, const char *css_info)
-{
-  const CSS_SELECTOR_STYLE *selector_style
-   = find_css_selector_style (&self->css_element_class_styles, css_info);
-
-  if (selector_style)
-    return selector_style->style;
-
-  return 0;
-}
-
 static void
 add_new_css_page (PAGES_CSS_LIST *css_pages, const char *page_name)
 {
@@ -4763,178 +3985,6 @@ collect_css_element_class (CONVERTER *self, const char 
*selector)
     }
 }
 
-int
-compare_strings (const void *a, const void *b)
-{
-  const char **str_a = (const char **) a;
-  const char **str_b = (const char **) b;
-
-  return strcmp (*str_a, *str_b);
-}
-
-/* return list to be freed by caller */
-STRING_LIST *
-html_get_css_elements_classes (CONVERTER *self, const char *filename)
-{
-  size_t j;
-  size_t page_number;
-  STRING_LIST *result;
-  const char **selectors;
-  size_t selector_nr = 0;
-
-  if (self->page_css.number <= 0)
-    return 0;
-
-  const CSS_LIST *global_context_css_list = &self->page_css.list[0];
-
-  if (filename)
-    {
-      page_number = find_page_name_number (&self->page_name_number,
-                                           filename);
-      if (!page_number)
-        {
-          if (self->page_css.number > 1)
-            {
-              const CSS_LIST *last_css_page
-               = &self->page_css.list[self->page_css.number -1];
-              if (last_css_page->page_name
-                  && !strcmp (filename, last_css_page->page_name))
-                {
-                  page_number = self->page_css.number -1;
-                }
-             }
-          if (!page_number)
-            {
-             /* this happens legitimately in case of an output file not
-                associated to an output unit and not having registered
-                any CSS selector.  Also the formatting of the node or
-                similar command is in general done in global context
-                so no file is added */
-              /* This debug message is C specific
-              if (self->conf->DEBUG.o.integer > 0)
-                {
-                  fprintf (stderr, "XS|css: REMARK: %s: get_css no page 
found\n",
-                                    filename);
-                }
-               */
-            }
-        }
-      if (page_number)
-        {
-          const CSS_LIST *css_list;
-          css_list = &self->page_css.list[page_number];
-          if (css_list->number)
-            {
-              /* +1 for 'span:hover a.copiable-link' */
-              size_t space
-               = css_list->number + global_context_css_list->number +1;
-              selectors = (const char **) malloc (sizeof (char *) * space);
-              memcpy (selectors, css_list->list,
-                      css_list->number * sizeof (char *));
-              selector_nr = css_list->number;
-            }
-        }
-    }
-
-  if (selector_nr <= 0)
-    {
-      if (global_context_css_list->number)
-        {
-          /* +1 for 'span:hover a.copiable-link' */
-          size_t space = global_context_css_list->number +1;
-          selectors = (const char **) malloc (sizeof (char *) * space);
-          memcpy (selectors, global_context_css_list->list,
-                  global_context_css_list->number * sizeof (char *));
-          selector_nr = global_context_css_list->number;
-        }
-      else
-        return 0;
-    }
-  else if (global_context_css_list->number)
-    {
-      size_t i;
-      size_t file_selector_nr = selector_nr;
-      /* add global context selectors if not already present */
-      for (i = 0; i < global_context_css_list->number; i++)
-        {
-          size_t j;
-          const char *global_selector = global_context_css_list->list[i];
-          int found = 0;
-          for (j = 0; j < file_selector_nr; j++)
-            {
-              if (!strcmp (global_selector, selectors[j]))
-                {
-                  found = 1;
-                  break;
-                }
-            }
-          if (!found)
-            {
-              selectors[selector_nr] = global_selector;
-              selector_nr++;
-            }
-        }
-    }
-
-  for (j = 0; j < selector_nr; j++)
-    {
-      if (!strcmp ("a.copiable-link", selectors[j]))
-        {
-          selectors[selector_nr] = "span:hover a.copiable-link";
-          selector_nr++;
-          break;
-        }
-    }
-
-  qsort (selectors, selector_nr, sizeof (char *), compare_strings);
-
-  result = new_string_list ();
-  for (j = 0; j < selector_nr; j++)
-    add_string (selectors[j], result);
-
-  free (selectors);
-
-  return result;
-}
-
-void
-html_css_add_info (CONVERTER *self, enum css_info_type type,
-                   const char *css_info)
-{
-  if (type == CI_css_info_rules)
-    add_string (css_info, &self->css_rule_lines);
-  else if (type == CI_css_info_imports)
-    add_string (css_info, &self->css_import_lines);
-}
-
-const STRING_LIST *
-html_css_get_info (CONVERTER *self, enum css_info_type type)
-{
-  if (type == CI_css_info_rules)
-    return &self->css_rule_lines;
-  else if (type == CI_css_info_imports)
-    return &self->css_import_lines;
-  else
-    {
-      size_t i;
-      if (self->css_element_class_styles.number > 0)
-        {
-          if (self->css_element_class_list.number == 0)
-            {
-              for (i = 0; i < self->css_element_class_styles.number; i++)
-                {
-                  const CSS_SELECTOR_STYLE *selector_style
-                    = &self->css_element_class_styles.list[i];
-                  if (selector_style->selector)
-                    add_string (selector_style->selector,
-                                &self->css_element_class_list);
-                }
-            }
-        }
-      return &self->css_element_class_list;
-    }
-}
-
 void
 close_html_lone_element (const CONVERTER *self, TEXT *result)
 {
diff --git a/tp/Texinfo/XS/convert/convert_html.h 
b/tp/Texinfo/XS/convert/convert_html.h
index 1650fa2213..8b3d7ac12d 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -6,18 +6,7 @@
 #include "element_types.h"
 #include "tree_types.h"
 #include "converter_types.h"
-
-enum count_elements_in_filename_type {
-  CEFT_total,
-  CEFT_remaining,
-  CEFT_current,
-};
-
-enum css_info_type {
-   CI_css_info_element_classes,
-   CI_css_info_imports,
-   CI_css_info_rules,
-};
+#include "html_converter_types.h"
 
 
 extern const char *html_conversion_context_type_names[];
@@ -102,35 +91,12 @@ void html_unset_raw_context (CONVERTER *self);
 void html_set_multiple_conversions (CONVERTER *self, const char 
*multiple_pass);
 void html_unset_multiple_conversions (CONVERTER *self);
 
-int html_in_math (const CONVERTER *self);
-int html_in_preformatted_context (const CONVERTER *self);
-int html_inside_preformatted (const CONVERTER *self);
-int html_in_upper_case (const CONVERTER *self);
-int html_in_non_breakable_space (const CONVERTER *self);
-int html_in_space_protected (const CONVERTER *self);
-int html_in_code (const CONVERTER *self);
-int html_in_string (const CONVERTER *self);
-int html_in_verbatim (const CONVERTER *self);
-int html_in_raw (const CONVERTER *self);
-int html_paragraph_number (const CONVERTER *self);
-int html_preformatted_number (const CONVERTER *self);
-enum command_id html_top_block_command (const CONVERTER *self);
-const COMMAND_OR_TYPE_STACK *html_preformatted_classes_stack
-                                    (const CONVERTER *self);
-enum command_id html_in_align (const CONVERTER *self);
-const char *html_in_multi_expanded (CONVERTER *self);
-
 char *debug_print_html_contexts (const CONVERTER *self);
 
 size_t html_count_elements_in_filename (const CONVERTER *self,
                  enum count_elements_in_filename_type type,
                  const char *filename);
 
-void html_register_file_information (CONVERTER *self, const char *key,
-                                     int value);
-int html_get_file_information (const CONVERTER *self, const char *key,
-                               const char *filename, int *status);
-
 int html_special_unit_variety_direction_index (const CONVERTER *self,
                                         const char *special_unit_variety);
 
@@ -174,49 +140,8 @@ void register_explained_command_string (
 FOOTNOTE_ID_NUMBER *find_footnote_id_number (const CONVERTER *self,
                                            const char *footnote_id);
 
-void html_register_opened_section_level (CONVERTER *self, size_t file_number,
-                                         int level, const char *close_string);
-STRING_LIST *html_close_registered_sections_level (CONVERTER *self,
-                                                   size_t file_number,
-                                                   int level);
-void html_register_opened_filename_section_level (CONVERTER *self,
-                                             const char *filename,
-                                         int level, const char *close_string);
-STRING_LIST *html_close_registered_filename_sections_level (CONVERTER *self,
-                                      const char *filename, int level);
-
 char *html_attribute_class (CONVERTER *self, const char *element,
                             const STRING_LIST *classes);
-STRING_LIST *html_get_css_elements_classes (CONVERTER *self,
-                                            const char *filename);
-void html_css_add_info (CONVERTER *self, enum css_info_type type,
-                        const char *css_info);
-const STRING_LIST *html_css_get_info (CONVERTER *self, enum css_info_type 
type);
-void html_css_set_selector_style (
-                       CSS_SELECTOR_STYLE_LIST *css_element_class_styles,
-                                  const char *css_info,
-                                  const char *css_style);
-const char *html_css_get_selector_style (CONVERTER* self, const char 
*css_info);
-
-void html_register_footnote (CONVERTER *self, const ELEMENT *command,
-     const char *footid, const char *docid, const int number_in_doc,
-     const char *footnote_location_filename, const char 
*multi_expanded_region);
-HTML_PENDING_FOOTNOTE_STACK *html_get_pending_footnotes (CONVERTER *self);
-void destroy_pending_footnotes (HTML_PENDING_FOOTNOTE_STACK *stack);
-
-void html_register_pending_formatted_inline_content (CONVERTER *self,
-                             const char *category, const char *inline_content);
-char *html_cancel_pending_formatted_inline_content (CONVERTER *self,
-                                                    const char *category);
-char *html_get_pending_formatted_inline_content (CONVERTER *self);
-
-void html_associate_pending_formatted_inline_content (CONVERTER *self,
-                                            const ELEMENT *element,
-                                            const void *hv,
-                                            const char *inline_content);
-char *html_get_associated_formatted_inline_content (CONVERTER *self,
-                                              const ELEMENT *element,
-                                              const void *hv);
 
 size_t html_check_htmlxref_already_warned (CONVERTER *self,
                                            const char *manual_name,
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.c 
b/tp/Texinfo/XS/convert/get_html_perl_info.c
index ba7a8474ba..9654b60315 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.c
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.c
@@ -35,6 +35,7 @@
 #include "command_ids.h"
 #include "converter_types.h"
 #include "types_data.h"
+#include "html_converter_types.h"
 /* also for non_perl_* */
 #include "utils.h"
 #include "builtin_commands.h"
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.h 
b/tp/Texinfo/XS/convert/get_html_perl_info.h
index f4f4f8fa64..15dbf559c5 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.h
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.h
@@ -7,7 +7,7 @@
 #include "EXTERN.h"
 #include "perl.h"
 
-#include "convert_html.h"
+#include "html_converter_types.h"
 
 size_t get_output_units_descriptor_converter_sv (SV *converter_in);
 
diff --git a/tp/Texinfo/XS/convert/html_conversion_state.c 
b/tp/Texinfo/XS/convert/html_conversion_state.c
new file mode 100644
index 0000000000..29d1d9ad7f
--- /dev/null
+++ b/tp/Texinfo/XS/convert/html_conversion_state.c
@@ -0,0 +1,977 @@
+/* Copyright 2010-2024 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "command_ids.h"
+#include "converter_types.h"
+#include "html_converter_types.h"
+#include "command_stack.h"
+/* new_string_list add_string fatal */
+#include "utils.h"
+#include "html_conversion_state.h"
+
+
+static int
+compare_page_name_number (const void *a, const void *b)
+{
+  const PAGE_NAME_NUMBER *pnn_a = (const PAGE_NAME_NUMBER *) a;
+  const PAGE_NAME_NUMBER *pnn_b = (const PAGE_NAME_NUMBER *) b;
+
+  return strcmp (pnn_a->page_name, pnn_b->page_name);
+}
+
+size_t
+find_page_name_number
+            (const PAGE_NAME_NUMBER_LIST *page_name_number,
+                                          const char *page_name)
+{
+  PAGE_NAME_NUMBER *result = 0;
+  static PAGE_NAME_NUMBER searched_page_name;
+
+  searched_page_name.page_name = page_name;
+  if (page_name_number->number == 0)
+    {
+      char *msg;
+      xasprintf (&msg, "no pages, searching for '%s'\n", page_name);
+      fatal (msg);
+      free (msg);
+    }
+
+  result = (PAGE_NAME_NUMBER *) bsearch (&searched_page_name,
+                page_name_number->list,
+                page_name_number->number, sizeof (PAGE_NAME_NUMBER),
+                compare_page_name_number);
+  if (!result)
+    return 0;
+  return result->number;
+}
+
+size_t
+count_elements_in_file_number (const CONVERTER *self,
+                 enum count_elements_in_filename_type type,
+                 size_t file_number)
+{
+  size_t i = file_number - 1;
+  const FILE_NAME_PATH_COUNTER *file_counter
+            = &self->output_unit_files.list[i];
+
+  if (type == CEFT_total)
+    return file_counter->elements_in_file_count;
+  else if (type == CEFT_remaining)
+    return file_counter->counter;
+  else /* if (type == CEFT_current) */
+    return file_counter->elements_in_file_count - file_counter->counter +1;
+}
+
+/* called from perl */
+size_t
+html_count_elements_in_filename (const CONVERTER *self,
+                 enum count_elements_in_filename_type type,
+                 const char *filename)
+{
+  size_t page_number = find_page_name_number (&self->page_name_number,
+                                              filename);
+
+  if (!page_number)
+    return 0;
+
+  return count_elements_in_file_number (self, type, page_number);
+}
+
+
+int
+html_in_code (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return top_integer_stack (&top_document_ctx->monospace);
+}
+
+int
+html_in_math (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return top_document_ctx->math_ctx;
+}
+
+int
+html_in_preformatted_context (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return top_integer_stack (&top_document_ctx->preformatted_context);
+}
+
+int
+html_inside_preformatted (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return top_document_ctx->inside_preformatted;
+}
+
+int
+html_in_non_breakable_space (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  HTML_FORMATTING_CONTEXT *top_formating_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_formating_ctx
+    = html_top_formatting_context (&top_document_ctx->formatting_context);
+  return top_formating_ctx->no_break;
+}
+
+int
+html_in_raw (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return top_document_ctx->raw_ctx;
+}
+
+int
+html_in_space_protected (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  HTML_FORMATTING_CONTEXT *top_formating_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_formating_ctx
+    = html_top_formatting_context (&top_document_ctx->formatting_context);
+  return top_formating_ctx->space_protected;
+}
+
+int
+html_in_string (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return top_document_ctx->string_ctx;
+}
+
+int
+html_in_upper_case (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  HTML_FORMATTING_CONTEXT *top_formating_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_formating_ctx
+    = html_top_formatting_context (&top_document_ctx->formatting_context);
+  return top_formating_ctx->upper_case_ctx;
+}
+
+int
+html_in_verbatim (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return top_document_ctx->verbatim_ctx;
+}
+
+int
+html_paragraph_number (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  HTML_FORMATTING_CONTEXT *top_formating_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_formating_ctx
+    = html_top_formatting_context (&top_document_ctx->formatting_context);
+  return top_formating_ctx->paragraph_number;
+}
+
+int
+html_preformatted_number (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  HTML_FORMATTING_CONTEXT *top_formating_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_formating_ctx
+    = html_top_formatting_context (&top_document_ctx->formatting_context);
+  return top_formating_ctx->preformatted_number;
+}
+
+enum command_id
+html_top_block_command (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  if (top_document_ctx->block_commands.top <= 0)
+    return 0;
+  return top_command (&top_document_ctx->block_commands);
+}
+
+const COMMAND_OR_TYPE_STACK *
+html_preformatted_classes_stack (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  return &top_document_ctx->preformatted_classes;
+}
+
+enum command_id
+html_in_align (const CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  COMMAND_OR_TYPE *context;
+  top_document_ctx = html_top_document_context (self);
+  context = top_command_or_type (&top_document_ctx->composition_context);
+  if (context->variety == CTV_type_command)
+    {
+      enum command_id cmd = context->ct.cmd;
+      if (html_commands_data[cmd].flags & HF_HTML_align)
+        return cmd;
+    }
+  return 0;
+}
+
+void
+html_set_code_context (CONVERTER *self, int code)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  push_integer_stack_integer (&top_document_ctx->monospace, code);
+}
+
+void
+html_pop_code_context (CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  pop_integer_stack (&top_document_ctx->monospace);
+}
+
+void
+html_set_string_context (CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_document_ctx->string_ctx++;
+}
+
+void
+html_unset_string_context (CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_document_ctx->string_ctx--;
+}
+
+void
+html_set_raw_context (CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_document_ctx->raw_ctx++;
+}
+
+void
+html_unset_raw_context (CONVERTER *self)
+{
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
+  top_document_ctx = html_top_document_context (self);
+  top_document_ctx->raw_ctx--;
+}
+
+const char *
+html_in_multi_expanded (CONVERTER *self)
+{
+  if (self->multiple_pass.top > 0)
+    return top_string_stack (&self->multiple_pass);
+
+  return 0;
+}
+
+void
+html_register_footnote (CONVERTER *self, const ELEMENT *command,
+     const char *footid, const char *docid, int number_in_doc,
+     const char *footnote_location_filename, const char *multi_expanded_region)
+{
+  HTML_PENDING_FOOTNOTE_STACK *stack;
+  HTML_PENDING_FOOTNOTE *pending_footnote;
+
+  if (self->shared_conversion_state.in_skipped_node_top == 1)
+    return;
+
+  stack = &self->pending_footnotes;
+
+  if (stack->top >= stack->space)
+    {
+      stack->stack
+        = realloc (stack->stack,
+                   (stack->space += 5) * sizeof (HTML_PENDING_FOOTNOTE *));
+    }
+  pending_footnote = (HTML_PENDING_FOOTNOTE *)
+                      malloc (sizeof (HTML_PENDING_FOOTNOTE));
+  stack->stack[stack->top] = pending_footnote;
+  stack->top++;
+
+  pending_footnote->command = command;
+  pending_footnote->footid = strdup (footid);
+  pending_footnote->docid = strdup (docid);
+  pending_footnote->number_in_doc = number_in_doc;
+  pending_footnote->footnote_location_filename
+       = strdup (footnote_location_filename);
+
+  if (multi_expanded_region)
+    pending_footnote->multi_expanded_region = strdup (multi_expanded_region);
+  else
+    pending_footnote->multi_expanded_region = 0;
+}
+
+HTML_PENDING_FOOTNOTE_STACK *
+html_get_pending_footnotes (CONVERTER *self)
+{
+  HTML_PENDING_FOOTNOTE_STACK *stack = (HTML_PENDING_FOOTNOTE_STACK *)
+     malloc (sizeof (HTML_PENDING_FOOTNOTE_STACK));
+
+  stack->top = self->pending_footnotes.top;
+  stack->space = self->pending_footnotes.space;
+  stack->stack = self->pending_footnotes.stack;
+
+  memset (&self->pending_footnotes, 0, sizeof (HTML_PENDING_FOOTNOTE_STACK));
+
+  return stack;
+}
+
+void
+destroy_pending_footnotes (HTML_PENDING_FOOTNOTE_STACK *stack)
+{
+  size_t i;
+  for (i = 0; i < stack->top; i++)
+    {
+      free (stack->stack[i]->multi_expanded_region);
+      free (stack->stack[i]->footid);
+      free (stack->stack[i]->docid);
+      free (stack->stack[i]->footnote_location_filename);
+      free (stack->stack[i]);
+    }
+  free (stack->stack);
+  free (stack);
+}
+
+void
+html_register_pending_formatted_inline_content (CONVERTER *self,
+                             const char *category, const char *inline_content)
+{
+  HTML_INLINE_CONTENT *pending_content;
+  HTML_INLINE_CONTENT_STACK *stack;
+
+  if (!inline_content)
+    return;
+
+  stack = &self->pending_inline_content;
+  if (stack->top >= stack->space)
+    {
+      stack->stack
+        = realloc (stack->stack,
+                   (stack->space += 5) * sizeof (HTML_INLINE_CONTENT));
+    }
+  pending_content = &stack->stack[stack->top];
+
+  pending_content->category = strdup (category);
+  pending_content->string = strdup (inline_content);
+
+  stack->top++;
+}
+
+/* cancel only the first pending content for the category */
+char *
+html_cancel_pending_formatted_inline_content (CONVERTER *self,
+                                              const char *category)
+{
+  HTML_INLINE_CONTENT_STACK *stack = &self->pending_inline_content;
+  if (stack->top)
+    {
+      size_t current_position = stack->top;
+      size_t current_idx;
+      while (current_position > 0)
+        {
+          current_idx = current_position - 1;
+          if (!strcmp (stack->stack[current_idx].category, category))
+            {
+              char *inline_content = stack->stack[current_idx].string;
+              free (stack->stack[current_idx].category);
+              if (current_position < stack->top)
+                {
+                  memmove (&stack->stack[current_idx],
+                           &stack->stack[current_idx+1],
+                           sizeof (HTML_INLINE_CONTENT)
+                               * (stack->top - (current_idx +1)));
+                }
+              stack->top--;
+              return inline_content;
+            }
+        }
+    }
+  return 0;
+}
+
+char *
+html_get_pending_formatted_inline_content (CONVERTER *self)
+{
+  HTML_INLINE_CONTENT_STACK *stack = &self->pending_inline_content;
+  if (stack->top)
+    {
+      TEXT result;
+      size_t i;
+      text_init (&result);
+      for (i = 0; i < stack->top; i++)
+        {
+          text_append (&result, stack->stack[i].string);
+          free (stack->stack[i].string);
+          free (stack->stack[i].category);
+        }
+      stack->top = 0;
+      return result.text;
+    }
+  else
+    return strdup ("");
+}
+
+static size_t
+get_associated_inline_content_number (
+     const HTML_ASSOCIATED_INLINE_CONTENT_LIST *associated_content_list,
+     const ELEMENT *element, const void *hv)
+{
+  size_t i;
+  for (i = 0; i < associated_content_list->number; i++)
+    {
+      const HTML_ASSOCIATED_INLINE_CONTENT *element_associated_content
+        = &associated_content_list->list[i];
+      if ((element && (element_associated_content->element == element
+                       || (element->hv
+                           && element_associated_content->hv == element->hv)))
+          || (hv && (element_associated_content->hv == hv
+                     || (element_associated_content->element
+                         && element_associated_content->element->hv == hv))))
+        {
+          return i +1;
+        }
+    }
+  return 0;
+}
+
+/* API to associate inline content to an element, typically
+   paragraph or preformatted.  Allows to associate the pending
+   content to the first inline element. */
+/* hv is used when called from perl, element when called from C */
+void
+html_associate_pending_formatted_inline_content (CONVERTER *self,
+                                            const ELEMENT *element,
+                                            const void *hv,
+                                            const char *inline_content)
+{
+  HTML_ASSOCIATED_INLINE_CONTENT_LIST *associated_content_list
+    = &self->associated_inline_content;
+  HTML_ASSOCIATED_INLINE_CONTENT *element_associated_content = 0;
+  size_t number = get_associated_inline_content_number 
(associated_content_list,
+                                                                   element, 
hv);
+  if (number > 0)
+    element_associated_content = &associated_content_list->list[number -1];
+
+  if (!element_associated_content)
+    {
+      size_t i;
+      int empty_slot = 0;
+
+      for (i = 0; i < associated_content_list->number; i++)
+        {
+          if (associated_content_list->list[i].inline_content.space == 0)
+            {
+              empty_slot = 1;
+              number = i +1;
+            }
+        }
+
+      if (!empty_slot)
+        {
+          if (associated_content_list->number >= 
associated_content_list->space)
+            {
+              associated_content_list->list
+                = realloc (associated_content_list->list,
+                   (associated_content_list->space += 5)
+                              * sizeof (HTML_ASSOCIATED_INLINE_CONTENT));
+            }
+          associated_content_list->number++;
+          number = associated_content_list->number;
+        }
+      element_associated_content
+        = &associated_content_list->list[number -1];
+      element_associated_content->element = element;
+      element_associated_content->hv = hv;
+      text_init (&element_associated_content->inline_content);
+      /*
+      fprintf (stderr, "NNN (%zu)\n", associated_content_list->number);
+       */
+    }
+  text_append (&element_associated_content->inline_content, inline_content);
+   /*
+  if (element)
+    fprintf (stderr, "RRR-EE %p -> %p %zu\n", element, element->hv, number);
+  if (hv)
+    fprintf (stderr, "RRR-PP %p %zu\n", hv, number);
+    */
+}
+
+/* hv is used when called from perl element when called from C */
+char *
+html_get_associated_formatted_inline_content (CONVERTER *self,
+                                              const ELEMENT *element,
+                                              const void *hv)
+{
+  HTML_ASSOCIATED_INLINE_CONTENT_LIST *associated_content_list
+    = &self->associated_inline_content;
+  HTML_ASSOCIATED_INLINE_CONTENT *element_associated_content = 0;
+  size_t number = get_associated_inline_content_number 
(associated_content_list,
+                                                                   element, 
hv);
+  /*
+  if (element)
+    fprintf (stderr, "GGG-EE %p -> %p %zu (%zu)\n", element, element->hv, 
number, associated_content_list->number);
+  if (hv)
+    fprintf (stderr, "GGG-PP %p %zu (%zu)\n", hv, number, 
associated_content_list->number);
+   */
+  if (number > 0)
+    element_associated_content = &associated_content_list->list[number -1];
+
+  if (element_associated_content)
+    {
+      char *result = element_associated_content->inline_content.text;
+      if (number == associated_content_list->number)
+        associated_content_list->number--;
+      else
+        memset (element_associated_content, 0,
+                sizeof (HTML_ASSOCIATED_INLINE_CONTENT));
+      return result;
+    }
+  return strdup ("");
+}
+
+FILE_INFO_KEY_PAIR *
+add_associated_file_info_integer (FILE_ASSOCIATED_INFO *a,
+                                  const char *key, int value)
+{
+  size_t i;
+  for (i = 0; i < a->info_number; i++)
+    {
+      if (!strcmp (a->info[i].key, key))
+        break;
+    }
+  if (i == a->info_number)
+    {
+      if (a->info_number == a->info_space)
+        {
+          a->info = realloc (a->info,
+                         (a->info_space += 5) * sizeof (FILE_INFO_KEY_PAIR));
+          if (!a->info)
+            fatal ("realloc failed");
+        }
+      a->info_number++;
+
+      a->info[i].key = key;
+    }
+
+  a->info[i].integer = value;
+
+  return &a->info[i];
+}
+
+/* API to register an information to a file and get it.  To be able to
+   set an information during conversion and get it back during headers
+   and footers conversion */
+
+void
+html_register_file_information (CONVERTER *self, const char *key,
+                                int value)
+{
+  FILE_ASSOCIATED_INFO *associated_info
+    = &self->html_files_information.list[self->current_filename.file_number];
+  add_associated_file_info_integer (associated_info, key, value);
+}
+
+const FILE_INFO_KEY_PAIR *
+lookup_associated_file_info (const FILE_ASSOCIATED_INFO *a,
+                             const char *key)
+{
+  size_t i;
+  for (i = 0; i < a->info_number; i++)
+    {
+      if (!strcmp (a->info[i].key, key))
+        return &a->info[i];
+    }
+  return 0;
+}
+
+int
+html_get_file_information (const CONVERTER *self, const char *key,
+                           const char *filename, int *status)
+{
+  size_t page_number;
+  const FILE_ASSOCIATED_INFO *associated_info;
+  const FILE_INFO_KEY_PAIR *k;
+
+  *status = 0;
+  if (filename)
+    {
+      page_number = find_page_name_number (&self->page_name_number,
+                                           filename);
+      if (!page_number)
+        {
+          *status = -1;
+          return 0;
+        }
+    }
+  else
+    page_number = self->current_filename.file_number;
+
+  associated_info = &self->html_files_information.list[page_number];
+  k = lookup_associated_file_info (associated_info, key);
+  if (!k)
+    {
+      *status = -2;
+      return 0;
+    }
+  return k->integer;
+}
+
+void
+html_register_opened_section_level (CONVERTER *self, size_t file_number,
+                                    int level, const char *close_string)
+{
+  STRING_STACK *file_pending_closes 
+    = &self->pending_closes.list[file_number -1];
+
+  while ((int) file_pending_closes->top < level)
+    {
+      push_string_stack_string (file_pending_closes, "");
+    }
+  push_string_stack_string (file_pending_closes, close_string);
+}  
+
+/* called from Perl */
+void
+html_register_opened_filename_section_level (CONVERTER *self,
+                                    const char *filename,
+                                    int level, const char *close_string)
+{
+  size_t page_number = find_page_name_number (&self->page_name_number,
+                                              filename);
+
+  if (!page_number)
+    return;
+
+  html_register_opened_section_level (self, page_number, level, close_string);
+}
+
+STRING_LIST *
+html_close_registered_sections_level (CONVERTER *self, size_t file_number,
+                                      int level)
+{
+  STRING_STACK *file_pending_closes
+    = &self->pending_closes.list[file_number -1];
+  STRING_LIST *closed_elements = new_string_list ();
+
+  while ((int) file_pending_closes->top > level)
+    {
+      const char *close_string = top_string_stack (file_pending_closes);
+      if (strlen (close_string))
+        {
+          add_string (close_string, closed_elements);
+        }
+      pop_string_stack (file_pending_closes);
+    }
+
+  return closed_elements;
+}
+
+/* called from Perl */
+STRING_LIST *
+html_close_registered_filename_sections_level (CONVERTER *self,
+                                      const char *filename, int level)
+{
+  size_t page_number = find_page_name_number (&self->page_name_number,
+                                              filename);
+
+  if (!page_number)
+    return 0;
+
+  return html_close_registered_sections_level (self, page_number, level);
+}
+
+
+
+void
+html_css_add_info (CONVERTER *self, enum css_info_type type,
+                   const char *css_info)
+{
+  if (type == CI_css_info_rules)
+    add_string (css_info, &self->css_rule_lines);
+  else if (type == CI_css_info_imports)
+    add_string (css_info, &self->css_import_lines);
+}
+
+const STRING_LIST *
+html_css_get_info (CONVERTER *self, enum css_info_type type)
+{
+  if (type == CI_css_info_rules)
+    return &self->css_rule_lines;
+  else if (type == CI_css_info_imports)
+    return &self->css_import_lines;
+  else
+    {
+      size_t i;
+      if (self->css_element_class_styles.number > 0)
+        {
+          if (self->css_element_class_list.number == 0)
+            {
+              for (i = 0; i < self->css_element_class_styles.number; i++)
+                {
+                  const CSS_SELECTOR_STYLE *selector_style
+                    = &self->css_element_class_styles.list[i];
+                  if (selector_style->selector)
+                    add_string (selector_style->selector,
+                                &self->css_element_class_list);
+                }
+            }
+        }
+      return &self->css_element_class_list;
+    }
+}
+
+static int
+compare_selector_style (const void *a, const void *b)
+{
+  const CSS_SELECTOR_STYLE *css_a = (const CSS_SELECTOR_STYLE *) a;
+  const CSS_SELECTOR_STYLE *css_b = (const CSS_SELECTOR_STYLE *) b;
+
+  return strcmp (css_a->selector, css_b->selector);
+}
+
+void
+sort_css_element_class_styles (
+       CSS_SELECTOR_STYLE_LIST *css_element_class_styles)
+{
+  qsort (css_element_class_styles->list,
+         css_element_class_styles->number,
+         sizeof (CSS_SELECTOR_STYLE), compare_selector_style);
+}
+
+/* can be modified if called by html_css_set_selector_style */
+CSS_SELECTOR_STYLE *
+find_css_selector_style
+     (const CSS_SELECTOR_STYLE_LIST *css_element_class_styles,
+                                           const char *selector)
+{
+  CSS_SELECTOR_STYLE *result = 0;
+  static CSS_SELECTOR_STYLE searched_selector;
+  /* remove const with a cast, it is more efficient than duplicating */
+  searched_selector.selector = (char *) selector;
+
+  result = (CSS_SELECTOR_STYLE *) bsearch (&searched_selector,
+                css_element_class_styles->list,
+                css_element_class_styles->number, sizeof (CSS_SELECTOR_STYLE),
+                compare_selector_style);
+
+  return result;
+}
+
+void
+html_css_set_selector_style (CSS_SELECTOR_STYLE_LIST *css_element_class_styles,
+                             const char *css_info,
+                             const char *css_style)
+{
+  CSS_SELECTOR_STYLE *selector_style
+   = find_css_selector_style (css_element_class_styles, css_info);
+
+  if (selector_style)
+    {
+      free (selector_style->style);
+      selector_style->style = 0;
+      if (css_style)
+        selector_style->style = strdup (css_style);
+    }
+  else
+    {
+      CSS_SELECTOR_STYLE_LIST *elt_class_styles
+        = css_element_class_styles;
+      if (elt_class_styles->space <= elt_class_styles->number)
+        {
+          elt_class_styles->list = realloc (elt_class_styles->list,
+             (elt_class_styles->space += 10) * sizeof (CSS_SELECTOR_STYLE));
+        }
+
+      selector_style
+        = &elt_class_styles->list[elt_class_styles->number];
+      selector_style->selector = strdup (css_info);
+      if (css_style)
+        selector_style->style = strdup (css_style);
+      else
+        selector_style->style = 0;
+
+      elt_class_styles->number++;
+
+      sort_css_element_class_styles (css_element_class_styles);
+    }
+}
+
+const char *
+html_css_get_selector_style (CONVERTER* self, const char *css_info)
+{
+  const CSS_SELECTOR_STYLE *selector_style
+   = find_css_selector_style (&self->css_element_class_styles, css_info);
+
+  if (selector_style)
+    return selector_style->style;
+
+  return 0;
+}
+
+int
+compare_strings (const void *a, const void *b)
+{
+  const char **str_a = (const char **) a;
+  const char **str_b = (const char **) b;
+
+  return strcmp (*str_a, *str_b);
+}
+
+/* return list to be freed by caller */
+STRING_LIST *
+html_get_css_elements_classes (CONVERTER *self, const char *filename)
+{
+  size_t j;
+  size_t page_number;
+  STRING_LIST *result;
+  const char **selectors;
+  size_t selector_nr = 0;
+
+  if (self->page_css.number <= 0)
+    return 0;
+
+  const CSS_LIST *global_context_css_list = &self->page_css.list[0];
+
+  if (filename)
+    {
+      page_number = find_page_name_number (&self->page_name_number,
+                                           filename);
+      if (!page_number)
+        {
+          if (self->page_css.number > 1)
+            {
+              const CSS_LIST *last_css_page
+               = &self->page_css.list[self->page_css.number -1];
+              if (last_css_page->page_name
+                  && !strcmp (filename, last_css_page->page_name))
+                {
+                  page_number = self->page_css.number -1;
+                }
+             }
+          if (!page_number)
+            {
+             /* this happens legitimately in case of an output file not
+                associated to an output unit and not having registered
+                any CSS selector.  Also the formatting of the node or
+                similar command is in general done in global context
+                so no file is added */
+              /* This debug message is C specific
+              if (self->conf->DEBUG.o.integer > 0)
+                {
+                  fprintf (stderr, "XS|css: REMARK: %s: get_css no page 
found\n",
+                                    filename);
+                }
+               */
+            }
+        }
+      if (page_number)
+        {
+          const CSS_LIST *css_list;
+          css_list = &self->page_css.list[page_number];
+          if (css_list->number)
+            {
+              /* +1 for 'span:hover a.copiable-link' */
+              size_t space
+               = css_list->number + global_context_css_list->number +1;
+              selectors = (const char **) malloc (sizeof (char *) * space);
+              memcpy (selectors, css_list->list,
+                      css_list->number * sizeof (char *));
+              selector_nr = css_list->number;
+            }
+        }
+    }
+
+  if (selector_nr <= 0)
+    {
+      if (global_context_css_list->number)
+        {
+          /* +1 for 'span:hover a.copiable-link' */
+          size_t space = global_context_css_list->number +1;
+          selectors = (const char **) malloc (sizeof (char *) * space);
+          memcpy (selectors, global_context_css_list->list,
+                  global_context_css_list->number * sizeof (char *));
+          selector_nr = global_context_css_list->number;
+        }
+      else
+        return 0;
+    }
+  else if (global_context_css_list->number)
+    {
+      size_t i;
+      size_t file_selector_nr = selector_nr;
+      /* add global context selectors if not already present */
+      for (i = 0; i < global_context_css_list->number; i++)
+        {
+          size_t j;
+          const char *global_selector = global_context_css_list->list[i];
+          int found = 0;
+          for (j = 0; j < file_selector_nr; j++)
+            {
+              if (!strcmp (global_selector, selectors[j]))
+                {
+                  found = 1;
+                  break;
+                }
+            }
+          if (!found)
+            {
+              selectors[selector_nr] = global_selector;
+              selector_nr++;
+            }
+        }
+    }
+
+  for (j = 0; j < selector_nr; j++)
+    {
+      if (!strcmp ("a.copiable-link", selectors[j]))
+        {
+          selectors[selector_nr] = "span:hover a.copiable-link";
+          selector_nr++;
+          break;
+        }
+    }
+
+  qsort (selectors, selector_nr, sizeof (char *), compare_strings);
+
+  result = new_string_list ();
+  for (j = 0; j < selector_nr; j++)
+    add_string (selectors[j], result);
+
+  free (selectors);
+
+  return result;
+}
+
diff --git a/tp/Texinfo/XS/convert/html_conversion_state.h 
b/tp/Texinfo/XS/convert/html_conversion_state.h
new file mode 100644
index 0000000000..e466022bd4
--- /dev/null
+++ b/tp/Texinfo/XS/convert/html_conversion_state.h
@@ -0,0 +1,76 @@
+/* html_conversion_state.h - definitions for html_conversion_state.c */
+#ifndef HTML_CONVERSION_STATE_H
+#define HTML_CONVERSION_STATE_H
+
+#include "html_converter_types.h"
+
+size_t count_elements_in_file_number (const CONVERTER *self,
+                 enum count_elements_in_filename_type type,
+                 size_t file_number);
+
+int html_in_code (const CONVERTER *self);
+int html_in_math (const CONVERTER *self);
+int html_in_preformatted_context (const CONVERTER *self);
+int html_inside_preformatted (const CONVERTER *self);
+int html_in_non_breakable_space (const CONVERTER *self);
+int html_in_raw (const CONVERTER *self);
+int html_in_space_protected (const CONVERTER *self);
+int html_in_string (const CONVERTER *self);
+int html_in_upper_case (const CONVERTER *self);
+int html_in_verbatim (const CONVERTER *self);
+int html_paragraph_number (const CONVERTER *self);
+int html_preformatted_number (const CONVERTER *self);
+enum command_id html_top_block_command (const CONVERTER *self);
+const COMMAND_OR_TYPE_STACK *html_preformatted_classes_stack
+                                    (const CONVERTER *self);
+enum command_id html_in_align (const CONVERTER *self);
+const char *html_in_multi_expanded (CONVERTER *self);
+
+void html_register_footnote (CONVERTER *self, const ELEMENT *command,
+     const char *footid, const char *docid, const int number_in_doc,
+     const char *footnote_location_filename, const char 
*multi_expanded_region);
+HTML_PENDING_FOOTNOTE_STACK *html_get_pending_footnotes (CONVERTER *self);
+void destroy_pending_footnotes (HTML_PENDING_FOOTNOTE_STACK *stack);
+
+void html_register_pending_formatted_inline_content (CONVERTER *self,
+                             const char *category, const char *inline_content);
+char *html_cancel_pending_formatted_inline_content (CONVERTER *self,
+                                                    const char *category);
+char *html_get_pending_formatted_inline_content (CONVERTER *self);
+
+void html_associate_pending_formatted_inline_content (CONVERTER *self,
+                                            const ELEMENT *element,
+                                            const void *hv,
+                                            const char *inline_content);
+char *html_get_associated_formatted_inline_content (CONVERTER *self,
+                                              const ELEMENT *element,
+                                              const void *hv);
+
+void html_register_file_information (CONVERTER *self, const char *key,
+                                     int value);
+int html_get_file_information (const CONVERTER *self, const char *key,
+                               const char *filename, int *status);
+
+void html_register_opened_filename_section_level (CONVERTER *self,
+                                             const char *filename,
+                                         int level, const char *close_string);
+STRING_LIST *html_close_registered_filename_sections_level (CONVERTER *self,
+                                      const char *filename, int level);
+
+void html_css_add_info (CONVERTER *self, enum css_info_type type,
+                        const char *css_info);
+const STRING_LIST *html_css_get_info (CONVERTER *self, enum css_info_type 
type);
+void sort_css_element_class_styles (
+       CSS_SELECTOR_STYLE_LIST *css_element_class_styles);
+CSS_SELECTOR_STYLE *find_css_selector_style
+     (const CSS_SELECTOR_STYLE_LIST *css_element_class_styles,
+                                           const char *selector);
+void html_css_set_selector_style (
+                       CSS_SELECTOR_STYLE_LIST *css_element_class_styles,
+                                  const char *css_info,
+                                  const char *css_style);
+const char *html_css_get_selector_style (CONVERTER* self, const char 
*css_info);
+
+STRING_LIST *html_get_css_elements_classes (CONVERTER *self,
+                                            const char *filename);
+#endif
diff --git a/tp/Texinfo/XS/convert/html_converter_types.h 
b/tp/Texinfo/XS/convert/html_converter_types.h
new file mode 100644
index 0000000000..868c5ff676
--- /dev/null
+++ b/tp/Texinfo/XS/convert/html_converter_types.h
@@ -0,0 +1,53 @@
+/* html_converter_types.h - declarations of types used in conversion to HTML */
+#ifndef HTML_CONVERTER_TYPES_H
+#define HTML_CONVERTER_TYPES_H
+
+/* Copyright 2010-2024 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include "command_ids.h"
+
+enum count_elements_in_filename_type {
+   CEFT_total,
+   CEFT_remaining,
+   CEFT_current,
+};
+
+enum css_info_type {
+   CI_css_info_element_classes,
+   CI_css_info_imports, 
+   CI_css_info_rules,
+};
+
+/* HTML command data flags */
+#define HF_composition_context  0x0001
+#define HF_format_context       0x0002
+#define HF_format_raw           0x0004
+#define HF_pre_class            0x0008
+#define HF_small_block_command  0x0010
+#define HF_HTML_align           0x0020
+#define HF_special_variety      0x0040
+#define HF_indented_preformatted 0x0080
+#define HF_style_command         0x0100
+
+typedef struct HTML_COMMAND_STRUCT {
+    unsigned long flags;
+    enum command_id pre_class_cmd;
+    enum command_id upper_case_cmd;
+} HTML_COMMAND_STRUCT;
+
+extern HTML_COMMAND_STRUCT html_commands_data[BUILTIN_CMD_NUMBER];
+
+#endif



reply via email to

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