texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Sat, 30 Dec 2023 13:57:13 -0500 (EST)

branch: master
commit 54a6c479b7f793588cbab17b8ba53dac845ee466
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sat Dec 30 19:57:08 2023 +0100

    * tp/Texinfo/Convert/HTML.pm, tp/Texinfo/XS/convert/converter.c:
    move contents_inline_element up in source file.
    
    * tp/Texinfo/XS/convert/converter.c: move mini_toc_internal and
    convert_heading_command up in source file.
---
 ChangeLog                            |    8 +
 tp/Texinfo/Convert/HTML.pm           |   90 +-
 tp/Texinfo/XS/convert/convert_html.c | 2362 +++++++++++++++++-----------------
 3 files changed, 1234 insertions(+), 1226 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 629e29c1f5..9c3efb93a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2023-12-30  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Convert/HTML.pm, tp/Texinfo/XS/convert/converter.c:
+       move contents_inline_element up in source file.
+
+       * tp/Texinfo/XS/convert/converter.c: move mini_toc_internal and
+       convert_heading_command up in source file.
+
 2023-12-30  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/XS/convert/converter.c (xml_comment): add.
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index 6cf6806b9b..4751f9e601 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -4600,6 +4600,51 @@ sub close_registered_sections_level($$)
   return \@closed_elements;
 }
 
+sub _contents_inline_element($$$)
+{
+  my $self = shift;
+  my $cmdname = shift;
+  # undef unless called from @-command formatting function
+  my $element = shift;
+
+  print STDERR "CONTENTS_INLINE $cmdname\n" if ($self->get_conf('DEBUG'));
+  my $table_of_contents
+   = &{$self->formatting_function('format_contents')}($self,
+                                                $cmdname, $element);
+  if ($table_of_contents) {
+    my ($special_unit_variety, $special_unit, $class_base,
+        $special_unit_direction)
+          = $self->command_name_special_unit_information($cmdname);
+    # FIXME is element- the best prefix?
+    my $result = $self->html_attribute_class('div', ["element-${class_base}"]);
+    my $heading;
+    if ($special_unit) {
+      my $unit_command = $special_unit->{'unit_command'};
+      my $id = $self->command_id($unit_command);
+      if (defined($id) and $id ne '') {
+        $result .= " id=\"$id\"";
+      }
+      $heading = $self->command_text($unit_command);
+    } else {
+      # happens when called as convert() and not output()
+      my $heading_tree = $self->special_unit_info('heading_tree',
+                                             $special_unit_variety);
+      if (defined($heading_tree)) {
+        $heading = $self->convert_tree($heading_tree,
+                                       "convert $cmdname special heading");
+      }
+    }
+    $heading = '' if (!defined($heading));
+    $result .= ">\n";
+    $result .= &{$self->formatting_function('format_heading_text')}($self,
+                                  $cmdname, [$class_base.'-heading'], $heading,
+                                  
$self->get_conf('CHAPTER_HEADER_LEVEL'))."\n";
+    $result .= $table_of_contents . "</div>\n";
+    return $result;
+  }
+  return '';
+}
+
 sub _convert_heading_command($$$$$)
 {
   my $self = shift;
@@ -6549,51 +6594,6 @@ sub _convert_printindex_command($$$$)
 }
 $default_commands_conversion{'printindex'} = \&_convert_printindex_command;
 
-sub _contents_inline_element($$$)
-{
-  my $self = shift;
-  my $cmdname = shift;
-  # undef unless called from @-command formatting function
-  my $element = shift;
-
-  print STDERR "CONTENTS_INLINE $cmdname\n" if ($self->get_conf('DEBUG'));
-  my $table_of_contents
-   = &{$self->formatting_function('format_contents')}($self,
-                                                $cmdname, $element);
-  if ($table_of_contents) {
-    my ($special_unit_variety, $special_unit, $class_base,
-        $special_unit_direction)
-          = $self->command_name_special_unit_information($cmdname);
-    # FIXME is element- the best prefix?
-    my $result = $self->html_attribute_class('div', ["element-${class_base}"]);
-    my $heading;
-    if ($special_unit) {
-      my $unit_command = $special_unit->{'unit_command'};
-      my $id = $self->command_id($unit_command);
-      if (defined($id) and $id ne '') {
-        $result .= " id=\"$id\"";
-      }
-      $heading = $self->command_text($unit_command);
-    } else {
-      # happens when called as convert() and not output()
-      my $heading_tree = $self->special_unit_info('heading_tree',
-                                             $special_unit_variety);
-      if (defined($heading_tree)) {
-        $heading = $self->convert_tree($heading_tree,
-                                       "convert $cmdname special heading");
-      }
-    }
-    $heading = '' if (!defined($heading));
-    $result .= ">\n";
-    $result .= &{$self->formatting_function('format_heading_text')}($self,
-                                  $cmdname, [$class_base.'-heading'], $heading,
-                                  
$self->get_conf('CHAPTER_HEADER_LEVEL'))."\n";
-    $result .= $table_of_contents . "</div>\n";
-    return $result;
-  }
-  return '';
-}
-
 sub _convert_informative_command($$$)
 {
   my $self = shift;
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index ba9094a71b..a9bd84a24a 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -9236,1056 +9236,1113 @@ convert_U_command (CONVERTER *self, const enum 
command_id cmd,
     }
 }
 
-void
-convert_raw_command (CONVERTER *self, const enum command_id cmd,
-                    const ELEMENT *element,
-                    const HTML_ARGS_FORMATTED *args_formatted,
-                    const char *content, TEXT *result)
+/* command is NULL unless called from @-command formatting function */
+static char *
+contents_inline_element (CONVERTER *self, const enum command_id cmd,
+                         const ELEMENT *element)
 {
-  if (cmd == CM_html)
+  char *table_of_contents;
+
+  if (self->conf->DEBUG > 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))
     {
-      if (content)
-        text_append (result, content);
-      return;
-    }
+      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)
+            {
+              char *heading = 0;
+              TEXT result;
+              STRING_LIST *classes;
+              char *class_base;
+              char *class;
+              char *attribute_class;
 
-  /* TODO the message is not marked as a translatable message.  Not
-     such an issue since the perl message is, but it could be problematic
-     if the perl code is removed. */
-  noticed_line_warn (self, element, "raw format %s is not converted",
-                     element_command_name (element));
-                //builtin_command_name (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];
 
-  format_protect_text (self, content, result);
-}
+              text_init (&result);
 
-void
-convert_xref_commands (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;
+              classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+              memset (classes, 0, sizeof (STRING_LIST));
 
-  ELEMENT *book_element = 0;
-  ELEMENT *reference_element = 0;
+              class_base = special_unit_info (self, SUI_type_class,
+                                              special_unit_variety);
+              xasprintf (&class, "element-%s", class_base);
 
-  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]);
-    }
+              add_string (class, classes);
+              free (class);
+              attribute_class = html_attribute_class (self, "div", classes);
+              clear_strings_list (classes);
 
-  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];
+              text_append (&result, attribute_class);
+              free (attribute_class);
 
-  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 (special_unit)
+                {
+                  ELEMENT *unit_command = special_unit->unit_command;
+                  char *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);
+                }
+              else
+                { /* happens when called as convert() and not output() */
+                  ELEMENT *heading_tree = special_unit_info_tree (self,
+                                   SUIT_type_heading, special_unit_variety);
+                  if (heading_tree)
+                    {
+                      char *explanation;
+                      xasprintf (&explanation, "convert %s special heading",
+                                               builtin_command_name (cmd));
+                      heading = html_convert_tree (self, heading_tree,
+                                                   explanation);
+                      free (explanation);
+                    }
+                }
+              text_append_n (&result, ">\n", 2);
 
