texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: * doc/texi2any_api.texi (Shared Conversion State


From: Patrice Dumas
Subject: branch master updated: * doc/texi2any_api.texi (Shared Conversion State in Default Formatting), tta/perl/Texinfo/Convert/HTML.pm (command_description) (_formatted_nodedescription_nr, _convert_menu_entry_type), tta/perl/XSTexinfo/convert/get_html_perl_info.c (find_node_target_info_nodedescription_sv): use the node element and not the nodedescription element to select the node description for the nodedescription shared conversion state, since it is easier to find the C tree node from XS based on the node Perl tree [...]
Date: Fri, 23 May 2025 02:05:13 -0400

This is an automated email from the git hooks/post-receive script.

pertusus pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new 94f47a38dd * doc/texi2any_api.texi (Shared Conversion State in Default 
Formatting), tta/perl/Texinfo/Convert/HTML.pm (command_description) 
(_formatted_nodedescription_nr, _convert_menu_entry_type), 
tta/perl/XSTexinfo/convert/get_html_perl_info.c 
(find_node_target_info_nodedescription_sv): use the node element and not the 
nodedescription element to select the node description for the nodedescription 
shared conversion state, since it is easier to find the C tree node from XS 
based  [...]
94f47a38dd is described below

commit 94f47a38dd0d68f6e939468c9e4504ef829ff37c
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Fri May 23 08:05:16 2025 +0200

    * doc/texi2any_api.texi (Shared Conversion State in Default
    Formatting), tta/perl/Texinfo/Convert/HTML.pm (command_description)
    (_formatted_nodedescription_nr, _convert_menu_entry_type),
    tta/perl/XSTexinfo/convert/get_html_perl_info.c
    (find_node_target_info_nodedescription_sv): use the node element and
    not the nodedescription element to select the node description for the
    nodedescription shared conversion state, since it is easier to find
    the C tree node from XS based on the node Perl tree element than based
    on the nodedescription Perl tree element.
    
    * tta/C/main/build_perl_info.c (store_document_texinfo_tree)
    (store_document_tree_output_units): move building section, nodes and
    heading lists to store_document_texinfo_tree to make sure that they
    are rebuilt if needed in more cases.
    
    * tta/C/main/build_perl_info.c (output_unit_to_perl_hash),
    tta/C/main/document_types.h (OUTPUT_UNIT), tta/C/main/output_unit.c
    (split_by_node, split_by_section), tta/perl/Texinfo/Common.pm
    (debug_print_output_unit), tta/perl/Texinfo/OutputUnits.pm
    (split_by_node, split_by_section): add unit_node and unit_section
    information to output unit, to hae a direct access to associated node
    and section information.
    
    * tta/C/convert/format_html.c (from_element_direction)
    (html_default_format_begin_file, html_convert_heading_command),
    tta/C/convert/html_prepare_converter.c (html_set_pages_files),
    tta/C/main/output_unit.c (split_pages, units_directions),
    tta/perl/Texinfo/Convert/Converter.pm (set_output_units_files)
    (sort_element_counts), tta/perl/Texinfo/Convert/HTML.pm
    (from_element_direction, _convert_heading_command)
    (_html_set_pages_files, _default_format_begin_file),
    tta/perl/Texinfo/Convert/IXIN.pm, tta/perl/Texinfo/OutputUnits.pm
    (split_pages, units_directions), tta/perl/init/book.pm
    (book_format_navigation_header, book_convert_heading_command)
    (book_unit_file_name): use output unit unit_node and unit_section
    instead of unit_command when relevant.  Remove _output_unit_node and
    _output_unit_section functions.
    
    * tta/perl/Texinfo/Convert/Plaintext.pm (process_footnotes): rename
    $element as $output_unit.
---
 ChangeLog                                       |  43 ++++++
 doc/texi2any_api.texi                           |   6 +-
 tta/C/convert/format_html.c                     |  68 ++-------
 tta/C/convert/html_prepare_converter.c          |  11 +-
 tta/C/main/build_perl_info.c                    | 106 +++++++-------
 tta/C/main/document_types.h                     |   7 +
 tta/C/main/output_unit.c                        | 182 +++++++++---------------
 tta/perl/Texinfo/Common.pm                      |  26 +++-
 tta/perl/Texinfo/Convert/Converter.pm           |  17 ++-
 tta/perl/Texinfo/Convert/HTML.pm                |  84 +++--------
 tta/perl/Texinfo/Convert/IXIN.pm                |  14 +-
 tta/perl/Texinfo/Convert/Plaintext.pm           |  10 +-
 tta/perl/Texinfo/ManipulateTree.pm              |   5 +
 tta/perl/Texinfo/OutputUnits.pm                 | 150 +++++++++----------
 tta/perl/XSTexinfo/convert/get_html_perl_info.c |  25 +---
 tta/perl/init/book.pm                           |  29 ++--
 16 files changed, 348 insertions(+), 435 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dac5f2f947..4b453d8184 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+2025-05-23  Patrice Dumas  <pertusus@free.fr>
+
+       * doc/texi2any_api.texi (Shared Conversion State in Default
+       Formatting), tta/perl/Texinfo/Convert/HTML.pm (command_description)
+       (_formatted_nodedescription_nr, _convert_menu_entry_type),
+       tta/perl/XSTexinfo/convert/get_html_perl_info.c
+       (find_node_target_info_nodedescription_sv): use the node element and
+       not the nodedescription element to select the node description for the
+       nodedescription shared conversion state, since it is easier to find
+       the C tree node from XS based on the node Perl tree element than based
+       on the nodedescription Perl tree element.
+
+       * tta/C/main/build_perl_info.c (store_document_texinfo_tree)
+       (store_document_tree_output_units): move building section, nodes and
+       heading lists to store_document_texinfo_tree to make sure that they
+       are rebuilt if needed in more cases.
+
+       * tta/C/main/build_perl_info.c (output_unit_to_perl_hash),
+       tta/C/main/document_types.h (OUTPUT_UNIT), tta/C/main/output_unit.c
+       (split_by_node, split_by_section), tta/perl/Texinfo/Common.pm
+       (debug_print_output_unit), tta/perl/Texinfo/OutputUnits.pm
+       (split_by_node, split_by_section): add unit_node and unit_section
+       information to output unit, to hae a direct access to associated node
+       and section information.
+
+       * tta/C/convert/format_html.c (from_element_direction)
+       (html_default_format_begin_file, html_convert_heading_command),
+       tta/C/convert/html_prepare_converter.c (html_set_pages_files),
+       tta/C/main/output_unit.c (split_pages, units_directions),
+       tta/perl/Texinfo/Convert/Converter.pm (set_output_units_files)
+       (sort_element_counts), tta/perl/Texinfo/Convert/HTML.pm
+       (from_element_direction, _convert_heading_command)
+       (_html_set_pages_files, _default_format_begin_file),
+       tta/perl/Texinfo/Convert/IXIN.pm, tta/perl/Texinfo/OutputUnits.pm
+       (split_pages, units_directions), tta/perl/init/book.pm
+       (book_format_navigation_header, book_convert_heading_command)
+       (book_unit_file_name): use output unit unit_node and unit_section
+       instead of unit_command when relevant.  Remove _output_unit_node and
+       _output_unit_section functions.
+
+       * tta/perl/Texinfo/Convert/Plaintext.pm (process_footnotes): rename
+       $element as $output_unit.
+
 2025-05-22  Patrice Dumas  <pertusus@free.fr>
 
        * tta/perl/Makefile.tres, tta/perl/t/html_tests.t
diff --git a/doc/texi2any_api.texi b/doc/texi2any_api.texi
index 1f83d6e606..2f222fec65 100644
--- a/doc/texi2any_api.texi
+++ b/doc/texi2any_api.texi
@@ -3910,7 +3910,7 @@ default formatting functions:
 @item @code{menu} @tab @code{html_menu_entry_index} @tab @tab integer
 @item @code{printindex} @tab @code{formatted_index_entries} @tab index_entry 
(index entry hash) @tab integer
 @item @code{top} @tab @code{in_skipped_node_top} @tab @tab integer
-@item @code{nodedescription} @tab @code{formatted_nodedescriptions} @tab 
element (@code{@@nodedescription} tree element) @tab integer
+@item @code{nodedescription} @tab @code{formatted_nodedescriptions} @tab 
element (@code{@@node} tree element) @tab integer
 @end multitable
 
 These shared information data correspond to:
@@ -3936,8 +3936,8 @@ Associate an index entry to the number of time it was 
formatted.
 Set to 1 in a @code{Top} node being skipped, in case
 @code{NO_TOP_NODE_OUTPUT} is set.
 @item formatted_nodedescriptions
-Associate a @code{@@nodedescription} tree element to the number of time
-it was formatted.
+Associate a @code{@@node} tree element to the number of time
+its description was formatted.
 @end vtable
 
 
diff --git a/tta/C/convert/format_html.c b/tta/C/convert/format_html.c
index e09f2632a3..ff2acdc3f0 100644
--- a/tta/C/convert/format_html.c
+++ b/tta/C/convert/format_html.c
@@ -2487,46 +2487,16 @@ from_element_direction (CONVERTER *self, int direction,
         }
       else if (type == HTT_node)
         {
-          if (target_unit->unit_type == OU_unit && 
target_unit->uc.unit_command)
-            {
-              const ELEMENT *target_command = target_unit->uc.unit_command;
-              if (target_command->e.c->cmd == CM_node)
-                command = target_command;
-              else if (self->document)
-                {
-                  int status;
-                  size_t section_number
-                    = lookup_extra_integer (target_command,
-                                         AI_key_section_number, &status);
-                  const SECTION_STRUCTURE *section_structure
-                    = self->document->sections_list.list[section_number -1];
+          if (target_unit->unit_node)
+            command = target_unit->unit_node->element;
 
-                  if (section_structure->associated_node)
-                    command = section_structure->associated_node->element;
-                }
-            }
           type = HTT_text;
         }
       else if (type == HTT_section || type == HTT_section_nonumber)
         {
-          if (target_unit->unit_type == OU_unit && 
target_unit->uc.unit_command)
-            {
-              const ELEMENT *target_command = target_unit->uc.unit_command;
-              if (target_command->e.c->cmd != CM_node)
-                command = target_command;
-              else if (self->document)
-                {
-                  int status;
-                  size_t node_number
-                    = lookup_extra_integer (target_command,
-                                         AI_key_node_number, &status);
-                  const NODE_STRUCTURE *node_structure
-                    = self->document->nodes_list.list[node_number -1];
+          if (target_unit->unit_section)
+            command = target_unit->unit_section->element;
 
-                  if (node_structure->associated_section)
-                    command = node_structure->associated_section->element;
-                }
-            }
           if (type == HTT_section_nonumber)
             type = HTT_text_nonumber;
           else
@@ -4302,7 +4272,6 @@ char *
 html_default_format_begin_file (CONVERTER *self, const char *filename,
                                 const OUTPUT_UNIT *output_unit)
 {
-  const ELEMENT *element_command = 0;
   const ELEMENT *node_command = 0;
   const ELEMENT *command_for_title = 0;
   BEGIN_FILE_INFORMATION *begin_info;
@@ -4312,26 +4281,15 @@ html_default_format_begin_file (CONVERTER *self, const 
char *filename,
 
   if (output_unit)
     {
+      const ELEMENT *element_command = 0;
+
+      if (output_unit->unit_node)
+        node_command = output_unit->unit_node->element;
+
       if (output_unit->unit_type == OU_special_unit)
         element_command = output_unit->uc.special_unit_command;
       else
         element_command = output_unit->uc.unit_command;
-      if (element_command && element_command->e.c->cmd != CM_node
-          && builtin_command_data[element_command->e.c->cmd].flags & CF_root
-          && self->document)
-        {
-          int status;
-          size_t section_number
-            = lookup_extra_integer (element_command,
-                                    AI_key_section_number, &status);
-
-          const SECTION_STRUCTURE *section_structure
-            = self->document->sections_list.list[section_number -1];
-          if (section_structure->associated_node)
-            node_command = section_structure->associated_node->element;
-        }
-      if (!node_command)
-        node_command = element_command;
 
       if (self->conf->SPLIT.o.string && strlen (self->conf->SPLIT.o.string)
           && element_command)
@@ -7596,11 +7554,9 @@ html_convert_heading_command (CONVERTER *self, const 
enum command_id cmd,
                 = node_structure->associated_title_command;
             }
         }
-      /* NOTE: if USE_NODES = 0 and there are no sectioning commands,
-         output_unit->uc.unit_command is NUL (and not equal to element). */
-      if (output_unit->uc.unit_command == element
-          && !associated_title_command
-          && normalized)
+      if (output_unit && output_unit->unit_node
+          && output_unit->unit_node->element == element
+          && !associated_title_command)
         {
           if (!strcmp (normalized, "Top"))
             heading_level = 0;
diff --git a/tta/C/convert/html_prepare_converter.c 
b/tta/C/convert/html_prepare_converter.c
index 64c4589f28..d4fa371ac9 100644
--- a/tta/C/convert/html_prepare_converter.c
+++ b/tta/C/convert/html_prepare_converter.c
@@ -5552,10 +5552,11 @@ html_set_pages_files (CONVERTER *self, const 
OUTPUT_UNIT_LIST *output_units,
               if (!node_filename)
                 {
                   /* use section to do the file name if there is no node */
-                  const ELEMENT *command = file_output_unit->uc.unit_command;
+                  const SECTION_STRUCTURE *command
+                    = file_output_unit->unit_section;
                   if (command)
                     {
-                      if (command->e.c->cmd == CM_top && !node_top
+                      if (command->element->e.c->cmd == CM_top && !node_top
                           && top_node_filename_str)
                         {
                    /* existing top_node_filename can happen, see
@@ -5584,7 +5585,7 @@ html_set_pages_files (CONVERTER *self, const 
OUTPUT_UNIT_LIST *output_units,
                       else
                         {
                           const HTML_TARGET *section_target
-                            = html_get_target (self, command);
+                            = html_get_target (self, command->element);
                           const char *section_filename
                             = section_target->section_filename;
 
@@ -5598,13 +5599,13 @@ html_set_pages_files (CONVERTER *self, const 
OUTPUT_UNIT_LIST *output_units,
                                 {/* NOTE we keep the order, as in perl */
                                   html_set_file_source_info (file_source_info,
                                                             "section",
-                                                            0, command, 0);
+                                                     0, command->element, 0);
                                 }
                             }
                           else
                             html_add_to_files_source_info (files_source_info,
                                                  section_filename, "section", 
0,
-                                                 command, 0);
+                                                 command->element, 0);
                           output_unit_file_name
                             = add_to_unit_file_name_paths 
(unit_file_name_paths,
                                                            section_filename,
diff --git a/tta/C/main/build_perl_info.c b/tta/C/main/build_perl_info.c
index dd51d10040..e8d741ab86 100644
--- a/tta/C/main/build_perl_info.c
+++ b/tta/C/main/build_perl_info.c
@@ -2160,6 +2160,54 @@ store_document_texinfo_tree (DOCUMENT *document)
       hv_store (document->hv, key, strlen (key), result_sv, 0);
       document->modified_information &= ~F_DOCM_tree;
     }
+  /* systematically rebuild, as section structure information
+     can be accessed from the tree.  Done in this function,
+     as it is supposed to be called before an access to modified
+     tree and sectioning structure.
+   */
+  /* Also store, such that next call that get cached values
+     get the right structure */
+  if (document->modified_information & F_DOCM_sections_list)
+    {
+      const char *key = "sections_list";
+      AV *av_list
+        = build_section_structure_list (&document->sections_list);
+      hv_store (document->hv, key, strlen (key),
+                newRV_inc ((SV *) av_list), 0);
+
+      document->modified_information &= ~F_DOCM_sections_list;
+    }
+
+  if (document->modified_information & F_DOCM_nodes_list)
+    {
+      const char *key = "nodes_list";
+      AV *av_list
+        = build_node_structure_list (&document->nodes_list);
+      hv_store (document->hv, key, strlen (key),
+                newRV_inc ((SV *) av_list), 0);
+
+      document->modified_information &= ~F_DOCM_nodes_list;
+    }
+
+  if (document->modified_information & F_DOCM_headings_list)
+    {
+      const char *key = "headings_list";
+      AV *av_list
+        = build_heading_structure_list (&document->headings_list);
+      hv_store (document->hv, key, strlen (key),
+                newRV_inc ((SV *) av_list), 0);
+
+      document->modified_information &= ~F_DOCM_headings_list;
+    }
+
+  /*
+  if (document->sectioning_root
+      && document->modified_information & F_DOCM_sectioning_root)
+    {
+      build_sectioning_root (document->sectioning_root);
+      document->modified_information &= ~F_DOCM_sectioning_root;
+    }
+   */
   return result_sv;
 }
 
@@ -2225,6 +2273,16 @@ output_unit_to_perl_hash (OUTPUT_UNIT *output_unit)
           sv = newRV_inc ((SV *) command->hv);
           STORE("unit_command");
         }
+      if (output_unit->unit_section)
+        {
+          sv = newRV_inc ((SV *) output_unit->unit_section->hv);
+          STORE("unit_section");
+        }
+      if (output_unit->unit_node)
+        {
+          sv = newRV_inc ((SV *) output_unit->unit_node->hv);
+          STORE("unit_node");
+        }
    /* there is nothing else of use for external_node_unit, exit now */
       if (output_unit->unit_type == OU_external_node_unit)
         return;
@@ -2477,54 +2535,6 @@ store_document_tree_output_units (DOCUMENT *document)
       if (document->tree)
         result_sv = store_document_texinfo_tree (document);
 
-      /* systematically rebuild, as section structure information
-         can be accessed from the tree.  Done in this function,
-         as it is supposed to be called before an access to modified
-         tree and sectioning structure.
-       */
-      /* Also store, such that next call that get cached values
-         get the right structure */
-      if (document->modified_information & F_DOCM_sections_list)
-        {
-          const char *key = "sections_list";
-          AV *av_list
-            = build_section_structure_list (&document->sections_list);
-          hv_store (document->hv, key, strlen (key),
-                    newRV_inc ((SV *) av_list), 0);
-
-          document->modified_information &= ~F_DOCM_sections_list;
-        }
-
-      if (document->modified_information & F_DOCM_nodes_list)
-        {
-          const char *key = "nodes_list";
-          AV *av_list
-            = build_node_structure_list (&document->nodes_list);
-          hv_store (document->hv, key, strlen (key),
-                    newRV_inc ((SV *) av_list), 0);
-
-          document->modified_information &= ~F_DOCM_nodes_list;
-        }
-
-      if (document->modified_information & F_DOCM_headings_list)
-        {
-          const char *key = "headings_list";
-          AV *av_list
-            = build_heading_structure_list (&document->headings_list);
-          hv_store (document->hv, key, strlen (key),
-                    newRV_inc ((SV *) av_list), 0);
-
-          document->modified_information &= ~F_DOCM_headings_list;
-        }
-
-      /*
-      if (document->sectioning_root
-          && document->modified_information & F_DOCM_sectioning_root)
-        {
-          build_sectioning_root (document->sectioning_root);
-          document->modified_information &= ~F_DOCM_sectioning_root;
-        }
-       */
       /* we hope that there are not two output units lists referring to the
          tree... */
       if (document->modified_information & F_DOCM_output_units)
diff --git a/tta/C/main/document_types.h b/tta/C/main/document_types.h
index d3469f8c4b..33a5dc2928 100644
--- a/tta/C/main/document_types.h
+++ b/tta/C/main/document_types.h
@@ -228,11 +228,18 @@ typedef struct OUTPUT_UNIT {
 
     enum output_unit_type unit_type;
     size_t index;
+    /* for regular unit we have both access to the unit command,
+       which may be the node or section tree element, and to
+       unit_node and/or unit_section structure information which allow
+       to access directly the associated node and associated section
+       information without going through the unit command */
     union {
       const struct ELEMENT *unit_command;
       /* for special units, not in the tree */
       struct ELEMENT *special_unit_command;
     } uc;
+    const NODE_STRUCTURE *unit_node;
+    const SECTION_STRUCTURE *unit_section;
     char *unit_filename;
     ELEMENT_LIST unit_contents;
     struct OUTPUT_UNIT *tree_unit_directions[2];
diff --git a/tta/C/main/output_unit.c b/tta/C/main/output_unit.c
index 5f08265ad6..abbd168ae9 100644
--- a/tta/C/main/output_unit.c
+++ b/tta/C/main/output_unit.c
@@ -174,8 +174,17 @@ split_by_node (DOCUMENT *document)
         {
           const char *normalized
             = lookup_extra_string (content, AI_key_normalized);
+
           if (normalized)
             {
+              int status;
+              size_t node_number
+                = lookup_extra_integer (content,
+                                        AI_key_node_number, &status);
+
+              const NODE_STRUCTURE *node_structure
+                = document->nodes_list.list[node_number -1];
+
               if (!current->uc.unit_command)
                 current->uc.unit_command = content;
               else
@@ -188,6 +197,9 @@ split_by_node (DOCUMENT *document)
                   last->tree_unit_directions[D_next] = current;
                   add_to_output_unit_list (output_units, current);
                 }
+              current->unit_node = node_structure;
+              if (node_structure->associated_section)
+                current->unit_section = node_structure->associated_section;
             }
         }
       if (pending_parts->number > 0)
@@ -240,56 +252,65 @@ split_by_section (DOCUMENT *document)
 
   for (i = 0; i < root->e.c->contents.number; i++)
     {
+      int status;
+
       ELEMENT *content = root->e.c->contents.list[i];
       enum command_id data_cmd = element_builtin_data_cmd (content);
       unsigned long flags = builtin_command_data[data_cmd].flags;
+      const NODE_STRUCTURE *node_structure = 0;
+      const SECTION_STRUCTURE *new_section_structure = 0;
 
-      const ELEMENT *new_section = 0;
       if (data_cmd == CM_node)
         {
-          int status;
           size_t node_number
                 = lookup_extra_integer (content,
                                         AI_key_node_number, &status);
           if (node_number)
             {
-              const NODE_STRUCTURE *node_structure
+              node_structure
                 = document->nodes_list.list[node_number -1];
 
               if (node_structure->associated_section)
-                new_section = node_structure->associated_section->element;
+                new_section_structure = node_structure->associated_section;
             }
         }
-      else
+      else if (flags & CF_root)
         {
+          size_t section_number
+            = lookup_extra_integer (content,
+                                    AI_key_section_number, &status);
+          const SECTION_STRUCTURE *section_structure
+            = document->sections_list.list[section_number -1];
+
           if (data_cmd == CM_part)
             {
-              int status;
-              size_t section_number
-                = lookup_extra_integer (content,
-                                        AI_key_section_number, &status);
-              const SECTION_STRUCTURE *part_structure
-                = document->sections_list.list[section_number -1];
-              if (part_structure->part_associated_section)
-                new_section
-                  = part_structure->part_associated_section->element;
-            }
-          if (!new_section && (CF_root & flags))
-            {
-              new_section = content;
+              if (section_structure->part_associated_section)
+                new_section_structure
+                  = section_structure->part_associated_section;
             }
+          if (!new_section_structure)
+            new_section_structure = section_structure;
+
+          if (new_section_structure->associated_node)
+            node_structure = new_section_structure->associated_node;
         }
-      if (new_section)
+      if (new_section_structure)
         {
           if (!current->uc.unit_command)
             {
-              current->uc.unit_command = new_section;
+              current->uc.unit_command = new_section_structure->element;
+              current->unit_section = new_section_structure;
+              if (node_structure)
+                current->unit_node = node_structure;
             }
-          else if (new_section != current->uc.unit_command)
+          else if (new_section_structure != current->unit_section)
             {
               OUTPUT_UNIT *last = output_units->list[output_units->number -1];
               current = new_output_unit (OU_unit);
-              current->uc.unit_command = new_section;
+              current->uc.unit_command = new_section_structure->element;
+              current->unit_section = new_section_structure;
+              if (node_structure)
+                current->unit_node = node_structure;
               current->tree_unit_directions[D_prev] = last;
               last->tree_unit_directions[D_next] = current;
               add_to_output_unit_list (output_units, current);
@@ -382,78 +403,6 @@ free_output_units_lists (OUTPUT_UNIT_LISTS 
*output_units_lists)
 }
 
 
-static const ELEMENT *
-output_unit_section (OUTPUT_UNIT *output_unit,
-                     const NODE_STRUCTURE_LIST *nodes_list)
-{
-  const ELEMENT *element;
-
-  if (!output_unit->uc.unit_command)
-    return 0;
-
-  element = output_unit->uc.unit_command;
-  if (element->e.c->cmd == CM_node)
-    {
-      const NODE_STRUCTURE *node_structure;
-      int status;
-      size_t node_number
-                = lookup_extra_integer (element,
-                                        AI_key_node_number, &status);
-
-      if (!node_number)
-        return 0;
-
-      node_structure = nodes_list->list[node_number -1];
-
-      if (node_structure->associated_section)
-        return node_structure->associated_section->element;
-      else
-        return 0;
-    }
-  else
-    return element;
-}
-
-static const ELEMENT *
-output_unit_node (OUTPUT_UNIT *output_unit,
-                  const SECTION_STRUCTURE_LIST *sections_list)
-{
-  const ELEMENT *element;
-
-  if (!output_unit->uc.unit_command)
-    return 0;
-
-  element = output_unit->uc.unit_command;
-
-  if (element->e.c->cmd == CM_node)
-    {
-      const char *normalized
-        = lookup_extra_string (element, AI_key_normalized);
-      if (normalized)
-        return element;
-      else
-        return 0;
-    }
-  else
-   {
-      const SECTION_STRUCTURE *section_structure;
-      int status;
-      size_t section_number
-                = lookup_extra_integer (element,
-                                        AI_key_section_number, &status);
-
-      if (!section_number)
-        return 0;
-
-      section_structure = sections_list->list[section_number -1];
-
-      if (section_structure->associated_node)
-        return section_structure->associated_node->element;
-      else
-        return 0;
-   }
-}
-
 typedef struct LEVEL_SPLIT_STRING {
     int level;
     char *split;
@@ -509,12 +458,12 @@ split_pages (OUTPUT_UNIT_LIST *output_units,
   for (j = 0; j < output_units->number; j++)
     {
       OUTPUT_UNIT *output_unit = output_units->list[j];
-      const ELEMENT *section = output_unit_section (output_unit, nodes_list);
       int level = -3;
-      if (section)
+      if (output_unit->unit_section)
         {
           int status;
-          level = lookup_extra_integer (section, AI_key_section_level, 
&status);
+          level = lookup_extra_integer (output_unit->unit_section->element,
+                                        AI_key_section_level, &status);
           if (status < 0)
             level = -3;
         }
@@ -659,9 +608,7 @@ units_directions (const C_HASHMAP *identifiers_target,
     {
       OUTPUT_UNIT *output_unit = output_units->list[i];
       const OUTPUT_UNIT **directions = output_unit->directions;
-      const ELEMENT *node = output_unit_node (output_unit, sections_list);
       const ELEMENT * const *node_directions;
-      const ELEMENT *section = output_unit_section (output_unit, nodes_list);
 
       directions[RUD_type_This] = output_unit;
       if (output_unit->tree_unit_directions[D_next]
@@ -673,13 +620,10 @@ units_directions (const C_HASHMAP *identifiers_target,
         directions[RUD_type_Back]
           = output_unit->tree_unit_directions[D_prev];
 
-      if (node)
+      if (output_unit->unit_node)
         {
-          int status;
-          size_t node_number
-           = lookup_extra_integer (node, AI_key_node_number, &status);
-          const NODE_STRUCTURE *node_structure
-           = nodes_list->list[node_number -1];
+          const NODE_STRUCTURE *node_structure = output_unit->unit_node;
+          const ELEMENT *node = node_structure->element;
           const ELEMENT *menu_child
            = first_menu_node (node_structure, identifiers_target);
           enum directions d;
@@ -789,7 +733,7 @@ units_directions (const C_HASHMAP *identifiers_target,
               forward_unit->directions[RUD_type_NodeBack] = output_unit;
             }
         }
-      if (!section)
+      if (! output_unit->unit_section)
         {
   /* If there is no associated section, find the previous element section.
      Use the FastForward of this element.
@@ -799,8 +743,7 @@ units_directions (const C_HASHMAP *identifiers_target,
           while (current_unit->tree_unit_directions[D_prev])
             {
               current_unit = current_unit->tree_unit_directions[D_prev];
-              section = output_unit_section (current_unit, nodes_list);
-              if (section)
+              if (current_unit->unit_section)
                 {
                   section_output_unit = current_unit;
                   break;
@@ -808,6 +751,7 @@ units_directions (const C_HASHMAP *identifiers_target,
             }
           if (section_output_unit)
             {
+              const ELEMENT *section = current_unit->unit_section->element;
               int section_level;
               int status;
 
@@ -826,18 +770,22 @@ units_directions (const C_HASHMAP *identifiers_target,
         }
       else
         {
-          const ELEMENT *up = section;
-          const SECTION_STRUCTURE_LIST *up_section_childs;
-          int up_section_level;
           int status;
-          size_t section_number
-                      = lookup_extra_integer (section,
-                                       AI_key_section_number, &status);
-          const SECTION_STRUCTURE *up_structure
-                      = sections_list->list[section_number -1];
+
+          const SECTION_STRUCTURE *section_structure
+            = output_unit->unit_section;
+          const ELEMENT *section = section_structure->element;
+
           enum directions d;
           const SECTION_STRUCTURE * const *section_directions
-                        = up_structure->section_directions;
+                        = section_structure->section_directions;
+
+          const SECTION_STRUCTURE_LIST *up_section_childs;
+          int up_section_level;
+          const SECTION_STRUCTURE *up_structure
+            = section_structure;
+          const ELEMENT *up = section;
+
           if (section_directions)
             {
               for (d = 0; d < directions_length; d++)
diff --git a/tta/perl/Texinfo/Common.pm b/tta/perl/Texinfo/Common.pm
index 30f01f6562..a462acdc2e 100644
--- a/tta/perl/Texinfo/Common.pm
+++ b/tta/perl/Texinfo/Common.pm
@@ -1910,11 +1910,27 @@ sub debug_print_output_unit
   my $type = $current->{'unit_type'};
   # Should never happen
   $type = 'UNDEF' if (!defined($type));
-  my $unit_cmd = '';
-  if ($current->{'unit_command'}) {
-    $unit_cmd = debug_print_element($current->{'unit_command'}, 0)
+  my $node_unit_cmd = '';
+  if ($current->{'unit_node'}) {
+    my $node_element = $current->{'unit_node'}->{'element'};
+    $node_unit_cmd = '{N';
+    if ($node_element eq $current->{'unit_command'}) {
+      $node_unit_cmd .= '*';
+    }
+    $node_unit_cmd .= ':' . debug_print_element($node_element, 0)
     .Texinfo::Convert::Texinfo::root_heading_command_to_texinfo(
-                                       $current->{'unit_command'});
+                                                $node_element).'}';
+  }
+  my $section_unit_cmd = '';
+  if ($current->{'unit_section'}) {
+    my $section_element = $current->{'unit_section'}->{'element'};
+    $section_unit_cmd = '{S';
+    if ($section_element eq $current->{'unit_command'}) {
+      $section_unit_cmd .= '*';
+    }
+    $section_unit_cmd .= ':'.debug_print_element($section_element, 0)
+      .Texinfo::Convert::Texinfo::root_heading_command_to_texinfo(
+                                               $section_element).'}';
   }
   my $fname = '';
   if (defined($current->{'unit_filename'})) {
@@ -1927,7 +1943,7 @@ sub debug_print_output_unit
   my $contents = '';
   $contents = "{C".scalar(@{$current->{'unit_contents'}}).'}'
     if $current->{'unit_contents'};
-  return "{$type}$fname$variety$contents$unit_cmd";
+  return "{$type}$fname$variety$contents$node_unit_cmd$section_unit_cmd";
 }
 
 # format list for debugging messages
diff --git a/tta/perl/Texinfo/Convert/Converter.pm 
b/tta/perl/Texinfo/Convert/Converter.pm
index aeccb0be85..0ef401676a 100644
--- a/tta/perl/Texinfo/Convert/Converter.pm
+++ b/tta/perl/Texinfo/Convert/Converter.pm
@@ -977,15 +977,16 @@ sub set_output_units_files($$$$$$)
         }
         if (!defined($file_output_unit->{'unit_filename'})) {
           # use section to do the file name if there is no node
-          my $command = $file_output_unit->{'unit_command'};
+          my $command = $file_output_unit->{'unit_section'};
           if ($command) {
-            if ($command->{'cmdname'} eq 'top' and !$node_top
+            if ($command->{'element'}->{'cmdname'} eq 'top' and !$node_top
                 and defined($top_node_filename)) {
               $self->set_file_path($top_node_filename, $destination_directory);
               $self->set_output_unit_file($file_output_unit, 
$top_node_filename);
             } else {
               my ($normalized_name, $filename)
-                 = $self->normalized_sectioning_command_filename($command);
+                 = $self->normalized_sectioning_command_filename(
+                                       $command->{'element'});
               $self->set_file_path($filename, $destination_directory);
               $self->set_output_unit_file($file_output_unit, $filename);
             }
@@ -1826,8 +1827,14 @@ sub sort_element_counts($$;$$)
 
   foreach my $output_unit (@$output_units) {
     my $name;
-    if ($output_unit->{'unit_command'}) {
-      my $command = $output_unit->{'unit_command'};
+    my $command_structure;
+    if ($use_sections) {
+      $command_structure = $output_unit->{'unit_section'};
+    } else {
+      $command_structure = $output_unit->{'unit_node'};
+    }
+    if ($command_structure) {
+      my $command = $command_structure->{'element'};
       # arguments_line type element
       my $arguments_line = $command->{'contents'}->[0];
       my $line_arg = $arguments_line->{'contents'}->[0];
diff --git a/tta/perl/Texinfo/Convert/HTML.pm b/tta/perl/Texinfo/Convert/HTML.pm
index ee2fbf4da2..bbeabbfae5 100644
--- a/tta/perl/Texinfo/Convert/HTML.pm
+++ b/tta/perl/Texinfo/Convert/HTML.pm
@@ -1781,7 +1781,7 @@ sub command_description($$;$)
     }
 
     my $formatted_nodedescription_nr
-       = _formatted_nodedescription_nr($self, $node_description);
+       = _formatted_nodedescription_nr($self, $node);
 
     my $cmdname = $command->{'cmdname'};
     my $context_name = "$cmdname description";
@@ -2031,35 +2031,13 @@ sub from_element_direction($$$;$$$)
         return $self->command_text($external_node_element, $type);
       }
     } elsif ($type eq 'node') {
-      if ($target_unit->{'unit_command'}) {
-        if ($target_unit->{'unit_command'}->{'cmdname'}) {
-          if ($target_unit->{'unit_command'}->{'cmdname'} eq 'node') {
-            $command = $target_unit->{'unit_command'};
-          } elsif ($self->{'document'}) {
-            my $section_element = $target_unit->{'unit_command'};
-            my $sections_list = $self->{'document'}->sections_list();
-            my $section_structure
-          = $sections_list->[$section_element->{'extra'}->{'section_number'} 
-1];
-            if ($section_structure->{'associated_node'}) {
-              $command = $section_structure->{'associated_node'}->{'element'};
-            }
-          }
-        }
+      if ($target_unit->{'unit_node'}) {
+        $command = $target_unit->{'unit_node'}->{'element'};
       }
       $type = 'text';
     } elsif ($type eq 'section' or $type eq 'section_nonumber') {
-      if ($target_unit->{'unit_command'}) {
-        if ($target_unit->{'unit_command'}->{'cmdname'} ne 'node') {
-          $command = $target_unit->{'unit_command'};
-        } elsif ($self->{'document'}) {
-          my $node_element = $target_unit->{'unit_command'};
-          my $nodes_list = $self->{'document'}->nodes_list();
-          my $node_structure
-            = $nodes_list->[$node_element->{'extra'}->{'node_number'} -1];
-          if ($node_structure->{'associated_section'}) {
-            $command = $node_structure->{'associated_section'}->{'element'};
-          }
-        }
+      if ($target_unit->{'unit_section'}) {
+        $command = $target_unit->{'unit_section'}->{'element'};
       }
       if ($type eq 'section_nonumber') {
         $type = 'text_nonumber';
@@ -4958,12 +4936,8 @@ sub _convert_heading_command($$$$$)
       $associated_title_command
         = $node_structure->{'associated_title_command'};
     }
-    # NOTE: if USE_NODES = 0 and there are no sectioning commands,
-    # $output_unit->{'unit_command'} does not exist.
-    if ($output_unit->{'unit_command'}
-        and $output_unit->{'unit_command'} eq $element
-        and $element->{'extra'}
-        and defined($element->{'extra'}->{'normalized'})
+    if ($output_unit and $output_unit->{'unit_node'}
+        and $output_unit->{'unit_node'}->{'element'} eq $element
         and !$associated_title_command) {
       if ($element->{'extra'}->{'normalized'} eq 'Top') {
         $heading_level = 0;
@@ -6463,7 +6437,7 @@ sub _convert_printindex_command($$$$)
   my $current_output_unit = $self->current_output_unit();
   if ($current_output_unit and $current_output_unit->{'unit_command'}) {
     $index_element_id
-     = $self->command_id ($current_output_unit->{'unit_command'});
+     = $self->command_id($current_output_unit->{'unit_command'});
   }
   if (!defined($index_element_id)) {
     my ($output_unit, $root_command)
@@ -7672,22 +7646,24 @@ sub _convert_multitable_body_type($$$$) {
 
 $default_types_conversion{'multitable_body'} = \&_convert_multitable_body_type;
 
+# The node is used, not the nodedescription because it is easier to
+# find the node in XS
 sub _formatted_nodedescription_nr($$)
 {
   my $self = shift;
-  my $node_description = shift;
+  my $node = shift;
 
   # update the number of time the node description was formatted
   my $formatted_nodedescription_nr
     = $self->get_shared_conversion_state('nodedescription',
                                     'formatted_nodedescriptions',
-                                     $node_description);
+                                     $node);
   $formatted_nodedescription_nr = 0
      if (!defined($formatted_nodedescription_nr));
   $formatted_nodedescription_nr++;
   $self->set_shared_conversion_state('nodedescription',
                                     'formatted_nodedescriptions',
-                    $node_description, $formatted_nodedescription_nr);
+                              $node, $formatted_nodedescription_nr);
   return $formatted_nodedescription_nr;
 }
 
@@ -7784,7 +7760,7 @@ sub _convert_menu_entry_type($$$)
                              and $menu_description->{'contents'}->[0]
                                   ->{'contents'}->[0]->{'text'} !~ /\S/))))) {
         $formatted_nodedescription_nr
-          = _formatted_nodedescription_nr($self, $node_description);
+          = _formatted_nodedescription_nr($self, $node);
       }
     }
   }
@@ -7819,9 +7795,6 @@ sub _convert_menu_entry_type($$$)
     }
 
     if ($menu_entry_node) {
-      # 'contents' seems to always be defined.  If it is
-      # not the case, it should not be an issue as an undefined
-      # 'contents' is ignored.
       my $name = $self->convert_tree(
          {'type' => '_code',
           'contents' => [$menu_entry_node]},
@@ -10407,9 +10380,9 @@ sub _html_set_pages_files($$$$$$$$$)
         }
         if (not defined($node_filename)) {
           # use section to do the file name if there is no node
-          my $command = $file_output_unit->{'unit_command'};
+          my $command = $file_output_unit->{'unit_section'};
           if ($command) {
-            if ($command->{'cmdname'} eq 'top' and !$node_top
+            if ($command->{'element'}->{'cmdname'} eq 'top' and !$node_top
                 and defined($top_node_filename)) {
               $unit_file_name_paths{$file_output_unit} = $top_node_filename;
 
@@ -10424,7 +10397,8 @@ sub _html_set_pages_files($$$$$$$$$)
                      'file_info_path' => undef};
             } else {
               my $section_filename
-                   = $self->{'targets'}->{$command}->{'section_filename'};
+                = $self->{'targets'}->{$command->{'element'}}
+                     ->{'section_filename'};
               $unit_file_name_paths{$file_output_unit} = $section_filename;
 
               if (not $files_source_info{$section_filename}
@@ -10436,7 +10410,7 @@ sub _html_set_pages_files($$$$$$$$$)
 
                 $files_source_info{$section_filename}
                   = {'file_info_type' => 'section',
-                     'file_info_element' => $command,
+                     'file_info_element' => $command->{'element'},
                      'file_info_path' => undef};
               }
             }
@@ -12053,25 +12027,13 @@ sub _default_format_begin_file($$$)
   my $filename = shift;
   my $output_unit = shift;
 
-  my ($element_command, $node_command, $command_for_title);
+  my ($node_command, $command_for_title);
   if ($output_unit) {
-    $element_command = $output_unit->{'unit_command'};
-    $node_command = $element_command;
-    my $document = $self->get_info('document');
-    my $sections_list;
-    if ($document) {
-      $sections_list = $document->sections_list();
-    }
-    if ($element_command and $element_command->{'cmdname'}
-        and $element_command->{'cmdname'} ne 'node'
-        and $sections_list) {
-      my $section_structure
-        = $sections_list->[$element_command->{'extra'}->{'section_number'} -1];
-      if ($section_structure->{'associated_node'}) {
-        $node_command = $section_structure->{'associated_node'}->{'element'};
-      }
+    if ($output_unit->{'unit_node'}) {
+      $node_command = $output_unit->{'unit_node'}->{'element'};
     }
 
+    my $element_command = $output_unit->{'unit_command'};
     if ($self->get_conf('SPLIT') and defined($element_command)) {
       $command_for_title = $element_command;
     }
diff --git a/tta/perl/Texinfo/Convert/IXIN.pm b/tta/perl/Texinfo/Convert/IXIN.pm
index 4d21743802..4b4c667ccc 100644
--- a/tta/perl/Texinfo/Convert/IXIN.pm
+++ b/tta/perl/Texinfo/Convert/IXIN.pm
@@ -239,8 +239,7 @@ sub ixin_none_element($$)
 # which is always up to date and handles better content in @insertcopying
 # or @titlepage, but has specific HTML code related to separate
 # elements.
-sub _get_element($$);
-sub _get_element($$)
+sub _get_root_command_output_unit($$)
 {
   my $self = shift;
   my $current = shift;
@@ -280,15 +279,14 @@ sub _associated_node_id($$$;$)
   my $node_command = shift;
 
   if (!defined($node_command)) {
-    my ($element, $root_command) = $self->_get_element($command);
+    my ($output_unit, $root_command)
+      = $self->_get_root_command_output_unit($command);
 
     if ($root_command) {
       if (!$root_command->{'cmdname'} or $root_command->{'cmdname'} ne 'node') 
{
-        if ($element
-            and $element->{'unit_command'}
-            and $element->{'unit_command'}->{'cmdname'}
-            and $element->{'unit_command'}->{'cmdname'} eq 'node') {
-          $node_command = $element->{'unit_command'};
+        if ($output_unit
+            and $output_unit->{'unit_node'})
+          $node_command = $output_unit->{'unit_node'}->{'element'};
         }
       } else {
         $node_command = $root_command;
diff --git a/tta/perl/Texinfo/Convert/Plaintext.pm 
b/tta/perl/Texinfo/Convert/Plaintext.pm
index a1ef6f0c71..887d2b4e22 100644
--- a/tta/perl/Texinfo/Convert/Plaintext.pm
+++ b/tta/perl/Texinfo/Convert/Plaintext.pm
@@ -1362,19 +1362,19 @@ sub _close_code($)
 my $footnote_indent = 3;
 sub process_footnotes($;$)
 {
-  my ($self, $element) = @_;
+  my ($self, $output_unit) = @_;
 
   my $formatter = new_formatter($self, 'line'); # may not be used
   push @{$self->{'formatters'}}, $formatter;
 
   if (scalar(@{$self->{'pending_footnotes'}})) {
 
-    $element = undef if ($element and
-                         not defined($element->{'unit_command'}));
+    $output_unit = undef if ($output_unit and
+                         not defined($output_unit->{'unit_command'}));
     my $node_element;
     my $label_element;
-    if ($element) {
-      $node_element = $element->{'unit_command'};
+    if ($output_unit) {
+      $node_element = $output_unit->{'unit_command'};
       if ($node_element->{'extra'}
           and defined($node_element->{'extra'}->{'normalized'})) {
         # arguments_line type element
diff --git a/tta/perl/Texinfo/ManipulateTree.pm 
b/tta/perl/Texinfo/ManipulateTree.pm
index 0ae2a1ac46..08d8d00ae9 100644
--- a/tta/perl/Texinfo/ManipulateTree.pm
+++ b/tta/perl/Texinfo/ManipulateTree.pm
@@ -575,6 +575,11 @@ sub element_number_or_error($)
 sub _print_root_command($)
 {
   my $element = shift;
+
+  if (!defined($element) or !defined($element->{'contents'})) {
+    confess("_print_root_command: unexpected element");
+  }
+
   my $argument_line = $element->{'contents'}->[0];
   if ($argument_line->{'contents'}
       and $argument_line->{'contents'}->[0]->{'contents'}) {
diff --git a/tta/perl/Texinfo/OutputUnits.pm b/tta/perl/Texinfo/OutputUnits.pm
index 9d598baa48..fff527ec6a 100644
--- a/tta/perl/Texinfo/OutputUnits.pm
+++ b/tta/perl/Texinfo/OutputUnits.pm
@@ -116,6 +116,8 @@ sub split_by_node($)
   my $document = shift;
   my $root = $document->tree();
 
+  my $nodes_list = $document->nodes_list();
+
   my $output_units;
 
   my $current = { 'unit_type' => 'unit' };
@@ -129,16 +131,23 @@ sub split_by_node($)
     if ($content->{'cmdname'} and $content->{'cmdname'} eq 'node'
         and $content->{'extra'}
         and defined($content->{'extra'}->{'normalized'})) {
+      my $node_structure
+        = $nodes_list->[$content->{'extra'}->{'node_number'} -1];
       if (not $current->{'unit_command'}) {
         $current->{'unit_command'} = $content;
+        $current->{'unit_node'} = $node_structure;
       } else {
         $current = { 'unit_type' => 'unit', 'unit_command' => $content,
+                     'unit_node' => $node_structure,
                     'tree_unit_directions' => {'prev' => $output_units->[-1]}};
         $output_units->[-1]->{'tree_unit_directions'} = {}
             if (! $output_units->[-1]->{'tree_unit_directions'});
         $output_units->[-1]->{'tree_unit_directions'}->{'next'} = $current;
         push @$output_units, $current;
       }
+      if ($node_structure->{'associated_section'}) {
+        $current->{'unit_section'} = $node_structure->{'associated_section'};
+      }
     }
     if (@pending_parts) {
       foreach my $part (@pending_parts) {
@@ -177,44 +186,58 @@ sub split_by_section($)
   my $output_units;
 
   my $nodes_list = $document->nodes_list();
+  my $sections_list = $document->sections_list();
 
   my $current = { 'unit_type' => 'unit' };
   push @$output_units, $current;
   foreach my $content (@{$root->{'contents'}}) {
-    my $new_section;
+    my $new_section_structure;
+    my $node_structure;
     if ($content->{'cmdname'}) {
       if ($content->{'cmdname'} eq 'node') {
         if ($content->{'extra'} and $content->{'extra'}->{'node_number'}) {
-          my $node_structure
+          $node_structure
             = $nodes_list->[$content->{'extra'}->{'node_number'} -1];
           if ($node_structure->{'associated_section'}) {
-            $new_section
-              = $node_structure->{'associated_section'}->{'element'};
+            $new_section_structure
+              = $node_structure->{'associated_section'};
           }
         }
-      } else {
+      } elsif ($Texinfo::Commands::root_commands{$content->{'cmdname'}}) {
         if ($content->{'cmdname'} eq 'part') {
           my $sections_list = $document->sections_list();
           my $part_structure
             = $sections_list->[$content->{'extra'}->{'section_number'} -1];
           if ($part_structure->{'part_associated_section'}) {
-            $new_section
-              = $part_structure->{'part_associated_section'}->{'element'};
+            $new_section_structure
+              = $part_structure->{'part_associated_section'};
           }
         }
-        if (not $new_section
-            and $Texinfo::Commands::root_commands{$content->{'cmdname'}}) {
-          $new_section = $content;
+        if (not $new_section_structure) {
+          $new_section_structure
+            = $sections_list->[$content->{'extra'}->{'section_number'} -1];
+        }
+
+        if ($new_section_structure->{'associated_node'}) {
+          $node_structure = $new_section_structure->{'associated_node'};
         }
       }
     }
-    if ($new_section) {
+    if ($new_section_structure) {
       if (not defined($current->{'unit_command'})) {
-        $current->{'unit_command'} = $new_section;
-      } elsif ($new_section ne $current->{'unit_command'}) {
+        $current->{'unit_command'} = $new_section_structure->{'element'};
+        $current->{'unit_section'} = $new_section_structure;
+        if ($node_structure) {
+          $current->{'unit_node'} = $node_structure;
+        }
+      } elsif ($new_section_structure ne $current->{'unit_section'}) {
         $current = { 'unit_type' => 'unit',
-                     'unit_command' => $new_section,
+                     'unit_command' => $new_section_structure->{'element'},
+                     'unit_section' => $new_section_structure,
                      'tree_unit_directions' => {'prev' => 
$output_units->[-1]}};
+        if ($node_structure) {
+          $current->{'unit_node'} = $node_structure;
+        }
         $output_units->[-1]->{'tree_unit_directions'} = {}
             if (! $output_units->[-1]->{'tree_unit_directions'});
         $output_units->[-1]->{'tree_unit_directions'}->{'next'} = $current;
@@ -287,9 +310,9 @@ sub split_pages($$$)
   my $current_first_in_page;
   foreach my $output_unit (@$output_units) {
     my $level;
-    my $section = _output_unit_section($output_unit, $nodes_list);
-    if (defined($section)) {
-      $level = $section->{'extra'}->{'section_level'};
+    if ($output_unit->{'unit_section'}) {
+      $level = $output_unit->{'unit_section'}
+                  ->{'element'}->{'extra'}->{'section_level'};
     }
     #print STDERR "level($split_level) $level "
     #       .output_unit_texi($output_unit)."\n";
@@ -322,57 +345,6 @@ sub _label_target_unit_element($)
   }
 }
 
-sub _output_unit_section($$)
-{
-  my $output_unit = shift;
-  my $nodes_list = shift;
-
-  if (not defined($output_unit->{'unit_command'})) {
-    return undef;
-  }
-  my $element = $output_unit->{'unit_command'};
-  if ($element->{'cmdname'} eq 'node') {
-    if (!$element->{'extra'}
-        or !$element->{'extra'}->{'node_number'}) {
-      return undef;
-    }
-    my $node_structure = $nodes_list->[$element->{'extra'}->{'node_number'} 
-1];
-    if ($node_structure->{'associated_section'}) {
-      return $node_structure->{'associated_section'}->{'element'};
-    } else {
-      return undef;
-    }
-  } else {
-    return $element;
-  }
-}
-
-sub _output_unit_node($$)
-{
-  my $output_unit = shift;
-  my $sections_list = shift;
-
-  if (not defined($output_unit->{'unit_command'})) {
-    return undef;
-  }
-  my $element = $output_unit->{'unit_command'};
-  if ($element->{'cmdname'} eq 'node') {
-    if (!$element->{'extra'}
-        or !defined($element->{'extra'}->{'normalized'})) {
-      return undef;
-    }
-    return $element;
-  } else {
-    my $section_structure
-      = $sections_list->[$element->{'extra'}->{'section_number'} -1];
-    if ($section_structure->{'associated_node'}) {
-      return $section_structure->{'associated_node'}->{'element'};
-    } else {
-      return undef;
-    }
-  }
-}
-
 # Do output units directions and store them in 'directions'.
 # The directions are only created if pointing to other output units.
 sub units_directions($$$$;$)
@@ -403,9 +375,10 @@ sub units_directions($$$$;$)
                                                                ->{'unit_type'})
           and $output_unit->{'tree_unit_directions'}->{'prev'}
                                                      ->{'unit_type'} eq 
'unit');
-    my $node = _output_unit_node($output_unit, $sections_list);
-    if ($node) {
-      my $node_structure = $nodes_list->[$node->{'extra'}->{'node_number'} -1];
+    my $node;
+    if ($output_unit->{'unit_node'}) {
+      my $node_structure = $output_unit->{'unit_node'};
+      my $node = $node_structure->{'element'};
       foreach my $direction(['NodeUp', 'up'], ['NodeNext', 'next'],
                             ['NodePrev', 'prev']) {
         $directions->{$direction->[0]}
@@ -478,8 +451,7 @@ sub units_directions($$$$;$)
                                        ->{'NodeBack'} = $output_unit;
       }
     }
-    my $section = _output_unit_section($output_unit, $nodes_list);
-    if (not defined($section)) {
+    if (not $output_unit->{'unit_section'}) {
       # If there is no associated section, find the previous element section.
       # Use the FastForward of this element.
       # Use it as FastBack if the section is top level, or use the FastBack.
@@ -488,13 +460,13 @@ sub units_directions($$$$;$)
       while ($current_unit->{'tree_unit_directions'}
              and $current_unit->{'tree_unit_directions'}->{'prev'}) {
         $current_unit = $current_unit->{'tree_unit_directions'}->{'prev'};
-        $section = _output_unit_section($current_unit, $nodes_list);
-        if (defined($section)) {
+        if ($current_unit->{'unit_section'}) {
           $section_output_unit = $current_unit;
           last;
         }
       }
       if ($section_output_unit) {
+        my $section = $current_unit->{'unit_section'}->{'element'};
         if ($section_output_unit->{'directions'}->{'FastForward'}) {
           $directions->{'FastForward'}
             = $section_output_unit->{'directions'}->{'FastForward'};
@@ -507,8 +479,8 @@ sub units_directions($$$$;$)
         }
       }
     } else {
-      my $section_structure
-        = $sections_list->[$section->{'extra'}->{'section_number'} -1];
+      my $section_structure = $output_unit->{'unit_section'};
+      my $section = $section_structure->{'element'};
       my $section_directions = $section_structure->{'section_directions'};
       if ($section_directions) {
         foreach my $direction(['Up', 'up'], ['Next', 'next'],
@@ -723,7 +695,7 @@ sub output_unit_texi($)
     return "No associated command (type $output_unit->{'unit_type'})";
   }
   return Texinfo::Convert::Texinfo::root_heading_command_to_texinfo(
-                                                          $unit_command);
+                                                         $unit_command);
 }
 
 sub _output_unit_name_string($)
@@ -772,14 +744,26 @@ sub print_output_units_details($$;$$)
 
     if ($output_unit->{'unit_type'} ne 'special_unit'
         and $output_unit->{'unit_command'}) {
-      my $element_string
+      my $element_string = '';
+      my $root_command_texi
         = Texinfo::ManipulateTree::root_command_element_string(
                                     $output_unit->{'unit_command'});
-      if (defined($element_string)) {
-        $result .= "{$element_string}";
-      } else {
-        $result .= '{}';
+      if (defined($root_command_texi)) {
+        $element_string .= $root_command_texi;
       }
+      # TODO info on both unit section and unit node?
+      #if ($output_unit->{'unit_node'}) {
+      #  $element_string
+      #   = Texinfo::ManipulateTree::root_command_element_string(
+      #                  $output_unit->{'unit_node'}->{'element'});
+      #}
+      #if ($output_unit->{'unit_section'}) {
+      #  $element_string .= '|' if ($element_string);
+      #  $element_string
+      #   = Texinfo::ManipulateTree::root_command_element_string(
+      #                  $output_unit->{'unit_section'}->{'element'});
+      #}
+      $result .= "{$element_string}";
     }
 
     if (defined($output_unit->{'unit_filename'})) {
diff --git a/tta/perl/XSTexinfo/convert/get_html_perl_info.c 
b/tta/perl/XSTexinfo/convert/get_html_perl_info.c
index cba970875b..2f54d87105 100644
--- a/tta/perl/XSTexinfo/convert/get_html_perl_info.c
+++ b/tta/perl/XSTexinfo/convert/get_html_perl_info.c
@@ -1815,28 +1815,15 @@ HTML_TARGET *
 find_node_target_info_nodedescription_sv (CONVERTER *converter,
                                           SV *element_sv)
 {
-  HV *element_hv;
-  SV **extra_sv;
-
   dTHX;
 
-  element_hv = (HV *)SvRV (element_sv);
-  extra_sv = hv_fetch (element_hv, "extra", strlen ("extra"), 0);
-  if (extra_sv)
+  const ELEMENT *node = html_find_element_from_sv (converter,
+                                                element_sv, 0);
+
+  if (node)
     {
-      HV *extra_hv = (HV *)SvRV (*extra_sv);
-      SV **element_node_sv = hv_fetch (extra_hv, "element_node",
-                                       strlen ("element_node"), 0);
-      if (element_node_sv)
-        {
-          const ELEMENT *node = html_find_element_from_sv (converter,
-                                                *element_node_sv, 0);
-          if (node)
-            {
-              HTML_TARGET *target_info = html_get_target (converter, node);
-              return target_info;
-            }
-        }
+      HTML_TARGET *target_info = html_get_target (converter, node);
+      return target_info;
     }
   return 0;
 }
diff --git a/tta/perl/init/book.pm b/tta/perl/init/book.pm
index d5e690f5d6..02c4ad58dd 100644
--- a/tta/perl/init/book.pm
+++ b/tta/perl/init/book.pm
@@ -158,15 +158,12 @@ sub book_format_navigation_header($$$$)
   my $element = shift;
 
   my $output_unit = $element->{'associated_unit'};
-  if ($output_unit and $output_unit->{'unit_command'}
-      and not $output_unit->{'unit_command'}->{'cmdname'} eq 'node'
-      and ($output_unit->{'unit_contents'}->[0] eq $element
-          or (!$output_unit->{'unit_contents'}->[0]->{'cmdname'}
-              and $output_unit->{'unit_contents'}->[1] eq $element))
+  if ($output_unit and $output_unit->{'unit_section'}
       and defined($output_unit->{'unit_filename'})
       and $self->count_elements_in_filename('current',
                          $output_unit->{'unit_filename'}) == 1) {
-    return book_print_up_toc($self, $output_unit->{'unit_command'}) .
+    return book_print_up_toc($self,
+                             $output_unit->{'unit_section'}->{'element'}) .
        &{$self->default_formatting_function('format_navigation_header')}($self,
                                  $buttons, $cmdname, $element);
 
@@ -364,20 +361,17 @@ sub book_convert_heading_command($$$$$)
   # node is used as heading if there is nothing else.
   if ($cmdname eq 'node') {
     my $associated_title_command;
+    my $node_structure;
     if ($document and $element->{'extra'}
         and $element->{'extra'}->{'node_number'}) {
       my $nodes_list = $document->nodes_list();
-      my $node_structure
+      $node_structure
         = $nodes_list->[$element->{'extra'}->{'node_number'} -1];
       $associated_title_command
         = $node_structure->{'associated_title_command'};
     }
-    # NOTE: if USE_NODES = 0 and there are no sectioning commands,
-    # $output_unit->{'unit_command'} does not exist.
-    if ($output_unit->{'unit_command'}
-        and $output_unit->{'unit_command'} eq $element
-        and $element->{'extra'}
-        and defined($element->{'extra'}->{'normalized'})
+    if ($output_unit->{'unit_node'}
+        and $output_unit->{'unit_node'} eq $node_structure
         and !$associated_title_command) {
       if ($element->{'extra'}->{'normalized'} eq 'Top') {
         $heading_level = 0;
@@ -511,13 +505,8 @@ sub book_unit_file_name($$$$)
   my $prefix = $converter->get_info('document_name');
   my $new_file_name;
   my $command;
-  if ($output_unit->{'unit_command'}) {
-    if ($output_unit->{'unit_command'}->{'cmdname'} ne 'node') {
-      $command = $output_unit->{'unit_command'};
-    } elsif ($output_unit->{'unit_command'}->{'extra'}
-             and 
$output_unit->{'unit_command'}->{'extra'}->{'associated_section'}) {
-      $command = 
$output_unit->{'unit_command'}->{'extra'}->{'associated_section'}->{'element'};
-    }
+  if ($output_unit->{'unit_section'}) {
+    $command = $output_unit->{'unit_section'}->{'element'};
   }
   return (undef, undef) unless ($command);
   if ($converter->unit_is_top_output_unit($output_unit)) {



reply via email to

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