[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Fri, 4 Oct 2024 19:12:22 -0400 (EDT) |
branch: master
commit ee46ee3a6609dab9eb4b1b9b5e83c17cb6c92dc4
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Thu Aug 15 12:23:09 2024 +0200
* tp/Texinfo/XS/convert/html_converter_types.h: declare
translated_special_unit_info, direction_string_type_names,
direction_string_context_names, html_conversion_context_type_names,
html_argument_formatting_type_names and
html_stage_handler_stage_type_names.
* tp/Texinfo/XS/convert_html.c (html_close_lone_element)
(convert_tree_append): rename close_html_lone_element as
html_close_lone_element, convert_to_html_internal as
convert_tree_append and translate_convert_to_html_internal as
html_translate_convert_tree_append.
* tp/Texinfo/XS/convert_html.c (html_default_format_jslicense_file)
(html_default_format_date_in_header): split functions formatting HTML
out of do_jslicenses_file and html_convert_output.
* tp/Texinfo/XS/Makefile.am (libtexinfo_convert_la_SOURCES),
tp/Texinfo/XS/format_html.c, tp/Texinfo/XS/convert_html.c: split
convert_html.c, moving the formatting to HTML to format_html.c,
including html_default_format_jslicense_file and
html_default_format_date_in_header, keeping only higher level
conversion functions in convert_html.c.
* tp/Texinfo/XS/convert_html.c
(html_convert_string_tree_new_formatting_context)
(html_convert_tree_new_formatting_context, html_convert_css_string):
prepend html_ and declare in header file.
* tp/Texinfo/XS/format_html.c (html_format_title_titlepage)
(html_format_node_redirection_page, html_format_comment)
(html_format_end_file, html_format_begin_file): prepend html_ and
declare in header file.
---
ChangeLog | 35 +
tp/Texinfo/XS/Makefile.am | 2 +
tp/Texinfo/XS/convert/ConvertXS.xs | 1 +
tp/Texinfo/XS/convert/build_html_perl_state.c | 9 +-
tp/Texinfo/XS/convert/convert_html.c | 12984 +------------------
tp/Texinfo/XS/convert/convert_html.h | 282 +-
.../XS/convert/{convert_html.c => format_html.c} | 3510 +----
.../XS/convert/{convert_html.h => format_html.h} | 103 +-
tp/Texinfo/XS/convert/get_html_perl_info.c | 12 +-
tp/Texinfo/XS/convert/html_converter_types.h | 12 +
tp/Texinfo/XS/convert/html_prepare_converter.c | 4 +
11 files changed, 665 insertions(+), 16289 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a4a13ddb92..0ef563ab7e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2024-08-15 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/XS/convert/html_converter_types.h: declare
+ translated_special_unit_info, direction_string_type_names,
+ direction_string_context_names, html_conversion_context_type_names,
+ html_argument_formatting_type_names and
+ html_stage_handler_stage_type_names.
+
+ * tp/Texinfo/XS/convert_html.c (html_close_lone_element)
+ (convert_tree_append): rename close_html_lone_element as
+ html_close_lone_element, convert_to_html_internal as
+ convert_tree_append and translate_convert_to_html_internal as
+ html_translate_convert_tree_append.
+
+ * tp/Texinfo/XS/convert_html.c (html_default_format_jslicense_file)
+ (html_default_format_date_in_header): split functions formatting HTML
+ out of do_jslicenses_file and html_convert_output.
+
+ * tp/Texinfo/XS/Makefile.am (libtexinfo_convert_la_SOURCES),
+ tp/Texinfo/XS/format_html.c, tp/Texinfo/XS/convert_html.c: split
+ convert_html.c, moving the formatting to HTML to format_html.c,
+ including html_default_format_jslicense_file and
+ html_default_format_date_in_header, keeping only higher level
+ conversion functions in convert_html.c.
+
+ * tp/Texinfo/XS/convert_html.c
+ (html_convert_string_tree_new_formatting_context)
+ (html_convert_tree_new_formatting_context, html_convert_css_string):
+ prepend html_ and declare in header file.
+
+ * tp/Texinfo/XS/format_html.c (html_format_title_titlepage)
+ (html_format_node_redirection_page, html_format_comment)
+ (html_format_end_file, html_format_begin_file): prepend html_ and
+ declare in header file.
+
2024-08-15 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/XS/convert/convert_html.c: rename
diff --git a/tp/Texinfo/XS/Makefile.am b/tp/Texinfo/XS/Makefile.am
index bf56df00bd..d7c0757487 100644
--- a/tp/Texinfo/XS/Makefile.am
+++ b/tp/Texinfo/XS/Makefile.am
@@ -388,6 +388,8 @@ C_libtexinfo_convert_sources = \
convert/create_buttons.h \
convert/convert_html.h \
convert/convert_html.c \
+ convert/format_html.h \
+ convert/format_html.c \
convert/html_converter_types.h \
convert/html_converter_init_options.c \
convert/html_converter_init_options.h \
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 49cf4ee2ca..2448ce3923 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -56,6 +56,7 @@
#include "build_html_perl_state.h"
#include "html_conversion_state.h"
#include "convert_html.h"
+#include "format_html.h"
#include "html_prepare_converter.h"
#include "get_html_perl_info.h"
diff --git a/tp/Texinfo/XS/convert/build_html_perl_state.c
b/tp/Texinfo/XS/convert/build_html_perl_state.c
index e4ab2192e4..e067d49191 100644
--- a/tp/Texinfo/XS/convert/build_html_perl_state.c
+++ b/tp/Texinfo/XS/convert/build_html_perl_state.c
@@ -48,13 +48,10 @@
#include "build_perl_info.h"
/* for NAMED_STRING_ELEMENT_LIST */
#include "translations.h"
-/* for no_arg_formatted_cmd */
+/* for no_arg_formatted_cmd direction_string_type_names
+ direction_string_context_names html_conversion_context_type_names
+ html_argument_formatting_type_names translated_special_unit_info */
#include "html_converter_types.h"
-/* for html_conversion_context_type_names direction_string_type_names
- direction_string_context_names html_argument_formatting_type_names
- translated_special_unit_info
- */
-#include "convert_html.h"
/* for special_unit_info_type_names html_global_unit_direction_names
html_setup_global_units_direction_names */
#include "html_prepare_converter.h"
diff --git a/tp/Texinfo/XS/convert/convert_html.c
b/tp/Texinfo/XS/convert/convert_html.c
index d25c323659..1864e36b02 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -19,11 +19,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <iconv.h>
-#include <unistr.h>
-#include <unictype.h>
#include "copy-file.h"
@@ -42,31 +37,34 @@
#include "builtin_commands.h"
#include "command_stack.h"
#include "errors.h"
+/* xasprintf get_label_element output_conversions ENCODING_CONVERSION fatal
+ encode_with_iconv output_unit_type_names get_cmd_global_uniq_command
+ */
#include "utils.h"
#include "customization_options.h"
#include "extra.h"
-#include "targets.h"
#include "debug.h"
+/* retrieve_output_units output_unit_texi */
#include "output_unit.h"
-#include "node_name_normalization.h"
-#include "manipulate_indices.h"
#include "convert_to_texinfo.h"
+/* translate_string NAMED_STRING_ELEMENT_LIST */
#include "translations.h"
-/* for OTXI_UNICODE_TEXT_CASES utf8_from_string string_from_utf8 */
-#include "unicode.h"
/* convert_to_text */
#include "convert_to_text.h"
+/* translated_command_tree encoded_output_file_name output_files_open_out
+ output_files_register_closed */
#include "convert_utils.h"
+/* call_latex_convert_to_latex_math */
#include "call_perl_function.h"
#include "call_html_perl_function.h"
/* for unregister_document_merge_with_document */
#include "document.h"
+/* conversion_paths_info create_destination_directory
+ set_global_document_commands clear_tree_added_elements
+ register_normalize_case_filename */
#include "converter.h"
-#include "manipulate_tree.h"
-/* for new_complete_menu_master_menu */
-#include "structuring.h"
-#include "api_to_perl.h"
#include "html_conversion_state.h"
+#include "format_html.h"
#include "convert_html.h"
const char *html_conversion_context_type_names[] = {
@@ -87,420 +85,6 @@ const char *html_stage_handler_stage_type_names[] = {
#undef html_hsht_type
};
-const char *direction_string_type_names[] =
-{
- #define tds_type(name) #name,
- TDS_TRANSLATED_TYPES_LIST
- TDS_NON_TRANSLATED_TYPES_LIST
- #undef tds_type
-};
-
-const char *direction_string_context_names[] =
-{
- "normal", "string"
-};
-
-const enum htmlxref_split_type htmlxref_entries[htmlxref_split_type_chapter +
1][htmlxref_split_type_chapter + 1] = {
- { htmlxref_split_type_mono, htmlxref_split_type_chapter,
htmlxref_split_type_section, htmlxref_split_type_node },
- { htmlxref_split_type_node, htmlxref_split_type_section,
htmlxref_split_type_chapter, htmlxref_split_type_mono },
- { htmlxref_split_type_section, htmlxref_split_type_chapter,
htmlxref_split_type_node, htmlxref_split_type_mono },
- { htmlxref_split_type_chapter, htmlxref_split_type_section,
htmlxref_split_type_node, htmlxref_split_type_mono },
-};
-
-/* string functions */
-
-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);
-}
-
-/* same as matching the regex /^\\[a-zA-Z0-9]+ /
- */
-char *
-html_after_escaped_characters (char *text)
-{
- char *p = text;
- if (*p != '\\')
- return 0;
-
- p++;
-
- if (!isascii_alnum (*p))
- return 0;
-
- while (isascii_alnum (*p))
- p++;
-
- if (*p == ' ')
- return p+1;
-
- 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;
-}
-
-/* to be inlined in text parsing codes */
-#define OTXI_PROTECT_XML_FORM_FEED_CASES(var) \
- OTXI_PROTECT_XML_CASES(var) \
- case '\f': \
- text_append_n (result, "", 5); var++; \
- break;
-
-#define OTXI_ISO_ENTITY_TEXT_CASES(var) \
- case '-': \
- if (*(var+1) && !memcmp (var, "---", 3)) \
- { \
- text_append_n (result, "—", 7); \
- var += 3; \
- } \
- else if (!memcmp (var, "--", 2)) \
- { \
- text_append_n (result, "–", 7); \
- var += 2; \
- } \
- else \
- { \
- text_append_n (result, "-", 1); \
- var++; \
- } \
- break; \
- case '`': \
- if (!memcmp (var, "``", 2)) \
- { \
- text_append_n (result, "“", 7); \
- var += 2; \
- } \
- else \
- { \
- text_append_n (result, "‘", 7); \
- var++; \
- } \
- break; \
- case '\'': \
- if (!memcmp (var, "''", 2)) \
- { \
- text_append_n (result, "”", 7); \
- var += 2; \
- } \
- else \
- { \
- text_append_n (result, "’", 7); \
- var++; \
- } \
- break;
-
-#define OTXI_NO_ISO_ENTITY_TEXT_CASES(var) \
- case '-': \
- if (*(var+1) && !memcmp (var, "---", 3)) \
- { \
- text_append_n (result, "--", 2); \
- var += 3; \
- } \
- else \
- { \
- text_append_n (result, "-", 1); \
- if (!memcmp (var, "--", 2)) \
- var += 2; \
- else \
- var++; \
- } \
- break; \
- case '`': \
- if (!memcmp (var, "``", 2)) \
- { \
- text_append_n (result, """, 6); \
- var += 2; \
- } \
- else \
- { \
- text_append_n (result, var, 1); \
- var++; \
- } \
- break; \
- case '\'': \
- if (!memcmp (var, "''", 2)) \
- { \
- text_append_n (result, """, 6); \
- var += 2; \
- } \
- else \
- { \
- text_append_n (result, var, 1); \
- var++; \
- } \
- break;
-
-#define OTXI_NO_BREAK_CASES(var) \
- case ' ': \
- case '\n': \
- text_append_n (result, \
- self->special_character[SC_non_breaking_space].string, \
- self->special_character[SC_non_breaking_space].len); \
- var += strspn (var, "\n "); \
- break;
-
-#define OTXI_SPACE_PROTECTION_CASES(var) \
- case ' ': \
- text_append_n (result, \
- self->special_character[SC_non_breaking_space].string, \
- self->special_character[SC_non_breaking_space].len); \
- var++; \
- break; \
- case '\n': \
- text_append_n (result, self->line_break_element.string, \
- self->line_break_element.len); \
- var++; \
- break;
-
-/* text conversion loop, with the protection of XML special
- characters and the possibility to add more delimiters and
- more cases to handle those delimiters */
-#define OTXI_CONVERT_TEXT(delimiters,other_cases) \
- { \
- while (*p) \
- { \
- int before_sep_nr = strcspn (p, "<>&\"\f" delimiters); \
- if (before_sep_nr) \
- { \
- text_append_n (result, p, before_sep_nr); \
- p += before_sep_nr; \
- } \
- if (!*p) \
- break; \
- switch (*p) \
- { \
- OTXI_PROTECT_XML_FORM_FEED_CASES(p) \
- other_cases \
- } \
- } \
- }
-
-/* conversion of text for all the possibilities regarding -- --- ''
- conversion, with the possibility to add more for spaces protection */
-#define OTXI_ALL_CONVERT_TEXT(additional_delim,other_cases) \
- const char *p = content_used; \
- if (html_in_code (self) || html_in_math (self)) \
- OTXI_CONVERT_TEXT(additional_delim, \
- other_cases) \
- else if (self->use_unicode_text) \
- OTXI_CONVERT_TEXT("-`'" additional_delim, \
- OTXI_UNICODE_TEXT_CASES(p) \
- other_cases) \
- else if (self->conf->USE_NUMERIC_ENTITY.o.integer > 0) \
- OTXI_CONVERT_TEXT("-`'" additional_delim, \
- OTXI_NUMERIC_ENTITY_TEXT_CASES(p) \
- other_cases) \
- else if (self->conf->USE_ISO.o.integer > 0) \
- OTXI_CONVERT_TEXT("-`'" additional_delim, \
- OTXI_ISO_ENTITY_TEXT_CASES(p) \
- other_cases) \
- else \
- OTXI_CONVERT_TEXT("-`'" additional_delim, \
- OTXI_NO_ISO_ENTITY_TEXT_CASES(p) \
- other_cases)
-
-void
-html_default_format_protect_text (const char *text, TEXT *result)
-{
- const char *p = text;
-
- OTXI_CONVERT_TEXT ( , )
-}
-
-void
-format_protect_text (CONVERTER *self, const char *text, TEXT *result)
-{
- FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_protect_text];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- (*self->current_format_protect_text) (text, result);
- }
- else
- {
- char *protected_text
- = call_formatting_function_format_protect_text (self,
- formatting_reference, text);
- text_append (result, protected_text);
- free (protected_text);
- }
-}
-
-static const char *reserved_unreserved_percent = "-_.!~*'()$&+,/:;=?@[]#%";
-
-/* NOTE the input string should be UTF-8 encoded */
-static char *
-url_protect_url_text (CONVERTER *self, const char *input_string)
-{
- TEXT text;
- TEXT result;
- text_init (&text);
- const char *p = input_string;
-
- text_append (&text, "");
-
- /* protect 'ligntly', do not protect unreserved and reserved characters
- + the % itself */
- while (*p)
- {
- if (isascii_alnum (*p) || isascii_alpha (*p) || isascii_digit (*p))
- {
- text_append_n (&text, p, 1);
- p++;
- }
- else
- {
- int n = strspn (p, reserved_unreserved_percent);
- if (n)
- {
- text_append_n (&text, p, n);
- p += n;
- }
- else
- {
- int n = strspn (p, "\r\n");
- if (n)
- {
- text_printf (&text, "%%%02x", (unsigned char)' ');
- p += n;
- }
- else
- {
- int i;
- int char_len = 1;
- if (!isascii (*p))
- {
- /* Protect UTF-8 with continuation bytes. */
- while ((p[char_len] & 0xC0) == 0x80)
- char_len++;
- }
- for (i = 0; i < char_len; i++)
- {
- /* the reason for forcing (unsigned char) is that the %x modifier
- expects an unsigned int parameter and a char will usually be
- promoted to an int when passed to a varargs function */
- text_printf (&text, "%%%02x", (unsigned char)*p);
- p += 1;
- }
- }
- }
- }
- }
- text_init (&result);
- format_protect_text (self, text.text, &result);
- free (text.text);
- return (result.text);
-}
-
-static const char *file_path_punct = "-_.~/:";
-
-/*
- protect a file path used in an url. Characters appearing in file paths
- are not protected. All the other characters that can be percent
- protected are protected, including characters with specific meaning in url.
- */
-static char *
-url_protect_file_text (CONVERTER *self, const char *input_string)
-{
- TEXT text;
- TEXT result;
- text_init (&text);
- const char *p = input_string;
-
- text_append (&text, "");
-
- while (*p)
- {
- if (isascii_alnum (*p) || isascii_alpha (*p) || isascii_digit (*p))
- {
- text_append_n (&text, p, 1);
- p++;
- }
- else
- {
- int n = strspn (p, file_path_punct);
- if (n)
- {
- text_append_n (&text, p, n);
- p += n;
- }
- else
- {
- int n = strspn (p, "\r\n");
- if (n)
- {
- text_printf (&text, "%%%02x", (unsigned char)' ');
- p += n;
- }
- else
- {
- int i;
- int char_len = 1;
- if (!isascii (*p))
- {
- /* Protect UTF-8 with continuation bytes. */
- while ((p[char_len] & 0xC0) == 0x80)
- char_len++;
- }
- for (i = 0; i < char_len; i++)
- {
- /* the reason for forcing (unsigned char) is that the %x modifier
- expects an unsigned int parameter and a char will usually be
- promoted to an int when passed to a varargs function */
- text_printf (&text, "%%%02x", (unsigned char)*p);
- p += 1;
- }
- }
- }
- }
- }
-
- text_init (&result);
- format_protect_text (self, text.text, &result);
- free (text.text);
- return (result.text);
-}
-
/* string translation and tree conversion */
@@ -623,29 +207,29 @@ html_pcdt_tree (const char *translation_context, const
char *string,
translation_context);
}
-static void
+void
add_tree_to_build (CONVERTER *self, ELEMENT *e)
{
if (self->external_references_number > 0)
add_to_element_list (&self->tree_to_build, e);
}
-static void
+void
remove_tree_to_build (CONVERTER *self, ELEMENT *e)
{
if (self->external_references_number > 0)
remove_element_from_list (&self->tree_to_build, e);
}
-static void convert_tree_append (CONVERTER *self, const ELEMENT *e,
- TEXT *result, const char *explanation);
+void convert_tree_append (CONVERTER *self, const ELEMENT *e,
+ TEXT *result, const char *explanation);
-static void
-translate_convert_tree_append (const char *string,
- CONVERTER *self,
- NAMED_STRING_ELEMENT_LIST *replaced_substrings,
- const char *translation_context,
- TEXT *result, const char *explanation)
+void
+html_translate_convert_tree_append (const char *string,
+ CONVERTER *self,
+ NAMED_STRING_ELEMENT_LIST *replaced_substrings,
+ const char *translation_context,
+ TEXT *result, const char *explanation)
{
ELEMENT *translation_tree = html_cdt_tree (string, self,
replaced_substrings, translation_context);
@@ -657,44 +241,6 @@ translate_convert_tree_append (const char *string,
destroy_element_and_children (translation_tree);
}
-ELEMENT *
-special_unit_info_tree (CONVERTER *self, const enum special_unit_info_tree
type,
- const char *special_unit_variety)
-{
- /* number is index +1 */
- size_t number = find_string (&self->special_unit_varieties,
- special_unit_variety);
- int j;
- int i = number -1;
-
- if (self->special_unit_info_tree[type][i])
- return self->special_unit_info_tree[type][i];
-
- for (j = 0; translated_special_unit_info[j].tree_type != SUIT_type_none; j++)
- {
- if (translated_special_unit_info[j].tree_type == type)
- {
- enum special_unit_info_type string_type
- = translated_special_unit_info[j].string_type;
- char *special_unit_info_string
- = self->special_unit_info[string_type][i];
- /* if set to undef in user customization. To be forbidden? */
- if (!special_unit_info_string)
- return 0;
- char *translation_context;
- xasprintf (&translation_context, "%s section heading",
- special_unit_variety);
- self->special_unit_info_tree[type][i]
- = html_pcdt_tree (translation_context, special_unit_info_string,
- self, 0);
- free (translation_context);
- add_tree_to_build (self, self->special_unit_info_tree[type][i]);
- return self->special_unit_info_tree[type][i];
- }
- }
- return 0;
-}
-
/* returned string to be freed by the caller */
char *
html_convert_tree (CONVERTER *self, const ELEMENT *tree,
@@ -711,11 +257,11 @@ html_convert_tree (CONVERTER *self, const ELEMENT *tree,
/* Call convert_tree out of the main conversion flow.
*/
char *
-convert_tree_new_formatting_context (CONVERTER *self, const ELEMENT *tree,
- const char *context_string,
- const char *multiple_pass,
- const char *document_global_context,
- enum command_id block_cmd)
+html_convert_tree_new_formatting_context (CONVERTER *self, const ELEMENT *tree,
+ const char *context_string,
+ const char *multiple_pass,
+ const char *document_global_context,
+ enum command_id block_cmd)
{
const char *multiple_pass_str = "";
char *result;
@@ -752,12247 +298,257 @@ convert_tree_new_formatting_context (CONVERTER *self,
const ELEMENT *tree,
-/* target, links, href and root command text formatting, with caching */
-
-/* this number should be safe to use even after targets list has been
- reallocated */
-
-size_t
-find_element_target_number_linear (const HTML_TARGET_LIST *targets,
- const ELEMENT *element)
-{
- size_t i;
-
- if (!targets->number)
- return 0;
-
- for (i = 0; i < targets->number; i ++)
- {
- HTML_TARGET *target = &targets->list[i];
- if (target->element == element)
- return i + 1;
- }
- return 0;
-}
-
-static int
-compare_element_target (const void *a, const void *b)
-{
- const HTML_TARGET *ete_a = (const HTML_TARGET *) a;
- const HTML_TARGET *ete_b = (const HTML_TARGET *) b;
- /* we cast to uintptr_t because comparison of pointers from different
- objects is undefined behaviour in C. In practice it is probably
- not an issue */
- uintptr_t a_element_addr = (uintptr_t)ete_a->element;
- uintptr_t b_element_addr = (uintptr_t)ete_b->element;
-
- return (a_element_addr > b_element_addr) - (a_element_addr < b_element_addr);
-}
-
-HTML_TARGET *
-find_element_target_search (const HTML_TARGET_LIST *targets,
- const ELEMENT *element)
+/* return value to be freed by caller */
+char *
+html_command_description (CONVERTER *self, const ELEMENT *command,
+ const enum html_text_type type)
{
- HTML_TARGET *result;
- static HTML_TARGET searched_element;
+ HTML_TARGET *target_info;
- if (targets->number == 0)
+ ELEMENT *manual_content = lookup_extra_element (command,
+ AI_key_manual_content);
+ if (manual_content)
return 0;
- searched_element.element = element;
- result = (HTML_TARGET *) bsearch (&searched_element,
- targets->list, targets->number, sizeof (HTML_TARGET),
- compare_element_target);
- return result;
-}
-
-/* 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)
-{
- enum command_id cmd = element_builtin_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);
-
- if (i > 0)
- return &targets[cmd].list[i - 1];
-
- return 0;
- */
-}
-
-/* the target may not be known already, so the caller may fill the
- HTML_TARGET in some cases */
-HTML_TARGET *
-find_element_special_target (const HTML_TARGET_LIST *targets,
- const ELEMENT *element)
-{
- return find_element_target_search (targets, element);
- /* with a linear search:
- size_t i = find_element_target_number_linear (targets, element);
-
- if (i > 0)
- return &targets->list[i - 1];
-
- return 0;
- */
-}
+ target_info = html_get_target (self, command);
-const char *
-html_command_id (const CONVERTER *self, const ELEMENT *command)
-{
- const HTML_TARGET *target_info = html_get_target (self, command);
if (target_info)
- return target_info->target;
- else
- return 0;
-}
-
-static int
-compare_htmlxref_manual (const void *a, const void *b)
-{
- const HTMLXREF_MANUAL *hxfm_a = (const HTMLXREF_MANUAL *) a;
- const HTMLXREF_MANUAL *hxfm_b = (const HTMLXREF_MANUAL *) b;
-
- return strcmp (hxfm_a->manual, hxfm_b->manual);
-}
-
-HTMLXREF_MANUAL *
-find_htmlxref_manual
- (const HTMLXREF_MANUAL_LIST *htmlxref_manuals, const char *manual)
-{
- HTMLXREF_MANUAL *result = 0;
- static HTMLXREF_MANUAL searched_manual;
- /* remove const with a cast, it is more efficient than duplicating */
- searched_manual.manual = (char *) manual;
-
- result = (HTMLXREF_MANUAL *) bsearch (&searched_manual,
- htmlxref_manuals->list,
- htmlxref_manuals->number, sizeof (HTMLXREF_MANUAL),
- compare_htmlxref_manual);
-
- return result;
-}
-
-char *
-html_normalized_to_id (const char *id)
-{
- if (isascii_digit (id[0]) || id[0] == '_')
- {
- char *result;
- xasprintf (&result, "%s%s", "g_t", id);
- return result;
- }
- return strdup (id);
-}
-
-/* calls customization function requiring elements */
-TARGET_FILENAME *
-html_normalized_label_id_file (CONVERTER *self, const char *normalized,
- const ELEMENT* label_element)
-{
- int called;
- char *target = 0;
- char *target_customized;
- char *normalized_label = 0;
- TARGET_FILENAME *target_filename
- = (TARGET_FILENAME *) malloc (sizeof (TARGET_FILENAME));
-
- if (normalized)
- {
- normalized_label = strdup (normalized);
- target = html_normalized_to_id (normalized);
- }
- else if (label_element)
- {
- normalized_label
- = convert_contents_to_identifier (label_element);
- if (normalized_label)
- target = html_normalized_to_id (normalized_label);
- }
-
- if (!target)
- target = strdup ("");
-
- /* to find out the Top node, one could check $normalized */
- target_customized = call_file_id_setting_label_target_name (self,
- normalized_label, label_element, target,
- &called);
-
- if (target_customized)
{
- free (target);
- target = target_customized;
- }
-
- target_filename->target = target;
- target_filename->filename
- = node_information_filename (self, normalized_label, label_element);
-
- free (normalized_label);
-
- return target_filename;
-}
-
-char *
-external_node_href (CONVERTER *self, const ELEMENT *external_node,
- const ELEMENT *source_command) /* for messages only */
-{
- TEXT result;
- char *target;
- char *target_filebase;
- /* used if !target_split */
- char *file = 0;
- /* used if target_split */
- char *directory = 0;
- const char *extension = 0;
- int target_split = 0;
- char *normalized = lookup_extra_string (external_node, AI_key_normalized);
- const ELEMENT *node_contents = lookup_extra_container (external_node,
- AI_key_node_content);
- const ELEMENT *manual_content = lookup_extra_container (external_node,
- AI_key_manual_content);
-
- TARGET_FILENAME *target_filename =
- html_normalized_label_id_file (self, normalized, node_contents);
-
- /* always undef if conversion is called through convert() */
- if (self->conf->EXTERNAL_CROSSREF_SPLIT.o.string
- && strlen (self->conf->EXTERNAL_CROSSREF_SPLIT.o.string))
- /* initialize to EXTERNAL_CROSSREF_SPLIT */
- target_split = 1;
-
- if (self->conf->EXTERNAL_CROSSREF_EXTENSION.o.string)
- extension = self->conf->EXTERNAL_CROSSREF_EXTENSION.o.string;
- else if (self->conf->EXTENSION.o.string)
- extension = self->conf->EXTENSION.o.string;
-
- /* both to be freed before return */
- target = target_filename->target;
- target_filebase = target_filename->filename;
- free (target_filename);
-
- if (manual_content)
- {
- char *manual_name;
- char *manual_base = 0;
- char *p;
- char *htmlxref_href = 0;
- enum htmlxref_split_type split_found = htmlxref_split_type_none;
- HTMLXREF_MANUAL *htmlxref_manual;
-
- self->convert_text_options->code_state++;
- manual_name = convert_to_text (manual_content,
- self->convert_text_options);
- self->convert_text_options->code_state--;
-
- if (self->conf->IGNORE_REF_TO_TOP_NODE_UP.o.integer > 0
- && !strlen (target))
- {
- char *top_node_up = self->conf->TOP_NODE_UP.o.string;
- if (top_node_up)
- {
- char *parentheses_manual_name;
- xasprintf (&parentheses_manual_name, "(%s)", manual_name);
- if (!strcmp (top_node_up, parentheses_manual_name))
- {
- free (parentheses_manual_name);
- free (manual_name);
- free (target);
- free (target_filebase);
- return strdup ("");
- }
- free (parentheses_manual_name);
- }
- }
- p = strrchr (manual_name, '/');
- if (!p)
- p = manual_name;
- else
- p++;
- manual_base = strdup (p);
-
- htmlxref_manual = find_htmlxref_manual (&self->htmlxref, manual_base);
-
- if (htmlxref_manual)
- {
- const enum htmlxref_split_type *ordered_split_types
- = htmlxref_entries[self->document_htmlxref_split_type];
- int i;
- for (i = 0; i < htmlxref_split_type_chapter +1; i++)
- {
- const enum htmlxref_split_type split_ordered
- = ordered_split_types[i];
- if (htmlxref_manual->urlprefix[split_ordered]
- && strlen (htmlxref_manual->urlprefix[split_ordered]))
- {
- split_found = split_ordered;
- htmlxref_href = url_protect_url_text (self,
- htmlxref_manual->urlprefix[split_ordered]);
- break;
- }
- }
- }
- if (split_found != htmlxref_split_type_none)
- {
- if (split_found == htmlxref_split_type_mono)
- target_split = 0;
- else
- target_split = 1;
- }
- else
- { /* nothing specified for that manual, use default */
- if (self->conf->CHECK_HTMLXREF.o.integer > 0)
- {
- if ((source_command != 0) &&
- (source_command->e.c->source_info.line_nr != 0))
- { /* check if already set and set if not */
- if (!html_check_htmlxref_already_warned (self, manual_name,
-
&source_command->e.c->source_info))
- {
- message_list_command_warn (&self->error_messages,
- self->conf,
- source_command, 0,
- "no htmlxref.cnf entry found for `%s'",
- manual_name);
- }
- }
- else
- {
- if (!html_check_htmlxref_already_warned (self,
- manual_name, 0))
- {
- message_list_document_warn (&self->error_messages,
- self->conf, 0,
- "no htmlxref.cnf entry found for `%s'", manual_name);
- }
- }
- }
- }
- free (manual_name);
-
- if (target_split)
- {
- char *directory_part;
- if (htmlxref_href)
- {
- directory_part = htmlxref_href;
- }
- else
- {
- TEXT dir_path;
- char *url_encoded_path;
- text_init (&dir_path);
-
- if (self->conf->EXTERNAL_DIR.o.string)
- {
- text_printf (&dir_path, "%s/%s",
- self->conf->EXTERNAL_DIR.o.string, manual_base);
- }
- else if (self->conf->SPLIT.o.string
- && strlen (self->conf->SPLIT.o.string))
- {
- text_append_n (&dir_path, "../", 3);
- text_append (&dir_path, manual_base);
- }
- if (self->output_format && strlen (self->output_format))
- {
- text_append_n (&dir_path, "_", 1);
- text_append (&dir_path, self->output_format);
- }
- url_encoded_path = url_protect_file_text (self, dir_path.text);
- free (dir_path.text);
- directory_part = url_encoded_path;
- }
- xasprintf (&directory, "%s/", directory_part);
- free (directory_part);
- }
- else
- { /* target not split */
- if (htmlxref_href)
- {
- file = htmlxref_href;
- }
- else
- {
- TEXT file_path;
- text_init (&file_path);
-
- if (self->conf->EXTERNAL_DIR.o.string)
- {
- text_printf (&file_path, "%s/%s",
- self->conf->EXTERNAL_DIR.o.string, manual_base);
- }
- else if (self->conf->SPLIT.o.string
- && strlen (self->conf->SPLIT.o.string))
- {
- text_append_n (&file_path, "../", 3);
- text_append (&file_path, manual_base);
- }
- else
- text_append (&file_path, manual_base);
- if (extension)
- text_printf (&file_path, ".%s", extension);
-
-
- file = url_protect_file_text (self, file_path.text);
- free (file_path.text);
- }
- }
- free (manual_base);
- }
-
- text_init (&result);
-
- if (target_split)
- {
- char *file_name = 0;
- TARGET_DIRECTORY_FILENAME *target_dir_filename;
-
- if ((!strcmp (target, "Top") || !strlen (target))
- && self->conf->TOP_NODE_FILE_TARGET.o.string)
- {
- file_name = strdup (self->conf->TOP_NODE_FILE_TARGET.o.string);
- }
- else
- {
- if (extension)
- xasprintf (&file_name, "%s.%s", target_filebase, extension);
- else
- file_name = strdup (target_filebase);
- }
- target_dir_filename
- = call_file_id_setting_external_target_split_name (self,
- normalized, external_node, target, directory, file_name);
- if (target_dir_filename)
- {
- free (directory);
- directory = target_dir_filename->directory;
- free (file_name);
- file_name = target_dir_filename->filename;
- free (target);
- target = target_dir_filename->target;
- free (target_dir_filename);
- }
- text_append (&result, directory);
- text_append (&result, file_name);
- if (strlen (target))
- {
- text_append_n (&result, "#", 1);
- text_append (&result, target);
- }
-
- free (file_name);
- free (directory);
- }
- else
- {
- TARGET_FILENAME *target_filename;
-
- if (!strlen (target))
- {
- free (target);
- target = strdup ("Top");
- }
-
- target_filename
- = call_file_id_setting_external_target_non_split_name (self,
- normalized, external_node, target, file);
-
- if (target_filename)
- {
- free (file);
- file = target_filename->filename;
- free (target);
- target = target_filename->target;
- free (target_filename);
- }
- text_append (&result, file);
- if (strlen (target))
- {
- text_append_n (&result, "#", 1);
- text_append (&result, target);
- }
-
- free (file);
- }
-
- free (target);
- free (target_filebase);
- return result.text;
-}
-
-/* index within the global (including special units) directions */
-int
-html_special_unit_variety_direction_index (const CONVERTER *self,
- const char *special_unit_variety)
-{
- /* number is index +1 */
- size_t number = find_string (&self->special_unit_varieties,
- special_unit_variety);
- int i = number -1;
- if (i >= 0)
- return D_Last +1 +i;
- return -1;
-}
-
-/*
- If FIND_CONTAINER is set, the element that holds the command output
- is found, otherwise the element that holds the command is found. This is
- mostly relevant for footnote only.
- If no known root element type is found, the returned root element is undef,
- and not set to the element at the tree root
- */
-/* NOTE should not be called with a text element */
-ROOT_AND_UNIT *
-html_get_tree_root_element (CONVERTER *self, const ELEMENT *command,
- int find_container)
-{
- const ELEMENT *current = command;
- const OUTPUT_UNIT *output_unit = 0;
- const ELEMENT *root_command = 0;
-
- while (1)
- {
- enum command_id data_cmd = element_builtin_data_cmd (current);
- unsigned long flags = builtin_command_data[data_cmd].flags;
-
- if (current->type == ET_special_unit_element)
- {
- ROOT_AND_UNIT *result = malloc (sizeof (ROOT_AND_UNIT));
- result->output_unit = current->e.c->associated_unit;
- result->root = current;
- return result;
- }
-
- if (data_cmd && (flags & CF_root))
- root_command = current;
- else if (data_cmd && (flags & CF_block)
- && builtin_command_data[data_cmd].data == BLOCK_region)
- {
- const OUTPUT_UNIT_LIST *output_units
- = retrieve_output_units (self->document,
- self->output_units_descriptors[OUDT_units]);
- if (data_cmd == CM_copying
- && self->document->global_commands.insertcopying.number > 0)
- {
- const ELEMENT_LIST global_insertcopying
- = self->document->global_commands.insertcopying;
- size_t i;
- for (i = 0; i < global_insertcopying.number; i++)
- {
- const ELEMENT *insertcopying
- = global_insertcopying.list[i];
- ROOT_AND_UNIT *cur_result = html_get_tree_root_element (self,
- insertcopying, find_container);
- if (cur_result->output_unit || cur_result->root)
- return cur_result;
- free (cur_result);
- }
- }
- else if (data_cmd == CM_titlepage
- && self->conf->USE_TITLEPAGE_FOR_TITLE.o.integer > 0
- && self->conf->SHOW_TITLE.o.integer > 0)
- {
- ROOT_AND_UNIT *result = malloc (sizeof (ROOT_AND_UNIT));
- result->output_unit = output_units->list[0];
- result->root = output_units->list[0]->uc.unit_command;
- return result;
- }
- if (output_unit || root_command)
- fatal ("Problem output_unit, root_command");
- ROOT_AND_UNIT *result = malloc (sizeof (ROOT_AND_UNIT));
- memset (result, 0, sizeof (ROOT_AND_UNIT));
- return result;
- }
- else if (find_container
- && html_commands_data[data_cmd].flags & HF_special_variety)
- {
- int j;
- for (j = 0; self->command_special_variety_name_index[j].cmd; j++)
- {
- /* @footnote and possibly @*contents when a separate element is set */
- COMMAND_ID_INDEX cmd_variety_index
- = self->command_special_variety_name_index[j];
- if (cmd_variety_index.cmd == data_cmd)
- {
- char *special_unit_variety
- = self->special_unit_varieties.list[cmd_variety_index.index];
- int special_unit_direction_index
- = html_special_unit_variety_direction_index (self,
- special_unit_variety);
- const OUTPUT_UNIT *special_unit
- = self->global_units_directions[special_unit_direction_index];
- if (special_unit)
- {
- ROOT_AND_UNIT *result = malloc (sizeof (ROOT_AND_UNIT));
- result->output_unit = special_unit;
- result->root = 0;
- return result;
- }
- break;
- }
- }
- }
-
- if (current->e.c->associated_unit)
- {
- ROOT_AND_UNIT *result = malloc (sizeof (ROOT_AND_UNIT));
- result->output_unit = current->e.c->associated_unit;
- result->root = current;
- return result;
- }
- else if (current->parent)
- {
- current = current->parent;
- }
- else
- {
- ROOT_AND_UNIT *result = malloc (sizeof (ROOT_AND_UNIT));
- result->output_unit = 0;
- result->root = root_command;
- return result;
- }
- }
-}
-
-const FILE_NUMBER_NAME *
-html_command_filename (CONVERTER *self, const ELEMENT *command)
-{
- HTML_TARGET *target_info;
-
- target_info = html_get_target (self, command);
-
- if (target_info)
- {
- ROOT_AND_UNIT *root_unit;
-
- if (target_info->filename_set)
- return &target_info->file_number_name;
-
- /* this finds a special element for footnote command if such an element
- exists. This is best, the special element filename is the footnote
- filename. */
-
- root_unit
- = html_get_tree_root_element (self, command, 1);
-
- if (root_unit && root_unit->output_unit
- && root_unit->output_unit->unit_filename)
- {
- target_info->file_number_name.filename
- = root_unit->output_unit->unit_filename;
- if (root_unit->output_unit->unit_type == OU_unit)
- {
- size_t file_index
- = self->output_unit_file_indices[root_unit->output_unit->index];
- target_info->file_number_name.file_number = file_index +1;
- }
- }
- target_info->filename_set = 1;
-
- free (root_unit);
-
- return &target_info->file_number_name;
- }
-
- return 0;
-}
-
-const ELEMENT *
-html_command_root_element_command (CONVERTER *self, const ELEMENT *command)
-{
- HTML_TARGET *target_info;
-
- target_info = html_get_target (self, command);
- if (target_info)
- {
- if (!target_info->root_element_command_set)
- {
- /* in contrast with command_filename() we find the root element through
- the location holding the @footnote command. It is better, as the
- footnote special element is not associated with a root command,
- it is better to stay in the document to find a root element. */
- ROOT_AND_UNIT *root_unit
- = html_get_tree_root_element (self, command, 0);
-
- if (root_unit && root_unit->output_unit
- && root_unit->output_unit->unit_type == OU_unit)
- {
- target_info->root_element_command
- = root_unit->output_unit->uc.unit_command;
- }
- else
- target_info->root_element_command = 0;
-
- target_info->root_element_command_set = 1;
-
- free (root_unit);
-
- }
- return target_info->root_element_command;
- }
- return 0;
-}
-
-const ELEMENT *
-html_command_node (CONVERTER *self, const ELEMENT *command)
-{
- HTML_TARGET *target_info;
-
- target_info = html_get_target (self, command);
- if (target_info)
- {
- if (!target_info->node_command_set)
- {
- /* this finds a special element for footnote command if
- such an element exists */
- ROOT_AND_UNIT *root_unit
- = html_get_tree_root_element (self, command, 1);
- if (root_unit)
- {
- if (root_unit->root)
- {
- const ELEMENT *root_command = root_unit->root;
- if (root_command && root_command->e.c->cmd == CM_node)
- target_info->node_command = root_command;
- else
- {
- const ELEMENT *associated_node
- = lookup_extra_element (root_command,
- AI_key_associated_node);
- if (associated_node)
- target_info->node_command = associated_node;
- }
- }
- free (root_unit);
- }
- target_info->node_command_set = 1;
- }
- return target_info->node_command;
- }
- return 0;
-}
-
-/* return value to be freed */
-/* SPECIFIED_TARGET can be used to specify explicitly the target.
- */
-char *
-html_internal_command_href (CONVERTER *self, const ELEMENT *command,
- const char *source_filename,
- const char *specified_target)
-{
- const HTML_TARGET *target_info;
- TEXT href;
- const char *filename_from;
- const char *target = 0;
- const FILE_NUMBER_NAME *target_filename;
- FILE_NUMBER_NAME *set_target_filename = 0;
-
- if (source_filename)
- filename_from = source_filename;
- else
- filename_from = self->current_filename.filename;
-
-
- if (specified_target)
- target = specified_target;
- else
- {
- const ELEMENT *target_command = command;
- /* for sectioning command prefer the associated node */
- const ELEMENT *associated_node = lookup_extra_element (command,
- AI_key_associated_node);
- if (associated_node)
- target_command = associated_node;
- target_info = html_get_target (self, target_command);
- if (target_info)
- target = target_info->target;
- }
- if (!target)
- return 0;
-
- text_init (&href);
-
- target_filename = html_command_filename (self, command);
- if (!target_filename || !target_filename->filename)
- {
- /* Happens if there are no pages, for example if OUTPUT is set to ''
- as in the test cases. Also for things in @titlepage when
- titlepage is not output. */
- const OUTPUT_UNIT_LIST *output_units
- = retrieve_output_units (self->document,
- self->output_units_descriptors[OUDT_units]);
- if (output_units->list[0]->unit_filename)
- { /* In that case use the first page. */
- set_target_filename = (FILE_NUMBER_NAME *)
- malloc (sizeof (FILE_NUMBER_NAME));
- set_target_filename->filename = output_units->list[0]->unit_filename;
- set_target_filename->file_number
- = self->output_unit_file_indices[0] +1;
- }
- target_filename = set_target_filename;
- }
-
- if (target_filename && target_filename->filename)
- {
- if (!filename_from
- || strcmp (target_filename->filename, filename_from))
- {
- const ELEMENT *command_root_element
- = html_command_root_element_command (self, command);
- char *protected_filename
- = url_protect_file_text (self, target_filename->filename);
-
- text_append (&href, protected_filename);
- free (protected_filename);
-
- /* omit target if the command is an element command, there is only
- one element in file and there is a file in the href */
- if (filename_from && command_root_element)
- {
- const ELEMENT *associated_section
- = lookup_extra_element (command_root_element,
- AI_key_associated_section);
- if (command_root_element == command
- || (associated_section
- && associated_section == command))
- {
- if (target_filename->file_number > 0)
- {
- size_t count_in_file
- = count_elements_in_file_number (self, CEFT_total,
-
target_filename->file_number);
- if (count_in_file == 1)
- target = "";
- }
- }
- }
- }
- }
-
- if (strlen (target))
- {
- text_append_n (&href, "#", 1);
- text_append (&href, target);
- }
-
- if (set_target_filename)
- free (set_target_filename);
-
- if (href.end <= 0)
- {
- free (href.text);
- return 0;
- }
-
- return href.text;
-}
-
-/* return value to be freed */
-/* Return string for linking to $COMMAND with <a href>.
- SOURCE_COMMAND is for messages only.
- SPECIFIED_TARGET can be set to specify explicitly the target
- */
-char *
-html_command_href (CONVERTER *self, const ELEMENT *command,
- const char *source_filename,
- const ELEMENT *source_command,
- const char *specified_target)
-{
- const ELEMENT *manual_content = lookup_extra_container (command,
- AI_key_manual_content);
- if (manual_content)
- {
- return external_node_href (self, command, source_command);
- }
-
- return html_internal_command_href (self, command, source_filename,
- specified_target);
-}
-
-const char *
-html_command_contents_target (CONVERTER *self, const ELEMENT *command,
- enum command_id contents_or_shortcontents)
-{
- const HTML_TARGET *target_info;
-
- if (contents_or_shortcontents == CM_summarycontents)
- contents_or_shortcontents = CM_shortcontents;
-
- target_info = html_get_target (self, command);
- if (target_info)
- {
- if (contents_or_shortcontents == CM_shortcontents)
- return target_info->shortcontents_target;
- else if (contents_or_shortcontents == CM_contents)
- return target_info->contents_target;
- }
- return 0;
-}
-
-static HTML_TARGET *
-get_footnote_location_target (const CONVERTER *self, const ELEMENT *command)
-{
- HTML_TARGET *result
- = find_element_special_target
- (&self->html_special_targets[ST_footnote_location],
- command);
- return result;
-}
-
-const char *
-html_footnote_location_target (const CONVERTER *self, const ELEMENT *command)
-{
- const HTML_TARGET *footnote_location_special_target_info
- = get_footnote_location_target (self, command);
- if (footnote_location_special_target_info)
- return footnote_location_special_target_info->target;
- return 0;
-}
-
-/* Return string for linking to CONTENTS_OR_SHORTCONTENTS associated
- element from $COMMAND with <a href> */
-char *
-html_command_contents_href (CONVERTER *self, const ELEMENT *command,
- enum command_id contents_or_shortcontents,
- const char *source_filename)
-{
- int j;
- const char *filename_from;
- const char *target = html_command_contents_target (self, command,
- contents_or_shortcontents);
-
- if (source_filename)
- filename_from = source_filename;
- else
- filename_from = self->current_filename.filename;
-
- for (j = 0; self->command_special_variety_name_index[j].cmd; j++)
- {
- const COMMAND_ID_INDEX cmd_variety_index
- = self->command_special_variety_name_index[j];
- if (cmd_variety_index.cmd == contents_or_shortcontents)
- {
- TEXT href;
- const FILE_NUMBER_NAME *target_filename = 0;
- const char *special_unit_variety
- = self->special_unit_varieties.list[cmd_variety_index.index];
- int special_unit_direction_index
- = html_special_unit_variety_direction_index (self,
- special_unit_variety);
- const OUTPUT_UNIT *special_unit
- = self->global_units_directions[special_unit_direction_index];
- if (special_unit)
- {
- target_filename = html_command_filename (self,
- special_unit->uc.special_unit_command);
- }
-
- text_init (&href);
-
- if (target_filename && target_filename->filename
- && (!filename_from
- || strcmp (target_filename->filename, filename_from)))
- text_append (&href, target_filename->filename);
-
- if (target && strlen (target))
- {
- text_append_n (&href, "#", 1);
- text_append (&href, target);
- }
-
- if (href.end <= 0)
- {
- free (href.text);
- return 0;
- }
- return href.text;
- }
- }
- return 0;
-}
-
-/*
- SPECIFIED_TARGET can be set to specify explicitly the target.
- TARGET_FILENAME_IN can be set to specify explicitly the file.
- Returned string to be freed by the caller.
- */
-char *
-html_footnote_location_href (CONVERTER *self, const ELEMENT *command,
- const char *source_filename,
- const char *specified_target,
- const char *target_filename_in)
-{
- TEXT href;
- const char *filename_from;
- HTML_TARGET *footnote_location_target_info;
- const char *target = 0;
- const char *target_filename = target_filename_in;
-
- if (source_filename)
- filename_from = source_filename;
- else
- filename_from = self->current_filename.filename;
-
- footnote_location_target_info = get_footnote_location_target (self, command);
-
- if (specified_target)
- target = specified_target;
- else
- target = footnote_location_target_info->target;
-
- /* In the default footnote formatting functions, which calls
- footnote_location_href, the target file is always known as the
- footnote in the document appears before the footnote text formatting.
- $target_filename is therefore always defined. It is a good thing
- for the case of @footnote being formatted more than once (in multiple
- @insertcopying for instance) as the file found just below may not be the
- correct one in such a case.
- */
- if (!target_filename)
- {
- if (footnote_location_target_info
- && footnote_location_target_info->file_number_name.filename)
- {
- target_filename
- = footnote_location_target_info->file_number_name.filename;
- }
- else
- {
- /* in contrast with command_filename() we find the location holding
- the @footnote command, not the footnote element with footnotes */
- ROOT_AND_UNIT *root_unit
- = html_get_tree_root_element (self, command, 0);
-
- if (root_unit && root_unit->output_unit
- && root_unit->output_unit->unit_filename)
- {
- size_t file_index
- = self->output_unit_file_indices[root_unit->output_unit->index];
- footnote_location_target_info->file_number_name.file_number
- = file_index +1;
- footnote_location_target_info->file_number_name.filename
- = root_unit->output_unit->unit_filename;
- }
- footnote_location_target_info->filename_set = 1;
-
- free (root_unit);
- target_filename
- = footnote_location_target_info->file_number_name.filename;
- }
- }
-
- text_init (&href);
- text_append (&href, "");
- if (target_filename
- && (!filename_from || strcmp (target_filename, filename_from)))
- {
- text_append (&href, target_filename);
- }
- if (target && strlen (target))
- {
- text_append_n (&href, "#", 1);
- text_append (&href, target);
- }
- return href.text;
-}
-
-/* the returned TREE_ADDED_ELEMENTS may not be NUL but have a NUL tree
- field, for instance in the case of an empty sectioning element
- */
-TREE_ADDED_ELEMENTS *
-html_internal_command_tree (CONVERTER *self, const ELEMENT *command,
- int no_number)
-{
- TREE_ADDED_ELEMENTS *tree;
- HTML_TARGET *target_info;
-
- target_info = html_get_target (self, command);
- if (target_info)
- {
- if (!target_info->tree.status)
- {
- tree = &target_info->tree;
- tree->status = tree_added_status_elements_added;
- if (command->type == ET_special_unit_element)
- {
- const char *special_unit_variety
- = command->e.c->associated_unit->special_unit_variety;
- ELEMENT *heading_tree = special_unit_info_tree (self,
- SUIT_type_heading, special_unit_variety);
- tree->tree = heading_tree;
- }
- else if (command->e.c->cmd == CM_node
- || command->e.c->cmd == CM_anchor)
- {
- ELEMENT *root_code = new_element_added (tree, ET__code);
- add_to_contents_as_array (root_code, command->e.c->args.list[0]);
- tree->tree = root_code;
- add_tree_to_build (self, tree->tree);
- }
- else if (command->e.c->cmd == CM_float)
- {
- tree->tree = float_type_number (self, command);
- tree->status = tree_added_status_new_tree;
- add_tree_to_build (self, tree->tree);
- }
- else if (command->e.c->args.number <= 0
- || command->e.c->args.list[0]->e.c->contents.number <= 0)
- { /* no argument, nothing to do */
- tree->status = tree_added_status_no_tree;
- }
- else
- {
- const char *section_number
- = lookup_extra_string (command, AI_key_section_number);
- if (section_number && !self->conf->NUMBER_SECTIONS.o.integer ==
0)
- {
- NAMED_STRING_ELEMENT_LIST *replaced_substrings
- = new_named_string_element_list ();
- ELEMENT *e_number = new_text_element (ET_normal_text);
- ELEMENT *section_title_copy
- = copy_tree (command->e.c->args.list[0]);
-
- add_element_to_named_string_element_list (
- replaced_substrings, "section_title",
- section_title_copy);
- text_append (e_number->e.text, section_number);
- add_element_to_named_string_element_list (
- replaced_substrings, "number", e_number);
-
- if (command->e.c->cmd == CM_appendix)
- {
- int status;
- int section_level = lookup_extra_integer (command,
- AI_key_section_level, &status);
- if (section_level == 1)
- {
- tree->tree
- = html_cdt_tree (
- "Appendix {number} {section_title}",
- self, replaced_substrings, 0);
- }
- }
- if (!tree->tree)
- /* TRANSLATORS: numbered section title */
- tree->tree = html_cdt_tree ("{number} {section_title}",
- self, replaced_substrings, 0);
-
- destroy_named_string_element_list (replaced_substrings);
- tree->status = tree_added_status_new_tree;
- add_tree_to_build (self, tree->tree);
- }
- else
- {
- tree->status = tree_added_status_reused_tree;
- tree->tree = command->e.c->args.list[0];
- }
-
- target_info->tree_nonumber.tree = command->e.c->args.list[0];
- target_info->tree_nonumber.status =
tree_added_status_reused_tree;
- }
- }
-
- if (no_number && target_info->tree_nonumber.tree)
- return &target_info->tree_nonumber;
- else
- return &target_info->tree;
- }
-
- return 0;
-}
-
-TREE_ADDED_ELEMENTS *
-html_external_command_tree (CONVERTER *self, const ELEMENT *command,
- ELEMENT *manual_content)
-{
- TREE_ADDED_ELEMENTS *tree;
-
- ELEMENT *root_code;
- ELEMENT *open_p;
- ELEMENT *close_p;
-
- ELEMENT *node_content = lookup_extra_container (command,
- AI_key_node_content);
-
- tree = new_tree_added_elements (tree_added_status_elements_added);
-
- root_code = new_element_added (tree, ET__code);
- open_p = new_text_element_added (tree, ET_normal_text);
- close_p = new_text_element_added (tree, ET_normal_text);
-
- text_append_n (open_p->e.text, "(", 1);
- text_append_n (close_p->e.text, ")", 1);
-
- add_to_element_contents (root_code, open_p);
- add_to_contents_as_array (root_code, manual_content);
- add_to_element_contents (root_code, close_p);
- if (node_content)
- add_to_contents_as_array (root_code, node_content);
-
- tree->tree = root_code;
- add_tree_to_build (self, tree->tree);
- return tree;
-}
-
-TREE_ADDED_ELEMENTS *
-html_command_tree (CONVERTER *self, const ELEMENT *command, int no_number)
-{
-
- ELEMENT *manual_content = lookup_extra_container (command,
- AI_key_manual_content);
- if (manual_content)
- {
- return html_external_command_tree (self, command, manual_content);
- }
-
- return html_internal_command_tree (self, command, no_number);
-}
-
-/* return value to be freed by caller */
-char *
-html_internal_command_text (CONVERTER *self, const ELEMENT *command,
- const enum html_text_type type)
-{
- HTML_TARGET *target_info = html_get_target (self, command);
-
- if (target_info)
- {
- if (target_info->command_text[type])
- return strdup (target_info->command_text[type]);
- else
- {
- ELEMENT *tree_root;
- char *explanation = 0;
- const char *context_name;
- ELEMENT *selected_tree;
- TREE_ADDED_ELEMENTS *command_tree
- = html_internal_command_tree (self, command, 0);
-
- if (!command_tree->tree)
- return strdup ("");
-
- if (command->e.c->cmd)
- {
- const char *command_name = element_command_name (command);
- context_name = command_name;
- xasprintf (&explanation, "command_text:%s @%s",
- html_command_text_type_name[type],
- command_name);
- }
- else
- {
- context_name = type_data[command->type].name;
- if (command->type == ET_special_unit_element)
- {
- char *special_unit_variety
- = command->e.c->associated_unit->special_unit_variety;
- xasprintf (&explanation, "command_text %s",
- special_unit_variety);
- }
- }
- html_new_document_context (self, context_name, explanation, 0);
-
- if ((type == HTT_text_nonumber || type == HTT_string_nonumber)
- && target_info->tree_nonumber.tree)
- selected_tree = target_info->tree_nonumber.tree;
- else
- selected_tree = command_tree->tree;
-
- if (type == HTT_string)
- {
- tree_root = new_element (ET__string);
- add_to_contents_as_array (tree_root, selected_tree);
- add_tree_to_build (self, tree_root);
- }
- else
- tree_root = selected_tree;
-
- html_set_multiple_conversions (self, 0);
- push_element_reference_stack_element (&self->referred_command_stack,
- command, command->hv);
- target_info->command_text[type]
- = html_convert_tree (self, tree_root, explanation);
- free (explanation);
- pop_element_reference_stack (&self->referred_command_stack);
-
- html_unset_multiple_conversions (self);
-
- html_pop_document_context (self);
-
- if (type == HTT_string)
- {
- remove_tree_to_build (self, tree_root);
- destroy_element (tree_root);
- }
- return strdup (target_info->command_text[type]);
- }
- }
-
- /*
- Can happen
- * if USE_NODES is 0 and there are no sectioning commands.
- * if a special element target was set to undef in user defined code.
- * for @*ref with missing targets (maybe @novalidate needed in that case).
- * for @node header if the node consist only in spaces (example in
sectioning
- in_menu_only_special_ascii_spaces_node).
- * for multiple targets with the same name, eg both @node and @anchor
- * with @inforef with node argument only, without manual argument.
- */
-
- return 0;
-}
-
-/* return value to be freed by caller */
-char *
-html_command_text (CONVERTER *self, const ELEMENT *command,
- const enum html_text_type type)
-{
- char *result;
- ELEMENT *manual_content = lookup_extra_container (command,
- AI_key_manual_content);
- if (manual_content)
- {
- char *context_str;
- ELEMENT *tree_root;
- TREE_ADDED_ELEMENTS *command_tree
- = html_external_command_tree (self, command, manual_content);
- if (type == HTT_string)
- {
- tree_root = new_element (ET__string);
- add_to_contents_as_array (tree_root, command_tree->tree);
- add_tree_to_build (self, tree_root);
- }
- else
- tree_root = command_tree->tree;
-
- if (command->e.c->cmd)
- /* this never happens, as the external node label tree
- element is never directly an @-command. It can be an @-command
- argument, in a menu, or a reconstituted tree. */
- xasprintf (&context_str, "command_text %s @%s",
- html_command_text_type_name[type],
- element_command_name (command));
- else if (command->type)
- xasprintf (&context_str, "command_text %s %s",
- html_command_text_type_name[type],
- type_data[command->type].name);
- else
- xasprintf (&context_str, "command_text %s ",
- html_command_text_type_name[type]);
-
- result = convert_tree_new_formatting_context (self, tree_root,
- context_str,
- "command_text-manual_content", 0, 0);
-
- free (context_str);
-
- if (type == HTT_string)
- {
- remove_tree_to_build (self, tree_root);
- destroy_element (tree_root);
- }
- destroy_tree_added_elements (self, command_tree);
- return result;
- }
-
- return html_internal_command_text (self, command, type);
-}
-
-/*
- if OUTPUT_UNITS is defined, the first output unit is used if a proper
- top output unit is not found.
- */
-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");
- const ELEMENT *section_top = document->global_commands.top;
-
- if (section_top)
- return section_top->e.c->associated_unit;
- else if (node_top)
- return node_top->e.c->associated_unit;
- else if (output_units)
- return output_units->list[0];
-
- return 0;
-}
-
-static int
-unit_is_top_output_unit (CONVERTER *self, const OUTPUT_UNIT *output_unit)
-{
- OUTPUT_UNIT *top_output_unit = html_get_top_unit (self->document, 0);
- return (top_output_unit && top_output_unit == output_unit);
-}
-
-/* return value to be freed by caller */
-char *
-html_command_description (CONVERTER *self, const ELEMENT *command,
- const enum html_text_type type)
-{
- HTML_TARGET *target_info;
-
- ELEMENT *manual_content = lookup_extra_element (command,
- AI_key_manual_content);
- if (manual_content)
- return 0;
-
- target_info = html_get_target (self, command);
-
- if (target_info)
- {
- if (target_info->command_description[type])
- return strdup (target_info->command_description[type]);
- else
- {
- const ELEMENT *node = 0;
- ELEMENT *tree_root;
- char *explanation;
- char *context_name;
- const ELEMENT *node_description;
- int formatted_nodedescription_nr = 0;
- HTML_TARGET *node_target_info;
- char *multiple_formatted = 0;
- ELEMENT *description_element;
- const char *command_name;
- enum command_id cmd = element_builtin_cmd (command);
-
- if (command->type == ET_special_unit_element)
- return 0;
-
- if (cmd == CM_float || cmd == CM_anchor)
- return 0;
-
- if (cmd == CM_node)
- node = command;
- else
- node = lookup_extra_element (command, AI_key_associated_node);
-
- if (!node)
- return 0;
-
- node_description
- = lookup_extra_element (node, AI_key_node_description);
-
- if (!node_description)
- return 0;
-
- node_target_info = html_get_target (self, node);
- node_target_info->formatted_nodedescription_nr++;
- formatted_nodedescription_nr
- = node_target_info->formatted_nodedescription_nr;
-
- if (formatted_nodedescription_nr > 1)
- {
- xasprintf (&multiple_formatted,
- "node-description-%d",
- formatted_nodedescription_nr);
- }
-
- if (node_description->e.c->cmd == CM_nodedescription)
- description_element = node_description->e.c->args.list[0];
- else
- {
- description_element = new_element (ET_NONE);
- description_element->e.c->contents
- = node_description->e.c->contents;
- add_tree_to_build (self, description_element);
- }
-
- command_name = element_command_name (command);
- xasprintf (&context_name, "%s description", command_name);
- xasprintf (&explanation, "command_description:%s @%s",
- html_command_text_type_name[type],
- command_name);
-
- if (type == HTT_string)
- {
- tree_root = new_element (ET__string);
- add_to_contents_as_array (tree_root, description_element);
- add_tree_to_build (self, tree_root);
- }
- else
- tree_root = description_element;
-
- target_info->command_description[type]
- = convert_tree_new_formatting_context (self, tree_root,
- context_name, multiple_formatted,
- explanation, 0);
- free (context_name);
- free (explanation);
-
- if (formatted_nodedescription_nr > 1)
- free (multiple_formatted);
- if (node_description->e.c->cmd != CM_nodedescription)
- {
- remove_tree_to_build (self, description_element);
- description_element->e.c->contents.list = 0;
- destroy_element (description_element);
- }
- if (type == HTT_string)
- {
- remove_tree_to_build (self, tree_root);
- destroy_element (tree_root);
- }
- return strdup (target_info->command_description[type]);
- }
- }
- /*
- Can happen
- * if USE_NODES is 0 and there are no sectioning commands.
- * if a special element target was set to undef in user defined code.
- * for @*ref with missing targets (maybe @novalidate needed in that case).
- * for @node header if the node consist only in spaces (example in
sectioning
- in_menu_only_special_ascii_spaces_node).
- * for multiple targets with the same name, eg both @node and @anchor
- * with @inforef with node argument only, without manual argument.
- */
- return 0;
-}
-
-/* return value to be freed by caller */
-char *
-from_element_direction (CONVERTER *self, int direction,
- enum html_text_type type,
- const OUTPUT_UNIT *source_unit,
- const char *source_filename,
- const ELEMENT *source_command)
-{
- const char *filename_from;
- const OUTPUT_UNIT *target_unit = 0;
- const ELEMENT *command = 0;
-
- /* this means that the direction given in Perl was not found in C */
- if (direction < 0)
- return 0;
-
- if (!source_unit)
- source_unit = self->current_output_unit;
-
- if (source_filename)
- filename_from = source_filename;
- else
- filename_from = self->current_filename.filename;
-
- /* To debug:
- fprintf (stderr, "FED: %s %s\n", html_command_text_type_name[type],
- self->direction_unit_direction_name[direction]);
- */
-
- if (direction < D_direction_Space)
- target_unit = self->global_units_directions[direction];
- else if (direction > NON_SPECIAL_DIRECTIONS_NR - 1)
- {
- /* special units (global) directions */
- target_unit
- = self->global_units_directions
- [D_direction_Last + direction - NON_SPECIAL_DIRECTIONS_NR +1];
- }
- else if ((!source_unit || unit_is_top_output_unit (self, source_unit))
- && self->conf->TOP_NODE_UP_URL.o.string
- && (direction == D_direction_Up || direction == D_direction_NodeUp))
- {
- if (type == HTT_href)
- return strdup (self->conf->TOP_NODE_UP_URL.o.string);
- else if (type == HTT_text || type == HTT_node
- || type == HTT_string || type == HTT_section)
- {
- if (self->conf->TOP_NODE_UP.o.string)
- return strdup (self->conf->TOP_NODE_UP.o.string);
- else
- return 0;
- }
- else
- {
- char *msg;
- xasprintf (&msg, "type %d not available for TOP_NODE_UP\n", type);
- fatal (msg);
- free (msg);
- }
- }
- else if (!target_unit && source_unit
- && source_unit->directions[direction - (D_direction_Space +1)])
- {
- target_unit = source_unit->directions[direction - (D_direction_Space
+1)];
- }
-
- if (target_unit)
- {
- if (target_unit->unit_type == OU_external_node_unit)
- {
- const ELEMENT *external_node_element
- = target_unit->uc.unit_command;
- if (type == HTT_href)
- return external_node_href (self, external_node_element,
- source_command);
- else if (type == HTT_text || type == HTT_node)
- return html_command_text (self, external_node_element, 0);
- else if (type == HTT_string)
- return html_command_text (self, external_node_element,
- HTT_string);
- }
- else if (type == HTT_node)
- {
- 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_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;
-}
-
-
-
-const char *
-html_special_unit_info (const CONVERTER *self,
- enum special_unit_info_type type,
- const char *special_unit_variety)
-{
- /* number is index +1 */
- size_t number = find_string (&self->special_unit_varieties,
- special_unit_variety);
- int i = number -1;
-
- return self->special_unit_info[type][i];
-}
-
-
-
-/* html_attribute_class */
-
-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++;
- }
-}
-
-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;
-}
-
-char *
-html_attribute_class (CONVERTER *self, const char *element,
- const STRING_LIST *classes)
-{
- TEXT result;
- char *style = 0;
- size_t i;
- int class_nr = 0;
- if (!classes || classes->number <= 0
- || self->conf->NO_CSS.o.integer > 0)
- {
- if (!strcmp (element, "span"))
- return strdup ("");
- else
- {
- char *result;
- xasprintf (&result, "<%s", element);
- return result;
- }
- }
-
- if (self->conf->INLINE_CSS_STYLE.o.integer > 0)
- {
- size_t i;
- TEXT inline_styles;
- text_init (&inline_styles);
- int style_nr = 0;
- for (i = 0; i < classes->number; i++)
- {
- const char *style_class = classes->list[i];
- char *selector;
- const CSS_SELECTOR_STYLE *selector_style;
-
- xasprintf (&selector, "%s.%s", element, style_class);
- selector_style
- = find_css_selector_style (&self->css_element_class_styles,
- selector);
- free (selector);
- if (selector_style && selector_style->style)
- {
- if (style_nr)
- text_printf (&inline_styles, ";%s", selector_style->style);
- else
- text_append (&inline_styles, selector_style->style);
- style_nr++;
- }
- }
- if (inline_styles.end)
- {
- xasprintf (&style, " style=\"%s\"", inline_styles.text);
- }
- free (inline_styles.text);
- }
- else
- {
- size_t i;
- for (i = 0; i < classes->number; i++)
- {
- const char *style_class = classes->list[i];
- char *selector;
-
- xasprintf (&selector, "%s.%s", element, style_class);
- collect_css_element_class (self, selector);
- free (selector);
- }
- }
- text_init (&result);
- text_printf (&result, "<%s class=\"", element);
- for (i = 0; i < classes->number; i++)
- {
- const char *class_name = classes->list[i];
- char *protected_class = protect_class_name (class_name);
- if (class_nr)
- text_printf (&result, " %s", protected_class);
- else
- text_append (&result, protected_class);
- free (protected_class);
- class_nr++;
- }
- text_append_n (&result, "\"", 1);
- if (style)
- {
- text_append (&result, style);
- free (style);
- }
- return result.text;
-}
-
-
-
-/* formatting functions */
-
-/* this function allows to call a conversion function associated to
- a COMMAND_CONVERSION different from the ELEMENT and CMD arguments
- associated command conversion */
-static void
-conversion_function_cmd_conversion (CONVERTER *self,
- COMMAND_CONVERSION_FUNCTION *command_conversion,
- const enum command_id cmd, const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (command_conversion->status == FRS_status_internal)
- {
- (command_conversion->command_conversion)
- (self, cmd, element, args_formatted,
- content, result);
- }
- else
- {
- FORMATTING_REFERENCE *formatting_reference
- = command_conversion->formatting_reference;
- if (formatting_reference->status > 0)
- call_commands_conversion (self, cmd, formatting_reference,
- element, args_formatted, content,
- result);
-
- }
-}
-
-char *
-html_default_format_comment (CONVERTER *self, const char *text)
-{
- char *with_space;
- char *result;
-
- xasprintf (&with_space, " %s", text);
- result = xml_comment (self, with_space);
- free (with_space);
- return result;
-}
-
-char *
-format_comment (CONVERTER *self, const char *text)
-{
- FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_comment];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_comment (self, text);
- }
- else
- {
- return call_formatting_function_format_comment (self,
- formatting_reference,
- text);
- }
-}
-
-void
-html_default_format_separate_anchor (CONVERTER *self, const char *id,
- const char *class, TEXT *result)
-{
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (class, classes);
-
- /* html_attribute_class would not work with span, so if span is
- used, html_attribute_class should not be used */
- attribute_class = html_attribute_class (self, "a", classes);
- text_append (result, attribute_class);
- text_printf (result, " id=\"%s\"></a>", id);
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-format_separate_anchor (CONVERTER *self, const char *id,
- const char *class, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_separate_anchor];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_separate_anchor (self, id, class, result);
- }
- else
- {
- char *separate_anchor
- = call_formatting_function_format_separate_anchor (self,
- formatting_reference, id, class);
- text_append (result, separate_anchor);
- free (separate_anchor);
- }
-}
-
-const char *
-direction_string (CONVERTER *self, int direction,
- enum direction_string_type string_type,
- enum direction_string_context context)
-{
- int direction_unit_direction_idx = direction;
-
- /* Perl direction not found in C */
- if (direction < 0)
- return 0;
-
- /* To debug:
- fprintf (stderr, "DS: %d %s %s %s\n", direction,
- direction_string_type_names[string_type],
- direction_string_context_names[context],
- self->direction_unit_direction_name[direction]);
- */
- if (direction >= FIRSTINFILE_MIN_IDX && direction <= FIRSTINFILE_MAX_IDX)
- {
- /* in general the offset is negative */
- direction += FIRSTINFILE_OFFSET;
- direction_unit_direction_idx = direction;
- }
- else if (direction > NON_SPECIAL_DIRECTIONS_NR - 1)
- direction -= FIRSTINFILE_NR;
-
- if (!self->directions_strings[string_type][direction][context]
- && string_type < TDS_TRANSLATED_MAX_NR)
- {
- HTML_DIRECTION_STRING_TRANSLATED *dir_translated
- = &self->translated_direction_strings[string_type][direction];
- if (dir_translated->to_convert)
- {
- char *result_string;
- TEXT translation_context;
- char *context_str;
- ELEMENT *translated_tree;
- ELEMENT *converted_tree;
- const char *direction_name;
- text_init (&translation_context);
- direction_name
- = self->direction_unit_direction_name[direction_unit_direction_idx];
- text_append (&translation_context, direction_name);
-
- if (direction == RUD_type_This)
- text_append_n (&translation_context, " (current section)", 18);
- text_append_n (&translation_context, " direction ", 11);
- text_append (&translation_context,
- direction_type_translation_context[string_type]);
- translated_tree = html_pcdt_tree (translation_context.text,
- dir_translated->to_convert,
- self, 0);
- free (translation_context.text);
- if (context == TDS_context_string)
- {
- converted_tree = new_element (ET__string);
- add_to_element_contents (converted_tree, translated_tree);
- }
- else
- converted_tree = translated_tree;
-
- xasprintf (&context_str, "DIRECTION %s (%s/%s)", direction_name,
- direction_string_type_names[string_type],
- direction_string_context_names[context]);
-
- add_tree_to_build (self, converted_tree);
- result_string
- = convert_tree_new_formatting_context (self, converted_tree,
- context_str, 0, context_str, 0);
-
- remove_tree_to_build (self, converted_tree);
- free (context_str);
-
- if (context == TDS_context_string)
- destroy_element (converted_tree);
- destroy_element_and_children (translated_tree);
- self->directions_strings[string_type][direction][context]
- = result_string;
- }
- else
- {
- const char *context_converted_string = 0;
- if (dir_translated->converted[context])
- context_converted_string = dir_translated->converted[context];
- else if (context == TDS_context_string)
- context_converted_string
- = dir_translated->converted[TDS_context_normal];
- if (context_converted_string)
- {
- char *translated_string
- = html_cdt_string (context_converted_string, self, 0, 0);
- char *result_string
- = html_substitute_non_breaking_space (self, translated_string);
- self->directions_strings[string_type][direction][context]
- = result_string;
- free (translated_string);
- }
- }
- }
- return self->directions_strings[string_type][direction][context];
-}
-
-static void
-direction_href_attributes (CONVERTER *self, int direction, TEXT *result)
-{
- if (self->conf->USE_ACCESSKEY.o.integer > 0)
- {
- const char *accesskey
- = direction_string (self, direction, TDS_type_accesskey,
- TDS_context_string);
- if (accesskey && strlen (accesskey))
- text_printf (result, " accesskey=\"%s\"", accesskey);
- }
-
- if (self->conf->USE_REL_REV.o.integer > 0)
- {
- const char *button_rel
- = direction_string (self, direction, TDS_type_rel,
- TDS_context_string);
- if (button_rel && strlen (button_rel))
- text_printf (result, " rel=\"%s\"", button_rel);
- }
-}
-
-static char *
-direction_a (CONVERTER *self, int direction, const char *href,
- const char *text, int omit_rel)
-{
- TEXT result;
- text_init (&result);
- text_printf (&result, "<a href=\"%s\"", href);
- if (!omit_rel)
- direction_href_attributes (self, direction, &result);
- text_append_n (&result, ">", 1);
- text_append (&result, text);
- text_append_n (&result, "</a>", 4);
- return result.text;
-}
-
-static char *copiable_link_array[] = {"copiable-link"};
-static const STRING_LIST copiable_link_classes = {copiable_link_array, 1, 1};
-
-static char *
-get_copiable_anchor (CONVERTER *self, const char *id)
-{
- if (id && strlen (id) && self->conf->COPIABLE_LINKS.o.integer > 0)
- {
- TEXT result;
- char *attribute_class = html_attribute_class (self, "a",
- &copiable_link_classes);
- text_init (&result);
- text_append (&result, attribute_class);
- free (attribute_class);
- text_printf (&result, " href=\"#%s\"> %s</a>",
- id, self->special_character[SC_paragraph_symbol].string);
- return result.text;
- }
- return 0;
-}
-
-void
-html_default_format_heading_text (CONVERTER *self, const enum command_id cmd,
- const STRING_LIST *classes, const char *text,
- int level, const char *id, const ELEMENT *element,
- const char *target, TEXT *result)
-{
- int heading_level = level;
- char *heading_html_element;
- const char *heading_target;
- char *copiable_anchor;
-
- if (!id && text[strspn (text, whitespace_chars)] == '\0')
- return;
-
- /* This happens with titlefont in title for instance */
- if (html_in_string (self))
- {
- text_append (result, text);
- if (cmd != CM_titlefont)
- text_append_n (result, "\n", 1);
- return;
- }
-
- if (level < 1)
- heading_level = 1;
- else
- {
- /* TODO if defaults of converter options become more used in C code,
- it could be relevant to predefine a table with code generated
- by a specific Perl script with options defaults instead of
- hardcoding */
- int max_header_level = 4;
- if (self->conf->MAX_HEADER_LEVEL.o.integer >= 1)
- max_header_level = self->conf->MAX_HEADER_LEVEL.o.integer;
- else if (self->conf->MAX_HEADER_LEVEL.o.integer == 0)
- max_header_level = 1;
-
- if (level > max_header_level)
- heading_level = max_header_level;
- }
- xasprintf (&heading_html_element, "h%d", heading_level);
-
- char *attribute_class
- = html_attribute_class (self, heading_html_element, classes);
- text_append (result, attribute_class);
- free (heading_html_element);
- free (attribute_class);
-
- if (id)
- {
- text_printf (result, " id=\"%s\"", id);
- /* The ID of this heading is likely the point the user would prefer being
- linked to over the $target, since that's where they would be seeing a
- copiable anchor. */
- heading_target = id;
- }
- else
- {
- heading_target = target;
- }
-
- text_append_n (result, ">", 1);
-
- copiable_anchor = get_copiable_anchor (self, heading_target);
-
- if (copiable_anchor)
- text_append_n (result, "<span>", 6);
-
- text_append (result, text);
-
- if (copiable_anchor)
- {
- text_append (result, copiable_anchor);
- free (copiable_anchor);
- text_append_n (result, "</span>", 7);
- }
-
- text_printf (result, "</h%d>", heading_level);
- if (cmd != CM_titlefont)
- text_append_n (result, "\n", 1);
- if (cmd == CM_part && self->conf->DEFAULT_RULE.o.string
- && strlen (self->conf->DEFAULT_RULE.o.string))
- {
- text_append (result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (result, "\n", 1);
- }
-}
-
-static char *toc_numbered_mark_array[] = {"toc-numbered-mark"};
-static const STRING_LIST toc_numbered_mark_classes
- = {toc_numbered_mark_array, 1, 1};
-
-char *
-html_default_format_contents (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element, const char *source_filename)
-{
- const char *filename_from;
- int is_contents = (cmd == CM_contents);
- TEXT result;
- const CONST_ELEMENT_LIST *root_children;
- const ELEMENT *section_root;
- int min_root_level;
- int max_root_level;
- int status;
- int has_toplevel_contents = 0;
- size_t i;
- int link_to_toc = 0;
- const STRING_LIST *toc_ul_classes = 0;
-
- if (source_filename)
- filename_from = source_filename;
- else
- filename_from = self->current_filename.filename;
-
- text_init (&result);
- text_append (&result, "");
-
- if (self->document->sections_list
- && self->document->sections_list->number > 0)
- {
- const ELEMENT *first = self->document->sections_list->list[0];
- section_root = lookup_extra_element_oot (first, AI_key_sectioning_root);
- /* this should not happen with $sections_list as set from Structuring
- sectioning_structure, but could happen with another source.
- We consider that if sectioning_root is set as usual, all the
- fields are set consistently with what sectioning_structure would
- have set. */
- if (!section_root)
- return result.text;
- }
- else
- return result.text;
-
- root_children = lookup_extra_contents (section_root, AI_key_section_childs);
- min_root_level = lookup_extra_integer (root_children->list[0],
- AI_key_section_level,
- &status);
- max_root_level = min_root_level;
-
- for (i = 0; i < root_children->number; i++)
- {
- const ELEMENT *top_section = root_children->list[i];
- int section_level
- = lookup_extra_integer (top_section, AI_key_section_level, &status);
- if (section_level < min_root_level)
- min_root_level = section_level;
- if (section_level > max_root_level)
- max_root_level = section_level;
- }
- /* chapter level elements are considered top-level here. */
- if (max_root_level < 1)
- max_root_level = 1;
- /*
- fprintf (stderr, "ROOT_LEVEL Max: %d, Min: %d\n", max_root_level,
- min_root_level);
- */
-
- if ((is_contents && !self->conf->BEFORE_TOC_LINES.o.string)
- || (!is_contents && !self->conf->BEFORE_SHORT_TOC_LINES.o.string))
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "div", classes);
- text_append (&result, attribute_class);
- free (attribute_class);
- destroy_strings_list (classes);
- text_append_n (&result, ">\n", 2);
- }
- else if (is_contents)
- text_append (&result, self->conf->BEFORE_TOC_LINES.o.string);
- else
- text_append (&result, self->conf->BEFORE_SHORT_TOC_LINES.o.string);
-
- if (self->conf->NUMBER_SECTIONS.o.integer > 0)
- toc_ul_classes = &toc_numbered_mark_classes;
- if (root_children->number > 1)
- {
- char *attribute_class;
- attribute_class = html_attribute_class (self, "ul", toc_ul_classes);
- text_append (&result, attribute_class);
- free (attribute_class);
- text_append_n (&result, ">\n", 2);
- has_toplevel_contents = 1;
- }
-
- link_to_toc = (!is_contents && self->conf->SHORT_TOC_LINK_TO_TOC.o.integer > 0
- && self->conf->contents.o.integer > 0
- && (!self->conf->CONTENTS_OUTPUT_LOCATION.o.string
- || strcmp (self->conf->CONTENTS_OUTPUT_LOCATION.o.string,
- "inline")
- || self->document->global_commands.contents.number > 0
- || self->document->global_commands.shortcontents.number > 0));
-
- for (i = 0; i < root_children->number; i++)
- {
- const ELEMENT *top_section = root_children->list[i];
- const ELEMENT *section = top_section;
- while (section)
- {
- int section_level = lookup_extra_integer (section,
AI_key_section_level,
- &status);
- const CONST_ELEMENT_LIST *section_childs
- = lookup_extra_contents (section, AI_key_section_childs);
- if (section->e.c->cmd != CM_top)
- {
- char *text;
- char *href;
- const char *toc_id = html_command_contents_target (self,
section, cmd);
-
- text = html_command_text (self, section, 0);
-
- if (link_to_toc)
- href = html_command_contents_href (self, section, CM_contents,
- filename_from);
- else
- href = html_command_href (self, section, filename_from, 0, 0);
- if (text && strlen (text))
- {
- /* no indenting for shortcontents */
- if (is_contents)
- {
- int i;
- for (i = 0; i < 2 * (section_level - min_root_level);
i++)
- text_append_n (&result, " ", 1);
- }
- text_append_n (&result, "<li>", 4);
- if ((toc_id && strlen (toc_id)) || href)
- {
- const ELEMENT *associated_node
- = lookup_extra_element (section,
- AI_key_associated_node);
- text_append_n (&result, "<a", 2);
- if (toc_id && strlen (toc_id))
- text_printf (&result, " id=\"%s\"", toc_id);
- if (href)
- text_printf (&result, " href=\"%s\"", href);
- if (associated_node)
- {
- int is_index = (associated_node->flags & EF_isindex);
- if (is_index)
- text_append_n (&result, " rel=\"index\"", 12);
- }
- text_append_n (&result, ">", 1);
- text_append (&result, text);
- text_append_n (&result, "</a>", 4);
- }
- else
- {
- text_append (&result, text);
- }
- }
- free (text);
- free (href);
- }
- else
- {
- if (section_childs && section_childs->number > 0
- && has_toplevel_contents)
- text_append_n (&result, "<li>", 4);
- }
- if (section_childs
- && (is_contents || section_level < max_root_level))
- {
- char *attribute_class;
- /* no indenting for shortcontents */
- if (is_contents)
- {
- int i;
- text_append_n (&result, "\n", 1);
- for (i = 0; i < 2 * (section_level - min_root_level); i++)
- text_append_n (&result, " ", 1);
- }
- attribute_class
- = html_attribute_class (self, "ul", toc_ul_classes);
- text_append (&result, attribute_class);
- free (attribute_class);
- text_append_n (&result, ">\n", 2);
- section = section_childs->list[0];
- }
- else
- {
- const ELEMENT * const *section_directions
- = lookup_extra_directions (section, AI_key_section_directions);
- if (section_directions
- && section_directions[D_next]
- && section->e.c->cmd != CM_top)
- {
- text_append_n (&result, "</li>\n", 6);
- if (section == top_section)
- break;
- section = section_directions[D_next];
- }
- else
- {
- int is_top_section = 0;
- if (section == top_section)
- {
- if (section->e.c->cmd != CM_top)
- text_append_n (&result, "</li>\n", 6);
- break;
- }
- while (1)
- {
- int section_level;
- int i;
-
- const ELEMENT * const *section_directions
- = lookup_extra_directions (section,
- AI_key_section_directions);
- if (!section_directions
- || !section_directions[D_up])
- break;
-
- section = section_directions[D_up];
-
- section_level = lookup_extra_integer (section,
- AI_key_section_level, &status);
- text_append_n (&result, "</li>\n", 6);
-
- for (i = 0; i < 2 * (section_level - min_root_level);
i++)
- text_append_n (&result, " ", 1);
- text_append_n (&result, "</ul>", 5);
- if (section == top_section)
- {
- if (has_toplevel_contents)
- text_append_n (&result, "</li>\n", 6);
- is_top_section = 1;
- break;
- }
- section_directions
- = lookup_extra_directions (section,
- AI_key_section_directions);
- if (section_directions
- && section_directions[D_next])
- {
- text_append_n (&result, "</li>\n", 6);
- section = section_directions[D_next];
- break;
- }
- }
- if (is_top_section)
- break;
- }
- }
- }
- }
-
-
- if (root_children->number > 1)
- text_append_n (&result, "\n</ul>", 6);
-
- if ((is_contents && !self->conf->AFTER_TOC_LINES.o.string)
- || (!is_contents && !self->conf->AFTER_SHORT_TOC_LINES.o.string))
- text_append_n (&result, "\n</div>\n", 8);
- else if (is_contents)
- text_append (&result, self->conf->AFTER_TOC_LINES.o.string);
- else
- text_append (&result, self->conf->AFTER_SHORT_TOC_LINES.o.string);
-
- return result.text;
-}
-
-char *
-format_contents (CONVERTER *self,
- const enum command_id cmd, const ELEMENT *element,
- const char *filename)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_contents];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_contents (self, cmd, element, filename);
- }
- else
- {
- return call_formatting_function_format_contents (self,
- formatting_reference,
- builtin_command_name (cmd), element, filename);
- }
-}
-
-void
-format_heading_text (CONVERTER *self, const enum command_id cmd,
- const STRING_LIST *classes, const char *text,
- int level, const char *id, const ELEMENT *element,
- const char *target, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_heading_text];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_heading_text (self, cmd, classes, text,
- level, id, element, target, result);
- }
- else
- {
- char *heading_text
- = call_formatting_function_format_heading_text (self,
- formatting_reference,
- builtin_command_name (cmd),
- classes, text,
- level, id, element, target);
- text_append (result, heading_text);
- free (heading_text);
- }
-}
-
-static char *foot_body_heading_array[] = {"footnote-body-heading"};
-static const STRING_LIST foot_body_heading_classes
- = {foot_body_heading_array, 1, 1};
-
-void
-html_default_format_single_footnote (CONVERTER *self, const ELEMENT *element,
- const char *footid, int number_in_doc,
- const char *footnote_location_href, const char *mark,
- TEXT *result)
-{
- char *attribute_class;
- size_t footnote_text_len;
- char *footnote_text;
- char *context_str;
- char *footnote_text_with_eol;
-
- xasprintf (&context_str, "%s %d %s", element_command_name (element),
- number_in_doc, footid);
- footnote_text
- = convert_tree_new_formatting_context (self, element->e.c->args.list[0],
- context_str, 0, 0, 0);
- free (context_str);
-
- footnote_text_len = strlen (footnote_text);
- if (footnote_text_len <= 0
- || footnote_text[footnote_text_len -1] != '\n')
- {
- xasprintf (&footnote_text_with_eol, "%s\n", footnote_text);
- free (footnote_text);
- }
- else
- footnote_text_with_eol = footnote_text;
-
- attribute_class = html_attribute_class (self, "h5",
- &foot_body_heading_classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- text_printf (result, "><a id=\"%s\" href=\"%s\">(%s)</a></h5>\n",
- footid, footnote_location_href, mark);
-
- text_append (result, footnote_text_with_eol);
- free (footnote_text_with_eol);
-}
-
-void
-format_single_footnote (CONVERTER *self, const ELEMENT *element,
- const char *footid, int number_in_doc,
- const char *footnote_location_href, const char *mark,
- TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_single_footnote];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_single_footnote (self, element, footid,
- number_in_doc, footnote_location_href,
- mark, result);
- }
- else
- {
- char *footnote
- = call_formatting_function_format_single_footnote (self,
- formatting_reference, element, footid,
- number_in_doc, footnote_location_href,
- mark);
-
- text_append (result, footnote);
- free (footnote);
- }
-}
-
-void
-html_default_format_footnotes_sequence (CONVERTER *self, TEXT *result)
-{
- size_t i;
- HTML_PENDING_FOOTNOTE_STACK *pending_footnotes
- = html_get_pending_footnotes (self);
-
- if (pending_footnotes->top > 0)
- {
- for (i = 0; i < pending_footnotes->top; i++)
- {
- const HTML_PENDING_FOOTNOTE *pending_footnote_info
- = pending_footnotes->stack[i];
- const ELEMENT *command = pending_footnote_info->command;
- const char *footid = pending_footnote_info->footid;
- int number_in_doc = pending_footnote_info->number_in_doc;
- char *footnote_mark;
- char *footnote_location_href
- = html_footnote_location_href (self, command, 0,
- pending_footnote_info->docid,
- pending_footnote_info->footnote_location_filename);
- /*
- NOTE the @-commands in @footnote that are formatted differently depending
- on in_multi_expanded($self) cannot know that the original context
- of the @footnote in the main document was $multi_expanded_region.
- We do not want to set multi_expanded in customizable code. However, it
- could be possible to set a shared_conversion_state based on
$multi_expanded_region
- and have all the conversion functions calling in_multi_expanded($self)
- also check the shared_conversion_state. The special situations
- with those @-commands in @footnote in multi expanded
- region do not justify this additional code and complexity. The
consequences
- should only be redundant anchors HTML elements.
- */
- if (self->conf->NUMBER_FOOTNOTES.o.integer > 0)
- xasprintf (&footnote_mark, "%d", number_in_doc);
- else if (self->conf->NO_NUMBER_FOOTNOTE_SYMBOL.o.string)
- footnote_mark
- = strdup (self->conf->NO_NUMBER_FOOTNOTE_SYMBOL.o.string);
- else
- footnote_mark = strdup ("");
-
- format_single_footnote (self, command, footid, number_in_doc,
- footnote_location_href, footnote_mark,
- result);
-
- free (footnote_mark);
- free (footnote_location_href);
- }
- }
- destroy_pending_footnotes (pending_footnotes);
-}
-
-void
-format_footnotes_sequence (CONVERTER *self, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_footnotes_sequence];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_footnotes_sequence (self, result);
- }
- else
- {
- char *footnotes_sequence
- = call_formatting_function_format_footnotes_sequence (self,
- formatting_reference);
- text_append (result, footnotes_sequence);
- free (footnotes_sequence);
- }
-}
-
-void
-default_format_footnotes_segment (CONVERTER *self, TEXT *result)
-{
- const char *class_base;
- char *attribute_class;
- char *class;
- STRING_LIST *classes;
- const ELEMENT *footnote_heading_tree;
- char *footnote_heading;
- int level;
- TEXT foot_lines;
-
- text_init (&foot_lines);
- format_footnotes_sequence (self, &foot_lines);
-
- if (foot_lines.end <= 0)
- {
- free (foot_lines.text);
- return;
- }
-
- classes = new_string_list ();
-
- class_base = html_special_unit_info (self, SUI_type_class,
- "footnotes");
- xasprintf (&class, "%s-segment", class_base);
-
- add_string (class, classes);
- free (class);
- attribute_class = html_attribute_class (self, "div", classes);
- clear_strings_list (classes);
-
- text_append (result, attribute_class);
- free (attribute_class);
-
- text_append_n (result, ">\n", 2);
-
- if (self->conf->DEFAULT_RULE.o.string
- && strlen (self->conf->DEFAULT_RULE.o.string))
- {
- text_append (result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (result, "\n", 1);
- }
-
- footnote_heading_tree = special_unit_info_tree (self,
- SUIT_type_heading, "footnotes");
- if (footnote_heading_tree)
- {
- footnote_heading = html_convert_tree (self, footnote_heading_tree,
- "convert footnotes special heading");
- }
- else
- {
- footnote_heading = "";
- }
-
- level = self->conf->FOOTNOTE_END_HEADER_LEVEL.o.integer;
-
- xasprintf (&class, "%s-heading", class_base);
-
- add_string (class, classes);
- free (class);
-
- format_heading_text (self, 0, classes, footnote_heading, level, 0, 0, 0,
- result);
- destroy_strings_list (classes);
- text_append_n (result, "\n", 1);
-
- if (footnote_heading_tree)
- free (footnote_heading);
-
- text_append (result, foot_lines.text);
- free (foot_lines.text);
- text_append (result, "</div>\n");
-}
-
-void
-format_footnotes_segment (CONVERTER *self, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_footnotes_segment];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- default_format_footnotes_segment (self, result);
- }
- else
- {
- char *footnotes_segment
- = call_formatting_function_format_footnotes_segment (self,
- formatting_reference);
- if (footnotes_segment)
- {
- text_append (result, footnotes_segment);
- free (footnotes_segment);
- }
- }
-}
-
-void
-html_default_format_program_string (CONVERTER *self, TEXT *result)
-{
- ELEMENT *tree;
- const char *explanation;
- if (self->conf->PROGRAM.o.string && strlen (self->conf->PROGRAM.o.string)
- && self->conf->PACKAGE_URL.o.string)
- {
- ELEMENT *program_homepage = new_text_element (ET_normal_text);
- ELEMENT *program = new_text_element (ET_normal_text);
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
-
- text_append (program_homepage->e.text, self->conf->PACKAGE_URL.o.string);
- text_append (program->e.text, self->conf->PROGRAM.o.string);
-
- add_element_to_named_string_element_list (substrings,
- "program_homepage", program_homepage);
- add_element_to_named_string_element_list (substrings,
- "program", program);
-
- tree = html_cdt_tree ("This document was generated on @emph{@today{}} "
- "using @uref{{program_homepage},
@emph{{program}}}.",
- self, substrings, 0);
- destroy_named_string_element_list (substrings);
- /* program and program_homepage are destroyed with the tree */
- explanation = "Tr program string program";
- }
- else
- {
- tree = html_cdt_tree ("This document was generated on @emph{@today{}}.",
- self, 0, 0);
- explanation = "Tr program string date";
- }
- add_tree_to_build (self, tree);
- convert_tree_append (self, tree, result, explanation);
- remove_tree_to_build (self, tree);
- destroy_element_and_children (tree);
-}
-
-void
-format_program_string (CONVERTER *self, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_program_string];
-
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_program_string (self, result);
- }
- else
- {
- char *program_string
- = call_formatting_function_format_program_string (self,
- formatting_reference);
- text_append (result, program_string);
- free (program_string);
- }
-}
-
-static char *program_in_footer_array[] = {"program-in-footer"};
-static const STRING_LIST program_in_footer_classes
- = {program_in_footer_array, 1, 1};
-
-char *
-html_default_format_end_file (CONVERTER *self, const char *filename,
- const OUTPUT_UNIT *output_unit)
-{
- TEXT result;
-
- text_init (&result);
- text_append (&result, "");
-
- if (self->conf->PROGRAM_NAME_IN_FOOTER.o.integer > 0)
- {
- char *open;
- size_t open_len;
- text_append_n (&result, "<p>\n ", 6);
- open = html_attribute_class (self, "span", &program_in_footer_classes);
- open_len = strlen (open);
- if (open_len > 0)
- {
- text_append (&result, open);
- text_append_n (&result, ">", 1);
- }
- free (open);
-
- format_program_string (self, &result);
-
- if (open_len > 0)
- text_append_n (&result, "</span>", 7);
- text_append_n (&result, "\n</p>", 5);
- }
- text_append_n (&result, "\n\n", 2);
-
- if (self->conf->PRE_BODY_CLOSE.o.string)
- text_append (&result, self->conf->PRE_BODY_CLOSE.o.string);
-
- if (self->jslicenses.number)
- {
- int infojs_jslicenses_file_nr = 0;
- int mathjax_jslicenses_file_nr = 0;
- size_t i;
- int status;
- for (i = 0; i < self->jslicenses.number; i++)
- {
- const JSLICENSE_FILE_INFO_LIST *jslicences_files_info
- = &self->jslicenses.list[i];
- if (!strcmp (jslicences_files_info->category, "infojs"))
- infojs_jslicenses_file_nr = jslicences_files_info->number;
- else if (!strcmp (jslicences_files_info->category, "mathjax"))
- mathjax_jslicenses_file_nr = jslicences_files_info->number;
- }
- if (infojs_jslicenses_file_nr > 0
- || ((html_get_file_information (self, "mathjax",
- filename, &status) > 0
- || (!self->conf->SPLIT.o.string
- || !strlen (self->conf->SPLIT.o.string)))
- && mathjax_jslicenses_file_nr > 0))
- {
- if (self->conf->JS_WEBLABELS_FILE.o.string
- && self->conf->JS_WEBLABELS.o.string
- && (!strcmp (self->conf->JS_WEBLABELS.o.string, "generate")
- || !strcmp (self->conf->JS_WEBLABELS.o.string, "reference")))
- {
- ELEMENT *tree;
- char *js_path = url_protect_url_text (self,
- self->conf->JS_WEBLABELS_FILE.o.string);
- text_append_n (&result, "<a href=\"", 9);
- text_append (&result, js_path);
- free (js_path);
- text_append_n (&result, "\" rel=\"jslicense\"><small>", 25);
-
- tree = html_cdt_tree ("JavaScript license information",
- self, 0, 0);
- add_tree_to_build (self, tree);
- convert_tree_append (self, tree, &result,
- "Tr JS license header");
- remove_tree_to_build (self, tree);
-
- destroy_element_and_children (tree);
-
- text_append_n (&result, "</small></a>", 12);
- }
- }
- }
- text_append_n (&result, "\n</body>\n</html>\n", 17);
- return result.text;
-}
-
-char *
-format_end_file (CONVERTER *self, const char *filename,
- const OUTPUT_UNIT *output_unit)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_end_file];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_end_file (self, filename, output_unit);
- }
- else
- {
- return call_formatting_function_format_end_file (self,
- formatting_reference,
- filename, output_unit);
- }
-}
-
-typedef struct BEGIN_FILE_INFORMATION {
- char *title;
- char *description;
- char *keywords;
- char *encoding;
- char *css_lines;
- char *root_html_element_attributes;
- char *body_attributes;
- char *generator;
- char *extra_head;
-} BEGIN_FILE_INFORMATION;
-
-void
-destroy_begin_file_information (BEGIN_FILE_INFORMATION *begin_info)
-{
- free (begin_info->title);
- free (begin_info->description);
- free (begin_info->keywords);
- free (begin_info->encoding);
- free (begin_info->css_lines);
- free (begin_info->root_html_element_attributes);
- free (begin_info->body_attributes);
- free (begin_info->generator);
- free (begin_info->extra_head);
-
- free (begin_info);
-}
-
-/* return string to be freed by the caller */
-static char *
-convert_string_tree_new_formatting_context (CONVERTER *self, ELEMENT *tree,
- const char *context_string, const char *multiple_pass)
-{
- ELEMENT *tree_root_string = new_element (ET__string);
- char *result;
-
- add_to_contents_as_array (tree_root_string, tree);
-
- add_tree_to_build (self, tree_root_string);
-
- result = convert_tree_new_formatting_context (self, tree_root_string,
- context_string, multiple_pass, 0, 0);
-
- remove_tree_to_build (self, tree_root_string);
- destroy_element (tree_root_string);
- return result;
-}
-
-void
-html_default_format_css_lines (CONVERTER *self, const char *filename,
- TEXT *result)
-{
- const STRING_LIST *css_refs;
- const STRING_LIST *css_import_lines;
- const STRING_LIST *css_rule_lines;
- STRING_LIST *css_element_classes;
- size_t i;
-
- if (self->conf->NO_CSS.o.integer > 0)
- return;
-
- css_refs = self->conf->CSS_REFS.o.strlist;
- css_element_classes = html_get_css_elements_classes (self, filename);
- css_import_lines = html_css_get_info (self, CI_css_info_imports);
- css_rule_lines = html_css_get_info (self, CI_css_info_rules);
-
- if (css_import_lines->number <= 0
- && (!css_element_classes || css_element_classes->number <= 0)
- && css_rule_lines->number <= 0
- && (!css_refs || css_refs->number <= 0))
- {
- if (css_element_classes)
- destroy_strings_list (css_element_classes);
- return;
- }
-
- text_append (result, "<style type=\"text/css\">\n<!--\n");
-
- if (css_import_lines->number > 0)
- {
- for (i = 0; i < css_import_lines->number; i++)
- text_append (result, css_import_lines->list[i]);
- text_append_n (result, "\n", 1);
- }
-
- if (css_element_classes)
- {
- if (css_element_classes->number > 0)
- {
- for (i = 0; i < css_element_classes->number; i++)
- {
- const char *selector = css_element_classes->list[i];
- const CSS_SELECTOR_STYLE *selector_style
- = find_css_selector_style (&self->css_element_class_styles,
- selector);
- if (selector_style->style)
- text_printf (result, "%s {%s}\n", selector,
- selector_style->style);
- }
- }
- destroy_strings_list (css_element_classes);
- }
-
- if (css_rule_lines->number > 0)
- {
- for (i = 0; i < css_rule_lines->number; i++)
- text_append (result, css_rule_lines->list[i]);
- text_append_n (result, "\n", 1);
- }
-
- text_append (result, "-->\n</style>\n");
-
- if (css_refs)
- {
- for (i = 0; i < css_refs->number; i++)
- {
- char *protected_ref = url_protect_url_text (self,
- css_refs->list[i]);
- text_printf (result,
- "<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\"",
- protected_ref);
- free (protected_ref);
-
- close_html_lone_element (self, result);
- text_append_n (result, "\n", 1);
- }
- }
-}
-
-void
-format_css_lines (CONVERTER *self, const char *filename, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_css_lines];
-
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_css_lines (self, filename, result);
- }
- else
- {
- char *css_lines
- = call_formatting_function_format_css_lines (self,
- formatting_reference, filename);
- text_append (result, css_lines);
- free (css_lines);
- }
-}
-
-/* return string to be freed by the caller */
-static
-char *root_html_element_attributes_string (CONVERTER *self)
-{
- if (self->conf->HTML_ROOT_ELEMENT_ATTRIBUTES.o.string
- && strlen (self->conf->HTML_ROOT_ELEMENT_ATTRIBUTES.o.string))
- {
- char *result;
- xasprintf (&result, " %s",
- self->conf->HTML_ROOT_ELEMENT_ATTRIBUTES.o.string);
- return result;
- }
- return 0;
-}
-
-/* This is used for normal output files and other files, like
- redirection file headers. $COMMAND is the tree element for
- a @node that is being output in the file.
-
- Returned structure to be freed by the caller.
-*/
-static BEGIN_FILE_INFORMATION *
-file_header_information (CONVERTER *self, const ELEMENT *command,
- const char *filename)
-{
- BEGIN_FILE_INFORMATION *begin_info = (BEGIN_FILE_INFORMATION *)
- malloc (sizeof (BEGIN_FILE_INFORMATION));
- const char *description = self->documentdescription_string;
- char *command_description = 0;
- int status;
- TEXT text;
- char *root_html_element_attributes
- = root_html_element_attributes_string (self);
-
- text_init (&text);
-
- memset (begin_info, 0, sizeof (BEGIN_FILE_INFORMATION));
-
- if (command)
- {
- char *command_string = html_command_text (self, command, HTT_string);
- if (command_string && strlen (command_string)
- && strcmp (command_string, self->title_string))
- {
- char *context_str;
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
- ELEMENT *title_tree_copy = copy_tree (self->title_tree);
- ELEMENT *element_tree_copy;
- ELEMENT *title_tree;
- ELEMENT *command_tree = 0;
-
- if (self->conf->SECTION_NAME_IN_TITLE.o.integer > 0)
- {
- const ELEMENT *associated_section
- = lookup_extra_element (command, AI_key_associated_section);
- if (associated_section && associated_section->e.c->args.number >
0)
- {
- command_tree = associated_section->e.c->args.list[0];
- }
- }
-
- if (!command_tree)
- {
- /* this should not happen, as the command_string should be empty already */
- TREE_ADDED_ELEMENTS *element_tree
- = html_command_tree (self, command, 0);
- command_tree = element_tree->tree;
- }
-
- element_tree_copy = copy_tree (command_tree);
-
- add_element_to_named_string_element_list (substrings, "title",
- title_tree_copy);
- add_element_to_named_string_element_list (substrings, "element_text",
- element_tree_copy);
-
- /* TRANSLATORS: sectioning element title for the page header */
- title_tree
- = html_cdt_tree ("{element_text} ({title})",
- self, substrings, 0);
-
- destroy_named_string_element_list (substrings);
-
- add_tree_to_build (self, title_tree);
-
- if (command->e.c->cmd)
- xasprintf (&context_str, "file_header_title-element-@%s",
- element_command_name (command));
- else if (command->type)
- xasprintf (&context_str, "file_header_title-element-%s",
- type_data[command->type].name);
- else
- context_str = strdup ("file_header_title-element-");
-
- begin_info->title
- = convert_string_tree_new_formatting_context (self,
- title_tree, context_str,
- "element_title");
-
- free (context_str);
- remove_tree_to_build (self, title_tree);
- destroy_element_and_children (title_tree);
- }
- free (command_string);
-
- command_description = html_command_description (self, command,
- HTT_string);
- }
- if (!begin_info->title)
- begin_info->title = strdup (self->title_string);
-
- if (command_description && strlen (command_description))
- begin_info->keywords = strdup (command_description);
- else if (begin_info->title)
- begin_info->keywords = strdup (begin_info->title);
-
- if (!description || !strlen (description))
- {
- if (command_description && strlen (command_description))
- description = command_description;
- else
- description = begin_info->title;
- }
-
- if (description && strlen (description))
- {
- text_printf (&text,
- "<meta name=\"description\" content=\"%s\"", description);
- close_html_lone_element (self, &text);
- begin_info->description = strdup (text.text);
- }
-
- free (command_description);
-
- text_reset (&text);
- if (self->conf->OUTPUT_ENCODING_NAME.o.string
- && strlen (self->conf->OUTPUT_ENCODING_NAME.o.string))
- {
- text_printf (&text,
- "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"",
- self->conf->OUTPUT_ENCODING_NAME.o.string);
- close_html_lone_element (self, &text);
- begin_info->encoding = strdup (text.text);
- }
-
- text_reset (&text);
- text_append (&text, "");
- format_css_lines (self, filename, &text);
- begin_info->css_lines = strdup (text.text);
-
- if (root_html_element_attributes)
- {
- begin_info->root_html_element_attributes
- = root_html_element_attributes;
- }
- else
- begin_info->root_html_element_attributes = strdup ("");
-
- text_reset (&text);
- if (self->conf->BODY_ELEMENT_ATTRIBUTES.o.string)
- text_append (&text, self->conf->BODY_ELEMENT_ATTRIBUTES.o.string);
- if (self->conf->HTML_MATH.o.string
- && !strcmp (self->conf->HTML_MATH.o.string, "mathjax")
- && html_get_file_information (self, "mathjax", filename, &status) > 0)
- {
- text_append_n (&text, " class=\"tex2jax_ignore\"", 23);
- }
-
- begin_info->body_attributes = strdup (text.text);
-
- text_reset (&text);
- if (self->conf->PROGRAM.o.string && strlen (self->conf->PROGRAM.o.string))
- {
- text_printf (&text, "<meta name=\"Generator\" content=\"%s\"",
- self->conf->PROGRAM.o.string);
- close_html_lone_element (self, &text);
- text_append_n (&text, "\n", 1);
- begin_info->generator = strdup (text.text);
- text_reset (&text);
- }
-
- if (self->conf->EXTRA_HEAD.o.string)
- text_append (&text, self->conf->EXTRA_HEAD.o.string);
- if (self->conf->INFO_JS_DIR.o.string)
- {
- if (!self->conf->SPLIT.o.string || !strlen (self->conf->SPLIT.o.string))
- {
- message_list_document_error (&self->error_messages, self->conf, 0,
- "%s not meaningful for non-split output", "INFO_JS_DIR");
- }
- else
- {
- char *jsdir;
- char *protected_jsdir;
- if (!strcmp (self->conf->INFO_JS_DIR.o.string, "."))
- jsdir = strdup ("");
- else
- {
- size_t len;
- jsdir = strdup (self->conf->INFO_JS_DIR.o.string);
- len = strlen (jsdir);
- if (len > 0)
- {
- if (jsdir[len - 1] != '/')
- {
- char *tmp;
- xasprintf (&tmp, "%s/", jsdir);
- free (jsdir);
- jsdir = tmp;
- }
- else if (len > 1 && jsdir[len - 2] == '/')
- {
- while (1)
- {
- len--;
- if (len <= 1 || jsdir[len - 2] != '/')
- break;
- }
- jsdir[len] = '\0';
- }
- }
- }
- protected_jsdir = url_protect_url_text (self, jsdir);
- free (jsdir);
- text_printf (&text, "<link rel=\"stylesheet\" type=\"text/css\" "
- "href=\"%sinfo.css\"", protected_jsdir);
- close_html_lone_element (self, &text);
- text_printf (&text, "\n<script src=\"%smodernizr.js\" "
- "type=\"text/javascript\"></script>\n"
- "<script src=\"%sinfo.js\" type=\"text/javascript\"></script>",
- protected_jsdir, protected_jsdir);
- free (protected_jsdir);
- }
- }
- if (self->conf->HTML_MATH.o.string
- && !strcmp (self->conf->HTML_MATH.o.string, "mathjax")
- && (html_get_file_information (self, "mathjax", filename, &status) > 0
- || (self->conf->SPLIT.o.string && strlen
(self->conf->SPLIT.o.string))))
- {
- char *mathjax_script = url_protect_url_text (self,
- self->conf->MATHJAX_SCRIPT.o.string);
- text_printf (&text, "<script type='text/javascript'>\n"
-"MathJax = {\n"
-"%s\n"
-"};\n"
-"</script><script type=\"text/javascript\" id=\"MathJax-script\" async\n"
-" src=\"%s\">\n"
-"</script>", self->conf->MATHJAX_CONFIGURATION.o.string, mathjax_script);
- free (mathjax_script);
- }
- begin_info->extra_head = text.text;
- return begin_info;
-}
-
-static void
-get_links (CONVERTER* self, const char *filename,
- const OUTPUT_UNIT *output_unit,
- const ELEMENT *node_command, TEXT *result)
-{
- if (self->conf->USE_LINKS.o.integer > 0
- && self->conf->LINKS_BUTTONS.o.buttons)
- {
- size_t i;
- const BUTTON_SPECIFICATION_LIST *link_buttons
- = self->conf->LINKS_BUTTONS.o.buttons;
- for (i = 0; i < link_buttons->number; i++)
- {
- const BUTTON_SPECIFICATION *link = &link_buttons->list[i];
- char *link_href;
- if (link->type != BST_direction)
- fatal ("LINKS_BUTTONS should only contain directions");
- link_href = from_element_direction (self, link->b.direction,
- HTT_href, output_unit,
- filename, node_command);
- if (link_href)
- {
- char *link_string
- = from_element_direction (self, link->b.direction, HTT_string,
- output_unit, 0, 0);
- const char *button_rel
- = direction_string (self, link->b.direction, TDS_type_rel,
- TDS_context_string);
- text_printf (result, "<link href=\"%s\"", link_href);
- if (button_rel)
- {
- text_printf (result, " rel=\"%s\"", button_rel);
- }
- if (link_string)
- {
- text_printf (result, " title=\"%s\"", link_string);
- free (link_string);
- }
- close_html_lone_element (self, result);
- text_append_n (result, "\n", 1);
- }
- free (link_href);
- }
- }
-}
-
-char *
-html_default_format_begin_file (CONVERTER *self, const char *filename,
- const OUTPUT_UNIT *output_unit)
-{
- const ELEMENT *element_command = 0;
- const ELEMENT *node_command = 0;
- const ELEMENT *command_for_title = 0;
- BEGIN_FILE_INFORMATION *begin_info;
- TEXT result;
- const char *package_and_version;
- const char *package_url;
-
- if (output_unit)
- {
- if (output_unit->unit_type == OU_special_unit)
- element_command = output_unit->uc.special_unit_command;
- else
- element_command = output_unit->uc.unit_command;
- if (element_command && element_command->e.c->cmd != CM_node)
- {
- node_command = lookup_extra_element (element_command,
- AI_key_associated_node);
- }
- if (!node_command)
- node_command = element_command;
-
- if (self->conf->SPLIT.o.string && strlen (self->conf->SPLIT.o.string)
- && element_command)
- command_for_title = element_command;
- }
-
- begin_info = file_header_information (self, command_for_title, filename);
-
- text_init (&result);
-
- if (self->conf->DOCTYPE.o.string)
- text_append (&result, self->conf->DOCTYPE.o.string);
- text_append_n (&result, "\n", 1);
- text_printf (&result, "<html%s>\n",
begin_info->root_html_element_attributes);
- if (self->conf->PACKAGE_AND_VERSION.o.string)
- package_and_version = self->conf->PACKAGE_AND_VERSION.o.string;
- else
- package_and_version = "";
- if (self->conf->PACKAGE_URL.o.string)
- package_url = self->conf->PACKAGE_URL.o.string;
- else
- package_url = "";
- text_printf (&result, "<!-- Created by %s, %s -->\n<head>\n",
- package_and_version, package_url);
- if (begin_info->encoding)
- text_append (&result, begin_info->encoding);
- text_append_n (&result, "\n", 1);
- if (self->copying_comment)
- text_append (&result, self->copying_comment);
- text_printf (&result, "<title>%s</title>\n\n", begin_info->title);
- if (begin_info->description)
- text_append (&result, begin_info->description);
- text_append_n (&result, "\n", 1);
- if (begin_info->keywords)
- {
- text_printf (&result, "<meta name=\"keywords\" content=\"%s\"",
- begin_info->keywords);
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
- }
- text_append (&result, "<meta name=\"resource-type\" content=\"document\"");
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
- text_append (&result, "<meta name=\"distribution\" content=\"global\"");
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
- if (begin_info->generator)
- text_append (&result, begin_info->generator);
- if (self->date_in_header)
- text_append (&result, self->date_in_header);
- text_append (&result,
- "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"");
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n\n", 2);
-
- get_links (self, filename, output_unit, node_command, &result);
-
- text_append (&result, begin_info->css_lines);
- text_append_n (&result, "\n", 1);
- if (begin_info->extra_head)
- text_append (&result, begin_info->extra_head);
- text_append_n (&result, "\n</head>\n\n", 10);
- text_printf (&result, "<body %s>\n", begin_info->body_attributes);
- if (self->conf->AFTER_BODY_OPEN.o.string)
- text_append (&result, self->conf->AFTER_BODY_OPEN.o.string);
-
- destroy_begin_file_information (begin_info);
-
- return result.text;
-}
-
-/* return string to be freed by the caller */
-char *
-format_begin_file (CONVERTER *self, const char *filename,
- const OUTPUT_UNIT *output_unit)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_begin_file];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_begin_file (self, filename, output_unit);
- }
- else
- {
- return call_formatting_function_format_begin_file (self,
- formatting_reference,
- filename, output_unit);
- }
-}
-
-static char *nav_icon_array[] = {"nav-icon"};
-static const STRING_LIST nav_icon_classes = {nav_icon_array, 1, 1};
-
-/* return string to be freed by the caller */
-char *
-html_default_format_button_icon_img (CONVERTER *self,
- const char *button_name,
- const char *icon, const char *name)
-{
- TEXT result;
- char *icon_protected;
- char *attribute_class;
-
- if (!icon)
- return strdup ("");
-
- text_init (&result);
-
- attribute_class = html_attribute_class (self, "img",
- &nav_icon_classes);
- text_append (&result, attribute_class);
- free (attribute_class);
-
- text_append_n (&result, " src=\"", 6);
- icon_protected = url_protect_url_text (self, icon);
- text_append (&result, icon_protected);
- free (icon_protected);
-
- text_append_n (&result, "\" alt=\"", 7);
- if (name)
- {
- if (button_name)
- text_printf (&result, "%s: %s", button_name, name);
- else
- text_append (&result, name);
- }
- else if (button_name)
- text_append (&result, button_name);
-
- text_append_n (&result, "\"", 1);
- close_html_lone_element (self, &result);
-
- return result.text;
-}
-
-/* return string to be freed by the caller */
-char *
-format_button_icon_img (CONVERTER *self,
- const char *button_name,
- const char *icon, const char *name)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_button_icon_img];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_button_icon_img (self, button_name,
- icon, name);
- }
- else
- {
- return call_formatting_function_format_button_icon_img (self,
- formatting_reference,
- button_name,
- icon, name);
- }
-}
-
-static FORMATTED_BUTTON_INFO *
-default_panel_button_dynamic_direction_internal (CONVERTER *self,
- int direction, const ELEMENT *element,
- int omit_rel,
- int use_first_element_in_file_directions)
-{
- char *href;
- char *node = 0;
- FORMATTED_BUTTON_INFO *formatted_button;
-
- formatted_button = (FORMATTED_BUTTON_INFO *)
- malloc (sizeof (FORMATTED_BUTTON_INFO));
- memset (formatted_button, 0, sizeof (FORMATTED_BUTTON_INFO));
-
- formatted_button->need_delimiter = 1;
-
- if (self->conf->USE_NODE_DIRECTIONS.o.integer > 0
- || (self->conf->USE_NODE_DIRECTIONS.o.integer < 0
- && self->conf->USE_NODES.o.integer > 0))
- direction += NODE_DIRECTIONS_OFFSET;
-
- if (use_first_element_in_file_directions)
- direction -= FIRSTINFILE_OFFSET;
-
- href = from_element_direction (self, direction, HTT_href, 0, 0, element);
-
- if (self->conf->xrefautomaticsectiontitle.o.string
- && !strcmp (self->conf->xrefautomaticsectiontitle.o.string, "on"))
- node = from_element_direction (self, direction, HTT_section, 0, 0, 0);
-
- if (!node)
- node = from_element_direction (self, direction, HTT_node, 0, 0, 0);
-
- if (node && node[strspn (node, whitespace_chars)] != '\0')
- {
- const char *text = direction_string (self, direction, TDS_type_text, 0);
- if (!text)
- text = "";
- if (href && strlen (href))
- {
- char *hyperlink
- = direction_a (self, direction, href, node, omit_rel);
- xasprintf (&formatted_button->active, "%s: %s", text, hyperlink);
- free (hyperlink);
- }
- else
- xasprintf (&formatted_button->active, "%s: %s", text, node);
- }
-
- free (href);
- free (node);
- return formatted_button;
-}
-
-static FORMATTED_BUTTON_INFO *
-default_panel_button_dynamic_direction (CONVERTER *self,
- int direction, const ELEMENT *element)
-{
- return default_panel_button_dynamic_direction_internal (self,
- direction, element, 0, 0);
-}
-
-static FORMATTED_BUTTON_INFO *
-default_panel_button_dynamic_direction_node_footer (CONVERTER *self,
- int direction, const ELEMENT *element)
-{
- return default_panel_button_dynamic_direction_internal (self,
- direction, element, 1, 0);
-}
-
-static FORMATTED_BUTTON_INFO *
-default_panel_button_dynamic_direction_section_footer (CONVERTER *self,
- int direction, const ELEMENT *element)
-{
- return default_panel_button_dynamic_direction_internal (self,
- direction, element, 0, 1);
-}
-
-/* the order corresponds to enum button_function_type */
-FORMATTED_BUTTON_INFO * (*html_format_button_function[]) (CONVERTER *self,
- int direction, const ELEMENT *element) = {
- 0,
- &default_panel_button_dynamic_direction_section_footer,
- &default_panel_button_dynamic_direction_node_footer,
- &default_panel_button_dynamic_direction,
- 0
-};
-
-FORMATTED_BUTTON_INFO *
-button_direction_function (CONVERTER *self, BUTTON_FUNCTION *button_function,
- int direction, const ELEMENT *element)
-{
- if (html_format_button_function[button_function->type])
- return (*html_format_button_function[button_function->type])
- (self, direction, element);
- else
- return call_button_direction_function (self, button_function->sv_reference,
- direction, element);
-}
-
-FORMATTED_BUTTON_INFO *
-html_default_format_button (CONVERTER *self,
- const BUTTON_SPECIFICATION *button,
- const ELEMENT *element)
-{
- if (button->type == BST_function)
- {
- return call_button_simple_function (self, button->b.sv_reference);
- }
- else if (button->type == BST_direction_info
- && button->b.button_info->type == BIT_function)
- {
- return button_direction_function (self,
- &button->b.button_info->bi.button_function,
- button->b.button_info->direction, element);
- }
- else
- {
- FORMATTED_BUTTON_INFO *formatted_button;
- formatted_button = (FORMATTED_BUTTON_INFO *)
- malloc (sizeof (FORMATTED_BUTTON_INFO));
- memset (formatted_button, 0, sizeof (FORMATTED_BUTTON_INFO));
-
- if (button->type == BST_external_string)
- {
- formatted_button->active
- = get_perl_scalar_reference_value (button->b.sv_string);
- formatted_button->need_delimiter = 1;
- }
- else if (button->type == BST_direction_info)
- {
- int direction = button->b.button_info->direction;
- if (button->b.button_info->type == BIT_external_string
- || button->b.button_info->type == BIT_string)
- {
- /* use given text */
- char *text;
- if (button->b.button_info->type == BIT_external_string)
- text = get_perl_scalar_reference_value
- (button->b.button_info->bi.sv_string);
- else
- text = strdup (button->b.button_info->bi.string);
-
- if (text)
- {
- char *href = from_element_direction (self, direction,
- HTT_href, 0, 0, element);
- if (href)
- {
- formatted_button->active
- = direction_a (self, direction, href, text, 0);
- free (href);
- free (text);
- }
- else
- {
- formatted_button->passive = text;
- }
- }
- }
- else if (button->b.button_info->type
- == BIT_selected_direction_information_type)
- {
- /* this case is mostly for tests, to test the direction type
- in direction_information_type with the direction direction */
- if (button->b.button_info->bi.direction_information_type >= 0)
- formatted_button->active
- = from_element_direction (self, direction,
- button->b.button_info->bi.direction_information_type,
- 0, 0, element);
- }
- else if (button->b.button_info->type
- == BIT_href_direction_information_type)
- {
- char *href = from_element_direction (self, direction,
- HTT_href, 0, 0, element);
- if (button->b.button_info->bi.direction_information_type >= 0)
- {
- char *text_formatted = from_element_direction (self,
- direction,
- button->b.button_info->bi.direction_information_type,
- 0, 0, 0);
- if (href && text_formatted)
- {
- formatted_button->active
- = direction_a (self, direction, href,
- text_formatted, 0);
- free (text_formatted);
- }
- else
- formatted_button->passive = text_formatted;
- }
- free (href);
- }
- formatted_button->need_delimiter = 1;
- }
- else if (button->type == BST_string)
- {
- formatted_button->active = strdup (button->b.string);
- formatted_button->need_delimiter = 1;
- }
- /* for the next cases, button->type == BST_direction */
- else if (button->b.direction == D_direction_Space)
- {
- /* handle space button */
- if (self->conf->ICONS.o.integer > 0
- && self->conf->ACTIVE_ICONS.o.icons->number > 0
- && self->conf->ACTIVE_ICONS.o.icons->list[button->b.direction]
- && strlen
-
(self->conf->ACTIVE_ICONS.o.icons->list[button->b.direction]))
- {
- const char *button_name_string = direction_string (self,
- button->b.direction, TDS_type_button,
- TDS_context_string);
- formatted_button->active
- = format_button_icon_img (self, button_name_string,
- self->conf->ACTIVE_ICONS.o.icons->list[button->b.direction],
0);
- }
- else
- {
- const char *button_text = direction_string (self,
- button->b.direction, TDS_type_text, 0);
- if (!button_text)
- button_text = "";
- formatted_button->active = strdup (button_text);
- }
- formatted_button->need_delimiter = 0;
- }
- else
- {
- char *href = from_element_direction (self, button->b.direction,
- HTT_href, 0, 0, element);
- if (href)
- {
- /* button is active */
- TEXT active_text;
- const char *active_icon = 0;
- const char *description
- = direction_string (self, button->b.direction,
- TDS_type_description, TDS_context_string);
-
- if (self->conf->ICONS.o.integer > 0
- && self->conf->ACTIVE_ICONS.o.icons->number > 0
- &&
self->conf->ACTIVE_ICONS.o.icons->list[button->b.direction]
- && strlen (self->conf->ACTIVE_ICONS.o.icons
- ->list[button->b.direction]))
- {
- active_icon = self->conf->ACTIVE_ICONS.o.icons
- ->list[button->b.direction];
- }
-
- text_init (&active_text);
- if (!active_icon)
- text_append_n (&active_text, "[", 1);
- text_printf (&active_text, "<a href=\"%s\"", href);
- if (description)
- text_printf (&active_text, " title=\"%s\"", description);
- if (self->conf->USE_ACCESSKEY.o.integer > 0)
- {
- const char *accesskey
- = direction_string (self, button->b.direction,
- TDS_type_accesskey,
TDS_context_string);
- if (accesskey && strlen (accesskey))
- text_printf (&active_text, " accesskey=\"%s\"", accesskey);
- }
- if (self->conf->USE_REL_REV.o.integer > 0)
- {
- const char *button_rel
- = direction_string (self, button->b.direction,
- TDS_type_rel, TDS_context_string);
- if (button_rel && strlen (button_rel))
- text_printf (&active_text, " rel=\"%s\"", button_rel);
- }
- text_append_n (&active_text, ">", 1);
- if (active_icon)
- {
- const char *button_name_string = direction_string (self,
- button->b.direction, TDS_type_button,
- TDS_context_string);
- char *icon_name = from_element_direction (self,
- button->b.direction,
- HTT_string,
- 0, 0, 0);
- char *icon_img
- = format_button_icon_img (self, button_name_string,
- active_icon, icon_name);
- free (icon_name);
-
- text_append (&active_text, icon_img);
- free (icon_img);
- }
- else
- {
- const char *button_text_string = direction_string (self,
- button->b.direction, TDS_type_text, 0);
- if (button_text_string)
- text_append (&active_text, button_text_string);
- }
-
- text_append_n (&active_text, "</a>", 4);
-
- if (!active_icon)
- text_append_n (&active_text, "]", 1);
-
- formatted_button->active = active_text.text;
- free (href);
- }
- else
- {
- TEXT passive_text;
- const char *passive_icon = 0;
-
- text_init (&passive_text);
-
- if (self->conf->ICONS.o.integer > 0
- && self->conf->PASSIVE_ICONS.o.icons->number > 0
- &&
self->conf->PASSIVE_ICONS.o.icons->list[button->b.direction]
- && strlen (self->conf->PASSIVE_ICONS.o.icons
- ->list[button->b.direction]))
- {
- passive_icon
- =
self->conf->PASSIVE_ICONS.o.icons->list[button->b.direction];
- }
- if (passive_icon)
- {
- const char *button_name_string
- = direction_string (self, button->b.direction,
- TDS_type_button, TDS_context_string);
- char *icon_name = from_element_direction (self,
- button->b.direction,
- HTT_string,
- 0, 0, 0);
- char *icon_img
- = format_button_icon_img (self, button_name_string,
- passive_icon, icon_name);
- free (icon_name);
-
- text_append (&passive_text, icon_img);
- free (icon_img);
- }
- else
- {
- const char *button_text_string
- = direction_string (self, button->b.direction,
- TDS_type_text, 0);
- text_append_n (&passive_text, "[", 1);
- if (button_text_string)
- text_append (&passive_text, button_text_string);
- text_append_n (&passive_text, "]", 1);
- }
- formatted_button->passive = passive_text.text;
- }
- formatted_button->need_delimiter = 0;
- }
- return formatted_button;
- }
- return 0;
-}
-
-FORMATTED_BUTTON_INFO *
-format_button (CONVERTER *self,
- const BUTTON_SPECIFICATION *button,
- const ELEMENT *element)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_button];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_button (self, button, element);
- }
- else
- {
- return call_formatting_function_format_button (self,
- formatting_reference,
- button, element);
- }
-}
-
-static void
-open_element_with_class (CONVERTER *self, const char *element_name,
- const STRING_LIST *classes, TEXT *result)
-{
- char *attribute_class = html_attribute_class (self, element_name,
- classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">", 1);
-}
-
-static char *nav_button_array[] = {"nav-button"};
-static const STRING_LIST nav_button_classes = {nav_button_array, 1, 1};
-
-static char *nav_panel_array[] = {"nav-panel"};
-static const STRING_LIST nav_panel_classes = {nav_panel_array, 1, 1};
-
-void
-html_default_format_navigation_panel (CONVERTER *self,
- const BUTTON_SPECIFICATION_LIST *buttons,
- const char *cmdname, const ELEMENT *element,
- int vertical, TEXT *result)
-{
- size_t i;
- size_t nr_of_buttons_shown = 0;
- TEXT result_buttons;
-
- if (!buttons)
- return;
-
- /* do the buttons first in case they are formatted as an empty string */
- text_init (&result_buttons);
- text_append (&result_buttons, "");
-
- for (i = 0; i < buttons->number; i++)
- {
- const BUTTON_SPECIFICATION *button = &buttons->list[i];
- FORMATTED_BUTTON_INFO *button_info;
- char *active = 0;
- char *passive = 0;
- int need_delimiter = 0;
- int direction = -1;
- if (button->type == BST_direction_info)
- direction = button->b.button_info->direction;
- else if (button->type == BST_direction)
- direction = button->b.direction;
-
- if (direction >= 0 && direction == D_direction_Space
- && nr_of_buttons_shown == 0)
- continue;
-
- button_info = format_button (self, button, element);
-
- if (button_info)
- {
- need_delimiter = button_info->need_delimiter;
- active = button_info->active;
- passive = button_info->passive;
- free (button_info);
- }
-
- if (self->conf->HEADER_IN_TABLE.o.integer > 0)
- {
- if (vertical)
- text_append_n (&result_buttons, "<tr>\n", 5);
- open_element_with_class (self, "td", &nav_button_classes,
- &result_buttons);
-
- if (active)
- text_append (&result_buttons, active);
- else if (passive)
- text_append (&result_buttons, passive);
-
- text_append_n (&result_buttons, "</td>\n", 6);
- if (vertical)
- text_append_n (&result_buttons, "</tr>\n", 6);
-
- nr_of_buttons_shown++;
- }
- else if (active)
- { /* only active buttons are print out when not in table */
- if (need_delimiter && nr_of_buttons_shown > 0)
- text_append_n (&result_buttons, ", ", 2);
-
- text_append (&result_buttons, active);
-
- nr_of_buttons_shown++;
- }
-
- free (active);
- free (passive);
- }
-
- if (result_buttons.end <= 0)
- {
- free (result_buttons.text);
- return;
- }
-
- if (self->conf->HEADER_IN_TABLE.o.integer > 0)
- {
- open_element_with_class (self, "table", &nav_panel_classes, result);
- text_append_n (result, "\n", 1);
-
- if (!vertical)
- text_append_n (result, "<tr>", 4);
- }
- else
- {
- open_element_with_class (self, "div", &nav_panel_classes, result);
- text_append_n (result, "\n", 1);
-
- text_append_n (result, "<p>\n", 4);
- }
-
- text_append (result, result_buttons.text);
-
- if (self->conf->HEADER_IN_TABLE.o.integer > 0)
- {
- if (!vertical)
- text_append_n (result, "</tr>", 5);
- text_append_n (result, "</table>\n", 9);
- }
- else
- {
- text_append_n (result, "</p>\n", 5);
- text_append_n (result, "</div>\n", 7);
- }
- free (result_buttons.text);
-}
-
-void
-format_navigation_panel (CONVERTER *self,
- BUTTON_SPECIFICATION_LIST *buttons,
- const char *cmdname, const ELEMENT *element,
- int vertical, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_navigation_panel];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_navigation_panel (self, buttons, cmdname,
- element, vertical, result);
- }
- else
- {
- char *navigation_panel
- = call_formatting_function_format_navigation_panel (self,
- formatting_reference,
- buttons, cmdname, element, vertical);
- text_append (result, navigation_panel);
- free (navigation_panel);
- }
-}
-
-static char *vertical_navigation_array[] = {"vertical-navigation"};
-static const STRING_LIST vertical_navigation_classes
- = {vertical_navigation_array, 1, 1};
-
-void
-html_default_format_navigation_header (CONVERTER *self,
- BUTTON_SPECIFICATION_LIST *buttons,
- const char *cmdname,
- const ELEMENT *element, TEXT *result)
-{
- int vertical = 0;
- size_t result_text_index;
- if (self->conf->VERTICAL_HEAD_NAVIGATION.o.integer > 0)
- vertical = 1;
- if (vertical)
- {
- open_element_with_class (self, "table",
- &vertical_navigation_classes, result);
- text_append_n (result, "\n", 1);
- text_append (result, "<tr>\n");
- open_element_with_class (self, "td",
- &vertical_navigation_classes, result);
- text_append_n (result, "\n", 1);
- }
-
- /* keep the current index in result to be able to determine if text was
- added by format_navigation_panel */
- result_text_index = result->end;
- format_navigation_panel (self, buttons, cmdname, element, vertical, result);
-
- if (vertical)
- text_append (result, "</td>\n<td>\n");
- else if (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "node")
- && self->conf->DEFAULT_RULE.o.string
- && result->end > result_text_index)
- {
- text_append (result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (result, "\n", 1);
- }
-}
-
-void
-format_navigation_header (CONVERTER *self,
- BUTTON_SPECIFICATION_LIST *buttons,
- const char *cmdname,
- const ELEMENT *element, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_navigation_header];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_navigation_header (self, buttons, cmdname,
- element, result);
- }
- else
- {
- char *navigation_header
- = call_formatting_function_format_navigation_header (self,
- formatting_reference,
- buttons, cmdname, element);
- text_append (result, navigation_header);
- free (navigation_header);
- }
-}
-
-void
-html_default_format_element_header (CONVERTER *self,
- const char *cmdname, const ELEMENT *command,
- const OUTPUT_UNIT *output_unit, TEXT *result)
-{
- if (self->conf->DEBUG.o.integer > 0)
- {
- size_t i;
- TEXT debug_txt;
- char *output_unit_text;
- text_init (&debug_txt);
- text_append (&debug_txt, "FORMAT elt header (");
- for (i = 0; i < output_unit->unit_contents.number; i++)
- {
- char *elt_str
- = print_element_debug (output_unit->unit_contents.list[i], 0);
- if (i > 0)
- text_append_n (&debug_txt, "|", 1);
- text_append (&debug_txt, elt_str);
- free (elt_str);
- }
- output_unit_text = output_unit_texi (output_unit);
- text_printf (&debug_txt, ") %s\n", output_unit_text);
- free (output_unit_text);
- fprintf (stderr, "%s", debug_txt.text);
- free (debug_txt.text);
- }
-
- /* Do the heading if the command is the first command in the element */
- if ((output_unit->unit_contents.list[0] == command
- || (!output_unit->unit_contents.list[0]->e.c->cmd
- && output_unit->unit_contents.list[1] == command))
- /* and there is more than one element */
- && (output_unit->tree_unit_directions[D_next]
- || output_unit->tree_unit_directions[D_prev]))
- {
- int is_top = unit_is_top_output_unit (self, output_unit);
- size_t file_index;
- size_t count_in_file;
- int first_in_page = 0;
- int previous_is_top = 0;
- if (output_unit->unit_filename)
- {
- file_index = self->output_unit_file_indices[output_unit->index];
- count_in_file
- = count_elements_in_file_number (self, CEFT_current,
- file_index +1);
- if (count_in_file == 1)
- first_in_page = 1;
- }
-
- if (output_unit->tree_unit_directions[D_prev]
- && unit_is_top_output_unit (self,
- output_unit->tree_unit_directions[D_prev]))
- previous_is_top = 1;
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- char *root_heading_texi = root_heading_command_to_texinfo (command);
- fprintf (stderr, "Header (%d, %d, %d): %s\n", previous_is_top,
- is_top, first_in_page, root_heading_texi);
- free (root_heading_texi);
- }
-
- if (is_top)
- /* use TOP_BUTTONS for top. */
- {
- if ((self->conf->SPLIT.o.string && strlen
(self->conf->SPLIT.o.string))
- || self->conf->HEADERS.o.integer > 0)
- format_navigation_header (self, self->conf->TOP_BUTTONS.o.buttons,
- cmdname, command, result);
- }
- else
- {
- if (first_in_page && self->conf->HEADERS.o.integer <= 0)
- {
- if (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "chapter"))
- {
- format_navigation_header (self,
- self->conf->CHAPTER_BUTTONS.o.buttons, cmdname, command,
- result);
- if (self->conf->DEFAULT_RULE.o.string
- && self->conf->VERTICAL_HEAD_NAVIGATION.o.integer <= 0)
- {
- text_append (result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (result, "\n", 1);
- }
- }
- else if (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "section"))
- {
- format_navigation_header (self,
- self->conf->SECTION_BUTTONS.o.buttons, cmdname, command,
- result);
- }
- }
- if ((first_in_page || previous_is_top)
- && self->conf->HEADERS.o.integer > 0)
- {
- format_navigation_header (self,
- self->conf->SECTION_BUTTONS.o.buttons, cmdname, command,
- result);
- }
- else if (self->conf->HEADERS.o.integer > 0
- || (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "node")))
- {
- /* got to do this here, as it isn't done otherwise since
- navigation_header is not called */
- format_navigation_panel (self,
- self->conf->SECTION_BUTTONS.o.buttons,
- cmdname, command, 0, result);
- }
- }
- }
-}
-
-void
-format_element_header (CONVERTER *self,
- const char *cmdname, const ELEMENT *element,
- const OUTPUT_UNIT *output_unit, TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_element_header];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_element_header (self, cmdname, element,
- output_unit, result);
- }
- else
- {
- char *element_header
- = call_formatting_function_format_element_header (self,
- formatting_reference,
- cmdname, element, output_unit);
- text_append (result, element_header);
- free (element_header);
- }
-}
-
-static int
-word_number_more_than_level (const char *text, int level, int *count)
-{
- const char *p = text;
-
- p += strspn (p, whitespace_chars);
-
- if (*p)
- *count = 1;
-
- while (*p)
- {
- size_t n = strspn (p, whitespace_chars);
- if (n)
- {
- p += n;
- /* if not followed by anything, ie at the end of the string,
- do not count the space */
- if (*p)
- {
- (*count)++;
- if (*count >= level)
- return 1;
- }
- else
- return 0;
- }
- /* skip a character */
- int char_len = 1;
- while ((p[char_len] & 0xC0) == 0x80)
- char_len++;
- p += char_len;
- }
- return 0;
-}
-
-void
-html_default_format_element_footer (CONVERTER *self,
- const enum output_unit_type unit_type,
- const OUTPUT_UNIT *output_unit,
- const char *content, const ELEMENT *element,
- TEXT *result)
-{
- int is_top = unit_is_top_output_unit (self, output_unit);
- int next_is_top = 0;
- int next_is_special = 0;
- int end_page = 0;
- BUTTON_SPECIFICATION_LIST *buttons = 0;
-
- if (output_unit->tree_unit_directions[D_next]
- && unit_is_top_output_unit (self,
- output_unit->tree_unit_directions[D_next]))
- next_is_top = 1;
-
- if (output_unit->tree_unit_directions[D_next]
- && output_unit->tree_unit_directions[D_next]->unit_type
- == OU_special_unit)
- next_is_special = 1;
-
- if (!output_unit->tree_unit_directions[D_next])
- end_page = 1;
- else if (output_unit->unit_filename
- && strcmp (output_unit->unit_filename,
- output_unit->tree_unit_directions[D_next]->unit_filename))
- {
- size_t file_index;
- size_t count_in_file;
-
- if (unit_type == OU_special_unit)
- file_index = self->special_unit_file_indices[output_unit->index];
- else
- file_index = self->output_unit_file_indices[output_unit->index];
- count_in_file
- = count_elements_in_file_number (self, CEFT_remaining, file_index +1);
-
- if (count_in_file == 1)
- end_page = 1;
- }
-
- if ((end_page || next_is_top || next_is_special || is_top)
- && self->conf->VERTICAL_HEAD_NAVIGATION.o.integer > 0
- && (!self->conf->SPLIT.o.string || !strlen (self->conf->SPLIT.o.string)
- || strcmp (self->conf->SPLIT.o.string, "node")
- || self->conf->HEADERS.o.integer > 0 || unit_type == OU_special_unit
- || is_top))
- {
- text_append_n (result, "</td>\n</tr>\n</table>\n", 21);
- }
-
- if (end_page)
- {
- STRING_LIST *closed_strings;
- closed_strings = html_close_registered_sections_level (self,
- self->current_filename.file_number, 0);
-
- if (closed_strings->number)
- {
- size_t i;
- for (i = 0; i < closed_strings->number; i++)
- {
- text_append (result, closed_strings->list[i]);
- free (closed_strings->list[i]);
- }
- }
- free (closed_strings->list);
- free (closed_strings);
-
- /* setup buttons for navigation footer */
- if ((is_top || unit_type == OU_special_unit)
- && ((self->conf->SPLIT.o.string
- && strcmp (self->conf->SPLIT.o.string, ""))
- || self->conf->MONOLITHIC.o.integer <= 0)
- && (self->conf->HEADERS.o.integer > 0
- || (self->conf->SPLIT.o.string
- && strcmp (self->conf->SPLIT.o.string, "")
- && strcmp (self->conf->SPLIT.o.string, "node"))))
- {
- if (is_top)
- buttons = self->conf->TOP_FOOTER_BUTTONS.o.buttons;
- else
- buttons = self->conf->MISC_BUTTONS.o.buttons;
- }
- else if (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "section"))
- buttons = self->conf->SECTION_FOOTER_BUTTONS.o.buttons;
- else if (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "chapter"))
- buttons = self->conf->CHAPTER_FOOTER_BUTTONS.o.buttons;
- else if (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "node"))
- {
- if (self->conf->HEADERS.o.integer > 0)
- {
- if (self->conf->WORDS_IN_PAGE.o.integer > 0)
- {
- int count;
- int more_than_level = word_number_more_than_level (content,
- self->conf->WORDS_IN_PAGE.o.integer,
&count);
- if (content && more_than_level)
- {
- buttons = self->conf->NODE_FOOTER_BUTTONS.o.buttons;
- }
- }
- else
- buttons = self->conf->NODE_FOOTER_BUTTONS.o.buttons;
- }
- }
- }
-
- if ((!output_unit->tree_unit_directions[D_next]
- || (output_unit->unit_filename
- && strcmp (output_unit->unit_filename,
- output_unit->tree_unit_directions[D_next]->unit_filename)))
- && (!self->conf->footnotestyle.o.string
- || strcmp (self->conf->footnotestyle.o.string, "separate")))
- {
- format_footnotes_segment (self, result);
- }
-
- if (buttons || !end_page || self->conf->PROGRAM_NAME_IN_FOOTER.o.integer > 0)
- {
- const char *rule = 0;
-
- if (!end_page && (is_top || next_is_top || (next_is_special
- && unit_type != OU_special_unit)))
- {
- rule = self->conf->BIG_RULE.o.string;
- }
- else if (!buttons || is_top || unit_type == OU_special_unit
- || (end_page && self->conf->SPLIT.o.string
- && (!strcmp (self->conf->SPLIT.o.string, "section")
- || !strcmp (self->conf->SPLIT.o.string, "chapter")))
- || (self->conf->SPLIT.o.string
- && !strcmp (self->conf->SPLIT.o.string, "node")
- && self->conf->HEADERS.o.integer > 0))
- {
- rule = self->conf->DEFAULT_RULE.o.string;
- }
- if (rule && strlen (rule))
- {
- text_append (result, rule);
- text_append_n (result, "\n", 1);
- }
- }
-
- if (buttons)
- {
- const char *cmdname = 0;
- if (element)
- cmdname = element_command_name (element);
-
- format_navigation_panel (self, buttons, cmdname, element, 0, result);
- }
-}
-
-void
-format_element_footer (CONVERTER *self,
- const enum output_unit_type unit_type,
- const OUTPUT_UNIT *output_unit,
- const char *content, const ELEMENT *element,
- TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_element_footer];
-
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- html_default_format_element_footer (self, unit_type, output_unit,
- content, element, result);
- }
- else
- {
- char *formatted_footer
- = call_formatting_function_format_element_footer (self,
- formatting_reference,
- unit_type,
- output_unit, content, element);
- text_append (result, formatted_footer);
- free (formatted_footer);
- }
-}
-
-/* return string to be freed by the caller */
-char *
-html_default_format_node_redirection_page (CONVERTER *self,
- const ELEMENT *element,
- const char *filename)
-{
- TEXT result;
- TEXT body;
- BEGIN_FILE_INFORMATION *begin_info;
- const char *package_and_version;
- const char *package_url;
- char *href = html_command_href (self, element, filename, 0, 0);
- char *name = html_command_text (self, element, 0);
- ELEMENT *direction_element = new_text_element (ET__converted);
- NAMED_STRING_ELEMENT_LIST *substrings = new_named_string_element_list ();
-
- text_printf (direction_element->e.text, "<a href=\"%s\">%s</a>", href, name);
- free (name);
-
- add_element_to_named_string_element_list (substrings,
- "href", direction_element);
-
- /* do it before in case there is CSS */
-
- text_init (&body);
- translate_convert_tree_append (
- "The node you are looking for is at {href}.",
- self, substrings, 0, &body, "Tr redirection sentence");
- destroy_named_string_element_list (substrings);
-
- begin_info = file_header_information (self, element, filename);
-
- text_init (&result);
-
- if (self->conf->DOCTYPE.o.string)
- text_append (&result, self->conf->DOCTYPE.o.string);
- text_append_n (&result, "\n", 1);
- text_printf (&result, "<html%s>\n",
begin_info->root_html_element_attributes);
- if (self->conf->PACKAGE_AND_VERSION.o.string)
- package_and_version = self->conf->PACKAGE_AND_VERSION.o.string;
- else
- package_and_version = "";
- if (self->conf->PACKAGE_URL.o.string)
- package_url = self->conf->PACKAGE_URL.o.string;
- else
- package_url = "";
- text_printf (&result, "<!-- Created by %s, %s -->\n"
- "<!-- This file redirects to the location of a node or anchor -->\n"
- "<head>\n",
- package_and_version, package_url);
- if (begin_info->encoding)
- text_append (&result, begin_info->encoding);
- text_append_n (&result, "\n", 1);
- if (self->copying_comment)
- text_append (&result, self->copying_comment);
- text_printf (&result, "<title>%s</title>\n\n", begin_info->title);
- if (begin_info->description)
- text_append (&result, begin_info->description);
- text_append_n (&result, "\n", 1);
- if (begin_info->keywords)
- {
- text_printf (&result, "<meta name=\"keywords\" content=\"%s\"",
- begin_info->keywords);
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
- }
- text_append (&result, "<meta name=\"resource-type\" content=\"document\"");
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
- text_append (&result, "<meta name=\"distribution\" content=\"global\"");
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
- if (begin_info->generator)
- text_append (&result, begin_info->generator);
- if (self->date_in_header)
- text_append (&result, self->date_in_header);
- text_append (&result, begin_info->css_lines);
- text_append_n (&result, "\n", 1);
- text_printf (&result, "<meta http-equiv=\"Refresh\" content=\"0; url=%s\"",
- href);
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
- text_append (&result,
- "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"");
- close_html_lone_element (self, &result);
- text_append_n (&result, "\n", 1);
-
- free (href);
-
- if (begin_info->extra_head)
- text_append (&result, begin_info->extra_head);
- text_append_n (&result, "\n</head>\n\n", 10);
- text_printf (&result, "<body %s>\n", begin_info->body_attributes);
- if (self->conf->AFTER_BODY_OPEN.o.string)
- text_append (&result, self->conf->AFTER_BODY_OPEN.o.string);
-
- text_append_n (&result, "\n<p>", 4);
- text_append (&result, body.text);
- free (body.text);
- text_append_n (&result, "</p>\n</body>\n", 13);
-
- destroy_begin_file_information (begin_info);
-
- return result.text;
-}
-
-/* return string to be freed by the caller */
-char *
-format_node_redirection_page (CONVERTER *self, const ELEMENT *element,
- const char *filename)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_node_redirection_page];
-
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_node_redirection_page (self, element,
- filename);
- }
- else
- {
- return call_formatting_function_format_node_redirection_page (self,
- formatting_reference,
- element, filename);
- }
-}
-
-static void
-text_element_conversion (CONVERTER *self,
- const HTML_NO_ARG_COMMAND_CONVERSION *specification,
- const enum command_id cmd,
- TEXT *result)
-{
- if (specification->element)
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class
- = html_attribute_class (self, specification->element, classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- text_append_n (result, ">", 1);
- if (specification->text)
- text_append (result, specification->text);
- text_append_n (result, "</", 2);
- text_append (result, specification->element);
- text_append_n (result, ">", 1);
- }
- else if (specification->text)
- text_append (result, specification->text);
-}
-
-void
-html_command_conversion_external (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- /* XS specific debug message */
- /*
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "DEBUG: command conversion %s '%s'\n",
- builtin_command_data[cmd].cmdname, content);
- */
-
- const FORMATTING_REFERENCE *formatting_reference
- = self->current_commands_conversion_function[cmd].formatting_reference;
-
- /* NOTE it should always be true as in the main loop a formatting
- function is called only if command_conversion is set, which should
- not be if formatting_reference status is 0 */
- if (formatting_reference->status > 0)
- call_commands_conversion (self, cmd, formatting_reference,
- element, args_formatted, content,
- result);
-}
-
-void
-html_convert_no_arg_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- enum command_id formatted_cmd = cmd;
- enum conversion_context context;
- const HTML_NO_ARG_COMMAND_CONVERSION *specification;
-
- if (html_in_preformatted_context (self) || html_in_math (self))
- context = HCC_type_preformatted;
- else if (html_in_string (self))
- context = HCC_type_string;
- else
- context = HCC_type_normal;
-
- if (cmd == CM_click)
- {
- enum command_id click_cmd = 0;
- const char *click_cmdname = lookup_extra_string (element,
- AI_key_clickstyle);
- if (click_cmdname)
- {
- click_cmd = lookup_builtin_command (click_cmdname);
- }
- if (click_cmd)
- {
- const HTML_NO_ARG_COMMAND_CONVERSION *conv_context
- = self->html_no_arg_command_conversion[click_cmd];
- if (conv_context[context].text || conv_context[context].element)
- {
- formatted_cmd = click_cmd;
- }
- }
- }
-
- if (html_in_upper_case (self)
- && html_commands_data[formatted_cmd].upper_case_cmd)
- {
- formatted_cmd = html_commands_data[formatted_cmd].upper_case_cmd;
- }
-
- specification
- = &self->html_no_arg_command_conversion[formatted_cmd][context];
-
- text_element_conversion (self, specification, formatted_cmd, result);
-}
-
-void
-html_css_string_convert_no_arg_command (CONVERTER *self,
- const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- enum command_id formatted_cmd = cmd;
- if (cmd == CM_click)
- {
- enum command_id click_cmd = 0;
- const char *click_cmdname = lookup_extra_string (element,
- AI_key_clickstyle);
- if (click_cmdname)
- {
- click_cmd = lookup_builtin_command (click_cmdname);
- }
- if (click_cmd)
- {
- formatted_cmd = click_cmd;
- }
- }
-
- if (html_in_upper_case (self)
- && html_commands_data[formatted_cmd].upper_case_cmd)
- {
- formatted_cmd = html_commands_data[formatted_cmd].upper_case_cmd;
- }
-
- text_append (result,
- self->html_no_arg_command_conversion[formatted_cmd]
- [HCC_type_css_string].text);
-}
-
-void
-html_convert_today_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- ELEMENT *today_element = expand_today (self->conf);
-
- add_tree_to_build (self, today_element);
-
- convert_tree_append (self, today_element, result, "convert today");
-
- remove_tree_to_build (self, today_element);
- destroy_element_and_children (today_element);
-}
-
-void
-html_convert_style_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- enum command_id style_cmd = cmd;
- const HTML_STYLE_COMMAND_CONVERSION *formatting_spec;
-
- /* happens with bogus @-commands without argument, like @strong something */
- if (!args_formatted || args_formatted->number <= 0
- || !args_formatted->args[0].formatted[AFT_type_normal])
- return;
-
- if (html_in_string (self))
- {
- text_append (result, args_formatted->args[0].formatted[AFT_type_normal]);
- return;
- }
-
- if (cmd == CM_kbd)
- {
- int code = (element->flags & EF_code);
- if (code > 0)
- style_cmd = CM_code;
- }
-
- if (html_in_preformatted_context (self))
- formatting_spec
- = &self->html_style_command_conversion[style_cmd][HCC_type_preformatted];
- else
- formatting_spec
- = &self->html_style_command_conversion[style_cmd][HCC_type_normal];
-
- if (formatting_spec->element)
- {
- char *open;
- size_t open_len;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (style_cmd), classes);
-
- if (style_cmd != cmd)
- {
- char *style_as_cmd;
- xasprintf (&style_as_cmd, "as-%s-%s",
- builtin_command_name (style_cmd),
- builtin_command_name (cmd));
- add_string (style_as_cmd, classes);
- free (style_as_cmd);
- }
-
- if (formatting_spec->quote && self->conf->OPEN_QUOTE_SYMBOL.o.string)
- text_append (result, self->conf->OPEN_QUOTE_SYMBOL.o.string);
-
- open
- = html_attribute_class (self, formatting_spec->element, classes);
- open_len = strlen (open);
- destroy_strings_list (classes);
-
- if (open_len > 0)
- {
- text_append (result, open);
- text_append_n (result, ">", 1);
- }
-
- if (open)
- free (open);
-
- text_append (result, args_formatted->args[0].formatted[AFT_type_normal]);
-
- if (open_len > 0)
- {
- text_append_n (result, "</", 2);
- text_append (result, formatting_spec->element);
- text_append_n (result, ">", 1);
- }
-
- if (formatting_spec->quote && self->conf->CLOSE_QUOTE_SYMBOL.o.string)
- text_append (result, self->conf->CLOSE_QUOTE_SYMBOL.o.string);
- }
- else
- text_append (result, args_formatted->args[0].formatted[AFT_type_normal]);
-}
-
-void
-html_convert_w_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (args_formatted && args_formatted->number > 0)
- {
- if (args_formatted->args[0].formatted[AFT_type_normal])
- text_append (result,
- args_formatted->args[0].formatted[AFT_type_normal]);
- }
- if (!html_in_string (self))
- {
- text_append (result, "<!-- /@w -->");
- }
-}
-
-void
-html_convert_value_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- ELEMENT *tree;
- ELEMENT *value_text = new_text_element (ET_normal_text);
- NAMED_STRING_ELEMENT_LIST *substrings = new_named_string_element_list ();
-
- text_append (value_text->e.text,
- args_formatted->args[0].formatted[AFT_type_monospacestring]);
- add_element_to_named_string_element_list (substrings,
- "value", value_text);
-
- tree = html_cdt_tree ("@{No value for `{value}'@}",
- self, substrings, 0);
-
- add_tree_to_build (self, tree);
- convert_tree_append (self, tree, result, "Tr missing value");
- remove_tree_to_build (self, tree);
-
- destroy_element_and_children (tree);
-
- destroy_named_string_element_list (substrings);
-}
-
-void
-html_convert_email_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const char *mail = 0;
- const char *mail_string = 0;
- const char *text = 0;
-
- if (args_formatted)
- {
- if (args_formatted->number > 0)
- {
- mail = args_formatted->args[0].formatted[AFT_type_url];
- mail_string
- = args_formatted->args[0].formatted[AFT_type_monospacestring];
- }
-
- if (args_formatted->number > 1
- && args_formatted->args[1].formatted[AFT_type_normal])
- {
- text = args_formatted->args[1].formatted[AFT_type_normal];
- }
- }
-
- if (!text || !strlen (text))
- {
- text = mail_string;
- }
-
- /* FIXME in perl unicode spaces are also matched */
- if (!mail || mail[strspn (mail, whitespace_chars)] == '\0')
- {
- if (text)
- text_append (result, text);
- return;
- }
-
- if (html_in_string (self))
- {
- text_printf (result, "%s (%s)", mail_string, text);
- }
- else
- {
- char *attribute_class;
- char *protected_mailto;
- char *mailto;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "a", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- xasprintf (&mailto, "mailto:%s", mail);
- protected_mailto = url_protect_url_text (self, mailto);
- free (mailto);
-
- text_printf (result, " href=\"%s\">%s</a>", protected_mailto, text);
- free (protected_mailto);
- }
-}
-
-void
-html_convert_explained_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- TEXT explained_string;
- TEXT *text_result;
- const char *explained_arg = 0;
- char *normalized_type = 0;
- const char *explanation_string = 0;
- const char *explanation_result = 0;
- EXPLAINED_COMMAND_TYPE_LIST *type_explanations
- = &self->shared_conversion_state.explained_commands;
-
- if (element->e.c->args.number > 0
- && element->e.c->args.list[0]->e.c->contents.number > 0)
- {
- normalized_type = convert_to_identifier (element->e.c->args.list[0]);
- }
- else
- normalized_type = strdup ("");
-
- if (args_formatted && args_formatted->number > 1)
- {
- if (args_formatted->args[1].formatted[AFT_type_string])
- {
- explanation_string
- = args_formatted->args[1].formatted[AFT_type_string];
-
- if (explanation_string[strspn
- (explanation_string, whitespace_chars)] != '\0')
- {
- register_explained_command_string (type_explanations,
- cmd, normalized_type, explanation_string);
- }
- else
- explanation_string = 0;
- }
- if (args_formatted->args[1].formatted[AFT_type_normal])
- explanation_result = args_formatted->args[1].formatted[AFT_type_normal];
- }
-
- if (!explanation_string)
- {
- EXPLAINED_COMMAND_TYPE *type_explanation
- = find_explained_command_string (type_explanations,
- cmd, normalized_type);
- if (type_explanation)
- explanation_string = type_explanation->explanation;
- }
-
- free (normalized_type);
-
- if (explanation_result)
- {
- text_init (&explained_string);
- text_result = &explained_string;
- }
- else
- text_result = result;
-
- if (args_formatted && args_formatted->number > 0 &&
- args_formatted->args[0].formatted[AFT_type_normal])
- explained_arg = args_formatted->args[0].formatted[AFT_type_normal];
- else
- explained_arg = "";
-
- if (!html_in_string (self))
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "abbr", classes);
- destroy_strings_list (classes);
- text_append (text_result, attribute_class);
- free (attribute_class);
-
- if (explanation_string)
- text_printf (text_result, " title=\"%s\"", explanation_string);
- text_append_n (text_result, ">", 1);
- text_append (text_result, explained_arg);
- text_append_n (text_result, "</abbr>", 7);
- }
- else
- text_append (text_result, explained_arg);
-
- if (explanation_result)
- {
- char *context_str;
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
- ELEMENT *explained_string_element = new_text_element (ET__converted);
- ELEMENT *explanation_result_element = new_text_element (ET__converted);
- ELEMENT *tree;
-
- text_append (explained_string_element->e.text, text_result->text);
- free (text_result->text);
- text_append (explanation_result_element->e.text, explanation_result);
-
- add_element_to_named_string_element_list (substrings,
- "explained_string", explained_string_element);
- add_element_to_named_string_element_list (substrings,
- "explanation", explanation_result_element);
- tree = html_cdt_tree ("{explained_string} ({explanation})",
- self, substrings, 0);
- destroy_named_string_element_list (substrings);
-
- xasprintf (&context_str, "convert explained %s",
- builtin_command_name (cmd));
- add_tree_to_build (self, tree);
- convert_tree_append (self, tree, result, context_str);
- remove_tree_to_build (self, tree);
- free (context_str);
- /* should destroy explained_*_element */
- destroy_element_and_children (tree);
- }
-}
-
-void
-html_convert_anchor_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (!html_in_multi_expanded (self) && !html_in_string (self))
- {
- const char *id = html_command_id (self, element);
- if (id && strlen (id))
- {
- format_separate_anchor (self, id, "anchor", result);
- }
- }
-}
-
-static int
-compare_footnote_id (const void *a, const void *b)
-{
- const FOOTNOTE_ID_NUMBER *fid_a = (const FOOTNOTE_ID_NUMBER *) a;
- const FOOTNOTE_ID_NUMBER *fid_b = (const FOOTNOTE_ID_NUMBER *) b;
-
- return strcmp (fid_a->footnote_id, fid_b->footnote_id);
-}
-
-FOOTNOTE_ID_NUMBER *
-find_footnote_id_number (const CONVERTER *self, const char *footnote_id)
-{
- const ELEMENT_LIST *global_footnotes
- = &self->document->global_commands.footnotes;
-
- FOOTNOTE_ID_NUMBER *result = 0;
- static FOOTNOTE_ID_NUMBER searched_footnote_id;
- searched_footnote_id.footnote_id = footnote_id;
- if (global_footnotes->number == 0)
- {
- char *msg;
- xasprintf (&msg, "no footnotes, searching for '%s'\n", footnote_id);
- fatal (msg);
- free (msg);
- }
-
- result = (FOOTNOTE_ID_NUMBER *) bsearch (&searched_footnote_id,
- self->shared_conversion_state.footnote_id_numbers,
- global_footnotes->number, sizeof (FOOTNOTE_ID_NUMBER),
- compare_footnote_id);
- return result;
-}
-
-void
-html_convert_footnote_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- static const char *target_prefix = "t_f";
- char *footnote_mark;
- const char *footnote_id;
- const char *footnote_docid;
- char *footid;
- char *docid;
- int multiple_expanded_footnote = 0;
- const char *multi_expanded_region;
- int foot_num;
- char *footnote_href;
- char *attribute_class;
- STRING_LIST *classes;
-
- self->shared_conversion_state.footnote_number++;
- foot_num = self->shared_conversion_state.footnote_number;
-
- if (self->conf->NUMBER_FOOTNOTES.o.integer > 0)
- xasprintf (&footnote_mark, "%d", foot_num);
- else if (self->conf->NO_NUMBER_FOOTNOTE_SYMBOL.o.string)
- footnote_mark = strdup (self->conf->NO_NUMBER_FOOTNOTE_SYMBOL.o.string);
- else
- footnote_mark = strdup ("");
-
- if (html_in_string (self))
- {
- text_printf (result, "(%s)", footnote_mark);
- free (footnote_mark);
- return;
- }
-
- footnote_id = html_command_id (self, element);
-
- /* happens for bogus footnotes */
- if (!footnote_id)
- {
- free (footnote_mark);
- return;
- }
-
- /* ID for linking back to the main text from the footnote. */
- footnote_docid = html_footnote_location_target (self, element);
-
- multi_expanded_region = html_in_multi_expanded (self);
- if (multi_expanded_region)
- {
- /* to avoid duplicate names, use a prefix that cannot happen in anchors */
- xasprintf (&footid, "%s%s_%s_%d", target_prefix, multi_expanded_region,
- footnote_id, foot_num);
- xasprintf (&docid, "%s%s_%s_%d", target_prefix, multi_expanded_region,
- footnote_docid, foot_num);
- }
- else
- {
- FOOTNOTE_ID_NUMBER *footnote_id_number
- = find_footnote_id_number (self, footnote_id);
- if (!footnote_id_number)
- fatal ("footnote_id not found");
- if (!footnote_id_number->number)
- {
- footid = strdup (footnote_id);
- docid = strdup (footnote_docid);
- }
- else
- {
- /* This should rarely happen, except for @footnote in @copying and
- multiple @insertcopying...
- Here it is not checked that there is no clash with another anchor.
- However, unless there are more than 1000 footnotes this should not
- happen at all, and even in that case it is very unlikely.
- */
- xasprintf (&footid, "%s_%d", footnote_id, foot_num);
- xasprintf (&docid, "%s_%d", footnote_docid, foot_num);
- multiple_expanded_footnote = 1;
- }
- footnote_id_number->number++;
- }
-
- if ((!self->conf->footnotestyle.o.string
- || strcmp (self->conf->footnotestyle.o.string, "separate"))
- && (multi_expanded_region || multiple_expanded_footnote))
- {
- /* if the footnote appears multiple times, command_href() will select
- one, but it may not be the one expanded at the location currently
- formatted (in general the first one, but it depends if it is in a
- tree element or not, for instance in @titlepage).
- With footnotestyle end, considering that the footnote is in the same file
- has a better chance of being correct.
- */
- xasprintf (&footnote_href, "#%s", footid);
- }
- else
- footnote_href = html_command_href (self, element, 0, 0, footid);
-
- html_register_footnote (self, element, footid, docid, foot_num,
- self->current_filename.filename,
- multi_expanded_region);
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "a", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- text_printf (result, " id=\"%s\" href=\"%s\">", docid, footnote_href);
-
- if (html_in_preformatted_context (self))
- text_printf (result, "(%s)", footnote_mark);
- else
- text_printf (result, "<sup>%s</sup>", footnote_mark);
-
- text_append_n (result, "</a>", 4);
-
- free (footnote_href);
- free (footnote_mark);
- free (footid);
- free (docid);
-}
-
-void
-html_convert_uref_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const char *url = 0;
- const char *url_string = 0;
- const char *text = 0;
- const char *replacement;
- char *protected_url;
- char *attribute_class;
- STRING_LIST *classes;
-
- if (!args_formatted)
- return;
-
- if (args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_url]
- && args_formatted->args[0].formatted[AFT_type_monospacestring])
- {
- url = args_formatted->args[0].formatted[AFT_type_url];
- url_string = args_formatted->args[0].formatted[AFT_type_monospacestring];
- }
- if (args_formatted->number > 1
- && args_formatted->args[1].formatted[AFT_type_normal])
- {
- text = args_formatted->args[1].formatted[AFT_type_normal];
- }
- if (args_formatted->number > 2
- && args_formatted->args[2].formatted[AFT_type_normal])
- {
- replacement
- = args_formatted->args[2].formatted[AFT_type_normal];
- if (strlen (replacement))
- text = replacement;
- }
- if ((!text || !strlen (text)) && url_string)
- text = url_string;
-
- if (!url || !strlen (url))
- {
- if (text)
- text_append (result, text);
- return;
- }
-
- if (html_in_string (self))
- {
- text_printf (result, "%s (%s)", text, url_string);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "a", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
- protected_url = url_protect_url_text (self, url);
- text_printf (result, " href=\"%s\">%s</a>", protected_url, text);
- free (protected_url);
-}
-
-static const char *image_files_extensions[] = {
-".png", ".jpg", ".jpeg", ".gif", 0
-};
-
-/* return, IMAGE_PATH and IMAGE_PATH_ENCODING to be freed by caller */
-static char *
-find_image_extension_file (CONVERTER *self, const ELEMENT *element,
- const char *image_basefile,
- const char *extension,
- char **image_path,
- char **image_path_encoding)
-{
- char *image_file;
- char *input_file_encoding;
- char *file_name;
- char *located_image_path;
-
- xasprintf (&image_file, "%s%s", image_basefile, extension);
- file_name = encoded_input_file_name (self->conf,
&self->document->global_info,
- image_file, 0, &input_file_encoding,
&element->e.c->source_info);
-
- located_image_path = locate_include_file (file_name,
- self->conf->INCLUDE_DIRECTORIES.o.strlist);
- free (file_name);
-
- if (located_image_path)
- {
- *image_path_encoding = input_file_encoding;
- *image_path = located_image_path;
- return image_file;
- }
-
- free (image_file);
- free (input_file_encoding);
- return 0;
-}
-
-typedef struct IMAGE_FILE_LOCATION_INFO {
- char *image_file;
- char *image_extension;
- char *image_path;
- char *image_path_encoding;
-} IMAGE_FILE_LOCATION_INFO;
-
-void
-free_image_file_location_info (IMAGE_FILE_LOCATION_INFO *location_info)
-{
- free (location_info->image_file);
- free (location_info->image_extension);
- free (location_info->image_path);
- free (location_info->image_path_encoding);
-}
-
-IMAGE_FILE_LOCATION_INFO *
-html_image_file_location_name (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element, const char *image_basefile,
- const HTML_ARGS_FORMATTED *args_formatted)
-{
- char *image_file = 0;
- const char *extension = 0;
-
- IMAGE_FILE_LOCATION_INFO *result = (IMAGE_FILE_LOCATION_INFO *)
- malloc (sizeof (IMAGE_FILE_LOCATION_INFO));
-
- if (args_formatted->number > 4
- && args_formatted->args[4].formatted[AFT_type_filenametext])
- {
- extension
- = args_formatted->args[4].formatted[AFT_type_filenametext];
- image_file
- = find_image_extension_file (self, element, image_basefile,
- extension, &result->image_path,
- &result->image_path_encoding);
- if (!image_file)
- {
- char *dot_ext;
- xasprintf (&dot_ext, ".%s", extension);
- image_file
- = find_image_extension_file (self, element, image_basefile,
- dot_ext, &result->image_path,
- &result->image_path_encoding);
- if (image_file)
- result->image_extension = dot_ext;
- else
- free (dot_ext);
- }
- else
- result->image_extension = strdup (extension);
- }
-
- if (!image_file)
- {
- int i;
- for (i = 0; image_files_extensions[i]; i++)
- {
- image_file
- = find_image_extension_file (self, element, image_basefile,
- image_files_extensions[i], &result->image_path,
- &result->image_path_encoding);
- if (image_file)
- {
- result->image_extension = strdup (image_files_extensions[i]);
- break;
- }
- }
- }
-
- if (!image_file)
- {
- result->image_path = 0;
- result->image_path_encoding = 0;
- if (extension)
- {
- xasprintf (&result->image_file, "%s%s", image_basefile,
- extension);
- result->image_extension = strdup (extension);
- }
- else
- {
- xasprintf (&result->image_file, "%s.jpg", image_basefile);
- result->image_extension = strdup (".jpg");
- }
- }
- else
- result->image_file = image_file;
-
- return result;
-}
-
-void
-html_convert_image_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (args_formatted
- && args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_filenametext]
- && strlen (args_formatted->args[0].formatted[AFT_type_filenametext]))
- {
- IMAGE_FILE_LOCATION_INFO *image_path_info;
- const char *image_basefile
- = args_formatted->args[0].formatted[AFT_type_filenametext];
- const char *basefile_string = 0;
- char *image_file;
- char *attribute_class;
- char *protected_image_file;
- STRING_LIST *classes;
- const char *alt_string;
-
- if (args_formatted->args[0].formatted[AFT_type_monospacestring])
- basefile_string
- = args_formatted->args[0].formatted[AFT_type_monospacestring];
-
- if (html_in_string (self))
- {
- if (basefile_string)
- text_append (result, basefile_string);
- return;
- }
-
- image_path_info = html_image_file_location_name (self, cmd, element,
- image_basefile,
- args_formatted);
- image_file = image_path_info->image_file;
- image_path_info->image_file = 0;
-
- if (!image_path_info->image_path)
- {
- /* it would have been relevant to output the message only if
- if not ($self->in_multiple_conversions())
- However, @image formatted in multiple conversions context should be
- rare out of test suites (and probably always incorrect), so we avoid
- complexity and slowdown. We still check that source_info is set, if
- not it should be a copy, therefore there is no need for error
- output, especially without line information. */
- if (element->e.c->source_info.line_nr)
- {
- message_list_command_warn (&self->error_messages, self->conf,
- element, 0, "@image file `%s' (for HTML) not found, using
`%s'",
- image_basefile, image_file);
- }
- }
- free_image_file_location_info (image_path_info);
- free (image_path_info);
-
- if (self->conf->IMAGE_LINK_PREFIX.o.string)
- {
- char *tmp;
- xasprintf (&tmp, "%s%s", self->conf->IMAGE_LINK_PREFIX.o.string,
- image_file);
- free (image_file);
- image_file = tmp;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "img", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- protected_image_file = url_protect_file_text (self, image_file);
- free (image_file);
-
- if (args_formatted->number > 3
- && args_formatted->args[3].formatted[AFT_type_string]
- && strlen (args_formatted->args[3].formatted[AFT_type_string]))
- alt_string = args_formatted->args[3].formatted[AFT_type_string];
- else if (basefile_string)
- alt_string = basefile_string;
- else
- alt_string = "";
-
- text_printf (result, " src=\"%s\" alt=\"%s\"", protected_image_file,
- alt_string);
-
- free (protected_image_file);
- close_html_lone_element (self, result);
- }
-}
-
-void
-html_convert_math_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *attribute_class;
- STRING_LIST *classes;
- const char *arg;
-
- if (!args_formatted || args_formatted->number <= 0
- || !args_formatted->args[0].formatted[AFT_type_normal])
- return;
-
- arg = args_formatted->args[0].formatted[AFT_type_normal];
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- if (self->conf->HTML_MATH.o.string
- && !strcmp (self->conf->HTML_MATH.o.string, "mathjax"))
- {
- html_register_file_information (self, "mathjax", 1);
- add_string ("tex2jax_process", classes);
- attribute_class = html_attribute_class (self, "em", classes);
- text_append (result, attribute_class);
- text_printf (result, ">\\(%s\\)</em>", arg);
- goto out;
- }
-
- attribute_class = html_attribute_class (self, "em", classes);
- text_append (result, attribute_class);
- text_printf (result, ">%s</em>", arg);
-
- out:
- destroy_strings_list (classes);
- free (attribute_class);
-}
-
-/* return string to be freed by caller */
-static char *
-set_case_if_only_word_characters (const char *text, int set_case)
-{
- char *text_set;
-
- if (set_case)
- {
- int str_len = strlen (text);
- if (str_len != 1 || !isascii_alnum (*text))
- {
- int w_len = word_bytes_len_multibyte (text);
- /* not only alphanumeric characters, do not change case */
- if (w_len != str_len)
- set_case = 0;
- }
- }
-
- if (set_case)
- text_set = to_upper_or_lower_multibyte (text, set_case);
- else
- text_set = strdup (text);
-
- return text_set;
-}
-
-char *
-html_accent_entities_html_accent_internal (CONVERTER *self, const char *text,
- const ELEMENT *element, int set_case,
- int use_numeric_entities)
-{
- char *text_set = set_case_if_only_word_characters (text, set_case);
-
- /* do not return a dotless i or j as such if it is further composed
- with an accented letter, return the letter as is */
- if (element->e.c->cmd == CM_dotless
- /* corresponds to perl exists unicode_accented_letters{accent}->{text} */
- && (!strcmp (text_set, "i") || !strcmp (text_set, "j")))
- {
- if (element->parent && element->parent->parent
- && element->parent->parent->e.c->cmd)
- {
- enum command_id p_cmd
- = element_builtin_cmd (element->parent->parent);
- if (builtin_command_data[p_cmd].flags & CF_accent
- && p_cmd != CM_tieaccent)
- {
- return text_set;
- }
- }
- }
-
- if (use_numeric_entities)
- {
- char *formatted_accent
- = xml_numeric_entity_accent (element->e.c->cmd, text_set);
- if (formatted_accent)
- {
- free (text_set);
- return formatted_accent;
- }
- }
- else
- {
- char *formatted_accent;
- if (strlen (text_set) == 1 && isascii_alpha (*text_set)
- && self->accent_entities[element->e.c->cmd].entity
- && self->accent_entities[element->e.c->cmd].characters
- && strlen (self->accent_entities[element->e.c->cmd].characters)
- && strrchr (self->accent_entities[element->e.c->cmd].characters,
- *text_set))
- {
- xasprintf (&formatted_accent, "&%s%s;", text_set,
- self->accent_entities[element->e.c->cmd].entity);
- free (text_set);
- return formatted_accent;
- }
- formatted_accent = xml_numeric_entity_accent (element->e.c->cmd,
- text_set);
- if (formatted_accent)
- {
- free (text_set);
- return formatted_accent;
- }
- }
- /* should only be the case of @dotless, as other commands have a diacritic
- associated, and only if the argument is not i nor j. */
- return text_set;
-}
-
-char *
-html_accent_entities_html_accent (CONVERTER *self, const char *text,
- const ELEMENT *element, int set_case)
-{
- return html_accent_entities_html_accent_internal (self, text,
- element, set_case, 0);
-}
-
-char *
-html_accent_entities_numeric_entities_accent (CONVERTER *self,
- const char *text, const ELEMENT *element, int set_case)
-{
- return html_accent_entities_html_accent_internal (self, text,
- element, set_case, 1);
-}
-
-void
-html_convert_accent_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *accent_text;
- char *(*format_accents)(CONVERTER *self, const char *text,
- const ELEMENT *element, int set_case);
-
- int output_encoded_characters = (self->conf->OUTPUT_CHARACTERS.o.integer >
0);
-
- if (self->conf->USE_NUMERIC_ENTITY.o.integer > 0)
- format_accents = &html_accent_entities_numeric_entities_accent;
- else
- format_accents = &html_accent_entities_html_accent;
-
- accent_text = convert_accents (self, element, &html_convert_tree,
- format_accents, output_encoded_characters,
- html_in_upper_case (self));
-
- text_append (result, accent_text);
- free (accent_text);
-}
-
-char *
-css_string_accent (CONVERTER *self, const char *text,
- const ELEMENT *element, int set_case)
-{
- char *text_set = set_case_if_only_word_characters (text, set_case);
-
- if (element->e.c->cmd == CM_dotless)
- {
- /* corresponds in perl, and for dotless, to
- Texinfo::Convert::Unicode::unicode_accented_letters{$accent}->{$text} */
- if (!strcmp (text_set, "i"))
- {
- free (text_set);
- return strdup ("\\" "0131" " ");
- }
- else if (!strcmp (text_set, "j"))
- {
- free (text_set);
- return strdup ("\\" "0237" " ");
- }
- }
-
- if (unicode_diacritics[element->e.c->cmd].text)
- {
- char *accent_and_diacritic;
- char *normalized_accent_text;
- static TEXT accented_text;
- text_init (&accented_text);
- if (element->e.c->cmd == CM_tieaccent)
- {
- /* tieaccent diacritic is naturally and correctly composed
- between two characters */
- /* we consider that letters are either characters or
- escaped characters as they appear in CSS strings */
- /* p non NUL corresponds to escaped characters */
- char *p = html_after_escaped_characters (text_set);
- char *next_text = 0;
- ucs4_t first_char;
- const uint8_t *next = 0;
- uint8_t *encoded_u8 = 0;
-
- if (!p)
- {
- /* check if a character matches */
- encoded_u8 = utf8_from_string (text);
- next = u8_next (&first_char, encoded_u8);
- if (next && (uc_is_general_category (first_char, UC_CATEGORY_L)
- /* ASCII digits */
- || (first_char >= 0x0030 && first_char <= 0x0039)))
- {
- next_text = string_from_utf8 (next);
- }
- }
- else
- {
- next_text = p;
- }
-
- if (next_text)
- {
- ucs4_t second_char;
- const char *q = html_after_escaped_characters (next_text);
-
- if (!q)
- {
- const uint8_t *remaining;
- if (!next)
- {/* next_text should be equal to p */
- encoded_u8 = utf8_from_string (p);
- next = encoded_u8;
- }
- remaining = u8_next (&second_char, next);
- if (remaining
- && (uc_is_general_category (second_char, UC_CATEGORY_L)
- /* ASCII digits */
- || (second_char >= 0x0030 && second_char <= 0x0039)))
- {
- /* next_text remains as the text to add after
- the diacritic */
- }
- else
- {
- if (!p)
- free (next_text);
- next_text = 0;
- }
- }
-
- if (next_text)
- {
- /* add the first character or escaped text */
- if (!p)
- {
- char *first_char_text;
- uint8_t *first_char_u8 = malloc (7 * sizeof (uint8_t));
- int first_char_len
- = u8_uctomb (first_char_u8, first_char, 6);
- if (first_char_len < 0)
- fatal ("u8_uctomb returns negative value");
- first_char_u8[first_char_len] = 0;
- first_char_text = string_from_utf8 (first_char_u8);
- free (first_char_u8);
- text_append (&accented_text, first_char_text);
- free (first_char_text);
- }
- else
- text_append_n (&accented_text, text_set, p - text_set);
-
- /* add the tie accent */
- text_printf (&accented_text, "\\%s ",
- unicode_diacritics[element->e.c->cmd].hex_codepoint);
- /* add the remaining, second character or escaped text
- and everything else after (which is in general invalid
- but we do not care) */
- text_append (&accented_text, next_text);
- }
- }
- free (encoded_u8);
- if (!p)
- free (next_text);
- if (accented_text.end > 0)
- {
- free (text_set);
- return accented_text.text;
- }
- }
-
- /* case of text and diacritic (including fallback for invalid tie
- accent) */
- /* check if the normalization leads to merging text and diacritic,
- if yes use the merged character, if not output text and diacitic
- to be set up for composition */
- xasprintf (&accent_and_diacritic, "%s%s",
- text, unicode_diacritics[element->e.c->cmd].text);
- normalized_accent_text = normalize_NFC (accent_and_diacritic);
- free (accent_and_diacritic);
- /* check if the normalization led to merging text and diacritic
- as one character. If not, the leading text remains, this
- is what the comparison checks */
- if (!strncmp (normalized_accent_text, text, strlen (text)))
- {
- /* no normalization as one character, output text and diacritic
- such that they could be composed */
- text_append (&accented_text, text);
- text_printf (&accented_text, "\\%s ",
- unicode_diacritics[element->e.c->cmd].hex_codepoint);
- }
- else
- {
- /* determine the hexadecimal unicode point of the normalized
- character to output in the format expected in CSS strings */
- char *next_text;
- uint8_t *encoded_u8 = utf8_from_string (normalized_accent_text);
- ucs4_t first_char;
- const uint8_t *next = u8_next (&first_char, encoded_u8);
- text_printf (&accented_text, "\\%04lX ", first_char);
- next_text = string_from_utf8 (next);
- free (encoded_u8);
- text_append (&accented_text, next_text);
- free (next_text);
- }
- free (normalized_accent_text);
- free (text_set);
- return accented_text.text;
- }
-
- /* There are diacritics for every accent command except for dotless.
- We should only get there with dotless if the argument is not recognized.
- */
- return text_set;
-}
-
-void
-html_css_string_convert_accent_command (CONVERTER *self,
- const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *accent_text;
- char *(*format_accents)(CONVERTER *self, const char *text,
- const ELEMENT *element, int set_case);
-
- int output_encoded_characters = (self->conf->OUTPUT_CHARACTERS.o.integer >
0);
-
- format_accents = &css_string_accent;
-
- accent_text = convert_accents (self, element, &html_convert_tree,
- format_accents, output_encoded_characters,
- html_in_upper_case (self));
-
- text_append (result, accent_text);
- free (accent_text);
-}
-
-void
-html_convert_indicateurl_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- /* happens with bogus @-commands without argument, like @strong something */
- if (!args_formatted || args_formatted->number <= 0
- || !args_formatted->args[0].formatted[AFT_type_normal])
- return;
-
- if (self->conf->OPEN_QUOTE_SYMBOL.o.string)
- text_append (result, self->conf->OPEN_QUOTE_SYMBOL.o.string);
-
- if (!html_in_string (self))
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "code", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- text_append_n (result, ">", 1);
-
- text_append (result, args_formatted->args[0].formatted[AFT_type_normal]);
- text_append_n (result, "</code>", 7);
- }
- else
- text_append (result, args_formatted->args[0].formatted[AFT_type_normal]);
-
- if (self->conf->CLOSE_QUOTE_SYMBOL.o.string)
- text_append (result, self->conf->CLOSE_QUOTE_SYMBOL.o.string);
-}
-
-void
-html_convert_titlefont_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (args_formatted && args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]))
- {
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
- format_heading_text (self, cmd, classes,
- args_formatted->args[0].formatted[AFT_type_normal],
- 0, 0, 0, 0, result);
- destroy_strings_list (classes);
- }
-}
-
-void
-html_convert_U_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (args_formatted && args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]))
- {
- text_printf (result, "&#x%s;",
- args_formatted->args[0].formatted[AFT_type_normal]);
- }
-}
-
-/* command is NULL unless called from @-command formatting function */
-static char *
-contents_inline_element (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element)
-{
- char *table_of_contents;
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "CONTENTS_INLINE %s\n", builtin_command_name (cmd));
-
- table_of_contents = format_contents (self, cmd, element, 0);
- if (table_of_contents && strlen (table_of_contents))
- {
- int j;
- for (j = 0; self->command_special_variety_name_index[j].cmd; j++)
- {
- COMMAND_ID_INDEX cmd_variety_index
- = self->command_special_variety_name_index[j];
- if (cmd_variety_index.cmd == cmd)
- {
- const char *id;
- char *heading = 0;
- TEXT result;
- STRING_LIST *classes;
- const char *class_base;
- char *class;
- char *attribute_class;
-
- const char *special_unit_variety
- = self->special_unit_varieties.list[cmd_variety_index.index];
- int special_unit_direction_index
- = html_special_unit_variety_direction_index (self,
- special_unit_variety);
- const OUTPUT_UNIT *special_unit
- = self->global_units_directions[special_unit_direction_index];
- const ELEMENT *unit_command
- = special_unit->uc.special_unit_command;
-
- text_init (&result);
-
- classes = new_string_list ();
- class_base = html_special_unit_info (self, SUI_type_class,
- special_unit_variety);
- xasprintf (&class, "region-%s", class_base);
-
- add_string (class, classes);
- free (class);
- attribute_class = html_attribute_class (self, "div", classes);
- clear_strings_list (classes);
-
- text_append (&result, attribute_class);
- free (attribute_class);
-
- id = html_command_id (self, unit_command);
- if (id && strlen (id))
- text_printf (&result, " id=\"%s\"", id);
- heading = html_command_text (self, unit_command, 0);
-
- text_append_n (&result, ">\n", 2);
-
- xasprintf (&class, "%s-heading", class_base);
-
- add_string (class, classes);
- free (class);
-
- if (!heading)
- heading = strdup ("");
- format_heading_text (self, 0, classes, heading,
- self->conf->CHAPTER_HEADER_LEVEL.o.integer,
- 0, 0, 0, &result);
- destroy_strings_list (classes);
-
- free (heading);
-
- text_append_n (&result, "\n", 1);
-
- text_append (&result, table_of_contents);
- text_append_n (&result, "</div>\n", 7);
-
- free (table_of_contents);
- return result.text;
- }
- }
- }
- return 0;
-}
-
-static char *mini_toc_array[] = {"mini-toc"};
-static const STRING_LIST mini_toc_classes = {mini_toc_array, 1, 1};
-
-/* Output a list of the nodes immediately below this one */
-void
-mini_toc_internal (CONVERTER *self, const ELEMENT *element, TEXT *result)
-{
- int entry_index = 0;
-
- const CONST_ELEMENT_LIST *section_childs = lookup_extra_contents (element,
- AI_key_section_childs);
- if (section_childs && section_childs->number > 0)
- {
- char *attribute_class;
- size_t i;
-
- attribute_class = html_attribute_class (self, "ul", &mini_toc_classes);
-
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">\n", 2);
-
- for (i = 0; i < section_childs->number; i++)
- {
- const ELEMENT *section = section_childs->list[i];
- /* using command_text leads to the same HTML formatting, but does not give
- the same result for the other files, as the formatting is done in a
- global context, while taking the tree first and calling convert_tree
- converts in the current page context.
- text = html_command_text (self, section, HTT_text_nonumber);
- */
- TREE_ADDED_ELEMENTS *command_tree
- = html_command_tree (self, section, 1);
- char *explanation;
- char *accesskey;
- char *text;
- char *href;
-
- /* happens with empty sectioning command */
- if (!command_tree->tree)
- continue;
-
- href = html_command_href (self, section, 0, 0, 0);
-
- xasprintf (&explanation, "mini_toc @%s",
- element_command_name (section));
- text = html_convert_tree (self, command_tree->tree, explanation);
- free (explanation);
-
- entry_index++;
-
- if (self->conf->USE_ACCESSKEY.o.integer > 0 && entry_index < 10)
- {
- xasprintf (&accesskey, " accesskey=\"%d\"", entry_index);
- }
- else
- accesskey = strdup ("");
-
- if (strlen (text))
- {
- if (href)
- {
- text_printf (result, "<li><a href=\"%s\"%s>%s</a>",
- href, accesskey, text);
- }
- else
- text_printf (result, "<li>%s", text);
-
- text_append_n (result, "</li>\n", 6);
- }
- free (text);
- free (href);
- free (accesskey);
- }
- text_append_n (result, "</ul>\n", 6);
- }
-}
-
-void
-html_convert_heading_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const char *element_id;
- const OUTPUT_UNIT *output_unit = 0;
- TEXT element_header;
- TEXT toc_or_mini_toc_or_auto_menu;
- enum command_id level_corrected_cmd;
- int status;
- char *heading;
- int heading_level = -1;
- int do_heading;
- const char *heading_id = 0;
- char *level_set_class = 0;
-
- const ELEMENT *opening_section = 0;
- enum command_id level_corrected_opening_section_cmd = 0;
-
- enum command_id data_cmd = element_builtin_data_cmd (element);
- unsigned long flags = builtin_command_data[data_cmd].flags;
-
- /* No situation where this could happen */
- if (html_in_string (self))
- {
- if (element->e.c->cmd != CM_node)
- {
- char *heading = html_command_text (self, element, HTT_string);
- text_append (result, heading);
- text_append_n (result, "\n", 1);
- free (heading);
- }
- if (content)
- text_append (result, content);
- return;
- }
-
- element_id = html_command_id (self, element);
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- char *root_heading_texi = root_heading_command_to_texinfo (element);
- fprintf (stderr, "CONVERT elt heading %s\n", root_heading_texi);
- free (root_heading_texi);
- }
-
- /* All the root commands are associated to an output unit, the condition
- on associated_unit is always true. */
- if (flags & CF_root && element->e.c->associated_unit)
- output_unit = element->e.c->associated_unit;
-
- text_init (&element_header);
- text_append (&element_header, "");
- if (output_unit)
- format_element_header (self, element_command_name (element), element,
- output_unit, &element_header);
-
- text_init (&toc_or_mini_toc_or_auto_menu);
- text_append (&toc_or_mini_toc_or_auto_menu, "");
- if (element->e.c->cmd == CM_top
- && self->conf->CONTENTS_OUTPUT_LOCATION.o.string
- && !strcmp (self->conf->CONTENTS_OUTPUT_LOCATION.o.string, "after_top")
- && self->document->sections_list
- && self->document->sections_list->number > 1)
- {
- enum command_id contents_cmds[2] = {CM_shortcontents, CM_contents};
- int i;
- for (i = 0; i < 2; i++)
- {
- int contents_set = 0;
- enum command_id cmd = contents_cmds[i];
- const OPTION *contents_option_ref
- = get_command_option (self->conf, cmd);
- if (contents_option_ref->o.integer > 0)
- contents_set = 1;
- if (contents_set)
- {
- char *contents_text
- = contents_inline_element (self, cmd, 0);
- if (contents_text)
- {
- text_append (&toc_or_mini_toc_or_auto_menu, contents_text);
- free (contents_text);
- }
- }
- }
- }
-
- if (toc_or_mini_toc_or_auto_menu.end <= 0
- && (flags & CF_sectioning_heading)
- && self->conf->FORMAT_MENU.o.string)
- {
- if (!strcmp (self->conf->FORMAT_MENU.o.string, "sectiontoc"))
- {
- mini_toc_internal (self, element, &toc_or_mini_toc_or_auto_menu);
- }
- else if (!strcmp (self->conf->FORMAT_MENU.o.string, "menu"))
- {
- const ELEMENT *node
- = lookup_extra_element (element, AI_key_associated_node);
- if (node)
- {
- int automatic_directions = (node->e.c->args.number <= 1);
- const CONST_ELEMENT_LIST *menus = lookup_extra_contents (node,
- AI_key_menus);
- if (!menus && automatic_directions)
- {
- ELEMENT *menu_node
- = new_complete_menu_master_menu (&self->error_messages,
- self->conf, &self->document->identifiers_target,
node);
-
- if (menu_node)
- {
- add_tree_to_build (self, menu_node);
- convert_tree_append (self, menu_node,
- &toc_or_mini_toc_or_auto_menu,
- "master menu");
- remove_tree_to_build (self, menu_node);
- /* there are only new or copied elements in the menu */
- destroy_element_and_children (menu_node);
- }
- }
- }
- }
- }
-
- if (self->conf->NO_TOP_NODE_OUTPUT.o.integer > 0
- && builtin_command_data[cmd].flags & CF_root)
- {
- int in_skipped_node_top
- = self->shared_conversion_state.in_skipped_node_top;
-
- if (in_skipped_node_top == 1)
- {
- format_separate_anchor (self, element_id,
- builtin_command_name (cmd), result);
- text_append (result, element_header.text);
- free (element_header.text);
- text_append (result, toc_or_mini_toc_or_auto_menu.text);
- free (toc_or_mini_toc_or_auto_menu.text);
- return;
- }
- }
-
- lookup_extra_integer (element, AI_key_section_level, &status);
- level_corrected_cmd = cmd;
- if (status >= 0)
- {
- /* if the level was changed, use a consistent command name */
- level_corrected_cmd = section_level_adjusted_command_name (element);
- if (level_corrected_cmd != cmd)
- {
- xasprintf (&level_set_class, "%s-level-set-%s",
- builtin_command_name (cmd),
- builtin_command_name (level_corrected_cmd));
- }
- }
-
- /* find the section starting here, can be through the associated node
- preceding the section, or the section itself */
-
- if (cmd == CM_node)
- {
- opening_section
- = lookup_extra_element (element, AI_key_associated_section);
- if (opening_section)
- level_corrected_opening_section_cmd
- = section_level_adjusted_command_name (opening_section);
- }
- else
- {
- const ELEMENT *associated_node
- = lookup_extra_element (element, AI_key_associated_node);
-
- /* if there is an associated node, it is not a section opening
- the section was opened before when the node was encountered */
- if (!associated_node
- /* to avoid *heading* @-commands */
- && (builtin_command_data[cmd].flags & CF_root))
- {
- opening_section = element;
- level_corrected_opening_section_cmd = level_corrected_cmd;
- }
- }
-
- /*
- could use empty args information also, to avoid calling command_text
- my $empty_heading = (!scalar(@$args) or !defined($args->[0]));
- */
-
-
- /* heading not defined may happen if the command is a @node, for example
- if there is an error in the node. */
- heading = html_command_text (self, element, 0);
-
- /* node is used as heading if there is nothing else. */
- if (cmd == CM_node)
- {
- const ELEMENT *associated_section
- = lookup_extra_element (element, AI_key_associated_section);
- const char *normalized = lookup_extra_string (element,
AI_key_normalized);
- /* NOTE: if USE_NODES = 0 and there are no sectioning commands,
- output_unit->uc.unit_command is NUL (and not equal to elemen). */
- if (output_unit->uc.unit_command == element
- && !associated_section
- && normalized)
- {
- if (!strcmp (normalized, "Top"))
- heading_level = 0;
- else
- {
- int use_next_heading = 0;
- if (self->conf->USE_NEXT_HEADING_FOR_LONE_NODE.o.integer > 0)
- {
- const ELEMENT *next_heading
- = find_root_command_next_heading_command (element,
- self->expanded_formats,
- (self->conf->CONTENTS_OUTPUT_LOCATION.o.string
- && !strcmp (
- self->conf->CONTENTS_OUTPUT_LOCATION.o.string,
"inline")),
- 0);
- if (next_heading)
- use_next_heading = 1;
- }
- if (!use_next_heading)
- /* use node */
- heading_level = 3;
- }
- }
- }
- else
- {
- int status;
- int level = lookup_extra_integer (element, AI_key_section_level,
&status);
- if (status >= 0)
- {
- heading_level = level;
- }
- else
- {
- heading_level = section_level (element);
- }
- }
- do_heading = (heading && strlen (heading) && heading_level >= 0);
-
- /* if set, the id is associated to the heading text */
- if (opening_section)
- {
- char *class;
- STRING_LIST *classes;
- char *attribute_class;
- int status;
- int level
- = lookup_extra_integer (opening_section, AI_key_section_level,
&status);
- STRING_LIST *closed_strings;
-
- /* if Structuring sectioning_structure was not called on the
- document (cannot happen in main program or test_utils.pl tests) */
- /* if (status < 0) */
- if (status != 0)
- level = section_level (opening_section);
-
- closed_strings = html_close_registered_sections_level (self,
- self->current_filename.file_number, level);
-
- if (closed_strings->number)
- {
- size_t i;
- for (i = 0; i < closed_strings->number; i++)
- {
- text_append (result, closed_strings->list[i]);
- free (closed_strings->list[i]);
- }
- }
- free (closed_strings->list);
- free (closed_strings);
-
- html_register_opened_section_level (self,
- self->current_filename.file_number, level, "</div>\n");
-
- /* use a specific class name to mark that this is the start of
- the section extent. It is not necessary where the section is. */
-
- classes = new_string_list ();
-
- xasprintf (&class, "%s-level-extent",
- builtin_command_name (level_corrected_opening_section_cmd));
-
- add_string (class, classes);
- free (class);
- attribute_class = html_attribute_class (self, "div", classes);
- destroy_strings_list (classes);
-
- text_append (result, attribute_class);
- free (attribute_class);
-
- if (element_id && strlen (element_id))
- text_printf (result, " id=\"%s\"", element_id);
- text_append (result, ">\n");
- }
- else if (element_id && strlen (element_id))
- {
- if (element_header.end > 0)
- {
- /* case of a @node without sectioning command and with a header.
- put the node element anchor before the header.
- Set the class name to the command name if there is no heading,
- else the class will be with the heading element. */
-
- char *id_class = 0;
- if (do_heading)
- {
- xasprintf (&id_class, "%s-id", builtin_command_name (cmd));
- }
- else
- id_class = strdup (builtin_command_name (cmd));
-
- format_separate_anchor (self, element_id, id_class, result);
-
- free (id_class);
- }
- else
- heading_id = element_id;
- }
-
- text_append (result, element_header.text);
- free (element_header.text);
-
- if (do_heading)
- {
- STRING_LIST *heading_classes;
- if (self->conf->TOC_LINKS.o.integer > 0
- && (builtin_command_data[cmd].flags & CF_root)
- && (builtin_command_data[cmd].flags & CF_sectioning_heading))
- {
- char *content_href = html_command_contents_href (self, element,
- CM_contents, 0);
- if (content_href)
- {
- char *heading_tmp = strdup (heading);
- free (heading);
- xasprintf (&heading, "<a href=\"%s\">%s</a>",
- content_href, heading_tmp);
- free (heading_tmp);
- free (content_href);
- }
- }
-
- heading_classes = new_string_list ();
- add_string (builtin_command_name (level_corrected_cmd), heading_classes);
- if (level_set_class)
- add_string (level_set_class, heading_classes);
- if (html_in_preformatted_context (self))
- {
- char *attribute_class;
- char *id_str = 0;
- if (heading_id)
- {
- xasprintf (&id_str, " id=\"%s\"", heading_id);
- }
- else
- id_str = strdup ("");
-
- attribute_class = html_attribute_class (self, "strong",
- heading_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_printf (result, "%s>%s</strong>\n", id_str, heading);
-
- free (id_str);
- }
- else
- {
- format_heading_text (self, level_corrected_cmd,
- heading_classes, heading,
- heading_level
- + self->conf->CHAPTER_HEADER_LEVEL.o.integer -1,
- heading_id, element, element_id, result);
- }
- destroy_strings_list (heading_classes);
- }
- else if (heading_id)
- {
- /* case of a lone node and no header, and case of an empty @top */
- format_separate_anchor (self, heading_id, builtin_command_name (cmd),
- result);
- }
-
- free (heading);
- free (level_set_class);
-
- if (content)
- text_append (result, content);
-
- text_append (result, toc_or_mini_toc_or_auto_menu.text);
- free (toc_or_mini_toc_or_auto_menu.text);
-}
-
-void
-html_convert_inline_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const char *format;
- size_t arg_index = 0;
-
- if (args_formatted && args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_monospacetext]
- && strlen (args_formatted->args[0].formatted[AFT_type_monospacetext]))
- format = args_formatted->args[0].formatted[AFT_type_monospacetext];
- else
- return;
-
- if (command_other_flags (element) & CF_inline_format)
- {
- if (cmd == CM_inlinefmtifelse
- && !format_expanded_p (self->expanded_formats, format))
- arg_index = 2;
- else if (format_expanded_p (self->expanded_formats, format))
- arg_index = 1;
- }
- else
- {
- int status;
- int expand_index = lookup_extra_integer (element, AI_key_expand_index,
- &status);
- if (expand_index > 0)
- arg_index = 1;
- }
- if (arg_index > 0 && arg_index < args_formatted->number)
- {
- if (args_formatted->args[arg_index].formatted[AFT_type_normal])
- {
- text_append (result,
- args_formatted->args[arg_index].formatted[AFT_type_normal]);
- }
- else if (args_formatted->args[arg_index].formatted[AFT_type_raw])
- text_append (result,
- args_formatted->args[arg_index].formatted[AFT_type_raw]);
- }
-}
-
-void
-html_convert_xref_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *name = 0;
- HTML_ARG_FORMATTED *file_arg = 0;
- char *file = 0;
- const char *book = 0;
- const ELEMENT *arg_node = 0;
- const ELEMENT *target_node = 0;
- ELEMENT *tree = 0;
-
- ELEMENT *book_element = 0;
- ELEMENT *reference_element = 0;
-
- /* happens with bogus @-commands without argument, maybe only
- at the end of a document */
- if (!args_formatted)
- return;
-
- if (cmd != CM_link && cmd != CM_inforef && args_formatted->number > 2
- && args_formatted->args[2].formatted[AFT_type_normal]
- && strlen (args_formatted->args[2].formatted[AFT_type_normal]))
- {
- name = strdup (args_formatted->args[2].formatted[AFT_type_normal]);
- }
- else if (args_formatted->number > 1
- && args_formatted->args[1].formatted[AFT_type_normal]
- && strlen (args_formatted->args[1].formatted[AFT_type_normal]))
- {
- name = strdup (args_formatted->args[1].formatted[AFT_type_normal]);
- }
-
- if (cmd == CM_link || cmd == CM_inforef)
- {
- if (args_formatted->number > 2)
- file_arg = &args_formatted->args[2];
- }
- else if (args_formatted->number > 3)
- file_arg = &args_formatted->args[3];
-
- if (file_arg && file_arg->formatted[AFT_type_filenametext]
- && strlen (file_arg->formatted[AFT_type_filenametext]))
- {
- file = strdup (file_arg->formatted[AFT_type_filenametext]);
- }
-
- if (args_formatted->number > 4
- && args_formatted->args[4].formatted[AFT_type_normal]
- && strlen (args_formatted->args[4].formatted[AFT_type_normal]))
- book = args_formatted->args[4].formatted[AFT_type_normal];
-
- if (element->e.c->args.number > 0)
- arg_node = element->e.c->args.list[0];
-
- /* check for internal reference */
- if (cmd != CM_inforef && !book && !file && arg_node)
- {
- const char *normalized = lookup_extra_string (arg_node,
AI_key_normalized);
- const ELEMENT *manual_content = lookup_extra_container (arg_node,
- AI_key_manual_content);
- if (normalized && !manual_content)
- {
- target_node = find_identifier_target (
- &self->document->identifiers_target,
- normalized);
- }
- }
-
- /* internal reference */
- if (target_node)
- {
- char *href = 0;
- STRING_LIST *classes = 0;
- /* This is the node if USE_NODES, otherwise this may be the sectioning
- command (if the sectioning command is really associated to the node) */
- const ELEMENT *target_root
- = html_command_root_element_command (self, target_node);
- const ELEMENT *associated_section = lookup_extra_element (target_node,
- AI_key_associated_section);
- reference_element = new_text_element (ET__converted);
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
-
- if (!associated_section || associated_section != target_root)
- target_root = target_node;
-
- if (!html_in_string (self))
- href = html_command_href (self, target_root, 0, element, 0);
-
- if (!name)
- {
- if (self->conf->xrefautomaticsectiontitle.o.string
- && !strcmp (self->conf->xrefautomaticsectiontitle.o.string, "on")
- && associated_section
- /* this condition avoids infinite recursions, indeed in that case
- the node will be used and not the section. There should not be
- @*ref in nodes, and even if there are, it does not seems to be
- possible to construct an infinite recursion with nodes only
- as the node must both be a reference target and refer to a specific
- target at the same time, which is not possible.
- */
- && !command_is_in_referred_command_stack (
- &self->referred_command_stack, associated_section, 0))
- {
- target_root = associated_section;
- if (html_in_string (self))
- name = html_command_text (self, target_root, HTT_string);
- else
- name = html_command_text (self, target_root,
HTT_text_nonumber);
- }
- else if (target_node->e.c->cmd == CM_float)
- {
- if (self->conf->XREF_USE_FLOAT_LABEL.o.integer <= 0)
- {
- if (html_in_string (self))
- name = html_command_text (self, target_root, HTT_string);
- else
- name = html_command_text (self, target_root, 0);
- }
- if (!name || !strlen (name))
- {
- if (args_formatted->number > 1
- && args_formatted->args[0].formatted[AFT_type_monospace])
- {
- name
- = strdup (
-
args_formatted->args[0].formatted[AFT_type_monospace]);
- }
- else
- name = strdup ("");
- }
- }
- else if (self->conf->XREF_USE_NODE_NAME_ARG.o.integer <= 0
- && (self->conf->XREF_USE_NODE_NAME_ARG.o.integer == 0
- || !html_in_preformatted_context (self))
- /* this condition avoids infinite recursions, example with
- USE_NODES=0 and node referring to the section and section referring
- to the node */
- && !command_is_in_referred_command_stack (
- &self->referred_command_stack, target_root, 0))
- {
- if (html_in_string (self))
- name = html_command_text (self, target_root, HTT_string);
- else
- name = html_command_text (self, target_root,
HTT_text_nonumber);
- }
- else if (args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_monospace])
- {
- name
- = strdup
(args_formatted->args[0].formatted[AFT_type_monospace]);
- }
- else
- name = strdup ("");
- }
-
- if (href)
- {
- char *attribute_class;
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "a", classes);
- text_append (reference_element->e.text, attribute_class);
- text_printf (reference_element->e.text, " href=\"%s\">%s</a>",
- href, name);
- free (attribute_class);
- destroy_strings_list (classes);
- }
- else
- {
- text_append (reference_element->e.text, name);
- }
- free (href);
-
- add_element_to_named_string_element_list (substrings,
- "reference_name", reference_element);
- if (cmd == CM_pxref)
- {
- tree = html_cdt_tree ("see {reference_name}",
- self, substrings, 0);
- }
- else if (cmd == CM_xref)
- {
- tree = html_cdt_tree ("See {reference_name}",
- self, substrings, 0);
- }
- else if (cmd == CM_ref || cmd == CM_link)
- {
- tree = html_cdt_tree ("{reference_name}",
- self, substrings, 0);
- }
- destroy_named_string_element_list (substrings);
- }
- else
- {
- /* external reference */
- char *href = 0;
- char *reference = 0;
- char *book_reference = 0;
-
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
-
- /* We setup a label_element based on the node argument and not directly the
- node argument to be able to use the $file argument */
-
- ELEMENT *label_element = 0;
- ELEMENT *manual_content = 0;
- ELEMENT *node_content = 0;
-
- if (arg_node)
- {
- node_content = lookup_extra_container (arg_node,
AI_key_node_content);
- if (node_content)
- {
- const char *normalized = lookup_extra_string (arg_node,
- AI_key_normalized);
- label_element = new_element (ET_NONE);
- add_extra_container (label_element, AI_key_node_content,
- copy_container_contents (node_content));
- if (normalized)
- add_extra_string_dup (label_element, AI_key_normalized,
- normalized);
- }
- }
-
- /* file argument takes precedence over the file in the node (file)node entry
*/
- if (file)
- {
- if (!label_element)
- label_element = new_element (ET_NONE);
- add_extra_container (label_element, AI_key_manual_content,
- copy_container_contents (file_arg->arg_tree));
- }
- else
- {
- manual_content = lookup_extra_container (arg_node,
- AI_key_manual_content);
- }
-
- if (manual_content)
- {
- ELEMENT *root_code;
-
- if (!label_element)
- label_element = new_element (ET_NONE);
-
- add_extra_container (label_element, AI_key_manual_content,
- copy_container_contents (manual_content));
-
- /* convert the manual part to file string */
- root_code = new_element (ET__code);
-
- add_to_contents_as_array (root_code, manual_content);
-
- add_tree_to_build (self, root_code);
- file = html_convert_tree (self, root_code, "node file in ref");
- remove_tree_to_build (self, root_code);
- destroy_element (root_code);
- }
-
- if (!name)
- {
- if (book)
- {
- if (node_content)
- {
- char *node_name;
- ELEMENT *node_no_file_tree = new_element (ET__code);
- add_to_contents_as_array (node_no_file_tree, node_content);
-
- add_tree_to_build (self, node_no_file_tree);
- node_name = html_convert_tree (self, node_no_file_tree,
- "node in ref");
- remove_tree_to_build (self, node_no_file_tree);
- destroy_element (node_no_file_tree);
-
- if (node_name && strcmp (node_name, "Top"))
- name = node_name;
- else
- free (node_name);
- }
- }
- else
- {
- if (label_element)
- name = html_command_text (self, label_element, 0);
- if (!name && args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_monospace]
- && strcmp
(args_formatted->args[0].formatted[AFT_type_monospace],
- "Top"))
- name
- = strdup
(args_formatted->args[0].formatted[AFT_type_monospace]);
- }
- }
-
- if (label_element)
- {
- if (!html_in_string (self))
- href = html_command_href (self, label_element, 0, element, 0);
- destroy_element (label_element);
- }
-
- if (href)
- {
- /* attribute to distiguish links to Texinfo manuals from other links
- and to provide manual name of target */
- TEXT manual_name_attribute;
- text_init (&manual_name_attribute);
- text_append (&manual_name_attribute, "");
- if (file && self->conf->NO_CUSTOM_HTML_ATTRIBUTE.o.integer <= 0)
- {
- text_append_n (&manual_name_attribute, "data-manual=\"", 13);
- format_protect_text (self, file, &manual_name_attribute);
- text_append_n (&manual_name_attribute, "\" ", 2);
- }
- if (name)
- {
- xasprintf (&reference, "<a %shref=\"%s\">%s</a>",
- manual_name_attribute.text, href, name);
- }
- else if (book)
- {
- xasprintf (&book_reference, "<a %shref=\"%s\">%s</a>",
- manual_name_attribute.text, href, book);
- }
- free (manual_name_attribute.text);
- free (href);
- }
-
-
- if (book && reference)
- {
- book_element = new_text_element (ET__converted);
- text_append (book_element->e.text, book);
- reference_element = new_text_element (ET__converted);
- text_append (reference_element->e.text, reference);
-
- add_element_to_named_string_element_list (substrings,
- "book", book_element);
- add_element_to_named_string_element_list (substrings,
- "reference", reference_element);
- if (cmd == CM_pxref)
- {
- tree = html_cdt_tree ("see {reference} in @cite{{book}}",
- self, substrings, 0);
- }
- else if (cmd == CM_xref)
- {
- tree = html_cdt_tree ("See {reference} in @cite{{book}}",
- self, substrings, 0);
- }
- else /* @ref */
- {
- tree = html_cdt_tree ("{reference} in @cite{{book}}",
- self, substrings, 0);
- }
- }
- else if (book_reference)
- {
- book_element = new_text_element (ET__converted);
- text_append (book_element->e.text, book_reference);
-
- add_element_to_named_string_element_list (substrings,
- "book_reference", book_element);
- if (cmd == CM_pxref)
- {
- tree = html_cdt_tree ("see @cite{{book_reference}}",
- self, substrings, 0);
- }
- else if (cmd == CM_xref || cmd == CM_inforef)
- {
- tree = html_cdt_tree ("See @cite{{book_reference}}",
- self, substrings, 0);
- }
- else /* @ref */
- {
- tree = html_cdt_tree ("@cite{{book_reference}}",
- self, substrings, 0);
- }
- }
- else if (book && name)
- {
- book_element = new_text_element (ET__converted);
- text_append (book_element->e.text, book);
- reference_element = new_text_element (ET__converted);
- text_append (reference_element->e.text, name);
-
- add_element_to_named_string_element_list (substrings,
- "book", book_element);
- add_element_to_named_string_element_list (substrings,
- "section", reference_element);
- if (cmd == CM_pxref)
- {
- tree = html_cdt_tree ("see `{section}' in @cite{{book}}",
- self, substrings, 0);
- }
- else if (cmd == CM_xref || cmd == CM_inforef)
- {
- tree = html_cdt_tree ("See `{section}' in @cite{{book}}",
- self, substrings, 0);
- }
- else /* @ref */
- {
- tree = html_cdt_tree ("`{section}' in @cite{{book}}",
- self, substrings, 0);
- }
- }
- else if (book)
- {
- book_element = new_text_element (ET__converted);
- text_append (book_element->e.text, book);
-
- add_element_to_named_string_element_list (substrings,
- "book", book_element);
- if (cmd == CM_pxref)
- {
- tree = html_cdt_tree ("see @cite{{book}}",
- self, substrings, 0);
- }
- else if (cmd == CM_xref || cmd == CM_inforef)
- {
- tree = html_cdt_tree ("See @cite{{book}}",
- self, substrings, 0);
- }
- else /* @ref */
- {
- tree = html_cdt_tree ("@cite{{book}}",
- self, substrings, 0);
- }
- }
- else if (reference)
- {
- reference_element = new_text_element (ET__converted);
- text_append (reference_element->e.text, reference);
-
- add_element_to_named_string_element_list (substrings,
- "reference", reference_element);
- if (cmd == CM_pxref)
- {
- tree = html_cdt_tree ("see {reference}",
- self, substrings, 0);
- }
- else if (cmd == CM_xref || cmd == CM_inforef)
- {
- tree = html_cdt_tree ("See {reference}",
- self, substrings, 0);
- }
- else /* @ref */
- {
- tree = html_cdt_tree ("{reference}",
- self, substrings, 0);
- }
- }
- else if (name)
- {
- reference_element = new_text_element (ET__converted);
- text_append (reference_element->e.text, name);
-
- add_element_to_named_string_element_list (substrings,
- "section", reference_element);
- if (cmd == CM_pxref)
- {
- tree = html_cdt_tree ("see `{section}'",
- self, substrings, 0);
- }
- else if (cmd == CM_xref || cmd == CM_inforef)
- {
- tree = html_cdt_tree ("See `{section}'",
- self, substrings, 0);
- }
- else /* @ref */
- {
- tree = html_cdt_tree ("`{section}'",
- self, substrings, 0);
- }
- }
- free (reference);
- free (book_reference);
- destroy_named_string_element_list (substrings);
- }
-
- if (tree)
- {
- char *context_str;
- xasprintf (&context_str, "convert xref %s", builtin_command_name (cmd));
- add_tree_to_build (self, tree);
- convert_tree_append (self, tree, result, context_str);
- remove_tree_to_build (self, tree);
- free (context_str);
- /* should destroy reference_element and book_element */
- destroy_element_and_children (tree);
- }
-
- free (file);
- free (name);
-}
-
-void
-html_convert_raw_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (cmd == CM_html)
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- if (!self->multiple_conversions)
- {
- message_list_command_warn (&self->error_messages, self->conf,
- element, 0, "raw format %s is not converted",
- element_command_name (element));
- }
- format_protect_text (self, content, result);
-}
-
-/* strings in extra_classes strings are transferred and later on
- free'd, but not extra_classes themselves */
-static void
-indent_with_table (CONVERTER *self, const enum command_id cmd,
- const char *content, const STRING_LIST *extra_classes,
- TEXT *result)
-{
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- if (extra_classes)
- merge_strings (classes, extra_classes);
-
- attribute_class = html_attribute_class (self, "table", classes);
- text_append (result, attribute_class);
- text_append_n (result, "><tr><td>", 9);
- text_append_n (result,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- text_append_n (result, "</td><td>", 9);
- text_append (result, content);
- text_append_n (result, "</td></tr></table>\n", 19);
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-html_convert_preformatted_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- STRING_LIST *additional_classes;
- enum command_id main_cmd = 0;
-
- if (!content || !strlen (content))
- return;
-
- if (html_in_string (self))
- {
- text_append (result, content);
- return;
- }
-
- additional_classes = new_string_list ();
-
- if (html_commands_data[cmd].flags & HF_small_block_command)
- {
- int i;
- for (i = 0; small_block_associated_command[i][0]; i++)
- {
- enum command_id small_cmd = small_block_associated_command[i][0];
- if (small_cmd == cmd)
- {
- main_cmd = small_block_associated_command[i][1];
- add_string (builtin_command_name (cmd), additional_classes);
- break;
- }
- }
- }
- else
- main_cmd = cmd;
-
- if (cmd == CM_example)
- {
- if (element->e.c->args.number > 0)
- {
- size_t i;
- for (i = 0; i < element->e.c->args.number; i++)
- {
- const ELEMENT *example_arg = element->e.c->args.list[i];
- /* convert or remove all @-commands, using simple ascii and unicode
- characters */
- char *converted_arg = convert_to_normalized (example_arg);
- if (strlen (converted_arg))
- {
- char *class_name;
- xasprintf (&class_name, "user-%s", converted_arg);
- add_string (class_name, additional_classes);
- free (class_name);
- }
- free (converted_arg);
- }
- }
- }
- else if (main_cmd == CM_lisp)
- {
- add_string (builtin_command_name (main_cmd), additional_classes);
- main_cmd = CM_example;
- }
-
- if (self->conf->INDENTED_BLOCK_COMMANDS_IN_TABLE.o.integer > 0
- && html_commands_data[cmd].flags & HF_indented_preformatted)
- {
- indent_with_table (self, cmd, content,
- additional_classes, result);
- }
- else
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (main_cmd), classes);
- merge_strings (classes, additional_classes);
-
- attribute_class = html_attribute_class (self, "div", classes);
- text_append (result, attribute_class);
- text_printf (result, ">\n%s</div>\n", content);
- free (attribute_class);
- destroy_strings_list (classes);
- }
-
- free (additional_classes->list);
- free (additional_classes);
-}
-
-void
-html_convert_indented_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- enum command_id main_cmd = 0;
- STRING_LIST *additional_classes;
-
- if (!content || !strlen (content))
- return;
-
- if (html_in_string (self))
- {
- text_append (result, content);
- return;
- }
-
- additional_classes = new_string_list ();
-
- if (html_commands_data[cmd].flags & HF_small_block_command)
- {
- int i;
- for (i = 0; small_block_associated_command[i][0]; i++)
- {
- enum command_id small_cmd = small_block_associated_command[i][0];
- if (small_cmd == cmd)
- {
- main_cmd = small_block_associated_command[i][1];
- add_string (builtin_command_name (cmd), additional_classes);
- break;
- }
- }
- }
- else
- main_cmd = cmd;
-
- if (self->conf->INDENTED_BLOCK_COMMANDS_IN_TABLE.o.integer > 0)
- {
- indent_with_table (self, main_cmd, content,
- additional_classes, result);
- }
- else
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (main_cmd), classes);
- merge_strings (classes, additional_classes);
-
- attribute_class = html_attribute_class (self, "blockquote", classes);
- text_append (result, attribute_class);
- text_printf (result, ">\n%s</blockquote>\n", content);
- free (attribute_class);
- destroy_strings_list (classes);
- }
-
- free (additional_classes->list);
- free (additional_classes);
-}
-
-void
-html_convert_verbatim_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- }
- else
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "pre", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- if (content)
- text_append (result, content);
- text_append_n (result, "</pre>", 6);
- free (attribute_class);
- destroy_strings_list (classes);
- }
-}
-
-void
-html_convert_displaymath_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *attribute_class;
- STRING_LIST *classes;
- int use_mathjax;
-
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- use_mathjax = (self->conf->HTML_MATH.o.string
- && !strcmp (self->conf->HTML_MATH.o.string, "mathjax"));
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- if (use_mathjax)
- {
- html_register_file_information (self, "mathjax", 1);
- add_string ("tex2jax_process", classes);
- }
-
- attribute_class = html_attribute_class (self, "pre", classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">", 1);
-
- destroy_strings_list (classes);
-
- if (use_mathjax)
- text_printf (result, "\\[%s\\]", content);
- else
- text_printf (result, "%s", content);
-
- text_append_n (result, "</pre>", 6);
-}
-
-void
-html_convert_simple_block_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *attribute_class;
- STRING_LIST *classes;
-
- if (!content)
- return;
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "div", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- text_append (result, content);
- text_append_n (result, "</div>", 6);
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-html_convert_menu_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *attribute_class;
- STRING_LIST *classes;
-
- if (cmd == CM_detailmenu)
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- self->shared_conversion_state.html_menu_entry_index = 0;
-
- if (!content || content[strspn (content, whitespace_chars)] == '\0')
- return;
-
- if (html_in_string (self))
- {
- text_append (result, content);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "table", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- if (html_inside_preformatted (self))
- text_append_n (result, "<tr><td>", 8);
- text_append_n (result, "\n", 1);
- text_append (result, content);
- if (html_inside_preformatted (self))
- text_append_n (result, "</td></tr>", 10);
- text_append_n (result, "</table>\n", 9);
-
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-static char *type_number_float_array[] = {"type-number-float"};
-static const STRING_LIST type_number_float_classes
- = {type_number_float_array, 1, 1};
-
-void
-html_convert_float_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *attribute_class;
- STRING_LIST *classes;
-
- const char *id;
- char *prepended_text = 0;
- char *caption_text = 0;
- char *caption_command_name = 0;
-
- const ELEMENT *caption_element;
- ELEMENT *prepended;
- FLOAT_CAPTION_PREPENDED_ELEMENT *caption_prepended
- = float_name_caption (self, element);
-
- caption_element = caption_prepended->caption;
- prepended = caption_prepended->prepended;
-
- free (caption_prepended);
-
- if (html_in_string (self))
- {
- if (prepended)
- {
- char *prepended_text;
- add_tree_to_build (self, prepended);
- prepended_text
- = convert_tree_new_formatting_context (self, prepended,
- "float prepended", 0, 0, 0);
-
- remove_tree_to_build (self, prepended);
- destroy_element_and_children (prepended);
- if (prepended_text)
- {
- text_append (result, prepended_text);
- free (prepended_text);
- }
- }
- if (content)
- text_append (result, content);
-
- if (caption_element && caption_element->e.c->args.number > 0
- && caption_element->e.c->args.list[0]->e.c->contents.number > 0)
- {
- char *caption_text
- = convert_tree_new_formatting_context (self,
- caption_element->e.c->args.list[0], "float caption", 0, 0, 0);
- if (caption_text)
- {
- text_append (result, caption_text);
- free (caption_text);
- }
- }
- return;
- }
-
- if (caption_element)
- caption_command_name = builtin_command_name (caption_element->e.c->cmd);
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "div", classes);
- text_append (result, attribute_class);
- free (attribute_class);
- clear_strings_list (classes);
-
- id = html_command_id (self, element);
- if (id && strlen (id))
- text_printf (result, " id=\"%s\"", id);
-
- text_append_n (result, ">\n", 2);
- text_append (result, content);
-
- if (prepended)
- {
- ELEMENT *args = new_element (ET_brace_container);
- ELEMENT *strong_element
- = new_command_element (ET_brace_command, CM_strong);
-
- add_to_element_args (strong_element, args);
- add_to_element_contents (args, prepended);
-
- add_tree_to_build (self, strong_element);
- prepended_text = convert_tree_new_formatting_context (self,
- strong_element, "float number type", 0, 0, 0);
- remove_tree_to_build (self, strong_element);
-
- destroy_element_and_children (strong_element);
-
- if (caption_element)
- {
- char *cancelled_prepended;
- /* register the converted prepended tree to be prepended to
- the first paragraph in caption formatting */
- if (prepended_text)
- html_register_pending_formatted_inline_content (self,
- caption_command_name, prepended_text);
- caption_text = convert_tree_new_formatting_context (self,
- caption_element->e.c->args.list[0], "float caption",
- 0, 0, 0);
- if (prepended_text)
- {
- cancelled_prepended
- = html_cancel_pending_formatted_inline_content (self,
- caption_command_name);
- /* unset if prepended text is in caption, i.e. is not cancelled */
- if (!cancelled_prepended)
- {
- free (prepended_text);
- prepended_text = 0;
- }
- else
- free (cancelled_prepended);
- }
- }
- if (prepended_text && strlen (prepended_text))
- {
- /* prepended text is not empty and did not find its way in caption */
- char *tmp;
- xasprintf (&tmp, "<p>%s</p>", prepended_text);
- free (prepended_text);
- prepended_text = tmp;
- }
- }
- else if (caption_element)
- {
- caption_text = convert_tree_new_formatting_context (self,
- caption_element->e.c->args.list[0], "float caption",
- 0, 0, 0);
- }
-
- if (caption_text && strlen (caption_text))
- {
- add_string (caption_command_name, classes);
- attribute_class = html_attribute_class (self, "div", classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- text_append_n (result, ">", 1);
- text_append (result, caption_text);
- text_append_n (result, "</div>", 6);
- }
- else if (prepended_text && strlen (prepended_text))
- {
- attribute_class = html_attribute_class (self, "div",
- &type_number_float_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">", 1);
- text_append (result, prepended_text);
- text_append_n (result, "</div>", 6);
- }
-
- free (caption_text);
- free (prepended_text);
-
- text_append_n (result, "</div>", 6);
-
- destroy_strings_list (classes);
-}
-
-void
-html_convert_quotation_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const CONST_ELEMENT_LIST *authors;
-
- char *cancelled = html_cancel_pending_formatted_inline_content (self,
- builtin_command_name (cmd));
- if (cancelled)
- free (cancelled);
-
- if (!html_in_string (self))
- {
- char *attribute_class;
-
- STRING_LIST *classes = new_string_list ();
-
- if (html_commands_data[cmd].flags & HF_small_block_command)
- {
- int i;
- for (i = 0; small_block_associated_command[i][0]; i++)
- {
- enum command_id small_cmd = small_block_associated_command[i][0];
- if (small_cmd == cmd)
- {
- enum command_id main_cmd =
small_block_associated_command[i][1];
- add_string (builtin_command_name (main_cmd), classes);
- break;
- }
- }
- }
- add_string (builtin_command_name (cmd), classes);
- attribute_class = html_attribute_class (self, "blockquote", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">\n", 2);
- if (content)
- text_append (result, content);
- text_append_n (result, "</blockquote>\n", 14);
- }
- else
- {
- if (content)
- text_append (result, content);
- }
-
- authors = lookup_extra_contents (element, AI_key_authors);
- if (authors)
- {
- size_t i;
- for (i = 0; i < authors->number; i++)
- {
- const ELEMENT *author = authors->list[i];
- if (author->e.c->args.number > 0
- && author->e.c->args.list[0]->e.c->contents.number > 0)
- {
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
- ELEMENT *author_arg_copy = copy_tree (author->e.c->args.list[0]);
- add_element_to_named_string_element_list (substrings,
- "author", author_arg_copy);
-
- /* TRANSLATORS: quotation author */
- translate_convert_tree_append (
- "@center --- @emph{{author}}",
- self, substrings, 0, result,
- "convert quotation author");
- destroy_named_string_element_list (substrings);
- }
- }
- }
-}
-
-void
-html_convert_cartouche_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *attribute_class;
- STRING_LIST *classes;
- int do_title;
- int do_content;
-
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- do_title = (args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]));
- do_content = (content
- && content[strspn (content, whitespace_chars)] != '\0');
-
- if (!do_title && !do_content)
- return;
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "table", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- if (do_title)
- {
- text_append_n (result, "<tr><th>\n", 9);
- text_append (result,
- args_formatted->args[0].formatted[AFT_type_normal]);
- text_append_n (result, "</th></tr>", 10);
- }
- if (do_content)
- {
- text_append_n (result, "<tr><td>\n", 9);
- text_append (result, content);
- text_append_n (result, "</td></tr>", 10);
- }
- text_append_n (result, "</table>\n", 9);
-
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-default_css_string_format_protect_text (const char *text, TEXT *result)
-{
- const char *p = text;
-
- while (*p)
- {
- int before_sep_nr = strcspn (p, "\\'");
- if (before_sep_nr)
- {
- text_append_n (result, p, before_sep_nr);
- p += before_sep_nr;
- }
- if (!*p)
- break;
- switch (*p)
- {
- case '\\':
- text_append_n (result, "\\\\", 2);
- break;
- case '\'':
- text_append_n (result, "\\'", 2);
- break;
- }
- p++;
- }
-}
-
-/* NOTE these switches are not done in perl, so the only perl functions
- that can be called are perl functions that do not call formatting/conversion
- functions or the formatting/conversion functions for HTML will be used. */
-char *
-html_convert_css_string (CONVERTER *self, const ELEMENT *element,
- const char *context_str)
-{
- char *css_string_context_str;
- char *context_string_str;
- char *explanation;
- char *result;
-
- void (* saved_current_format_protect_text) (const char *text, TEXT *result);
- FORMATTING_REFERENCE *saved_formatting_references
- = self->current_formatting_references;
- COMMAND_CONVERSION_FUNCTION *saved_commands_conversion_function
- = self->current_commands_conversion_function;
- TYPE_CONVERSION_FUNCTION *saved_types_conversion_function
- = self->current_types_conversion_function;
- saved_current_format_protect_text = self->current_format_protect_text;
-
- self->current_formatting_references
- = &self->css_string_formatting_references[0];
- self->current_commands_conversion_function
- = &self->css_string_command_conversion_function[0];
- self->current_types_conversion_function
- = &self->css_string_type_conversion_function[0];
- self->current_format_protect_text = &default_css_string_format_protect_text;
-
- if (context_str)
- xasprintf (&css_string_context_str, "CSS string %s");
- else
- css_string_context_str = "CSS string ";
-
- xasprintf (&context_string_str, "C(%s)", css_string_context_str);
- xasprintf (&explanation, "new_fmt_ctx %s", context_string_str);
-
- html_new_document_context (self, css_string_context_str, 0, 0);
- html_set_string_context (self);
-
- result = html_convert_tree (self, element, explanation);
-
- html_pop_document_context (self);
-
- free (explanation);
- free (context_string_str);
- if (context_str)
- free (css_string_context_str);
-
- self->current_formatting_references = saved_formatting_references;
- self->current_commands_conversion_function
- = saved_commands_conversion_function;
- self->current_types_conversion_function = saved_types_conversion_function;
- self->current_format_protect_text = saved_current_format_protect_text;
-
- return result;
-}
-
-SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD
- special_list_mark_css_string_no_arg_command[] = {
- {CM_minus, "\\2212 ", 0},
- {0, 0, 0},
-};
-
-char *
-html_convert_css_string_for_list_mark (CONVERTER *self, const ELEMENT *element,
- const char *explanation)
-{
- char *result;
- int i;
- for (i = 0; special_list_mark_css_string_no_arg_command[i].cmd > 0; i++)
- {
- enum command_id cmd = special_list_mark_css_string_no_arg_command[i].cmd;
- special_list_mark_css_string_no_arg_command[i].saved
- = self->html_no_arg_command_conversion[cmd][HCC_type_css_string].text;
- self->html_no_arg_command_conversion[cmd][HCC_type_css_string].text
- = special_list_mark_css_string_no_arg_command[i].string;
- }
-
- result = html_convert_css_string (self, element, explanation);
-
- for (i = 0; special_list_mark_css_string_no_arg_command[i].cmd > 0; i++)
- {
- enum command_id cmd = special_list_mark_css_string_no_arg_command[i].cmd;
- self->html_no_arg_command_conversion[cmd][HCC_type_css_string].text
- = special_list_mark_css_string_no_arg_command[i].saved;
- special_list_mark_css_string_no_arg_command[i].saved = 0;
- }
-
- return result;
-}
-
-void
-html_convert_itemize_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const ELEMENT *command_as_argument;
- const char *command_as_argument_name = 0;
- const char *mark_class_name = 0;
- STRING_LIST *classes;
- char *attribute_class;
- const CSS_SELECTOR_STYLE *selector_style = 0;
-
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- command_as_argument = lookup_extra_element (element,
- AI_key_command_as_argument);
- if (command_as_argument)
- {
- if (command_as_argument->e.c->cmd == CM_click)
- {
- command_as_argument_name = lookup_extra_string (command_as_argument,
- AI_key_clickstyle);
- }
- if (!command_as_argument_name)
- command_as_argument_name = element_command_name (command_as_argument);
-
- if (!strcmp (command_as_argument_name, "w"))
- mark_class_name = "none";
- else
- mark_class_name = command_as_argument_name;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- if (mark_class_name)
- {
- char *mark_class;
- char *ul_mark_selector;
- xasprintf (&mark_class, "mark-%s", mark_class_name);
- xasprintf (&ul_mark_selector, "ul.%s", mark_class);
-
- selector_style = find_css_selector_style
(&self->css_element_class_styles,
- ul_mark_selector);
- free (ul_mark_selector);
- if (selector_style && selector_style->style)
- {
- add_string (mark_class, classes);
- }
- free (mark_class);
- }
-
- attribute_class = html_attribute_class (self, "ul", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- if (!selector_style && self->conf->NO_CSS.o.integer <= 0)
- {
- char *css_string
- = html_convert_css_string_for_list_mark (self,
element->e.c->args.list[0],
- "itemize arg");
- if (css_string && strlen (css_string))
- {
- text_append (result, " style=\"list-style-type: '");
- format_protect_text (self, css_string, result);
- text_append_n (result, "'\"", 2);
- }
- free (css_string);
- }
-
- text_append_n (result, ">\n", 2);
- if (content)
- text_append (result, content);
- text_append_n (result, "</ul>\n", 6);
-}
-
-void
-html_convert_enumerate_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- STRING_LIST *classes;
- char *attribute_class;
- const char *specification;
-
- if (!content || !strlen (content))
- return;
-
- if (html_in_string (self))
- {
- text_append (result, content);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "ol", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
-
- specification = lookup_extra_string (element,
- AI_key_enumerate_specification);
-
- if (specification)
- {
- int use_start = 1;
- unsigned int start = 0;
- const char *type = 0;
- size_t specification_len = strlen (specification);
- if (specification_len == 1 && isascii_alpha (*specification))
- {
- if (isascii_lower (*specification))
- {
- start = 1 + (*specification - 'a');
- type = "a";
- }
- else
- {
- start = 1 + (*specification - 'A');
- type = "A";
- }
- }
- else
- {
- use_start = 0;
- if (specification_len > 0)
- {
- const char *p = specification;
- int only_digits = 1;
- while (*p)
- {
- if (!isascii_digit (*p))
- {
- only_digits = 0;
- break;
- }
- p++;
- }
- if (only_digits)
- {
- unsigned int spec_number = strtoul (specification, NULL, 10);
- if (spec_number != 1)
- {
- use_start = 1;
- start = spec_number;
- }
- }
- }
- }
- if (type)
- text_printf (result, " type=\"%s\"", type);
- if (use_start)
- text_printf (result, " start=\"%u\"", start);
- }
-
- text_append_n (result, ">\n", 2);
- text_append (result, content);
- text_append_n (result, "</ol>\n", 6);
-}
-
-void
-html_convert_multitable_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- STRING_LIST *classes;
- char *attribute_class;
-
- if (!content || !strlen (content))
- return;
-
- if (html_in_string (self))
- {
- text_append (result, content);
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "table", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">\n", 2);
- text_append (result, content);
- text_append_n (result, "</table>\n", 9);
-}
-
-void
-html_convert_xtable_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- STRING_LIST *classes;
- char *attribute_class;
-
- if (!content || !strlen (content))
- return;
-
- if (html_in_string (self))
- {
- text_append (result, content);
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "dl", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">\n", 2);
- text_append (result, content);
- text_append_n (result, "</dl>\n", 6);
-}
-
-void
-html_convert_verbatiminclude_command (CONVERTER *self,
- const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- ELEMENT *verbatim_include_verbatim
- = expand_verbatiminclude (&self->error_messages, self->conf,
- &self->document->global_info, element);
-
- if (verbatim_include_verbatim)
- {
- add_tree_to_build (self, verbatim_include_verbatim);
- convert_tree_append (self, verbatim_include_verbatim,
- result, "convert verbatiminclude");
- remove_tree_to_build (self, verbatim_include_verbatim);
- destroy_element_and_children (verbatim_include_verbatim);
- }
-}
-
-void
-html_convert_sp_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const STRING_LIST *misc_args = lookup_extra_misc_args (element,
- AI_key_misc_args);
- unsigned int sp_nr = 1;
- unsigned int i;
-
- if (misc_args && misc_args->number > 0)
- {
- const char *sp_number_string = misc_args->list[0];
- sp_nr = strtoul (sp_number_string, NULL, 10);
- }
-
- if (html_in_preformatted_context (self) || html_in_string (self))
- {
- for (i = 0; i < sp_nr; i++)
- text_append_n (result, "\n", 1);
- }
- else
- {
- for (i = 0; i < sp_nr; i++)
- {
- text_append_n (result, self->line_break_element.string,
- self->line_break_element.len);
- text_append_n (result, "\n", 1);
- }
- }
-}
-
-void
-html_convert_exdent_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *pending_formatted = html_get_pending_formatted_inline_content (self);
- const char *arg = 0;
- char *attribute_class;
- STRING_LIST *classes;
-
- /* args_formatted null does not seems to be possible in practice */
- if (args_formatted && args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]))
- arg = args_formatted->args[0].formatted[AFT_type_normal];
-
- if (html_in_string (self))
- {
- if (pending_formatted)
- {
- text_append (result, pending_formatted);
- free (pending_formatted);
- }
- if (arg)
- text_append (result, arg);
- text_append_n (result, "\n", 1);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- if (html_in_preformatted_context (self))
- attribute_class = html_attribute_class (self, "pre", classes);
- else
- attribute_class = html_attribute_class (self, "p", classes);
-
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- if (pending_formatted)
- {
- text_append (result, pending_formatted);
- free (pending_formatted);
- }
- if (arg)
- text_append (result, arg);
- text_append_n (result, "\n", 1);
- if (html_in_preformatted_context (self))
- text_append_n (result, "</pre>", 6);
- else
- text_append_n (result, "</p>", 4);
-
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-html_convert_center_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *arg = 0;
- char *attribute_class;
- STRING_LIST *classes;
-
- /* args_formatted null does not seems to be possible in practice */
- if (args_formatted && args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]))
- arg = args_formatted->args[0].formatted[AFT_type_normal];
- else
- return;
-
- if (html_in_string (self))
- {
- text_append (result, arg);
- text_append_n (result, "\n", 1);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "div", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- text_append (result, arg);
- text_append_n (result, "\n", 1);
- text_append_n (result, "</div>", 6);
-
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-html_convert_author_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const char *arg = 0;
- char *attribute_class;
- STRING_LIST *classes;
-
- const ELEMENT *titlepage = lookup_extra_element (element, AI_key_titlepage);
-
- if (!titlepage)
- return;
-
- if (args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]))
- arg = args_formatted->args[0].formatted[AFT_type_normal];
- else
- return;
-
- if (html_in_string (self))
- {
- text_append (result, arg);
- text_append_n (result, "\n", 1);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "strong", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- text_append (result, arg);
- text_append_n (result, "</strong>", 9);
- text_append_n (result, self->line_break_element.string,
- self->line_break_element.len);
- text_append_n (result, "\n", 1);
-
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-html_convert_title_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const char *arg = 0;
- char *attribute_class;
- STRING_LIST *classes;
-
- if (args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]))
- arg = args_formatted->args[0].formatted[AFT_type_normal];
- else
- return;
-
- if (html_in_string (self))
- {
- text_append (result, arg);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "h1", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- text_append (result, arg);
- text_append_n (result, "</h1>", 5);
- text_append_n (result, "\n", 1);
-
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-void
-html_convert_subtitle_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const char *arg = 0;
- char *attribute_class;
- STRING_LIST *classes;
-
- if (args_formatted->number > 0
- && args_formatted->args[0].formatted[AFT_type_normal]
- && strlen (args_formatted->args[0].formatted[AFT_type_normal]))
- arg = args_formatted->args[0].formatted[AFT_type_normal];
- else
- return;
-
- if (html_in_string (self))
- {
- text_append (result, arg);
- return;
- }
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "h3", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- text_append (result, arg);
- text_append_n (result, "</h3>", 5);
- text_append_n (result, "\n", 1);
-
- free (attribute_class);
- destroy_strings_list (classes);
-}
-
-static char *table_term_preformatted_code_array[]
- = {"table-term-preformatted-code"};
-static const STRING_LIST table_term_preformatted_code_classes
- = {table_term_preformatted_code_array, 1, 1};
-
-void
-html_convert_item_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- if (element->parent && element_builtin_cmd (element->parent) == CM_itemize)
- {
- if (content
- && content[strspn (content, whitespace_chars)] != '\0')
- {
- text_printf (result, "<li>%s</li>", content);
- }
- }
- else if (element->parent
- && element_builtin_cmd (element->parent) == CM_enumerate)
- {
- if (content
- && content[strspn (content, whitespace_chars)] != '\0')
- {
- text_printf (result, "<li> %s</li>", content);
- }
- }
- else if (element->parent && element->parent->type == ET_table_term)
- {
- if (element->e.c->args.number > 0
- && element->e.c->args.list[0]->e.c->contents.number > 0)
- {
- ELEMENT *converted_e;
- TREE_ADDED_ELEMENTS *tree;
- char *anchor = 0;
- const char *index_entry_id;
- const char *pre_class_close = 0;
-
- if (cmd != CM_item)
- text_append_n (result, "<dt>", 4);
-
- index_entry_id = html_command_id (self, element);
-
- if (index_entry_id)
- {
- text_printf (result, "<a id=\"%s\"></a>", index_entry_id);
- anchor = get_copiable_anchor (self, index_entry_id);
- if (anchor)
- text_append_n (result, "<span>", 6);
- }
-
- if (html_in_preformatted_context (self))
- {
- const COMMAND_OR_TYPE_STACK *pre_classes
- = html_preformatted_classes_stack (self);
- size_t i;
- for (i = 0; i < pre_classes->top; i++)
- {
- const COMMAND_OR_TYPE *cmd_or_type
- = &pre_classes->stack[i];
- if (cmd_or_type->variety == CTV_type_command)
- {
- enum command_id pre_class_cmd = cmd_or_type->ct.cmd;
- if (builtin_command_data[pre_class_cmd].flags
- & CF_preformatted_code)
- {
- char *attribute_class
- = html_attribute_class (self, "code",
- &table_term_preformatted_code_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">", 1);
-
- pre_class_close = "</code>";
- break;
- }
- }
- }
- }
-
- tree = table_item_content_tree (self, element);
- if (tree)
- {
- add_tree_to_build (self, tree->tree);
- converted_e = tree->tree;
- }
- else
- converted_e = element->e.c->args.list[0];
-
- convert_tree_append (self, converted_e, result,
- "convert table_item_tree");
-
- if (pre_class_close)
- text_append (result, pre_class_close);
-
- if (anchor)
- {
- text_append (result, anchor);
- text_append_n (result, "</span>", 7);
- free (anchor);
- }
-
- text_append_n (result, "</dt>\n", 6);
-
- if (tree)
- destroy_tree_added_elements (self, tree);
- }
- }
- else if (element->parent->type == ET_row)
- {
- conversion_function_cmd_conversion (self,
- &self->current_commands_conversion_function[CM_tab],
- cmd, element, args_formatted,
- content, result);
- }
-}
-
-static char *
-trim_trailing_content (const char *content)
-{
- char *trimmed_content = strdup (content);
- size_t str_len = strlen (trimmed_content);
- if (str_len > 0)
- {
- char *q = trimmed_content + str_len - 1;
- while (q > trimmed_content)
- {
- if (!strchr (whitespace_chars, *q))
- {
- break;
- }
- q--;
- }
- *(q +1) = '\0';
- }
- return trimmed_content;
-}
-
-void
-html_convert_tab_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- char *trimmed_content;
- size_t cell_nr;
- int status;
- const ELEMENT *row;
- const ELEMENT *multitable;
- const ELEMENT *columnfractions;
- enum command_id first_row_cmd;
- const char *html_element = "td";
-
- if (content)
- {
- const char *p = content;
- p += strspn (p, whitespace_chars);
- trimmed_content = trim_trailing_content (p);
- }
- else
- trimmed_content = strdup ("");
-
- if (html_in_string (self))
- {
- text_append (result, trimmed_content);
- free (trimmed_content);
- return;
- }
-
- row = element->parent;
- first_row_cmd = element_builtin_cmd (row->e.c->contents.list[0]);
- if (first_row_cmd == CM_headitem)
- html_element = "th";
-
- text_append_n (result, "<", 1);
- text_append_n (result, html_element, 2);
-
- cell_nr = (size_t) lookup_extra_integer (element, AI_key_cell_number,
&status);
- multitable = row->parent->parent;
-
- columnfractions = lookup_extra_element (multitable, AI_key_columnfractions);
-
- if (columnfractions)
- {
- const STRING_LIST *cf_misc_args
- = lookup_extra_misc_args (columnfractions, AI_key_misc_args);
- if (cf_misc_args->number >= cell_nr)
- {
- const char *fraction_str
- = cf_misc_args->list[cell_nr -1];
- double fraction = strtod (fraction_str, NULL);
- if (self->conf->_INLINE_STYLE_WIDTH.o.integer > 0)
- text_printf (result, " style=\"width: %0.f%%\"", 100 * fraction);
- else
- text_printf (result, " width=\"%0.f%%\"", 100 * fraction);
- }
- }
- text_append_n (result, ">", 1);
- text_append (result, trimmed_content);
- free (trimmed_content);
- text_append_n (result, "</", 2);
- text_append_n (result, html_element, 2);
- text_append_n (result, ">", 1);
-}
-
-void
-html_convert_insertcopying_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (self->document->global_commands.copying)
- {
- ELEMENT *tmp = new_element (ET_NONE);
- tmp->e.c->contents =
self->document->global_commands.copying->e.c->contents;
- convert_tree_append (self, tmp, result, "convert insertcopying");
- tmp->e.c->contents.list = 0;
- destroy_element (tmp);
- }
-}
-
-static char *caption_in_listoffloats_array[] = {"caption-in-listoffloats"};
-static const STRING_LIST caption_in_listoffloats_classes
- = {caption_in_listoffloats_array, 1, 1};
-static char *shortcaption_in_listoffloats_array[]
- = {"shortcaption-in-listoffloats"};
-static const STRING_LIST shortcaption_in_listoffloats_classes
- = {shortcaption_in_listoffloats_array, 1, 1};
-
-void
-html_convert_listoffloats_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const LISTOFFLOATS_TYPE_LIST *listoffloats;
- const char *listoffloats_name;
- size_t i;
-
- if (html_in_string (self))
- return;
-
- listoffloats = &self->document->listoffloats;
-
- if (!listoffloats->number)
- return;
-
- listoffloats_name = lookup_extra_string (element, AI_key_float_type);
-
- for (i = 0; i < listoffloats->number; i++)
- {
- const LISTOFFLOATS_TYPE *float_types = &listoffloats->float_types[i];
- if (!strcmp (float_types->type, listoffloats_name))
- {
- char *attribute_class;
- char *multiple_pass_str;
- STRING_LIST *classes;
- size_t j;
- int *formatted_listoffloats_nr;
-
- if (float_types->float_list.number <= 0)
- return;
-
- formatted_listoffloats_nr
- = &self->shared_conversion_state.formatted_listoffloats_nr[i];
- (*formatted_listoffloats_nr)++;
- if (*formatted_listoffloats_nr > 1)
- xasprintf (&multiple_pass_str, "listoffloats-%d",
- (*formatted_listoffloats_nr) - 1);
- else
- multiple_pass_str = "listoffloats";
-
- classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- attribute_class = html_attribute_class (self, "dl", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">\n", 2);
-
- for (j = 0; j < float_types->float_list.number; j++)
- {
- char *caption_attribute_class;
- const ELEMENT *caption_element;
- const STRING_LIST *caption_classes = 0;
- const ELEMENT *float_elt = float_types->float_list.list[j];
- char *float_href = html_command_href (self, float_elt, 0, 0, 0);
- char *float_text;
-
- if (!float_href)
- continue;
-
- text_append_n (result, "<dt>", 4);
- float_text = html_command_text (self, float_elt, 0);
- if (float_text && strlen (float_text))
- {
- if (strlen (float_href))
- {
- text_printf (result, "<a href=\"%s\">%s</a>",
- float_href, float_text);
- }
- else /* not sure that it can happen */
- {
- text_append (result, float_text);
- }
- }
-
- text_append_n (result, "</dt>", 5);
-
- free (float_text);
- free (float_href);
-
- caption_element = lookup_extra_element (float_elt,
- AI_key_shortcaption);
- if (caption_element)
- caption_classes = &shortcaption_in_listoffloats_classes;
- else
- {
- caption_element = lookup_extra_element (float_elt,
- AI_key_caption);
- if (caption_element)
- caption_classes = &caption_in_listoffloats_classes;
- }
-
- caption_attribute_class = html_attribute_class (self, "dd",
- caption_classes);
- text_append (result, caption_attribute_class);
- free (caption_attribute_class);
- text_append_n (result, ">", 1);
- if (caption_element)
- {
- char *caption_text
- = convert_tree_new_formatting_context (self,
- caption_element->e.c->args.list[0],
- builtin_command_name (cmd),
- multiple_pass_str, 0, 0);
- text_append (result, caption_text);
- free (caption_text);
- }
- text_append_n (result, "</dd>\n", 6);
- }
- text_append_n (result, "</dl>\n", 6);
-
- if (*formatted_listoffloats_nr > 1)
- free (multiple_pass_str);
- free (attribute_class);
- destroy_strings_list (classes);
- }
- }
-}
-
-#define SUBENTRIES_MAX_LEVEL 2
-
-static void
-clear_normalized_entry_levels (char **normalized_entry_levels)
-{
- int i;
- for (i = 0; i < SUBENTRIES_MAX_LEVEL; i++)
- {
- free (normalized_entry_levels[i]);
- normalized_entry_levels[i] = 0;
- }
-}
-
-static char *
-normalized_upper_case (ELEMENT *e)
-{
- char *normalized = convert_to_normalized (e);
- char *result = to_upper_or_lower_multibyte (normalized, 1);
- free (normalized);
- return result;
-}
-
-static void
-printindex_letters_head_foot_internal (CONVERTER *self, const char *index_name,
- const enum command_id cmd,
- STRING_LIST *entry_classes,
- const char *head_or_foot,
- const char *letters_header_explanation,
- const char *alpha_text,
- const char *non_alpha_text, TEXT *result)
-{
- char *index_name_cmd_class;
- char *attribute_class;
-
- xasprintf (&index_name_cmd_class, "%s-letters-%s-%s",
- index_name, head_or_foot, builtin_command_name (cmd));
- add_string (index_name_cmd_class, entry_classes);
- free (index_name_cmd_class);
- attribute_class = html_attribute_class (self, "table", entry_classes);
- clear_strings_list (entry_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, "><tr><th>", 9);
-
- /* TRANSLATORS: before list of letters and symbols grouping index entries */
- translate_convert_tree_append ("Jump to", self, 0, 0, result,
- letters_header_explanation);
- text_append_n (result, ": ", 2);
- text_append_n (result,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- text_append_n (result, " </th><td>", 10);
- if (non_alpha_text)
- text_append (result, non_alpha_text);
- if (non_alpha_text && alpha_text)
- {
- text_append_n (result, " ", 1);
- text_append_n (result,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- text_append_n (result, " \n", 2);
- text_append_n (result,
- self->line_break_element.string,
- self->line_break_element.len);
- text_append_n (result, "\n", 1);
- }
- if (alpha_text)
- text_append (result, alpha_text);
- text_append_n (result, "</td></tr></table>\n", 19);
-}
-
-static ROOT_AND_UNIT *
-get_element_root_command_element (CONVERTER *self, const ELEMENT *command)
-{
- ROOT_AND_UNIT *root_unit = html_get_tree_root_element (self, command, 0);
-
- if (root_unit && root_unit->root)
- {
- const ELEMENT *root_command = root_unit->root;
- if (self->conf->USE_NODES.o.integer > 0)
- {
- if (root_command->e.c->cmd != CM_node)
- {
- const ELEMENT *associated_node =
- lookup_extra_element (root_command,
- AI_key_associated_node);
- if (associated_node)
- root_unit->root = associated_node;
- }
- }
- else if (root_command->e.c->cmd == CM_node)
- {
- const ELEMENT *associated_section
- = lookup_extra_element (root_command,
-
AI_key_associated_section);
- if (associated_section)
- root_unit->root = associated_section;
- }
- }
- return root_unit;
-}
-
-void
-html_convert_printindex_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- const STRING_LIST *misc_args;
- const char *index_name;
- const INDEX_SORTED_BY_LETTER *idx;
- const INDEX_SORTED_BY_LETTER *index_sorted = 0;
- const char *index_element_id = 0;
- char **letter_id;
- char **alpha;
- char **non_alpha;
- size_t non_alpha_nr = 0;
- size_t alpha_nr = 0;
- int *letter_is_symbol;
- char **formatted_letters;
- size_t symbol_idx = 0;
- size_t normalized_letter_idx = 0;
- size_t i;
- char *entry_class_seeentry;
- char *section_class_seeentry;
- char *cmd_index_entry_class;
- char *section_class_seealso;
- char *cmd_index_section_class;
- char *summary_letter_cmd;
- char *attribute_class;
- TEXT entries_text;
- TEXT result_index_entries;
- char *index_name_cmd_class;
- char *alpha_text = 0;
- char *non_alpha_text = 0;
- char *language;
- INDEX_SORTED_BY_LETTER *index_entries_by_letter
- = get_converter_indices_sorted_by_letter (self, &language);
-
- if (!index_entries_by_letter)
- return;
-
- if (html_in_string (self))
- return;
-
- misc_args = lookup_extra_misc_args (element, AI_key_misc_args);
- if (misc_args && misc_args->number > 0)
- index_name = misc_args->list[0];
- else
- return;
-
- for (idx = index_entries_by_letter; idx->name; idx++)
- {
- if (!strcmp (idx->name, index_name))
- {
- index_sorted = idx;
- break;
- }
- }
- if (!index_sorted || !index_sorted->letter_number)
- return;
-
- if (self->current_output_unit
- && self->current_output_unit->uc.unit_command)
- index_element_id
- = html_command_id (self, self->current_output_unit->uc.unit_command);
-
- if (!index_element_id)
- {
- ROOT_AND_UNIT *root_unit
- = get_element_root_command_element (self, element);
- if (root_unit && root_unit->root)
- {
- index_element_id = html_command_id (self, root_unit->root);
- }
- if (!index_element_id)
- /* to avoid duplicate names, use a prefix that cannot happen in anchors */
- index_element_id = "t_i";
- free (root_unit);
- }
-
- letter_id = (char **) malloc (index_sorted->letter_number * sizeof (char *));
- /* we allocate twice as needed here, but it is more practical */
- alpha = (char **) malloc ((index_sorted->letter_number +1) * sizeof (char
*));
- non_alpha = (char **)
- malloc ((index_sorted->letter_number +1) * sizeof (char *));
- memset (alpha, 0, (index_sorted->letter_number +1) * sizeof (char *));
- memset (non_alpha, 0, (index_sorted->letter_number +1) * sizeof (char *));
- letter_is_symbol
- = (int *) malloc (index_sorted->letter_number * sizeof (int));
- formatted_letters = (char **) malloc
- (index_sorted->letter_number * sizeof (char *));
-
- for (i = 0; i < index_sorted->letter_number; i++)
- {
- const char *letter = index_sorted->letter_entries[i].letter;
- uint8_t *encoded_u8 = utf8_from_string (letter);
- ucs4_t next_char;
- u8_next (&next_char, encoded_u8);
- letter_is_symbol[i]
- = !(uc_is_property (next_char, UC_PROPERTY_ALPHABETIC));
- free (encoded_u8);
- if (letter_is_symbol[i])
- {
- symbol_idx++;
- xasprintf (&letter_id[i], "%s_%s_symbol-%zu", index_element_id,
- index_name, symbol_idx);
- }
- else
- {
- char *normalized_letter;
- ELEMENT *letter_text = new_text_element (ET_normal_text);
- text_append (letter_text->e.text, letter);
- normalized_letter = normalize_transliterate_texinfo (letter_text,
- (self->conf->TEST.o.integer > 0));
- destroy_element (letter_text);
-
- if (strcmp (letter, normalized_letter))
- {
- char *tmp_normalized_letter;
- /* disambiguate, as it could be another letter, case of @l, for example */
- normalized_letter_idx++;
- xasprintf (&tmp_normalized_letter, "%s-%zu", normalized_letter,
- normalized_letter_idx);
- free (normalized_letter);
- normalized_letter = tmp_normalized_letter;
- }
-
- xasprintf (&letter_id[i], "%s_%s_letter-%s", index_element_id,
- index_name, normalized_letter);
- free (normalized_letter);
- }
- }
-
- html_new_document_context (self, builtin_command_name (cmd), 0, 0);
-
- STRING_LIST *entry_classes = new_string_list ();
- STRING_LIST *section_classes = new_string_list ();
-
- xasprintf (&entry_class_seeentry, "%s-index-see-entry",
- builtin_command_name (cmd));
- xasprintf (§ion_class_seeentry, "%s-index-see-entry-section",
- builtin_command_name (cmd));
- xasprintf (&cmd_index_entry_class, "%s-index-entry",
- builtin_command_name (cmd));
- xasprintf (§ion_class_seealso, "%s-index-see-also",
- builtin_command_name (cmd));
- xasprintf (&cmd_index_section_class, "%s-index-section",
- builtin_command_name (cmd));
- xasprintf (&summary_letter_cmd, "summary-letter-%s",
- builtin_command_name (cmd));
-
- text_init (&entries_text);
- text_init (&result_index_entries);
-
- /* Next do the entries to determine the letters that are not empty */
- for (i = 0; i < index_sorted->letter_number; i++)
- {
- const INDEX_ENTRY *first_entry = 0;
- const LETTER_INDEX_ENTRIES *letter_entry
- = &index_sorted->letter_entries[i];
- const char *letter = letter_entry->letter;
- size_t entry_nr = 0;
- /* since we normalize, a different formatting will not trigger a new
- formatting of the main entry or a subentry level. This is the
- same for Texinfo TeX */
- size_t j;
-
- char *prev_normalized_entry_levels[SUBENTRIES_MAX_LEVEL+1];
- memset (prev_normalized_entry_levels, 0,
- sizeof (char *) * (SUBENTRIES_MAX_LEVEL +1));
- text_reset (&entries_text);
-
- for (j = 0; j < letter_entry->entries_number; j++)
- {
- int level;
- int in_code;
- int *formatted_index_entry_nr;
- char *multiple_pass_str;
- size_t entry_index_nr;
- const INDEX *entry_index;
- const ELEMENT *seeentry;
- const ELEMENT *seealso;
- char *new_normalized_entry_levels[SUBENTRIES_MAX_LEVEL +1];
- ELEMENT *entry_trees[SUBENTRIES_MAX_LEVEL +1];
- int last_entry_level;
- char *convert_info;
- ELEMENT *target_element;
- const ELEMENT *associated_command = 0;
- char *entry_href;
- ELEMENT *entry_tree;
- const ELEMENT *subentry;
- ELEMENT_LIST *other_subentries_tree = 0;
- int subentry_level = 1;
- ELEMENT *entry_content_element;
- ELEMENT *entry_ref_tree;
- INDEX_ENTRY *index_entry_ref = letter_entry->entries[j];
- ELEMENT *main_entry_element = index_entry_ref->entry_element;
- const INDEX_ENTRY_LOCATION *index_entry_info
- = lookup_extra_index_entry (main_entry_element,
- AI_key_index_entry);
- int entry_number = index_entry_info->number;
- entry_nr++;
-
- if (self->conf->NO_TOP_NODE_OUTPUT.o.integer > 0)
- {
- const ELEMENT *element_node
- = lookup_extra_element (main_entry_element,
- AI_key_element_node);
- if (element_node)
- {
- const char *normalized = lookup_extra_string (element_node,
- AI_key_normalized);
- if (normalized && !strcmp (normalized, "Top"))
- continue;
- }
- }
-
- memset (new_normalized_entry_levels, 0,
- sizeof (char *) * (SUBENTRIES_MAX_LEVEL +1));
-
- entry_content_element = index_content_element (main_entry_element,
0);
- entry_index_nr
- = index_number_index_by_name (&self->sorted_index_names,
- index_entry_ref->index_name);
- entry_index = self->sorted_index_names.list[entry_index_nr-1];
-
- /* to avoid double error messages, call convert_tree_new_formatting_context
- below with a multiple_pass argument if an entry was already formatted once,
- for example if there are multiple printindex. */
- formatted_index_entry_nr
- = &self->shared_conversion_state
- .formatted_index_entries[entry_index_nr -1][entry_number -1];
- (*formatted_index_entry_nr)++;
-
- if (*formatted_index_entry_nr > 1)
- xasprintf (&multiple_pass_str, "index-formatted-%d",
- *formatted_index_entry_nr);
-
- in_code = entry_index->in_code;
-
- if (in_code)
- entry_ref_tree = new_element (ET__code);
- else
- entry_ref_tree = new_element (ET_NONE);
-
- add_to_contents_as_array (entry_ref_tree, entry_content_element);
-
- /* index entry with @seeentry or @seealso */
- seeentry = lookup_extra_element (main_entry_element,
AI_key_seeentry);
- seealso = lookup_extra_element (main_entry_element, AI_key_seealso);
-
- memset (entry_trees, 0, sizeof (ELEMENT *) * SUBENTRIES_MAX_LEVEL);
-
- /* determine the trees and normalized main entry and subentries, to be
- compared with the previous line normalized entries to determine
- what is already formatted as part of the previous lines and
- what levels should be added. The last level is always formatted. */
- new_normalized_entry_levels[0]
- = normalized_upper_case (entry_ref_tree);
- entry_trees[0] = entry_ref_tree;
- subentry = index_entry_ref->entry_element;
-
- while (subentry_level <= SUBENTRIES_MAX_LEVEL)
- {
- const ELEMENT *new_subentry = lookup_extra_element (subentry,
- AI_key_subentry);
- ELEMENT *subentry_tree = 0;
- if (!new_subentry)
- break;
-
- subentry = new_subentry;
-
- if (subentry->e.c->args.number > 0
- && subentry->e.c->args.list[0]->e.c->contents.number > 0)
- {
- if (in_code)
- subentry_tree = new_element (ET__code);
- else
- subentry_tree = new_element (ET_NONE);
-
- add_to_contents_as_array (subentry_tree,
- subentry->e.c->args.list[0]);
- }
-
- if (subentry_level >= SUBENTRIES_MAX_LEVEL)
- {
- /* at the max, concatenate the remaining subentries */
- other_subentries_tree
- = comma_index_subentries_tree (subentry, 0);
- if (other_subentries_tree)
- {
- if (!subentry_tree)
- {
- if (in_code)
- subentry_tree = new_element (ET__code);
- else
- subentry_tree = new_element (ET_NONE);
- }
- insert_list_slice_into_contents (subentry_tree,
- subentry_tree->e.c->contents.number,
- other_subentries_tree, 0,
- other_subentries_tree->number);
- }
- }
- else if (subentry_tree)
- {
- new_normalized_entry_levels[subentry_level]
- = normalized_upper_case (subentry_tree);
-
- }
- entry_trees[subentry_level] = subentry_tree;
- subentry_level++;
- }
- /* level/index of the last entry */
- last_entry_level = subentry_level - 1;
-
- /* format the leading entries when there are subentries (all entries
- except the last one), and when there is not such a subentry already
- formatted on the previous lines.
- Each on a line with increasing indentation, no hyperlink. */
- if (last_entry_level > 0)
- {
- int with_new_formatted_entry = 0;
- for (level = 0; level < last_entry_level; level++)
- {
- char *convert_info;
- char *entry;
-
- if (!with_new_formatted_entry
- && prev_normalized_entry_levels[level]
- && !strcmp (prev_normalized_entry_levels[level],
- new_normalized_entry_levels[level]))
- {
- if (level > 0)
- destroy_element (entry_trees[level]);
- continue;
- }
-
- with_new_formatted_entry = 1;
- xasprintf (&convert_info,
- "index %s l %s index entry %zu subentry %d",
- index_name, letter, entry_nr -1, level);
- if (level > 0)
- add_tree_to_build (self, entry_trees[level]);
- if (*formatted_index_entry_nr > 1)
- {
- /* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
- entry_trees[level], convert_info,
- multiple_pass_str, 0, 0);
- }
- else
- {
- entry = html_convert_tree (self, entry_trees[level],
- convert_info);
- }
- if (level > 0)
- {
- remove_tree_to_build (self, entry_trees[level]);
- destroy_element (entry_trees[level]);
- }
- free (convert_info);
-
- add_string (cmd_index_entry_class, entry_classes);
- if (level > 0)
- {
- /* indent */
- char *index_entry_level;
- xasprintf (&index_entry_level, "index-entry-level-%d",
- level);
- add_string (index_entry_level, entry_classes);
- free (index_entry_level);
- }
- text_append_n (&entries_text, "<tr><td></td>", 13);
- attribute_class = html_attribute_class (self, "td",
- entry_classes);
- text_append (&entries_text, attribute_class);
- clear_strings_list (entry_classes);
- free (attribute_class);
- text_append_n (&entries_text, ">", 1);
-
- if (in_code)
- text_append_n (&entries_text, "<code>", 6);
- text_append (&entries_text, entry);
- free (entry);
- if (in_code)
- text_append_n (&entries_text, "</code>", 7);
- text_append_n (&entries_text, "</td>", 5);
- /* empty cell, no section for this line */
- text_append_n (&entries_text, "<td></td></tr>\n", 15);
- }
- }
- /* last entry, always converted, associated to chapter/node and
- with an hyperlink or to seeentry/seealso */
- entry_tree = entry_trees[last_entry_level];
-
- if (seeentry || seealso)
- {
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
- ELEMENT *referred_tree;
- const ELEMENT *referred_entry;
- char *entry;
- char *reference = 0;
-
- if (seeentry)
- referred_entry = seeentry;
- else
- referred_entry = seealso;
-
- if (in_code)
- referred_tree = new_element (ET__code);
- else
- referred_tree = new_element (ET_NONE);
-
- if (referred_entry->e.c->args.number > 0
- && referred_entry->e.c->args.list[0]->e.c->contents.number >
0)
- {
- ELEMENT *referred_copy
- = copy_tree (referred_entry->e.c->args.list[0]);
- add_to_contents_as_array (referred_tree, referred_copy);
- }
-
- if (seeentry)
- {
- char *convert_info;
- ELEMENT *result_tree;
- ELEMENT *entry_tree_copy = copy_tree (entry_tree);
- add_element_to_named_string_element_list (substrings,
- "main_index_entry", entry_tree_copy);
- add_element_to_named_string_element_list (substrings,
- "seeentry", referred_tree);
- if (in_code)
- {
- /* TRANSLATORS: redirect to another index entry */
- /* TRANSLATORS: @: is discardable and is used to avoid a msgfmt error */
- result_tree = html_cdt_tree (
- "@code{{main_index_entry}}, @emph{See@:} @code{{seeentry}}",
- self, substrings, 0);
- }
- else
- {
- /* TRANSLATORS: redirect to another index entry */
- /* TRANSLATORS: @: is discardable and used to avoid a msgfmt error */
- result_tree = html_cdt_tree (
- "{main_index_entry}, @emph{See@:} {seeentry}",
- self, substrings, 0);
- }
- xasprintf (&convert_info,
- "index %s l %s index entry %zu seeentry",
- index_name, letter, entry_nr -1);
- add_tree_to_build (self, result_tree);
- if (*formatted_index_entry_nr > 1)
- {
- /* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
- result_tree, convert_info, multiple_pass_str, 0,
0);
- }
- else
- {
- entry = html_convert_tree (self, result_tree,
- convert_info);
- }
- remove_tree_to_build (self, result_tree);
- destroy_element_and_children (result_tree);
- free (convert_info);
-
- add_string (entry_class_seeentry, entry_classes);
- add_string (section_class_seeentry, section_classes);
- }
- else
- {
- /* TRANSLATORS: refer to another index entry */
- ELEMENT *reference_tree;
- char *conv_str_entry;
- char *conv_str_reference;
-
- add_element_to_named_string_element_list (substrings,
- "see_also_entry", referred_tree);
- reference_tree = html_cdt_tree (
- "@emph{See also} {see_also_entry}",
- self, substrings, 0);
-
- xasprintf (&conv_str_entry,
- "index %s l %s index entry %zu (with seealso)",
- index_name, letter, entry_nr -1);
- xasprintf (&conv_str_reference,
- "index %s l %s index entry %zu seealso",
- index_name, letter, entry_nr -1);
-
- add_tree_to_build (self, entry_tree);
- add_tree_to_build (self, reference_tree);
- if (*formatted_index_entry_nr > 1)
- {
- /* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
- entry_tree, conv_str_entry,
- multiple_pass_str, 0, 0);
- reference = convert_tree_new_formatting_context (self,
- reference_tree, conv_str_reference,
- multiple_pass_str, 0, 0);
- }
- else
- {
- entry = html_convert_tree (self, entry_tree,
- conv_str_entry);
- reference = html_convert_tree (self, reference_tree,
- conv_str_reference);
- }
- remove_tree_to_build (self, entry_tree);
- remove_tree_to_build (self, reference_tree);
- destroy_element_and_children (reference_tree);
-
- free (conv_str_entry);
- free (conv_str_reference);
-
- add_string (cmd_index_entry_class, entry_classes);
- add_string (section_class_seealso, section_classes);
- }
-
- destroy_named_string_element_list (substrings);
-
- text_append_n (&entries_text, "<tr><td></td>", 13);
- if (last_entry_level > 0)
- {
- char *index_entry_level;
- xasprintf (&index_entry_level, "index-entry-level-%d",
- last_entry_level);
- add_string (index_entry_level, entry_classes);
- free (index_entry_level);
- }
- attribute_class = html_attribute_class (self, "td",
entry_classes);
- text_append (&entries_text, attribute_class);
- clear_strings_list (entry_classes);
- free (attribute_class);
- text_append_n (&entries_text, ">", 1);
-
- if (!seeentry && in_code)
- text_append_n (&entries_text, "<code>", 6);
- text_append (&entries_text, entry);
- free (entry);
- if (!seeentry)
- {
- if (in_code)
- text_append_n (&entries_text, "</code>", 7);
- if (self->conf->INDEX_ENTRY_COLON.o.string)
- text_append (&entries_text,
- self->conf->INDEX_ENTRY_COLON.o.string);
- }
- text_append_n (&entries_text, "</td>", 5);
-
- attribute_class
- = html_attribute_class (self, "td", section_classes);
- text_append (&entries_text, attribute_class);
- clear_strings_list (section_classes);
- free (attribute_class);
- text_append_n (&entries_text, ">", 1);
- if (reference)
- {
- text_append (&entries_text, reference);
- free (reference);
- }
- text_append_n (&entries_text, "</td></tr>\n", 11);
-
- }
- else
- {
- char *entry = 0;
- if (entry_tree)
- {
- xasprintf (&convert_info, "index %s l %s index entry %zu",
- index_name, letter, entry_nr -1);
-
- if (last_entry_level > 0)
- add_tree_to_build (self, entry_tree);
- if (*formatted_index_entry_nr > 1)
- {
- /* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
- entry_tree, convert_info,
- multiple_pass_str, 0, 0);
- }
- else
- {
- entry = html_convert_tree (self, entry_tree,
- convert_info);
- }
- if (last_entry_level > 0)
- remove_tree_to_build (self, entry_tree);
- free (convert_info);
- }
-
- if (last_entry_level == 0
- && (!entry
- || entry[strspn (entry, whitespace_chars)] == '\0'))
- {
- free (entry);
- free (new_normalized_entry_levels[0]);
- new_normalized_entry_levels[0] = 0;
- }
- else
- {
- if (!first_entry)
- first_entry = index_entry_ref;
-
- if (index_entry_ref->entry_associated_element)
- target_element = index_entry_ref->entry_associated_element;
- else
- target_element = main_entry_element;
-
- entry_href
- = html_command_href (self, target_element, 0, 0, 0);
-
- add_string (cmd_index_entry_class, entry_classes);
- if (last_entry_level > 0)
- {
- char *index_entry_level;
- xasprintf (&index_entry_level, "index-entry-level-%d",
- last_entry_level);
- add_string (index_entry_level, entry_classes);
- free (index_entry_level);
- }
- text_append_n (&entries_text, "<tr><td></td>", 13);
- attribute_class = html_attribute_class (self, "td",
- entry_classes);
- text_append (&entries_text, attribute_class);
- clear_strings_list (entry_classes);
- free (attribute_class);
- text_append_n (&entries_text, ">", 1);
-
- text_printf (&entries_text, "<a href=\"%s\">", entry_href);
- free (entry_href);
- if (in_code)
- text_append_n (&entries_text, "<code>", 6);
- if (entry)
- {
- text_append (&entries_text, entry);
- free (entry);
- }
- if (in_code)
- text_append_n (&entries_text, "</code>", 7);
- text_append_n (&entries_text, "</a>", 4);
- if (self->conf->INDEX_ENTRY_COLON.o.string)
- text_append (&entries_text,
- self->conf->INDEX_ENTRY_COLON.o.string);
- text_append_n (&entries_text, "</td>", 5);
-
- if (self->conf->NODE_NAME_IN_INDEX.o.integer > 0)
- {
- associated_command
- = lookup_extra_element (main_entry_element,
- AI_key_element_node);
- if (!associated_command)
- associated_command
- = html_command_node (self, target_element);
-
- if (!associated_command
- && *formatted_index_entry_nr == 1)
- {
- char *element_region
- = lookup_extra_string (main_entry_element,
- AI_key_element_region);
- /* do not warn if the entry is in a special region, like titlepage */
- if (!element_region)
- {
- /* NOTE $self->in_multiple_conversions() is not checked as printindex
- should not happen in multiple tree conversion, but the error message
- is printed for the first entry formatting only. */
- message_list_command_warn (&self->error_messages,
- self->conf,
- main_entry_element, 0,
- "entry for index `%s' for @printindex %s outside of any node",
- entry_index->name, index_name);
- }
- }
- }
-
- if (!associated_command)
- {
- associated_command
- = html_command_root_element_command (self,
- target_element);
- if (!associated_command)
- {
- associated_command
- = self->global_units_directions[D_Top]->uc.unit_command;
-
- /* NOTE the warning here catches the most relevant cases of
- index entry that is not associated to the right command, which
- are very few in the test suite. There is also a warning in the
- parser with a much broader scope with possible overlap, but the
- overlap is not a problem.
- NODE_NAME_IN_INDEX may be undef even with USE_NODES set if the
- converter is called as convert() as in the test suite */
-
- if (self->conf->NODE_NAME_IN_INDEX.o.integer == 0
- && *formatted_index_entry_nr == 1)
- {
- char *element_region
- = lookup_extra_string (main_entry_element,
- AI_key_element_region);
- /* do not warn if the entry is in a special region, like titlepage */
- if (!element_region)
- {
- /* NOTE $self->in_multiple_conversions() is not checked as printindex
- should not happen in multiple tree conversion, but the error message
- is printed for the first entry formatting only.
- NOTE the index entry may be associated to a node in that case. */
- message_list_command_warn (&self->error_messages,
- self->conf,
- main_entry_element, 0,
- "entry for index `%s' for @printindex %s outside of any section",
- entry_index->name, index_name);
- }
- }
- }
- }
-
- add_string (cmd_index_section_class, section_classes);
- attribute_class
- = html_attribute_class (self, "td", section_classes);
- text_append (&entries_text, attribute_class);
- free (attribute_class);
- clear_strings_list (section_classes);
- text_append_n (&entries_text, ">", 1);
-
- if (associated_command)
- {
- char *associated_command_href
- = html_command_href (self, associated_command, 0, 0, 0);
- char *associated_command_text
- = html_command_text (self, associated_command, 0);
-
- if (associated_command_href)
- {
- text_printf (&entries_text, "<a href=\"%s\">%s</a>",
- associated_command_href, associated_command_text);
- }
- else
- {
- text_append (&entries_text, associated_command_text);
- }
-
- free (associated_command_text);
- free (associated_command_href);
- }
- text_append_n (&entries_text, "</td></tr>\n", 11);
- }
- }
-
- if (new_normalized_entry_levels[0] != 0)
- {
- for (level = 0; level < SUBENTRIES_MAX_LEVEL; level++)
- {
- free (prev_normalized_entry_levels[level]);
- prev_normalized_entry_levels[level]
- = new_normalized_entry_levels[level];
- }
- }
-
- if (last_entry_level > 0 && entry_tree)
- destroy_element (entry_tree);
-
- if (other_subentries_tree)
- free_comma_index_subentries_tree (other_subentries_tree);
-
- destroy_element (entry_ref_tree);
-
- if (*formatted_index_entry_nr > 1)
- free (multiple_pass_str);
- }
- clear_normalized_entry_levels (prev_normalized_entry_levels);
-
- if (entries_text.end > 0)
- {
- char *formatted_letter;
- const ELEMENT *letter_command = 0;
- enum command_id letter_cmd = 0;
-
- if (first_entry)
- {
- INDEX_ENTRY_TEXT_OR_COMMAND *entry_text_or_command
- = index_entry_first_letter_text_or_command (first_entry);
-
- if (entry_text_or_command)
- {
- letter_command = entry_text_or_command->command;
-
- free (entry_text_or_command->text);
- free (entry_text_or_command);
-
- if (letter_command)
- letter_cmd = element_builtin_data_cmd (letter_command);
- }
- }
-
- if (letter_command
- && (!(builtin_command_data[letter_cmd].flags & CF_accent))
- && letter_cmd != CM_U
- /* special case, the uppercasing of that command is not done
- if as a command, while it is done correctly in letter */
- && letter_cmd != CM_ss)
- {
- ELEMENT *formatted_command = 0;
- char *explanation;
- if (html_commands_data[letter_cmd].upper_case_cmd)
- {
- formatted_command
- = new_command_element (ET_brace_noarg_command,
- html_commands_data[letter_cmd].upper_case_cmd);
- }
-
- xasprintf (&explanation, "index letter %s command", letter);
- if (formatted_command)
- {
- add_tree_to_build (self, formatted_command);
- formatted_letter
- = html_convert_tree (self, formatted_command, explanation);
- remove_tree_to_build (self, formatted_command);
- destroy_element (formatted_command);
- }
- else
- formatted_letter
- = html_convert_tree (self, letter_command, explanation);
- free (explanation);
- }
- else
- {
- TEXT text_letter;
- text_init (&text_letter);
- text_append (&text_letter, "");
- format_protect_text (self, letter, &text_letter);
- formatted_letter = text_letter.text;
- }
-
- formatted_letters[i] = formatted_letter;
-
- text_append_n (&result_index_entries, "<tr>", 4);
- text_printf (&result_index_entries, "<th id=\"%s\">", letter_id[i]);
- text_append (&result_index_entries, formatted_letter);
- text_append_n (&result_index_entries, "</th></tr>\n", 11);
- text_append (&result_index_entries, entries_text.text);
- text_append_n (&result_index_entries, "<tr><td colspan=\"3\">", 20);
- if (self->conf->DEFAULT_RULE.o.string)
- text_append (&result_index_entries,
- self->conf->DEFAULT_RULE.o.string);
- text_append_n (&result_index_entries, "</td></tr>\n", 11);
- }
- else
- {
- formatted_letters[i] = 0;
- }
- }
-
- add_string (summary_letter_cmd, entry_classes);
- attribute_class = html_attribute_class (self, "a", entry_classes);
- for (i = 0; i < index_sorted->letter_number; i++)
- {
- if (formatted_letters[i])
- {
- text_reset (&entries_text);
-
- text_append (&entries_text, attribute_class);
- text_printf (&entries_text, " href=\"#%s\"><b>", letter_id[i]);
- text_append (&entries_text, formatted_letters[i]);
- text_append_n (&entries_text, "</b></a>", 8);
-
- if (letter_is_symbol[i])
- {
- non_alpha[non_alpha_nr] = strdup (entries_text.text);
- non_alpha_nr++;
- }
- else
- {
- alpha[alpha_nr] = strdup (entries_text.text);
- alpha_nr++;
- }
-
- free (formatted_letters[i]);
- }
- }
- free (attribute_class);
-
- free (letter_is_symbol);
- free (formatted_letters);
-
- for (i = 0; i < index_sorted->letter_number; i++)
- free (letter_id[i]);
- free (letter_id);
-
- free (entry_class_seeentry);
- free (section_class_seeentry);
- free (cmd_index_entry_class);
- free (section_class_seealso);
- free (cmd_index_section_class);
- free (summary_letter_cmd);
-
- destroy_strings_list (section_classes);
-
- if (non_alpha_nr + alpha_nr <= 0)
- {
- free (alpha);
- free (non_alpha);
- html_pop_document_context (self);
- free (entries_text.text);
- free (result_index_entries.text);
- destroy_strings_list (entry_classes);
- return;
- }
-
- clear_strings_list (entry_classes);
-
- add_string (builtin_command_name (cmd), entry_classes);
- xasprintf (&index_name_cmd_class, "%s-%s",
- index_name, builtin_command_name (cmd));
- add_string (index_name_cmd_class, entry_classes);
- free (index_name_cmd_class);
- attribute_class = html_attribute_class (self, "div", entry_classes);
- clear_strings_list (entry_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">\n", 2);
-
- /* Format the summary letters */
- if (non_alpha_nr + alpha_nr > 1)
- {
- if (non_alpha_nr > 0)
- {
- text_reset (&entries_text);
- text_append (&entries_text, non_alpha[0]);
- if (non_alpha_nr > 1)
- {
- for (i = 1; i < non_alpha_nr; i++)
- {
- text_append_n (&entries_text, "\n ", 2);
- text_append_n (&entries_text,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- text_append_n (&entries_text, " \n", 2);
- text_append (&entries_text, non_alpha[i]);
- }
- }
- text_append_n (&entries_text, "\n", 1);
- non_alpha_text = strdup (entries_text.text);
- }
- if (alpha_nr > 0)
- {
- text_reset (&entries_text);
- for (i = 0; i < alpha_nr; i++)
- {
- text_append (&entries_text, alpha[i]);
- text_append_n (&entries_text, "\n ", 2);
- text_append_n (&entries_text,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- text_append_n (&entries_text, " \n", 2);
- }
- alpha_text = strdup (entries_text.text);
- }
-
- /* format the summary */
- printindex_letters_head_foot_internal (self, index_name, cmd,
- entry_classes, "header",
- "Tr letters header text",
- alpha_text, non_alpha_text, result);
- }
-
- if (non_alpha_nr > 0)
- {
- for (i = 0; i < non_alpha_nr; i++)
- free (non_alpha[i]);
- }
- free (non_alpha);
-
- if (alpha_nr > 0)
- {
- for (i = 0; i < alpha_nr; i++)
- free (alpha[i]);
- }
- free (alpha);
-
- /* now format the index entries */
- xasprintf (&index_name_cmd_class, "%s-entries-%s",
- index_name, builtin_command_name (cmd));
- add_string (index_name_cmd_class, entry_classes);
- free (index_name_cmd_class);
- attribute_class = html_attribute_class (self, "table", entry_classes);
- clear_strings_list (entry_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">\n<tr><td></td>", 15);
-
- xasprintf (&index_name_cmd_class, "entries-header-%s",
- builtin_command_name (cmd));
- add_string (index_name_cmd_class, entry_classes);
- free (index_name_cmd_class);
- attribute_class = html_attribute_class (self, "th", entry_classes);
- clear_strings_list (entry_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">", 1);
- /* TRANSLATORS: index entries column header in index formatting */
- translate_convert_tree_append ("Index Entry", self, 0, 0, result,
- "Tr th idx entries 1");
- text_append_n (result, "</th>", 5);
-
- xasprintf (&index_name_cmd_class, "sections-header-%s",
- builtin_command_name (cmd));
- add_string (index_name_cmd_class, entry_classes);
- free (index_name_cmd_class);
- attribute_class = html_attribute_class (self, "th", entry_classes);
- clear_strings_list (entry_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">", 1);
- /* TRANSLATORS: section of index entry column header in index formatting */
- translate_convert_tree_append ("Section", self, 0, 0, result,
- "Tr th idx entries 2");
- text_append_n (result, "</th></tr>\n", 11);
- text_append_n (result, "<tr><td colspan=\"3\">", 20);
- if (self->conf->DEFAULT_RULE.o.string)
- text_append (result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (result, "</td></tr>\n", 11);
- text_append (result, result_index_entries.text);
- text_append_n (result, "</table>\n", 9);
-
-
- html_pop_document_context (self);
-
- if (non_alpha_nr + alpha_nr > 1)
- {
- printindex_letters_head_foot_internal (self, index_name, cmd,
- entry_classes, "footer",
- "Tr letters footer text",
- alpha_text, non_alpha_text, result);
-
- if (non_alpha_nr > 0)
- free (non_alpha_text);
- if (alpha_nr > 0)
- free (alpha_text);
- }
-
- text_append_n (result, "</div>\n", 7);
-
- free (entries_text.text);
- free (result_index_entries.text);
-
- destroy_strings_list (entry_classes);
-}
-
-void
-html_convert_informative_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (html_in_string (self))
- return;
-
- set_informative_command_value (self->conf, element);
-}
-
-void
-html_convert_contents_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- if (html_in_string (self))
- return;
-
- enum command_id used_cmd;
-
- if (cmd == CM_summarycontents)
- used_cmd = CM_shortcontents;
- else
- used_cmd = cmd;
-
- set_informative_command_value (self->conf, element);
-
- if (self->conf->CONTENTS_OUTPUT_LOCATION.o.string
- && !strcmp (self->conf->CONTENTS_OUTPUT_LOCATION.o.string, "inline")
- && ((used_cmd == CM_contents && self->conf->contents.o.integer > 0)
- || (used_cmd == CM_shortcontents
- && self->conf->shortcontents.o.integer > 0))
- && self->document->sections_list
- && self->document->sections_list->number > 1)
- {
- char *contents = contents_inline_element (self, used_cmd, element);
- if (contents)
- {
- text_append (result, contents);
- free (contents);
- }
- }
-}
-
-void
-html_convert_def_line_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result);
-
-void
-html_convert_def_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result)
-{
- STRING_LIST *classes;
- enum command_id original_cmd = cmd;
- char *class;
-
- if (builtin_command_data[cmd].flags & CF_line)
- {
- html_convert_def_line_type (self, ET_def_line, element, content, result);
- return;
- }
-
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- classes = new_string_list ();
-
- if (cmd != CM_defblock)
- {
- if (builtin_command_data[cmd].flags & CF_def_alias)
- {
- int i;
- for (i = 0; def_aliases[i].alias ; i++)
- {
- if (def_aliases[i].alias == cmd)
- {
- original_cmd = def_aliases[i].command;
- break;
- }
- }
- }
-
- xasprintf (&class, "first-%s", builtin_command_name (original_cmd));
- add_string (class, classes);
- free (class);
-
- if (cmd != original_cmd)
- {
- xasprintf (&class, "first-%s-alias-first-%s",
- builtin_command_name (cmd),
- builtin_command_name (original_cmd));
- add_string (class, classes);
- free (class);
- }
- }
- else
- add_string (builtin_command_name (cmd), classes);
-
- add_string ("def-block", classes);
-
- if (self->conf->DEF_TABLE.o.integer <= 0)
- {
- open_element_with_class (self, "dl", classes, result);
- text_append_n (result, "\n", 1);
- if (content)
- text_append (result, content);
- text_append_n (result, "</dl>\n", 6);
- }
- else
- {
- open_element_with_class (self, "table", classes, result);
- text_append_n (result, "\n", 1);
- if (content)
- text_append (result, content);
- text_append_n (result, "</table>\n", 9);
- }
-
- destroy_strings_list (classes);
-}
-
-
-void
-html_command_open_external (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element, TEXT *result)
-{
- if (self->commands_open[cmd].status > 0)
- call_commands_open (self, cmd, element, result);
-}
-
-void
-html_open_node_part_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element, TEXT *result)
-{
- if (self->conf->NO_TOP_NODE_OUTPUT.o.integer > 0)
- {
- const ELEMENT *node_element = 0;
- int in_skipped_node_top
- = self->shared_conversion_state.in_skipped_node_top;
-
- if (cmd == CM_node)
- node_element = element;
- else if (cmd == CM_part)
- {
- const ELEMENT *part_following_node
- = lookup_extra_element (element, AI_key_part_following_node);
- if (part_following_node)
- node_element = part_following_node;
- }
- if (node_element || cmd == CM_part)
- {
- int node_is_top = 0;
- if (node_element)
- {
- const char *normalized = lookup_extra_string (node_element,
- AI_key_normalized);
- if (normalized && !strcmp (normalized, "Top"))
- {
- node_is_top = 1;
- in_skipped_node_top = 1;
- self->shared_conversion_state.in_skipped_node_top
- = in_skipped_node_top;
- }
- }
- if (!node_is_top && in_skipped_node_top == 1)
- {
- in_skipped_node_top = -1;
- self->shared_conversion_state.in_skipped_node_top
- = in_skipped_node_top;
- }
- }
- }
-}
-
-void
-html_open_quotation_command (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element, TEXT *result)
-{
- const char *cmdname = element_command_name (element);
- char *formatted_quotation_arg_to_prepend = 0;
- if (element->e.c->args.number > 0
- && element->e.c->args.list[0]->e.c->contents.number > 0)
- {
- ELEMENT *tree;
- char *explanation;
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
- ELEMENT *quotation_arg_copy = copy_tree (element->e.c->args.list[0]);
- add_element_to_named_string_element_list (substrings,
- "quotation_arg", quotation_arg_copy);
- tree = html_cdt_tree ("@b{{quotation_arg}:} ",
- self, substrings, 0);
- destroy_named_string_element_list (substrings);
- xasprintf (&explanation, "open %s prepended arg", cmdname);
- add_tree_to_build (self, tree);
- formatted_quotation_arg_to_prepend
- = html_convert_tree (self, tree, explanation);
- remove_tree_to_build (self, tree);
- destroy_element_and_children (tree);
- free (explanation);
- }
- html_register_pending_formatted_inline_content (self, cmdname,
- formatted_quotation_arg_to_prepend);
- free (formatted_quotation_arg_to_prepend);
-}
-
-
-void
-html_type_conversion_external (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = self->current_types_conversion_function[type].formatting_reference;
- /* NOTE it should always be true, as in the main loop a formatting
- function is called only if type_conversion is set, which should not
- be if formatting_reference status is 0 */
- if (formatting_reference->status > 0)
- call_types_conversion (self, type, formatting_reference,
- element, content, result);
-}
-
-void
-html_convert_text (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- char *content_used;
- int contents_used_to_be_freed = 0;
-
- if (html_in_verbatim (self))
- {
- /* do not use the customization API as in perl */
- html_default_format_protect_text (content, result);
- return;
- }
- else if (html_in_raw (self))
- {
- text_append (result, content);
- return;
- }
-
- if (html_in_upper_case (self))
- {
- content_used = to_upper_or_lower_multibyte (content, 1);
- contents_used_to_be_freed = 1;
- }
- else
- /* cast needed to drop const to avoid a compiler warning */
- content_used = (char *) content;
-
- if (html_in_preformatted_context (self))
- {
- OTXI_ALL_CONVERT_TEXT ( , )
- }
- else if (html_in_non_breakable_space (self))
- {
- OTXI_ALL_CONVERT_TEXT (" \n", OTXI_NO_BREAK_CASES(p))
- }
- else if (html_in_space_protected (self))
- {
- OTXI_ALL_CONVERT_TEXT (" \n", OTXI_SPACE_PROTECTION_CASES(p))
- }
- else
- {
- OTXI_ALL_CONVERT_TEXT ( , )
- }
-
- if (contents_used_to_be_freed)
- free (content_used);
-}
-
-#define ADDN(str,nr) text_append_n (result, str, nr)
-void
-html_css_string_convert_text (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- char *content_used;
- int contents_used_to_be_freed = 0;
-
- if (html_in_upper_case (self))
- {
- content_used = to_upper_or_lower_multibyte (content, 1);
- contents_used_to_be_freed = 1;
- }
- else
- /* cast needed to avoid a compiler warning */
- content_used = (char *) content;
-
- if (html_in_code (self) || html_in_math (self))
- {
- default_css_string_format_protect_text (content_used, result);
- goto out;
- }
-
- const char *p = content_used;
- while (*p)
- {
- int before_sep_nr = strcspn (p, "\\-`'");
- if (before_sep_nr)
- {
- text_append_n (result, p, before_sep_nr);
- p += before_sep_nr;
- }
- if (!*p)
- break;
- switch (*p)
- {
- case '-':
- if (*(p+1) && !memcmp (p, "---", 3))
- {
- ADDN("\\2014 ",6);
- p += 3;
- }
- else if (!memcmp (p, "--", 2))
- {
- ADDN("\\2013 ",6);
- p += 2;
- }
- else
- {
- text_append_n (result, "-", 1);
- p++;
- }
- break;
- case '`':
- if (!memcmp (p, "``", 2))
- {
- ADDN("\\201C ",6);
- p += 2;
- }
- else
- {
- ADDN("\\2018 ",6);
- p++;
- }
- break;
- case '\'':
- if (!memcmp (p, "''", 2))
- {
- ADDN("\\201D ",6);
- p += 2;
- }
- else
- {
- ADDN("\\2019 ",6);
- p++;
- }
- break;
- case '\\':
- ADDN("\\\\", 2);
- p++;
- break;
- }
- }
- out:
- if (contents_used_to_be_freed)
- free (content_used);
-}
-#undef ADDN
-
-void
-html_convert_paragraph_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- TEXT content_text;
- enum command_id align_cmd;
- char *associated_content
- = html_get_associated_formatted_inline_content (self, element, 0);
-
- text_init (&content_text);
-
- if (associated_content)
- {
- text_append (&content_text, associated_content);
- free (associated_content);
- }
- if (content)
- text_append (&content_text, content);
-
- if (content_text.end <= 0)
- {
- free (content_text.text);
- return;
- }
-
- if (html_paragraph_number (self) == 1)
- {
- enum command_id in_format_cmd = html_top_block_command (self);
- if (in_format_cmd)
- {
- /* no first paragraph in those environment to avoid extra spacing */
- if (in_format_cmd == CM_itemize
- || in_format_cmd == CM_enumerate
- || in_format_cmd == CM_multitable
- /* this should only happen if in @nodedescriptionblock, otherwise
- there are no paragraphs, but preformatted */
- || in_format_cmd == CM_menu)
- {
- text_append (result, content_text.text);
- free (content_text.text);
- return;
- }
- }
- }
-
- if (html_in_string (self))
- {
- text_append (result, content_text.text);
- free (content_text.text);
- return;
- }
-
- if (content_text.text[strspn (content_text.text, whitespace_chars)] == '\0')
- {
- free (content_text.text);
- return;
- }
-
- align_cmd = html_in_align (self);
-
- if (align_cmd)
- {
- char *attribute_class;
- char *class;
- STRING_LIST *classes = new_string_list ();
-
- xasprintf (&class, "%s-paragraph", builtin_command_name (align_cmd));
- add_string (class, classes);
- free (class);
-
- attribute_class = html_attribute_class (self, "p", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- free (attribute_class);
- destroy_strings_list (classes);
- }
- else
- text_append_n (result, "<p>", 3);
-
- text_append (result, content_text.text);
- free (content_text.text);
-
- text_append_n (result, "</p>", 4);
-}
-
-static char *
-preformatted_class (const CONVERTER *self)
-{
- const COMMAND_OR_TYPE *cur_pre_class = 0;
- const COMMAND_OR_TYPE_STACK *pre_classes
- = html_preformatted_classes_stack (self);
- size_t i;
- for (i = 0; i < pre_classes->top; i++)
- {
- const COMMAND_OR_TYPE *cmd_or_type = &pre_classes->stack[i];
- if (!(cur_pre_class
- && (cur_pre_class->variety == CTV_type_command
- && builtin_command_data[cur_pre_class->ct.cmd].flags
- & CF_preformatted_code)
- && (!((cmd_or_type->variety == CTV_type_command
- && builtin_command_data[cmd_or_type->ct.cmd].flags
- & CF_preformatted_code)
- || cmd_or_type->ct.cmd == CM_menu))))
- cur_pre_class = cmd_or_type;
- }
- if (cur_pre_class)
- {
- char *pre_class = 0;
- if (cur_pre_class->variety == CTV_type_command)
- {
- xasprintf (&pre_class, "%s-preformatted",
- builtin_command_name (cur_pre_class->ct.cmd));
- }
- else if (cur_pre_class->variety == CTV_type_type)
-
- {
- xasprintf (&pre_class, "%s-preformatted",
- self->pre_class_types[cur_pre_class->ct.type]);
- }
- if (pre_class)
- return pre_class;
- }
- /* should not happen */
- return 0;
-}
-
-void
-html_convert_preformatted_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- TEXT content_text;
- char *trimmed_content;
- enum command_id in_format_cmd;
- char *pre_class = 0;
- int in_def = 0;
- char *attribute_class;
- STRING_LIST *classes;
-
- char *associated_content
- = html_get_associated_formatted_inline_content (self, element, 0);
-
- text_init (&content_text);
-
- if (associated_content)
- {
- text_append (&content_text, associated_content);
- free (associated_content);
- }
- if (content)
- text_append (&content_text, content);
-
- if (content_text.end <= 0)
- {
- free (content_text.text);
- return;
- }
-
- in_format_cmd = html_top_block_command (self);
- if (in_format_cmd == CM_multitable)
- {
- const char *p = content_text.text;
- p += strspn (p, whitespace_chars);
- trimmed_content = trim_trailing_content (p);
- free (content_text.text);
- }
- else
- trimmed_content = content_text.text;
-
- if (html_in_string (self))
- {
- text_append (result, trimmed_content);
- free (trimmed_content);
- return;
- }
-
- /* menu_entry_description is always in a preformatted container
- in the tree, as the whole menu is meant to be an
- environment where spaces and newlines are preserved. */
- if (element->parent && element->parent->type == ET_menu_entry_description)
- {
- if (!html_inside_preformatted (self))
- {
- /* If not in preformatted block command,
- we don't preserve spaces and newlines in menu_entry_description,
- instead the whole menu_entry is in a table, so no <pre> in that situation
- */
- text_append (result, trimmed_content);
- free (trimmed_content);
- return;
- }
- else
- {
- /* if directly in description, we want to avoid the linebreak that
- comes with pre being a block level element, so set a special class */
- pre_class = strdup ("menu-entry-description-preformatted");
- }
- }
-
- if (!pre_class)
- pre_class = preformatted_class (self);
-
- /* this may happen with lines without textual content
- between a def* and def*x. */
- if (element->parent)
- {
- enum command_id p_cmd = element_builtin_cmd (element->parent);
- if (builtin_command_data[p_cmd].flags & CF_def || p_cmd == CM_defblock)
- {
- in_def = 1;
- text_append_n (result, "<dd>", 4);
- }
- }
-
- classes = new_string_list ();
- if (pre_class)
- {
- add_string (pre_class, classes);
- free (pre_class);
- }
- attribute_class = html_attribute_class (self, "pre", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- free (attribute_class);
- destroy_strings_list (classes);
-
- /* a newline immediately after a <pre> is ignored. */
- if (trimmed_content[0] == '\n')
- text_append_n (result, "\n", 1);
- text_append (result, trimmed_content);
- free (trimmed_content);
-
- text_append_n (result, "</pre>", 6);
-
- if (in_def)
- text_append_n (result, "</dd>", 5);
-}
-
-void
-html_convert_balanced_braces_type (CONVERTER *self,
- const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- if (content)
- text_append (result, content);
-}
-
-void
-html_convert_index_entry_command_type (CONVERTER *self,
- const enum element_type type,
- const ELEMENT *element,
- const char *content,
- TEXT *result)
-{
- const char *index_id;
-
- if (html_in_string (self) || html_in_multi_expanded (self))
- return;
-
- index_id = html_command_id (self, element);
-
- if (index_id && strlen (index_id))
- {
- format_separate_anchor (self, index_id, "index-entry-id", result);
- if (!html_in_preformatted_context (self))
- text_append_n (result, "\n", 1);
- }
-}
-
-void
-html_convert_definfoenclose_type (CONVERTER *self, const enum element_type
type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- const char *begin = lookup_extra_string (element, AI_key_begin);
- const char *end = lookup_extra_string (element, AI_key_end);
-
- if (begin)
- format_protect_text (self, begin, result);
- if (content)
- text_append (result, content);
- if (end)
- format_protect_text (self, end, result);
-}
-
-void
-html_convert_untranslated_def_line_arg_type
- (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- const char *category_text = element->e.c->contents.list[0]->e.text->text;
- const char *translation_context
- = lookup_extra_string (element, AI_key_translation_context);
- ELEMENT *translated = html_cdt_tree (category_text,
- self, 0, translation_context);
-
- add_tree_to_build (self, translated);
-
- convert_tree_append (self, translated, result,
- "translated TEXT");
-
- remove_tree_to_build (self, translated);
- destroy_element_and_children (translated);
-}
-
-void
-html_convert_row_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- }
-
- if (!content || content[strspn (content, whitespace_chars)] == '\0')
- return;
- else
- {
- text_append_n (result, "<tr>", 4);
- text_append (result, content);
- text_append_n (result, "</tr>", 5);
-
- if (element->e.c->contents.number > 0)
- {
- enum command_id first_cmd
- = element_builtin_cmd (element->e.c->contents.list[0]);
- if (first_cmd != CM_headitem)
- /* if headitem, end of line added in _convert_multitable_head_type */
- text_append (result, "\n");
- }
- }
-}
-
-void
-html_convert_multitable_head_type (CONVERTER *self,
- const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- }
-
- if (!content || content[strspn (content, whitespace_chars)] == '\0')
- return;
- else
- {
- text_append_n (result, "<thead>", 7);
- text_append (result, content);
- text_append_n (result, "</thead>\n", 9);
- }
-}
-
-void
-html_convert_multitable_body_type (CONVERTER *self,
- const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- if (html_in_string (self))
- {
- if (content)
- text_append (result, content);
- }
-
- if (!content || content[strspn (content, whitespace_chars)] == '\0')
- return;
- else
- {
- text_append_n (result, "<tbody>", 7);
- text_append (result, content);
- text_append_n (result, "</tbody>\n", 9);
- }
-}
-
-static char *menu_entry_destination_array[] = {"menu-entry-destination"};
-static const STRING_LIST menu_entry_destination_classes
- = {menu_entry_destination_array, 1, 1};
-static char *menu_entry_description_array[] = {"menu-entry-description"};
-static const STRING_LIST menu_entry_description_classes
- = {menu_entry_description_array, 1, 1};
-
-static void
-menu_entry_a (const CONVERTER *self, const char *href, int isindex,
- int html_menu_entry_index, TEXT *result)
-{
- text_printf (result, "<a href=\"%s\"", href);
- if (isindex)
- text_append_n (result, " rel=\"index\"", 12);
- if (self->conf->USE_ACCESSKEY.o.integer > 0 && html_menu_entry_index < 10)
- text_printf (result, " accesskey=\"%d\"", html_menu_entry_index);
- text_append_n (result, ">", 1);
-}
-
-void
-html_convert_menu_entry_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- const ELEMENT *name_entry = 0;
- const ELEMENT *menu_description = 0;
- ELEMENT *menu_entry_node = 0;
- const ELEMENT *menu_entry_leading_text = 0;
- const ELEMENT *menu_entry_separators[2];
- const ELEMENT *manual_content;
- const ELEMENT *node_description = 0;
- const ELEMENT *section = 0;
- size_t i;
- int entry_separators_nr = 0;
- int entry_separators_idx = 0;
- char *href = 0;
- int isindex = 0;
- int formatted_nodedescription_nr = 0;
- int in_string = html_in_string (self);
- int html_menu_entry_index;
-
- memset (menu_entry_separators, 0, 2 * sizeof (const ELEMENT *));
-
- for (i = 0; i < element->e.c->contents.number; i++)
- {
- ELEMENT *arg = element->e.c->contents.list[i];
- if (arg->type == ET_menu_entry_leading_text)
- menu_entry_leading_text = arg;
- else if (arg->type == ET_menu_entry_name)
- name_entry = arg;
- else if (arg->type == ET_menu_entry_description)
- menu_description = arg;
- else if (arg->type == ET_menu_entry_separator)
- {
- menu_entry_separators[entry_separators_nr] = arg;
- entry_separators_nr++;
- }
- else if (arg->type == ET_menu_entry_node)
- menu_entry_node = arg;
- }
-
- manual_content = lookup_extra_container (menu_entry_node,
- AI_key_manual_content);
-
- if (manual_content)
- href = html_command_href (self, menu_entry_node, 0, element, 0);
- else
- {
- /* may not be defined in case of menu entry node consisting only of spaces */
- const char *normalized = lookup_extra_string (menu_entry_node,
- AI_key_normalized);
- if (normalized)
- {
- const ELEMENT *node
- = find_identifier_target (&self->document->identifiers_target,
- normalized);
- if (node)
- {
- node_description
- = lookup_extra_element (node, AI_key_node_description);
-
- /* if !NODE_NAME_IN_MENU, we pick the associated section, except if
- the node is the element command */
- if (self->conf->NODE_NAME_IN_MENU.o.integer <= 0)
- {
- const ELEMENT *associated_section = lookup_extra_element
(node,
-
AI_key_associated_section);
- if (associated_section)
- {
- const ELEMENT *associated_command
- = html_command_root_element_command (self, node);
- if (associated_command != node)
- {
- section = associated_section;
- href = html_command_href (self, section,
- 0, element, 0);
- }
- }
- }
- if (!href)
- href = html_command_href (self, node, 0, element, 0);
-
- /* will mark the target as an index with rel index. See
- http://microformats.org/wiki/existing-rel-values#HTML5_link_type_extensions
- */
- isindex = (node->flags & EF_isindex);
-
- if (node_description
- /* not menu_description probably cannot happen */
- && (!menu_description
- /* empty description */
- || (menu_description->e.c->contents.number <= 0
- || (menu_description->e.c->contents.number == 1
- &&
(menu_description->e.c->contents.list[0]->e.c->contents.number <= 0
- ||
(menu_description->e.c->contents.list[0]->e.c->contents.number == 1
- &&
menu_description->e.c->contents.list[0]->e.c->contents.list[0]->type ==
ET_normal_text
- &&
menu_description->e.c->contents.list[0]->e.c->contents.list[0]->e.text->text[
- strspn
(menu_description->e.c->contents.list[0]->e.c->contents.list[0]->e.text->text,
- whitespace_chars)] == '\0'))))))
- {
- /* update the number of time the node description was formatted */
- HTML_TARGET *target_info
- = html_get_target (self, node);
- target_info->formatted_nodedescription_nr++;
- formatted_nodedescription_nr
- = target_info->formatted_nodedescription_nr;
- }
- }
- }
- }
- self->shared_conversion_state.html_menu_entry_index++;
- html_menu_entry_index = self->shared_conversion_state.html_menu_entry_index;
-
- if (html_inside_preformatted (self) || in_string)
- {
- const char *leading_text = menu_entry_leading_text->e.text->text;
- const char *menu_symbol;
- if (!in_string)
- {
- char *pre_class = preformatted_class (self);
- char *attribute_class;
- STRING_LIST *classes = new_string_list ();
- if (pre_class)
- {
- add_string (pre_class, classes);
- free (pre_class);
- }
- attribute_class = html_attribute_class (self, "pre", classes);
- text_append (result, attribute_class);
- text_append_n (result, ">", 1);
- free (attribute_class);
- destroy_strings_list (classes);
- }
-
- /* add leading text, replacing "*" by MENU_SYMBOL */
- menu_symbol = strchr (leading_text, '*');
- if (menu_symbol - leading_text > 0)
- {
- text_append_n (result, leading_text, menu_symbol - leading_text);
- leading_text = menu_symbol;
- }
- if (self->conf->MENU_SYMBOL.o.string)
- text_append (result, self->conf->MENU_SYMBOL.o.string);
- /* past "*" */
- leading_text++;
- text_append (result, leading_text);
-
- if (name_entry)
- {
- convert_tree_append (self, name_entry, result,
- "menu_arg menu_entry_name preformatted");
- convert_tree_append (self,
- menu_entry_separators[entry_separators_idx],
- result, "menu_arg name separator preformatted");
- entry_separators_idx++;
- }
-
- if (menu_entry_node)
- {
- ELEMENT *root_code = new_element (ET__code);
- if (!in_string && href)
- {
- menu_entry_a (self, href, isindex, html_menu_entry_index,
- result);
- }
-
- add_to_contents_as_array (root_code, menu_entry_node);
-
- add_tree_to_build (self, root_code);
-
- convert_tree_append (self, root_code, result,
- "menu_arg menu_entry_node preformatted");
-
- remove_tree_to_build (self, root_code);
-
- destroy_element (root_code);
-
- if (!in_string && href)
- text_append_n (result, "</a>", 4);
- }
-
- if (entry_separators_idx < entry_separators_nr)
- {
- convert_tree_append (self,
- menu_entry_separators[entry_separators_idx],
- result, "menu_arg node separator preformatted");
- entry_separators_idx++;
- }
-
- if (!in_string)
- text_append_n (result, "</pre>", 6);
-
- if (formatted_nodedescription_nr > 0)
- {
- char *multiple_formatted = 0;
- char *description;
- ELEMENT *description_element;
- if (formatted_nodedescription_nr > 1)
- {
- xasprintf (&multiple_formatted,
- "preformatted-node-description-%d",
- formatted_nodedescription_nr);
- }
-
- if (node_description->e.c->cmd == CM_nodedescription)
- description_element = node_description->e.c->args.list[0];
- else
- {
- description_element = new_element (ET_NONE);
- description_element->e.c->contents =
node_description->e.c->contents;
- add_tree_to_build (self, description_element);
- }
-
- description
- = convert_tree_new_formatting_context (self, description_element,
- "menu_arg node description preformatted", multiple_formatted,
- 0, CM_menu);
-
- if (description)
- {
- text_append (result, description);
- free (description);
- }
-
- if (formatted_nodedescription_nr > 1)
- free (multiple_formatted);
- if (node_description->e.c->cmd != CM_nodedescription)
- {
- remove_tree_to_build (self, description_element);
- description_element->e.c->contents.list = 0;
- destroy_element (description_element);
- }
- }
- else if (menu_description)
- {
- convert_tree_append (self, menu_description, result,
- "menu_arg description preformatted");
- }
- }
- else
- {
- char *description = 0;
- char *name_no_number = 0;
- text_append_n (result, "<tr>", 4);
- open_element_with_class (self, "td",
- &menu_entry_destination_classes, result);
-
- if (section && href)
- {
- char *name = html_command_text (self, section, 0);
- if (name && strlen (name))
- {
- name_no_number = html_command_text (self, section,
- HTT_text_nonumber);
- menu_entry_a (self, href, isindex, html_menu_entry_index,
- result);
- text_append (result, name);
- text_append_n (result, "</a>", 4);
- }
- free (name);
- }
- if (!name_no_number)
- {
- char *name = 0;
- if (name_entry)
- {
- name = html_convert_tree (self, name_entry,
- "convert menu_entry_name");
- if (name)
- {
- if (!strlen (name))
- {
- free (name);
- name = 0;
- }
- }
- }
- if (!name)
- {
- const ELEMENT *manual_content
- = lookup_extra_container (menu_entry_node,
- AI_key_manual_content);
- ELEMENT *node_content
- = lookup_extra_container (menu_entry_node,
- AI_key_node_content);
- if (manual_content)
- {
- name = html_command_text (self, menu_entry_node, 0);
- }
- else if (node_content)
- {
- ELEMENT *root_code = new_element (ET__code);
-
- add_to_contents_as_array (root_code, node_content);
-
- add_tree_to_build (self, root_code);
-
- name = html_convert_tree (self, root_code,
- "menu_arg name");
-
- remove_tree_to_build (self, root_code);
-
- destroy_element (root_code);
- }
- }
-
- if (self->conf->MENU_SYMBOL.o.string)
- text_append (result, self->conf->MENU_SYMBOL.o.string);
- text_append_n (result, " ", 1);
-
- if (href)
- {
- menu_entry_a (self, href, isindex, html_menu_entry_index,
- result);
- }
-
- if (name)
- {
- size_t n = strspn (name, whitespace_chars);
- if (n)
- {
- name_no_number = strdup (name + n);
- free (name);
- }
- else
- name_no_number = name;
-
- text_append (result, name_no_number);
- }
-
- if (href)
- text_append_n (result, "</a>", 4);
- }
-
- if (self->conf->MENU_ENTRY_COLON.o.string)
- text_append (result, self->conf->MENU_ENTRY_COLON.o.string);
- text_append_n (result, "</td>", 5);
-
- open_element_with_class (self, "td",
- &menu_entry_description_classes, result);
-
- if (formatted_nodedescription_nr > 0)
- {
- char *multiple_formatted = 0;
- ELEMENT *description_element;
- if (formatted_nodedescription_nr > 1)
- {
- xasprintf (&multiple_formatted,
- "node-description-%d",
- formatted_nodedescription_nr);
- }
-
- if (node_description->e.c->cmd == CM_nodedescription)
- description_element = node_description->e.c->args.list[0];
- else
- {
- description_element = new_element (ET_NONE);
- description_element->e.c->contents =
node_description->e.c->contents;
- add_tree_to_build (self, description_element);
- }
-
- description
- = convert_tree_new_formatting_context (self, description_element,
- "menu_arg node description", multiple_formatted,
- 0, CM_menu);
-
- if (formatted_nodedescription_nr > 1)
- free (multiple_formatted);
- if (node_description->e.c->cmd != CM_nodedescription)
- {
- remove_tree_to_build (self, description_element);
- description_element->e.c->contents.list = 0;
- destroy_element (description_element);
- }
- }
- else if (menu_description)
- {
- description = html_convert_tree (self, menu_description,
- "menu_arg description");
- }
-
- if (description)
- {
- text_append (result, description);
- free (description);
- }
-
- free (name_no_number);
- text_append_n (result, "</td></tr>\n", 11);
- }
-
- free (href);
-}
-
-static char *menu_comment_array[] = {"menu-comment"};
-static const STRING_LIST menu_comment_classes = {menu_comment_array, 1, 1};
-
-void
-html_convert_menu_comment_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- char *attribute_class;
-
- if (html_inside_preformatted (self) || html_in_string (self))
- {
- if (content)
- text_append (result, content);
- return;
- }
-
- text_append_n (result, "<tr>", 4);
- attribute_class = html_attribute_class (self, "th",
- &menu_comment_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, " colspan=\"2\">", 13);
-
- if (content)
- text_append (result, content);
-
- text_append_n (result, "</th></tr>", 10);
-}
-
-void
-html_convert_before_item_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- enum command_id in_format_cmd;
-
- if (!content || content[strspn (content, whitespace_chars)] == '\0')
- return;
-
- if (html_in_string (self))
- {
- text_append (result, content);
- return;
- }
-
- in_format_cmd = html_top_block_command (self);
-
- if (in_format_cmd == CM_itemize || in_format_cmd == CM_enumerate)
- {
- text_append_n (result, "<li>", 4);
- text_append (result, content);
- text_append_n (result, "</li>", 5);
- }
- else if (in_format_cmd == CM_table || in_format_cmd == CM_vtable
- || in_format_cmd == CM_ftable)
- {
- text_append_n (result, "<dd>", 4);
- text_append (result, content);
- text_append_n (result, "</dd>\n", 6);
- }
- else if (in_format_cmd == CM_multitable)
- {
- char *trimmed_content;
- const char *p = content;
- p += strspn (p, whitespace_chars);
- trimmed_content = trim_trailing_content (p);
-
- text_append_n (result, "<tr><td>", 8);
- text_append (result, trimmed_content);
- free (trimmed_content);
- text_append_n (result, "</td></tr>\n", 11);
- }
-}
-
-void
-html_convert_table_term_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- if (content)
- {
- text_append (result, "<dt>");
- text_append (result, content);
- }
-}
-
-#define static_class(name, class) \
-static char * name ##_array[] = {#class}; \
-static const STRING_LIST name ##_classes = {name ##_array, 1, 1};
-
-static_class(def_type, def-type)
-static_class(def_name, def-name)
-static_class(def_code_arguments, def-code-arguments)
-static_class(def_var_arguments, def-var-arguments)
-static_class(call_def, call-def)
-static_class(category_def, category-def)
-
-#undef static_class
-
-void
-html_convert_def_line_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- const char *index_id;
- PARSED_DEF *parsed_def;
- STRING_LIST *classes;
- char *attribute_class;
- char *alias_class = 0;
- enum command_id original_def_cmd;
- enum command_id def_cmd;
- enum command_id original_cmd = 0;
- enum command_id base_cmd = 0;
- TEXT def_call;
- char *anchor;
-
- if (html_in_string (self))
- {
- /* should probably never happen */
- char *text;
- text = convert_to_text (element, self->convert_text_options);
- format_protect_text (self, text, result);
- free (text);
- }
-
- index_id = html_command_id (self, element);
-
- parsed_def = definition_arguments_content (element);
-
- if (element->e.c->cmd)
- original_def_cmd = element->e.c->cmd;
- else
- original_def_cmd = element->parent->e.c->cmd;
-
- if (builtin_command_data[original_def_cmd].flags & CF_def_alias)
- {
- int i;
- for (i = 0; def_aliases[i].alias ; i++)
- {
- if (def_aliases[i].alias == original_def_cmd)
- {
- original_cmd = def_aliases[i].command;
- break;
- }
- }
-
- xasprintf (&alias_class, "%s-alias-%s",
- builtin_command_name (original_def_cmd),
- builtin_command_name (original_cmd));
- }
- else
- original_cmd = original_def_cmd;
-
- /* parent is defblock, we do not put it in class */
- if (element->e.c->cmd == CM_defline || element->e.c->cmd == CM_deftypeline)
- def_cmd = element->e.c->cmd;
- else
- /* the parent is the def both for def* def_line and def*x */
- def_cmd = element->parent->e.c->cmd;
-
- if (builtin_command_data[def_cmd].flags & CF_def_alias)
- {
- int i;
- for (i = 0; def_aliases[i].alias ; i++)
- {
- if (def_aliases[i].alias == def_cmd)
- {
- base_cmd = def_aliases[i].command;
- break;
- }
- }
- }
- else
- base_cmd = def_cmd;
-
- classes = new_string_list ();
-
- add_string (builtin_command_name (original_cmd), classes);
- if (alias_class)
- {
- add_string (alias_class, classes);
- free (alias_class);
- }
- if (base_cmd != original_cmd)
- {
- char *class;
- xasprintf (&class, "def-cmd-%s", builtin_command_name (base_cmd));
- add_string (class, classes);
- free (class);
- }
-
- add_string ("def-line", classes);
-
- text_init (&def_call);
- text_append (&def_call, "");
- if (parsed_def->type)
- {
- char *type_text;
- size_t type_text_len;
- ELEMENT *root_code = new_element (ET__code);
- char *explanation;
-
- xasprintf (&explanation, "DEF_TYPE %s", builtin_command_name (def_cmd));
-
- add_to_contents_as_array (root_code, parsed_def->type);
-
- add_tree_to_build (self, root_code);
-
- type_text = html_convert_tree (self, root_code, explanation);
-
- remove_tree_to_build (self, root_code);
-
- destroy_element (root_code);
- free (explanation);
-
- type_text_len = strlen (type_text);
-
- if (type_text_len > 0)
- {
- char *attribute_class = html_attribute_class (self, "code",
- &def_type_classes);
- text_append (&def_call, attribute_class);
- free (attribute_class);
- text_append_n (&def_call, ">", 1);
- text_append_n (&def_call, type_text, type_text_len);
- text_append_n (&def_call, "</code>", 7);
- }
- if ((base_cmd == CM_deftypefn || base_cmd == CM_deftypeop)
- && self->conf->deftypefnnewline.o.string
- && !strcmp (self->conf->deftypefnnewline.o.string, "on"))
- {
- text_append_n (&def_call, self->line_break_element.string,
- self->line_break_element.len);
- text_append_n (&def_call, " ", 1);
- }
- else if (type_text_len > 0)
- text_append_n (&def_call, " ", 1);
- free (type_text);
- }
-
- if (parsed_def->name)
- {
- char *attribute_class = html_attribute_class (self, "strong",
- &def_name_classes);
- char *explanation;
- xasprintf (&explanation, "DEF_NAME %s", builtin_command_name (def_cmd));
-
- ELEMENT *root_code = new_element (ET__code);
-
- add_to_contents_as_array (root_code, parsed_def->name);
-
- add_tree_to_build (self, root_code);
-
- text_append (&def_call, attribute_class);
- free (attribute_class);
- text_append_n (&def_call, ">", 1);
-
- convert_tree_append (self, root_code, &def_call, explanation);
-
- remove_tree_to_build (self, root_code);
- destroy_element (root_code);
-
- text_append_n (&def_call, "</strong>", 9);
- free (explanation);
- }
-
- if (parsed_def->args)
- {
- char *args_formatted;
- char *explanation;
- xasprintf (&explanation, "DEF_ARGS %s", builtin_command_name (def_cmd));
- /* arguments not only metasyntactic variables
- (deftypefn, deftypevr, deftypeop, deftypecv) */
- /* Texinfo::Common::def_no_var_arg_commands{$base_command_name} */
- if (strlen (builtin_command_name (base_cmd)) >= 7
- && !memcmp (builtin_command_name (base_cmd), "deftype", 7))
- {
- ELEMENT *root_code = new_element (ET__code);
-
- add_to_contents_as_array (root_code, parsed_def->args);
-
- add_tree_to_build (self, root_code);
-
- args_formatted = html_convert_tree (self, root_code, explanation);
-
- remove_tree_to_build (self, root_code);
- destroy_element (root_code);
-
- if (args_formatted[strspn (args_formatted, whitespace_chars)] !=
'\0')
- {
- char *attribute_class = html_attribute_class (self, "code",
- &def_code_arguments_classes);
- int omit_def_name_space = (element->flags &
EF_omit_def_name_space);
- if (!omit_def_name_space)
- text_append_n (&def_call, " ", 1);
- text_append (&def_call, attribute_class);
- free (attribute_class);
- text_append_n (&def_call, ">", 1);
- text_append (&def_call, args_formatted);
- text_append_n (&def_call, "</code>", 7);
- }
- }
- else
- {
- html_set_code_context (self, 0);
- args_formatted = html_convert_tree (self, parsed_def->args,
- explanation);
- html_pop_code_context (self);
- if (args_formatted[strspn (args_formatted, whitespace_chars)] !=
'\0')
- {
- char *attribute_class = html_attribute_class (self, "var",
- &def_var_arguments_classes);
- int omit_def_name_space = (element->flags &
EF_omit_def_name_space);
- if (!omit_def_name_space)
- text_append_n (&def_call, " ", 1);
- text_append (&def_call, attribute_class);
- free (attribute_class);
- text_append_n (&def_call, ">", 1);
- text_append (&def_call, args_formatted);
- text_append_n (&def_call, "</var>", 6);
- }
- }
- free (explanation);
- free (args_formatted);
- }
-
- if (self->conf->DEF_TABLE.o.integer > 0)
- {
- ELEMENT *category_tree
- = definition_category_tree (self->conf, element);
-
- attribute_class = html_attribute_class (self, "tr", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
- if (index_id && strlen (index_id) && !html_in_multi_expanded (self))
- text_printf (result, " id=\"%s\"", index_id);
- text_append_n (result, ">", 1);
-
- attribute_class = html_attribute_class (self, "td",
- &call_def_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">", 1);
- text_append_n (result, def_call.text, def_call.end);
- free (def_call.text);
- text_append_n (result, "</td>", 5);
-
- attribute_class = html_attribute_class (self, "td",
- &category_def_classes);
- text_append (result, attribute_class);
- free (attribute_class);
- text_append_n (result, ">[", 2);
-
- if (category_tree)
- {
- add_tree_to_build (self, category_tree);
- convert_tree_append (self, category_tree, result, 0);
- remove_tree_to_build (self, category_tree);
- destroy_element_and_children (category_tree);
- }
- text_append_n (result, "]</td></tr>\n", 12);
-
- destroy_parsed_def (parsed_def);
- return;
- }
-
- attribute_class = html_attribute_class (self, "dt", classes);
- destroy_strings_list (classes);
- text_append (result, attribute_class);
- free (attribute_class);
- if (index_id && strlen (index_id) && !html_in_multi_expanded (self))
- text_printf (result, " id=\"%s\"", index_id);
- text_append_n (result, ">", 1);
-
- if (parsed_def->category)
- {
- ELEMENT *category_tree = 0;
- NAMED_STRING_ELEMENT_LIST *substrings
- = new_named_string_element_list ();
- ELEMENT *category_copy = copy_tree (parsed_def->category);
-
- add_element_to_named_string_element_list (substrings,
- "category", category_copy);
- if (parsed_def->class)
- {
- ELEMENT *class_copy = copy_tree (parsed_def->class);
- add_element_to_named_string_element_list (substrings,
- "class", class_copy);
-
- if (base_cmd == CM_deftypeop && parsed_def->type
- && self->conf->deftypefnnewline.o.string
- && !strcmp (self->conf->deftypefnnewline.o.string, "on"))
- {
- category_tree
- = html_cdt_tree ("{category} on @code{{class}}:@* ",
- self, substrings, 0);
- }
- else if (base_cmd == CM_defop || base_cmd == CM_deftypeop)
- {
- category_tree
- = html_cdt_tree ("{category} on @code{{class}}: ",
- self, substrings, 0);
- }
- else if (base_cmd == CM_defcv || base_cmd == CM_deftypecv)
- {
- category_tree
- = html_cdt_tree ("{category} of @code{{class}}: ",
- self, substrings, 0);
- }
- }
+ if (target_info->command_description[type])
+ return strdup (target_info->command_description[type]);
else
{
- if ((base_cmd == CM_deftypefn || base_cmd == CM_deftypeop)
- && parsed_def->type
- && self->conf->deftypefnnewline.o.string
- && !strcmp (self->conf->deftypefnnewline.o.string, "on"))
- {
- category_tree
- = html_cdt_tree ("{category}:@* ",
- self, substrings, 0);
- }
- else
- {
- category_tree
- = html_cdt_tree ("{category}: ",
- self, substrings, 0);
- }
- }
- destroy_named_string_element_list (substrings);
-
- if (category_tree)
- {
- char *attribute_open = html_attribute_class (self, "span",
- &category_def_classes);
- size_t open_len = strlen (attribute_open);
+ const ELEMENT *node = 0;
+ ELEMENT *tree_root;
char *explanation;
+ char *context_name;
+ const ELEMENT *node_description;
+ int formatted_nodedescription_nr = 0;
+ HTML_TARGET *node_target_info;
+ char *multiple_formatted = 0;
+ ELEMENT *description_element;
+ const char *command_name;
+ enum command_id cmd = element_builtin_cmd (command);
- xasprintf (&explanation, "DEF_CATEGORY %s",
- builtin_command_name (def_cmd));
-
- if (open_len)
- {
- text_append_n (result, attribute_open, open_len);
- text_append_n (result, ">", 1);
- }
- free (attribute_open);
- add_tree_to_build (self, category_tree);
- convert_tree_append (self, category_tree, result, explanation);
- remove_tree_to_build (self, category_tree);
- destroy_element_and_children (category_tree);
- if (open_len)
- text_append_n (result, "</span>", 7);
- free (explanation);
- }
- }
-
- destroy_parsed_def (parsed_def);
-
- anchor = get_copiable_anchor (self, index_id);
-
- if (anchor)
- text_append_n (result, "<span>", 6);
-
- text_append_n (result, def_call.text, def_call.end);
- free (def_call.text);
- if (anchor)
- {
- text_append (result, anchor);
- text_append_n (result, "</span>", 7);
- }
-
- text_append_n (result, "</dt>\n", 6);
-
- free (anchor);
-}
-
-void
-html_convert_def_item_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, const char *content,
- TEXT *result)
-{
- if (!content)
- return;
-
- if (html_in_string (self))
- text_append (result, content);
-
- if (content[strspn (content, whitespace_chars)] == '\0')
- return;
-
- if (self->conf->DEF_TABLE.o.integer <= 0)
- {
- text_append_n (result, "<dd>", 4);
- text_append (result, content);
- text_append_n (result, "</dd>", 5);
- }
- else
- {
- text_append_n (result, "<tr><td colspan=\"2\">", 20);
- text_append (result, content);
- text_append_n (result, "</td></tr>", 10);
- }
-}
-
-void
-html_convert_table_definition_type (CONVERTER *self,
- const enum element_type type,
- const ELEMENT *element, const char
*content,
- TEXT *result)
-{
- if (!content)
- return;
-
- if (html_in_string (self))
- text_append (result, content);
-
- if (content[strspn (content, whitespace_chars)] == '\0')
- return;
-
- text_append_n (result, "<dd>", 4);
- text_append (result, content);
- text_append_n (result, "</dd>\n", 6);
-}
-
-
-void
-html_type_open_external (CONVERTER *self, enum element_type type,
- const ELEMENT *element, TEXT *result)
-{
- if (self->types_open[type].status > 0)
- call_types_open (self, type, element, result);
-}
-
-void
-html_open_inline_container_type (CONVERTER *self, const enum element_type type,
- const ELEMENT *element, TEXT *result)
-{
- char *pending_formatted = html_get_pending_formatted_inline_content (self);
- if (pending_formatted)
- {
- html_associate_pending_formatted_inline_content (self, element, 0,
- pending_formatted);
- free (pending_formatted);
- }
-}
-
-void
-html_output_unit_conversion_external (CONVERTER *self,
- const enum output_unit_type unit_type,
- const OUTPUT_UNIT *output_unit, const char *content,
- TEXT *result)
-{
- if (self->output_units_conversion[unit_type].status > 0)
- call_output_units_conversion (self, unit_type, output_unit, content,
- result);
-}
-
-void
-html_convert_unit_type (CONVERTER *self, const enum output_unit_type unit_type,
- const OUTPUT_UNIT *output_unit, const char *content,
- TEXT *result)
-{
- STRING_LIST *closed_strings;
- const ELEMENT *unit_command;
-
- if (html_in_string (self))
- return;
-
- if (!output_unit->tree_unit_directions[D_prev])
- {
- text_append (result, self->title_titlepage);
- if (!output_unit->tree_unit_directions[D_next])
- {
- /* only one unit, use simplified formatting */
- if (content)
- text_append (result, content);
- /* if there is one unit it also means that there is no formatting
- of footnotes in a separate unit. And if footnotestyle is end
- the footnotes won't be done in format_element_footer either. */
- format_footnotes_segment (self, result);
- if (self->conf->DEFAULT_RULE.o.string
- && self->conf->PROGRAM_NAME_IN_FOOTER.o.integer > 0)
- {
- text_append (result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (result, "\n", 1);
- }
-
- /* do it here, as it is won't be done at end of page in
- format_element_footer */
- closed_strings = html_close_registered_sections_level (self,
- self->current_filename.file_number, 0);
-
- if (closed_strings->number)
- {
- size_t i;
- for (i = 0; i < closed_strings->number; i++)
- {
- text_append (result, closed_strings->list[i]);
- free (closed_strings->list[i]);
- }
- free (closed_strings->list);
- }
- free (closed_strings);
- return;
- }
- }
-
- if (content)
- text_append (result, content);
-
- unit_command = output_unit->uc.unit_command;
-
- format_element_footer (self, unit_type, output_unit, content, unit_command,
- result);
-}
-
-void
-html_convert_special_unit_type (CONVERTER *self,
- const enum output_unit_type unit_type,
- const OUTPUT_UNIT *output_unit,
- const char *content,
- TEXT *result)
-{
- char *heading;
- size_t number;
- TEXT special_unit_body;
- const ELEMENT *unit_command;
- const char *id;
- const char *class_base;
- char *attribute_class;
- char *class;
- STRING_LIST *classes;
-
- const char *special_unit_variety;
- STRING_LIST *closed_strings;
- size_t count_in_file = 0;
- int level;
-
- if (html_in_string (self))
- return;
-
- special_unit_variety = output_unit->special_unit_variety;
- number = find_string (&self->special_unit_varieties,
- special_unit_variety);
-
- closed_strings = html_close_registered_sections_level (self,
- self->current_filename.file_number, 0);
-
- if (closed_strings->number)
- {
- size_t i;
- for (i = 0; i < closed_strings->number; i++)
- {
- text_append (result, closed_strings->list[i]);
- free (closed_strings->list[i]);
- }
- free (closed_strings->list);
- }
- free (closed_strings);
-
- text_init (&special_unit_body);
- text_append (&special_unit_body, "");
-
- (*self->special_unit_body_formatting[number -1].special_unit_body_formatting)
- (self, number, special_unit_variety, output_unit, &special_unit_body);
-
- /* This may happen with footnotes in regions that are not expanded,
- like @copying or @titlepage */
- if (special_unit_body.end == 0)
- {
- free (special_unit_body.text);
- return;
- }
-
- classes = new_string_list ();
-
- unit_command = output_unit->uc.special_unit_command;
- id = html_command_id (self, unit_command);
- class_base = html_special_unit_info (self, SUI_type_class,
- special_unit_variety);
- xasprintf (&class, "element-%s", class_base);
+ if (command->type == ET_special_unit_element)
+ return 0;
- add_string (class, classes);
- free (class);
- attribute_class = html_attribute_class (self, "div", classes);
- clear_strings_list (classes);
+ if (cmd == CM_float || cmd == CM_anchor)
+ return 0;
- text_append (result, attribute_class);
- free (attribute_class);
+ if (cmd == CM_node)
+ node = command;
+ else
+ node = lookup_extra_element (command, AI_key_associated_node);
- if (id && strlen (id))
- text_printf (result, " id=\"%s\"", id);
- text_append (result, ">\n");
+ if (!node)
+ return 0;
- if (output_unit->unit_filename)
- {
- size_t file_index = self->special_unit_file_indices[output_unit->index];
- count_in_file
- = count_elements_in_file_number (self, CEFT_current, file_index +1);
- }
+ node_description
+ = lookup_extra_element (node, AI_key_node_description);
- if (self->conf->HEADERS.o.integer > 0
- /* first in page */
- || count_in_file == 1)
- {
- format_navigation_header (self, self->conf->MISC_BUTTONS.o.buttons, 0,
- unit_command, result);
- }
+ if (!node_description)
+ return 0;
- heading = html_command_text (self, unit_command, 0);
- level = self->conf->CHAPTER_HEADER_LEVEL.o.integer;
- if (!strcmp (special_unit_variety, "footnotes"))
- level = self->conf->FOOTNOTE_SEPARATE_HEADER_LEVEL.o.integer;
+ node_target_info = html_get_target (self, node);
+ node_target_info->formatted_nodedescription_nr++;
+ formatted_nodedescription_nr
+ = node_target_info->formatted_nodedescription_nr;
- xasprintf (&class, "%s-heading", class_base);
+ if (formatted_nodedescription_nr > 1)
+ {
+ xasprintf (&multiple_formatted,
+ "node-description-%d",
+ formatted_nodedescription_nr);
+ }
- add_string (class, classes);
- free (class);
+ if (node_description->e.c->cmd == CM_nodedescription)
+ description_element = node_description->e.c->args.list[0];
+ else
+ {
+ description_element = new_element (ET_NONE);
+ description_element->e.c->contents
+ = node_description->e.c->contents;
+ add_tree_to_build (self, description_element);
+ }
- format_heading_text (self, 0, classes, heading, level, 0, 0, 0, result);
- free (heading);
- destroy_strings_list (classes);
- text_append_n (result, "\n", 1);
+ command_name = element_command_name (command);
+ xasprintf (&context_name, "%s description", command_name);
+ xasprintf (&explanation, "command_description:%s @%s",
+ html_command_text_type_name[type],
+ command_name);
- text_append (result, special_unit_body.text);
- free (special_unit_body.text);
- text_append (result, "</div>");
+ if (type == HTT_string)
+ {
+ tree_root = new_element (ET__string);
+ add_to_contents_as_array (tree_root, description_element);
+ add_tree_to_build (self, tree_root);
+ }
+ else
+ tree_root = description_element;
- format_element_footer (self, unit_type, output_unit, content, unit_command,
- result);
-}
+ target_info->command_description[type]
+ = convert_tree_new_formatting_context (self, tree_root,
+ context_name, multiple_formatted,
+ explanation, 0);
+ free (context_name);
+ free (explanation);
-void
-contents_shortcontents_in_title (CONVERTER *self, TEXT *result)
-{
- if (self->document->sections_list
- && self->document->sections_list->number > 0
- && self->conf->CONTENTS_OUTPUT_LOCATION.o.string
- && !strcmp (self->conf->CONTENTS_OUTPUT_LOCATION.o.string,
"after_title"))
- {
- enum command_id contents_cmds[2] = {CM_shortcontents, CM_contents};
- int i;
- for (i = 0; i < 2; i++)
- {
- int contents_set = 0;
- enum command_id cmd = contents_cmds[i];
- const OPTION *contents_option_ref
- = get_command_option (self->conf, cmd);
- if (contents_option_ref->o.integer > 0)
- contents_set = 1;
- if (contents_set)
+ if (formatted_nodedescription_nr > 1)
+ free (multiple_formatted);
+ if (node_description->e.c->cmd != CM_nodedescription)
{
- char *contents_text
- = contents_inline_element (self, cmd, 0);
- if (contents_text)
- {
- text_append (result, contents_text);
- if (self->conf->DEFAULT_RULE.o.string)
- {
- text_append (result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (result, "\n", 1);
- }
- free (contents_text);
- }
+ remove_tree_to_build (self, description_element);
+ description_element->e.c->contents.list = 0;
+ destroy_element (description_element);
+ }
+ if (type == HTT_string)
+ {
+ remove_tree_to_build (self, tree_root);
+ destroy_element (tree_root);
}
+ return strdup (target_info->command_description[type]);
}
}
+ /*
+ Can happen
+ * if USE_NODES is 0 and there are no sectioning commands.
+ * if a special element target was set to undef in user defined code.
+ * for @*ref with missing targets (maybe @novalidate needed in that case).
+ * for @node header if the node consist only in spaces (example in
sectioning
+ in_menu_only_special_ascii_spaces_node).
+ * for multiple targets with the same name, eg both @node and @anchor
+ * with @inforef with node argument only, without manual argument.
+ */
+ return 0;
}
-static void
-format_simpletitle (CONVERTER *self, TEXT *result)
+/* return string to be freed by the caller */
+static char *
+convert_string_tree_new_formatting_context (CONVERTER *self, ELEMENT *tree,
+ const char *context_string, const char *multiple_pass)
{
- char *title_text;
- char *context_str;
- enum command_id cmd = self->simpletitle_cmd;
-
- STRING_LIST *classes = new_string_list ();
- add_string (builtin_command_name (cmd), classes);
-
- xasprintf (&context_str, "%s simpletitle",
- builtin_command_name (cmd));
- title_text
- = convert_tree_new_formatting_context (self,
- self->simpletitle_tree, context_str, 0, 0, 0);
- free (context_str);
- format_heading_text (self, cmd, classes, title_text,
- 0, 0, 0, 0, result);
- destroy_strings_list (classes);
- free (title_text);
-}
+ ELEMENT *tree_root_string = new_element (ET__string);
+ char *result;
-/* Convert @titlepage. Falls back to simpletitle. */
-char *
-html_default_format_titlepage (CONVERTER *self)
-{
- int titlepage_text = 0;
- TEXT result;
- text_init (&result);
- text_append (&result, "");
- if (self->document->global_commands.titlepage)
- {
- ELEMENT *tmp = new_element (ET_NONE);
- tmp->e.c->contents =
self->document->global_commands.titlepage->e.c->contents;
- convert_tree_append (self, tmp, &result, "convert titlepage");
- tmp->e.c->contents.list = 0;
- destroy_element (tmp);
- titlepage_text = 1;
- }
- else if (self->simpletitle_tree)
- {
- format_simpletitle (self, &result);
- titlepage_text = 1;
- }
- if (titlepage_text && self->conf->DEFAULT_RULE.o.string)
- {
- text_append (&result, self->conf->DEFAULT_RULE.o.string);
- text_append_n (&result, "\n", 1);
- }
- contents_shortcontents_in_title (self, &result);
- return result.text;
-}
+ add_to_contents_as_array (tree_root_string, tree);
-char *
-format_titlepage (CONVERTER *self)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_titlepage];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_titlepage (self);
- }
- else
- {
- return call_formatting_function_format_titlepage (self,
- formatting_reference);
- }
+ add_tree_to_build (self, tree_root_string);
+
+ result = convert_tree_new_formatting_context (self, tree_root_string,
+ context_string, multiple_pass, 0, 0);
+
+ remove_tree_to_build (self, tree_root_string);
+ destroy_element (tree_root_string);
+ return result;
}
-char *
-html_default_format_title_titlepage (CONVERTER *self)
+void
+default_css_string_format_protect_text (const char *text, TEXT *result)
{
- if (self->conf->SHOW_TITLE.o.integer > 0)
+ const char *p = text;
+
+ while (*p)
{
- if (self->conf->USE_TITLEPAGE_FOR_TITLE.o.integer)
+ int before_sep_nr = strcspn (p, "\\'");
+ if (before_sep_nr)
{
- return format_titlepage (self);
+ text_append_n (result, p, before_sep_nr);
+ p += before_sep_nr;
}
- else
+ if (!*p)
+ break;
+ switch (*p)
{
- TEXT result;
- text_init (&result);
- text_append (&result, "");
-
- if (self->simpletitle_tree)
- format_simpletitle (self, &result);
-
- contents_shortcontents_in_title (self, &result);
- return result.text;
+ case '\\':
+ text_append_n (result, "\\\\", 2);
+ break;
+ case '\'':
+ text_append_n (result, "\\'", 2);
+ break;
}
+ p++;
}
- return strdup ("");
}
+/* NOTE these switches are not done in perl, so the only perl functions
+ that can be called are perl functions that do not call formatting/conversion
+ functions or the formatting/conversion functions for HTML will be used. */
char *
-format_title_titlepage (CONVERTER *self)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_title_titlepage];
- if (formatting_reference->status == FRS_status_default_set
- || formatting_reference->status == FRS_status_none)
- {
- return html_default_format_title_titlepage (self);
- }
- else
- {
- return call_formatting_function_format_title_titlepage (self,
- formatting_reference);
- }
-}
-
-void
-html_special_unit_body_formatting_external (CONVERTER *self,
- const size_t special_unit_number,
- const char *special_unit_variety,
- const OUTPUT_UNIT *output_unit,
- TEXT *result)
-{
- if (self->special_unit_body[special_unit_number -1].status > 0)
- call_special_unit_body_formatting (self, special_unit_number,
- special_unit_variety,
- output_unit, result);
-}
-
-void
-html_default_format_special_body_contents (CONVERTER *self,
- const size_t special_unit_number,
- const char *special_unit_variety,
- const OUTPUT_UNIT *output_unit,
- TEXT *result)
-{
- char *table_of_contents = format_contents (self, CM_contents, 0, 0);
- text_append (result, table_of_contents);
- free (table_of_contents);
-}
-
-void
-html_default_format_special_body_shortcontents (CONVERTER *self,
- const size_t special_unit_number,
- const char *special_unit_variety,
- const OUTPUT_UNIT *output_unit,
- TEXT *result)
-{
- char *shortcontents = format_contents (self, CM_shortcontents, 0, 0);
- text_append (result, shortcontents);
- free (shortcontents);
-}
-
-void
-html_default_format_special_body_footnotes (CONVERTER *self,
- const size_t special_unit_number,
- const char *special_unit_variety,
- const OUTPUT_UNIT *output_unit,
- TEXT *result)
+html_convert_css_string (CONVERTER *self, const ELEMENT *element,
+ const char *context_str)
{
- format_footnotes_sequence (self, result);
-}
-
-static char *direction_about_array[] = {"direction-about"};
-static const STRING_LIST direction_about_classes
- = {direction_about_array, 1, 1};
+ char *css_string_context_str;
+ char *context_string_str;
+ char *explanation;
+ char *result;
-static char *button_direction_about_array[] = {"button-direction-about"};
-static const STRING_LIST button_direction_about_classes
- = {button_direction_about_array, 1, 1};
+ void (* saved_current_format_protect_text) (const char *text, TEXT *result);
+ FORMATTING_REFERENCE *saved_formatting_references
+ = self->current_formatting_references;
+ COMMAND_CONVERSION_FUNCTION *saved_commands_conversion_function
+ = self->current_commands_conversion_function;
+ TYPE_CONVERSION_FUNCTION *saved_types_conversion_function
+ = self->current_types_conversion_function;
+ saved_current_format_protect_text = self->current_format_protect_text;
-static char *name_direction_about_array[] = {"name-direction-about"};
-static const STRING_LIST name_direction_about_classes
- = {name_direction_about_array, 1, 1};
+ self->current_formatting_references
+ = &self->css_string_formatting_references[0];
+ self->current_commands_conversion_function
+ = &self->css_string_command_conversion_function[0];
+ self->current_types_conversion_function
+ = &self->css_string_type_conversion_function[0];
+ self->current_format_protect_text
+ = &html_default_css_string_format_protect_text;
-static char *description_direction_about_array[]
- = {"description-direction-about"};
-static const STRING_LIST description_direction_about_classes
- = {description_direction_about_array, 1, 1};
+ if (context_str)
+ xasprintf (&css_string_context_str, "CSS string %s");
+ else
+ css_string_context_str = "CSS string ";
-static char *example_direction_about_array[] = {"example-direction-about"};
-static const STRING_LIST example_direction_about_classes
- = {example_direction_about_array, 1, 1};
+ xasprintf (&context_string_str, "C(%s)", css_string_context_str);
+ xasprintf (&explanation, "new_fmt_ctx %s", context_string_str);
-void
-html_default_format_special_body_about (CONVERTER *self,
- const size_t special_unit_number,
- const char *special_unit_variety,
- const OUTPUT_UNIT *output_unit,
- TEXT *result)
-{
- size_t i;
- const BUTTON_SPECIFICATION_LIST *buttons
- = self->conf->SECTION_BUTTONS.o.buttons;
+ html_new_document_context (self, css_string_context_str, 0, 0);
+ html_set_string_context (self);
- if (self->conf->PROGRAM_NAME_IN_ABOUT.o.integer > 0)
- {
- text_append_n (result, "<p>\n ", 6);
- format_program_string (self, result);
- text_append_n (result, "\n</p>\n", 6);
- }
+ result = html_convert_tree (self, element, explanation);
- text_append_n (result, "<p>\n", 4);
+ html_pop_document_context (self);
- if (!buttons)
- {
- translate_convert_tree_append (
- "There are no buttons for this document.", self, 0, 0,
- result, "ABOUT");
- text_append_n (result, "\n</p>\n", 6);
- return;
- }
+ free (explanation);
+ free (context_string_str);
+ if (context_str)
+ free (css_string_context_str);
- translate_convert_tree_append (
- " The buttons in the navigation panels have the following meaning:",
- self, 0, 0, result, "ABOUT");
- text_append_n (result, "\n</p>\n", 6);
- open_element_with_class (self, "table", &direction_about_classes, result);
- text_append (result, "\n <tr>\n ");
- open_element_with_class (self, "th", &button_direction_about_classes,
- result);
- text_append_n (result, " ", 1);
- translate_convert_tree_append ("Button", self, 0, 0, result, "ABOUT");
- text_append_n (result, " </th>\n ", 11);
- open_element_with_class (self, "th", &name_direction_about_classes,
- result);
- text_append_n (result, " ", 1);
- translate_convert_tree_append ("Name", self, 0, 0, result, "ABOUT");
- text_append_n (result, " </th>\n ", 11);
- open_element_with_class (self, "th", &description_direction_about_classes,
- result);
- text_append_n (result, " ", 1);
- translate_convert_tree_append ("Go to", self, 0, 0, result, "ABOUT");
- text_append_n (result, " </th>\n ", 11);
- open_element_with_class (self, "th", &example_direction_about_classes,
- result);
- text_append_n (result, " ", 1);
- translate_convert_tree_append ("From 1.2.3 go to", self, 0, 0,
- result, "ABOUT");
- text_append (result, "</th>\n </tr>\n");
-
- for (i = 0; i < buttons->number; i++)
- {
- const BUTTON_SPECIFICATION *button = &buttons->list[i];
- int direction = -1;
- const char *button_name;
- const char *button_description;
- const char *button_example;
+ self->current_formatting_references = saved_formatting_references;
+ self->current_commands_conversion_function
+ = saved_commands_conversion_function;
+ self->current_types_conversion_function = saved_types_conversion_function;
+ self->current_format_protect_text = saved_current_format_protect_text;
- if (button->type == BST_direction_info)
- direction = button->b.button_info->direction;
- else if (button->type == BST_direction)
- direction = button->b.direction;
+ return result;
+}
- if (direction < 0 || direction == D_direction_Space)
- continue;
+/* return string to be freed by the caller */
+char *
+html_convert_string_tree_new_formatting_context (CONVERTER *self,
+ ELEMENT *tree, const char *context_string,
+ const char *multiple_pass)
+{
+ ELEMENT *tree_root_string = new_element (ET__string);
+ char *result;
- text_append_n (result, " <tr>\n ", 11);
- open_element_with_class (self, "td", &button_direction_about_classes,
- result);
+ add_to_contents_as_array (tree_root_string, tree);
- /* if the button spec is an array we do not know what the button
- looks like, so we do not show the button but still show explanations. */
+ add_tree_to_build (self, tree_root_string);
- if (button->type == BST_direction)
- {
- if (self->conf->ICONS.o.integer > 0
- && self->conf->ACTIVE_ICONS.o.icons->number > 0
- && self->conf->ACTIVE_ICONS.o.icons->list[direction]
- && strlen (self->conf->ACTIVE_ICONS.o.icons->list[direction]))
- {
- const char *button_name_string
- = direction_string (self, direction,
- TDS_type_button, TDS_context_string);
- char *button = format_button_icon_img (self, button_name_string,
- self->conf->ACTIVE_ICONS.o.icons->list[direction], 0);
- text_append (result, button);
- free (button);
- }
- else
- {
- const char *button_text = direction_string (self, direction,
- TDS_type_text, 0);
- text_append_n (result, " [", 2);
- if (button_text)
- text_append (result, button_text);
- text_append_n (result, "] ", 2);
- }
- }
- text_append_n (result, "</td>\n ", 10);
- open_element_with_class (self, "td", &name_direction_about_classes,
- result);
-
- button_name = direction_string (self, direction, TDS_type_button, 0);
- if (button_name)
- text_append (result, button_name);
- text_append_n (result, "</td>\n ", 10);
- open_element_with_class (self, "td",
- &description_direction_about_classes,
- result);
- button_description = direction_string (self, direction,
- TDS_type_description, 0);
- if (button_description)
- text_append (result, button_description);
- text_append_n (result, "</td>\n ", 10);
- open_element_with_class (self, "td", &example_direction_about_classes,
- result);
- button_example = direction_string (self, direction, TDS_type_example, 0);
- if (button_example)
- text_append (result, button_example);
- text_append_n (result, "</td>\n </tr>\n", 14);
- }
+ result = html_convert_tree_new_formatting_context (self, tree_root_string,
+ context_string, multiple_pass, 0, 0);
- text_append_n (result, "</table>\n\n<p>\n", 14);
-
- translate_convert_tree_append (
- " where the @strong{ Example } assumes that the current position is at "
- "@strong{ Subsubsection One-Two-Three } of a document of the following "
- "structure:", self, 0, 0, result, "ABOUT");
-
- text_append_n (result, "\n</p>\n\n<ul>\n", 12);
- text_append (result, " <li> 1. ");
- translate_convert_tree_append ("Section One",
- self, 0, 0, result, "ABOUT");
- text_append (result, "\n <ul>\n <li>1.1 ");
- translate_convert_tree_append ("Subsection One-One",
- self, 0, 0, result, "ABOUT");
- text_append (result, "\n <ul>\n <li>...</li>\n"
- " </ul>\n </li>\n <li>1.2 ");
- translate_convert_tree_append ("Subsection One-Two",
- self, 0, 0, result, "ABOUT");
- text_append (result, "\n <ul>\n <li>1.2.1 ");
- translate_convert_tree_append ("Subsubsection One-Two-One",
- self, 0, 0, result, "ABOUT");
- text_append (result, "</li>\n <li>1.2.2 ");
- translate_convert_tree_append ("Subsubsection One-Two-Two",
- self, 0, 0, result, "ABOUT");
- text_append (result, "</li>\n <li>1.2.3 ");
- translate_convert_tree_append ("Subsubsection One-Two-Three",
- self, 0, 0, result, "ABOUT");
- text_append_n (result, " ", 1);
- text_append_n (result,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- text_append_n (result, " ", 1);
- text_append_n (result,
- self->special_character[SC_non_breaking_space].string,
- self->special_character[SC_non_breaking_space].len);
- text_append_n (result, "\n", 1);
-
- text_append (result, " <strong><== ");
- translate_convert_tree_append ("Current Position",
- self, 0, 0, result, "ABOUT");
- text_append (result, " </strong></li>\n <li>1.2.4 ");
- translate_convert_tree_append ("Subsubsection One-Two-Four",
- self, 0, 0, result, "ABOUT");
- text_append (result, "</li>\n </ul>\n </li>\n <li>1.3 ");
- translate_convert_tree_append ("Subsection One-Three",
- self, 0, 0, result, "ABOUT");
- text_append (result, "\n <ul>\n <li>...</li>\n"
- " </ul>\n </li>\n <li>1.4 ");
- translate_convert_tree_append ("Subsection One-Four",
- self, 0, 0, result, "ABOUT");
- text_append (result, "</li>\n </ul>\n </li>\n</ul>\n");
+ remove_tree_to_build (self, tree_root_string);
+ destroy_element (tree_root_string);
+ return result;
}
@@ -13454,7 +1010,7 @@ html_prepare_title_titlepage (CONVERTER *self, const
char *output_file,
self->current_filename.file_number = 1;
}
- self->title_titlepage = format_title_titlepage (self);
+ self->title_titlepage = html_format_title_titlepage (self);
memset (&self->current_filename, 0, sizeof (FILE_NUMBER_NAME));
}
@@ -13531,7 +1087,8 @@ html_prepare_converted_output_info (CONVERTER *self,
const char *output_file,
{
self->title_tree = fulltitle_tree;
- html_title_string = convert_string_tree_new_formatting_context (self,
+ html_title_string
+ = html_convert_string_tree_new_formatting_context (self,
fulltitle_tree, "title_string", 0);
if (html_title_string[strspn (html_title_string, whitespace_chars)]
== '\0')
@@ -13549,7 +1106,8 @@ html_prepare_converted_output_info (CONVERTER *self,
const char *output_file,
self->title_tree = default_title;
- html_title_string = convert_string_tree_new_formatting_context (self,
+ html_title_string
+ = html_convert_string_tree_new_formatting_context (self,
default_title, "title_string", 0);
self->added_title_tree = 1;
@@ -13591,7 +1149,7 @@ html_prepare_converted_output_info (CONVERTER *self,
const char *output_file,
if (copying_comment && strlen (copying_comment) > 0)
{
- self->copying_comment = format_comment (self, copying_comment);
+ self->copying_comment = html_format_comment (self, copying_comment);
}
free (copying_comment);
}
@@ -13610,7 +1168,7 @@ html_prepare_converted_output_info (CONVERTER *self,
const char *output_file,
= self->document->global_commands.documentdescription->e.c->contents;
documentdescription_string
- = convert_string_tree_new_formatting_context (self,
+ = html_convert_string_tree_new_formatting_context (self,
tmp, "documentdescription", 0);
tmp->e.c->contents.list = 0;
@@ -14516,9 +2074,10 @@ convert_output_output_unit_internal (CONVERTER *self,
}
/* do end file first in case it requires some CSS */
- file_end = format_end_file (self, output_unit_filename, output_unit);
- file_beginning = format_begin_file (self, output_unit_filename,
- file_output_unit);
+ file_end = html_format_end_file (self, output_unit_filename,
+ output_unit);
+ file_beginning = html_format_begin_file (self, output_unit_filename,
+ file_output_unit);
text_reset (text);
if (file_beginning)
{
@@ -14620,21 +2179,7 @@ html_convert_output (CONVERTER *self, const ELEMENT
*root,
/* set self->date_in_header to format it only once */
if (self->conf->DATE_IN_HEADER.o.integer > 0)
{
- ELEMENT *today_element = new_command_element (ET_brace_noarg_command,
- CM_today);
- char *today;
-
- add_tree_to_build (self, today_element);
- today = convert_tree_new_formatting_context (self, today_element,
- "DATE_IN_HEADER", 0, 0, 0);
- remove_tree_to_build (self, today_element);
- destroy_element (today_element);
-
- text_printf (&text,
- "<meta name=\"date\" content=\"%s\"", today);
- free (today);
- close_html_lone_element (self, &text);
- text_append_n (&text, "\n", 1);
+ html_default_format_date_in_header (self, &text);
self->date_in_header = strdup (text.text);
text_reset (&text);
}
@@ -14674,8 +2219,8 @@ html_convert_output (CONVERTER *self, const ELEMENT
*root,
}
/* do end file first, in case it needs some CSS */
- file_end = format_end_file (self, output_filename, 0);
- file_beginning = format_begin_file (self, output_filename, 0);
+ file_end = html_format_end_file (self, output_filename, 0);
+ file_beginning = html_format_begin_file (self, output_filename, 0);
if (file_beginning)
{
text_append (&result, file_beginning);
@@ -14931,9 +2476,7 @@ do_jslicenses_file (CONVERTER *self)
const char *destination_directory = self->destination_directory;
const char *setting = self->conf->JS_WEBLABELS.o.string;
const char *path = self->conf->JS_WEBLABELS_FILE.o.string;
- TEXT result;
- char *root_html_element_attributes;
- size_t i;
+ char *formatted_jlicenses;
int path_not_ok = 0;
char *license_file;
char *path_encoding;
@@ -14969,59 +2512,8 @@ do_jslicenses_file (CONVERTER *self)
return;
}
- text_init (&result);
- if (self->conf->DOCTYPE.o.string)
- text_append (&result, self->conf->DOCTYPE.o.string);
- text_append_n (&result, "\n", 1);
- root_html_element_attributes
- = root_html_element_attributes_string (self);
- if (!root_html_element_attributes)
- root_html_element_attributes = strdup ("");
- text_printf (&result, "<html%s>", root_html_element_attributes);
- free (root_html_element_attributes);
- text_append (&result, "<head><title>jslicense labels</title></head>\n"
- "<body>\n"
- "<table id=\"jslicense-labels1\">\n");
-
- for (i = 0; i < self->jslicenses.number; i++)
- {
- size_t j;
- JSLICENSE_FILE_INFO_LIST *jlicense_file_info_list
- = &self->jslicenses.list[i];
-
- for (j = 0; j < jlicense_file_info_list->number; j++)
- {
- JSLICENSE_FILE_INFO *jlicense_file_info
- = &jlicense_file_info_list->list[j];
- char *p_file
- = url_protect_url_text (self, jlicense_file_info->filename);
- char *p_url
- = url_protect_url_text (self, jlicense_file_info->url);
- char *p_source
- = url_protect_url_text (self, jlicense_file_info->source);
- text_append_n (&result, "<tr>\n", 5);
- text_append_n (&result, "<td><a href=\"", 13);
- text_append (&result, p_file);
- text_append_n (&result, "\">", 2);
- text_append (&result, jlicense_file_info->filename);
- text_append_n (&result, "</a></td>\n", 10);
- text_append_n (&result, "<td><a href=\"", 13);
- text_append (&result, p_url);
- text_append_n (&result, "\">", 2);
- text_append (&result, jlicense_file_info->license);
- text_append_n (&result, "</a></td>\n", 10);
- text_append_n (&result, "<td><a href=\"", 13);
- text_append (&result, p_source);
- text_append_n (&result, "\">", 2);
- text_append (&result, jlicense_file_info->source);
- text_append_n (&result, "</a></td>\n", 10);
- text_append_n (&result, "</tr>\n", 6);
- free (p_file);
- free (p_url);
- free (p_source);
- }
- }
- text_append_n (&result, "</table>\n</body></html>\n", 24);
+ formatted_jlicenses
+ = html_default_format_jslicense_file (self, &self->jslicenses);
if (destination_directory && strlen (destination_directory))
xasprintf (&license_file, "%s/%s", destination_directory, path);
@@ -15056,12 +2548,12 @@ do_jslicenses_file (CONVERTER *self)
file_error_or_write_close (self, license_file,
encoded_out_filepath, file_fh,
- conversion, result.text,
+ conversion, formatted_jlicenses,
open_error_message);
free (open_error_message);
free (encoded_out_filepath);
free (license_file);
- free (result.text);
+ free (formatted_jlicenses);
}
static const char *js_files[4] = {"info.js", "modernizr.js", "info.css", 0};
@@ -15314,7 +2806,7 @@ html_prepare_node_redirection_page (CONVERTER *self,
const ELEMENT *element,
self->current_filename.filename = filename;
self->current_filename.file_number = 0;
- result = format_node_redirection_page (self, element, filename);
+ result = html_format_node_redirection_page (self, element, filename);
self->current_filename.filename = 0;
diff --git a/tp/Texinfo/XS/convert/convert_html.h
b/tp/Texinfo/XS/convert/convert_html.h
index f182dafa1e..c931041228 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -18,257 +18,45 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "command_ids.h"
-#include "element_types.h"
#include "tree_types.h"
#include "converter_types.h"
#include "html_converter_types.h"
-typedef struct ROOT_AND_UNIT {
- const OUTPUT_UNIT *output_unit;
- const ELEMENT *root;
-} ROOT_AND_UNIT;
-
-extern const char *html_conversion_context_type_names[];
-
-extern const char *html_argument_formatting_type_names[];
-
-/* in conversion_data.c */
-extern const TRANSLATED_SUI_ASSOCIATION translated_special_unit_info[];
-
-extern const char *direction_string_type_names[];
-extern const char *direction_string_context_names[];
-
-extern const char *html_stage_handler_stage_type_names[];
-
-
-char *html_after_escaped_characters (char *text);
-char *html_substitute_non_breaking_space (CONVERTER *self, const char *text);
-
-void html_default_format_protect_text (const char *text, TEXT *result);
-
-
-HTML_TARGET *html_get_target (const CONVERTER *self, const ELEMENT *element);
-const char *html_command_id (const CONVERTER *self, const ELEMENT *command);
-char *html_normalized_to_id (const char *id);
-TARGET_FILENAME *html_normalized_label_id_file (CONVERTER *self,
- const char *normalized,
- const ELEMENT* label_element);
-
-int html_special_unit_variety_direction_index (const CONVERTER *self,
- const char *special_unit_variety);
-ROOT_AND_UNIT *html_get_tree_root_element (CONVERTER *self,
- const ELEMENT *command,
- int find_container);
-
-const char *html_command_contents_target (CONVERTER *self,
- const ELEMENT *command,
- enum command_id contents_or_shortcontents);
-const char *html_footnote_location_target (const CONVERTER *self,
- const ELEMENT *command);
-const FILE_NUMBER_NAME *html_command_filename (CONVERTER *self,
- const ELEMENT *command);
-const ELEMENT *html_command_root_element_command (CONVERTER *self,
- const ELEMENT *command);
-const ELEMENT *html_command_node (CONVERTER *self, const ELEMENT *command);
-char *html_internal_command_href (CONVERTER *self, const ELEMENT *command,
- const char *source_filename,
- const char *specified_target);
-char *html_command_contents_href (CONVERTER *self, const ELEMENT *command,
- enum command_id contents_or_shortcontents,
- const char *source_filename);
-char *html_footnote_location_href (CONVERTER *self, const ELEMENT *command,
- const char *source_filename,
- const char *specified_target,
- const char *target_filename_in);
-TREE_ADDED_ELEMENTS *html_internal_command_tree (CONVERTER *self,
- const ELEMENT *command, int no_number);
-char *html_internal_command_text (CONVERTER *self, const ELEMENT *command,
- const enum html_text_type type);
-char *html_command_description (CONVERTER *self, const ELEMENT *command,
- const enum html_text_type type);
-
-OUTPUT_UNIT *html_get_top_unit (DOCUMENT *document,
- const OUTPUT_UNIT_LIST *output_units);
-
-FOOTNOTE_ID_NUMBER *find_footnote_id_number (const CONVERTER *self,
- const char *footnote_id);
-
-
-const char *html_special_unit_info (const CONVERTER *self,
- enum special_unit_info_type type,
- const char *special_unit_variety);
-
-char *html_attribute_class (CONVERTER *self, const char *element,
- const STRING_LIST *classes);
-
-
-void
-html_command_conversion_external (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element,
- const HTML_ARGS_FORMATTED *args_formatted,
- const char *content, TEXT *result);
-
-#define COMMAND_CONVERSION_FUNCTION(name) \
-void html_convert_##name (CONVERTER *self, const enum command_id cmd, \
- const ELEMENT *element, \
- const HTML_ARGS_FORMATTED *args_formatted, \
- const char *content, TEXT *result);
-#define CSS_STRING_COMMAND_CONVERSION_FUNCTION(name) \
-void html_css_string_convert_##name (CONVERTER *self, const enum command_id
cmd, \
- const ELEMENT *element, \
- const HTML_ARGS_FORMATTED *args_formatted, \
- const char *content, TEXT *result);
-
-COMMAND_CONVERSION_FUNCTION(no_arg_command)
-CSS_STRING_COMMAND_CONVERSION_FUNCTION(no_arg_command)
-COMMAND_CONVERSION_FUNCTION(today_command)
-COMMAND_CONVERSION_FUNCTION(style_command)
-COMMAND_CONVERSION_FUNCTION(w_command)
-COMMAND_CONVERSION_FUNCTION(value_command)
-COMMAND_CONVERSION_FUNCTION(email_command)
-COMMAND_CONVERSION_FUNCTION(explained_command)
-COMMAND_CONVERSION_FUNCTION(anchor_command)
-COMMAND_CONVERSION_FUNCTION(footnote_command)
-COMMAND_CONVERSION_FUNCTION(uref_command)
-COMMAND_CONVERSION_FUNCTION(image_command)
-COMMAND_CONVERSION_FUNCTION(math_command)
-COMMAND_CONVERSION_FUNCTION(accent_command)
-CSS_STRING_COMMAND_CONVERSION_FUNCTION(accent_command)
-COMMAND_CONVERSION_FUNCTION(indicateurl_command)
-COMMAND_CONVERSION_FUNCTION(titlefont_command)
-COMMAND_CONVERSION_FUNCTION(U_command)
-COMMAND_CONVERSION_FUNCTION(heading_command)
-COMMAND_CONVERSION_FUNCTION(inline_command)
-COMMAND_CONVERSION_FUNCTION(xref_command)
-
-COMMAND_CONVERSION_FUNCTION(raw_command)
-COMMAND_CONVERSION_FUNCTION(preformatted_command)
-COMMAND_CONVERSION_FUNCTION(indented_command)
-COMMAND_CONVERSION_FUNCTION(verbatim_command)
-COMMAND_CONVERSION_FUNCTION(displaymath_command)
-COMMAND_CONVERSION_FUNCTION(simple_block_command)
-COMMAND_CONVERSION_FUNCTION(menu_command)
-COMMAND_CONVERSION_FUNCTION(float_command)
-COMMAND_CONVERSION_FUNCTION(quotation_command)
-COMMAND_CONVERSION_FUNCTION(cartouche_command)
-COMMAND_CONVERSION_FUNCTION(itemize_command)
-COMMAND_CONVERSION_FUNCTION(enumerate_command)
-COMMAND_CONVERSION_FUNCTION(multitable_command)
-COMMAND_CONVERSION_FUNCTION(xtable_command)
-
-COMMAND_CONVERSION_FUNCTION(verbatiminclude_command)
-COMMAND_CONVERSION_FUNCTION(sp_command)
-COMMAND_CONVERSION_FUNCTION(exdent_command)
-COMMAND_CONVERSION_FUNCTION(center_command)
-COMMAND_CONVERSION_FUNCTION(author_command)
-COMMAND_CONVERSION_FUNCTION(title_command)
-COMMAND_CONVERSION_FUNCTION(subtitle_command)
-COMMAND_CONVERSION_FUNCTION(item_command)
-COMMAND_CONVERSION_FUNCTION(tab_command)
-COMMAND_CONVERSION_FUNCTION(insertcopying_command)
-COMMAND_CONVERSION_FUNCTION(listoffloats_command)
-COMMAND_CONVERSION_FUNCTION(printindex_command)
-COMMAND_CONVERSION_FUNCTION(informative_command)
-COMMAND_CONVERSION_FUNCTION(contents_command)
-COMMAND_CONVERSION_FUNCTION(def_command)
-
-#undef COMMAND_CONVERSION_FUNCTION
-
-void html_command_open_external (CONVERTER *self, const enum command_id cmd,
- const ELEMENT *element, TEXT *result);
-
-#define COMMAND_OPEN_FUNCTION(name) \
-void html_open_##name (CONVERTER *self, const enum command_id cmd, \
- const ELEMENT *element, TEXT *result);
-
-COMMAND_OPEN_FUNCTION(quotation_command)
-COMMAND_OPEN_FUNCTION(node_part_command)
-
-#undef COMMAND_OPEN_FUNCTION
-
-void html_type_conversion_external (CONVERTER *self,
- const enum element_type type,
- const ELEMENT *element, const char
*content,
- TEXT *result);
-
-#define ELEMENT_TYPE_CONVERSION_FUNCTION(name) \
-void html_convert_##name (CONVERTER *self, const enum element_type type, \
- const ELEMENT *element, const char *content, \
- TEXT *result);
-
-#define CSS_STRING_ELEMENT_TYPE_CONVERSION_FUNCTION(name) \
-void html_css_string_convert_##name (CONVERTER *self, const enum element_type
type, \
- const ELEMENT *element, const char *content, \
- TEXT *result);
-
-ELEMENT_TYPE_CONVERSION_FUNCTION(text)
-CSS_STRING_ELEMENT_TYPE_CONVERSION_FUNCTION(text)
-ELEMENT_TYPE_CONVERSION_FUNCTION(paragraph_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(preformatted_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(balanced_braces_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(index_entry_command_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(definfoenclose_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(untranslated_def_line_arg_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(row_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(multitable_head_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(multitable_body_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(menu_entry_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(menu_comment_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(before_item_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(table_term_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(def_line_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(def_item_type)
-ELEMENT_TYPE_CONVERSION_FUNCTION(table_definition_type)
-
-#undef CSS_STRING_ELEMENT_TYPE_CONVERSION_FUNCTION
-#undef ELEMENT_TYPE_CONVERSION_FUNCTION
-
-void html_type_open_external (CONVERTER *self, enum element_type type,
- const ELEMENT *element, TEXT *result);
-
-#define ELEMENT_TYPE_OPEN_FUNCTION(name) \
-void html_open_##name (CONVERTER *self, const enum element_type type, \
- const ELEMENT *element, TEXT *result);
-
-ELEMENT_TYPE_OPEN_FUNCTION(inline_container_type)
-
-#undef ELEMENT_TYPE_OPEN_FUNCTION
-
-void html_output_unit_conversion_external (CONVERTER *self,
- const enum output_unit_type unit_type,
- const OUTPUT_UNIT *output_unit, const char *content,
- TEXT *result);
-
-#define UNIT_CONVERSION_FUNCTION(name) \
-void html_convert_##name (CONVERTER *self, \
- const enum output_unit_type unit_type, \
- const OUTPUT_UNIT *output_unit, const char *content,
\
- TEXT *result);
-
-UNIT_CONVERSION_FUNCTION(unit_type);
-UNIT_CONVERSION_FUNCTION(special_unit_type);
-
-#undef UNIT_CONVERSION_FUNCTION
-
-void html_special_unit_body_formatting_external (CONVERTER *self,
- const size_t special_unit_number,
- const char *special_unit_variety,
- const OUTPUT_UNIT *output_unit,
- TEXT *result);
-
-#define SPECIAL_BODY_FORMATTING_FUNCTION(name) \
-void html_default_format_special_body_##name (CONVERTER *self, \
- const size_t special_unit_number, \
- const char *special_unit_variety, \
- const OUTPUT_UNIT *output_unit, \
- TEXT *result);
-
-SPECIAL_BODY_FORMATTING_FUNCTION(contents)
-SPECIAL_BODY_FORMATTING_FUNCTION(shortcontents)
-SPECIAL_BODY_FORMATTING_FUNCTION(footnotes)
-SPECIAL_BODY_FORMATTING_FUNCTION(about)
-
-#undef SPECIAL_BODY_FORMATTING_FUNCTION
+
+
+ELEMENT *html_cdt_tree (const char *string, CONVERTER *self,
+ NAMED_STRING_ELEMENT_LIST *replaced_substrings,
+ const char *translation_context);
+char *html_cdt_string (const char *string, CONVERTER *self,
+ NAMED_STRING_ELEMENT_LIST *replaced_substrings,
+ const char *translation_context);
+ELEMENT *html_pcdt_tree (const char *translation_context, const char *string,
+ CONVERTER *self,
+ NAMED_STRING_ELEMENT_LIST *replaced_substrings);
+
+void add_tree_to_build (CONVERTER *self, ELEMENT *e);
+void remove_tree_to_build (CONVERTER *self, ELEMENT *e);
+
+char *html_convert_tree (CONVERTER *self, const ELEMENT *tree,
+ const char *explanation);
+void convert_tree_append (CONVERTER *self, const ELEMENT *e,
+ TEXT *result, const char *explanation);
+void html_translate_convert_tree_append (const char *string,
+ CONVERTER *self,
+ NAMED_STRING_ELEMENT_LIST *replaced_substrings,
+ const char *translation_context,
+ TEXT *result, const char *explanation);
+char *html_convert_tree_new_formatting_context (CONVERTER *self,
+ const ELEMENT *tree,
+ const char *context_string,
+ const char *multiple_pass,
+ const char *document_global_context,
+ enum command_id block_cmd);
+char *html_convert_css_string (CONVERTER *self, const ELEMENT *element,
+ const char *context_str);
+char *html_convert_string_tree_new_formatting_context (CONVERTER *self,
+ ELEMENT *tree, const char *context_string,
+ const char *multiple_pass);
void html_clear_direction_string_type (const CONVERTER *self,
diff --git a/tp/Texinfo/XS/convert/convert_html.c
b/tp/Texinfo/XS/convert/format_html.c
similarity index 79%
copy from tp/Texinfo/XS/convert/convert_html.c
copy to tp/Texinfo/XS/convert/format_html.c
index d25c323659..35a3038cd0 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/format_html.c
@@ -25,8 +25,6 @@
#include <unistr.h>
#include <unictype.h>
-#include "copy-file.h"
-
#include "conversion_data.h"
#include "text.h"
#include "element_types.h"
@@ -51,16 +49,15 @@
#include "node_name_normalization.h"
#include "manipulate_indices.h"
#include "convert_to_texinfo.h"
-#include "translations.h"
/* for OTXI_UNICODE_TEXT_CASES utf8_from_string string_from_utf8 */
#include "unicode.h"
/* convert_to_text */
#include "convert_to_text.h"
#include "convert_utils.h"
-#include "call_perl_function.h"
#include "call_html_perl_function.h"
-/* for unregister_document_merge_with_document */
+/* for unregister_document_merge_with_document
#include "document.h"
+ */
#include "converter.h"
#include "manipulate_tree.h"
/* for new_complete_menu_master_menu */
@@ -68,24 +65,7 @@
#include "api_to_perl.h"
#include "html_conversion_state.h"
#include "convert_html.h"
-
-const char *html_conversion_context_type_names[] = {
- #define cctx_type(name) #name,
- HCC_CONTEXT_TYPES_LIST
- #undef cctx_type
-};
-
-const char *html_argument_formatting_type_names[] = {
- #define html_aft_type(name) #name,
- HTML_ARGUMENTS_FORMATTED_FORMAT_TYPE
- #undef html_aft_type
-};
-
-const char *html_stage_handler_stage_type_names[] = {
- #define html_hsht_type(name) #name,
- HTML_STAGE_HANDLER_STAGE_TYPE
- #undef html_hsht_type
-};
+#include "format_html.h"
const char *direction_string_type_names[] =
{
@@ -110,7 +90,7 @@ const enum htmlxref_split_type
htmlxref_entries[htmlxref_split_type_chapter + 1]
/* string functions */
void
-close_html_lone_element (const CONVERTER *self, TEXT *result)
+html_close_lone_element (const CONVERTER *self, TEXT *result)
{
if (self->conf->USE_XML_SYNTAX.o.integer > 0)
text_append_n (result, "/>", 2);
@@ -366,6 +346,34 @@ format_protect_text (CONVERTER *self, const char *text,
TEXT *result)
}
}
+void
+html_default_css_string_format_protect_text (const char *text, TEXT *result)
+{
+ const char *p = text;
+
+ while (*p)
+ {
+ int before_sep_nr = strcspn (p, "\\'");
+ if (before_sep_nr)
+ {
+ text_append_n (result, p, before_sep_nr);
+ p += before_sep_nr;
+ }
+ if (!*p)
+ break;
+ switch (*p)
+ {
+ case '\\':
+ text_append_n (result, "\\\\", 2);
+ break;
+ case '\'':
+ text_append_n (result, "\\'", 2);
+ break;
+ }
+ p++;
+ }
+}
+
static const char *reserved_unreserved_percent = "-_.!~*'()$&+,/:;=?@[]#%";
/* NOTE the input string should be UTF-8 encoded */
@@ -503,255 +511,6 @@ url_protect_file_text (CONVERTER *self, const char
*input_string)
-/* string translation and tree conversion */
-
-char *
-format_translate_message (CONVERTER *self,
- const char *message, const char *lang,
- const char *message_context)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->current_formatting_references[FR_format_translate_message];
-
- return call_formatting_function_format_translate_message (self,
- formatting_reference,
- message, lang, message_context);
-}
-
-/* return string to be freed by the caller */
-char *
-html_translate_string (CONVERTER *self, const char *string,
- const char *lang,
- const char *translation_context)
-{
- const FORMATTING_REFERENCE *formatting_reference
- = &self->formatting_references[FR_format_translate_message];
-
- /* there is no place where FRS_status_ignore could be set, but
- it does not hurt to consider it possible */
- if (formatting_reference->status
- && formatting_reference->status != FRS_status_ignored
- && formatting_reference->status != FRS_status_none
- /* this function may not be defined in Perl, thus this condition */
- && formatting_reference->sv_reference)
- {
- char *translated_string
- = format_translate_message (self, string, lang, translation_context);
-
- if (translated_string)
- return translated_string;
- }
-
- return translate_string (string, lang, translation_context);
-}
-
-/* returns a document descriptor. */
-/* same as gdt with html_translate_string called instead of translate_string */
-size_t
-html_gdt (const char *string, CONVERTER *self, const char *lang,
- NAMED_STRING_ELEMENT_LIST *replaced_substrings,
- const char *translation_context)
-{
- const OPTIONS *options = self->conf;
- int debug_level = 0;
- size_t document_descriptor;
-
- char *translated_string = html_translate_string (self, string, lang,
- translation_context);
-
- if (options && options->DEBUG.o.integer >= 0)
- debug_level = options->DEBUG.o.integer;
-
- document_descriptor = replace_convert_substrings (translated_string,
- replaced_substrings, debug_level);
- free (translated_string);
- return document_descriptor;
-}
-
-/* same as gdt_tree with html_gdt called instead of gdt */
-ELEMENT *
-html_gdt_tree (const char *string, CONVERTER *self,
- const char *lang, NAMED_STRING_ELEMENT_LIST
*replaced_substrings,
- const char *translation_context)
-{
- DOCUMENT *document = self->document;
-
- size_t gdt_document_descriptor = html_gdt (string, self, lang,
- replaced_substrings, translation_context);
-
- ELEMENT *tree
- = unregister_document_merge_with_document (gdt_document_descriptor,
- document);
- return tree;
-}
-
-/* same as cdt_tree with html_gdt_tree called instead of gdt_tree */
-ELEMENT *
-html_cdt_tree (const char *string, CONVERTER *self,
- NAMED_STRING_ELEMENT_LIST *replaced_substrings,
- const char *translation_context)
-{
- const char *lang = self->conf->documentlanguage.o.string;
-
- return html_gdt_tree (string, self, lang,
- replaced_substrings, translation_context);
-}
-
-char *
-html_cdt_string (const char *string, CONVERTER *self,
- NAMED_STRING_ELEMENT_LIST *replaced_substrings,
- const char *translation_context)
-{
- char *translated_string;
- char *result;
- const char *lang = self->conf->documentlanguage.o.string;
-
- translated_string = html_translate_string (self, string, lang,
- translation_context);
-
- result = replace_substrings (translated_string, replaced_substrings);
- free (translated_string);
- return result;
-}
-
-ELEMENT *
-html_pcdt_tree (const char *translation_context, const char *string,
- CONVERTER *self,
- NAMED_STRING_ELEMENT_LIST *replaced_substrings)
-{
- return html_cdt_tree (string, self, replaced_substrings,
- translation_context);
-}
-
-static void
-add_tree_to_build (CONVERTER *self, ELEMENT *e)
-{
- if (self->external_references_number > 0)
- add_to_element_list (&self->tree_to_build, e);
-}
-
-static void
-remove_tree_to_build (CONVERTER *self, ELEMENT *e)
-{
- if (self->external_references_number > 0)
- remove_element_from_list (&self->tree_to_build, e);
-}
-
-static void convert_tree_append (CONVERTER *self, const ELEMENT *e,
- TEXT *result, const char *explanation);
-
-static void
-translate_convert_tree_append (const char *string,
- CONVERTER *self,
- NAMED_STRING_ELEMENT_LIST *replaced_substrings,
- const char *translation_context,
- TEXT *result, const char *explanation)
-{
- ELEMENT *translation_tree = html_cdt_tree (string, self,
- replaced_substrings, translation_context);
-
- add_tree_to_build (self, translation_tree);
- convert_tree_append (self, translation_tree, result, explanation);
- remove_tree_to_build (self, translation_tree);
-
- destroy_element_and_children (translation_tree);
-}
-
-ELEMENT *
-special_unit_info_tree (CONVERTER *self, const enum special_unit_info_tree
type,
- const char *special_unit_variety)
-{
- /* number is index +1 */
- size_t number = find_string (&self->special_unit_varieties,
- special_unit_variety);
- int j;
- int i = number -1;
-
- if (self->special_unit_info_tree[type][i])
- return self->special_unit_info_tree[type][i];
-
- for (j = 0; translated_special_unit_info[j].tree_type != SUIT_type_none; j++)
- {
- if (translated_special_unit_info[j].tree_type == type)
- {
- enum special_unit_info_type string_type
- = translated_special_unit_info[j].string_type;
- char *special_unit_info_string
- = self->special_unit_info[string_type][i];
- /* if set to undef in user customization. To be forbidden? */
- if (!special_unit_info_string)
- return 0;
- char *translation_context;
- xasprintf (&translation_context, "%s section heading",
- special_unit_variety);
- self->special_unit_info_tree[type][i]
- = html_pcdt_tree (translation_context, special_unit_info_string,
- self, 0);
- free (translation_context);
- add_tree_to_build (self, self->special_unit_info_tree[type][i]);
- return self->special_unit_info_tree[type][i];
- }
- }
- return 0;
-}
-
-/* returned string to be freed by the caller */
-char *
-html_convert_tree (CONVERTER *self, const ELEMENT *tree,
- const char *explanation)
-{
- TEXT result;
- text_init (&result);
-
- convert_tree_append (self, tree, &result, explanation);
-
- return result.text;
-}
-
-/* Call convert_tree out of the main conversion flow.
- */
-char *
-convert_tree_new_formatting_context (CONVERTER *self, const ELEMENT *tree,
- const char *context_string,
- const char *multiple_pass,
- const char *document_global_context,
- enum command_id block_cmd)
-{
- const char *multiple_pass_str = "";
- char *result;
- char *explanation;
- char *context_string_str;
-
- html_new_document_context (self, context_string,
- document_global_context, block_cmd);
- xasprintf (&context_string_str, "C(%s)", context_string);
-
- if (multiple_pass)
- {
- html_set_multiple_conversions (self, multiple_pass);
- multiple_pass_str = "|M";
- }
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "XS|new_fmt_ctx %s%s\n", context_string_str,
- multiple_pass_str);
-
- xasprintf (&explanation, "new_fmt_ctx %s", context_string_str);
- result = html_convert_tree (self, tree, explanation);
-
- free (explanation);
-
- if (multiple_pass)
- html_unset_multiple_conversions (self);
-
- free (context_string_str);
- html_pop_document_context (self);
-
- return result;
-}
-
-
-
/* target, links, href and root command text formatting, with caching */
/* this number should be safe to use even after targets list has been
@@ -1801,6 +1560,45 @@ html_footnote_location_href (CONVERTER *self, const
ELEMENT *command,
return href.text;
}
+ELEMENT *
+special_unit_info_tree (CONVERTER *self,
+ const enum special_unit_info_tree type,
+ const char *special_unit_variety)
+{
+ /* number is index +1 */
+ size_t number = find_string (&self->special_unit_varieties,
+ special_unit_variety);
+ int j;
+ int i = number -1;
+
+ if (self->special_unit_info_tree[type][i])
+ return self->special_unit_info_tree[type][i];
+
+ for (j = 0; translated_special_unit_info[j].tree_type != SUIT_type_none; j++)
+ {
+ if (translated_special_unit_info[j].tree_type == type)
+ {
+ enum special_unit_info_type string_type
+ = translated_special_unit_info[j].string_type;
+ char *special_unit_info_string
+ = self->special_unit_info[string_type][i];
+ /* if set to undef in user customization. To be forbidden? */
+ if (!special_unit_info_string)
+ return 0;
+ char *translation_context;
+ xasprintf (&translation_context, "%s section heading",
+ special_unit_variety);
+ self->special_unit_info_tree[type][i]
+ = html_pcdt_tree (translation_context, special_unit_info_string,
+ self, 0);
+ free (translation_context);
+ add_tree_to_build (self, self->special_unit_info_tree[type][i]);
+ return self->special_unit_info_tree[type][i];
+ }
+ }
+ return 0;
+}
+
/* the returned TREE_ADDED_ELEMENTS may not be NUL but have a NUL tree
field, for instance in the case of an empty sectioning element
*/
@@ -2085,7 +1883,7 @@ html_command_text (CONVERTER *self, const ELEMENT
*command,
xasprintf (&context_str, "command_text %s ",
html_command_text_type_name[type]);
- result = convert_tree_new_formatting_context (self, tree_root,
+ result = html_convert_tree_new_formatting_context (self, tree_root,
context_str,
"command_text-manual_content", 0, 0);
@@ -2133,179 +1931,54 @@ unit_is_top_output_unit (CONVERTER *self, const
OUTPUT_UNIT *output_unit)
/* return value to be freed by caller */
char *
-html_command_description (CONVERTER *self, const ELEMENT *command,
- const enum html_text_type type)
+from_element_direction (CONVERTER *self, int direction,
+ enum html_text_type type,
+ const OUTPUT_UNIT *source_unit,
+ const char *source_filename,
+ const ELEMENT *source_command)
{
- HTML_TARGET *target_info;
+ const char *filename_from;
+ const OUTPUT_UNIT *target_unit = 0;
+ const ELEMENT *command = 0;
- ELEMENT *manual_content = lookup_extra_element (command,
- AI_key_manual_content);
- if (manual_content)
+ /* this means that the direction given in Perl was not found in C */
+ if (direction < 0)
return 0;
- target_info = html_get_target (self, command);
+ if (!source_unit)
+ source_unit = self->current_output_unit;
- if (target_info)
+ if (source_filename)
+ filename_from = source_filename;
+ else
+ filename_from = self->current_filename.filename;
+
+ /* To debug:
+ fprintf (stderr, "FED: %s %s\n", html_command_text_type_name[type],
+ self->direction_unit_direction_name[direction]);
+ */
+
+ if (direction < D_direction_Space)
+ target_unit = self->global_units_directions[direction];
+ else if (direction > NON_SPECIAL_DIRECTIONS_NR - 1)
{
- if (target_info->command_description[type])
- return strdup (target_info->command_description[type]);
- else
+ /* special units (global) directions */
+ target_unit
+ = self->global_units_directions
+ [D_direction_Last + direction - NON_SPECIAL_DIRECTIONS_NR +1];
+ }
+ else if ((!source_unit || unit_is_top_output_unit (self, source_unit))
+ && self->conf->TOP_NODE_UP_URL.o.string
+ && (direction == D_direction_Up || direction == D_direction_NodeUp))
+ {
+ if (type == HTT_href)
+ return strdup (self->conf->TOP_NODE_UP_URL.o.string);
+ else if (type == HTT_text || type == HTT_node
+ || type == HTT_string || type == HTT_section)
{
- const ELEMENT *node = 0;
- ELEMENT *tree_root;
- char *explanation;
- char *context_name;
- const ELEMENT *node_description;
- int formatted_nodedescription_nr = 0;
- HTML_TARGET *node_target_info;
- char *multiple_formatted = 0;
- ELEMENT *description_element;
- const char *command_name;
- enum command_id cmd = element_builtin_cmd (command);
-
- if (command->type == ET_special_unit_element)
- return 0;
-
- if (cmd == CM_float || cmd == CM_anchor)
- return 0;
-
- if (cmd == CM_node)
- node = command;
- else
- node = lookup_extra_element (command, AI_key_associated_node);
-
- if (!node)
- return 0;
-
- node_description
- = lookup_extra_element (node, AI_key_node_description);
-
- if (!node_description)
- return 0;
-
- node_target_info = html_get_target (self, node);
- node_target_info->formatted_nodedescription_nr++;
- formatted_nodedescription_nr
- = node_target_info->formatted_nodedescription_nr;
-
- if (formatted_nodedescription_nr > 1)
- {
- xasprintf (&multiple_formatted,
- "node-description-%d",
- formatted_nodedescription_nr);
- }
-
- if (node_description->e.c->cmd == CM_nodedescription)
- description_element = node_description->e.c->args.list[0];
- else
- {
- description_element = new_element (ET_NONE);
- description_element->e.c->contents
- = node_description->e.c->contents;
- add_tree_to_build (self, description_element);
- }
-
- command_name = element_command_name (command);
- xasprintf (&context_name, "%s description", command_name);
- xasprintf (&explanation, "command_description:%s @%s",
- html_command_text_type_name[type],
- command_name);
-
- if (type == HTT_string)
- {
- tree_root = new_element (ET__string);
- add_to_contents_as_array (tree_root, description_element);
- add_tree_to_build (self, tree_root);
- }
- else
- tree_root = description_element;
-
- target_info->command_description[type]
- = convert_tree_new_formatting_context (self, tree_root,
- context_name, multiple_formatted,
- explanation, 0);
- free (context_name);
- free (explanation);
-
- if (formatted_nodedescription_nr > 1)
- free (multiple_formatted);
- if (node_description->e.c->cmd != CM_nodedescription)
- {
- remove_tree_to_build (self, description_element);
- description_element->e.c->contents.list = 0;
- destroy_element (description_element);
- }
- if (type == HTT_string)
- {
- remove_tree_to_build (self, tree_root);
- destroy_element (tree_root);
- }
- return strdup (target_info->command_description[type]);
- }
- }
- /*
- Can happen
- * if USE_NODES is 0 and there are no sectioning commands.
- * if a special element target was set to undef in user defined code.
- * for @*ref with missing targets (maybe @novalidate needed in that case).
- * for @node header if the node consist only in spaces (example in
sectioning
- in_menu_only_special_ascii_spaces_node).
- * for multiple targets with the same name, eg both @node and @anchor
- * with @inforef with node argument only, without manual argument.
- */
- return 0;
-}
-
-/* return value to be freed by caller */
-char *
-from_element_direction (CONVERTER *self, int direction,
- enum html_text_type type,
- const OUTPUT_UNIT *source_unit,
- const char *source_filename,
- const ELEMENT *source_command)
-{
- const char *filename_from;
- const OUTPUT_UNIT *target_unit = 0;
- const ELEMENT *command = 0;
-
- /* this means that the direction given in Perl was not found in C */
- if (direction < 0)
- return 0;
-
- if (!source_unit)
- source_unit = self->current_output_unit;
-
- if (source_filename)
- filename_from = source_filename;
- else
- filename_from = self->current_filename.filename;
-
- /* To debug:
- fprintf (stderr, "FED: %s %s\n", html_command_text_type_name[type],
- self->direction_unit_direction_name[direction]);
- */
-
- if (direction < D_direction_Space)
- target_unit = self->global_units_directions[direction];
- else if (direction > NON_SPECIAL_DIRECTIONS_NR - 1)
- {
- /* special units (global) directions */
- target_unit
- = self->global_units_directions
- [D_direction_Last + direction - NON_SPECIAL_DIRECTIONS_NR +1];
- }
- else if ((!source_unit || unit_is_top_output_unit (self, source_unit))
- && self->conf->TOP_NODE_UP_URL.o.string
- && (direction == D_direction_Up || direction == D_direction_NodeUp))
- {
- if (type == HTT_href)
- return strdup (self->conf->TOP_NODE_UP_URL.o.string);
- else if (type == HTT_text || type == HTT_node
- || type == HTT_string || type == HTT_section)
- {
- if (self->conf->TOP_NODE_UP.o.string)
- return strdup (self->conf->TOP_NODE_UP.o.string);
- else
+ if (self->conf->TOP_NODE_UP.o.string)
+ return strdup (self->conf->TOP_NODE_UP.o.string);
+ else
return 0;
}
else
@@ -2672,7 +2345,7 @@ html_default_format_comment (CONVERTER *self, const char
*text)
}
char *
-format_comment (CONVERTER *self, const char *text)
+html_format_comment (CONVERTER *self, const char *text)
{
FORMATTING_REFERENCE *formatting_reference
= &self->current_formatting_references[FR_format_comment];
@@ -2795,7 +2468,7 @@ direction_string (CONVERTER *self, int direction,
add_tree_to_build (self, converted_tree);
result_string
- = convert_tree_new_formatting_context (self, converted_tree,
+ = html_convert_tree_new_formatting_context (self, converted_tree,
context_str, 0, context_str, 0);
remove_tree_to_build (self, converted_tree);
@@ -3319,8 +2992,9 @@ html_default_format_single_footnote (CONVERTER *self,
const ELEMENT *element,
xasprintf (&context_str, "%s %d %s", element_command_name (element),
number_in_doc, footid);
footnote_text
- = convert_tree_new_formatting_context (self, element->e.c->args.list[0],
- context_str, 0, 0, 0);
+ = html_convert_tree_new_formatting_context (self,
+ element->e.c->args.list[0],
+ context_str, 0, 0, 0);
free (context_str);
footnote_text_len = strlen (footnote_text);
@@ -3696,8 +3370,8 @@ html_default_format_end_file (CONVERTER *self, const char
*filename,
}
char *
-format_end_file (CONVERTER *self, const char *filename,
- const OUTPUT_UNIT *output_unit)
+html_format_end_file (CONVERTER *self, const char *filename,
+ const OUTPUT_UNIT *output_unit)
{
const FORMATTING_REFERENCE *formatting_reference
= &self->current_formatting_references[FR_format_end_file];
@@ -3731,8 +3405,8 @@ destroy_begin_file_information (BEGIN_FILE_INFORMATION
*begin_info)
{
free (begin_info->title);
free (begin_info->description);
- free (begin_info->keywords);
free (begin_info->encoding);
+ free (begin_info->keywords);
free (begin_info->css_lines);
free (begin_info->root_html_element_attributes);
free (begin_info->body_attributes);
@@ -3742,26 +3416,6 @@ destroy_begin_file_information (BEGIN_FILE_INFORMATION
*begin_info)
free (begin_info);
}
-/* return string to be freed by the caller */
-static char *
-convert_string_tree_new_formatting_context (CONVERTER *self, ELEMENT *tree,
- const char *context_string, const char *multiple_pass)
-{
- ELEMENT *tree_root_string = new_element (ET__string);
- char *result;
-
- add_to_contents_as_array (tree_root_string, tree);
-
- add_tree_to_build (self, tree_root_string);
-
- result = convert_tree_new_formatting_context (self, tree_root_string,
- context_string, multiple_pass, 0, 0);
-
- remove_tree_to_build (self, tree_root_string);
- destroy_element (tree_root_string);
- return result;
-}
-
void
html_default_format_css_lines (CONVERTER *self, const char *filename,
TEXT *result)
@@ -3837,7 +3491,7 @@ html_default_format_css_lines (CONVERTER *self, const
char *filename,
protected_ref);
free (protected_ref);
- close_html_lone_element (self, result);
+ html_close_lone_element (self, result);
text_append_n (result, "\n", 1);
}
}
@@ -3960,7 +3614,7 @@ file_header_information (CONVERTER *self, const ELEMENT
*command,
context_str = strdup ("file_header_title-element-");
begin_info->title
- = convert_string_tree_new_formatting_context (self,
+ = html_convert_string_tree_new_formatting_context (self,
title_tree, context_str,
"element_title");
@@ -3993,7 +3647,7 @@ file_header_information (CONVERTER *self, const ELEMENT
*command,
{
text_printf (&text,
"<meta name=\"description\" content=\"%s\"", description);
- close_html_lone_element (self, &text);
+ html_close_lone_element (self, &text);
begin_info->description = strdup (text.text);
}
@@ -4006,7 +3660,7 @@ file_header_information (CONVERTER *self, const ELEMENT
*command,
text_printf (&text,
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"",
self->conf->OUTPUT_ENCODING_NAME.o.string);
- close_html_lone_element (self, &text);
+ html_close_lone_element (self, &text);
begin_info->encoding = strdup (text.text);
}
@@ -4040,7 +3694,7 @@ file_header_information (CONVERTER *self, const ELEMENT
*command,
{
text_printf (&text, "<meta name=\"Generator\" content=\"%s\"",
self->conf->PROGRAM.o.string);
- close_html_lone_element (self, &text);
+ html_close_lone_element (self, &text);
text_append_n (&text, "\n", 1);
begin_info->generator = strdup (text.text);
text_reset (&text);
@@ -4091,7 +3745,7 @@ file_header_information (CONVERTER *self, const ELEMENT
*command,
free (jsdir);
text_printf (&text, "<link rel=\"stylesheet\" type=\"text/css\" "
"href=\"%sinfo.css\"", protected_jsdir);
- close_html_lone_element (self, &text);
+ html_close_lone_element (self, &text);
text_printf (&text, "\n<script src=\"%smodernizr.js\" "
"type=\"text/javascript\"></script>\n"
"<script src=\"%sinfo.js\" type=\"text/javascript\"></script>",
@@ -4157,7 +3811,7 @@ get_links (CONVERTER* self, const char *filename,
text_printf (result, " title=\"%s\"", link_string);
free (link_string);
}
- close_html_lone_element (self, result);
+ html_close_lone_element (self, result);
text_append_n (result, "\n", 1);
}
free (link_href);
@@ -4231,10 +3885,10 @@ html_default_format_begin_file (CONVERTER *self, const
char *filename,
text_append_n (&result, "\n", 1);
}
text_append (&result, "<meta name=\"resource-type\" content=\"document\"");
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
text_append_n (&result, "\n", 1);
text_append (&result, "<meta name=\"distribution\" content=\"global\"");
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
text_append_n (&result, "\n", 1);
if (begin_info->generator)
text_append (&result, begin_info->generator);
@@ -4242,7 +3896,7 @@ html_default_format_begin_file (CONVERTER *self, const
char *filename,
text_append (&result, self->date_in_header);
text_append (&result,
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"");
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
text_append_n (&result, "\n\n", 2);
get_links (self, filename, output_unit, node_command, &result);
@@ -4263,8 +3917,8 @@ html_default_format_begin_file (CONVERTER *self, const
char *filename,
/* return string to be freed by the caller */
char *
-format_begin_file (CONVERTER *self, const char *filename,
- const OUTPUT_UNIT *output_unit)
+html_format_begin_file (CONVERTER *self, const char *filename,
+ const OUTPUT_UNIT *output_unit)
{
const FORMATTING_REFERENCE *formatting_reference
= &self->current_formatting_references[FR_format_begin_file];
@@ -4321,7 +3975,7 @@ html_default_format_button_icon_img (CONVERTER *self,
text_append (&result, button_name);
text_append_n (&result, "\"", 1);
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
return result.text;
}
@@ -5316,6 +4970,93 @@ format_element_footer (CONVERTER *self,
}
}
+void
+html_default_format_date_in_header (CONVERTER *self, TEXT *result)
+{
+ ELEMENT *today_element = new_command_element (ET_brace_noarg_command,
+ CM_today);
+ char *today;
+
+ add_tree_to_build (self, today_element);
+ today = html_convert_tree_new_formatting_context (self, today_element,
+ "DATE_IN_HEADER", 0, 0, 0);
+ remove_tree_to_build (self, today_element);
+ destroy_element (today_element);
+
+ text_printf (result,
+ "<meta name=\"date\" content=\"%s\"", today);
+ free (today);
+ html_close_lone_element (self, result);
+ text_append_n (result, "\n", 1);
+}
+
+/* return string to be freed by the caller */
+char *
+html_default_format_jslicense_file (CONVERTER *self,
+ const JSLICENSE_CATEGORY_LIST *jslicenses)
+{
+ TEXT result;
+ size_t i;
+ char *root_html_element_attributes;
+
+ text_init (&result);
+
+ if (self->conf->DOCTYPE.o.string)
+ text_append (&result, self->conf->DOCTYPE.o.string);
+ text_append_n (&result, "\n", 1);
+ root_html_element_attributes
+ = root_html_element_attributes_string (self);
+ if (!root_html_element_attributes)
+ root_html_element_attributes = strdup ("");
+ text_printf (&result, "<html%s>", root_html_element_attributes);
+ free (root_html_element_attributes);
+ text_append (&result, "<head><title>jslicense labels</title></head>\n"
+ "<body>\n"
+ "<table id=\"jslicense-labels1\">\n");
+
+ for (i = 0; i < jslicenses->number; i++)
+ {
+ size_t j;
+ JSLICENSE_FILE_INFO_LIST *jlicense_file_info_list
+ = &jslicenses->list[i];
+
+ for (j = 0; j < jlicense_file_info_list->number; j++)
+ {
+ JSLICENSE_FILE_INFO *jlicense_file_info
+ = &jlicense_file_info_list->list[j];
+ char *p_file
+ = url_protect_url_text (self, jlicense_file_info->filename);
+ char *p_url
+ = url_protect_url_text (self, jlicense_file_info->url);
+ char *p_source
+ = url_protect_url_text (self, jlicense_file_info->source);
+ text_append_n (&result, "<tr>\n", 5);
+ text_append_n (&result, "<td><a href=\"", 13);
+ text_append (&result, p_file);
+ text_append_n (&result, "\">", 2);
+ text_append (&result, jlicense_file_info->filename);
+ text_append_n (&result, "</a></td>\n", 10);
+ text_append_n (&result, "<td><a href=\"", 13);
+ text_append (&result, p_url);
+ text_append_n (&result, "\">", 2);
+ text_append (&result, jlicense_file_info->license);
+ text_append_n (&result, "</a></td>\n", 10);
+ text_append_n (&result, "<td><a href=\"", 13);
+ text_append (&result, p_source);
+ text_append_n (&result, "\">", 2);
+ text_append (&result, jlicense_file_info->source);
+ text_append_n (&result, "</a></td>\n", 10);
+ text_append_n (&result, "</tr>\n", 6);
+ free (p_file);
+ free (p_url);
+ free (p_source);
+ }
+ }
+ text_append_n (&result, "</table>\n</body></html>\n", 24);
+
+ return result.text;
+}
+
/* return string to be freed by the caller */
char *
html_default_format_node_redirection_page (CONVERTER *self,
@@ -5341,7 +5082,7 @@ html_default_format_node_redirection_page (CONVERTER
*self,
/* do it before in case there is CSS */
text_init (&body);
- translate_convert_tree_append (
+ html_translate_convert_tree_append (
"The node you are looking for is at {href}.",
self, substrings, 0, &body, "Tr redirection sentence");
destroy_named_string_element_list (substrings);
@@ -5383,10 +5124,10 @@ html_default_format_node_redirection_page (CONVERTER
*self,
text_append_n (&result, "\n", 1);
}
text_append (&result, "<meta name=\"resource-type\" content=\"document\"");
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
text_append_n (&result, "\n", 1);
text_append (&result, "<meta name=\"distribution\" content=\"global\"");
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
text_append_n (&result, "\n", 1);
if (begin_info->generator)
text_append (&result, begin_info->generator);
@@ -5396,11 +5137,11 @@ html_default_format_node_redirection_page (CONVERTER
*self,
text_append_n (&result, "\n", 1);
text_printf (&result, "<meta http-equiv=\"Refresh\" content=\"0; url=%s\"",
href);
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
text_append_n (&result, "\n", 1);
text_append (&result,
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"");
- close_html_lone_element (self, &result);
+ html_close_lone_element (self, &result);
text_append_n (&result, "\n", 1);
free (href);
@@ -5424,8 +5165,8 @@ html_default_format_node_redirection_page (CONVERTER
*self,
/* return string to be freed by the caller */
char *
-format_node_redirection_page (CONVERTER *self, const ELEMENT *element,
- const char *filename)
+html_format_node_redirection_page (CONVERTER *self, const ELEMENT *element,
+ const char *filename)
{
const FORMATTING_REFERENCE *formatting_reference
= &self->current_formatting_references[FR_format_node_redirection_page];
@@ -6374,7 +6115,7 @@ html_convert_image_command (CONVERTER *self, const enum
command_id cmd,
alt_string);
free (protected_image_file);
- close_html_lone_element (self, result);
+ html_close_lone_element (self, result);
}
}
@@ -7111,9 +6852,41 @@ html_convert_heading_command (CONVERTER *self, const
enum command_id cmd,
if (self->conf->NO_TOP_NODE_OUTPUT.o.integer > 0
&& builtin_command_data[cmd].flags & CF_root)
{
+ const ELEMENT *node_element = 0;
int in_skipped_node_top
= self->shared_conversion_state.in_skipped_node_top;
+ if (cmd == CM_node)
+ node_element = element;
+ else if (cmd == CM_part)
+ {
+ const ELEMENT *part_following_node
+ = lookup_extra_element (element, AI_key_part_following_node);
+ if (part_following_node)
+ node_element = part_following_node;
+ }
+ if (node_element || cmd == CM_part)
+ {
+ int node_is_top = 0;
+ if (node_element)
+ {
+ const char *normalized = lookup_extra_string (node_element,
+ AI_key_normalized);
+ if (normalized && !strcmp (normalized, "Top"))
+ {
+ node_is_top = 1;
+ in_skipped_node_top = 1;
+ self->shared_conversion_state.in_skipped_node_top
+ = in_skipped_node_top;
+ }
+ }
+ if (!node_is_top && in_skipped_node_top == 1)
+ {
+ in_skipped_node_top = -1;
+ self->shared_conversion_state.in_skipped_node_top
+ = in_skipped_node_top;
+ }
+ }
if (in_skipped_node_top == 1)
{
format_separate_anchor (self, element_id,
@@ -8306,7 +8079,7 @@ html_convert_float_command (CONVERTER *self, const enum
command_id cmd,
char *prepended_text;
add_tree_to_build (self, prepended);
prepended_text
- = convert_tree_new_formatting_context (self, prepended,
+ = html_convert_tree_new_formatting_context (self, prepended,
"float prepended", 0, 0, 0);
remove_tree_to_build (self, prepended);
@@ -8324,7 +8097,7 @@ html_convert_float_command (CONVERTER *self, const enum
command_id cmd,
&& caption_element->e.c->args.list[0]->e.c->contents.number > 0)
{
char *caption_text
- = convert_tree_new_formatting_context (self,
+ = html_convert_tree_new_formatting_context (self,
caption_element->e.c->args.list[0], "float caption", 0, 0, 0);
if (caption_text)
{
@@ -8363,7 +8136,7 @@ html_convert_float_command (CONVERTER *self, const enum
command_id cmd,
add_to_element_contents (args, prepended);
add_tree_to_build (self, strong_element);
- prepended_text = convert_tree_new_formatting_context (self,
+ prepended_text = html_convert_tree_new_formatting_context (self,
strong_element, "float number type", 0, 0, 0);
remove_tree_to_build (self, strong_element);
@@ -8377,7 +8150,7 @@ html_convert_float_command (CONVERTER *self, const enum
command_id cmd,
if (prepended_text)
html_register_pending_formatted_inline_content (self,
caption_command_name, prepended_text);
- caption_text = convert_tree_new_formatting_context (self,
+ caption_text = html_convert_tree_new_formatting_context (self,
caption_element->e.c->args.list[0], "float caption",
0, 0, 0);
if (prepended_text)
@@ -8406,7 +8179,7 @@ html_convert_float_command (CONVERTER *self, const enum
command_id cmd,
}
else if (caption_element)
{
- caption_text = convert_tree_new_formatting_context (self,
+ caption_text = html_convert_tree_new_formatting_context (self,
caption_element->e.c->args.list[0], "float caption",
0, 0, 0);
}
@@ -8507,7 +8280,7 @@ html_convert_quotation_command (CONVERTER *self, const
enum command_id cmd,
"author", author_arg_copy);
/* TRANSLATORS: quotation author */
- translate_convert_tree_append (
+ html_translate_convert_tree_append (
"@center --- @emph{{author}}",
self, substrings, 0, result,
"convert quotation author");
@@ -8569,105 +8342,19 @@ html_convert_cartouche_command (CONVERTER *self, const
enum command_id cmd,
destroy_strings_list (classes);
}
-void
-default_css_string_format_protect_text (const char *text, TEXT *result)
-{
- const char *p = text;
+SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD
+ special_list_mark_css_string_no_arg_command[] = {
+ {CM_minus, "\\2212 ", 0},
+ {0, 0, 0},
+};
- while (*p)
- {
- int before_sep_nr = strcspn (p, "\\'");
- if (before_sep_nr)
- {
- text_append_n (result, p, before_sep_nr);
- p += before_sep_nr;
- }
- if (!*p)
- break;
- switch (*p)
- {
- case '\\':
- text_append_n (result, "\\\\", 2);
- break;
- case '\'':
- text_append_n (result, "\\'", 2);
- break;
- }
- p++;
- }
-}
-
-/* NOTE these switches are not done in perl, so the only perl functions
- that can be called are perl functions that do not call formatting/conversion
- functions or the formatting/conversion functions for HTML will be used. */
-char *
-html_convert_css_string (CONVERTER *self, const ELEMENT *element,
- const char *context_str)
-{
- char *css_string_context_str;
- char *context_string_str;
- char *explanation;
- char *result;
-
- void (* saved_current_format_protect_text) (const char *text, TEXT *result);
- FORMATTING_REFERENCE *saved_formatting_references
- = self->current_formatting_references;
- COMMAND_CONVERSION_FUNCTION *saved_commands_conversion_function
- = self->current_commands_conversion_function;
- TYPE_CONVERSION_FUNCTION *saved_types_conversion_function
- = self->current_types_conversion_function;
- saved_current_format_protect_text = self->current_format_protect_text;
-
- self->current_formatting_references
- = &self->css_string_formatting_references[0];
- self->current_commands_conversion_function
- = &self->css_string_command_conversion_function[0];
- self->current_types_conversion_function
- = &self->css_string_type_conversion_function[0];
- self->current_format_protect_text = &default_css_string_format_protect_text;
-
- if (context_str)
- xasprintf (&css_string_context_str, "CSS string %s");
- else
- css_string_context_str = "CSS string ";
-
- xasprintf (&context_string_str, "C(%s)", css_string_context_str);
- xasprintf (&explanation, "new_fmt_ctx %s", context_string_str);
-
- html_new_document_context (self, css_string_context_str, 0, 0);
- html_set_string_context (self);
-
- result = html_convert_tree (self, element, explanation);
-
- html_pop_document_context (self);
-
- free (explanation);
- free (context_string_str);
- if (context_str)
- free (css_string_context_str);
-
- self->current_formatting_references = saved_formatting_references;
- self->current_commands_conversion_function
- = saved_commands_conversion_function;
- self->current_types_conversion_function = saved_types_conversion_function;
- self->current_format_protect_text = saved_current_format_protect_text;
-
- return result;
-}
-
-SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD
- special_list_mark_css_string_no_arg_command[] = {
- {CM_minus, "\\2212 ", 0},
- {0, 0, 0},
-};
-
-char *
-html_convert_css_string_for_list_mark (CONVERTER *self, const ELEMENT *element,
- const char *explanation)
-{
- char *result;
- int i;
- for (i = 0; special_list_mark_css_string_no_arg_command[i].cmd > 0; i++)
+char *
+html_convert_css_string_for_list_mark (CONVERTER *self, const ELEMENT *element,
+ const char *explanation)
+{
+ char *result;
+ int i;
+ for (i = 0; special_list_mark_css_string_no_arg_command[i].cmd > 0; i++)
{
enum command_id cmd = special_list_mark_css_string_no_arg_command[i].cmd;
special_list_mark_css_string_no_arg_command[i].saved
@@ -9525,7 +9212,7 @@ html_convert_listoffloats_command (CONVERTER *self, const
enum command_id cmd,
if (caption_element)
{
char *caption_text
- = convert_tree_new_formatting_context (self,
+ = html_convert_tree_new_formatting_context (self,
caption_element->e.c->args.list[0],
builtin_command_name (cmd),
multiple_pass_str, 0, 0);
@@ -9589,7 +9276,7 @@ printindex_letters_head_foot_internal (CONVERTER *self,
const char *index_name,
text_append_n (result, "><tr><th>", 9);
/* TRANSLATORS: before list of letters and symbols grouping index entries */
- translate_convert_tree_append ("Jump to", self, 0, 0, result,
+ html_translate_convert_tree_append ("Jump to", self, 0, 0, result,
letters_header_explanation);
text_append_n (result, ": ", 2);
text_append_n (result,
@@ -9871,7 +9558,8 @@ html_convert_printindex_command (CONVERTER *self, const
enum command_id cmd,
index_entry_ref->index_name);
entry_index = self->sorted_index_names.list[entry_index_nr-1];
- /* to avoid double error messages, call convert_tree_new_formatting_context
+ /* to avoid double error messages, call
+ html_convert_tree_new_formatting_context
below with a multiple_pass argument if an entry was already formatted once,
for example if there are multiple printindex. */
formatted_index_entry_nr
@@ -9992,7 +9680,7 @@ html_convert_printindex_command (CONVERTER *self, const
enum command_id cmd,
if (*formatted_index_entry_nr > 1)
{
/* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
+ entry = html_convert_tree_new_formatting_context (self,
entry_trees[level], convert_info,
multiple_pass_str, 0, 0);
}
@@ -10100,7 +9788,7 @@ html_convert_printindex_command (CONVERTER *self, const
enum command_id cmd,
if (*formatted_index_entry_nr > 1)
{
/* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
+ entry = html_convert_tree_new_formatting_context (self,
result_tree, convert_info, multiple_pass_str, 0,
0);
}
else
@@ -10140,10 +9828,11 @@ html_convert_printindex_command (CONVERTER *self,
const enum command_id cmd,
if (*formatted_index_entry_nr > 1)
{
/* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
+ entry = html_convert_tree_new_formatting_context (self,
entry_tree, conv_str_entry,
multiple_pass_str, 0, 0);
- reference = convert_tree_new_formatting_context (self,
+ reference
+ = html_convert_tree_new_formatting_context (self,
reference_tree, conv_str_reference,
multiple_pass_str, 0, 0);
}
@@ -10223,7 +9912,7 @@ html_convert_printindex_command (CONVERTER *self, const
enum command_id cmd,
if (*formatted_index_entry_nr > 1)
{
/* call with multiple_pass argument */
- entry = convert_tree_new_formatting_context (self,
+ entry = html_convert_tree_new_formatting_context (self,
entry_tree, convert_info,
multiple_pass_str, 0, 0);
}
@@ -10647,7 +10336,7 @@ html_convert_printindex_command (CONVERTER *self, const
enum command_id cmd,
free (attribute_class);
text_append_n (result, ">", 1);
/* TRANSLATORS: index entries column header in index formatting */
- translate_convert_tree_append ("Index Entry", self, 0, 0, result,
+ html_translate_convert_tree_append ("Index Entry", self, 0, 0, result,
"Tr th idx entries 1");
text_append_n (result, "</th>", 5);
@@ -10661,7 +10350,7 @@ html_convert_printindex_command (CONVERTER *self, const
enum command_id cmd,
free (attribute_class);
text_append_n (result, ">", 1);
/* TRANSLATORS: section of index entry column header in index formatting */
- translate_convert_tree_append ("Section", self, 0, 0, result,
+ html_translate_convert_tree_append ("Section", self, 0, 0, result,
"Tr th idx entries 2");
text_append_n (result, "</th></tr>\n", 11);
text_append_n (result, "<tr><td colspan=\"3\">", 20);
@@ -10996,7 +10685,7 @@ html_css_string_convert_text (CONVERTER *self, const
enum element_type type,
if (html_in_code (self) || html_in_math (self))
{
- default_css_string_format_protect_text (content_used, result);
+ html_default_css_string_format_protect_text (content_used, result);
goto out;
}
@@ -11682,7 +11371,8 @@ html_convert_menu_entry_type (CONVERTER *self, const
enum element_type type,
}
description
- = convert_tree_new_formatting_context (self, description_element,
+ = html_convert_tree_new_formatting_context (self,
+ description_element,
"menu_arg node description preformatted", multiple_formatted,
0, CM_menu);
@@ -11830,7 +11520,8 @@ html_convert_menu_entry_type (CONVERTER *self, const
enum element_type type,
}
description
- = convert_tree_new_formatting_context (self, description_element,
+ = html_convert_tree_new_formatting_context (self,
+ description_element,
"menu_arg node description", multiple_formatted,
0, CM_menu);
@@ -12646,7 +12337,7 @@ format_simpletitle (CONVERTER *self, TEXT *result)
xasprintf (&context_str, "%s simpletitle",
builtin_command_name (cmd));
title_text
- = convert_tree_new_formatting_context (self,
+ = html_convert_tree_new_formatting_context (self,
self->simpletitle_tree, context_str, 0, 0, 0);
free (context_str);
format_heading_text (self, cmd, classes, title_text,
@@ -12729,7 +12420,7 @@ html_default_format_title_titlepage (CONVERTER *self)
}
char *
-format_title_titlepage (CONVERTER *self)
+html_format_title_titlepage (CONVERTER *self)
{
const FORMATTING_REFERENCE *formatting_reference
= &self->current_formatting_references[FR_format_title_titlepage];
@@ -12835,14 +12526,14 @@ html_default_format_special_body_about (CONVERTER
*self,
if (!buttons)
{
- translate_convert_tree_append (
+ html_translate_convert_tree_append (
"There are no buttons for this document.", self, 0, 0,
result, "ABOUT");
text_append_n (result, "\n</p>\n", 6);
return;
}
- translate_convert_tree_append (
+ html_translate_convert_tree_append (
" The buttons in the navigation panels have the following meaning:",
self, 0, 0, result, "ABOUT");
text_append_n (result, "\n</p>\n", 6);
@@ -12944,30 +12635,30 @@ html_default_format_special_body_about (CONVERTER
*self,
text_append_n (result, "</table>\n\n<p>\n", 14);
- translate_convert_tree_append (
+ html_translate_convert_tree_append (
" where the @strong{ Example } assumes that the current position is at "
"@strong{ Subsubsection One-Two-Three } of a document of the following "
"structure:", self, 0, 0, result, "ABOUT");
text_append_n (result, "\n</p>\n\n<ul>\n", 12);
text_append (result, " <li> 1. ");
- translate_convert_tree_append ("Section One",
+ html_translate_convert_tree_append ("Section One",
self, 0, 0, result, "ABOUT");
text_append (result, "\n <ul>\n <li>1.1 ");
- translate_convert_tree_append ("Subsection One-One",
+ html_translate_convert_tree_append ("Subsection One-One",
self, 0, 0, result, "ABOUT");
text_append (result, "\n <ul>\n <li>...</li>\n"
" </ul>\n </li>\n <li>1.2 ");
- translate_convert_tree_append ("Subsection One-Two",
+ html_translate_convert_tree_append ("Subsection One-Two",
self, 0, 0, result, "ABOUT");
text_append (result, "\n <ul>\n <li>1.2.1 ");
- translate_convert_tree_append ("Subsubsection One-Two-One",
+ html_translate_convert_tree_append ("Subsubsection One-Two-One",
self, 0, 0, result, "ABOUT");
text_append (result, "</li>\n <li>1.2.2 ");
- translate_convert_tree_append ("Subsubsection One-Two-Two",
+ html_translate_convert_tree_append ("Subsubsection One-Two-Two",
self, 0, 0, result, "ABOUT");
text_append (result, "</li>\n <li>1.2.3 ");
- translate_convert_tree_append ("Subsubsection One-Two-Three",
+ html_translate_convert_tree_append ("Subsubsection One-Two-Three",
self, 0, 0, result, "ABOUT");
text_append_n (result, " ", 1);
text_append_n (result,
@@ -12980,2597 +12671,18 @@ html_default_format_special_body_about (CONVERTER
*self,
text_append_n (result, "\n", 1);
text_append (result, " <strong><== ");
- translate_convert_tree_append ("Current Position",
+ html_translate_convert_tree_append ("Current Position",
self, 0, 0, result, "ABOUT");
text_append (result, " </strong></li>\n <li>1.2.4 ");
- translate_convert_tree_append ("Subsubsection One-Two-Four",
+ html_translate_convert_tree_append ("Subsubsection One-Two-Four",
self, 0, 0, result, "ABOUT");
text_append (result, "</li>\n </ul>\n </li>\n <li>1.3 ");
- translate_convert_tree_append ("Subsection One-Three",
+ html_translate_convert_tree_append ("Subsection One-Three",
self, 0, 0, result, "ABOUT");
text_append (result, "\n <ul>\n <li>...</li>\n"
" </ul>\n </li>\n <li>1.4 ");
- translate_convert_tree_append ("Subsection One-Four",
+ html_translate_convert_tree_append ("Subsection One-Four",
self, 0, 0, result, "ABOUT");
text_append (result, "</li>\n </ul>\n </li>\n</ul>\n");
}
-
-
-/* reset translated data and translate no args commands */
-
-void
-html_clear_direction_string_type (const CONVERTER *self,
- char ***type_directions_strings)
-{
- int i;
- int nr_string_directions = NON_SPECIAL_DIRECTIONS_NR - FIRSTINFILE_NR
- + self->special_unit_varieties.number;
- int nr_dir_str_contexts = TDS_context_string + 1;
-
- for (i = 0; i < nr_string_directions; i++)
- {
- char **direction_strings = type_directions_strings[i];
- int j;
- /* NULL only happens for customized_directions_strings */
- if (direction_strings != NULL)
- {
- for (j = 0; j < nr_dir_str_contexts; j++)
- {
- free (direction_strings[j]);
- direction_strings[j] = 0;
- }
- }
- }
-}
-
-void
-html_reset_translated_special_unit_info_tree (CONVERTER *self)
-{
- STRING_LIST *special_unit_varieties = &self->special_unit_varieties;
- int j;
- for (j = 0; translated_special_unit_info[j].tree_type != SUIT_type_none; j++)
- {
- size_t i;
- enum special_unit_info_tree tree_type
- = translated_special_unit_info[j].tree_type;
- for (i = 0; i < special_unit_varieties->number; i++)
- {
- if (self->special_unit_info_tree[tree_type][i])
- {
- remove_tree_to_build (self,
- self->special_unit_info_tree[tree_type][i]);
- destroy_element_and_children (
- self->special_unit_info_tree[tree_type][i]);
-
- }
- self->special_unit_info_tree[tree_type][i] = 0;
- }
- }
-}
-
-static void
-reset_unset_no_arg_commands_formatting_context (CONVERTER *self,
- enum command_id cmd, enum conversion_context reset_context,
- enum conversion_context ref_context, int translate)
-{
- HTML_NO_ARG_COMMAND_CONVERSION *no_arg_command_context;
- HTML_NO_ARG_COMMAND_CONVERSION *conversion_contexts
- = self->html_no_arg_command_conversion[cmd];
- no_arg_command_context = &conversion_contexts[reset_context];
- if (ref_context >= 0)
- {
- if (no_arg_command_context->unset)
- {
- HTML_NO_ARG_COMMAND_CONVERSION *no_arg_ref
- = &conversion_contexts[ref_context];
-
- if (no_arg_ref->text)
- {
- free (no_arg_command_context->text);
- no_arg_command_context->text = strdup (no_arg_ref->text);
- }
- if (no_arg_ref->translated_tree)
- no_arg_command_context->translated_tree
- = no_arg_ref->translated_tree;
- if (no_arg_ref->translated_converted)
- {
- free (no_arg_command_context->translated_converted);
- no_arg_command_context->translated_converted
- = strdup (no_arg_ref->translated_converted);
- }
- if (no_arg_ref->translated_to_convert)
- {
- free (no_arg_command_context->translated_to_convert);
- no_arg_command_context->translated_to_convert
- = strdup (no_arg_ref->translated_to_convert);
- }
- }
- }
-
- if (translate
- && no_arg_command_context->translated_tree
- && !no_arg_command_context->translated_converted)
- {
- char *translation_result = 0;
- char *explanation;
- char *context;
- ELEMENT *tree_built = 0;
- ELEMENT *translated_tree = no_arg_command_context->translated_tree;
- if (self->external_references_number > 0 && !translated_tree->hv)
- {
- add_to_element_list (&self->tree_to_build, translated_tree);
- tree_built = translated_tree;
- }
- xasprintf (&explanation, "Translated NO ARG @%s ctx %s",
- builtin_command_data[cmd].cmdname,
- html_conversion_context_type_names[reset_context]);
- xasprintf (&context, "Tr %s ctx %s",
- builtin_command_data[cmd].cmdname,
- html_conversion_context_type_names[reset_context]);
- if (reset_context == HCC_type_normal)
- {
- translation_result = html_convert_tree (self, translated_tree,
- explanation);
- }
- else if (reset_context == HCC_type_preformatted)
- {
- enum command_id preformatted_cmd = CM_example;
- /* there does not seems to be anything simpler... */
- html_new_document_context (self, context, 0, 0);
- html_open_command_update_context (self, preformatted_cmd);
- translation_result = html_convert_tree (self, translated_tree,
- explanation);
- html_convert_command_update_context (self, preformatted_cmd);
- html_pop_document_context (self);
- }
- else if (reset_context == HCC_type_string)
- {
- html_new_document_context (self, context, 0, 0);
- html_set_string_context (self);
-
- translation_result = html_convert_tree (self, translated_tree,
- explanation);
- html_pop_document_context (self);
- }
- else if (reset_context == HCC_type_css_string)
- {
- translation_result = html_convert_css_string (self, translated_tree,
- context);
- }
- free (explanation);
- free (context);
- if (no_arg_command_context->text)
- free (no_arg_command_context->text);
- no_arg_command_context->text = translation_result;
- if (tree_built)
- remove_element_from_list (&self->tree_to_build, tree_built);
- }
-}
-
-void
-html_complete_no_arg_commands_formatting (CONVERTER *self, enum command_id cmd,
- int translate)
-{
- reset_unset_no_arg_commands_formatting_context (self, cmd, HCC_type_normal,
- -1, translate);
- reset_unset_no_arg_commands_formatting_context (self, cmd,
- HCC_type_preformatted,
- HCC_type_normal, translate);
- reset_unset_no_arg_commands_formatting_context (self, cmd, HCC_type_string,
- HCC_type_preformatted,
translate);
- reset_unset_no_arg_commands_formatting_context (self, cmd,
HCC_type_css_string,
- HCC_type_string, translate);
-}
-
-void
-html_translate_names (CONVERTER *self)
-{
- size_t j;
- const STRING_LIST *special_unit_varieties = &self->special_unit_varieties;
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- fprintf (stderr, "\nXS|TRANSLATE_NAMES encoding_name: %s"
- " documentlanguage: %s\n",
- self->conf->OUTPUT_ENCODING_NAME.o.string,
- self->conf->documentlanguage.o.string);
- }
-
- /* reset strings such that they are translated when needed. */
- for (j = 0; j < TDS_TRANSLATED_MAX_NR; j++)
- {
- html_clear_direction_string_type (self, self->directions_strings[j]);
- }
-
- /* reset trees such that they are created based on Texinfo code string
- translation on-demand */
- html_reset_translated_special_unit_info_tree (self);
-
- /* delete the tree and formatted results for special elements
- such that they are redone with the new tree when needed. */
- for (j = 0; j < special_unit_varieties->number; j++)
- {
- const char *special_unit_variety = special_unit_varieties->list[j];
- int special_unit_direction_index
- = html_special_unit_variety_direction_index (self,
special_unit_variety);
- if (special_unit_direction_index >= 0)
- {
- const OUTPUT_UNIT *special_unit
- = self->global_units_directions[special_unit_direction_index];
- if (special_unit)
- {
- const ELEMENT *command = special_unit->uc.special_unit_command;
- if (command)
- {
- HTML_TARGET *target_info
- = html_get_target (self, command);
- if (target_info)
- {
- /* the tree is a reference to special_unit_info_tree, so it should
- not be freed, but it needs to be reset to trigger the creation of the
- special_unit_info_tree tree when needed */
- clear_tree_added_elements (self, &target_info->tree);
- free (target_info->command_text[HTT_string]);
- target_info->command_text[HTT_string] = 0;
- free (target_info->command_text[HTT_text]);
- target_info->command_text[HTT_text] = 0;
- free (target_info->command_description[HTT_string]);
- target_info->command_description[HTT_string] = 0;
- free (target_info->command_description[HTT_text]);
- target_info->command_description[HTT_text] = 0;
- }
- }
- }
- }
- }
-
- /* self->no_arg_formatted_cmd_translated is used here to hold the translated
- commands, and the information is kept if it is also used to pass
- translated commands results to Perl */
- {
- size_t translated_nr = 0;
- COMMAND_ID_LIST *translated_cmds
- = &self->no_arg_formatted_cmd_translated;
- /* in general this is done in build_html_translated_names. Still need
- to do it here if build_html_translated_names is never called */
- if (translated_cmds->number)
- {
- memset (translated_cmds->list, 0, translated_cmds->number
- * sizeof (enum command_id));
- }
-
- for (j = 0; j < no_arg_formatted_cmd.number; j++)
- {
- enum command_id cmd = no_arg_formatted_cmd.list[j];
- enum conversion_context cctx;
- int add_cmd = 0;
- for (cctx = 0; cctx < NO_ARG_COMMAND_CONTEXT_NR; cctx++)
- {
- HTML_NO_ARG_COMMAND_CONVERSION *format_spec
- = &self->html_no_arg_command_conversion[cmd][cctx];
- if (format_spec->translated_converted
- && !format_spec->unset)
- {
- add_cmd = 1;
- free (format_spec->text);
- format_spec->text
- = html_cdt_string (format_spec->translated_converted, self,
- 0, 0);
- }
- else if (cctx == HCC_type_normal)
- {
- ELEMENT *translated_tree = 0;
- if (format_spec->translated_to_convert)
- {/* it is very unlikely to have small strings to add,
- but in case there are it should be ok */
- translated_tree =
- html_cdt_tree (format_spec->translated_to_convert,
- self, 0, 0);
- }
- else
- translated_tree = translated_command_tree (self, cmd);
-
- if (translated_tree)
- {
- add_cmd = 1;
- if (format_spec->translated_tree)
- destroy_element_and_children (
- format_spec->translated_tree);
-
- format_spec->translated_tree = translated_tree;
- }
- }
- }
- if (add_cmd)
- {
- translated_cmds->list[translated_nr] = cmd;
- translated_nr++;
- }
- }
-
- translated_cmds->number = translated_nr;
- for (j = 0; j < translated_nr; j++)
- {
- enum command_id cmd = translated_cmds->list[j];
- html_complete_no_arg_commands_formatting (self, cmd, 1);
- }
-
- /* not passed to Perl in that case, unset to avoid spurious error
- messages */
- if (self->external_references_number <= 0)
- {
- memset (translated_cmds->list, 0, translated_cmds->number
- * sizeof (enum command_id));
- translated_cmds->number = 0;
- }
- }
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "END TRANSLATE_NAMES\n\n");
-
- self->modified_state |= HMSF_translations;
-}
-
-
-
-/* last preparations of conversion. At this point conversion of
- Texinfo tree is possible */
-
-static const enum command_id conf_for_documentlanguage[]
- = {CM_documentlanguage, 0};
-
-int
-html_run_stage_handlers (CONVERTER *self,
- enum html_stage_handler_stage_type stage)
-{
- size_t i;
- HTML_STAGE_HANDLER_INFO_LIST *stage_handlers
- = &self->html_stage_handlers[stage];
-
- if (stage_handlers->number > 0)
- {
- const char *stage_name = html_stage_handler_stage_type_names[stage];
-
- for (i = 0; i < stage_handlers->number; i++)
- {
- int call_status;
- HTML_STAGE_HANDLER_INFO *stage_handler
- = &stage_handlers->list[i];
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "RUN handler %zu: stage %s, priority %s\n",
- i +1, stage_name, stage_handler->priority);
-
- if (stage_handler->sv)
- {
- call_status = call_stage_handler (self, stage_handler->sv,
- stage_name);
- if (call_status != 0)
- {
- if (call_status < 0)
- {
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "handler %d of stage %s priority %s failed",
- (int) i+1, stage_name, stage_handler->priority);
- }
- else
- {
- /* the handler is supposed to have output an error message
- already if $status > 0 */
- if (self->conf->DEBUG.o.integer > 0
- || self->conf->VERBOSE.o.integer > 0)
- {
- fprintf (stderr,
- "FAIL handler %zu: stage %s, priority %s\n",
- i +1, stage_name, stage_handler->priority);
- }
- }
- return call_status;
- }
- }
- }
- }
- return 0;
-}
-
-static const enum command_id simpletitle_cmds[] =
- {CM_settitle, CM_shorttitlepage, 0};
-
-void
-html_prepare_simpletitle (CONVERTER *self)
-{
- int i;
- for (i = 0; simpletitle_cmds[i]; i++)
- {
- enum command_id cmd = simpletitle_cmds[i];
- const ELEMENT *command
- = get_cmd_global_uniq_command (&self->document->global_commands, cmd);
- if (command && command->e.c->args.number > 0
- && command->e.c->args.list[0]->e.c->contents.number > 0)
- {
- self->simpletitle_tree = command->e.c->args.list[0];
- self->simpletitle_cmd = cmd;
- break;
- }
- }
-}
-
-/* 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->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));
-
- 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;
-}
-
-void
-html_prepare_title_titlepage (CONVERTER *self, const char *output_file,
- const char *output_filename)
-{
- const OUTPUT_UNIT_LIST *output_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_units]);
-
- if (strlen (output_file))
- {
- self->current_filename.filename = output_units->list[0]->unit_filename;
- self->current_filename.file_number
- = self->output_unit_file_indices[0]+1;
- }
- else
- {
- /* case of convert() call. Need to setup the page here */
- if (self->page_name_number.number <= 0)
- html_setup_output_simple_page (self, output_filename);
- self->current_filename.filename = output_filename;
- self->current_filename.file_number = 1;
- }
-
- self->title_titlepage = format_title_titlepage (self);
- memset (&self->current_filename, 0, sizeof (FILE_NUMBER_NAME));
-}
-
-static const enum command_id fulltitle_cmds[] =
- {CM_settitle, CM_title, CM_shorttitlepage, CM_top, 0};
-
-
-int
-html_prepare_converted_output_info (CONVERTER *self, const char *output_file,
- const char *output_filename)
-{
- int i;
- ELEMENT *fulltitle_tree = 0;
- char *html_title_string = 0;
- char *default_document_language = 0;
- char *preamble_document_language = 0;
- int init_handler_status;
- int handler_fatal_error_level
- = self->conf->HANDLER_FATAL_ERROR_LEVEL.o.integer;
-
- int structure_handler_status
- = html_run_stage_handlers (self, HSHT_type_structure);
-
- if (structure_handler_status < handler_fatal_error_level
- && structure_handler_status > -handler_fatal_error_level)
- {}
- else
- return 0;
-
- if (self->conf->documentlanguage.o.string)
- default_document_language = strdup (self->conf->documentlanguage.o.string);
-
- set_global_document_commands (self, CL_preamble, conf_for_documentlanguage);
-
- if (self->conf->documentlanguage.o.string)
- preamble_document_language = strdup
(self->conf->documentlanguage.o.string);
-
- if (! (!default_document_language && !preamble_document_language)
- && (!default_document_language || !preamble_document_language
- || strcmp (default_document_language, preamble_document_language)))
- html_translate_names (self);
-
- /*
- prepare title. fulltitle uses more possibility than simpletitle for
- title, including @-commands found in @titlepage only. Therefore
- simpletitle is more in line with what makeinfo in C did.
- */
-
- html_prepare_simpletitle (self);
-
- for (i = 0; fulltitle_cmds[i]; i++)
- {
- enum command_id cmd = fulltitle_cmds[i];
- const ELEMENT *command
- = get_cmd_global_uniq_command (&self->document->global_commands, cmd);
- if (command && command->e.c->args.number > 0
- && command->e.c->args.list[0]->e.c->contents.number > 0)
- {
- fulltitle_tree = command->e.c->args.list[0];
- break;
- }
- }
-
- if (!fulltitle_tree
- && self->document->global_commands.titlefont.number > 0
- && self->document->global_commands.titlefont.list[0]->e.c->args.number > 0
- && self->document->global_commands.titlefont.list[0]->e.c->args.list[0]
- ->e.c->contents.number > 0)
- {
- fulltitle_tree = self->document->global_commands.titlefont.list[0];
- }
-
- if (fulltitle_tree)
- {
- self->title_tree = fulltitle_tree;
-
- html_title_string = convert_string_tree_new_formatting_context (self,
- fulltitle_tree, "title_string", 0);
- if (html_title_string[strspn (html_title_string, whitespace_chars)]
- == '\0')
- {
- free (html_title_string);
- html_title_string = 0;
- }
- }
-
- if (!html_title_string)
- {
- ELEMENT *default_title = html_cdt_tree ("Untitled Document",
- self, 0, 0);
- SOURCE_INFO cmd_source_info;
-
- self->title_tree = default_title;
-
- html_title_string = convert_string_tree_new_formatting_context (self,
- default_title, "title_string", 0);
-
- self->added_title_tree = 1;
-
- if (self->document->global_info.input_file_name)
- {
- /* setup a source info with file only */
- memset (&cmd_source_info, 0, sizeof (SOURCE_INFO));
- cmd_source_info.file_name
- = self->document->global_info.input_file_name;
- /* this is more in line with the Perl function used, as DEBUG is
- checked in the called function */
- message_list_line_error_ext (&self->error_messages, self->conf,
- MSG_warning, 0, &cmd_source_info,
- "must specify a title with a title command or @top");
- }
- else
- {
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "must specify a title with a title command or @top");
- }
- }
-
- self->title_string = html_title_string;
-
- /* copying comment */
-
- if (self->document->global_commands.copying)
- {
- char *copying_comment;
- ELEMENT *tmp = new_element (ET_NONE);
-
- tmp->e.c->contents =
self->document->global_commands.copying->e.c->contents;
-
- copying_comment = convert_to_text (tmp, self->convert_text_options);
-
- tmp->e.c->contents.list = 0;
- destroy_element (tmp);
-
- if (copying_comment && strlen (copying_comment) > 0)
- {
- self->copying_comment = format_comment (self, copying_comment);
- }
- free (copying_comment);
- }
-
- /* documentdescription */
- if (self->conf->documentdescription.o.string)
- self->documentdescription_string
- = strdup (self->conf->documentdescription.o.string);
- else if (self->document->global_commands.documentdescription)
- {
- ELEMENT *tmp = new_element (ET_NONE);
- char *documentdescription_string;
- size_t documentdescription_string_len;
-
- tmp->e.c->contents
- = self->document->global_commands.documentdescription->e.c->contents;
-
- documentdescription_string
- = convert_string_tree_new_formatting_context (self,
- tmp, "documentdescription", 0);
-
- tmp->e.c->contents.list = 0;
- destroy_element (tmp);
-
- documentdescription_string_len = strlen (documentdescription_string);
- if (documentdescription_string_len > 0
- && documentdescription_string[documentdescription_string_len -1]
- == '\n')
- documentdescription_string[documentdescription_string_len -1] = '\0';
-
- self->documentdescription_string = documentdescription_string;
- }
-
- init_handler_status = html_run_stage_handlers (self, HSHT_type_init);
-
- if (init_handler_status < handler_fatal_error_level
- && init_handler_status > -handler_fatal_error_level)
- {}
- else
- {
- free (default_document_language);
- free (preamble_document_language);
-
- return 0;
- }
-
- html_prepare_title_titlepage (self, output_file, output_filename);
-
- set_global_document_commands (self, CL_before, conf_for_documentlanguage);
-
- if (! (!default_document_language && !preamble_document_language)
- && (!default_document_language || !preamble_document_language
- || strcmp (default_document_language, preamble_document_language)))
- html_translate_names (self);
-
- free (default_document_language);
- free (preamble_document_language);
-
- return 1;
-}
-
-
-
-/* conversion */
-
-void
-destroy_args_formatted (HTML_ARGS_FORMATTED *args_formatted)
-{
- if (args_formatted)
- {
- size_t i;
- for (i = 0; i < args_formatted->number; i++)
- {
- int j;
- HTML_ARG_FORMATTED *arg_formatted = &args_formatted->args[i];
- if (arg_formatted->arg_tree)
- {
- for (j = 0; j < AFT_type_raw+1; j++)
- free (arg_formatted->formatted[j]);
- }
- }
- free (args_formatted->args);
- }
- free (args_formatted);
-}
-
-
-#define ADD(x) text_append (result, x)
-
-char *
-debug_print_html_contexts (const CONVERTER *self)
-{
- size_t i;
- TEXT contexts_str;
- text_init (&contexts_str);
- text_append (&contexts_str, "[");
- const HTML_DOCUMENT_CONTEXT_STACK *document_context_stack
- = &self->html_document_context;
- const HTML_DOCUMENT_CONTEXT *top_document_ctx
- = html_top_document_context (self);
- const HTML_FORMATTING_CONTEXT_STACK *formatting_context_stack
- = &top_document_ctx->formatting_context;
-
- for (i = 0; i < document_context_stack->top; i++)
- {
- const HTML_DOCUMENT_CONTEXT *document_context
- = &document_context_stack->stack[i];
- if (i != 0)
- text_append (&contexts_str, "|");
- if (document_context->context)
- text_append (&contexts_str, document_context->context);
- else
- text_append (&contexts_str, "UNDEF");
- }
- text_append (&contexts_str, "](");
-
- for (i = 0; i < formatting_context_stack->top; i++)
- {
- const HTML_FORMATTING_CONTEXT *formatting_context
- = &formatting_context_stack->stack[i];
- if (i != 0)
- text_append (&contexts_str, "|");
- if (formatting_context->context_name)
- text_append (&contexts_str, formatting_context->context_name);
- else
- text_append (&contexts_str, "UNDEF");
-
- }
- text_append (&contexts_str, ")");
- /*
- text_append (&contexts_str, "{");
- for (i = 0; i < top_document_ctx->block_commands.top; i++)
- {
- enum command_id cmd = top_document_ctx->block_commands.stack[i];
- if (i != 0)
- text_append (&contexts_str, "|");
- text_append (&contexts_str, builtin_command_name (cmd));
- }
- text_append (&contexts_str, "}");
- */
- return contexts_str.text;
-}
-
-/* EXPLANATION is used for debugging */
-void
-convert_tree_append (CONVERTER *self, const ELEMENT *element,
- TEXT *result, const char *explanation)
-{
- /* for debugging, for explanations */
- TEXT command_type;
- char *debug_str;
- const char *command_name = 0;
- enum command_id cmd = CM_NONE;
-
- text_init (&command_type);
- if (! (type_data[element->type].flags & TF_text))
- {
- cmd = element_builtin_cmd (element);
- command_name = element_command_name (element);
- if (command_name)
- text_printf (&command_type, "@%s ", command_name);
- }
-
- if (element->type)
- text_append (&command_type, type_data[element->type].name);
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- TEXT debug_str;
- char *contexts_str = debug_print_html_contexts (self);
- const char *explanation_str = explanation;
- if (!explanation)
- explanation_str = "NO EXPLANATION";
- text_init (&debug_str);
- text_printf (&debug_str, "XS|ELEMENT(%s) %s, ->", explanation_str,
- contexts_str);
- free (contexts_str);
- if (command_name)
- text_printf (&debug_str, " cmd: %s,", command_name);
- if (element->type)
- text_printf (&debug_str, " type: %s",
- type_data[element->type].name);
- if (type_data[element->type].flags & TF_text)
- {
- if (element->e.text->end > 0)
- {
- char *text = debug_protect_eol (element->e.text->text);
- text_printf (&debug_str, " text: %s", text);
- free (text);
- }
- else
- text_append_n (&debug_str, " text(EMPTY)", 12);
- }
- text_append (&debug_str, "\n");
- /*
- text_printf (&debug_str, "DETAILS: %s",
- print_element_debug_details (element, 0));
- */
- fprintf (stderr, "%s", debug_str.text);
- free (debug_str.text);
- }
-
- /* Process text */
-
- if (type_data[element->type].flags & TF_text)
- {
- TEXT text_result;
- /* NOTE C only text types cannot be ignored here */
- if (self->current_types_conversion_function[element->type].status
- == FRS_status_ignored)
- {
- if (self->conf->DEBUG.o.integer > 0)
- {
- fprintf (stderr, "IGNORED %s\n", command_type.text);
- }
- goto out;
- }
-
- text_init (&text_result);
- text_append (&text_result, "");
-
- /* already converted to html, keep it as is, assume it cannot be NULL */
- if (element->type == ET__converted)
- text_append_n (&text_result, element->e.text->text,
- element->e.text->end);
- else
- {
- (*(self->current_types_conversion_function[ET_text].type_conversion))
- (self, ET_text, element, element->e.text->text,
- &text_result);
- }
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- fprintf (stderr, "XS|DO TEXT => `%s'\n", text_result.text);
- }
-
- ADD(text_result.text);
- free (text_result.text);
- goto out;
- }
-
- /* ignored if ignored both as type and command */
- if ((element->type
- && (self->current_types_conversion_function[element->type].status
- == FRS_status_ignored
- /* type unknown in Perl */
- || (type_data[element->type].flags & TF_at_command
- && element->type != ET_index_entry_command
- && element->type != ET_definfoenclose_command)))
- && (!cmd
- || self->current_commands_conversion_function[cmd].status
- == FRS_status_ignored))
- {
- if (self->conf->DEBUG.o.integer > 0)
- {
- fprintf (stderr, "IGNORED %s\n", command_type.text);
- }
- goto out;
- }
-
- if (cmd
- && (element->type != ET_definfoenclose_command
- && element->type != ET_index_entry_command))
- {
- enum command_id data_cmd = element_builtin_data_cmd (element);
- /* XS only debug message */
- /*
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "COMMAND: %s %s\n",
- builtin_command_data[data_cmd].cmdname,
- builtin_command_data[cmd].cmdname);
- */
-
- if (builtin_command_data[data_cmd].flags & CF_root)
- {
- self->current_root_command = element;
- self->modified_state |= HMSF_current_root;
- }
-
- if (self->current_commands_conversion_function[cmd].command_conversion)
- {
- TEXT content_formatted;
- HTML_ARGS_FORMATTED *args_formatted = 0;
-
- int convert_to_latex
- = html_open_command_update_context (self, data_cmd);
-
- if (self->command_open_function[cmd].command_open)
- {
- (*self->command_open_function[cmd].command_open)
- (self, data_cmd, element, result);
- }
-
- text_init (&content_formatted);
- text_append (&content_formatted, "");
-
- if (element->e.c->contents.number > 0)
- {
-
- if (convert_to_latex
- && !(builtin_command_data[data_cmd].flags & CF_brace))
- {
- ELEMENT *tmp = new_element (ET_NONE);
- char *latex_content;
-
- add_tree_to_build (self, tmp);
- tmp->e.c->contents = element->e.c->contents;
- latex_content = call_latex_convert_to_latex_math (self,
- tmp);
- remove_tree_to_build (self, tmp);
- tmp->e.c->contents.list = 0;
- destroy_element (tmp);
-
- if (latex_content)
- {
- text_append (&content_formatted, latex_content);
- free (latex_content);
- }
- }
- else
- {
- size_t content_idx;
- text_append (&content_formatted, "");
- for (content_idx = 0; content_idx <
element->e.c->contents.number;
- content_idx++)
- {
- const ELEMENT *content
- = element->e.c->contents.list[content_idx];
- char *explanation;
- xasprintf (&explanation, "%s c[%zu]", command_type.text,
- content_idx);
- convert_tree_append (self, content,
- &content_formatted,
- explanation);
- free (explanation);
- }
- }
- }
-
- if ((builtin_command_data[data_cmd].flags & CF_brace)
- || (builtin_command_data[data_cmd].flags & CF_line
- && builtin_command_data[data_cmd].data == LINE_line)
- || ((cmd == CM_item || cmd == CM_itemx)
- && element->parent->type == ET_table_term)
- || (cmd == CM_quotation || cmd == CM_smallquotation)
- || cmd == CM_float
- || cmd == CM_cartouche)
- {
- if (element->e.c->args.number > 0)
- {
- TEXT formatted_arg;
- size_t arg_idx;
-
- text_init (&formatted_arg);
-
- args_formatted = (HTML_ARGS_FORMATTED *)
- malloc (sizeof (HTML_ARGS_FORMATTED));
- args_formatted->number = element->e.c->args.number;
- args_formatted->args = (HTML_ARG_FORMATTED *)
- malloc (args_formatted->number * sizeof (HTML_ARG_FORMATTED));
- memset (args_formatted->args, 0,
- args_formatted->number * sizeof (HTML_ARG_FORMATTED));
-
- for (arg_idx = 0; arg_idx < element->e.c->args.number;
arg_idx++)
- {
- char *explanation;
- unsigned long arg_flags = 0;
- const ELEMENT *arg = element->e.c->args.list[arg_idx];
- HTML_ARG_FORMATTED *arg_formatted
- = &args_formatted->args[arg_idx];
-
- if (arg->e.c->contents.number <= 0)
- {
- continue;
- }
- /* NOTE that commands with F_AFT_none as only flag do not
- have their flag reset to F_AFT_normal here, such that
- their argument is not converter here */
- if (arg_idx < MAX_COMMAND_ARGS_NR
- /* could check html_command_args_flags[cmd].status,
- but it is probably faster not to */
- && html_command_args_flags[cmd].flags[arg_idx])
- arg_flags =
html_command_args_flags[cmd].flags[arg_idx];
- else
- arg_flags = F_AFT_normal;
-
- arg_formatted->arg_tree = arg;
-
- if (arg_flags & F_AFT_normal)
- {
- text_reset (&formatted_arg);
- if (convert_to_latex)
- {
- char *latex_content
- = call_latex_convert_to_latex_math (self,
- arg);
- if (latex_content)
- {
- text_append (&formatted_arg, latex_content);
- free (latex_content);
- }
- }
- else
- {
- xasprintf (&explanation, "%s A[%zu]normal",
- command_type.text, arg_idx);
- convert_tree_append (self, arg,
- &formatted_arg,
- explanation);
- free (explanation);
- }
- arg_formatted->formatted[AFT_type_normal]
- = strdup (formatted_arg.text);
- }
- if (arg_flags & F_AFT_monospace)
- {
- HTML_DOCUMENT_CONTEXT *top_document_ctx
- = html_top_document_context (self);
- text_reset (&formatted_arg);
- xasprintf (&explanation, "%s A[%zu]monospace",
- command_type.text, arg_idx);
- push_integer_stack_integer (
- &top_document_ctx->monospace, 1);
-
- convert_tree_append (self, arg, &formatted_arg,
- explanation);
- pop_integer_stack
- (&top_document_ctx->monospace);
-
- free (explanation);
- arg_formatted->formatted[AFT_type_monospace]
- = strdup (formatted_arg.text);
- }
- if (arg_flags & F_AFT_string)
- {
- HTML_DOCUMENT_CONTEXT *string_document_ctx;
- text_reset (&formatted_arg);
- html_new_document_context (self, command_type.text,
- 0, 0);
- string_document_ctx = html_top_document_context
(self);
- string_document_ctx->string_ctx++;
-
- xasprintf (&explanation, "%s A[%zu]string",
- command_type.text, arg_idx);
- convert_tree_append (self, arg, &formatted_arg,
- explanation);
-
- free (explanation);
-
- html_pop_document_context (self);
-
- arg_formatted->formatted[AFT_type_string]
- = strdup (formatted_arg.text);
- }
- if (arg_flags & F_AFT_monospacestring)
- {
- HTML_DOCUMENT_CONTEXT *string_document_ctx;
- text_reset (&formatted_arg);
- html_new_document_context (self, command_type.text,
- 0, 0);
- string_document_ctx = html_top_document_context
(self);
- string_document_ctx->string_ctx++;
- push_integer_stack_integer (
- &string_document_ctx->monospace, 1);
- xasprintf (&explanation, "%s A[%zu]monospacestring",
- command_type.text, arg_idx);
- convert_tree_append (self, arg, &formatted_arg,
- explanation);
-
- free (explanation);
- pop_integer_stack
- (&string_document_ctx->monospace);
- html_pop_document_context (self);
- arg_formatted->formatted[AFT_type_monospacestring]
- = strdup (formatted_arg.text);
- }
- if (arg_flags & F_AFT_monospacetext)
- {
- char *text;
-
- self->convert_text_options->code_state++;
- text = convert_to_text (arg,
- self->convert_text_options);
- self->convert_text_options->code_state--;
-
- arg_formatted->formatted[AFT_type_monospacetext]
- = text;
- }
- if (arg_flags & F_AFT_filenametext)
- {
- char *text;
- self->convert_text_options->code_state++;
- /* Always use encoded characters for file names */
- text_set_options_encoding_if_not_ascii (self,
- self->convert_text_options);
- text = convert_to_text (arg,
- self->convert_text_options);
- text_reset_options_encoding
- (self->convert_text_options);
- self->convert_text_options->code_state--;
-
- arg_formatted->formatted[AFT_type_filenametext] =
text;
- }
- if (arg_flags & F_AFT_url)
- {
- char *text;
- self->convert_text_options->code_state++;
- /* set the encoding to UTF-8 to always have a string that is
suitable
- for percent encoding. */
- text_set_options_encoding (
- self->convert_text_options, "utf-8");
- text = convert_to_text (arg,
- self->convert_text_options);
- text_reset_options_encoding
- (self->convert_text_options);
- self->convert_text_options->code_state--;
-
- arg_formatted->formatted[AFT_type_url] = text;
- }
- if (arg_flags & F_AFT_raw)
- {
- HTML_DOCUMENT_CONTEXT *top_document_ctx
- = html_top_document_context (self);
- text_reset (&formatted_arg);
- top_document_ctx->raw_ctx++;
- xasprintf (&explanation, "%s A[%zu]raw",
- command_type.text, arg_idx);
- convert_tree_append (self, arg, &formatted_arg,
- explanation);
-
- free (explanation);
- top_document_ctx->raw_ctx--;
- arg_formatted->formatted[AFT_type_raw]
- = strdup (formatted_arg.text);
- }
- }
- free (formatted_arg.text);
- }
- }
-
- html_convert_command_update_context (self, data_cmd);
-
- if (element->e.c->cmd == CM_node)
- {
- self->current_node = element;
- self->modified_state |= HMSF_current_node;
- }
-
- /* args are formatted, now format the command itself */
- if
(self->current_commands_conversion_function[cmd].command_conversion)
- {
- (*self->current_commands_conversion_function[cmd].command_conversion)
- (self, cmd, element, args_formatted,
- content_formatted.text, result);
- }
- else if (args_formatted)
- fprintf (stderr, "No command_conversion for %s\n",
- command_name);
- if (args_formatted)
- destroy_args_formatted (args_formatted);
-
- if (cmd == CM_documentlanguage)
- {
- html_translate_names (self);
- }
-
- free (content_formatted.text);
-
- goto out;
- }
- else
- {
- if (self->conf->DEBUG.o.integer > 0
- || self->conf->VERBOSE.o.integer > 0)
- fprintf (stderr, "Command not converted: %s\n", command_name);
- if (builtin_command_data[data_cmd].flags & CF_root)
- {
- self->current_root_command = 0;
- self->modified_state |= HMSF_current_root;
- }
- goto out;
- }
- }
- else if (element->type)
- {
- enum element_type type = element->type;
- TEXT type_result;
- TEXT content_formatted;
-
- text_init (&type_result);
- text_append (&type_result, "");
-
- html_open_type_update_context (self, type);
-
- if (self->type_open_function[type].type_open)
- (*self->type_open_function[type].type_open)
- (self, type, element, &type_result);
-
- text_init (&content_formatted);
-
- if (type == ET_definfoenclose_command)
- {
- if (element->e.c->args.number > 0)
- {
- convert_tree_append (self, element->e.c->args.list[0],
- &content_formatted,
- "DEFINFOENCLOSE_ARG");
- }
- }
- else if (element->e.c->contents.number > 0
- && type != ET_untranslated_def_line_arg)
- {
- size_t content_idx;
- text_append (&content_formatted, "");
- for (content_idx = 0; content_idx < element->e.c->contents.number;
- content_idx++)
- {
- const ELEMENT *content =
element->e.c->contents.list[content_idx];
- char *explanation;
- xasprintf (&explanation, "%s c[%zu]", command_type.text,
- content_idx);
- convert_tree_append (self, content, &content_formatted,
- explanation);
- free (explanation);
- }
- }
-
- html_convert_type_update_context (self, type);
-
- if (self->current_types_conversion_function[type].type_conversion)
- {
- (*self->current_types_conversion_function[type].type_conversion)
- (self, type, element, content_formatted.text, &type_result);
- }
- else if (content_formatted.end > 0)
- {
- text_append (&type_result, content_formatted.text);
- }
- free (content_formatted.text);
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- fprintf (stderr, "XS|DO type (%s) => `%s'\n", type_data[type].name,
- type_result.text);
- }
- ADD(type_result.text);
- free (type_result.text);
-
- goto out;
- }
- else if (element->e.c->contents.number > 0)
- {
- /* no type, no cmdname, but contents. */
- /* this happens inside accents, for section/node names, for @images. */
- TEXT content_formatted;
-
- text_init (&content_formatted);
- text_append (&content_formatted, "");
-
- size_t content_idx;
- for (content_idx = 0; content_idx < element->e.c->contents.number;
- content_idx++)
- {
- const ELEMENT *content = element->e.c->contents.list[content_idx];
- char *explanation;
- xasprintf (&explanation, " C[%zu]", content_idx);
- convert_tree_append (self, content, &content_formatted,
- explanation);
- free (explanation);
- }
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "UNNAMED HOLDER => `%s'\n", content_formatted.text);
- ADD(content_formatted.text);
- free (content_formatted.text);
- goto out;
- }
- else
- {
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "UNNAMED empty\n");
- if (self->current_types_conversion_function[0].type_conversion)
- {
- (*self->current_types_conversion_function[0].type_conversion)
- (self, 0, element, "", result);
- }
-
- goto out;
- }
- debug_str = print_element_debug (element, 0);
- fprintf (stderr, "DEBUG: HERE!(%p:%s)\n", element, debug_str);
- free (debug_str);
-
- out:
- free (command_type.text);
-}
-#undef ADD
-
-void
-convert_output_unit (CONVERTER *self, const OUTPUT_UNIT *output_unit,
- const char *explanation, TEXT *result)
-{
- TEXT content_formatted;
- /* store this to be able to show only what was added in debug message */
- size_t input_result_end = result->end;
- enum output_unit_type unit_type = output_unit->unit_type;
-
- if (self->output_unit_conversion_function[unit_type].status
- == FRS_status_ignored)
- {
- if (self->conf->DEBUG.o.integer > 0)
- {
- fprintf (stderr, "IGNORED OU %s\n",
- output_unit_type_names[unit_type]);
- }
- return;
- }
-
- if (self->conf->DEBUG.o.integer > 0)
- {
- char *output_unit_txi = output_unit_texi (output_unit);
- fprintf (stderr, "XS|UNIT(%s) -> ou: %s '%s'\n", explanation,
- output_unit_type_names[unit_type],
- output_unit_txi);
- free (output_unit_txi);
- }
-
- self->current_output_unit = output_unit;
-
- text_init (&content_formatted);
- text_append (&content_formatted, "");
-
- if (output_unit->unit_contents.number > 0)
- {
- size_t content_idx;
- for (content_idx = 0; content_idx < output_unit->unit_contents.number;
- content_idx++)
- {
- const ELEMENT *content = output_unit->unit_contents.list[content_idx];
- char *content_explanation;
- xasprintf (&content_explanation, "%s c[%zu]",
- output_unit_type_names[unit_type], content_idx);
- convert_tree_append (self, content, &content_formatted,
- content_explanation);
- free (content_explanation);
- }
- }
-
- if (self->output_unit_conversion_function[unit_type].status)
- {
- (*(self->output_unit_conversion_function[unit_type].output_unit_conversion))
- (self, unit_type, output_unit,
- content_formatted.text, result);
- }
- else
- {
- text_append (result, content_formatted.text);
- }
-
- free (content_formatted.text);
-
- self->current_output_unit = 0;
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "DOUNIT (%s) => `%s'\n",
output_unit_type_names[unit_type],
- result->text + input_result_end);
-}
-
-/* wrapper to avoid code repetition and use similar functions as in perl */
-void
-convert_convert_output_unit_internal (CONVERTER *self, TEXT *result,
- const OUTPUT_UNIT *output_unit,
- size_t unit_nr,
- const char *debug_str,
- const char *explanation_str)
-{
- char *explanation;
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "\n%s %zu\n", debug_str, unit_nr);
-
- xasprintf (&explanation, "%s %zu", explanation_str, unit_nr);
- convert_output_unit (self, output_unit, explanation, result);
- free (explanation);
-}
-
-char *
-html_convert_convert (CONVERTER *self, const ELEMENT *root)
-{
- TEXT result;
- size_t unit_nr = 0;
- size_t i;
-
- const OUTPUT_UNIT_LIST *output_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_units]);
- const OUTPUT_UNIT_LIST *special_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_special_units]);
-
- text_init (&result);
-
- self->current_filename.filename = "";
- self->current_filename.file_number = 1;
-
- for (i = 0; i < output_units->number; i++)
- {
- const OUTPUT_UNIT *output_unit = output_units->list[i];
- convert_convert_output_unit_internal (self, &result, output_unit,
- unit_nr, "C UNIT", "convert unit");
- unit_nr++;
- }
- if (special_units && special_units->number)
- {
- for (i = 0; i < special_units->number; i++)
- {
- const OUTPUT_UNIT *special_unit = special_units->list[i];
- convert_convert_output_unit_internal (self, &result,
- special_unit, unit_nr, "C UNIT", "convert unit");
- unit_nr++;
- }
- }
-
- self->current_filename.filename = 0;
-
- return result.text;
-}
-
-int
-convert_output_output_unit_internal (CONVERTER *self,
- const ENCODING_CONVERSION *conversion,
- TEXT *text,
- const OUTPUT_UNIT *output_unit,
- size_t unit_nr)
-{
- FILE_NAME_PATH_COUNTER *unit_file = 0;
- size_t file_index;
- int empty_body = 0; /* set if body is empty and it is a special unit */
- char *output_unit_filename = output_unit->unit_filename;
-
- self->current_filename.filename = output_unit_filename;
-
- text_reset (text);
- text_append (text, "");
-
- if (output_unit->unit_type == OU_special_unit)
- {
- char *debug_str;
- const char *special_unit_variety = output_unit->special_unit_variety;
-
- file_index = self->special_unit_file_indices[output_unit->index];
- self->current_filename.file_number = file_index +1;
- unit_file = &self->output_unit_files.list[file_index];
-
- xasprintf (&debug_str, "UNIT SPECIAL %s", special_unit_variety);
- convert_convert_output_unit_internal (self, text,
- output_unit, unit_nr, debug_str, "output s-unit");
- free (debug_str);
-
- if (!strcmp (text->text, ""))
- empty_body = 1;
- }
- else
- {
- file_index = self->output_unit_file_indices[output_unit->index];
- self->current_filename.file_number = file_index +1;
- unit_file = &self->output_unit_files.list[file_index];
-
- convert_convert_output_unit_internal (self, text, output_unit,
- unit_nr, "UNIT", "output unit");
- }
-
- unit_file->counter--;
-
- /* register the output but do not print anything. Printing
- only when file_counters reach 0, to be sure that all the
- elements have been converted before headers are done. */
-
- if (!empty_body)
- {
- if (!unit_file->first_unit)
- {
- unit_file->first_unit = output_unit;
- text_init (&unit_file->body);
- }
- text_append (&unit_file->body, text->text);
- }
- else
- {
- if (!unit_file->first_unit
- || unit_file->body.end == 0)
- {
- return 1;
- }
- }
-
- if (unit_file->counter == 0)
- {
- const OUTPUT_UNIT *file_output_unit = unit_file->first_unit;
- char *file_end;
- char *file_beginning;
- char *out_filepath = unit_file->filepath;
- char *path_encoding;
- char *open_error_message;
- int overwritten_file;
-
- char *encoded_out_filepath = encoded_output_file_name (self->conf,
- &self->document->global_info, out_filepath,
- &path_encoding, 0);
- /* overwritten_file being set cannot happen */
- FILE *file_fh = output_files_open_out (&self->output_files_information,
- encoded_out_filepath, &open_error_message,
- &overwritten_file, 0);
- free (path_encoding);
- if (!file_fh)
- {
- message_list_document_error (&self->error_messages, self->conf, 0,
- "could not open %s for writing: %s",
- out_filepath, open_error_message);
- free (open_error_message);
- free (encoded_out_filepath);
- return 0;
- }
-
- /* do end file first in case it requires some CSS */
- file_end = format_end_file (self, output_unit_filename, output_unit);
- file_beginning = format_begin_file (self, output_unit_filename,
- file_output_unit);
- text_reset (text);
- if (file_beginning)
- {
- text_append (text, file_beginning);
- free (file_beginning);
- }
- if (unit_file->body.end)
- {
- text_append (text, unit_file->body.text);
- }
- if (file_end)
- {
- text_append (text, file_end);
- free (file_end);
- }
- if (text->end)
- {
- char *result;
- size_t res_len;
- size_t write_len;
-
- if (conversion)
- {
- result = encode_with_iconv (conversion->iconv, text->text, 0);
- res_len = strlen (result);
- }
- else
- {
- result = text->text;
- res_len = text->end;
- }
- write_len = fwrite (result, sizeof (char), res_len, file_fh);
- if (conversion)
- free (result);
- if (write_len != res_len)
- { /* register error message instead? */
- fprintf (stderr, "ERROR: write to %s failed (%zu/%zu)\n",
- encoded_out_filepath, write_len, res_len);
- free (encoded_out_filepath);
- return 0;
- }
- }
- /* NOTE do not close STDOUT here to be in line with perl code */
- if (strcmp (out_filepath, "-"))
- {
- output_files_register_closed (&self->output_files_information,
- encoded_out_filepath);
- if (fclose (file_fh))
- {
- message_list_document_error (&self->error_messages, self->conf,
0,
- "error on closing %s: %s",
- out_filepath, strerror (errno));
- free (encoded_out_filepath);
- return 0;
- }
- }
- free (encoded_out_filepath);
- }
- return 1;
-}
-
-char *
-html_convert_output (CONVERTER *self, const ELEMENT *root,
- const char *output_file, const char
*destination_directory,
- const char *output_filename, const char *document_name)
-{
- int status = 1;
- TEXT result;
- TEXT text; /* reused for all the output units */
-
- const OUTPUT_UNIT_LIST *output_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_units]);
- const OUTPUT_UNIT_LIST *special_units = retrieve_output_units
- (self->document, self->output_units_descriptors[OUDT_special_units]);
- char *encoded_destination_directory;
- char *dir_encoding;
- int succeeded;
-
- /* cast to remove const since the encoded_output_file_name argument cannot
- be const even though the string is not modified */
- encoded_destination_directory = encoded_output_file_name (self->conf,
- &self->document->global_info,
- (char *)destination_directory,
- &dir_encoding, 0);
- free (dir_encoding);
-
- succeeded = create_destination_directory (self,
- encoded_destination_directory,
- destination_directory);
-
- free (encoded_destination_directory);
-
- if (!succeeded)
- return 0;
-
- text_init (&result);
- text_init (&text);
-
- /* set self->date_in_header to format it only once */
- if (self->conf->DATE_IN_HEADER.o.integer > 0)
- {
- ELEMENT *today_element = new_command_element (ET_brace_noarg_command,
- CM_today);
- char *today;
-
- add_tree_to_build (self, today_element);
- today = convert_tree_new_formatting_context (self, today_element,
- "DATE_IN_HEADER", 0, 0, 0);
- remove_tree_to_build (self, today_element);
- destroy_element (today_element);
-
- text_printf (&text,
- "<meta name=\"date\" content=\"%s\"", today);
- free (today);
- close_html_lone_element (self, &text);
- text_append_n (&text, "\n", 1);
- self->date_in_header = strdup (text.text);
- text_reset (&text);
- }
-
- text_append (&result, "");
-
-
- if (!strlen (output_file))
- {
- char *file_end;
- char *file_beginning;
- size_t unit_nr = 0;
- size_t i;
-
- self->current_filename.filename = output_filename;
- self->current_filename.file_number = 1;
-
- text_append (&text, "");
-
- for (i = 0; i < output_units->number; i++)
- {
- const OUTPUT_UNIT *output_unit = output_units->list[i];
- convert_convert_output_unit_internal (self, &text, output_unit,
- unit_nr, "UNIT NO-PAGE", "no-page output unit");
- unit_nr++;
- }
- if (special_units && special_units->number)
- {
- for (i = 0; i < special_units->number; i++)
- {
- const OUTPUT_UNIT *special_unit = special_units->list[i];
- convert_convert_output_unit_internal (self, &text,
- special_unit, unit_nr, "UNIT NO-PAGE",
- "no-page output unit");
- unit_nr++;
- }
- }
-
- /* do end file first, in case it needs some CSS */
- file_end = format_end_file (self, output_filename, 0);
- file_beginning = format_begin_file (self, output_filename, 0);
- if (file_beginning)
- {
- text_append (&result, file_beginning);
- free (file_beginning);
- }
- text_append (&result, text.text);
- if (file_end)
- {
- text_append (&result, file_end);
- free (file_end);
- }
- self->current_filename.filename = 0;
- }
- else
- {
- size_t unit_nr = 0;
- size_t i;
- const ENCODING_CONVERSION *conversion = 0;
-
- if (self->conf->OUTPUT_ENCODING_NAME.o.string
- && strcmp (self->conf->OUTPUT_ENCODING_NAME.o.string, "utf-8"))
- {
- conversion
- = get_encoding_conversion (
- self->conf->OUTPUT_ENCODING_NAME.o.string,
- &output_conversions);
- }
-
- if (self->conf->DEBUG.o.integer > 0)
- fprintf (stderr, "DO Units with filenames\n");
-
- for (i = 0; i < output_units->number; i++)
- {
- const OUTPUT_UNIT *output_unit = output_units->list[i];
- status = convert_output_output_unit_internal (self, conversion,
- &text, output_unit, unit_nr);
- if (!status)
- {
- /*
- fprintf (stderr, " FAILED U(%d %d): %s\n", i, unit_nr,
- output_unit_texi (output_unit));
- */
- goto out;
- }
- unit_nr++;
- }
- if (special_units && special_units->number)
- {
- for (i = 0; i < special_units->number; i++)
- {
- const OUTPUT_UNIT *special_unit = special_units->list[i];
- status = convert_output_output_unit_internal (self, conversion,
- &text, special_unit, unit_nr);
- if (!status)
- goto out;
- unit_nr++;
- }
- }
- memset (&self->current_filename, 0, sizeof (FILE_NUMBER_NAME));
- }
-
- out:
- free (text.text);
-
- if (status)
- return result.text;
- else
- {
- free (result.text);
- return 0;
- }
-}
-
-
-
-/* This function cleans up the conversion state that is relevant during
- conversion. Other information is removed when calling reset_parser
- later on and should not be freed here */
-void
-html_conversion_finalization (CONVERTER *self)
-{
- size_t i;
- for (i = 0; i < self->html_files_information.number; i++)
- {
- free (self->html_files_information.list[i].info);
- }
- free (self->html_files_information.list);
-
- /* should not be possible with default code, as
- close_registered_sections_level(..., 0)
- is called at the end of processing or at the end of each file.
- However, it could happen if the conversion functions are user
- defined.
- */
- for (i = 0; i < self->pending_closes.number; i++)
- {
- STRING_STACK *file_pending_closes = &self->pending_closes.list[i];
- if (file_pending_closes->top > 0)
- {
- FILE_NAME_PATH_COUNTER *file_counter
- = &self->output_unit_files.list[i];
- const char *page_name = file_counter->filename;
-
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "%s: %zu registered opened sections not closed",
- page_name, file_pending_closes->top);
- clear_string_stack (file_pending_closes);
- }
- }
-
- if (self->pending_inline_content.top > 0)
- {
- char *inline_content = html_get_pending_formatted_inline_content (self);
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "%zu registered inline contents: %s",
- self->pending_inline_content.top, inline_content);
- free (inline_content);
- }
-
- for (i = 0; i < self->associated_inline_content.number; i++)
- {
- HTML_ASSOCIATED_INLINE_CONTENT *associated_content
- = &self->associated_inline_content.list[i];
- if (associated_content->inline_content.space > 0)
- {
- char *inline_content = associated_content->inline_content.text;
- if (associated_content->element)
- {
- char *element_str
- = print_element_debug (associated_content->element, 0);
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "left inline content associated to %s: '%s'", element_str,
- inline_content);
- free (element_str);
- }
- else if (associated_content->hv)
- {
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "left inline content of %p: '%s'", associated_content->hv,
- inline_content);
- }
- else
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "left inline content associated: '%s'", inline_content);
- free (associated_content->inline_content.text);
- }
- }
- self->associated_inline_content.number = 0;
-
- html_pop_document_context (self);
-
- /* could change to 0 in releases? */
- if (1)
- {
- if (self->html_document_context.top > 0)
- fprintf (stderr, "BUG: document context top > 0: %zu\n",
- self->html_document_context.top);
- if (self->document_global_context)
- fprintf (stderr, "BUG: document_global_context: %d\n",
- self->document_global_context);
- if (self->multiple_conversions)
- fprintf (stderr, "BUG: multiple_conversions: %d\n",
- self->multiple_conversions);
- }
-}
-
-void
-html_check_transfer_state_finalization (CONVERTER *self)
-{
- /* could change to 0 in releases? */
- if (1)
- {
- /* check that all the state changes have been transmitted */
- /*
- if (self->tree_to_build.number > 0)
- fprintf (stderr, "BUG: tree_to_build: %zu\n",
- self->tree_to_build.number);
- */
- if (self->no_arg_formatted_cmd_translated.number)
- fprintf (stderr, "BUG: no_arg_formatted_cmd_translated: %zu\n",
- self->no_arg_formatted_cmd_translated.number);
- }
-}
-
-
-
-/* code run after the conversion when called as output */
-
-/* return 0 on success, -1 on write or close error, -2 if file_fh is 0,
- which should mean a failure to open */
-static int
-file_error_or_write_close (CONVERTER *self, const char *out_filepath,
- const char *encoded_out_filepath,
- FILE *file_fh,
- const ENCODING_CONVERSION *conversion,
- char *page,
- const char *open_error_message)
-{
- if (!file_fh)
- {
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "could not open %s for writing: %s",
- out_filepath, open_error_message);
- return -2;
- }
- else
- {
- char *result;
- size_t res_len;
- size_t write_len;
-
- if (conversion)
- {
- result = encode_with_iconv (conversion->iconv,
- page, 0);
- res_len = strlen (result);
- }
- else
- {
- result = page;
- res_len = strlen (page);
- }
- write_len = fwrite (result, sizeof (char),
- res_len, file_fh);
- if (conversion)
- free (result);
- if (write_len != res_len)
- { /* register error message instead? */
- fprintf (stderr,
- "ERROR: write to %s failed (%zu/%zu)\n",
- encoded_out_filepath, write_len, res_len);
- return -1;
- }
- output_files_register_closed
- (&self->output_files_information,
- encoded_out_filepath);
- if (fclose (file_fh))
- {
- message_list_document_error (
- &self->error_messages, self->conf, 0,
- "error on closing %s: %s",
- out_filepath, strerror (errno));
- return -1;
- }
- }
- return 0;
-}
-
-static void
-do_jslicenses_file (CONVERTER *self)
-{
- const char *destination_directory = self->destination_directory;
- const char *setting = self->conf->JS_WEBLABELS.o.string;
- const char *path = self->conf->JS_WEBLABELS_FILE.o.string;
- TEXT result;
- char *root_html_element_attributes;
- size_t i;
- int path_not_ok = 0;
- char *license_file;
- char *path_encoding;
- char *open_error_message;
- int overwritten_file;
- char *encoded_out_filepath;
- FILE *file_fh;
- const ENCODING_CONVERSION *conversion = 0;
-
- /* Possible settings:
- 'generate' - create file at JS_WEBLABELS_FILE
- 'reference' - reference file at JS_WEBLABELS_FILE but do not create it
- 'omit' - do nothing */
- if (!setting || strcmp (setting, "generate") || !path || !strlen (path))
- return;
-
- if (!memcmp (path, "/", 1))
- path_not_ok = 1;
- else
- {
- const char *p = path;
- while (isascii_alpha (*p))
- p++;
- if (*p == ':')
- path_not_ok = 1;
- }
-
- if (path_not_ok)
- {
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "cannot use absolute path or URL `%s' for JS_WEBLABELS_FILE when generating
web labels file",
- path);
- return;
- }
-
- text_init (&result);
- if (self->conf->DOCTYPE.o.string)
- text_append (&result, self->conf->DOCTYPE.o.string);
- text_append_n (&result, "\n", 1);
- root_html_element_attributes
- = root_html_element_attributes_string (self);
- if (!root_html_element_attributes)
- root_html_element_attributes = strdup ("");
- text_printf (&result, "<html%s>", root_html_element_attributes);
- free (root_html_element_attributes);
- text_append (&result, "<head><title>jslicense labels</title></head>\n"
- "<body>\n"
- "<table id=\"jslicense-labels1\">\n");
-
- for (i = 0; i < self->jslicenses.number; i++)
- {
- size_t j;
- JSLICENSE_FILE_INFO_LIST *jlicense_file_info_list
- = &self->jslicenses.list[i];
-
- for (j = 0; j < jlicense_file_info_list->number; j++)
- {
- JSLICENSE_FILE_INFO *jlicense_file_info
- = &jlicense_file_info_list->list[j];
- char *p_file
- = url_protect_url_text (self, jlicense_file_info->filename);
- char *p_url
- = url_protect_url_text (self, jlicense_file_info->url);
- char *p_source
- = url_protect_url_text (self, jlicense_file_info->source);
- text_append_n (&result, "<tr>\n", 5);
- text_append_n (&result, "<td><a href=\"", 13);
- text_append (&result, p_file);
- text_append_n (&result, "\">", 2);
- text_append (&result, jlicense_file_info->filename);
- text_append_n (&result, "</a></td>\n", 10);
- text_append_n (&result, "<td><a href=\"", 13);
- text_append (&result, p_url);
- text_append_n (&result, "\">", 2);
- text_append (&result, jlicense_file_info->license);
- text_append_n (&result, "</a></td>\n", 10);
- text_append_n (&result, "<td><a href=\"", 13);
- text_append (&result, p_source);
- text_append_n (&result, "\">", 2);
- text_append (&result, jlicense_file_info->source);
- text_append_n (&result, "</a></td>\n", 10);
- text_append_n (&result, "</tr>\n", 6);
- free (p_file);
- free (p_url);
- free (p_source);
- }
- }
- text_append_n (&result, "</table>\n</body></html>\n", 24);
-
- if (destination_directory && strlen (destination_directory))
- xasprintf (&license_file, "%s/%s", destination_directory, path);
- else
- license_file = strdup (path);
-
- encoded_out_filepath = encoded_output_file_name (self->conf,
- &self->document->global_info, license_file,
- &path_encoding, 0);
- file_fh = output_files_open_out (&self->output_files_information,
- encoded_out_filepath, &open_error_message,
- &overwritten_file, 0);
- free (path_encoding);
- if (overwritten_file)
- {
- message_list_document_warn (&self->error_messages, self->conf, 0,
- "overwritting output file with js licences: %s",
- license_file);
- }
-
- if (file_fh)
- {
- if (self->conf->OUTPUT_ENCODING_NAME.o.string
- && strcmp (self->conf->OUTPUT_ENCODING_NAME.o.string, "utf-8"))
- {
- conversion
- = get_encoding_conversion (
- self->conf->OUTPUT_ENCODING_NAME.o.string,
- &output_conversions);
- }
- }
-
- file_error_or_write_close (self, license_file,
- encoded_out_filepath, file_fh,
- conversion, result.text,
- open_error_message);
- free (open_error_message);
- free (encoded_out_filepath);
- free (license_file);
- free (result.text);
-}
-
-static const char *js_files[4] = {"info.js", "modernizr.js", "info.css", 0};
-
-void
-html_do_js_files (CONVERTER *self)
-{
- const char *destination_directory = self->destination_directory;
-
- if (self->conf->INFO_JS_DIR.o.string)
- {
- const char *info_js_dir = self->conf->INFO_JS_DIR.o.string;
- char *jsdir;
- char *dir_encoding;
- int succeeded;
- char *encoded_jsdir;
-
- if (destination_directory && strlen (destination_directory))
- {
- xasprintf (&jsdir, "%s/%s", destination_directory, info_js_dir);
- }
- else
- jsdir = strdup (info_js_dir);
-
- encoded_jsdir = encoded_output_file_name (self->conf,
- &self->document->global_info,
- jsdir, &dir_encoding, 0);
-
- free (dir_encoding);
-
- succeeded = create_destination_directory (self, encoded_jsdir, jsdir);
-
- if (succeeded)
- {
- int i;
- if (self->conf->TEST.o.integer <= 0)
- {
- /* conversion_paths_info paths are byte strings */
- char *jssrcdir;
- if (!conversion_paths_info.texinfo_uninstalled)
- {
- xasprintf (&jssrcdir, "%s/%s",
- conversion_paths_info.p.installed.pkgdatadir,
- "js");
- }
- else
- {
- if (conversion_paths_info.p.uninstalled.top_srcdir)
- xasprintf (&jssrcdir, "%s/%s",
- conversion_paths_info.p.uninstalled.top_srcdir,
- "js");
- else
- jssrcdir = strdup ("js");
- }
- for (i = 0; js_files[i]; i++)
- {
- char *from;
- char *to;
- int status;
-
- xasprintf (&from, "%s/%s", jssrcdir, js_files[i]);
- xasprintf (&to, "%s/%s", encoded_jsdir, js_files[i]);
- status = copy_file_to (from, to);
-
- if (status != 0)
- {
- char *to_file_name;
- char *from_file_name;
-
- xasprintf (&to_file_name, "%s/%s", jsdir, js_files[i]);
- xasprintf (&from_file_name, "%s/%s", jsdir, js_files[i]);
-
- switch (status)
- {
- case GL_COPY_ERR_OPEN_READ:
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "error while opening %s for reading: %s",
- from_file_name, strerror (errno));
- break;
-
- case GL_COPY_ERR_OPEN_BACKUP_WRITE:
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "cannot open %s for writing: %s",
- to_file_name, strerror (errno));
- break;
-
- case GL_COPY_ERR_READ:
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "error reading %s: %s",
- from_file_name, strerror (errno));
- break;
-
- case GL_COPY_ERR_WRITE:
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "error writing %s: %s",
- to_file_name, strerror (errno));
- break;
-
- case GL_COPY_ERR_AFTER_READ:
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "error after reading %s: %s",
- from_file_name, strerror (errno));
- break;
-
- case GL_COPY_ERR_GET_ACL:
- message_list_document_warn (&self->error_messages,
- self->conf, 0,
- "%s: %s",
- from_file_name, strerror (errno));
- break;
-
- case GL_COPY_ERR_SET_ACL:
- message_list_document_warn (&self->error_messages,
- self->conf, 0,
- "preserving permissions for %s: %s",
- to_file_name, strerror (errno));
- break;
-
- default:
- message_list_document_warn (&self->error_messages,
- self->conf, 0,
- "unexpected error on copying %s into %s",
- from_file_name, to_file_name);
- break;
- }
- free (to_file_name);
- free (from_file_name);
- }
- free (to);
- free (from);
- }
- free (jssrcdir);
- }
- else
- {
- /* create empty files for tests to keep results stable. */
- for (i = 0; js_files[i]; i++)
- {
- char *to;
- FILE *FH;
-
- xasprintf (&to, "%s/%s", encoded_jsdir, js_files[i]);
- FH = fopen (to, "w");
- if (!FH)
- {
- char *to_file_name;
- xasprintf (&to_file_name, "%s/%s", jsdir, js_files[i]);
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "error on creating empty %s: %s",
- to_file_name, strerror (errno));
- free (to_file_name);
- }
- else
- {
- if (fclose (FH) == EOF)
- {
- char *to_file_name;
- xasprintf (&to_file_name, "%s/%s", jsdir,
js_files[i]);
- message_list_document_error (&self->error_messages,
- self->conf, 0,
- "error on closing empty %s: %s",
- to_file_name, strerror (errno));
- free (to_file_name);
- }
- }
- free (to);
- }
- }
- }
- free (encoded_jsdir);
- free (jsdir);
- }
-
- if (self->jslicenses.number > 0)
- do_jslicenses_file (self);
-}
-
-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;
-}
-
-/* return string to be freed by the caller */
-char *
-html_prepare_node_redirection_page (CONVERTER *self, const ELEMENT *element,
- const char *filename)
-{
- char *result;
-
- self->current_filename.filename = filename;
- self->current_filename.file_number = 0;
-
- result = format_node_redirection_page (self, element, filename);
-
- self->current_filename.filename = 0;
-
- return result;
-}
-
-int
-html_node_redirections (CONVERTER *self,
- const char *output_file, const char *destination_directory)
-{
- FILE_SOURCE_INFO_LIST *files_source_info = &self->files_source_info;
- int redirection_files_done = 0;
- if (self->document->identifiers_target.number > 0
- && self->conf->NODE_FILES.o.integer > 0
- && strlen (output_file) > 0)
- {
- const LABEL_LIST *label_targets = &self->document->labels_list;
- size_t i;
- const ENCODING_CONVERSION *conversion = 0;
-
- if (self->conf->OUTPUT_ENCODING_NAME.o.string
- && strcmp (self->conf->OUTPUT_ENCODING_NAME.o.string, "utf-8"))
- {
- conversion
- = get_encoding_conversion (
- self->conf->OUTPUT_ENCODING_NAME.o.string,
- &output_conversions);
- }
-
- for (i = 0; i < label_targets->number; i++)
- {
- const FILE_NUMBER_NAME *target_filename;
- const ELEMENT *label_element;
- const ELEMENT *target_element;
- const char *node_filename;
- LABEL *label = &label_targets->list[i];
- const char *normalized;
-
- if (!label->identifier || label->reference)
- continue;
-
- target_element = label->element;
- label_element = get_label_element (target_element);
-
- /* filename may not be defined in case of an @anchor or similar in
- @titlepage, and @titlepage is not used. */
- target_filename = html_command_filename (self, target_element);
-
- /* NOTE 'node_filename' is not used for Top, TOP_NODE_FILE_TARGET
- is. The other manual must use the same convention to get it
- right. We do not do 'node_filename' as a redirection file
- either. */
- normalized = lookup_extra_string (target_element, AI_key_normalized);
- if (normalized && !strcmp (normalized, "Top")
- && self->conf->TOP_NODE_FILE_TARGET.o.string)
- {
- node_filename = self->conf->TOP_NODE_FILE_TARGET.o.string;
- }
- else
- {
- const HTML_TARGET *node_target
- = html_get_target (self, target_element);
- node_filename = node_target->node_filename;
- }
- if (target_filename && target_filename->filename
- && strcmp (target_filename->filename, node_filename))
- {
- size_t file_idx
- = register_normalize_case_filename (self, node_filename);
- const FILE_NAME_PATH_COUNTER *output_unit_file
- = &self->output_unit_files.list[file_idx];
- char *redirection_filename = output_unit_file->filename;
- int redirection_filename_total_count
- = output_unit_file->elements_in_file_count;
-
- FILE_SOURCE_INFO *file_source_info
- = 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
- || !strcmp (file_source_info->type, "redirection")))
- {
- const char *file_info_type = file_source_info->type;
- char *label_texi
- = convert_contents_to_texinfo (label_element);
- message_list_command_warn (&self->error_messages,
- self->conf, target_element, 0,
- "@%s `%s' file %s for redirection exists",
- element_command_name (target_element),
- label_texi, redirection_filename);
- free (label_texi);
-
- if (!strcmp (file_info_type, "special_file")
- || !strcmp (file_info_type, "stand_in_file"))
- {
- const char *name = file_source_info->name;
- if (!strcmp (name, "non_split"))
- /* This cannot actually happen, as the @anchor/@node/@float
- with potentially conflicting name will also be in the
- non-split output document and therefore does not need
- a redirection. */
- message_list_document_warn (&self->error_messages,
- self->conf, 1, "conflict with whole document file");
- else if (!strcmp (name, "Top"))
- message_list_document_warn (&self->error_messages,
- self->conf, 1, "conflict with Top file");
- else if (!strcmp (name, "user_defined"))
- message_list_document_warn (&self->error_messages,
- self->conf, 1, "conflict with user-defined file");
- else if (!strcmp (name, "unknown_node"))
- message_list_document_warn (&self->error_messages,
- self->conf, 1, "conflict with unknown node file");
- else if (!strcmp (name, "unknown"))
- message_list_document_warn (&self->error_messages,
- self->conf, 1,
- "conflict with file without known source");
- }
- else if (!strcmp (file_info_type, "node"))
- {
- const ELEMENT *conflicting_node
- = file_source_info->element;
- char *node_texi
- = convert_contents_to_texinfo
- (conflicting_node->e.c->args.list[0]);
- pmessage_list_command_warn (&self->error_messages,
- self->conf, conflicting_node, 1,
- "conflict of redirection file with file based on node name",
- "conflict with @%s `%s' file",
- element_command_name (conflicting_node),
- node_texi);
- free (node_texi);
- }
- else if (!strcmp (file_info_type, "redirection"))
- {
- const ELEMENT *conflicting_node
- = file_source_info->element;
- char *node_texi
- = convert_contents_to_texinfo
- (conflicting_node->e.c->args.list[0]);
- message_list_command_warn (&self->error_messages,
- self->conf, conflicting_node, 1,
- "conflict with @%s `%s' redirection file",
- element_command_name (conflicting_node),
- node_texi);
- free (node_texi);
- }
- else if (!strcmp (file_info_type, "section"))
- {
- const ELEMENT *conflicting_section
- = file_source_info->element;
- char *section_texi
- = convert_contents_to_texinfo
- (conflicting_section->e.c->args.list[0]);
- pmessage_list_command_warn (&self->error_messages,
- self->conf, conflicting_section, 1,
- "conflict of redirection file with file based on section name",
- "conflict with @%s `%s' file",
- element_command_name (conflicting_section),
- section_texi);
- free (section_texi);
- }
- else if (!strcmp (file_info_type, "special_unit"))
- {
- const ELEMENT *unit_command
- = file_source_info->element;
- const OUTPUT_UNIT *special_unit
- = unit_command->e.c->associated_unit;
- message_list_document_warn (&self->error_messages,
- self->conf, 1,
- "conflict with %s special element",
- special_unit->special_unit_variety);
- }
- }
- else
- {
- char *redirection_page;
- char *out_filepath;
- char *path_encoding;
- char *open_error_message;
- int overwritten_file;
- int status;
-
- html_add_to_files_source_info (files_source_info,
- redirection_filename, "redirection", 0,
- target_element, 0);
-
- redirection_page
- = html_prepare_node_redirection_page (self, target_element,
- redirection_filename);
- if (destination_directory && strlen (destination_directory))
- {
- xasprintf (&out_filepath, "%s/%s", destination_directory,
- redirection_filename);
- }
- else
- out_filepath = strdup (redirection_filename);
-
- char *encoded_out_filepath
- = encoded_output_file_name (self->conf,
- &self->document->global_info, out_filepath,
- &path_encoding, 0);
- /* overwritten_file being set cannot happen */
- FILE *file_fh
- = output_files_open_out (&self->output_files_information,
- encoded_out_filepath, &open_error_message,
- &overwritten_file, 0);
- free (path_encoding);
-
- status
- = file_error_or_write_close (self, out_filepath,
- encoded_out_filepath, file_fh,
- conversion, redirection_page,
- open_error_message);
-
- free (encoded_out_filepath);
- free (out_filepath);
- free (redirection_page);
- free (open_error_message);
-
- /* NOTE failure to open a file does not stop the processing */
- if (status == -1)
- return -1;
- else if (status >= 0)
- redirection_files_done++;
- }
- }
- }
- }
-
- return redirection_files_done;
-}
-
-int
-html_finish_output (CONVERTER *self, const char *output_file,
- const char *destination_directory)
-{
- int finish_handler_status;
- int handler_fatal_error_level
- = self->conf->HANDLER_FATAL_ERROR_LEVEL.o.integer;
- int node_redirections_status;
-
- html_do_js_files (self);
-
- finish_handler_status = html_run_stage_handlers (self, HSHT_type_finish);
-
- if (finish_handler_status < handler_fatal_error_level
- && finish_handler_status > -handler_fatal_error_level)
- {}
- else
- return 0;
-
- node_redirections_status = html_node_redirections (self, output_file,
- destination_directory);
- if (node_redirections_status < 0)
- return 0;
-
- return 1;
-}
diff --git a/tp/Texinfo/XS/convert/convert_html.h
b/tp/Texinfo/XS/convert/format_html.h
similarity index 76%
copy from tp/Texinfo/XS/convert/convert_html.h
copy to tp/Texinfo/XS/convert/format_html.h
index f182dafa1e..98e21edd8c 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/format_html.h
@@ -1,6 +1,6 @@
-/* convert_html.h - definitions for convert_html.c */
-#ifndef CONVERT_HTML_H
-#define CONVERT_HTML_H
+/* format_html.h - definitions for format_html.c */
+#ifndef FORMAT_HTML_H
+#define FORMAT_HTML_H
/* Copyright 2010-2024 Free Software Foundation, Inc.
@@ -28,23 +28,13 @@ typedef struct ROOT_AND_UNIT {
const ELEMENT *root;
} ROOT_AND_UNIT;
-extern const char *html_conversion_context_type_names[];
-
-extern const char *html_argument_formatting_type_names[];
-
-/* in conversion_data.c */
-extern const TRANSLATED_SUI_ASSOCIATION translated_special_unit_info[];
-
-extern const char *direction_string_type_names[];
-extern const char *direction_string_context_names[];
-
-extern const char *html_stage_handler_stage_type_names[];
-
char *html_after_escaped_characters (char *text);
char *html_substitute_non_breaking_space (CONVERTER *self, const char *text);
void html_default_format_protect_text (const char *text, TEXT *result);
+void html_default_css_string_format_protect_text (const char *text,
+ TEXT *result);
HTML_TARGET *html_get_target (const CONVERTER *self, const ELEMENT *element);
@@ -101,6 +91,18 @@ const char *html_special_unit_info (const CONVERTER *self,
char *html_attribute_class (CONVERTER *self, const char *element,
const STRING_LIST *classes);
+char *html_format_comment (CONVERTER *self, const char *text);
+char *html_format_end_file (CONVERTER *self, const char *filename,
+ const OUTPUT_UNIT *output_unit);
+char *html_format_begin_file (CONVERTER *self, const char *filename,
+ const OUTPUT_UNIT *output_unit);
+void html_default_format_date_in_header (CONVERTER *self, TEXT *result);
+char *html_default_format_jslicense_file (CONVERTER *self,
+ const JSLICENSE_CATEGORY_LIST *jslicenses);
+char *html_format_node_redirection_page (CONVERTER *self,
+ const ELEMENT *element,
+ const char *filename);
+
void
html_command_conversion_external (CONVERTER *self, const enum command_id cmd,
@@ -270,76 +272,7 @@ SPECIAL_BODY_FORMATTING_FUNCTION(about)
#undef SPECIAL_BODY_FORMATTING_FUNCTION
-
-void html_clear_direction_string_type (const CONVERTER *self,
- char ***type_directions_strings);
-
-void html_complete_no_arg_commands_formatting (CONVERTER *self,
- enum command_id cmd,
- int translate);
-void html_reset_translated_special_unit_info_tree (CONVERTER *self);
-
-void html_translate_names (CONVERTER *self);
-
-
-int html_run_stage_handlers (CONVERTER *self,
- enum html_stage_handler_stage_type stage);
-
-void html_setup_output_simple_page (CONVERTER *self,
- const char *output_filename);
-
-void html_prepare_simpletitle (CONVERTER *self);
-void html_prepare_title_titlepage (CONVERTER *self, const char *output_file,
- const char *output_filename);
-int html_prepare_converted_output_info (CONVERTER *self,
- const char *output_file,
- const char *output_filename);
-
-
-char *debug_print_html_contexts (const CONVERTER *self);
-
-char *html_convert_convert (CONVERTER *self, const ELEMENT *root);
-char *html_convert_tree (CONVERTER *self, const ELEMENT *tree,
- const char *explanation);
-
-char *html_convert_output (CONVERTER *self, const ELEMENT *root,
- const char *output_file,
- const char *destination_directory,
- const char *output_filename,
- const char *document_name);
-
-
-void html_conversion_finalization (CONVERTER *self);
-
-void html_check_transfer_state_finalization (CONVERTER *self);
-
-
-void html_do_js_files (CONVERTER *self);
-
-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);
-
-char *html_prepare_node_redirection_page (CONVERTER *self,
- const ELEMENT *element,
- const char *filename);
-int html_node_redirections (CONVERTER *self,
- const char *output_file, const char *destination_directory);
-
-int html_finish_output (CONVERTER *self, const char *output_file,
- const char *destination_directory);
+char *html_format_title_titlepage (CONVERTER *self);
#endif
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.c
b/tp/Texinfo/XS/convert/get_html_perl_info.c
index 380a58a834..a06674deb0 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.c
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.c
@@ -35,6 +35,9 @@
#include "command_ids.h"
#include "converter_types.h"
#include "types_data.h"
+/* also for direction_string_type_names direction_string_context_names
+ html_conversion_context_type_names html_stage_handler_stage_type_names
+ */
#include "html_converter_types.h"
/* also for non_perl_* */
#include "utils.h"
@@ -49,13 +52,10 @@
new_htmlxref_manual_list htmlxref_split_type_names
html_formatting_reference_names */
#include "html_prepare_converter.h"
-/*
- for html_conversion_context_type_names direction_string_type_names
- direction_string_context_names html_stage_handler_stage_type_names
- html_special_unit_variety_direction_index html_get_target
- find_footnote_id_number
+/* html_special_unit_variety_direction_index html_get_target
+ find_footnote_id_number
*/
-#include "convert_html.h"
+#include "format_html.h"
#include "get_perl_info.h"
#include "get_converter_perl_info.h"
/* for newSVpv_utf8 */
diff --git a/tp/Texinfo/XS/convert/html_converter_types.h
b/tp/Texinfo/XS/convert/html_converter_types.h
index 9d40344261..72ad155a89 100644
--- a/tp/Texinfo/XS/convert/html_converter_types.h
+++ b/tp/Texinfo/XS/convert/html_converter_types.h
@@ -75,6 +75,18 @@ typedef struct COMMAND_ARGS_SPECIFICATION {
unsigned long flags[MAX_COMMAND_ARGS_NR];
} COMMAND_ARGS_SPECIFICATION;
+/* in conversion_data.c */
+extern const TRANSLATED_SUI_ASSOCIATION translated_special_unit_info[];
+
+/* in format_html.c */
+extern const char *direction_string_type_names[];
+extern const char *direction_string_context_names[];
+
+/* in convert_html.c */
+extern const char *html_conversion_context_type_names[];
+extern const char *html_argument_formatting_type_names[];
+extern const char *html_stage_handler_stage_type_names[];
+
extern COMMAND_ARGS_SPECIFICATION html_command_args_flags[BUILTIN_CMD_NUMBER];
extern HTML_COMMAND_STRUCT html_commands_data[BUILTIN_CMD_NUMBER];
diff --git a/tp/Texinfo/XS/convert/html_prepare_converter.c
b/tp/Texinfo/XS/convert/html_prepare_converter.c
index 31d6ad2be7..e47ddf7e97 100644
--- a/tp/Texinfo/XS/convert/html_prepare_converter.c
+++ b/tp/Texinfo/XS/convert/html_prepare_converter.c
@@ -49,6 +49,10 @@
xml_text_entity_no_arg_commands_formatting */
#include "converter.h"
#include "call_html_perl_function.h"
+#include "format_html.h"
+/* html_complete_no_arg_commands_formatting html_run_stage_handlers
+ html_add_to_files_source_info html_find_file_source_info
+ html_setup_output_simple_page */
#include "convert_html.h"
#include "html_prepare_converter.h"