texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Sun, 31 Dec 2023 18:26:41 -0500 (EST)

branch: master
commit 235cdc2ee08f833ac34b597321341df51dde9fea
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Mon Jan 1 00:19:12 2024 +0100

    * tp/Texinfo/XS/convert/convert_html.c (get_copiable_anchor): return 0
    if there is no copiable anchor.  Update callers.
    
    * tp/Texinfo/XS/convert/ConvertXS.xs
    (html_preformatted_classes_stack),
    tp/Texinfo/XS/convert/convert_html.c (HTML_COMMAND_STRUCT)
    (html_preformatted_classes_stack, register_pre_class_command)
    (reset_unset_no_arg_commands_formatting_context)
    (html_open_command_update_context, html_open_type_update_context)
    (html_convert_type_update_context),
    tp/Texinfo/XS/main/converter_types.h (HTML_DOCUMENT_CONTEXT): use a
    COMMAND_OR_TYPE_STACK for preformatted_classes_stack, with a command
    id for a preformatted command and a type id for a preformatted type.
    Turn to strings only when passing to perl.
    
    * tp/Texinfo/XS/convert/convert_html.c
    (conversion_function_cmd_conversion): new function that selects the
    function called for conversion based on a COMMAND_CONVERSION_FUNCTION
    argument, not on the command id or element argument.  Allows to call a
    conversion function associated to a command conversion different from
    the command id or element arguments.
    
    * tp/Texinfo/XS/convert/converter.c (new_tree_added_elements)
    (clear_tree_added_elements, free_tree_added_elements)
    (destroy_tree_added_elements, new_element_added): move
    TREE_ADDED_ELEMENTS related functions from convert_html.c to
    converter.c to be usable more generally than in the html converter.
    
    * tp/Texinfo/XS/convert/converter.c (table_item_content_tree): add.
    
    * tp/Texinfo/XS/convert/convert_html.c (convert_item_command)
    (commands_internal_conversion_table): implement convert_item_command.
---
 ChangeLog                            |  35 +++++
 tp/Texinfo/XS/convert/ConvertXS.xs   |  11 +-
 tp/Texinfo/XS/convert/convert_html.c | 287 ++++++++++++++++++++++-------------
 tp/Texinfo/XS/convert/convert_html.h |   2 +-
 tp/Texinfo/XS/convert/converter.c    | 117 +++++++++++++-
 tp/Texinfo/XS/convert/converter.h    |  14 ++
 tp/Texinfo/XS/main/converter_types.h |   2 +-
 7 files changed, 360 insertions(+), 108 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a9fb4af69d..d8e73dcb6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,41 @@
 
        No functional changes intended.
 
+2023-12-31  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/XS/convert/convert_html.c (get_copiable_anchor): return 0
+       if there is no copiable anchor.  Update callers.
+
+       * tp/Texinfo/XS/convert/ConvertXS.xs
+       (html_preformatted_classes_stack),
+       tp/Texinfo/XS/convert/convert_html.c (HTML_COMMAND_STRUCT)
+       (html_preformatted_classes_stack, register_pre_class_command)
+       (reset_unset_no_arg_commands_formatting_context)
+       (html_open_command_update_context, html_open_type_update_context)
+       (html_convert_type_update_context),
+       tp/Texinfo/XS/main/converter_types.h (HTML_DOCUMENT_CONTEXT): use a
+       COMMAND_OR_TYPE_STACK for preformatted_classes_stack, with a command
+       id for a preformatted command and a type id for a preformatted type.
+       Turn to strings only when passing to perl.
+
+       * tp/Texinfo/XS/convert/convert_html.c
+       (conversion_function_cmd_conversion): new function that selects the
+       function called for conversion based on a COMMAND_CONVERSION_FUNCTION
+       argument, not on the command id or element argument.  Allows to call a
+       conversion function associated to a command conversion different from
+       the command id or element arguments.
+
+       * tp/Texinfo/XS/convert/converter.c (new_tree_added_elements)
+       (clear_tree_added_elements, free_tree_added_elements)
+       (destroy_tree_added_elements, new_element_added): move
+       TREE_ADDED_ELEMENTS related functions from convert_html.c to
+       converter.c to be usable more generally than in the html converter.
+
+       * tp/Texinfo/XS/convert/converter.c (table_item_content_tree): add.
+
+       * tp/Texinfo/XS/convert/convert_html.c (convert_item_command)
+       (commands_internal_conversion_table): implement convert_item_command.
+
 2023-12-31  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/HTML.pm (_convert_item_command): rename $index_id
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 454b4a345b..5ad6fc9b30 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -679,7 +679,7 @@ SV *
 html_preformatted_classes_stack (SV *converter_in)
      PREINIT:
          CONVERTER *self;
