texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Fri, 8 Dec 2023 07:06:54 -0500 (EST)

branch: master
commit ffe074b6c3e41b9ec7a6421715fd20329da35222
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Fri Dec 8 13:06:45 2023 +0100

    * tp/Texinfo/Convert/HTML.pm (_convert_def_line_type): avoid
    intermediate variables, move code around.
    
    * tp/Texinfo/XS/convert/convert_html.c (html_in_multi_expanded): add.
    
    * tp/Texinfo/XS/main/utils.c (def_aliases), tp/Texinfo/XS/main/utils.h
    (DEF_ALIAS), tp/Texinfo/XS/parsetexi/def.c (parse_def): move DEF_ALIAS
    to utils.h and def_aliases to utils.c from def.c.
    Add aliases of def*x commands.
    
    * tp/Texinfo/XS/convert/convert_html.c (convert_def_line_type)
    (types_internal_conversion_table): implement convert_def_line_type in
    C.
    
    * tp/Texinfo/XS/convert/convert_html.c
    (reset_translated_special_unit_info_tree): remove a destroyed element
    from tree to build.
    (convert_to_html_internal) <untranslated>: add tree to build.
    
    * tp/Texinfo/XS/convert/convert_html.c (html_finalize_output_state):
    free tree_to_build.list after the corresponding messages have been
    issued.
    Show the tree_to_build elements remaining.  The elements could have
    been destroyed, so only show if DEBUG is set.  With DEBUG, this could
    produce a segfault, but using valgrind should give an idea where the
    tree_to_build element was created/destroyed.
    
    * tp/Texinfo/XS/convert/convert_html.c (html_free_converter): show the
    ignored error messages.
---
 ChangeLog                            |  32 +++
 tp/Texinfo/Convert/HTML.pm           | 155 ++++++------
 tp/Texinfo/XS/convert/convert_html.c | 460 ++++++++++++++++++++++++++++++++---
 tp/Texinfo/XS/main/utils.c           |  28 +++
 tp/Texinfo/XS/main/utils.h           |   9 +
 tp/Texinfo/XS/parsetexi/def.c        |  26 +-
 6 files changed, 581 insertions(+), 129 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4fac840d88..31da3094ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2023-12-08  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Convert/HTML.pm (_convert_def_line_type): avoid
+       intermediate variables, move code around.
+
+       * tp/Texinfo/XS/convert/convert_html.c (html_in_multi_expanded): add.
+
+       * tp/Texinfo/XS/main/utils.c (def_aliases), tp/Texinfo/XS/main/utils.h
+       (DEF_ALIAS), tp/Texinfo/XS/parsetexi/def.c (parse_def): move DEF_ALIAS
+       to utils.h and def_aliases to utils.c from def.c.
+       Add aliases of def*x commands.
+
+       * tp/Texinfo/XS/convert/convert_html.c (convert_def_line_type)
+       (types_internal_conversion_table): implement convert_def_line_type in
+       C.
+
+       * tp/Texinfo/XS/convert/convert_html.c
+       (reset_translated_special_unit_info_tree): remove a destroyed element
+       from tree to build.
+       (convert_to_html_internal) <untranslated>: add tree to build.
+
+       * tp/Texinfo/XS/convert/convert_html.c (html_finalize_output_state):
+       free tree_to_build.list after the corresponding messages have been
+       issued.
+       Show the tree_to_build elements remaining.  The elements could have
+       been destroyed, so only show if DEBUG is set.  With DEBUG, this could
+       produce a segfault, but using valgrind should give an idea where the
+       tree_to_build element was created/destroyed.
+
+       * tp/Texinfo/XS/convert/convert_html.c (html_free_converter): show the
+       ignored error messages.
+
 2023-12-08  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/XS/convert/call_html_perl_function.c (call_types_open):
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index c56295cffb..3187b110fb 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -7181,89 +7181,90 @@ sub _convert_def_line_type($$$$)
       $type_element, $name_element, $arguments)
          = Texinfo::Convert::Utils::definition_arguments_content($element);
 