-  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];
+              xasprintf (&class, "%s-heading", class_base);
 
-  if (element->args.number > 0)
-    arg_node = element->args.list[0];
+              add_string (class, classes);
+              free (class);
 
-  /* check for internal reference */
-  if (cmd != CM_inforef && !book && !file && arg_node)
-    {
-      char *normalized = lookup_extra_string (arg_node, "normalized");
-      ELEMENT *manual_content = lookup_extra_element (arg_node,
-                                                      "manual_content");
-      if (normalized && !manual_content)
-        {
-          target_node = find_identifier_target (
-                                  self->document->identifiers_target,
-                                  normalized);
+              if (!heading)
+                heading = strdup ("");
+              format_heading_text (self, 0, classes, heading,
+                                   self->conf->CHAPTER_HEADER_LEVEL,
+                                   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;
+}
 
-  /* internal reference */
-  if (target_node)
+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;
+
+  /* drop the const with a cast, but we know that it is not modified, with
+     0 as the third argument */
+  ELEMENT_LIST *section_childs = lookup_extra_contents ((ELEMENT *) element,
+                                                        "section_childs", 0);
+  if (section_childs && section_childs->number > 0)
     {
-      char *href;
-      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,
-                                                       "associated_section");
-      reference_element = new_element (ET__converted);
-      NAMED_STRING_ELEMENT_LIST *substrings
-                                       = new_named_string_element_list ();
+      char *attribute_class;
+      size_t i;
 
-      if (!associated_section || associated_section != target_root)
-        target_root = target_node;
+      attribute_class = html_attribute_class (self, "ul", &mini_toc_classes);
 
-      href = html_command_href (self, target_root, 0, element, 0);
+      text_append (result, attribute_class);
+      free (attribute_class);
+      text_append_n (result, ">\n", 2);
 
-      if (!name)
+      for (i = 0; i < section_childs->number; i++)
         {
-          if (!strcmp (self->conf->xrefautomaticsectiontitle, "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))
+          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 = 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 > 0 && entry_index < 10)
             {
-              target_root = associated_section;
-              name = html_command_text (self, target_root, HTT_text_nonumber);
+              xasprintf (&accesskey, " accesskey=\"%d\"", entry_index);
             }
-          else if (target_node->cmd == CM_float)
+          else
+            accesskey = strdup ("");
+
+          if (strlen (text))
             {
-              if (self->conf->XREF_USE_FLOAT_LABEL <= 0)
+              if (href)
                 {
-                  name = html_command_text (self, target_root, 0);
+                  text_printf (result, "<li><a href=\"%s\"%s>%s</a>",
+                               href, accesskey, text);
                 }
-              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 <= 0
-                   && (self->conf->XREF_USE_NODE_NAME_ARG == 0
-                       || !html_in_preformatted_context (self)))
-            {
-              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
+                text_printf (result, "<li>%s", text);
+
+              text_append_n (result, "</li>\n", 6);
             }
-          else
-            name = strdup ("");
+          free (text);
+          free (href);
+          free (accesskey);
         }
+      text_append_n (result, "</ul>\n", 6);
+    }
+}
 
-      if (href && !html_in_string (self))
-        {
-          char *attribute_class;
-          classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
-          memset (classes, 0, sizeof (STRING_LIST));
-          add_string (builtin_command_name (cmd), classes);
+void
+convert_heading_command (CONVERTER *self, const enum command_id cmd,
+                    const ELEMENT *element,
+                    const HTML_ARGS_FORMATTED *args_formatted,
+                    const char *content, TEXT *result)
+{
+  char *element_id;
+  OUTPUT_UNIT *output_unit = 0;
+  TEXT element_header;
+  /* could use only one, but this is more similar to perl code */
+  TEXT tables_of_contents;
+  TEXT mini_toc_or_auto_menu;
+  enum command_id level_corrected_cmd;
+  int status;
+  char *heading;
+  int heading_level = -1;
+  int do_heading;
+  char *heading_id = 0;
+  char *level_set_class = 0;
 
-          attribute_class = html_attribute_class (self, "a", classes);
-          text_append (&reference_element->text, attribute_class);
-          text_printf (&reference_element->text, " href=\"%s\">%s</a>",
-                                                 href, name);
-          free (attribute_class);
-          destroy_strings_list (classes);
-        }
-      else
-        {
-          text_append (&reference_element->text, name);
-        }
-      free (href);
+  const ELEMENT *opening_section = 0;
+  enum command_id level_corrected_opening_section_cmd = 0;
 
-      add_element_to_named_string_element_list (substrings,
-                          "reference_name", reference_element);
-      if (cmd == CM_pxref)
-        {
-          tree = html_gdt_tree ("see {reference_name}", self->document,
-                                self, substrings, 0, 0);
-        }
-      else if (cmd == CM_xref)
-        {
-          tree = html_gdt_tree ("See {reference_name}", self->document,
-                                self, substrings, 0, 0);
-        }
-      else if (cmd == CM_ref || cmd == CM_link)
+  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->cmd != CM_node)
         {
-          tree = html_gdt_tree ("{reference_name}", self->document,
-                                self, substrings, 0, 0);
+          char *heading = html_command_text (self, element, HTT_string);
+          text_append (result, heading);
+          text_append_n (result, "\n", 1);
+          free (heading);
         }
-      destroy_named_string_element_list (substrings);
+      if (content)
+        text_append (result, content);
+      return;
     }