-         STRING_STACK *preformatted_classes_stack;
+         COMMAND_OR_TYPE_STACK *preformatted_classes_stack;
          AV *preformatted_classes_av;
          size_t i;
      CODE:
@@ -689,8 +689,15 @@ html_preformatted_classes_stack (SV *converter_in)
          preformatted_classes_av = newAV();
          for (i = 0; i < preformatted_classes_stack->top; i++)
            {
+             COMMAND_OR_TYPE *cmd_or_type
+               = &preformatted_classes_stack->stack[i];
+             char *pre_class = 0;
+             if (cmd_or_type->variety == CTV_type_command)
+               pre_class = builtin_command_data[cmd_or_type->cmd].cmdname;
+             else if (cmd_or_type->variety == CTV_type_type)
+               pre_class = self->pre_class_types[cmd_or_type->type];
              SV *class_sv
-               = newSVpv_utf8 (preformatted_classes_stack->stack[i], 0);
+               = newSVpv_utf8 (pre_class, 0);
              av_push (preformatted_classes_av, class_sv);
            }
          RETVAL = newRV_noinc ((SV *)preformatted_classes_av);
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index a640f3496b..84a9401b55 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -208,7 +208,7 @@ CMD_VARIETY command_special_unit_variety[] = {
 
 typedef struct HTML_COMMAND_STRUCT {
     unsigned long flags;
-    const char *pre_class;
+    enum command_id pre_class_cmd;
 } HTML_COMMAND_STRUCT;
 
 static HTML_COMMAND_STRUCT html_commands_data[BUILTIN_CMD_NUMBER];
@@ -769,7 +769,7 @@ html_top_block_command (CONVERTER *self)
   return top_command (&top_document_ctx->block_commands);
 }
 
