[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Fri, 4 Oct 2024 12:02:13 -0400 (EDT) |
branch: master
commit 28dd6be383762f7dc808115143bef23e843d1bf0
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Aug 14 18:55:13 2024 +0200
* tp/Texinfo/XS/convert/convert_html.c (html_get_target): call
directly find_element_target_search and not find_element_target.
Remove find_element_target, replace with html_get_target calls.
* tp/Texinfo/XS/convert/convert_html.c (html_get_top_unit)
(html_set_file_source_info, html_add_to_files_source_info)
(html_find_file_source_info, html_setup_output_simple_page):
* tp/Texinfo/XS/convert/html_prepare_converter.c (html_get_target)
(html_prepare_output_units_global_targets)
(compare_global_units_direction_name, add_to_unit_file_name_paths)
(html_setup_global_units_direction_names)
(html_find_direction_name_global_unit, html_set_pages_files)
(prepare_special_units_directions, compare_page_name_number)
(html_prepare_units_directions_files),
tp/Texinfo/XS/convert/convert_html.c: move html_get_target,
html_prepare_output_units_global_targets,
compare_global_units_direction_name,
html_setup_global_units_direction_names,
html_find_direction_name_global_unit, add_to_unit_file_name_paths,
html_set_pages_files, prepare_special_units_directions and
html_prepare_units_directions_files to html_prepare_converter.c.
---
ChangeLog | 25 +
tp/Texinfo/XS/convert/convert_html.c | 1456 +++++-------------------
tp/Texinfo/XS/convert/convert_html.h | 35 +-
tp/Texinfo/XS/convert/html_prepare_converter.c | 831 +++++++++++++-
tp/Texinfo/XS/convert/html_prepare_converter.h | 4 +
5 files changed, 1193 insertions(+), 1158 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b9ae151345..09a71df5b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,31 @@
* tp/Texinfo/XS/convert/convert_html.h: declare node_part_command
open function.
+2024-08-14 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/XS/convert/convert_html.c (html_get_target): call
+ directly find_element_target_search and not find_element_target.
+ Remove find_element_target, replace with html_get_target calls.
+
+ * tp/Texinfo/XS/convert/convert_html.c (html_get_top_unit)
+ (html_set_file_source_info, html_add_to_files_source_info)
+ (html_find_file_source_info, html_setup_output_simple_page):
+
+ * tp/Texinfo/XS/convert/html_prepare_converter.c (html_get_target)
+ (html_prepare_output_units_global_targets)
+ (compare_global_units_direction_name, add_to_unit_file_name_paths)
+ (html_setup_global_units_direction_names)
+ (html_find_direction_name_global_unit, html_set_pages_files)
+ (prepare_special_units_directions, compare_page_name_number)
+ (html_prepare_units_directions_files),
+ tp/Texinfo/XS/convert/convert_html.c: move html_get_target,
+ html_prepare_output_units_global_targets,
+ compare_global_units_direction_name,
+ html_setup_global_units_direction_names,
+ html_find_direction_name_global_unit, add_to_unit_file_name_paths,
+ html_set_pages_files, prepare_special_units_directions and
+ html_prepare_units_directions_files to html_prepare_converter.c.
+
2024-08-14 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/XS/convert/convert_html.c (html_normalized_to_id)
diff --git a/tp/Texinfo/XS/convert/convert_html.c
b/tp/Texinfo/XS/convert/convert_html.c
index 9670d4e42d..90c228ce9a 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -145,8 +145,8 @@ html_register_id (CONVERTER *self, const char *string)
if OUTPUT_UNITS is defined, the first output unit is used if a proper
top output unit is not found.
*/
-static OUTPUT_UNIT *
-get_top_unit (DOCUMENT *document, const OUTPUT_UNIT_LIST *output_units)
+OUTPUT_UNIT *
+html_get_top_unit (DOCUMENT *document, const OUTPUT_UNIT_LIST *output_units)
{
const ELEMENT *node_top = find_identifier_target
(&document->identifiers_target, "Top");
@@ -165,7 +165,7 @@ get_top_unit (DOCUMENT *document, const OUTPUT_UNIT_LIST
*output_units)
static int
unit_is_top_output_unit (CONVERTER *self, const OUTPUT_UNIT *output_unit)
{
- OUTPUT_UNIT *top_output_unit = get_top_unit (self->document, 0);
+ OUTPUT_UNIT *top_output_unit = html_get_top_unit (self->document, 0);
return (top_output_unit && top_output_unit == output_unit);
}
@@ -357,6 +357,43 @@ html_after_escaped_characters (char *text)
return 0;
}
+/*
+static const char *xml_named_entity_nbsp = " ";
+ */
+static const char *html_default_entity_nbsp = " ";
+
+char *
+html_substitute_non_breaking_space (CONVERTER *self, const char *text)
+{
+ TEXT result;
+ text_init (&result);
+ text_append (&result, "");
+
+ const char *p = text;
+
+ while (*p)
+ {
+ const char *q = strstr (p, html_default_entity_nbsp);
+ if (q)
+ {
+ if (q - p)
+ {
+ text_append_n (&result, p, q - p);
+ }
+ text_append_n (&result,
+ self->special_character[SC_non_breaking_space].string,
+ self->special_character[SC_non_breaking_space].len);
+ p = q + 6; /* 6: length of html_default_entity_nbsp */
+ }
+ else
+ {
+ text_append (&result, p);
+ break;
+ }
+ }
+ return result.text;
+}
+
/* this number should be safe to use even after targets list has been
reallocated */
@@ -409,12 +446,14 @@ find_element_target_search (const HTML_TARGET_LIST
*targets,
return result;
}
-/* becomes invalid if the targets list is reallocated */
+/* note that the returned pointer may be invalidated if the targets list
+ is reallocated. Callers should make sure that the html target is
+ used before a reallocation is possible */
HTML_TARGET *
-find_element_target (const HTML_TARGET_LIST *targets, const ELEMENT *element)
+html_get_target (const CONVERTER *self, const ELEMENT *element)
{
enum command_id cmd = element_builtin_cmd (element);
- return find_element_target_search (&targets[cmd], element);
+ return find_element_target_search (&self->html_targets[cmd], element);
/* with a linear search:
size_t i = find_element_target_number_linear (&targets[cmd], element);
@@ -424,6 +463,7 @@ find_element_target (const HTML_TARGET_LIST *targets, const
ELEMENT *element)
return 0;
*/
}
+
/* the target may not be known already, so the caller may fill the
HTML_TARGET in some cases */
HTML_TARGET *
@@ -441,6 +481,94 @@ find_element_special_target (const HTML_TARGET_LIST
*targets,
*/
}
+void
+html_set_file_source_info (FILE_SOURCE_INFO *file_source_info,
+ const char *file_info_type,
+ const char *file_info_name,
+ const ELEMENT *file_info_element,
+ const char *filepath)
+{
+ file_source_info->type = file_info_type;
+ file_source_info->name = file_info_name;
+ file_source_info->element = file_info_element;
+ if (filepath)
+ file_source_info->path = strdup (filepath);
+ else
+ file_source_info->path = 0;
+}
+
+FILE_SOURCE_INFO *
+html_add_to_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info,
+ const char *filename,
+ const char *file_info_type,
+ const char *file_info_name,
+ const ELEMENT *file_info_element,
+ const char *filepath)
+{
+ FILE_SOURCE_INFO *new_file_source_info;
+ if (files_source_info->number == files_source_info->space)
+ {
+ files_source_info->list = realloc (files_source_info->list,
+ (files_source_info->space += 5) * sizeof (FILE_SOURCE_INFO));
+ if (!files_source_info->list)
+ fatal ("realloc failed");
+ }
+
+ new_file_source_info =
+ &files_source_info->list[files_source_info->number];
+
+ new_file_source_info->filename = strdup (filename);
+ html_set_file_source_info (new_file_source_info, file_info_type,
+ file_info_name, file_info_element, filepath);
+
+ files_source_info->number++;
+
+ return new_file_source_info;
+}
+
+FILE_SOURCE_INFO *
+html_find_file_source_info (FILE_SOURCE_INFO_LIST *files_source_info,
+ const char *filename)
+{
+ size_t i;
+ for (i = 0; i < files_source_info->number; i++)
+ {
+ FILE_SOURCE_INFO *file_source_info = &files_source_info->list[i];
+ if (!strcmp (file_source_info->filename, filename))
+ return file_source_info;
+ }
+ return 0;
+}
+
+/* setup a page (+global context) in case there are no files, ie called
+ with convert or output with an empty string as filename. */
+void
+html_setup_output_simple_page (CONVERTER *self, const char *output_filename)
+{
+ PAGE_NAME_NUMBER *page_name_number;
+ self->page_css.number = 1+1;
+ self->page_css.space = self->page_css.number;
+ self->page_css.list = (CSS_LIST *)
+ malloc (self->page_css.space * sizeof (CSS_LIST));
+ memset (self->page_css.list, 0,
+ self->page_css.number * sizeof (CSS_LIST));
+
+ self->html_files_information.number = 1+1;
+ self->html_files_information.list = (FILE_ASSOCIATED_INFO *)
+ malloc (self->html_files_information.number
+ * sizeof (FILE_ASSOCIATED_INFO));
+ memset (self->html_files_information.list, 0,
+ self->html_files_information.number * sizeof (FILE_ASSOCIATED_INFO));
+
+ self->page_name_number.number = 1;
+ self->page_name_number.list = (PAGE_NAME_NUMBER *)
+ malloc (self->page_name_number.number * sizeof (PAGE_NAME_NUMBER));
+
+ page_name_number = &self->page_name_number.list[0];
+ page_name_number->number = 1;
+ page_name_number->page_name = output_filename;
+}
+
char *
format_translate_message (CONVERTER *self,
const char *message, const char *lang,
@@ -590,54 +718,6 @@ translate_convert_to_html_internal (const char *string,
destroy_element_and_children (translation_tree);
}
-
-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);
-}
-
-
-/*
-static const char *xml_named_entity_nbsp = " ";
- */
-static const char *html_default_entity_nbsp = " ";
-
-char *
-html_substitute_non_breaking_space (CONVERTER *self, const char *text)
-{
- TEXT result;
- text_init (&result);
- text_append (&result, "");
-
- const char *p = text;
-
- while (*p)
- {
- const char *q = strstr (p, html_default_entity_nbsp);
- if (q)
- {
- if (q - p)
- {
- text_append_n (&result, p, q - p);
- }
- text_append_n (&result,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- p = q + 6; /* 6: length of html_default_entity_nbsp */
- }
- else
- {
- text_append (&result, p);
- break;
- }
- }
- return result.text;
-}
-
ELEMENT *
special_unit_info_tree (CONVERTER *self, const enum special_unit_info_tree
type,
const char *special_unit_variety)
@@ -1427,18 +1507,6 @@ html_add_special_unit_info (SPECIAL_UNIT_INFO_LIST
*special_unit_info_list,
return special_unit_info;
}
-/* note that the returned pointer may be invalidated if the targets list
- is reallocated. Callers should make sure that the html target is
- used before a reallocation is possible */
-HTML_TARGET *
-html_get_target (const CONVERTER *self, const ELEMENT *element)
-{
- HTML_TARGET *result
- = find_element_target (self->html_targets, element);
-
- return result;
-}
-
const char *
html_command_id (const CONVERTER *self, const ELEMENT *command)
{
@@ -2726,1116 +2794,184 @@ from_element_direction (CONVERTER *self, int
direction,
const ELEMENT *associated_node
= lookup_extra_element (target_command,
AI_key_associated_node);
- if (associated_node)
- command = associated_node;
- }
- }
- type = HTT_text;
- }
- else if (type == HTT_section)
- {
- if (target_unit->unit_type == OU_unit &&
target_unit->uc.unit_command)
- {
- const ELEMENT *target_command = target_unit->uc.unit_command;
- if (target_command->e.c->cmd != CM_node)
- command = target_command;
- else
- {
- const ELEMENT *associated_section
- = lookup_extra_element (target_command,
- AI_key_associated_section);
- if (associated_section)
- command = associated_section;
- }
- }
- type = HTT_text_nonumber;
- }
- else
- {
- if (target_unit->unit_type == OU_special_unit)
- command = target_unit->uc.special_unit_command;
- else
- command = target_unit->uc.unit_command;
- if (type == HTT_href)
- {
- if (command)
- return html_command_href (self, command,
- filename_from, 0, 0);
- else
- return 0;
- }
- }
- }
- else
- return 0;
-
- if (command)
- return html_command_text (self, command, type);
-
- /*
- We end up here if there is a target element, but not of the expected
- 'type'. For example, if type is section but there is no section associated
- to the target element node.
- */
- return 0;
-}
-
-static void
-add_new_css_page (PAGES_CSS_LIST *css_pages, const char *page_name)
-{
- CSS_LIST *page_css_list;
- if (css_pages->space <= css_pages->number)
- {
- css_pages->list = realloc (css_pages->list,
- (css_pages->space += 10) * sizeof (CSS_LIST));
- }
-
- page_css_list = &css_pages->list[css_pages->number];
- memset (page_css_list, 0, sizeof (CSS_LIST));
- page_css_list->page_name = strdup (page_name);
-
- css_pages->number++;
-}
-
-static void
-collect_css_element_class (CONVERTER *self, const char *selector)
-{
- const CSS_SELECTOR_STYLE *selector_style
- = find_css_selector_style (&self->css_element_class_styles, selector);
- if (selector_style)
- {
- size_t i;
- size_t css_files_index;
- CSS_LIST *page_css_list;
- if (self->document_global_context)
- {
- css_files_index = 0;
- }
- else
- {
- css_files_index = self->current_filename.file_number;
- /* files not associated to output units. Only try the
- last one, as the files should be processed sequentially */
- if (css_files_index == 0)
- {
- if (self->current_filename.filename)
- {
- if (self->page_css.number > 1)
- {
- CSS_LIST *last_css_page
- = &self->page_css.list[self->page_css.number -1];
- if (last_css_page->page_name
- && !strcmp (self->current_filename.filename,
- last_css_page->page_name))
- {
- css_files_index = self->page_css.number -1;
- }
- }
- if (css_files_index == 0)
- {
- add_new_css_page (&self->page_css,
- self->current_filename.filename);
- css_files_index = self->page_css.number -1;
- }
- }
- }
- if (css_files_index == 0)
- {
- fprintf (stderr, "BUG: %s: CSS no current file\n", selector);
- return;
- }
- }
- page_css_list = &self->page_css.list[css_files_index];
- for (i = 0; i < page_css_list->number; i++)
- {
- if (!strcmp (page_css_list->list[i], selector))
- return;
- }
- if (page_css_list->number == page_css_list->space)
- {
- page_css_list->list
- = realloc (page_css_list->list,
- (page_css_list->space += 5) * sizeof (char *));
- }
- page_css_list->list[page_css_list->number] = strdup (selector);
- page_css_list->number++;
- }
-}
-
-void
-close_html_lone_element (const CONVERTER *self, TEXT *result)
-{
- if (self->conf->USE_XML_SYNTAX.o.integer > 0)
- text_append_n (result, "/>", 2);
- else
- text_append_n (result, ">", 1);
-}
-
-static char *
-protect_class_name (const char *class_name)
-{
- TEXT result;
- TEXT space_protected;
- text_init (&result);
- text_init (&space_protected);
- const char *p = class_name;
- while (*p)
- {
- int n = strcspn (p, " ");
- if (n)
- {
- text_append_n (&space_protected, p, n);
- p += n;
- }
- if (*p)
- {
- int n = strspn (p, " ");
- if (n)
- {
- int i;
- for (i = 0; i < n; i++)
- text_append_n (&space_protected, "-", 1);
- p += n;
- }
- }
- }
-
- /* do not use the customization API as in perl */
- html_default_format_protect_text (space_protected.text, &result);
- free (space_protected.text);
- return result.text;
-}
-
-/* Associate output units to the global targets, First, Last, Top, Index.
- and special output units */
-void
-html_prepare_output_units_global_targets (CONVERTER *self)
-{
- int i;
- int all_special_units_nr = 0;
- int s;
- const OUTPUT_UNIT_LIST *output_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_units]);
-
- const OUTPUT_UNIT *top_output_unit = get_top_unit (self->document,
- output_units);
-
- size_t special_output_units_lists[2] = {
- self->output_units_descriptors[OUDT_special_units],
- self->output_units_descriptors[OUDT_associated_special_units]};
-
- self->global_units_directions[D_First] = output_units->list[0];
- self->global_units_directions[D_Last]
- = output_units->list[output_units->number - 1];
-
- self->global_units_directions[D_Top] = top_output_unit;
-
- /* It is always the first printindex, even if it is not output (for example
- it is in @copying and @titlepage, which are certainly wrong constructs).
- */
- if (self->document->global_commands.printindex.number > 0)
- {
- const ELEMENT *printindex
- = self->document->global_commands.printindex.list[0];
- ROOT_AND_UNIT *root_unit
- = html_get_tree_root_element (self, printindex, 0);
- if (root_unit->output_unit)
- {
- const OUTPUT_UNIT *document_unit = root_unit->output_unit;
- const ELEMENT *root_command = root_unit->root;
- if (root_command && root_command->e.c->cmd == CM_node)
- {
- const ELEMENT *associated_section
- = lookup_extra_element (root_command,
- AI_key_associated_section);
- if (associated_section)
- root_command = associated_section;
- }
- /* find the first level 1 sectioning element to associate the printindex
- with */
- if (root_command && root_command->e.c->cmd != CM_node)
- {
- while (1)
- {
- int status;
- int section_level
- = lookup_extra_integer (root_command, AI_key_section_level,
- &status);
- if (!status && section_level <= 1)
- break;
-
- const ELEMENT * const *up_section_directions
- = lookup_extra_directions (root_command,
- AI_key_section_directions);
- if (up_section_directions
- && up_section_directions[D_up]
- && up_section_directions[D_up]
- ->e.c->associated_unit)
- {
- root_command = up_section_directions[D_up];
- document_unit = root_command->e.c->associated_unit;
- }
- else
- break;
- }
- }
- self->global_units_directions[D_Index] = document_unit;
- }
- free (root_unit);
- }
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- int i;
- fprintf (stderr, "GLOBAL DIRECTIONS:\n");
- for (i = 0; i < D_Last+1; i++)
- {
- if (self->global_units_directions[i])
- {
- const OUTPUT_UNIT *global_unit =
self->global_units_directions[i];
- char *unit_texi = output_unit_texi (global_unit);
- fprintf (stderr, " %s: %s\n",
html_global_unit_direction_names[i],
- unit_texi);
- free (unit_texi);
- }
- }
- fprintf (stderr, "\n");
- }
-
- /* determine total number of special output units and fill
- special_units_directions_name_unit. Used to simplify building perl
- directions */
- for (i = 0; i < 2; i++)
- {
- size_t special_units_descriptor = special_output_units_lists[i];
- const OUTPUT_UNIT_LIST *units_list
- = retrieve_output_units (self->document, special_units_descriptor);
- if (units_list && units_list->number)
- all_special_units_nr += units_list->number;
- }
-
- self->special_units_direction_name = (SPECIAL_UNIT_DIRECTION *)
- malloc (sizeof (SPECIAL_UNIT_DIRECTION) * (all_special_units_nr+1));
- memset (self->special_units_direction_name, 0,
- sizeof (SPECIAL_UNIT_DIRECTION) * (all_special_units_nr+1));
-
- s = 0;
- for (i = 0; i < 2; i++)
- {
- size_t special_units_descriptor = special_output_units_lists[i];
- const OUTPUT_UNIT_LIST *units_list
- = retrieve_output_units (self->document, special_units_descriptor);
- if (units_list && units_list->number)
- {
- size_t j;
- for (j = 0; j < units_list->number; j++)
- {
- const OUTPUT_UNIT *special_unit = units_list->list[j];
- const char *special_unit_variety =
special_unit->special_unit_variety;
- int special_unit_direction_index
- = html_special_unit_variety_direction_index (self,
- special_unit_variety);
- self->global_units_directions[special_unit_direction_index]
- = special_unit;
-
- self->special_units_direction_name[s].output_unit = special_unit;
- self->special_units_direction_name[s].direction
- = html_special_unit_info (self, SUI_type_direction,
- special_unit_variety);
- s++;
- }
- }
- }
-}
-
-static int
-compare_global_units_direction_name (const void *a, const void *b)
-{
- const SPECIAL_UNIT_DIRECTION *gudn_a = (const SPECIAL_UNIT_DIRECTION *) a;
- const SPECIAL_UNIT_DIRECTION *gudn_b = (const SPECIAL_UNIT_DIRECTION *) b;
-
- return strcmp (gudn_a->direction, gudn_b->direction);
-}
-
-/* To find more easily a global output unit based on a direction name, for an
- XS interface, associate global output units to names and sort according
- to names */
-void
-html_setup_global_units_direction_names (CONVERTER *self)
-{
- SPECIAL_UNIT_DIRECTION *global_units_direction_names;
- int i;
- int global_directions_nr = 0;
- int global_units_direction_idx = 0;
- const SPECIAL_UNIT_DIRECTION *special_units_direction_name
- = self->special_units_direction_name;
-
- for (i = 0; i < D_Last+1; i++)
- if (self->global_units_directions[i])
- global_directions_nr++;
-
- for (i = 0; special_units_direction_name[i].output_unit; i++)
- global_directions_nr++;
-
- global_units_direction_names = (SPECIAL_UNIT_DIRECTION *)
- malloc (sizeof (SPECIAL_UNIT_DIRECTION) * (global_directions_nr));
-
- for (i = 0; i < D_Last+1; i++)
- {
- if (self->global_units_directions[i])
- {
- global_units_direction_names[global_units_direction_idx].direction
- = html_global_unit_direction_names[i];
- global_units_direction_names[global_units_direction_idx].output_unit
- = self->global_units_directions[i];
- global_units_direction_idx++;
- }
- }
-
- for (i = 0; special_units_direction_name[i].output_unit; i++)
- {
- global_units_direction_names[global_units_direction_idx].direction
- = special_units_direction_name[i].direction;
- global_units_direction_names[global_units_direction_idx].output_unit
- = special_units_direction_name[i].output_unit;
- global_units_direction_idx++;
- }
-
- qsort (global_units_direction_names,
- global_directions_nr,
- sizeof (SPECIAL_UNIT_DIRECTION), compare_global_units_direction_name);
-
- self->global_units_direction_name.list = global_units_direction_names;
- self->global_units_direction_name.number = global_directions_nr;
-}
-
-/* Used from Perl through an XS override, in similar C codes the
- direction indices are used instead of the direction names */
-const OUTPUT_UNIT *
-html_find_direction_name_global_unit (const CONVERTER *self,
- const char *direction_name)
-{
- SPECIAL_UNIT_DIRECTION *result = 0;
- static SPECIAL_UNIT_DIRECTION searched_direction;
-
- searched_direction.direction = direction_name;
- result = (SPECIAL_UNIT_DIRECTION *) bsearch (&searched_direction,
- self->global_units_direction_name.list,
- self->global_units_direction_name.number,
- sizeof (SPECIAL_UNIT_DIRECTION),
- compare_global_units_direction_name);
- if (!result)
- return 0;
- return result->output_unit;
-}
-
-static void
-set_file_source_info (FILE_SOURCE_INFO *file_source_info,
- const char *file_info_type, const char
*file_info_name,
- const ELEMENT *file_info_element, const char
*filepath)
-{
- file_source_info->type = file_info_type;
- file_source_info->name = file_info_name;
- file_source_info->element = file_info_element;
- if (filepath)
- file_source_info->path = strdup (filepath);
- else
- file_source_info->path = 0;
-}
-
-static FILE_SOURCE_INFO *
-add_to_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info,
- const char *filename,
- const char *file_info_type, const char
*file_info_name,
- const ELEMENT *file_info_element, const char
*filepath)
-{
- FILE_SOURCE_INFO *new_file_source_info;
- if (files_source_info->number == files_source_info->space)
- {
- files_source_info->list = realloc (files_source_info->list,
- (files_source_info->space += 5) * sizeof (FILE_SOURCE_INFO));
- if (!files_source_info->list)
- fatal ("realloc failed");
- }
-
- new_file_source_info =
- &files_source_info->list[files_source_info->number];
-
- new_file_source_info->filename = strdup (filename);
- set_file_source_info (new_file_source_info, file_info_type,
- file_info_name, file_info_element, filepath);
-
- files_source_info->number++;
-
- return new_file_source_info;
-}
-
-static FILE_SOURCE_INFO *
-find_file_source_info (FILE_SOURCE_INFO_LIST *files_source_info,
- const char *filename)
-{
- size_t i;
- for (i = 0; i < files_source_info->number; i++)
- {
- FILE_SOURCE_INFO *file_source_info = &files_source_info->list[i];
- if (!strcmp (file_source_info->filename, filename))
- return file_source_info;
- }
- return 0;
-}
-
-void
-html_reset_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info)
-{
- size_t i;
- for (i = 0; i < files_source_info->number; i++)
- {
- free (files_source_info->list[i].filename);
- free (files_source_info->list[i].path);
- }
- files_source_info->number = 0;
-}
-
-void
-html_free_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info)
-{
- html_reset_files_source_info (files_source_info);
- free (files_source_info->list);
- files_source_info->list = 0;
- files_source_info->space = 0;
-}
-
-void
-html_destroy_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info)
-{
- html_free_files_source_info (files_source_info);
- free (files_source_info);
-}
-
-static char *
-add_to_unit_file_name_paths (char **unit_file_name_paths,
- const char *filename,
- const OUTPUT_UNIT *output_unit)
-{
- unit_file_name_paths[output_unit->index] = strdup (filename);
-
- return unit_file_name_paths[output_unit->index];
-}
-
-/* calls customization function requiring output units */
-static FILE_SOURCE_INFO_LIST *
-html_set_pages_files (CONVERTER *self, const OUTPUT_UNIT_LIST *output_units,
- const OUTPUT_UNIT_LIST *special_units,
- const OUTPUT_UNIT_LIST *associated_special_units,
- const char *output_file,
- const char *destination_directory, const char
*output_filename,
- const char *document_name)
-{
- FILE_SOURCE_INFO_LIST *files_source_info;
- char **unit_file_name_paths;
- size_t i;
-
- initialize_output_units_files (self);
-
- files_source_info = &self->files_source_info;
-
- unit_file_name_paths = (char **)
- malloc (output_units->number * sizeof (char *));
- memset (unit_file_name_paths, 0,
- output_units->number * sizeof (char *));
-
- if (!self->conf->SPLIT.o.string || !strlen (self->conf->SPLIT.o.string))
- {
- size_t i;
- add_to_files_source_info (files_source_info, output_filename,
- "special_file", "non_split", 0,
- output_file);
- for (i = 0; i < output_units->number; i++)
- {
- add_to_unit_file_name_paths (unit_file_name_paths,
- output_filename,
- output_units->list[i]);
- }
- }
- else
- {
- char *top_node_filename_str;
- const OUTPUT_UNIT *node_top_output_unit = 0;
- const char *extension = 0;
- const ELEMENT *node_top = 0;
- size_t file_nr = 0;
- size_t i;
-
- /* first determine the top node file name. */
- if (self->document->identifiers_target.number > 0)
- node_top = find_identifier_target (&self->document->identifiers_target,
- "Top");
-
- top_node_filename_str = top_node_filename (self, document_name);
-
- if (node_top && top_node_filename_str)
- {
- size_t i;
- node_top_output_unit = node_top->e.c->associated_unit;
- for (i = 0; i < output_units->number; i++)
- if (output_units->list[i] == node_top_output_unit)
- break;
- add_to_files_source_info (files_source_info, top_node_filename_str,
- "special_file", "Top", 0, 0);
- add_to_unit_file_name_paths (unit_file_name_paths,
- top_node_filename_str,
- node_top_output_unit);
- }
-
- if (self->conf->EXTENSION.o.string
- && strlen (self->conf->EXTENSION.o.string))
- extension = self->conf->EXTENSION.o.string;
-
- for (i = 0; i < output_units->number; i++)
- {
- const OUTPUT_UNIT *output_unit = output_units->list[i];
- const OUTPUT_UNIT *file_output_unit;
- const char *output_unit_file_name;
- /* For Top node. */
- if (node_top_output_unit && node_top_output_unit == output_unit)
- continue;
-
- file_output_unit = output_unit->first_in_page;
- output_unit_file_name
- = unit_file_name_paths[file_output_unit->index];
- if (!output_unit_file_name)
- {
- const char *node_filename = 0;
- size_t j;
- for (j = 0; j < file_output_unit->unit_contents.number; j++)
- {
- const ELEMENT *root_command
- = file_output_unit->unit_contents.list[j];
- if (root_command->e.c->cmd == CM_node)
- {
- const ELEMENT *node_target = 0;
- const char *normalized = lookup_extra_string
(root_command,
-
AI_key_normalized);
- if (normalized)
- node_target
- = find_identifier_target (
- &self->document->identifiers_target,
- normalized);
- /* double node are not normalized, they are handled here */
- if (!node_target)
- {
- const FILE_SOURCE_INFO *file_source_info = 0;
-
- TEXT file_name_text;
- text_init (&file_name_text);
- text_append (&file_name_text, "unknown_node");
- if (extension)
- {
- text_append (&file_name_text, ".");
- text_append (&file_name_text, extension);
- }
- file_source_info
- = find_file_source_info (files_source_info,
- file_name_text.text);
- if (!file_source_info)
- {
- file_source_info
- = add_to_files_source_info (files_source_info,
- file_name_text.text, "node", 0,
- root_command, 0);
- node_filename = file_source_info->filename;
- }
- free (file_name_text.text);
- }
- else
- {
- /* Nodes with {'extra'}->{'is_target'} should always be in
- 'identifiers_target', and thus in targets. It is a bug otherwise.
*/
- FILE_SOURCE_INFO *file_source_info = 0;
- HTML_TARGET *node_target
- = find_element_target (self->html_targets,
- root_command);
- node_filename = node_target->node_filename;
-
- file_source_info
- = find_file_source_info (files_source_info,
- node_filename);
- if (file_source_info)
- {
- if (!strcmp (file_source_info->type,
- "stand_in_file"))
- {/* NOTE we keep the order, as in perl */
- set_file_source_info (file_source_info,
- "node",
- 0, root_command, 0);
- }
- }
- else
- add_to_files_source_info (files_source_info,
- node_filename, "node", 0,
- root_command, 0);
- }
- output_unit_file_name
- = add_to_unit_file_name_paths (unit_file_name_paths,
- node_filename,
- file_output_unit);
- break;
- }
- }
- if (!node_filename)
- {
- /* use section to do the file name if there is no node */
- const ELEMENT *command = file_output_unit->uc.unit_command;
- if (command)
- {
- if (command->e.c->cmd == CM_top && !node_top
- && top_node_filename_str)
- {
- /* existing top_node_filename can happen, see
- html_tests.t top_file_name_and_node_name_collision */
- FILE_SOURCE_INFO *file_source_info
- = find_file_source_info (files_source_info,
- top_node_filename_str);
- if (file_source_info)
- {/* NOTE we keep the order, as in perl */
- set_file_source_info (file_source_info,
- "special_file", "Top",
- 0, 0);
- }
- else
- {
- add_to_files_source_info (files_source_info,
- top_node_filename_str,
- "special_file", "Top",
- 0, 0);
- }
- output_unit_file_name
- = add_to_unit_file_name_paths (unit_file_name_paths,
-
top_node_filename_str,
- file_output_unit);
- }
- else
- {
- const HTML_TARGET *section_target
- = find_element_target (self->html_targets,
- command);
- const char *section_filename
- = section_target->section_filename;
-
- FILE_SOURCE_INFO *file_source_info
- = find_file_source_info (files_source_info,
- section_filename);
- if (file_source_info)
- {
- if (!strcmp (file_source_info->type,
- "stand_in_file"))
- {/* NOTE we keep the order, as in perl */
- set_file_source_info (file_source_info,
- "section",
- 0, command, 0);
- }
- }
- else
- add_to_files_source_info (files_source_info,
- section_filename, "section",
0,
- command, 0);
- output_unit_file_name
- = add_to_unit_file_name_paths
(unit_file_name_paths,
- section_filename,
- file_output_unit);
- }
- }
- else
- {
- /* when everything else has failed */
- if (file_nr == 0 && !node_top
- && top_node_filename_str)
- {
- const FILE_SOURCE_INFO *file_source_info
- = find_file_source_info (files_source_info,
- top_node_filename_str);
- if (!file_source_info)
- {
- add_to_files_source_info (files_source_info,
- top_node_filename_str,
- "stand_in_file", "Top",
- 0, 0);
- }
- output_unit_file_name
- = add_to_unit_file_name_paths (unit_file_name_paths,
- top_node_filename_str,
- file_output_unit);
- }
- else
- {
- const FILE_SOURCE_INFO *file_source_info;
-
- TEXT file_name_text;
- text_init (&file_name_text);
- text_printf (&file_name_text, "%s_%zu",
document_name,
- file_nr);
- if (extension)
- {
- text_append (&file_name_text, ".");
- text_append (&file_name_text, extension);
- }
- file_source_info
- = find_file_source_info (files_source_info,
- file_name_text.text);
- if (!file_source_info)
- {
- add_to_files_source_info (files_source_info,
- file_name_text.text,
- "stand_in_file",
- "unknown",
- 0, 0);
- }
- output_unit_file_name
- = add_to_unit_file_name_paths (unit_file_name_paths,
- file_name_text.text,
- file_output_unit);
- free (file_name_text.text);
- }
- file_nr++;
- }
- }
- }
- if (output_unit != file_output_unit)
- add_to_unit_file_name_paths (unit_file_name_paths,
- output_unit_file_name,
- output_unit);
- }
- free (top_node_filename_str);
- }
-
- self->output_unit_file_indices = (size_t *)
- malloc (output_units->number * sizeof (size_t));
-
- for (i = 0; i < output_units->number; i++)
- {
- size_t output_unit_file_idx = 0;
- const FILE_NAME_PATH_COUNTER *output_unit_file;
- OUTPUT_UNIT *output_unit = output_units->list[i];
- char *filename = unit_file_name_paths[i];
- const FILE_SOURCE_INFO *file_source_info
- = find_file_source_info (files_source_info, filename);
- const char *filepath = file_source_info->path;
-
- FILE_NAME_PATH *file_name_path
- = call_file_id_setting_unit_file_name (self, output_unit,
- filename, filepath);
- if (file_name_path)
- {
- if (file_name_path->filename)
- {
- FILE_SOURCE_INFO *file_source_info
- = find_file_source_info (files_source_info,
- file_name_path->filename);
- if (file_source_info)
- {
- /* It is likely that setting different paths for the same file is
- not intended, so we warn. */
- if (file_source_info->path && file_name_path->filepath
- && strcmp (file_source_info->path,
- file_name_path->filepath))
- {
- message_list_document_warn (&self->error_messages,
- self->conf, 0,
- "resetting %s file path %s to %s",
- file_name_path->filename,
- file_source_info->path,
- file_name_path->filepath);
- }
- else if (file_name_path->filepath
- && !file_source_info->path)
- {
- message_list_document_warn (&self->error_messages,
- self->conf, 0,
- "resetting %s file path from a relative path to %s",
- file_name_path->filename,
- file_name_path->filepath);
- }
- else if (!file_name_path->filepath
- && file_source_info->path)
- {
- message_list_document_warn (&self->error_messages,
- self->conf, 0,
- "resetting %s file path from %s to a relative path",
- file_name_path->filename,
- file_source_info->path);
- }
- set_file_source_info (file_source_info, "special_file",
- "user_defined", 0, file_name_path->filepath);
+ if (associated_node)
+ command = associated_node;
}
- else
- add_to_files_source_info (files_source_info,
- file_name_path->filename,
- "special_file", "user_defined",
- 0, file_name_path->filepath);
- free (filename);
- filename = file_name_path->filename;
}
- free (file_name_path->filepath);
- free (file_name_path);
- }
- output_unit_file_idx
- = set_output_unit_file (self, output_unit, filename, 1);
- self->output_unit_file_indices[i] = output_unit_file_idx;
- output_unit_file = &self->output_unit_files.list[output_unit_file_idx];
- if (self->conf->DEBUG.o.integer > 0)
- {
- char *output_unit_text = output_unit_texi (output_unit);
- fprintf (stderr, "Page %s: %s(%d)\n", output_unit_text,
- output_unit->unit_filename, output_unit_file->counter);
- free (output_unit_text);
+ type = HTT_text;
}
- free (filename);
- }
-
- free (unit_file_name_paths);
-
- if (special_units && special_units->number)
- {
- size_t i;
- self->special_unit_file_indices = (size_t *)
- malloc (special_units->number * sizeof (size_t));
- for (i = 0; i < special_units->number; i++)
+ else if (type == HTT_section)
{
- size_t special_unit_file_idx = 0;
- const FILE_NAME_PATH_COUNTER *special_unit_file;
- OUTPUT_UNIT *special_unit = special_units->list[i];
- const ELEMENT *unit_command = special_unit->uc.special_unit_command;
- const HTML_TARGET *special_unit_target
- = find_element_target (self->html_targets, unit_command);
- const char *filename = special_unit_target->special_unit_filename;
-
- /* Associate the special elements that have no page with the main page.
- This may only happen if not split. */
- if (!filename && special_units->number
- && output_units->list[0]->unit_filename)
- {
- filename = output_units->list[0]->unit_filename;
- }
-
- if (filename)
+ if (target_unit->unit_type == OU_unit &&
target_unit->uc.unit_command)
{
- FILE_SOURCE_INFO *file_source_info
- = find_file_source_info (files_source_info, filename);
- if (file_source_info)
+ const ELEMENT *target_command = target_unit->uc.unit_command;
+ if (target_command->e.c->cmd != CM_node)
+ command = target_command;
+ else
{
- if (!strcmp (file_source_info->type, "stand_in_file"))
- {/* NOTE we keep the order, as in perl */
- set_file_source_info (file_source_info, "special_unit",
- 0, unit_command, 0);
- }
+ const ELEMENT *associated_section
+ = lookup_extra_element (target_command,
+ AI_key_associated_section);
+ if (associated_section)
+ command = associated_section;
}
+ }
+ type = HTT_text_nonumber;
+ }
+ else
+ {
+ if (target_unit->unit_type == OU_special_unit)
+ command = target_unit->uc.special_unit_command;
+ else
+ command = target_unit->uc.unit_command;
+ if (type == HTT_href)
+ {
+ if (command)
+ return html_command_href (self, command,
+ filename_from, 0, 0);
else
- add_to_files_source_info (files_source_info, filename,
- "special_unit", 0, unit_command, 0);
+ return 0;
}
- special_unit_file_idx
- = set_output_unit_file (self, special_unit, filename, 1);
- self->special_unit_file_indices[i] = special_unit_file_idx;
- special_unit_file
- = &self->output_unit_files.list[special_unit_file_idx];
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "Special page: %s(%d)\n", filename,
- special_unit_file->counter);
}
}
+ else
+ return 0;
- for (i = 0; i < files_source_info->number; i++)
- {
- FILE_SOURCE_INFO *file_source_info = &files_source_info->list[i];
- set_file_path (self, file_source_info->filename, file_source_info->path,
- destination_directory);
- }
+ if (command)
+ return html_command_text (self, command, type);
/*
- to be able to associate to the output unit file the associated
- output units will be output into, this is done after document output
- units got files.
- In practice only used for contents and shortcontents.
+ We end up here if there is a target element, but not of the expected
+ 'type'. For example, if type is section but there is no section associated
+ to the target element node.
*/
- if (associated_special_units && associated_special_units->number > 0)
- {
- size_t i;
- for (i = 0; i < associated_special_units->number; i++)
- {
- const char *filename = 0;
- OUTPUT_UNIT *special_unit = associated_special_units->list[i];
- const OUTPUT_UNIT *associated_output_unit
- = special_unit->associated_document_unit;
- const ELEMENT *unit_command = special_unit->uc.special_unit_command;
- HTML_TARGET *element_target
- = find_element_target (self->html_targets, unit_command);
-
- if (!element_target->special_unit_filename)
- {/* set the file if not already set */
- char *unit_filename = 0;
- if (associated_output_unit)
- unit_filename = strdup (associated_output_unit->unit_filename);
- element_target->special_unit_filename = unit_filename;
- }
- filename = element_target->special_unit_filename;
-
- /* set here the file name, but do not increment the counter as it is
- already set for the output unit the special output unit is in. */
- if (filename)
- set_output_unit_file (self, special_unit, filename, 0);
- }
- }
-
- /* 0 is for document_global_context_css, the remaining indices
- for the output unit files */
- self->page_css.number = self->output_unit_files.number +1;
- self->page_css.space = self->page_css.number;
- self->page_css.list = (CSS_LIST *)
- malloc (self->page_css.space * sizeof (CSS_LIST));
- memset (self->page_css.list, 0,
- self->page_css.number * sizeof (CSS_LIST));
-
- self->html_files_information.number = self->output_unit_files.number +1;
- self->html_files_information.list = (FILE_ASSOCIATED_INFO *)
- malloc (self->html_files_information.number * sizeof
(FILE_ASSOCIATED_INFO));
- memset (self->html_files_information.list, 0,
- self->html_files_information.number * sizeof (FILE_ASSOCIATED_INFO));
-
- self->pending_closes.number = self->output_unit_files.number +1;
- self->pending_closes.list = (STRING_STACK *)
- malloc (self->pending_closes.number * sizeof (STRING_STACK));
- memset (self->pending_closes.list, 0,
- self->pending_closes.number * sizeof (STRING_STACK));
-
- return files_source_info;
+ return 0;
}
-/* setup a page (+global context) in case there are no files, ie called
- with convert or output with an empty string as filename. */
-void
-setup_output_simple_page (CONVERTER *self, const char *output_filename)
+static void
+add_new_css_page (PAGES_CSS_LIST *css_pages, const char *page_name)
{
- PAGE_NAME_NUMBER *page_name_number;
- self->page_css.number = 1+1;
- self->page_css.space = self->page_css.number;
- self->page_css.list = (CSS_LIST *)
- malloc (self->page_css.space * sizeof (CSS_LIST));
- memset (self->page_css.list, 0,
- self->page_css.number * sizeof (CSS_LIST));
-
- self->html_files_information.number = 1+1;
- self->html_files_information.list = (FILE_ASSOCIATED_INFO *)
- malloc (self->html_files_information.number
- * sizeof (FILE_ASSOCIATED_INFO));
- memset (self->html_files_information.list, 0,
- self->html_files_information.number * sizeof (FILE_ASSOCIATED_INFO));
-
- self->pending_closes.number = 1+1;
- self->pending_closes.list = (STRING_STACK *)
- malloc (self->pending_closes.number * sizeof (STRING_STACK));
- memset (self->pending_closes.list, 0,
- self->pending_closes.number * sizeof (STRING_STACK));
+ CSS_LIST *page_css_list;
+ if (css_pages->space <= css_pages->number)
+ {
+ css_pages->list = realloc (css_pages->list,
+ (css_pages->space += 10) * sizeof (CSS_LIST));
+ }
- self->page_name_number.number = 1;
- self->page_name_number.list = (PAGE_NAME_NUMBER *)
- malloc (self->page_name_number.number * sizeof (PAGE_NAME_NUMBER));
+ page_css_list = &css_pages->list[css_pages->number];
+ memset (page_css_list, 0, sizeof (CSS_LIST));
+ page_css_list->page_name = strdup (page_name);
- page_name_number = &self->page_name_number.list[0];
- page_name_number->number = 1;
- page_name_number->page_name = output_filename;
+ css_pages->number++;
}
static void
-prepare_special_units_directions (CONVERTER *self,
- OUTPUT_UNIT_LIST *special_units)
+collect_css_element_class (CONVERTER *self, const char *selector)
{
- size_t i;
-
- if (!special_units)
- return;
-
- for (i = 0; i < special_units->number; i++)
+ const CSS_SELECTOR_STYLE *selector_style
+ = find_css_selector_style (&self->css_element_class_styles, selector);
+ if (selector_style)
{
- OUTPUT_UNIT *special_unit = special_units->list[i];
- special_unit->directions[RUD_type_This] = special_unit;
+ size_t i;
+ size_t css_files_index;
+ CSS_LIST *page_css_list;
+ if (self->document_global_context)
+ {
+ css_files_index = 0;
+ }
+ else
+ {
+ css_files_index = self->current_filename.file_number;
+ /* files not associated to output units. Only try the
+ last one, as the files should be processed sequentially */
+ if (css_files_index == 0)
+ {
+ if (self->current_filename.filename)
+ {
+ if (self->page_css.number > 1)
+ {
+ CSS_LIST *last_css_page
+ = &self->page_css.list[self->page_css.number -1];
+ if (last_css_page->page_name
+ && !strcmp (self->current_filename.filename,
+ last_css_page->page_name))
+ {
+ css_files_index = self->page_css.number -1;
+ }
+ }
+ if (css_files_index == 0)
+ {
+ add_new_css_page (&self->page_css,
+ self->current_filename.filename);
+ css_files_index = self->page_css.number -1;
+ }
+ }
+ }
+ if (css_files_index == 0)
+ {
+ fprintf (stderr, "BUG: %s: CSS no current file\n", selector);
+ return;
+ }
+ }
+ page_css_list = &self->page_css.list[css_files_index];
+ for (i = 0; i < page_css_list->number; i++)
+ {
+ if (!strcmp (page_css_list->list[i], selector))
+ return;
+ }
+ if (page_css_list->number == page_css_list->space)
+ {
+ page_css_list->list
+ = realloc (page_css_list->list,
+ (page_css_list->space += 5) * sizeof (char *));
+ }
+ page_css_list->list[page_css_list->number] = strdup (selector);
+ page_css_list->number++;
}
}
-/* Return structure to be freed by the caller */
-FILE_SOURCE_INFO_LIST *
-html_prepare_units_directions_files (CONVERTER *self,
- const char *output_file, const char *destination_directory,
- const char *output_filename, const char *document_name)
+void
+close_html_lone_element (const CONVERTER *self, TEXT *result)
{
- size_t i;
- FILE_SOURCE_INFO_LIST *files_source_info = 0;
- size_t external_nodes_units_descriptor
- = new_output_units_descriptor (self->document);
- OUTPUT_UNIT_LIST *external_node_target_units
- = retrieve_output_units (self->document, external_nodes_units_descriptor);
- OUTPUT_UNIT_LIST *output_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_units]);
- OUTPUT_UNIT_LIST *special_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_special_units]);
- OUTPUT_UNIT_LIST *associated_special_units = retrieve_output_units
- (self->document,
- self->output_units_descriptors[OUDT_associated_special_units]);
-
- self->output_units_descriptors[OUDT_external_nodes_units]
- = external_nodes_units_descriptor;
-
- html_prepare_output_units_global_targets (self);
-
- split_pages (output_units, self->conf->SPLIT.o.string);
-
- if (strlen (output_file))
- {
- files_source_info =
- html_set_pages_files (self, output_units, special_units,
- associated_special_units, output_file,
- destination_directory, output_filename, document_name);
- }
+ if (self->conf->USE_XML_SYNTAX.o.integer > 0)
+ text_append_n (result, "/>", 2);
else
- setup_output_simple_page (self, output_filename);
-
- units_directions (&self->document->identifiers_target, output_units,
- external_node_target_units,
- self->conf->DEBUG.o.integer);
-
- prepare_special_units_directions (self, special_units);
-
- units_file_directions (output_units);
+ text_append_n (result, ">", 1);
+}
- /* elements_in_file_count is only set in HTML, not in
- Texinfo::Convert::Converter */
- if (self->output_unit_files.number)
+static char *
+protect_class_name (const char *class_name)
+{
+ TEXT result;
+ TEXT space_protected;
+ text_init (&result);
+ text_init (&space_protected);
+ const char *p = class_name;
+ while (*p)
{
- /* set elements_in_file_count and prepare page_name_number
- for sorting */
- self->page_name_number.number = self->output_unit_files.number;
- self->page_name_number.list = (PAGE_NAME_NUMBER *)
- malloc (self->page_name_number.number * sizeof (PAGE_NAME_NUMBER));
-
- for (i = 0; i < self->output_unit_files.number; i++)
+ int n = strcspn (p, " ");
+ if (n)
{
- FILE_NAME_PATH_COUNTER *file_counter
- = &self->output_unit_files.list[i];
- PAGE_NAME_NUMBER *page_name_number = &self->page_name_number.list[i];
-
- /* counter is dynamic, decreased when the element is encountered
- elements_in_file_count is not modified afterwards */
- file_counter->elements_in_file_count = file_counter->counter;
-
- page_name_number->number = i+1;
- page_name_number->page_name = file_counter->filename;
+ text_append_n (&space_protected, p, n);
+ p += n;
+ }
+ if (*p)
+ {
+ int n = strspn (p, " ");
+ if (n)
+ {
+ int i;
+ for (i = 0; i < n; i++)
+ text_append_n (&space_protected, "-", 1);
+ p += n;
+ }
}
-
- qsort (self->page_name_number.list,
- self->page_name_number.number,
- sizeof (PAGE_NAME_NUMBER), compare_page_name_number);
}
- return files_source_info;
+ /* do not use the customization API as in perl */
+ html_default_format_protect_text (space_protected.text, &result);
+ free (space_protected.text);
+ return result.text;
}
char *
@@ -12646,7 +11782,7 @@ html_convert_menu_entry_type (CONVERTER *self, const
enum element_type type,
{
/* update the number of time the node description was formatted */
HTML_TARGET *target_info
- = find_element_target (self->html_targets, node);
+ = html_get_target (self, node);
target_info->formatted_nodedescription_nr++;
formatted_nodedescription_nr
= target_info->formatted_nodedescription_nr;
@@ -14655,6 +13791,34 @@ clear_type_explanations (EXPLAINED_COMMAND_TYPE_LIST
*type_explanations)
}
}
+void
+html_reset_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info)
+{
+ size_t i;
+ for (i = 0; i < files_source_info->number; i++)
+ {
+ free (files_source_info->list[i].filename);
+ free (files_source_info->list[i].path);
+ }
+ files_source_info->number = 0;
+}
+
+void
+html_free_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info)
+{
+ html_reset_files_source_info (files_source_info);
+ free (files_source_info->list);
+ files_source_info->list = 0;
+ files_source_info->space = 0;
+}
+
+void
+html_destroy_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info)
+{
+ html_free_files_source_info (files_source_info);
+ free (files_source_info);
+}
+
void
html_reset_converter (CONVERTER *self)
{
@@ -15188,7 +14352,7 @@ html_translate_names (CONVERTER *self)
if (command)
{
HTML_TARGET *target_info
- = find_element_target (self->html_targets, command);
+ = html_get_target (self, command);
if (target_info)
{
/* the tree is a reference to special_unit_info_tree, so it should
@@ -16237,7 +15401,7 @@ html_prepare_title_titlepage (CONVERTER *self, const
char *output_file,
{
/* case of convert() call. Need to setup the page here */
if (self->page_name_number.number <= 0)
- setup_output_simple_page (self, output_filename);
+ html_setup_output_simple_page (self, output_filename);
self->current_filename.filename = output_filename;
self->current_filename.file_number = 1;
}
@@ -16883,8 +16047,8 @@ html_node_redirections (CONVERTER *self,
= output_unit_file->elements_in_file_count;
FILE_SOURCE_INFO *file_source_info
- = find_file_source_info (files_source_info,
- redirection_filename);
+ = html_find_file_source_info (files_source_info,
+ redirection_filename);
if (file_source_info
/* first condition finds conflict with tree elements */
&& (redirection_filename_total_count > 0
@@ -16990,7 +16154,7 @@ html_node_redirections (CONVERTER *self,
int overwritten_file;
int status;
- add_to_files_source_info (files_source_info,
+ html_add_to_files_source_info (files_source_info,
redirection_filename, "redirection", 0,
target_element, 0);
diff --git a/tp/Texinfo/XS/convert/convert_html.h
b/tp/Texinfo/XS/convert/convert_html.h
index 72c5a63c6d..a3d3eafcac 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -47,6 +47,12 @@ extern COMMAND_ID_LIST no_arg_formatted_cmd;
void html_conversion_finalization (CONVERTER *self);
+int html_id_is_registered (CONVERTER *self, const char *string);
+void html_register_id (CONVERTER *self, const char *string);
+
+OUTPUT_UNIT *html_get_top_unit (DOCUMENT *document,
+ const OUTPUT_UNIT_LIST *output_units);
+
ROOT_AND_UNIT *html_get_tree_root_element (CONVERTER *self,
const ELEMENT *command,
int find_container);
@@ -54,6 +60,27 @@ ROOT_AND_UNIT *html_get_tree_root_element (CONVERTER *self,
char *html_after_escaped_characters (char *text);
char *html_substitute_non_breaking_space (CONVERTER *self, const char *text);
+HTML_TARGET *html_get_target (const CONVERTER *self, const ELEMENT *element);
+
+void html_set_file_source_info (FILE_SOURCE_INFO *file_source_info,
+ const char *file_info_type,
+ const char *file_info_name,
+ const ELEMENT *file_info_element,
+ const char *filepath);
+FILE_SOURCE_INFO *html_add_to_files_source_info (
+ FILE_SOURCE_INFO_LIST *files_source_info,
+ const char *filename,
+ const char *file_info_type,
+ const char *file_info_name,
+ const ELEMENT *file_info_element,
+ const char *filepath);
+FILE_SOURCE_INFO *html_find_file_source_info (
+ FILE_SOURCE_INFO_LIST *files_source_info,
+ const char *filename);
+
+void html_setup_output_simple_page (CONVERTER *self,
+ const char *output_filename);
+
const char *html_special_unit_info (const CONVERTER *self,
enum special_unit_info_type type,
const char *special_unit_variety);
@@ -82,13 +109,9 @@ SPECIAL_UNIT_INFO *html_add_special_unit_info (
SPECIAL_UNIT_INFO_LIST *special_unit_info_list,
int type, size_t variety_nr, const char *value);
-int html_id_is_registered (CONVERTER *self, const char *string);
-void html_register_id (CONVERTER *self, const char *string);
-
int html_special_unit_variety_direction_index (const CONVERTER *self,
const char *special_unit_variety);
-HTML_TARGET *html_get_target (const CONVERTER *self, const ELEMENT *element);
const char *html_command_id (const CONVERTER *self, const ELEMENT *command);
const char *html_command_contents_target (CONVERTER *self,
const ELEMENT *command,
@@ -123,10 +146,6 @@ FOOTNOTE_ID_NUMBER *find_footnote_id_number (const
CONVERTER *self,
char *html_attribute_class (CONVERTER *self, const char *element,
const STRING_LIST *classes);
-FILE_SOURCE_INFO_LIST * html_prepare_units_directions_files (CONVERTER *self,
- const char *output_file, const char *destination_directory,
- const char *output_filename, const char *document_name);
-
void
html_command_conversion_external (CONVERTER *self, const enum command_id cmd,
diff --git a/tp/Texinfo/XS/convert/html_prepare_converter.c
b/tp/Texinfo/XS/convert/html_prepare_converter.c
index 63669ed549..c1d4bbb80d 100644
--- a/tp/Texinfo/XS/convert/html_prepare_converter.c
+++ b/tp/Texinfo/XS/convert/html_prepare_converter.c
@@ -29,14 +29,15 @@
#include "conversion_data.h"
/* new_element */
#include "tree.h"
-#include "extra.h"
-#include "utils.h"
#include "errors.h"
-/* unicode_character_brace_no_arg_commands */
-#include "unicode.h"
#include "builtin_commands.h"
#include "command_stack.h"
+#include "utils.h"
#include "customization_options.h"
+#include "extra.h"
+#include "targets.h"
+/* unicode_character_brace_no_arg_commands */
+#include "unicode.h"
#include "convert_to_texinfo.h"
#include "node_name_normalization.h"
#include "manipulate_indices.h"
@@ -3814,3 +3815,825 @@ html_prepare_conversion_units_targets (CONVERTER *self,
sort_cmd_targets (self);
}
+
+
+/* Associate output units to the global targets, First, Last, Top, Index.
+ and special output units */
+void
+html_prepare_output_units_global_targets (CONVERTER *self)
+{
+ int i;
+ int all_special_units_nr = 0;
+ int s;
+ const OUTPUT_UNIT_LIST *output_units = retrieve_output_units
+ (self->document, self->output_units_descriptors[OUDT_units]);
+
+ const OUTPUT_UNIT *top_output_unit = html_get_top_unit (self->document,
+ output_units);
+
+ size_t special_output_units_lists[2] = {
+ self->output_units_descriptors[OUDT_special_units],
+ self->output_units_descriptors[OUDT_associated_special_units]};
+
+ self->global_units_directions[D_First] = output_units->list[0];
+ self->global_units_directions[D_Last]
+ = output_units->list[output_units->number - 1];
+
+ self->global_units_directions[D_Top] = top_output_unit;
+
+ /* It is always the first printindex, even if it is not output (for example
+ it is in @copying and @titlepage, which are certainly wrong constructs).
+ */
+ if (self->document->global_commands.printindex.number > 0)
+ {
+ const ELEMENT *printindex
+ = self->document->global_commands.printindex.list[0];
+ ROOT_AND_UNIT *root_unit
+ = html_get_tree_root_element (self, printindex, 0);
+ if (root_unit->output_unit)
+ {
+ const OUTPUT_UNIT *document_unit = root_unit->output_unit;
+ const ELEMENT *root_command = root_unit->root;
+ if (root_command && root_command->e.c->cmd == CM_node)
+ {
+ const ELEMENT *associated_section
+ = lookup_extra_element (root_command,
+ AI_key_associated_section);
+ if (associated_section)
+ root_command = associated_section;
+ }
+ /* find the first level 1 sectioning element to associate the printindex
+ with */
+ if (root_command && root_command->e.c->cmd != CM_node)
+ {
+ while (1)
+ {
+ int status;
+ int section_level
+ = lookup_extra_integer (root_command, AI_key_section_level,
+ &status);
+ if (!status && section_level <= 1)
+ break;
+
+ const ELEMENT * const *up_section_directions
+ = lookup_extra_directions (root_command,
+ AI_key_section_directions);
+ if (up_section_directions
+ && up_section_directions[D_up]
+ && up_section_directions[D_up]
+ ->e.c->associated_unit)
+ {
+ root_command = up_section_directions[D_up];
+ document_unit = root_command->e.c->associated_unit;
+ }
+ else
+ break;
+ }
+ }
+ self->global_units_directions[D_Index] = document_unit;
+ }
+ free (root_unit);
+ }
+
+ if (self->conf->DEBUG.o.integer > 0)
+ {
+ int i;
+ fprintf (stderr, "GLOBAL DIRECTIONS:\n");
+ for (i = 0; i < D_Last+1; i++)
+ {
+ if (self->global_units_directions[i])
+ {
+ const OUTPUT_UNIT *global_unit =
self->global_units_directions[i];
+ char *unit_texi = output_unit_texi (global_unit);
+ fprintf (stderr, " %s: %s\n",
html_global_unit_direction_names[i],
+ unit_texi);
+ free (unit_texi);
+ }
+ }
+ fprintf (stderr, "\n");
+ }
+
+ /* determine total number of special output units and fill
+ special_units_directions_name_unit. Used to simplify building perl
+ directions */
+ for (i = 0; i < 2; i++)
+ {
+ size_t special_units_descriptor = special_output_units_lists[i];
+ const OUTPUT_UNIT_LIST *units_list
+ = retrieve_output_units (self->document, special_units_descriptor);
+ if (units_list && units_list->number)
+ all_special_units_nr += units_list->number;
+ }
+
+ self->special_units_direction_name = (SPECIAL_UNIT_DIRECTION *)
+ malloc (sizeof (SPECIAL_UNIT_DIRECTION) * (all_special_units_nr+1));
+ memset (self->special_units_direction_name, 0,
+ sizeof (SPECIAL_UNIT_DIRECTION) * (all_special_units_nr+1));
+
+ s = 0;
+ for (i = 0; i < 2; i++)
+ {
+ size_t special_units_descriptor = special_output_units_lists[i];
+ const OUTPUT_UNIT_LIST *units_list
+ = retrieve_output_units (self->document, special_units_descriptor);
+ if (units_list && units_list->number)
+ {
+ size_t j;
+ for (j = 0; j < units_list->number; j++)
+ {
+ const OUTPUT_UNIT *special_unit = units_list->list[j];
+ const char *special_unit_variety =
special_unit->special_unit_variety;
+ int special_unit_direction_index
+ = html_special_unit_variety_direction_index (self,
+ special_unit_variety);
+ self->global_units_directions[special_unit_direction_index]
+ = special_unit;
+
+ self->special_units_direction_name[s].output_unit = special_unit;
+ self->special_units_direction_name[s].direction
+ = html_special_unit_info (self, SUI_type_direction,
+ special_unit_variety);
+ s++;
+ }
+ }
+ }
+}
+
+static int
+compare_global_units_direction_name (const void *a, const void *b)
+{
+ const SPECIAL_UNIT_DIRECTION *gudn_a = (const SPECIAL_UNIT_DIRECTION *) a;
+ const SPECIAL_UNIT_DIRECTION *gudn_b = (const SPECIAL_UNIT_DIRECTION *) b;
+
+ return strcmp (gudn_a->direction, gudn_b->direction);
+}
+
+/* To find more easily a global output unit based on a direction name, for an
+ XS interface, associate global output units to names and sort according
+ to names */
+void
+html_setup_global_units_direction_names (CONVERTER *self)
+{
+ SPECIAL_UNIT_DIRECTION *global_units_direction_names;
+ int i;
+ int global_directions_nr = 0;
+ int global_units_direction_idx = 0;
+ const SPECIAL_UNIT_DIRECTION *special_units_direction_name
+ = self->special_units_direction_name;
+
+ for (i = 0; i < D_Last+1; i++)
+ if (self->global_units_directions[i])
+ global_directions_nr++;
+
+ for (i = 0; special_units_direction_name[i].output_unit; i++)
+ global_directions_nr++;
+
+ global_units_direction_names = (SPECIAL_UNIT_DIRECTION *)
+ malloc (sizeof (SPECIAL_UNIT_DIRECTION) * (global_directions_nr));
+
+ for (i = 0; i < D_Last+1; i++)
+ {
+ if (self->global_units_directions[i])
+ {
+ global_units_direction_names[global_units_direction_idx].direction
+ = html_global_unit_direction_names[i];
+ global_units_direction_names[global_units_direction_idx].output_unit
+ = self->global_units_directions[i];
+ global_units_direction_idx++;
+ }
+ }
+
+ for (i = 0; special_units_direction_name[i].output_unit; i++)
+ {
+ global_units_direction_names[global_units_direction_idx].direction
+ = special_units_direction_name[i].direction;
+ global_units_direction_names[global_units_direction_idx].output_unit
+ = special_units_direction_name[i].output_unit;
+ global_units_direction_idx++;
+ }
+
+ qsort (global_units_direction_names,
+ global_directions_nr,
+ sizeof (SPECIAL_UNIT_DIRECTION), compare_global_units_direction_name);
+
+ self->global_units_direction_name.list = global_units_direction_names;
+ self->global_units_direction_name.number = global_directions_nr;
+}
+
+/* Used from Perl through an XS override, in similar C codes the
+ direction indices are used instead of the direction names */
+const OUTPUT_UNIT *
+html_find_direction_name_global_unit (const CONVERTER *self,
+ const char *direction_name)
+{
+ SPECIAL_UNIT_DIRECTION *result = 0;
+ static SPECIAL_UNIT_DIRECTION searched_direction;
+
+ searched_direction.direction = direction_name;
+ result = (SPECIAL_UNIT_DIRECTION *) bsearch (&searched_direction,
+ self->global_units_direction_name.list,
+ self->global_units_direction_name.number,
+ sizeof (SPECIAL_UNIT_DIRECTION),
+ compare_global_units_direction_name);
+ if (!result)
+ return 0;
+ return result->output_unit;
+}
+
+
+static char *
+add_to_unit_file_name_paths (char **unit_file_name_paths,
+ const char *filename,
+ const OUTPUT_UNIT *output_unit)
+{
+ unit_file_name_paths[output_unit->index] = strdup (filename);
+
+ return unit_file_name_paths[output_unit->index];
+}
+
+/* calls customization function requiring output units */
+static FILE_SOURCE_INFO_LIST *
+html_set_pages_files (CONVERTER *self, const OUTPUT_UNIT_LIST *output_units,
+ const OUTPUT_UNIT_LIST *special_units,
+ const OUTPUT_UNIT_LIST *associated_special_units,
+ const char *output_file,
+ const char *destination_directory, const char
*output_filename,
+ const char *document_name)
+{
+ FILE_SOURCE_INFO_LIST *files_source_info;
+ char **unit_file_name_paths;
+ size_t i;
+
+ initialize_output_units_files (self);
+
+ files_source_info = &self->files_source_info;
+
+ unit_file_name_paths = (char **)
+ malloc (output_units->number * sizeof (char *));
+ memset (unit_file_name_paths, 0,
+ output_units->number * sizeof (char *));
+
+ if (!self->conf->SPLIT.o.string || !strlen (self->conf->SPLIT.o.string))
+ {
+ size_t i;
+ html_add_to_files_source_info (files_source_info, output_filename,
+ "special_file", "non_split", 0,
+ output_file);
+ for (i = 0; i < output_units->number; i++)
+ {
+ add_to_unit_file_name_paths (unit_file_name_paths,
+ output_filename,
+ output_units->list[i]);
+ }
+ }
+ else
+ {
+ char *top_node_filename_str;
+ const OUTPUT_UNIT *node_top_output_unit = 0;
+ const char *extension = 0;
+ const ELEMENT *node_top = 0;
+ size_t file_nr = 0;
+ size_t i;
+
+ /* first determine the top node file name. */
+ if (self->document->identifiers_target.number > 0)
+ node_top = find_identifier_target (&self->document->identifiers_target,
+ "Top");
+
+ top_node_filename_str = top_node_filename (self, document_name);
+
+ if (node_top && top_node_filename_str)
+ {
+ size_t i;
+ node_top_output_unit = node_top->e.c->associated_unit;
+ for (i = 0; i < output_units->number; i++)
+ if (output_units->list[i] == node_top_output_unit)
+ break;
+ html_add_to_files_source_info (files_source_info,
+ top_node_filename_str,
+ "special_file", "Top", 0, 0);
+ add_to_unit_file_name_paths (unit_file_name_paths,
+ top_node_filename_str,
+ node_top_output_unit);
+ }
+
+ if (self->conf->EXTENSION.o.string
+ && strlen (self->conf->EXTENSION.o.string))
+ extension = self->conf->EXTENSION.o.string;
+
+ for (i = 0; i < output_units->number; i++)
+ {
+ const OUTPUT_UNIT *output_unit = output_units->list[i];
+ const OUTPUT_UNIT *file_output_unit;
+ const char *output_unit_file_name;
+ /* For Top node. */
+ if (node_top_output_unit && node_top_output_unit == output_unit)
+ continue;
+
+ file_output_unit = output_unit->first_in_page;
+ output_unit_file_name
+ = unit_file_name_paths[file_output_unit->index];
+ if (!output_unit_file_name)
+ {
+ const char *node_filename = 0;
+ size_t j;
+ for (j = 0; j < file_output_unit->unit_contents.number; j++)
+ {
+ const ELEMENT *root_command
+ = file_output_unit->unit_contents.list[j];
+ if (root_command->e.c->cmd == CM_node)
+ {
+ const ELEMENT *node_target = 0;
+ const char *normalized = lookup_extra_string
(root_command,
+
AI_key_normalized);
+ if (normalized)
+ node_target
+ = find_identifier_target (
+ &self->document->identifiers_target,
+ normalized);
+ /* double node are not normalized, they are handled here */
+ if (!node_target)
+ {
+ const FILE_SOURCE_INFO *file_source_info = 0;
+
+ TEXT file_name_text;
+ text_init (&file_name_text);
+ text_append (&file_name_text, "unknown_node");
+ if (extension)
+ {
+ text_append (&file_name_text, ".");
+ text_append (&file_name_text, extension);
+ }
+ file_source_info
+ = html_find_file_source_info (files_source_info,
+ file_name_text.text);
+ if (!file_source_info)
+ {
+ file_source_info
+ = html_add_to_files_source_info (
+ files_source_info,
+ file_name_text.text, "node", 0,
+ root_command, 0);
+ node_filename = file_source_info->filename;
+ }
+ free (file_name_text.text);
+ }
+ else
+ {
+ /* Nodes with {'extra'}->{'is_target'} should always be in
+ 'identifiers_target', and thus in targets. It is a bug otherwise.
*/
+ FILE_SOURCE_INFO *file_source_info = 0;
+ HTML_TARGET *node_target
+ = html_get_target (self, root_command);
+ node_filename = node_target->node_filename;
+
+ file_source_info
+ = html_find_file_source_info (files_source_info,
+ node_filename);
+ if (file_source_info)
+ {
+ if (!strcmp (file_source_info->type,
+ "stand_in_file"))
+ {/* NOTE we keep the order, as in perl */
+ html_set_file_source_info (file_source_info,
+ "node",
+ 0, root_command, 0);
+ }
+ }
+ else
+ html_add_to_files_source_info (files_source_info,
+ node_filename, "node", 0,
+ root_command, 0);
+ }
+ output_unit_file_name
+ = add_to_unit_file_name_paths (unit_file_name_paths,
+ node_filename,
+ file_output_unit);
+ break;
+ }
+ }
+ if (!node_filename)
+ {
+ /* use section to do the file name if there is no node */
+ const ELEMENT *command = file_output_unit->uc.unit_command;
+ if (command)
+ {
+ if (command->e.c->cmd == CM_top && !node_top
+ && top_node_filename_str)
+ {
+ /* existing top_node_filename can happen, see
+ html_tests.t top_file_name_and_node_name_collision */
+ FILE_SOURCE_INFO *file_source_info
+ = html_find_file_source_info (files_source_info,
+ top_node_filename_str);
+ if (file_source_info)
+ {/* NOTE we keep the order, as in perl */
+ html_set_file_source_info (file_source_info,
+ "special_file", "Top",
+ 0, 0);
+ }
+ else
+ {
+ html_add_to_files_source_info (files_source_info,
+ top_node_filename_str,
+ "special_file", "Top",
+ 0, 0);
+ }
+ output_unit_file_name
+ = add_to_unit_file_name_paths (unit_file_name_paths,
+
top_node_filename_str,
+ file_output_unit);
+ }
+ else
+ {
+ const HTML_TARGET *section_target
+ = html_get_target (self, command);
+ const char *section_filename
+ = section_target->section_filename;
+
+ FILE_SOURCE_INFO *file_source_info
+ = html_find_file_source_info (files_source_info,
+ section_filename);
+ if (file_source_info)
+ {
+ if (!strcmp (file_source_info->type,
+ "stand_in_file"))
+ {/* NOTE we keep the order, as in perl */
+ html_set_file_source_info (file_source_info,
+ "section",
+ 0, command, 0);
+ }
+ }
+ else
+ html_add_to_files_source_info (files_source_info,
+ section_filename, "section",
0,
+ command, 0);
+ output_unit_file_name
+ = add_to_unit_file_name_paths
(unit_file_name_paths,
+ section_filename,
+ file_output_unit);
+ }
+ }
+ else
+ {
+ /* when everything else has failed */
+ if (file_nr == 0 && !node_top
+ && top_node_filename_str)
+ {
+ const FILE_SOURCE_INFO *file_source_info
+ = html_find_file_source_info (files_source_info,
+ top_node_filename_str);
+ if (!file_source_info)
+ {
+ html_add_to_files_source_info (files_source_info,
+ top_node_filename_str,
+ "stand_in_file", "Top",
+ 0, 0);
+ }
+ output_unit_file_name
+ = add_to_unit_file_name_paths (unit_file_name_paths,
+ top_node_filename_str,
+ file_output_unit);
+ }
+ else
+ {
+ const FILE_SOURCE_INFO *file_source_info;
+
+ TEXT file_name_text;
+ text_init (&file_name_text);
+ text_printf (&file_name_text, "%s_%zu",
document_name,
+ file_nr);
+ if (extension)
+ {
+ text_append (&file_name_text, ".");
+ text_append (&file_name_text, extension);
+ }
+ file_source_info
+ = html_find_file_source_info (files_source_info,
+ file_name_text.text);
+ if (!file_source_info)
+ {
+ html_add_to_files_source_info (files_source_info,
+ file_name_text.text,
+ "stand_in_file",
+ "unknown",
+ 0, 0);
+ }
+ output_unit_file_name
+ = add_to_unit_file_name_paths (unit_file_name_paths,
+ file_name_text.text,
+ file_output_unit);
+ free (file_name_text.text);
+ }
+ file_nr++;
+ }
+ }
+ }
+ if (output_unit != file_output_unit)
+ add_to_unit_file_name_paths (unit_file_name_paths,
+ output_unit_file_name,
+ output_unit);
+ }
+ free (top_node_filename_str);
+ }
+
+ self->output_unit_file_indices = (size_t *)
+ malloc (output_units->number * sizeof (size_t));
+
+ for (i = 0; i < output_units->number; i++)
+ {
+ size_t output_unit_file_idx = 0;
+ const FILE_NAME_PATH_COUNTER *output_unit_file;
+ OUTPUT_UNIT *output_unit = output_units->list[i];
+ char *filename = unit_file_name_paths[i];
+ const FILE_SOURCE_INFO *file_source_info
+ = html_find_file_source_info (files_source_info, filename);
+ const char *filepath = file_source_info->path;
+
+ FILE_NAME_PATH *file_name_path
+ = call_file_id_setting_unit_file_name (self, output_unit,
+ filename, filepath);
+ if (file_name_path)
+ {
+ if (file_name_path->filename)
+ {
+ FILE_SOURCE_INFO *file_source_info
+ = html_find_file_source_info (files_source_info,
+ file_name_path->filename);
+ if (file_source_info)
+ {
+ /* It is likely that setting different paths for the same file is
+ not intended, so we warn. */
+ if (file_source_info->path && file_name_path->filepath
+ && strcmp (file_source_info->path,
+ file_name_path->filepath))
+ {
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0,
+ "resetting %s file path %s to %s",
+ file_name_path->filename,
+ file_source_info->path,
+ file_name_path->filepath);
+ }
+ else if (file_name_path->filepath
+ && !file_source_info->path)
+ {
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0,
+ "resetting %s file path from a relative path to %s",
+ file_name_path->filename,
+ file_name_path->filepath);
+ }
+ else if (!file_name_path->filepath
+ && file_source_info->path)
+ {
+ message_list_document_warn (&self->error_messages,
+ self->conf, 0,
+ "resetting %s file path from %s to a relative path",
+ file_name_path->filename,
+ file_source_info->path);
+ }
+ html_set_file_source_info (file_source_info, "special_file",
+ "user_defined", 0, file_name_path->filepath);
+ }
+ else
+ html_add_to_files_source_info (files_source_info,
+ file_name_path->filename,
+ "special_file", "user_defined",
+ 0, file_name_path->filepath);
+ free (filename);
+ filename = file_name_path->filename;
+ }
+ free (file_name_path->filepath);
+ free (file_name_path);
+ }
+ output_unit_file_idx
+ = set_output_unit_file (self, output_unit, filename, 1);
+ self->output_unit_file_indices[i] = output_unit_file_idx;
+ output_unit_file = &self->output_unit_files.list[output_unit_file_idx];
+ if (self->conf->DEBUG.o.integer > 0)
+ {
+ char *output_unit_text = output_unit_texi (output_unit);
+ fprintf (stderr, "Page %s: %s(%d)\n", output_unit_text,
+ output_unit->unit_filename, output_unit_file->counter);
+ free (output_unit_text);
+ }
+ free (filename);
+ }
+
+ free (unit_file_name_paths);
+
+ if (special_units && special_units->number)
+ {
+ size_t i;
+ self->special_unit_file_indices = (size_t *)
+ malloc (special_units->number * sizeof (size_t));
+ for (i = 0; i < special_units->number; i++)
+ {
+ size_t special_unit_file_idx = 0;
+ const FILE_NAME_PATH_COUNTER *special_unit_file;
+ OUTPUT_UNIT *special_unit = special_units->list[i];
+ const ELEMENT *unit_command = special_unit->uc.special_unit_command;
+ const HTML_TARGET *special_unit_target
+ = html_get_target (self, unit_command);
+ const char *filename = special_unit_target->special_unit_filename;
+
+ /* Associate the special elements that have no page with the main page.
+ This may only happen if not split. */
+ if (!filename && special_units->number
+ && output_units->list[0]->unit_filename)
+ {
+ filename = output_units->list[0]->unit_filename;
+ }
+
+ if (filename)
+ {
+ FILE_SOURCE_INFO *file_source_info
+ = html_find_file_source_info (files_source_info, filename);
+ if (file_source_info)
+ {
+ if (!strcmp (file_source_info->type, "stand_in_file"))
+ {/* NOTE we keep the order, as in perl */
+ html_set_file_source_info (file_source_info,
+ "special_unit",
+ 0, unit_command, 0);
+ }
+ }
+ else
+ html_add_to_files_source_info (files_source_info, filename,
+ "special_unit", 0,
+ unit_command, 0);
+ }
+ special_unit_file_idx
+ = set_output_unit_file (self, special_unit, filename, 1);
+ self->special_unit_file_indices[i] = special_unit_file_idx;
+ special_unit_file
+ = &self->output_unit_files.list[special_unit_file_idx];
+ if (self->conf->DEBUG.o.integer > 0)
+ fprintf (stderr, "Special page: %s(%d)\n", filename,
+ special_unit_file->counter);
+ }
+ }
+
+ for (i = 0; i < files_source_info->number; i++)
+ {
+ FILE_SOURCE_INFO *file_source_info = &files_source_info->list[i];
+ set_file_path (self, file_source_info->filename, file_source_info->path,
+ destination_directory);
+ }
+
+ /*
+ to be able to associate to the output unit file the associated
+ output units will be output into, this is done after document output
+ units got files.
+ In practice only used for contents and shortcontents.
+ */
+ if (associated_special_units && associated_special_units->number > 0)
+ {
+ size_t i;
+ for (i = 0; i < associated_special_units->number; i++)
+ {
+ const char *filename = 0;
+ OUTPUT_UNIT *special_unit = associated_special_units->list[i];
+ const OUTPUT_UNIT *associated_output_unit
+ = special_unit->associated_document_unit;
+ const ELEMENT *unit_command = special_unit->uc.special_unit_command;
+ HTML_TARGET *element_target
+ = html_get_target (self, unit_command);
+
+ if (!element_target->special_unit_filename)
+ {/* set the file if not already set */
+ char *unit_filename = 0;
+ if (associated_output_unit)
+ unit_filename = strdup (associated_output_unit->unit_filename);
+ element_target->special_unit_filename = unit_filename;
+ }
+ filename = element_target->special_unit_filename;
+
+ /* set here the file name, but do not increment the counter as it is
+ already set for the output unit the special output unit is in. */
+ if (filename)
+ set_output_unit_file (self, special_unit, filename, 0);
+ }
+ }
+
+ /* 0 is for document_global_context_css, the remaining indices
+ for the output unit files */
+ self->page_css.number = self->output_unit_files.number +1;
+ self->page_css.space = self->page_css.number;
+ self->page_css.list = (CSS_LIST *)
+ malloc (self->page_css.space * sizeof (CSS_LIST));
+ memset (self->page_css.list, 0,
+ self->page_css.number * sizeof (CSS_LIST));
+
+ self->html_files_information.number = self->output_unit_files.number +1;
+ self->html_files_information.list = (FILE_ASSOCIATED_INFO *)
+ malloc (self->html_files_information.number * sizeof
(FILE_ASSOCIATED_INFO));
+ memset (self->html_files_information.list, 0,
+ self->html_files_information.number * sizeof (FILE_ASSOCIATED_INFO));
+
+ return files_source_info;
+}
+
+static void
+prepare_special_units_directions (CONVERTER *self,
+ OUTPUT_UNIT_LIST *special_units)
+{
+ size_t i;
+
+ if (!special_units)
+ return;
+
+ for (i = 0; i < special_units->number; i++)
+ {
+ OUTPUT_UNIT *special_unit = special_units->list[i];
+ special_unit->directions[RUD_type_This] = special_unit;
+ }
+}
+
+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);
+}
+
+/* Return structure to be freed by the caller */
+FILE_SOURCE_INFO_LIST *
+html_prepare_units_directions_files (CONVERTER *self,
+ const char *output_file, const char *destination_directory,
+ const char *output_filename, const char *document_name)
+{
+ size_t i;
+ FILE_SOURCE_INFO_LIST *files_source_info = 0;
+ size_t external_nodes_units_descriptor
+ = new_output_units_descriptor (self->document);
+ OUTPUT_UNIT_LIST *external_node_target_units
+ = retrieve_output_units (self->document, external_nodes_units_descriptor);
+ OUTPUT_UNIT_LIST *output_units = retrieve_output_units
+ (self->document, self->output_units_descriptors[OUDT_units]);
+ OUTPUT_UNIT_LIST *special_units = retrieve_output_units
+ (self->document, self->output_units_descriptors[OUDT_special_units]);
+ OUTPUT_UNIT_LIST *associated_special_units = retrieve_output_units
+ (self->document,
+ self->output_units_descriptors[OUDT_associated_special_units]);
+
+ self->output_units_descriptors[OUDT_external_nodes_units]
+ = external_nodes_units_descriptor;
+
+ html_prepare_output_units_global_targets (self);
+
+ split_pages (output_units, self->conf->SPLIT.o.string);
+
+ if (strlen (output_file))
+ {
+ files_source_info =
+ html_set_pages_files (self, output_units, special_units,
+ associated_special_units, output_file,
+ destination_directory, output_filename, document_name);
+ }
+ else
+ html_setup_output_simple_page (self, output_filename);
+
+ units_directions (&self->document->identifiers_target, output_units,
+ external_node_target_units,
+ self->conf->DEBUG.o.integer);
+
+ prepare_special_units_directions (self, special_units);
+
+ units_file_directions (output_units);
+
+ /* elements_in_file_count is only set in HTML, not in
+ Texinfo::Convert::Converter */
+ if (self->output_unit_files.number)
+ {
+ /* set elements_in_file_count and prepare page_name_number
+ for sorting */
+ self->page_name_number.number = self->output_unit_files.number;
+ self->page_name_number.list = (PAGE_NAME_NUMBER *)
+ malloc (self->page_name_number.number * sizeof (PAGE_NAME_NUMBER));
+
+ for (i = 0; i < self->output_unit_files.number; i++)
+ {
+ FILE_NAME_PATH_COUNTER *file_counter
+ = &self->output_unit_files.list[i];
+ PAGE_NAME_NUMBER *page_name_number = &self->page_name_number.list[i];
+
+ /* counter is dynamic, decreased when the element is encountered
+ elements_in_file_count is not modified afterwards */
+ file_counter->elements_in_file_count = file_counter->counter;
+
+ page_name_number->number = i+1;
+ page_name_number->page_name = file_counter->filename;
+ }
+
+ qsort (self->page_name_number.list,
+ self->page_name_number.number,
+ sizeof (PAGE_NAME_NUMBER), compare_page_name_number);
+ }
+
+ return files_source_info;
+}
+
diff --git a/tp/Texinfo/XS/convert/html_prepare_converter.h
b/tp/Texinfo/XS/convert/html_prepare_converter.h
index 4f626a9763..9dab29f8a3 100644
--- a/tp/Texinfo/XS/convert/html_prepare_converter.h
+++ b/tp/Texinfo/XS/convert/html_prepare_converter.h
@@ -23,4 +23,8 @@ void html_prepare_conversion_units (CONVERTER *self);
void html_prepare_conversion_units_targets (CONVERTER *self,
const char *document_name);
+FILE_SOURCE_INFO_LIST * html_prepare_units_directions_files (CONVERTER *self,
+ const char *output_file, const char *destination_directory,
+ const char *output_filename, const char *document_name);
+
#endif