-  else
-    {
-     /* external reference */
-      char *href = 0;
-      char *reference = 0;
-      char *book_reference = 0;
 
-      NAMED_STRING_ELEMENT_LIST *substrings
-                                       = new_named_string_element_list ();
+  element_id = html_command_id (self, element);
 
- /* We setup a label_element based on the node argument and not directly the
-    node argument to be able to use the $file argument */
+  if (self->conf->DEBUG > 0)
+    fprintf (stderr, "CONVERT elt heading %s\n",
+                     root_heading_command_to_texinfo (element));
 
-      ELEMENT *label_element = 0;
-      ELEMENT *manual_content = 0;
-      ELEMENT *node_content = 0;
+  if (flags & CF_root && element->associated_unit)
+    output_unit = element->associated_unit;
 
-      if (arg_node)
+  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 (&tables_of_contents);
+  text_append (&tables_of_contents, "");
+  if (element->cmd == CM_top
+      && !strcmp (self->conf->CONTENTS_OUTPUT_LOCATION, "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++)
         {
-          node_content = lookup_extra_element (arg_node, "node_content");
-          if (node_content)
+          int contents_set = 0;
+          enum command_id cmd = contents_cmds[i];
+          COMMAND_OPTION_REF *contents_option_ref
+             = get_command_option (self->conf, cmd);
+          if (*(contents_option_ref->int_ref) > 0)
+            contents_set = 1;
+          free (contents_option_ref);
+          if (contents_set)
             {
-              char *normalized = lookup_extra_string (arg_node, "normalized");
-              label_element = new_element (ET_NONE);
-              add_extra_element (label_element, "node_content", node_content);
-              if (normalized)
-                add_extra_string_dup (label_element, "normalized", normalized);
+              char *contents_text
+                = contents_inline_element (self, cmd, 0);
+              if (contents_text)
+                {
+                  text_append (&tables_of_contents, contents_text);
+                  free (contents_text);
+                }
             }
         }
+    }
 
- /* file argument takes precedence over the file in the node (file)node entry 
*/
-      if (file)
-        {
-          if (!label_element)
-            label_element = new_element (ET_NONE);
-          /* TODO would be better to have add_extra_element argument const */
-          add_extra_element (label_element, "manual_content",
-                             (ELEMENT *)file_arg->tree);
-        }
-      else
+  text_init (&mini_toc_or_auto_menu);
+  text_append (&mini_toc_or_auto_menu, "");
+  if (tables_of_contents.end <= 0
+      && (flags & CF_sectioning_heading))
+    {
+      if (!strcmp (self->conf->FORMAT_MENU, "sectiontoc"))
         {
-          manual_content = lookup_extra_element (arg_node, "manual_content");
+          mini_toc_internal (self, element, &mini_toc_or_auto_menu);
         }
-
-      if (manual_content)
+      else if (!strcmp (self->conf->FORMAT_MENU, "menu"))
         {
-          ELEMENT *root_code;
-
-          if (!label_element)
-            label_element = new_element (ET_NONE);
-
-          add_extra_element (label_element, "manual_content",
-                             manual_content);
+          ELEMENT *node
+            = lookup_extra_element (element, "associated_node");
+          if (node)
+            {
+              int automatic_directions = (node->args.number <= 1);
+              ELEMENT_LIST *menus = lookup_extra_contents (node, "menus", 0);
+              if (!menus && automatic_directions)
+                {
+                  ELEMENT *menu_node
+                   = new_complete_menu_master_menu (self->conf,
+                             self->document->identifiers_target, node);
 
-          root_code = new_element (ET__code);
+                  if (menu_node)
+                    {
+                      add_to_element_list (&self->tree_to_build, menu_node);
+                      convert_to_html_internal (self, menu_node,
+                                                &mini_toc_or_auto_menu, 0);
+                      remove_element_from_list (&self->tree_to_build,
+                                                menu_node);
+                      /* there are only new or copied elements in the menu */
+                      destroy_element_and_children (menu_node);
+                    }
+                }
+            }
+        }
+    }
 
-          add_to_contents_as_array (root_code, manual_content);
+  if (self->conf->NO_TOP_NODE_OUTPUT > 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;
 
-          add_to_element_list (&self->tree_to_build, root_code);
-          file = html_convert_tree (self, root_code, "node file in ref");
-          remove_element_from_list (&self->tree_to_build, root_code);
-          destroy_element (root_code);
+      if (cmd == CM_node)
+        node_element = element;
+      else if (cmd == CM_part)
+        {
+          ELEMENT *part_following_node
+            = lookup_extra_element (element, "part_following_node");
+          if (part_following_node)
+            node_element = part_following_node;
         }
-
-      if (!name)
+      if (node_element || cmd == CM_part)
         {
-          if (book)
+          int node_is_top = 0;
+          if (node_element)
             {
-              if (node_content)
+              char *normalized = lookup_extra_string (node_element,
+                                                      "normalized");
+              if (normalized && !strcmp (normalized, "Top"))
                 {
-                  char *node_name;
-                  ELEMENT *node_no_file_tree = new_element (ET__code);
-                  add_to_contents_as_array (node_no_file_tree, node_content);
-
-                  add_to_element_list (&self->tree_to_build, 
node_no_file_tree);
-                  node_name = html_convert_tree (self, node_no_file_tree,
-                                                 "node in ref");
-                  remove_element_from_list (&self->tree_to_build, 
node_no_file_tree);
-                  destroy_element (node_no_file_tree);
-
-                  if (node_name && strcmp (node_name, "Top"))
-                    name = node_name;
-                  else
-                    free (node_name);
+                  node_is_top = 1;
+                  in_skipped_node_top = 1;
+                  self->shared_conversion_state.in_skipped_node_top
+                    = in_skipped_node_top;
                 }
             }
-          else
+          if (!node_is_top && in_skipped_node_top == 1)
             {
-              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]);
+              in_skipped_node_top = -1;
+              self->shared_conversion_state.in_skipped_node_top
+                = in_skipped_node_top;
             }
         }
-
-      if (label_element)
+      if (in_skipped_node_top == 1)
         {
-          if (!html_in_string (self))
-            href = html_command_href (self, label_element, 0, element, 0);
-          destroy_element (label_element);
+          format_separate_anchor (self, element_id,
+                                  builtin_command_name(cmd), result);
+          text_append (result, element_header.text);
+          free (element_header.text);
+          text_append (result, tables_of_contents.text);
+          free (tables_of_contents.text);
+          text_append (result, mini_toc_or_auto_menu.text);
+          free (mini_toc_or_auto_menu.text);
+          return;
         }
+    }
 