-  my @classes = ();
-  my $command_name;
-  if ($Texinfo::Common::def_aliases{$element->{'extra'}->{'def_command'}}) {
-    $command_name
-        = $Texinfo::Common::def_aliases{$element->{'extra'}->{'def_command'}};
-  } else {
-    $command_name = $element->{'extra'}->{'def_command'};
-  }
+  my $original_def_cmdname = $element->{'extra'}->{'original_def_cmdname'};
   my $original_command_name;
-  if 
($Texinfo::Common::def_aliases{$element->{'extra'}->{'original_def_cmdname'}}) {
-    my $original_def_cmdname = $element->{'extra'}->{'original_def_cmdname'};
+  my $alias_class;
+  if ($Texinfo::Common::def_aliases{$original_def_cmdname}) {
     $original_command_name = 
$Texinfo::Common::def_aliases{$original_def_cmdname};
-    push @classes, "$original_def_cmdname-alias-$original_command_name";
+    $alias_class = "$original_def_cmdname-alias-$original_command_name";
   } else {
-    $original_command_name = $element->{'extra'}->{'original_def_cmdname'};
+    $original_command_name = $original_def_cmdname;
   }
-  if ($command_name ne $original_command_name) {
-    push @classes, "def-cmd-$command_name";
+
+  my $def_command = $element->{'extra'}->{'def_command'};
+  my $base_command_name;
+  if ($Texinfo::Common::def_aliases{$def_command}) {
+    $base_command_name
+        = $Texinfo::Common::def_aliases{$def_command};
+  } else {
+    $base_command_name = $def_command;
   }
-  unshift @classes, $original_command_name;
 
-  my $result_type = '';
+  my @classes = ();
+  push @classes, $original_command_name;
+  if (defined($alias_class)) {
+    push @classes, $alias_class;
+  }
+  if ($base_command_name ne $original_command_name) {
+    push @classes, "def-cmd-$base_command_name";
+  }
+
+  my $def_call = '';
   if ($type_element) {
     my $type_text = $self->_convert({'type' => '_code',
        'contents' => [$type_element]});
     if ($type_text ne '') {
-      $result_type = $self->html_attribute_class('code', ['def-type']).'>'.
-         $type_text .'</code>';
+      $def_call .= $self->html_attribute_class('code', ['def-type']).'>'.
+          $type_text .'</code>';
     }
     if ($self->get_conf('deftypefnnewline') eq 'on'
-        and ($command_name eq 'deftypefn' or $command_name eq 'deftypeop')) {
-      $result_type .= $self->get_info('line_break_element');
+        and ($base_command_name eq 'deftypefn'
+             or $base_command_name eq 'deftypeop')) {
+      $def_call .= $self->get_info('line_break_element') . ' ';
+    } elsif ($type_text ne '') {
+      $def_call .= ' ';
     }
   }
 
-  my $result_name = '';
   if ($name_element) {
-    $result_name = $self->html_attribute_class('strong', ['def-name']).'>'.
+    $def_call .= $self->html_attribute_class('strong', ['def-name']).'>'.
        $self->_convert({'type' => '_code', 'contents' => [$name_element]})
        .'</strong>';
   }
 
-  my $def_space = ' ';
-  if ($element->{'extra'}->{'omit_def_name_space'}) {
-    $def_space = '';
-  }
-
-  my $result_arguments = '';
   if ($arguments) {
   # arguments not only metasyntactic variables
   # (deftypefn, deftypevr, deftypeop, deftypecv)
-    if ($Texinfo::Common::def_no_var_arg_commands{$command_name}) {
+    if ($Texinfo::Common::def_no_var_arg_commands{$base_command_name}) {
       my $arguments_formatted = $self->_convert({'type' => '_code',
                                                  'contents' => [$arguments]});
-      $result_arguments = $self->html_attribute_class('code',
+      if ($arguments_formatted =~ /\S/) {
+        $def_call .= ' ' unless($element->{'extra'}->{'omit_def_name_space'});
+        $def_call .= $self->html_attribute_class('code',
                                       ['def-code-arguments']).'>'
-                          . $arguments_formatted.'</code>'
-          if ($arguments_formatted =~ /\S/);
+                          . $arguments_formatted.'</code>';
+      }
     } else {
       # only metasyntactic variable arguments (deffn, defvr, deftp, defop, 
defcv)
       # FIXME not part of the API
       _set_code_context($self, 0);
-      my $arguments_formatted = $self->_convert({'contents' => [$arguments]});
+      my $arguments_formatted = $self->_convert($arguments);
       _pop_code_context($self);
       if ($arguments_formatted =~ /\S/) {
-        $result_arguments = $self->html_attribute_class('var',
+        $def_call .= ' ' unless($element->{'extra'}->{'omit_def_name_space'});
+        $def_call .= $self->html_attribute_class('var',
                                ['def-var-arguments']).'>'
               . $arguments_formatted .'</var>';
       }
     }
   }
 
-  my $def_call = '';
-  $def_call .= $result_type . ' ' if ($result_type ne '');
-  $def_call .= $result_name;
-  $def_call .= $def_space . $result_arguments if ($result_arguments ne '');
-
   if ($self->get_conf('DEF_TABLE')) {
     my $category_result = '';
     my $definition_category_tree
       = Texinfo::Convert::Utils::definition_category_tree($self, $element);
     $category_result
-      = $self->convert_tree({'contents' => [$definition_category_tree]})
+      = $self->convert_tree($definition_category_tree)
         if (defined($definition_category_tree));
 
     return $self->html_attribute_class('tr', \@classes)
@@ -7272,28 +7273,33 @@ sub _convert_def_line_type($$$$)
       . '>' . '[' . $category_result . ']' . "</td></tr>\n";
   }
 
-  my $category_result = '';
-  my $category_tree;
+  my $result = $self->html_attribute_class('dt', \@classes) . "$index_label>";
+
   if ($category_element) {
+    my $category_tree;
     if ($class_element) {
-      if ($command_name eq 'deftypeop'
+      my $substrings = {'category' => $category_element,
+                        'class' => $class_element};
+      if ($base_command_name eq 'deftypeop'
           and $type_element
           and $self->get_conf('deftypefnnewline') eq 'on') {
         $category_tree = $self->gdt('{category} on @code{{class}}:@* ',
-              {'category' => $category_element,
-              'class' => $class_element});
-      } elsif ($command_name eq 'defop' or $command_name eq 'deftypeop') {
+                                    $substrings);
+      } elsif ($base_command_name eq 'defop'
+               or $base_command_name eq 'deftypeop') {
         $category_tree = $self->gdt('{category} on @code{{class}}: ',
-              {'category' => $category_element,
-              'class' => $class_element});
-      } elsif ($command_name eq 'defcv' or $command_name eq 'deftypecv') {
+                                    $substrings);
+      } elsif ($base_command_name eq 'defcv'
+               or $base_command_name eq 'deftypecv') {
         $category_tree = $self->gdt('{category} of @code{{class}}: ',
-              {'category' => $category_element,
-              'class' => $class_element});
+                                    $substrings);
       }
-    } elsif ($type_element
-            and ($command_name eq 'deftypefn' or $command_name eq 'deftypeop')
-            and $self->get_conf('deftypefnnewline') eq 'on') {
+    } else {
+      my $substrings = {'category' => $category_element};
+      if ($type_element
+          and ($base_command_name eq 'deftypefn'
+               or $base_command_name eq 'deftypeop')
+          and $self->get_conf('deftypefnnewline') eq 'on') {
         # FIXME if in @def* in @example and with @deftypefnnewline
         # on there is no effect of @deftypefnnewline on, as @* in
         # preformatted environment becomes an end of line, but the def*
@@ -7301,31 +7307,34 @@ sub _convert_def_line_type($$$$)
         # an explicit <br> in that case.  Probably requires changing
         # the conversion of @* in a @def* line in preformatted, nothing
         # really specific of @deftypefnnewline on.
-        $category_tree = $self->gdt('{category}:@* ',
-                                    {'category' => $category_element});
-    } else {
-      $category_tree = $self->gdt('{category}: ', {'category' => 
$category_element});
+        $category_tree = $self->gdt('{category}:@* ', $substrings);
+      } else {
+        $category_tree = $self->gdt('{category}: ', $substrings);
+      }
     }
-    $category_result = $self->convert_tree($category_tree);
-  }
-
-  if ($category_result ne '') {
-    my $open = $self->html_attribute_class('span', ['category-def']);
-    if ($open ne '') {
-      $category_result = $open.'>'.$category_result.'</span>';
+    if ($category_tree) {
+      my $open = $self->html_attribute_class('span', ['category-def']);
+      if ($open ne '') {
+        $result .= $open.'>';
+      }
+      $result .= $self->convert_tree($category_tree);
+      if ($open ne '') {
+        $result .= '</span>';
+      }
     }
   }
-  my $anchor_span_open = '';
-  my $anchor_span_close = '';
+
   my $anchor = $self->_get_copiable_anchor($index_id);
   if ($anchor ne '') {
-    $anchor_span_open = '<span>';
-    $anchor_span_close = '</span>';
+    $result .= '<span>';
   }
-  return $self->html_attribute_class('dt', \@classes)
-       . "$index_label>" . $category_result . $anchor_span_open
-       . $def_call
-       . "$anchor$anchor_span_close</dt>\n";
+  $result .= $def_call;
+  if ($anchor ne '') {
+    $result .= $anchor . '</span>';
+  }
+  $result .= "</dt>\n";
+
+  return $result;
 }
 
 sub _get_copiable_anchor {
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index b93e34f3ca..b05af71f84 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -724,6 +724,15 @@ html_unset_raw_context (CONVERTER *self)
   top_document_ctx->raw_ctx--;
 }
 
+const char *
+html_in_multi_expanded (CONVERTER *self)
+{
+  if (self->multiple_pass.top > 0)
+    return top_string_stack (&self->multiple_pass);
+
+  return 0;
+}
+
 size_t
 count_elements_in_filename (CONVERTER *self,
                  enum count_elements_in_filename_type type,
@@ -3739,6 +3748,28 @@ html_attribute_class (CONVERTER *self, const char 
*element,
   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)
+{
+  TEXT result;
+
+  text_init (&result);
+  text_append (&result, "");
+  if (id && strlen (id) && self->conf->COPIABLE_LINKS > 0)
+    {
+      char *attribute_class = html_attribute_class (self, "a",
+                                                    &copiable_link_classes);
+      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;
+}
+
 void
 html_merge_index_entries (CONVERTER *self)
 {
@@ -4828,28 +4859,6 @@ format_separate_anchor (CONVERTER *self, const char *id,
     }
 }
 
-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)
-{
-  TEXT result;
-
-  text_init (&result);
-  text_append (&result, "");
-  if (id && strlen (id) && self->conf->COPIABLE_LINKS > 0)
-    {
-      char *attribute_class = html_attribute_class (self, "a",
-                                                    &copiable_link_classes);
-      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;
-}
-
 void
 html_default_format_heading_text (CONVERTER *self, const enum command_id cmd,
                      const STRING_LIST *classes, const char *text,
@@ -5459,6 +5468,365 @@ format_footnotes_segment (CONVERTER *self, TEXT *result)
     }
 }
 
+#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)
+
+void
+convert_def_line_type (CONVERTER *self, const enum element_type type,
+                       const ELEMENT *element, const char *content,
+                       TEXT *result)
+{
+  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;
+  size_t anchor_str_len;
+
+  if (html_in_string (self))
+    {
+      /* should probably never happen */
+      char *text;
+      TEXT_OPTIONS *text_conv_options
+         = copy_options_for_convert_text (self, 0);
+      text = convert_to_text (element, text_conv_options);
+      free (text_conv_options);
+      format_protect_text (self, text, result);
+    }
+
+  index_id = html_command_id (self, element);
+
+  parsed_def = definition_arguments_content (element);
+
+  if (element->cmd)
+    original_def_cmd = element->cmd;
+  else
+    original_def_cmd = element->parent->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->cmd == CM_defline || element->cmd == CM_deftypeline)
+    def_cmd = element->cmd;
+  else
+  /* the parent is the def both for def* def_line and def*x */
+    def_cmd = element->parent->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 = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+  memset (classes, 0, sizeof (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);
+    }
+
+  text_init (&def_call);
+  text_append (&def_call, "");
+  if (parsed_def->type)
+    {
+      size_t type_text_len;
+      TREE_ADDED_ELEMENTS *code_tree = new_tree_added_elements ();
+
+      ELEMENT *root_code = new_element_added (code_tree, ET__code);
+      add_to_contents_as_array (root_code, parsed_def->type);
+
+      add_to_element_list (&self->tree_to_build, root_code);
+
+      char *type_text = html_convert_tree (self, root_code, 0);
+      destroy_tree_added_elements (self, code_tree);
+      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)
+          && !strcmp (self->conf->deftypefnnewline, "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);
+    }
+
+  if (parsed_def->name)
+    {
+      char *attribute_class = html_attribute_class (self, "strong",
+                                                    &def_name_classes);
+      TREE_ADDED_ELEMENTS *code_tree = new_tree_added_elements ();
+
+      ELEMENT *root_code = new_element_added (code_tree, ET__code);
+      add_to_contents_as_array (root_code, parsed_def->name);
+
+      add_to_element_list (&self->tree_to_build, root_code);
+
+      text_append (&def_call, attribute_class);
+      free (attribute_class);
+      text_append_n (&def_call, ">", 1);
+      convert_to_html_internal (self, root_code, &def_call, 0);
+      destroy_tree_added_elements (self, code_tree);
+      text_append_n (&def_call, "</strong>", 9);
+    }
+
+  if (parsed_def->args)
+    {
+      char *args_formatted;
+   /* 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))
+        {
+          TREE_ADDED_ELEMENTS *code_tree = new_tree_added_elements ();
+
+          ELEMENT *root_code = new_element_added (code_tree, ET__code);
+          add_to_contents_as_array (root_code, parsed_def->args);
+
+          add_to_element_list (&self->tree_to_build, root_code);
+
+          args_formatted = html_convert_tree (self, root_code, 0);
+          destroy_tree_added_elements (self, code_tree);
+          if (args_formatted[strspn (args_formatted, whitespace_chars)] != 
'\0')
+            {
+              char *attribute_class = html_attribute_class (self, "code",
+                                              &def_code_arguments_classes);
+              int status;
+              int omit_def_name_space = lookup_extra_integer (element,
+                                              "omit_def_name_space", &status);
+              if (omit_def_name_space <= 0)
+                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, 0);
+          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 status;
+              int omit_def_name_space = lookup_extra_integer (element,
+                                              "omit_def_name_space", &status);
+              if (omit_def_name_space <= 0)
+                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);
+            }
+        }
+    }
+
+  if (self->conf->DEF_TABLE > 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_to_element_list (&self->tree_to_build, category_tree);
+          convert_to_html_internal (self, category_tree, result, 0);
+          remove_element_from_list (&self->tree_to_build, category_tree);
+          destroy_element_and_children (category_tree);
+        }
+      text_append_n (result, "]</td></tr>\n", 12);
+      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
+              && !strcmp (self->conf->deftypefnnewline, "on"))
+            {
+               category_tree
+                  = html_gdt_tree ("{category} on @code{{class}}:@* ",
+                                   self->document, self, substrings, 0, 0);
+            }
+          else if (base_cmd == CM_defop || base_cmd == CM_deftypeop)
+            {
+               category_tree
+                  = html_gdt_tree ("{category} on @code{{class}}: ",
+                                   self->document, self, substrings, 0, 0);
+            }
+          else if (base_cmd == CM_defcv || base_cmd == CM_deftypecv)
+            {
+               category_tree
+                  = html_gdt_tree ("{category} of @code{{class}}: ",
+                                   self->document, self, substrings, 0, 0);
+            }
+        }
+      else
+        {
+          if ((base_cmd == CM_deftypefn || base_cmd == CM_deftypeop)
+              && parsed_def->type
+              && !strcmp (self->conf->deftypefnnewline, "on"))
+            {
+              category_tree
+                  = html_gdt_tree ("{category}:@* ",
+                                   self->document, self, substrings, 0, 0);
+            }
+          else
+            {
+              category_tree
+                  = html_gdt_tree ("{category}: ",
+                                   self->document, self, substrings, 0, 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);
+          if (open_len)
+            {
+              text_append_n (result, attribute_open, open_len);
+              text_append_n (result, ">", 1);
+            }
+          add_to_element_list (&self->tree_to_build, category_tree);
+          convert_to_html_internal (self, category_tree, result, 0);
+          remove_element_from_list (&self->tree_to_build, category_tree);
+          destroy_element_and_children (category_tree);
+          if (open_len)
+            text_append_n (result, "</span>", 7);
+        }
+    }
+
+  anchor = get_copiable_anchor (self, index_id);
+  anchor_str_len = strlen (anchor);
+
+  if (anchor_str_len)
+    text_append_n (result, "<span>", 6);
+
+  text_append_n (result, def_call.text, def_call.end);
+  free (def_call.text);
+  if (anchor_str_len)
+    {
+      text_append_n (result, anchor, anchor_str_len);
+      text_append_n (result, "</span>", 7);
+    }
+
+  text_append_n (result, "</dt>\n", 6);
+
+  free (anchor);
+}
+
 void
 convert_table_term_type (CONVERTER *self, const enum element_type type,
                         const ELEMENT *element, const char *content,
@@ -6244,6 +6612,7 @@ static TYPE_INTERNAL_CONVERSION 
types_internal_conversion_table[] = {
   {ET_table_term, &convert_table_term_type},
   {ET_text, &convert_text},
   {ET_row, &convert_row_type},
+  {ET_def_line, &convert_def_line_type},
   {0, 0},
 };
 
@@ -6530,8 +6899,13 @@ reset_translated_special_unit_info_tree (CONVERTER *self)
       for (i = 0; i < special_unit_varieties->number; i++)
         {
           if (self->special_unit_info_tree[tree_type][i])
-            destroy_element_and_children (
-              self->special_unit_info_tree[tree_type][i]);
+            {
+              remove_element_from_list (&self->tree_to_build,
+                       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;
         }
     }
@@ -6993,8 +7367,6 @@ html_finalize_output_state (CONVERTER *self)
 
   self->added_targets.number = 0;
 
-  free (self->tree_to_build.list);
-
   free (self->special_units_direction_name);
   self->special_units_direction_name = 0;
   free (self->output_unit_file_indices);
@@ -7063,7 +7435,7 @@ html_finalize_output_state (CONVERTER *self)
         {
           char *inline_content = associated_content->inline_content;
           message_list_document_warn (&self->error_messages, self->conf,
-             "associated inline content not used: %s\n",
+             "associated inline content not used: '%s'",
               inline_content);
           free (associated_content->inline_content);
         }
@@ -7078,8 +7450,21 @@ html_finalize_output_state (CONVERTER *self)
   if (1)
     {
       if (self->tree_to_build.number > 0)
-        fprintf (stderr, "BUG: tree_to_build: %zu\n",
-                         self->tree_to_build.number);
+        {
+          fprintf (stderr, "BUG: tree_to_build: %zu\n",
+                           self->tree_to_build.number);
+          if (self->conf->DEBUG > 0)
+            {
+              for (i = 0; i < self->tree_to_build.number; i++)
+                {
+                  ELEMENT *element = self->tree_to_build.list[i];
+              /* in most cases, the trees have been destroyed, so this
+                 will often segfault */
+                  fprintf (stderr, " %d: '%s'\n", i,
+                                   convert_to_texinfo (element));
+                }
+            }
+        }
       if (self->html_document_context.top > 0)
         fprintf (stderr, "BUG: document context top > 0: %zu\n",
                          self->html_document_context.top);
@@ -7090,6 +7475,9 @@ html_finalize_output_state (CONVERTER *self)
         fprintf (stderr, "BUG: ignore_notice: %d\n",
                          self->ignore_notice);
     }