-STRING_STACK *
+COMMAND_OR_TYPE_STACK *
 html_preformatted_classes_stack (CONVERTER *self)
 {
   HTML_DOCUMENT_CONTEXT *top_document_ctx;
@@ -1581,14 +1581,11 @@ register_format_context_command (enum command_id cmd)
 
 void register_pre_class_command (enum command_id cmd, enum command_id main_cmd)
 {
-  const char *pre_class_str;
-
   if (main_cmd)
-    pre_class_str = builtin_command_data[main_cmd].cmdname;
+    html_commands_data[cmd].pre_class_cmd = main_cmd;
   else
-    pre_class_str = builtin_command_data[cmd].cmdname;
+    html_commands_data[cmd].pre_class_cmd = cmd;
 
-  html_commands_data[cmd].pre_class = pre_class_str;
   html_commands_data[cmd].flags |= HF_pre_class;
 }
 
@@ -2152,6 +2149,34 @@ noticed_line_warn (CONVERTER *self, const ELEMENT 
*element,
 
 #define ADDN(str,nr) text_append_n (result, str, nr)
 
+/* 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);
+
+    }
+}
+
 void
 default_css_string_format_protect_text (const char *text, TEXT *result)
 {
@@ -2594,75 +2619,6 @@ url_protect_file_text (CONVERTER *self, const char 
*input_string)
   return (result.text);
 }
 
-static TREE_ADDED_ELEMENTS *
-new_tree_added_elements (enum tree_added_elements_status status)
-{
-  TREE_ADDED_ELEMENTS *new
-    = (TREE_ADDED_ELEMENTS *) malloc (sizeof (TREE_ADDED_ELEMENTS));
-  memset (new, 0, sizeof (TREE_ADDED_ELEMENTS));
-  new->status = status;
-  return new;
-}
-
-static void
-clear_tree_added_elements (CONVERTER *self, TREE_ADDED_ELEMENTS *tree_elements)
-{
-  /*
-   targets have all associated tree added elements structures that can be
-   left as 0, in particular with tree_added_status_none if nothing refers to
-   them, and are always cleared in the end.  So it is normal to have cleared
-   tree added elements with status none, but they also should not have any
-   added elements.
-   */
-   /*
-  if (tree_elements->status == tree_added_status_none)
-    {
-      fprintf (stderr, "CTAE: %p no status (%zu)\n", tree_elements, 
tree_elements->added.number);
-    }
-   */
-
-  if (tree_elements->tree
-      && tree_elements->status != tree_added_status_reused_tree)
-    remove_element_from_list (&self->tree_to_build, tree_elements->tree);
-
-  if (tree_elements->status == tree_added_status_new_tree)
-    destroy_element_and_children (tree_elements->tree);
-  else if (tree_elements->status == tree_added_status_elements_added)
-    {
-      size_t i;
-      for (i = 0; i < tree_elements->added.number; i++)
-        {
-          ELEMENT *added_e = tree_elements->added.list[i];
-          destroy_element (added_e);
-        }
-      tree_elements->added.number = 0;
-    }
-  tree_elements->tree = 0;
-  tree_elements->status = 0;
-}
-
-static void
-free_tree_added_elements (CONVERTER *self, TREE_ADDED_ELEMENTS *tree_elements)
-{
-  clear_tree_added_elements (self, tree_elements);
-  free (tree_elements->added.list);
-}
-
-static void
-destroy_tree_added_elements (CONVERTER *self, TREE_ADDED_ELEMENTS 
*tree_elements)
-{
-  free_tree_added_elements (self, tree_elements);
-  free (tree_elements);
-}
-
-ELEMENT *
-new_element_added (TREE_ADDED_ELEMENTS *added_elements, enum element_type type)
-{
-  ELEMENT *new = new_element (type);
-  add_to_element_list (&added_elements->added, new);
-  return new;
-}
-
 static void
 push_html_formatting_context (HTML_FORMATTING_CONTEXT_STACK *stack,
                               char *context_name)
@@ -4489,20 +4445,19 @@ static const STRING_LIST copiable_link_classes = 
{copiable_link_array, 1, 1};
 static char *
 get_copiable_anchor (CONVERTER *self, const char *id)
 {
-  TEXT result;
-
-  text_init (&result);
-  text_append (&result, "");
   if (id && strlen (id) && self->conf->COPIABLE_LINKS > 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 result.text;
+  return 0;
 }
 
 void
@@ -5748,6 +5703,8 @@ html_default_format_heading_text (CONVERTER *self, const 
enum command_id cmd,
   int heading_level = level;
   char *heading_html_element;
   const char *heading_target;
+  char *copiable_anchor;
+
   if (!id && text[strspn (text, whitespace_chars)] == '\0')
     return;
 
@@ -5788,17 +5745,19 @@ html_default_format_heading_text (CONVERTER *self, 
const enum command_id cmd,
 
   text_append_n (result, ">", 1);
 
-  if (heading_target && self->conf->COPIABLE_LINKS > 0)
-    {
-      char *copiable_anchor = get_copiable_anchor(self, heading_target);
-      text_append_n (result, "<span>", 6);
-      text_append (result, text);
+  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);
     }
-  else
-   text_append (result, text);
 
   text_printf (result, "</h%d>", heading_level);
   if (cmd != CM_titlefont)
@@ -7690,7 +7649,6 @@ convert_def_line_type (CONVERTER *self, const enum 
element_type type,
   enum command_id base_cmd = 0;
   TEXT def_call;
   char *anchor;
-  size_t anchor_str_len;
 
   if (html_in_string (self))
     {
@@ -8017,16 +7975,15 @@ convert_def_line_type (CONVERTER *self, const enum 
element_type type,
   destroy_parsed_def (parsed_def);
 
   anchor = get_copiable_anchor (self, index_id);
-  anchor_str_len = strlen (anchor);
 
-  if (anchor_str_len)
+  if (anchor)
     text_append_n (result, "<span>", 6);
 
   text_append_n (result, def_call.text, def_call.end);
   free (def_call.text);
-  if (anchor_str_len)
+  if (anchor)
     {
-      text_append_n (result, anchor, anchor_str_len);
+      text_append (result, anchor);
       text_append_n (result, "</span>", 7);
     }
 
@@ -10631,7 +10588,6 @@ static char *type_number_float_array[] = 
{"type-number-float"};
 static const STRING_LIST type_number_float_classes
   = {type_number_float_array, 1, 1};
 
-
 void
 convert_float_command (CONVERTER *self, const enum command_id cmd,
                     const ELEMENT *element,
@@ -11231,6 +11187,129 @@ convert_xtable_command (CONVERTER *self, const enum 
command_id cmd,
   text_append_n (result, "</dl>\n", 6);
 }
 
+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
+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->parent->cmd == CM_itemize)
+    {
+      if (content
+          && content[strspn (content, whitespace_chars)] != '\0')
+        {
+          text_printf (result, "<li>%s</li>", content);
+        }
+    }
+  else if (element->parent && element->parent->cmd == 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->args.number > 0
+          && element->args.list[0]->contents.number > 0)
+        {
+          ELEMENT *converted_e;
+          TREE_ADDED_ELEMENTS *tree;
+          char *anchor = 0;
+          char *index_entry_id;
+          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))
+            {
+              COMMAND_OR_TYPE_STACK *pre_classes
+                = html_preformatted_classes_stack (self);
+              size_t i;
+              for (i = 0; i < pre_classes->top; i++)
+                {
+                  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->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_to_element_list (&self->tree_to_build, tree->tree);
+              converted_e = tree->tree;
+            }
+          else
+            converted_e = element->args.list[0];
+
+          convert_to_html_internal (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);
+            }
+
+          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);
+    }
+}
+
 void
 convert_xref_commands (CONVERTER *self, const enum command_id cmd,
                     const ELEMENT *element,
@@ -11942,6 +12021,9 @@ static COMMAND_INTERNAL_CONVERSION 
commands_internal_conversion_table[] = {
   {CM_author, &convert_author_command},
   {CM_title, &convert_title_command},
   {CM_subtitle, &convert_subtitle_command},
+  {CM_item, &convert_item_command},
+  {CM_headitem, &convert_item_command},
+  {CM_itemx, &convert_item_command},
 
   {CM_insertcopying, &convert_insertcopying_command},
   {CM_listoffloats, &convert_listoffloats_command},
@@ -13857,8 +13939,8 @@ reset_unset_no_arg_commands_formatting_context 
(CONVERTER *self,
           push_command_or_type (&top_document_ctx->composition_context,
                                 preformated_cmd, 0);
       /* should not be needed for at commands no brace translation strings */
-          push_string_stack_string (&top_document_ctx->preformatted_classes,
-                              html_commands_data[preformated_cmd].pre_class);
+          push_command_or_type (&top_document_ctx->preformatted_classes,
+                         html_commands_data[preformated_cmd].pre_class_cmd, 0);
           push_integer_stack_integer (&top_document_ctx->preformatted_context,
                                       1);
           top_document_ctx->inside_preformatted++;
@@ -13868,7 +13950,7 @@ reset_unset_no_arg_commands_formatting_context 
(CONVERTER *self,
           top_document_ctx->inside_preformatted--;
           pop_integer_stack (&top_document_ctx->preformatted_context);
           pop_command_or_type (&top_document_ctx->composition_context);
-          pop_string_stack (&top_document_ctx->preformatted_classes);
+          pop_command_or_type (&top_document_ctx->preformatted_classes);
           html_pop_document_context (self);
         }
       else if (reset_context == HCC_type_string)
@@ -14109,8 +14191,8 @@ html_open_command_update_context (CONVERTER *self, enum 
command_id data_cmd)
 
   if (html_commands_data[data_cmd].flags & HF_pre_class)
     {
-      push_string_stack_string (&top_document_ctx->preformatted_classes,
-                                html_commands_data[data_cmd].pre_class);
+      push_command_or_type (&top_document_ctx->preformatted_classes,
+                            html_commands_data[data_cmd].pre_class_cmd, 0);
       if (builtin_command_data[data_cmd].flags & CF_preformatted)
         {
           preformatted = 1;
@@ -14188,7 +14270,7 @@ html_convert_command_update_context (CONVERTER *self, 
enum command_id data_cmd)
 
   if (html_commands_data[data_cmd].flags & HF_pre_class)
     {
-      pop_string_stack (&top_document_ctx->preformatted_classes);
+      pop_command_or_type (&top_document_ctx->preformatted_classes);
       if (builtin_command_data[data_cmd].flags & CF_preformatted)
         top_document_ctx->inside_preformatted--;
     }
@@ -14262,8 +14344,7 @@ html_open_type_update_context (CONVERTER *self, enum 
element_type type)
     }
   else if (self->pre_class_types[type])
     {
-      push_string_stack_string (&top_document_ctx->preformatted_classes,
-                                self->pre_class_types[type]);
+      push_command_or_type (&top_document_ctx->preformatted_classes, 0, type);
       push_command_or_type (&top_document_ctx->composition_context,
                             0, type);
       push_integer_stack_integer (&top_document_ctx->preformatted_context, 1);
@@ -14297,7 +14378,7 @@ html_convert_type_update_context (CONVERTER *self, enum 
element_type type)
 
   if (self->pre_class_types[type])
     {
-      pop_string_stack (&top_document_ctx->preformatted_classes);
+      pop_command_or_type (&top_document_ctx->preformatted_classes);
       pop_command_or_type (&top_document_ctx->composition_context);
       pop_integer_stack (&top_document_ctx->preformatted_context);
     }
diff --git a/tp/Texinfo/XS/convert/convert_html.h 
b/tp/Texinfo/XS/convert/convert_html.h
index d3c7bbe9ed..4e7174d2a5 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -68,7 +68,7 @@ int html_in_raw (CONVERTER *self);
 int html_paragraph_number (CONVERTER *self);
 int html_preformatted_number (CONVERTER *self);
 enum command_id html_top_block_command (CONVERTER *self);
-STRING_STACK *html_preformatted_classes_stack (CONVERTER *self);
+COMMAND_OR_TYPE_STACK *html_preformatted_classes_stack (CONVERTER *self);
 enum command_id html_in_align (CONVERTER *self);
 
 char *debug_print_html_contexts (CONVERTER *self);
diff --git a/tp/Texinfo/XS/convert/converter.c 
b/tp/Texinfo/XS/convert/converter.c
index f34f050764..321991626f 100644
--- a/tp/Texinfo/XS/convert/converter.c
+++ b/tp/Texinfo/XS/convert/converter.c
@@ -366,7 +366,7 @@ float_name_caption (CONVERTER *self, const ELEMENT *float_e)
   if (!caption_element)
     caption_element = lookup_extra_element (float_e, "shortcaption");
 
-  if (float_type && strlen (float_type)) 
+  if (float_type && strlen (float_type))
     type_element = float_e->args.list[0];
 
   if (float_number)
@@ -424,6 +424,121 @@ float_name_caption (CONVERTER *self, const ELEMENT 
*float_e)
   return result;
 }
 
+TREE_ADDED_ELEMENTS *
+new_tree_added_elements (enum tree_added_elements_status status)
+{
+  TREE_ADDED_ELEMENTS *new
+    = (TREE_ADDED_ELEMENTS *) malloc (sizeof (TREE_ADDED_ELEMENTS));
+  memset (new, 0, sizeof (TREE_ADDED_ELEMENTS));
+  new->status = status;
+  return new;
+}
+
+/* NOTE in addition to freeing memory, the tree root is removed from
+   tree_to_build if relevant. */
+void
+clear_tree_added_elements (CONVERTER *self, TREE_ADDED_ELEMENTS *tree_elements)
+{
+  /*
+   HTML targets have all associated tree added elements structures that can be
+   left as 0, in particular with tree_added_status_none if nothing refers to
+   them, and are always cleared in the end.  So it is normal to have cleared
+   tree added elements with status none, but they also should not have any
+   added elements.
+   */
+   /*
+  if (tree_elements->status == tree_added_status_none)
+    {
+      fprintf (stderr, "CTAE: %p no status (%zu)\n", tree_elements, 
tree_elements->added.number);
+    }
+   */
+
+  if (tree_elements->tree
+      && tree_elements->status != tree_added_status_reused_tree)
+    remove_element_from_list (&self->tree_to_build, tree_elements->tree);
+
+  if (tree_elements->status == tree_added_status_new_tree)
+    destroy_element_and_children (tree_elements->tree);
+  else if (tree_elements->status == tree_added_status_elements_added)
+    {
+      size_t i;
+      for (i = 0; i < tree_elements->added.number; i++)
+        {
+          ELEMENT *added_e = tree_elements->added.list[i];
+          destroy_element (added_e);
+        }
+      tree_elements->added.number = 0;
+    }
+  tree_elements->tree = 0;
+  tree_elements->status = 0;
+}
+
+void
+free_tree_added_elements (CONVERTER *self, TREE_ADDED_ELEMENTS *tree_elements)
+{
+  clear_tree_added_elements (self, tree_elements);
+  free (tree_elements->added.list);
+}
+
+void
+destroy_tree_added_elements (CONVERTER *self, TREE_ADDED_ELEMENTS 
*tree_elements)
+{
+  free_tree_added_elements (self, tree_elements);
+  free (tree_elements);
+}
+
+ELEMENT *
+new_element_added (TREE_ADDED_ELEMENTS *added_elements, enum element_type type)
+{
+  ELEMENT *new = new_element (type);
+  add_to_element_list (&added_elements->added, new);
+  return new;
+}
+
+TREE_ADDED_ELEMENTS *
+table_item_content_tree (CONVERTER *self, const ELEMENT *element)
+{
+  ELEMENT *table_command = element->parent->parent->parent;
+  ELEMENT *command_as_argument = lookup_extra_element (table_command,
+                                               "command_as_argument");
+
+  if (element->args.number > 0 && command_as_argument)
+    {
+      TREE_ADDED_ELEMENTS *tree
+        = new_tree_added_elements (tree_added_status_elements_added);
+      int status;
+      int command_as_argument_kbd_code;
+      ELEMENT *command = new_element_added (tree, ET_NONE);
+      ELEMENT *arg = new_element_added (tree, ET_brace_command_arg);
+      enum command_id cmd = element_builtin_cmd (command_as_argument);
+
+      tree->tree = command;
+
+      command->cmd = cmd;
+      command->source_info = element->source_info;
+      command_as_argument_kbd_code = lookup_extra_integer (table_command,
+                                 "command_as_argument_kbd_code", &status);
+      if (command_as_argument_kbd_code > 0)
+        add_extra_integer (command, "code", 1);
+
+      if (command_as_argument->type == ET_definfoenclose_command)
+        {
+          char *begin = lookup_extra_string (command_as_argument, "begin");
+          char *end = lookup_extra_string (command_as_argument, "end");
+          command->type = command_as_argument->type;
+          if (begin)
+            add_extra_string_dup (command, "begin", begin);
+          if (end)
+            add_extra_string_dup (command, "end", end);
+        }
+      add_to_element_args (command, arg);
+      add_to_contents_as_array (arg, element->args.list[0]);
+      return tree;
+    }
+
+  return 0;
+}
+
 char *
 convert_accents (CONVERTER *self, const ELEMENT *accent,
  char *(*convert_tree)(CONVERTER *self, const ELEMENT *tree, char 
*explanation),
diff --git a/tp/Texinfo/XS/convert/converter.h 
b/tp/Texinfo/XS/convert/converter.h
index 065189b313..90c52d0fcc 100644
--- a/tp/Texinfo/XS/convert/converter.h
+++ b/tp/Texinfo/XS/convert/converter.h
@@ -85,6 +85,20 @@ void set_global_document_commands (CONVERTER *converter,
 char *node_information_filename (CONVERTER *self, char *normalized,
                                  const ELEMENT *label_element);
 
+TREE_ADDED_ELEMENTS *new_tree_added_elements
+                      (enum tree_added_elements_status status);
+ELEMENT *new_element_added (TREE_ADDED_ELEMENTS *added_elements,
+                            enum element_type type);
+void clear_tree_added_elements (CONVERTER *self,
+                                TREE_ADDED_ELEMENTS *tree_elements);
+void free_tree_added_elements (CONVERTER *self,
+                               TREE_ADDED_ELEMENTS *tree_elements);
+void destroy_tree_added_elements (CONVERTER *self,
+                                  TREE_ADDED_ELEMENTS *tree_elements);
+
+TREE_ADDED_ELEMENTS *table_item_content_tree (CONVERTER *self,
+                                              const ELEMENT *element);
+
 TARGET_FILENAME *normalized_sectioning_command_filename (CONVERTER *self,
                                                    const ELEMENT *command);
 
diff --git a/tp/Texinfo/XS/main/converter_types.h 
b/tp/Texinfo/XS/main/converter_types.h
index ad48261afe..629abd67b1 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -464,7 +464,7 @@ typedef struct HTML_DOCUMENT_CONTEXT {
     COMMAND_OR_TYPE_STACK composition_context;
     COMMAND_STACK block_commands;
     HTML_FORMATTING_CONTEXT_STACK formatting_context;
-    STRING_STACK preformatted_classes;
+    COMMAND_OR_TYPE_STACK preformatted_classes;
 } HTML_DOCUMENT_CONTEXT;
 
 typedef struct HTML_DOCUMENT_CONTEXT_STACK {



reply via email to

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