-      if (href)
+  lookup_extra_integer (element, "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)
         {
-       /* 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 <= 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);
+          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, "associated_section");
+      if (opening_section)
+        level_corrected_opening_section_cmd
+          = section_level_adjusted_command_name (opening_section);
+    }
+  else
+    {
+      ELEMENT *associated_node
+        = lookup_extra_element (element, "associated_node");
 
-      if (book && reference)
+       /* 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))
         {
-          book_element = new_element (ET__converted);
-          text_append (&book_element->text, book);
-          reference_element = new_element (ET__converted);
-          text_append (&reference_element->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_gdt_tree ("see {reference} in @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else if (cmd == CM_xref)
-            {
-              tree = html_gdt_tree ("See {reference} in @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else /* @ref */
-            {
-              tree = html_gdt_tree ("{reference} in @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
+          opening_section = element;
+          level_corrected_opening_section_cmd = level_corrected_cmd;
         }
-      else if (book_reference)
-        {
-          book_element = new_element (ET__converted);
-          text_append (&book_element->text, book_reference);
+    }
 
-          add_element_to_named_string_element_list (substrings,
-                                          "book_reference", book_element);
-          if (cmd == CM_pxref)
-            {
-              tree = html_gdt_tree ("see @cite{{book_reference}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else if (cmd == CM_xref || cmd == CM_inforef)
-            {
-              tree = html_gdt_tree ("See @cite{{book_reference}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else /* @ref */
+  /*
+   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);
+
+  if (cmd == CM_node)
+    {
+      ELEMENT *associated_section
+        = lookup_extra_element (element, "associated_section");
+      char *normalized = lookup_extra_string (element, "normalized");
+      if ((!output_unit
+           || (output_unit->unit_command
+               && output_unit->unit_command == element
+               && !associated_section))
+          && normalized)
+        {
+          if (!strcmp (normalized, "Top"))
+            heading_level = 0;
+          else
             {
-              tree = html_gdt_tree ("@cite{{book_reference}}",
-                                    self->document, self, substrings, 0, 0);
+              int use_next_heading = 0;
+              if (self->conf->USE_NEXT_HEADING_FOR_LONE_NODE > 0)
+                {
+                  ELEMENT *next_heading
+                    = find_root_command_next_heading_command (element,
+                                                        self->expanded_formats,
+                    (!strcmp (self->conf->CONTENTS_OUTPUT_LOCATION, "inline")),
+                            0);
+                  if (next_heading)
+                    use_next_heading = 1;
+                }
+              if (!use_next_heading)
+                /* use node */
+                heading_level = 3;
             }
         }
-      else if (book && name)
+    }
+  else
+    {
+      int status;
+      int level = lookup_extra_integer (element, "section_level", &status);
+      if (status >= 0)
         {
-          book_element = new_element (ET__converted);
-          text_append (&book_element->text, book);
-          reference_element = new_element (ET__converted);
-          text_append (&reference_element->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_gdt_tree ("see `{section}' in @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else if (cmd == CM_xref || cmd == CM_inforef)
-            {
-              tree = html_gdt_tree ("See `{section}' in @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else /* @ref */
-            {
-              tree = html_gdt_tree ("`{section}' in @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
+          heading_level = level;
         }
-      else if (book)
+      else
         {
-          book_element = new_element (ET__converted);
-          text_append (&book_element->text, book);
+          heading_level = section_level (element);
+        }
+    }
+  do_heading = (heading && strlen (heading) && heading_level >= 0);
 
-          add_element_to_named_string_element_list (substrings,
-                                          "book", book_element);
-          if (cmd == CM_pxref)
-            {
-              tree = html_gdt_tree ("see @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else if (cmd == CM_xref || cmd == CM_inforef)
-            {
-              tree = html_gdt_tree ("See @cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else /* @ref */
+  /* 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, "section_level", &status);
+      STRING_LIST *closed_strings;
+
+      closed_strings = html_close_registered_sections_level (self, level);
+
+      if (closed_strings->number)
+        {
+          int i;
+          for (i = 0; i < closed_strings->number; i++)
             {
-              tree = html_gdt_tree ("@cite{{book}}",
-                                    self->document, self, substrings, 0, 0);
+              text_append (result, closed_strings->list[i]);
+              free (closed_strings->list[i]);
             }
         }
-      else if (reference)
-        {
-          reference_element = new_element (ET__converted);
-          text_append (&reference_element->text, reference);
+      free (closed_strings->list);
+      free (closed_strings);
 
-          add_element_to_named_string_element_list (substrings,
-                                         "reference", reference_element);
-          if (cmd == CM_pxref)
-            {
-              tree = html_gdt_tree ("see {reference}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else if (cmd == CM_xref || cmd == CM_inforef)
-            {
-              tree = html_gdt_tree ("See {reference}",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else /* @ref */
+      html_register_opened_section_level (self, 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 = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+      memset (classes, 0, sizeof (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 > 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)
             {
-              tree = html_gdt_tree ("{reference}",
-                                    self->document, self, substrings, 0, 0);
+              char *heading_tmp = strdup (heading);
+              free (heading);
+              xasprintf (&heading, "<a href=\"%s\">%s</a>",
+                                   content_href, heading_tmp);
+              free (heading_tmp);
+              free (content_href);
             }
         }
-      else if (name)
-        {
-          reference_element = new_element (ET__converted);
-          text_append (&reference_element->text, name);
 
-          add_element_to_named_string_element_list (substrings,
-                                         "section", reference_element);
-          if (cmd == CM_pxref)
-            {
-              tree = html_gdt_tree ("see `{section}'",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else if (cmd == CM_xref || cmd == CM_inforef)
-            {
-              tree = html_gdt_tree ("See `{section}'",
-                                    self->document, self, substrings, 0, 0);
-            }
-          else /* @ref */
+      heading_classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+      memset (heading_classes, 0, sizeof (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)
             {
-              tree = html_gdt_tree ("`{section}'",
-                                    self->document, self, substrings, 0, 0);
+              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);
         }
-      free (reference);
-      free (book_reference);
-      destroy_named_string_element_list (substrings);
+      else
+        {
+          format_heading_text (self, level_corrected_cmd,
+                    heading_classes, heading,
+                    heading_level + self->conf->CHAPTER_HEADER_LEVEL -1,
+                    heading_id, element, element_id, result);
+        }
+      destroy_strings_list (heading_classes);
     }
-
-  if (tree)
+  else if (heading_id)
     {
-      char *context_str;
-      xasprintf (&context_str, "convert xref %s", builtin_command_name (cmd));
-      add_to_element_list (&self->tree_to_build, tree);
-      convert_to_html_internal (self, tree, result, context_str);
-      remove_element_from_list (&self->tree_to_build, tree);
-      free (context_str);
-      /* should destroy reference_element and book_element */
-      destroy_element_and_children (tree);
+   /* 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 (file);
-  free (name);
+  free (heading);
+  free (level_set_class);
+
+  if (content)
+    text_append (result, content);
+
+  text_append (result, tables_of_contents.text);
+  free (tables_of_contents.text);
+  text_append (result, mini_toc_or_auto_menu.text);
+  free (mini_toc_or_auto_menu.text);
 }
 
-/* command is NULL unless called from @-command formatting function */
-static char *
-contents_inline_element (CONVERTER *self, const enum command_id cmd,
-                         const ELEMENT *element)
+void
+convert_raw_command (CONVERTER *self, const enum command_id cmd,
+                    const ELEMENT *element,
+                    const HTML_ARGS_FORMATTED *args_formatted,
+                    const char *content, TEXT *result)
 {
-  char *table_of_contents;
+  if (cmd == CM_html)
+    {
+      if (content)
+        text_append (result, content);
+      return;
+    }
 
-  if (self->conf->DEBUG > 0)
-    fprintf (stderr, "CONTENTS_INLINE %s\n", builtin_command_name (cmd));
+  /* TODO the message is not marked as a translatable message.  Not
+     such an issue since the perl message is, but it could be problematic
+     if the perl code is removed. */
+  noticed_line_warn (self, element, "raw format %s is not converted",
+                     element_command_name (element));
+                //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)
-            {
-              char *heading = 0;
-              TEXT result;
-              STRING_LIST *classes;
-              char *class_base;
-              char *class;
-              char *attribute_class;
+  format_protect_text (self, content, result);
+}
 
-              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];
+void
+convert_xref_commands (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;
 
-              text_init (&result);
+  ELEMENT *book_element = 0;
+  ELEMENT *reference_element = 0;
 
-              classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
-              memset (classes, 0, sizeof (STRING_LIST));
+  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]);
+    }
 
-              class_base = special_unit_info (self, SUI_type_class,
-                                              special_unit_variety);
-              xasprintf (&class, "element-%s", class_base);
+  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];
 
-              add_string (class, classes);
-              free (class);
-              attribute_class = html_attribute_class (self, "div", classes);
-              clear_strings_list (classes);
+  if (file_arg && file_arg->formatted[AFT_type_filenametext]
+      && strlen (file_arg->formatted[AFT_type_filenametext]))
+    {
+      file = strdup (file_arg->formatted[AFT_type_filenametext]);
+    }
 
-              text_append (&result, attribute_class);
-              free (attribute_class);
+  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 (special_unit)
-                {
-                  ELEMENT *unit_command = special_unit->unit_command;
-                  char *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);
-                }
-              else
-                { /* happens when called as convert() and not output() */
-                  ELEMENT *heading_tree = special_unit_info_tree (self,
-                                   SUIT_type_heading, special_unit_variety);
-                  if (heading_tree)
-                    {
-                      char *explanation;
-                      xasprintf (&explanation, "convert %s special heading",
-                                               builtin_command_name (cmd));
-                      heading = html_convert_tree (self, heading_tree,
-                                                   explanation);
-                      free (explanation);
-                    }
-                }
-              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,
-                                   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;
-}
-
-void
-contents_shortcontents_in_title (CONVERTER *self, TEXT *result)
-{
-  if (self->document->sections_list
-      && self->document->sections_list->number > 0
-      && !strcmp (self->conf->CONTENTS_OUTPUT_LOCATION, "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];
-          COMMAND_OPTION_REF *contents_option_ref
-             = get_command_option (self->conf, cmd);
-          if (*(contents_option_ref->int_ref) > 0)
-            contents_set = 1;
-          free (contents_option_ref);
-          if (contents_set)
-            {
-              char *contents_text
-                = contents_inline_element (self, cmd, 0);
-              if (contents_text)
-                {
-                  text_append (result, contents_text);
-                  text_append (result, self->conf->DEFAULT_RULE);
-                  text_append_n (result, "\n", 1);
-                  free (contents_text);
-                }
-            }
-        }
-    }
-}
-
-static void
-format_simpletitle (CONVERTER *self, TEXT *result)
-{
-  char *title_text;
-  char *context_str;
-  STRING_LIST *classes;
-  enum command_id cmd = self->simpletitle_cmd;
-  classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
-  memset (classes, 0, sizeof (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);
-}
-
-/* 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->contents = self->document->global_commands->titlepage->contents;
-      convert_to_html_internal (self, tmp, &result, "convert titlepage");
-      tmp->contents.list = 0;
-      destroy_element (tmp);
-      titlepage_text = 1;
-    }
-  else if (self->simpletitle_tree)
-    {
-      format_simpletitle (self, &result);
-      titlepage_text = 1;
-    }
-  if (titlepage_text)
-    {
-      text_append (&result, self->conf->DEFAULT_RULE);
-      text_append_n (&result, "\n", 1);
-    }
-  contents_shortcontents_in_title (self, &result);
-  return result.text;
-}
-
-char *
-format_titlepage (CONVERTER *self)
-{
-  FORMATTING_REFERENCE *formatting_reference
-   = &self->current_formatting_references[FR_format_titlepage];
-  if (formatting_reference->status == FRS_status_default_set)
-    {
-      return html_default_format_titlepage (self);
-    }
-  else
-    {
-      return call_formatting_function_format_titlepage (self,
-                                               formatting_reference);
-    }
-}
+  if (element->args.number > 0)
+    arg_node = element->args.list[0];
 
-char *
-html_default_format_title_titlepage (CONVERTER *self)
-{
-  if (self->conf->SHOW_TITLE > 0)
+  /* check for internal reference */
+  if (cmd != CM_inforef && !book && !file && arg_node)
     {
-      if (self->conf->USE_TITLEPAGE_FOR_TITLE)
-        {
-          return format_titlepage (self);
-        }
-      else
+      char *normalized = lookup_extra_string (arg_node, "normalized");
+      ELEMENT *manual_content = lookup_extra_element (arg_node,
+                                                      "manual_content");
+      if (normalized && !manual_content)
         {
-          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;
+          target_node = find_identifier_target (
+                                  self->document->identifiers_target,
+                                  normalized);
         }
     }
-  return strdup ("");
-}
 
-char *
-format_title_titlepage (CONVERTER *self)
-{
-  FORMATTING_REFERENCE *formatting_reference
-   = &self->current_formatting_references[FR_format_title_titlepage];
-  if (formatting_reference->status == FRS_status_default_set)
-    {
-      return html_default_format_title_titlepage (self);
-    }
-  else
+  /* internal reference */
+  if (target_node)
     {
-      return call_formatting_function_format_title_titlepage (self,
-                                                      formatting_reference);
-    }
-}
-
-/* NOTE these switches are not done in perl, so the only perl functions
-   that can be callled 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, char 
*explanation)
-{
-  char *result;
-  HTML_DOCUMENT_CONTEXT *top_document_ctx;
-
-  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;
-
-  html_new_document_context (self, "css_string", 0, 0);
-  top_document_ctx = html_top_document_context (self);
-  top_document_ctx->string_ctx++;
-
-  result = html_convert_tree (self, element, explanation);
-
-  html_pop_document_context (self);
-
-  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;
+      char *href;
+      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,
+                                                       "associated_section");
+      reference_element = new_element (ET__converted);
+      NAMED_STRING_ELEMENT_LIST *substrings
+                                       = new_named_string_element_list ();
 
-  return result;
-}
+      if (!associated_section || associated_section != target_root)
+        target_root = target_node;
 
-typedef struct SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD {
-    enum command_id cmd;
-    char *string;
-    char *saved;
-} SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD;
+      href = html_command_href (self, target_root, 0, element, 0);
 
-static SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD
-            special_list_mark_css_string_no_arg_command[] = {
- {CM_minus, "\\2212 ", 0},
- {0, 0, 0},
-};
+      if (!name)
+        {
+          if (!strcmp (self->conf->xrefautomaticsectiontitle, "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;
+              name = html_command_text (self, target_root, HTT_text_nonumber);
+            }
+          else if (target_node->cmd == CM_float)
+            {
+              if (self->conf->XREF_USE_FLOAT_LABEL <= 0)
+                {
+                  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 <= 0
+                   && (self->conf->XREF_USE_NODE_NAME_ARG == 0
+                       || !html_in_preformatted_context (self)))
+            {
+              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 ("");
+        }
 
-char *
-html_convert_css_string_for_list_mark (CONVERTER *self, const ELEMENT *element,
-                                       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_command_conversion[cmd][HCC_type_css_string].text;
-      self->html_command_conversion[cmd][HCC_type_css_string].text
-        = special_list_mark_css_string_no_arg_command[i].string;
-    }
+      if (href && !html_in_string (self))
+        {
+          char *attribute_class;
+          classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+          memset (classes, 0, sizeof (STRING_LIST));
+          add_string (builtin_command_name (cmd), classes);
 
-  result = html_convert_css_string (self, element, explanation);
+          attribute_class = html_attribute_class (self, "a", classes);
+          text_append (&reference_element->text, attribute_class);
+          text_printf (&reference_element->text, " href=\"%s\">%s</a>",
+                                                 href, name);
+          free (attribute_class);
+          destroy_strings_list (classes);
+        }
+      else
+        {
+          text_append (&reference_element->text, name);
+        }
+      free (href);
 
-  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_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;
+      add_element_to_named_string_element_list (substrings,
+                          "reference_name", reference_element);
+      if (cmd == CM_pxref)
+        {
+          tree = html_gdt_tree ("see {reference_name}", self->document,
+                                self, substrings, 0, 0);
+        }
+      else if (cmd == CM_xref)
+        {
+          tree = html_gdt_tree ("See {reference_name}", self->document,
+                                self, substrings, 0, 0);
+        }
+      else if (cmd == CM_ref || cmd == CM_link)
+        {
+          tree = html_gdt_tree ("{reference_name}", self->document,
+                                self, substrings, 0, 0);
+        }
+      destroy_named_string_element_list (substrings);
     }
+  else
+    {
+     /* external reference */
+      char *href = 0;
+      char *reference = 0;
+      char *book_reference = 0;
 
-  return result;
-}
+      NAMED_STRING_ELEMENT_LIST *substrings
+                                       = new_named_string_element_list ();
 
-void
-convert_itemize_command (CONVERTER *self, const enum command_id cmd,
-                    const ELEMENT *element,
-                    const HTML_ARGS_FORMATTED *args_formatted,
-                    const char *content, TEXT *result)
-{
-  ELEMENT *command_as_argument;
-  const char *command_as_argument_name = 0;
-  const char *mark_class_name = 0;
-  STRING_LIST *classes;
-  char *attribute_class;
-  CSS_SELECTOR_STYLE *selector_style = 0;
+ /* We setup a label_element based on the node argument and not directly the
+    node argument to be able to use the $file argument */
 
-  if (html_in_string (self))
-    {
-      if (content)
-        text_append (result, content);
-      return;
-    }
+      ELEMENT *label_element = 0;
+      ELEMENT *manual_content = 0;
+      ELEMENT *node_content = 0;
 
-  command_as_argument = lookup_extra_element (element, "command_as_argument");
-  if (command_as_argument)
-    {
-      if (command_as_argument->cmd == CM_click)
+      if (arg_node)
         {
-          command_as_argument_name = lookup_extra_string (command_as_argument,
-                                                          "clickstyle");
+          node_content = lookup_extra_element (arg_node, "node_content");
+          if (node_content)
+            {
+              char *normalized = lookup_extra_string (arg_node, "normalized");
+              label_element = new_element (ET_NONE);
+              add_extra_element (label_element, "node_content", node_content);
+              if (normalized)
+                add_extra_string_dup (label_element, "normalized", normalized);
+            }
         }
-      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";
+ /* file argument takes precedence over the file in the node (file)node entry 
*/
+      if (file)
+        {
+          if (!label_element)
+            label_element = new_element (ET_NONE);
+          /* TODO would be better to have add_extra_element argument const */
+          add_extra_element (label_element, "manual_content",
+                             (ELEMENT *)file_arg->tree);
+        }
       else
-        mark_class_name = command_as_argument_name;
-    }
+        {
+          manual_content = lookup_extra_element (arg_node, "manual_content");
+        }
 
-  classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
-  memset (classes, 0, sizeof (STRING_LIST));
-  add_string (builtin_command_name(cmd), classes);
+      if (manual_content)
+        {
+          ELEMENT *root_code;
 
-  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);
+          if (!label_element)
+            label_element = new_element (ET_NONE);
 
-      selector_style = find_css_selector_style 
(&self->css_element_class_styles,
-                                                ul_mark_selector);
-      free (ul_mark_selector);
-      if (selector_style)
-        {
-          add_string (mark_class, classes);
-        }
-      free (mark_class);
-    }
+          add_extra_element (label_element, "manual_content",
+                             manual_content);
 
-  attribute_class = html_attribute_class (self, "ul", classes);
-  destroy_strings_list (classes);
-  text_append (result, attribute_class);
-  free (attribute_class);
+          root_code = new_element (ET__code);
 
-  if (!selector_style && self->conf->NO_CSS <= 0)
-    {
-      char *css_string
-        = html_convert_css_string_for_list_mark (self, element->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);
+          add_to_contents_as_array (root_code, manual_content);
+
+          add_to_element_list (&self->tree_to_build, root_code);
+          file = html_convert_tree (self, root_code, "node file in ref");
+          remove_element_from_list (&self->tree_to_build, root_code);
+          destroy_element (root_code);
         }
-      free (css_string);
-    }
 
-  text_append_n (result, ">\n", 2);
-  if (content)
-    text_append (result, content);
-  text_append_n (result, "</ul>\n", 6);
-}
+      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);
 
-static char *mini_toc_array[] = {"mini-toc"};
-static const STRING_LIST mini_toc_classes = {mini_toc_array, 1, 1};
+                  add_to_element_list (&self->tree_to_build, 
node_no_file_tree);
+                  node_name = html_convert_tree (self, node_no_file_tree,
+                                                 "node in ref");
+                  remove_element_from_list (&self->tree_to_build, 
node_no_file_tree);
+                  destroy_element (node_no_file_tree);
 
-/* 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;
+                  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]);
+            }
+        }
 
-  /* drop the const with a cast, but we know that it is not modified, with
-     0 as the third argument */
-  ELEMENT_LIST *section_childs = lookup_extra_contents ((ELEMENT *) element,
-                                                        "section_childs", 0);
-  if (section_childs && section_childs->number > 0)
-    {
-      char *attribute_class;
-      size_t i;
+      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 <= 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);
+        }
 
-      attribute_class = html_attribute_class (self, "ul", &mini_toc_classes);
 
-      text_append (result, attribute_class);
-      free (attribute_class);
-      text_append_n (result, ">\n", 2);
+      if (book && reference)
+        {
+          book_element = new_element (ET__converted);
+          text_append (&book_element->text, book);
+          reference_element = new_element (ET__converted);
+          text_append (&reference_element->text, reference);
 
-      for (i = 0; i < section_childs->number; i++)
+          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_gdt_tree ("see {reference} in @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else if (cmd == CM_xref)
+            {
+              tree = html_gdt_tree ("See {reference} in @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else /* @ref */
+            {
+              tree = html_gdt_tree ("{reference} in @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+        }
+      else if (book_reference)
         {
-          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 = html_command_href (self, section, 0, 0, 0);
+          book_element = new_element (ET__converted);
+          text_append (&book_element->text, book_reference);
 
-          xasprintf (&explanation, "mini_toc @%s",
-                     element_command_name (section));
-          text = html_convert_tree (self, command_tree->tree, explanation);
-          free (explanation);
+          add_element_to_named_string_element_list (substrings,
+                                          "book_reference", book_element);
+          if (cmd == CM_pxref)
+            {
+              tree = html_gdt_tree ("see @cite{{book_reference}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else if (cmd == CM_xref || cmd == CM_inforef)
+            {
+              tree = html_gdt_tree ("See @cite{{book_reference}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else /* @ref */
+            {
+              tree = html_gdt_tree ("@cite{{book_reference}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+        }
+      else if (book && name)
+        {
+          book_element = new_element (ET__converted);
+          text_append (&book_element->text, book);
+          reference_element = new_element (ET__converted);
+          text_append (&reference_element->text, name);
 
-          entry_index++;
+          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_gdt_tree ("see `{section}' in @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else if (cmd == CM_xref || cmd == CM_inforef)
+            {
+              tree = html_gdt_tree ("See `{section}' in @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else /* @ref */
+            {
+              tree = html_gdt_tree ("`{section}' in @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+        }
+      else if (book)
+        {
+          book_element = new_element (ET__converted);
+          text_append (&book_element->text, book);
 
-          if (self->conf->USE_ACCESSKEY > 0 && entry_index < 10)
+          add_element_to_named_string_element_list (substrings,
+                                          "book", book_element);
+          if (cmd == CM_pxref)
             {
-              xasprintf (&accesskey, " accesskey=\"%d\"", entry_index);
+              tree = html_gdt_tree ("see @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
             }
-          else
-            accesskey = strdup ("");
+          else if (cmd == CM_xref || cmd == CM_inforef)
+            {
+              tree = html_gdt_tree ("See @cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else /* @ref */
+            {
+              tree = html_gdt_tree ("@cite{{book}}",
+                                    self->document, self, substrings, 0, 0);
+            }
+        }
+      else if (reference)
+        {
+          reference_element = new_element (ET__converted);
+          text_append (&reference_element->text, reference);
 
-          if (strlen (text))
+          add_element_to_named_string_element_list (substrings,
+                                         "reference", reference_element);
+          if (cmd == CM_pxref)
             {
-              if (href)
-                {
-                  text_printf (result, "<li><a href=\"%s\"%s>%s</a>",
-                               href, accesskey, text);
-                }
-              else
-                text_printf (result, "<li>%s", text);
+              tree = html_gdt_tree ("see {reference}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else if (cmd == CM_xref || cmd == CM_inforef)
+            {
+              tree = html_gdt_tree ("See {reference}",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else /* @ref */
+            {
+              tree = html_gdt_tree ("{reference}",
+                                    self->document, self, substrings, 0, 0);
+            }
+        }
+      else if (name)
+        {
+          reference_element = new_element (ET__converted);
+          text_append (&reference_element->text, name);
 
-              text_append_n (result, "</li>\n", 6);
+          add_element_to_named_string_element_list (substrings,
+                                         "section", reference_element);
+          if (cmd == CM_pxref)
+            {
+              tree = html_gdt_tree ("see `{section}'",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else if (cmd == CM_xref || cmd == CM_inforef)
+            {
+              tree = html_gdt_tree ("See `{section}'",
+                                    self->document, self, substrings, 0, 0);
+            }
+          else /* @ref */
+            {
+              tree = html_gdt_tree ("`{section}'",
+                                    self->document, self, substrings, 0, 0);
             }
-          free (text);
-          free (href);
-          free (accesskey);
         }
-      text_append_n (result, "</ul>\n", 6);
+      free (reference);
+      free (book_reference);
+      destroy_named_string_element_list (substrings);
     }
-}
-
-void
-convert_heading_command (CONVERTER *self, const enum command_id cmd,
-                    const ELEMENT *element,
-                    const HTML_ARGS_FORMATTED *args_formatted,
-                    const char *content, TEXT *result)
-{
-  char *element_id;
-  OUTPUT_UNIT *output_unit = 0;
-  TEXT element_header;
-  /* could use only one, but this is more similar to perl code */
-  TEXT tables_of_contents;
-  TEXT mini_toc_or_auto_menu;
-  enum command_id level_corrected_cmd;
-  int status;
-  char *heading;
-  int heading_level = -1;
-  int do_heading;
-  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 (tree)
     {
-      if (element->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;
+      char *context_str;
+      xasprintf (&context_str, "convert xref %s", builtin_command_name (cmd));
+      add_to_element_list (&self->tree_to_build, tree);
+      convert_to_html_internal (self, tree, result, context_str);
+      remove_element_from_list (&self->tree_to_build, tree);
+      free (context_str);
+      /* should destroy reference_element and book_element */
+      destroy_element_and_children (tree);
     }
 
-  element_id = html_command_id (self, element);
-
-  if (self->conf->DEBUG > 0)
-    fprintf (stderr, "CONVERT elt heading %s\n",
-                     root_heading_command_to_texinfo (element));
-
-  if (flags & CF_root && element->associated_unit)
-    output_unit = element->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);
+  free (file);
+  free (name);
+}
 
-  text_init (&tables_of_contents);
-  text_append (&tables_of_contents, "");
-  if (element->cmd == CM_top
-      && !strcmp (self->conf->CONTENTS_OUTPUT_LOCATION, "after_top")
-      && self->document->sections_list
-      && self->document->sections_list->number > 1)
+void
+contents_shortcontents_in_title (CONVERTER *self, TEXT *result)
+{
+  if (self->document->sections_list
+      && self->document->sections_list->number > 0
+      && !strcmp (self->conf->CONTENTS_OUTPUT_LOCATION, "after_title"))
     {
       enum command_id contents_cmds[2] = {CM_shortcontents, CM_contents};
       int i;
@@ -10304,347 +10361,290 @@ convert_heading_command (CONVERTER *self, const 
enum command_id cmd,
                 = contents_inline_element (self, cmd, 0);
               if (contents_text)
                 {
-                  text_append (&tables_of_contents, contents_text);
+                  text_append (result, contents_text);
+                  text_append (result, self->conf->DEFAULT_RULE);
+                  text_append_n (result, "\n", 1);
                   free (contents_text);
                 }
             }
         }
     }
+}
 
-  text_init (&mini_toc_or_auto_menu);
-  text_append (&mini_toc_or_auto_menu, "");
-  if (tables_of_contents.end <= 0
-      && (flags & CF_sectioning_heading))
-    {
-      if (!strcmp (self->conf->FORMAT_MENU, "sectiontoc"))
-        {
-          mini_toc_internal (self, element, &mini_toc_or_auto_menu);
-        }
-      else if (!strcmp (self->conf->FORMAT_MENU, "menu"))
-        {
-          ELEMENT *node
-            = lookup_extra_element (element, "associated_node");
-          if (node)
-            {
-              int automatic_directions = (node->args.number <= 1);
-              ELEMENT_LIST *menus = lookup_extra_contents (node, "menus", 0);
-              if (!menus && automatic_directions)
-                {
-                  ELEMENT *menu_node
-                   = new_complete_menu_master_menu (self->conf,
-                             self->document->identifiers_target, node);
+static void
+format_simpletitle (CONVERTER *self, TEXT *result)
+{
+  char *title_text;
+  char *context_str;
+  STRING_LIST *classes;
+  enum command_id cmd = self->simpletitle_cmd;
+  classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+  memset (classes, 0, sizeof (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);
+}
 
-                  if (menu_node)
-                    {
-                      add_to_element_list (&self->tree_to_build, menu_node);
-                      convert_to_html_internal (self, menu_node,
-                                                &mini_toc_or_auto_menu, 0);
-                      remove_element_from_list (&self->tree_to_build,
-                                                menu_node);
-                      /* there are only new or copied elements in the menu */
-                      destroy_element_and_children (menu_node);
-                    }
-                }
-            }
-        }
+/* 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->contents = self->document->global_commands->titlepage->contents;
+      convert_to_html_internal (self, tmp, &result, "convert titlepage");
+      tmp->contents.list = 0;
+      destroy_element (tmp);
+      titlepage_text = 1;
     }
-
-  if (self->conf->NO_TOP_NODE_OUTPUT > 0
-      && builtin_command_data[cmd].flags & CF_root)
+  else if (self->simpletitle_tree)
     {
-      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)
-        {
-          ELEMENT *part_following_node
-            = lookup_extra_element (element, "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)
-            {
-              char *normalized = lookup_extra_string (node_element,
-                                                      "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,
-                                  builtin_command_name(cmd), result);
-          text_append (result, element_header.text);
-          free (element_header.text);
-          text_append (result, tables_of_contents.text);
-          free (tables_of_contents.text);
-          text_append (result, mini_toc_or_auto_menu.text);
-          free (mini_toc_or_auto_menu.text);
-          return;
-        }
+      format_simpletitle (self, &result);
+      titlepage_text = 1;
     }
-
-  lookup_extra_integer (element, "section_level", &status);
-  level_corrected_cmd = cmd;
-  if (status >= 0)
+  if (titlepage_text)
     {
-      /* 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));
-        }
+      text_append (&result, self->conf->DEFAULT_RULE);
+      text_append_n (&result, "\n", 1);
     }
+  contents_shortcontents_in_title (self, &result);
+  return result.text;
+}
 
- /* find the section starting here, can be through the associated node
-    preceding the section, or the section itself */
-
-  if (cmd == CM_node)
+char *
+format_titlepage (CONVERTER *self)
+{
+  FORMATTING_REFERENCE *formatting_reference
+   = &self->current_formatting_references[FR_format_titlepage];
+  if (formatting_reference->status == FRS_status_default_set)
     {
-      opening_section
-       = lookup_extra_element (element, "associated_section");
-      if (opening_section)
-        level_corrected_opening_section_cmd
-          = section_level_adjusted_command_name (opening_section);
+      return html_default_format_titlepage (self);
     }
   else
     {
-      ELEMENT *associated_node
-        = lookup_extra_element (element, "associated_node");
+      return call_formatting_function_format_titlepage (self,
+                                               formatting_reference);
+    }
+}
 
-       /* 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))
+char *
+html_default_format_title_titlepage (CONVERTER *self)
+{
+  if (self->conf->SHOW_TITLE > 0)
+    {
+      if (self->conf->USE_TITLEPAGE_FOR_TITLE)
         {
-          opening_section = element;
-          level_corrected_opening_section_cmd = level_corrected_cmd;
+          return format_titlepage (self);
         }
-    }
-
-  /*
-   could use empty args information also, to avoid calling command_text
-   my $empty_heading = (!scalar(@$args) or !defined($args->[0]));
-   */
+      else
+        {
+          TEXT result;
+          text_init (&result);
+          text_append (&result, "");
 
+          if (self->simpletitle_tree)
+            format_simpletitle (self, &result);
 
- /* 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);
+          contents_shortcontents_in_title (self, &result);
+          return result.text;
+        }
+    }
+  return strdup ("");
+}
 
-  if (cmd == CM_node)
+char *
+format_title_titlepage (CONVERTER *self)
+{
+  FORMATTING_REFERENCE *formatting_reference
+   = &self->current_formatting_references[FR_format_title_titlepage];
+  if (formatting_reference->status == FRS_status_default_set)
     {
-      ELEMENT *associated_section
-        = lookup_extra_element (element, "associated_section");
-      char *normalized = lookup_extra_string (element, "normalized");
-      if ((!output_unit
-           || (output_unit->unit_command
-               && output_unit->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 > 0)
-                {
-                  ELEMENT *next_heading
-                    = find_root_command_next_heading_command (element,
-                                                        self->expanded_formats,
-                    (!strcmp (self->conf->CONTENTS_OUTPUT_LOCATION, "inline")),
-                            0);
-                  if (next_heading)
-                    use_next_heading = 1;
-                }
-              if (!use_next_heading)
-                /* use node */
-                heading_level = 3;
-            }
-        }
+      return html_default_format_title_titlepage (self);
     }
   else
     {
-      int status;
-      int level = lookup_extra_integer (element, "section_level", &status);
-      if (status >= 0)
-        {
-          heading_level = level;
-        }
-      else
-        {
-          heading_level = section_level (element);
-        }
+      return call_formatting_function_format_title_titlepage (self,
+                                                      formatting_reference);
     }
-  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, "section_level", &status);
-      STRING_LIST *closed_strings;
+/* NOTE these switches are not done in perl, so the only perl functions
+   that can be callled 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, char 
*explanation)
+{
+  char *result;
+  HTML_DOCUMENT_CONTEXT *top_document_ctx;
 
-      closed_strings = html_close_registered_sections_level (self, level);
+  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;
 
-      if (closed_strings->number)
-        {
-          int 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);
+  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;
 
-      html_register_opened_section_level (self, level, "</div>\n");
+  html_new_document_context (self, "css_string", 0, 0);
+  top_document_ctx = html_top_document_context (self);
+  top_document_ctx->string_ctx++;
 
-    /* use a specific class name to mark that this is the start of
-       the section extent. It is not necessary where the section is. */
+  result = html_convert_tree (self, element, explanation);
 
-      classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
-      memset (classes, 0, sizeof (STRING_LIST));
+  html_pop_document_context (self);
 
-      xasprintf (&class, "%s-level-extent",
-                 builtin_command_name (level_corrected_opening_section_cmd));
+  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;
 
-      add_string (class, classes);
-      free (class);
-      attribute_class = html_attribute_class (self, "div", classes);
-      destroy_strings_list (classes);
+  return result;
+}
 
-      text_append (result, attribute_class);
-      free (attribute_class);
+typedef struct SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD {
+    enum command_id cmd;
+    char *string;
+    char *saved;
+} SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD;
 
-      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. */
+static SPECIAL_LIST_MARK_CSS_NO_ARGS_CMD
+            special_list_mark_css_string_no_arg_command[] = {
+ {CM_minus, "\\2212 ", 0},
+ {0, 0, 0},
+};
 
-         char *id_class = 0;
-         if (do_heading)
-           {
-             xasprintf (&id_class, "%s-id", builtin_command_name (cmd));
-           }
-         else
-           id_class = strdup (builtin_command_name (cmd));
+char *
+html_convert_css_string_for_list_mark (CONVERTER *self, const ELEMENT *element,
+                                       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_command_conversion[cmd][HCC_type_css_string].text;
+      self->html_command_conversion[cmd][HCC_type_css_string].text
+        = special_list_mark_css_string_no_arg_command[i].string;
+    }
 
-         format_separate_anchor (self, element_id, id_class, result);
+  result = html_convert_css_string (self, element, explanation);
 
-         free (id_class);
-       }
-     else
-       heading_id = element_id;
-   }
+  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_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;
+    }
 
-  text_append (result, element_header.text);
-  free (element_header.text);
+  return result;
+}
 
-  if (do_heading)
+void
+convert_itemize_command (CONVERTER *self, const enum command_id cmd,
+                    const ELEMENT *element,
+                    const HTML_ARGS_FORMATTED *args_formatted,
+                    const char *content, TEXT *result)
+{
+  ELEMENT *command_as_argument;
+  const char *command_as_argument_name = 0;
+  const char *mark_class_name = 0;
+  STRING_LIST *classes;
+  char *attribute_class;
+  CSS_SELECTOR_STYLE *selector_style = 0;
+
+  if (html_in_string (self))
     {
-      STRING_LIST *heading_classes;
-      if (self->conf->TOC_LINKS > 0
-          && (builtin_command_data[cmd].flags & CF_root)
-          && (builtin_command_data[cmd].flags & CF_sectioning_heading))
+      if (content)
+        text_append (result, content);
+      return;
+    }
+
+  command_as_argument = lookup_extra_element (element, "command_as_argument");
+  if (command_as_argument)
+    {
+      if (command_as_argument->cmd == CM_click)
         {
-          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);
-            }
+          command_as_argument_name = lookup_extra_string (command_as_argument,
+                                                          "clickstyle");
         }
+      if (!command_as_argument_name)
+        command_as_argument_name = element_command_name (command_as_argument);
 
-      heading_classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
-      memset (heading_classes, 0, sizeof (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 ("");
+      if (!strcmp (command_as_argument_name, "w"))
+        mark_class_name = "none";
+      else
+        mark_class_name = command_as_argument_name;
+    }
 
-          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);
+  classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+  memset (classes, 0, sizeof (STRING_LIST));
+  add_string (builtin_command_name(cmd), classes);
 
-          free (id_str);
-        }
-      else
+  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)
         {
-          format_heading_text (self, level_corrected_cmd,
-                    heading_classes, heading,
-                    heading_level + self->conf->CHAPTER_HEADER_LEVEL -1,
-                    heading_id, element, element_id, result);
+          add_string (mark_class, classes);
         }
-      destroy_strings_list (heading_classes);
+      free (mark_class);
     }
-  else if (heading_id)
+
+  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 <= 0)
     {
-   /* 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);
+      char *css_string
+        = html_convert_css_string_for_list_mark (self, element->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);
     }
 
-  free (heading);
-  free (level_set_class);
-
+  text_append_n (result, ">\n", 2);
   if (content)
     text_append (result, content);
-
-  text_append (result, tables_of_contents.text);
-  free (tables_of_contents.text);
-  text_append (result, mini_toc_or_auto_menu.text);
-  free (mini_toc_or_auto_menu.text);
+  text_append_n (result, "</ul>\n", 6);
 }
 
 void



reply via email to

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