+
+  free (self->tree_to_build.list);
+
 }
 
 void
@@ -7125,6 +7513,11 @@ html_free_converter (CONVERTER *self)
     {
       fprintf (stderr, "BUG: %zu ignored messages in HTML conversion\n",
                        self->error_messages.number);
+      for (i = 0; i < self->error_messages.number; i++)
+        {
+          ERROR_MESSAGE *error_message = &self->error_messages.list[i];
+          fprintf (stderr, " %d: %s", i, error_message->error_line);
+        }
     }
 
   free_generic_converter (self);
@@ -7916,12 +8309,15 @@ convert_to_html_internal (CONVERTER *self, const 
ELEMENT *element,
         {
           char *translation_context
             = lookup_extra_string (element, "translation_context");
-          const ELEMENT *translated = html_gdt_tree (element->text.text,
-                                      self->document,
-                                      self, 0, translation_context, 0);
+          ELEMENT *translated = html_gdt_tree (element->text.text,
+                                               self->document,
+                                           self, 0, translation_context, 0);
+
+          add_to_element_list (&self->tree_to_build, translated);
 
           convert_to_html_internal (self, translated, &text_result,
                                     "translated TEXT");
+          remove_element_from_list (&self->tree_to_build, translated);
         }
       else
         {
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index f2a7943a91..2ecf5e0dc4 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -51,6 +51,34 @@
 const char *whitespace_chars = " \t\v\f\r\n";
 const char *digit_chars = "0123456789";
 
+DEF_ALIAS def_aliases[] = {
+  CM_defun, CM_deffn, "Function", "category of functions for @defun",
+  CM_defmac, CM_deffn, "Macro", 0,
+  CM_defspec, CM_deffn, "Special Form", 0,
+  CM_defvar, CM_defvr, "Variable", "category of variables for @defvar",
+  CM_defopt, CM_defvr, "User Option", 0,
+  CM_deftypefun, CM_deftypefn, "Function", "category of functions for 
@deftypefun",
+  CM_deftypevar, CM_deftypevr, "Variable", "category of variables in typed 
languages for @deftypevar",
+  CM_defivar, CM_defcv, "Instance Variable", "category of instance variables 
in object-oriented programming for @defivar",
+  CM_deftypeivar, CM_deftypecv, "Instance Variable", "category of instance 
variables with data type in object-oriented programming for @deftypeivar",
+  CM_defmethod, CM_defop, "Method", "category of methods in object-oriented 
programming for @defmethod",
+  CM_deftypemethod, CM_deftypeop, "Method", "category of methods with data 
type in object-oriented programming for @deftypemethod",
+
+  /* the following aliases are not used in the XS parser */
+  CM_defunx, CM_deffnx, "Function", "category of functions for @defun",
+  CM_defmacx, CM_deffnx, "Macro", 0,
+  CM_defspecx, CM_deffnx, "Special Form", 0,
+  CM_defvarx, CM_defvrx, "Variable", "category of variables for @defvar",
+  CM_defoptx, CM_defvrx, "User Option", 0,
+  CM_deftypefunx, CM_deftypefnx, "Function", "category of functions for 
@deftypefun",
+  CM_deftypevarx, CM_deftypevrx, "Variable", "category of variables in typed 
languages for @deftypevar",
+  CM_defivarx, CM_defcvx, "Instance Variable", "category of instance variables 
in object-oriented programming for @defivar",
+  CM_deftypeivarx, CM_deftypecvx, "Instance Variable", "category of instance 
variables with data type in object-oriented programming for @deftypeivar",
+  CM_defmethodx, CM_defopx, "Method", "category of methods in object-oriented 
programming for @defmethod",
+  CM_deftypemethodx, CM_deftypeopx, "Method", "category of methods with data 
type in object-oriented programming for @deftypemethod",
+  0, 0, 0, 0
+};
+
 /* to keep synchronized with enum directions in tree_types.h */
 const char *direction_names[] = {"next", "prev", "up"};
 const char *direction_texts[] = {"Next", "Prev", "Up"};
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index a9349a4903..e2ed603440 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -57,6 +57,15 @@ typedef struct {
 extern ENCODING_CONVERSION_LIST output_conversions;
 extern ENCODING_CONVERSION_LIST input_conversions;
 
+typedef struct {
+    enum command_id alias;
+    enum command_id command;
+    char *category;
+    char *translation_context;
+} DEF_ALIAS;
+
+extern DEF_ALIAS def_aliases[];
+
 enum global_option_command_type {
    GO_NONE,
    GO_int,
diff --git a/tp/Texinfo/XS/parsetexi/def.c b/tp/Texinfo/XS/parsetexi/def.c
index d954877954..bad886a628 100644
--- a/tp/Texinfo/XS/parsetexi/def.c
+++ b/tp/Texinfo/XS/parsetexi/def.c
@@ -28,7 +28,7 @@
 #include "tree.h"
 #include "builtin_commands.h"
 #include "extra.h"
-/* for whitespace_chars and fatal */
+/* for whitespace_chars fatal def_aliases */
 #include "utils.h"
 /* for relocate_source_marks */
 #include "manipulate_tree.h"
@@ -140,28 +140,6 @@ next_bracketed_or_word_agg (ELEMENT *current, int *i)
   return new;
 }
 
-typedef struct {
-    enum command_id alias;
-    enum command_id command;
-    char *category;
-    char *translation_context;
-} DEF_ALIAS;
-
-DEF_ALIAS def_aliases[] = {
-  CM_defun, CM_deffn, "Function", "category of functions for @defun",
-  CM_defmac, CM_deffn, "Macro", 0,
-  CM_defspec, CM_deffn, "Special Form", 0,
-  CM_defvar, CM_defvr, "Variable", "category of variables for @defvar",
-  CM_defopt, CM_defvr, "User Option", 0,
-  CM_deftypefun, CM_deftypefn, "Function", "category of functions for 
@deftypefun",
-  CM_deftypevar, CM_deftypevr, "Variable", "category of variables in typed 
languages for @deftypevar",
-  CM_defivar, CM_defcv, "Instance Variable", "category of instance variables 
in object-oriented programming for @defivar",
-  CM_deftypeivar, CM_deftypecv, "Instance Variable", "category of instance 
variables with data type in object-oriented programming for @deftypeivar",
-  CM_defmethod, CM_defop, "Method", "category of methods in object-oriented 
programming for @defmethod",
-  CM_deftypemethod, CM_deftypeop, "Method", "category of methods with data 
type in object-oriented programming for @deftypemethod",
-  0, 0, 0, 0
-};
-
 typedef struct {
     enum command_id command;
     char **arguments;
@@ -371,7 +349,7 @@ parse_def (enum command_id command, ELEMENT *current)
     {
       char *category;
       int i;
-      for (i = 0; i < sizeof (def_aliases) / sizeof (*def_aliases); i++)
+      for (i = 0; def_aliases[i].alias ; i++)
         {
           if (def_aliases[i].alias == command)
             goto found;



reply via email to

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