[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 = " ";
@@ -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