texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Mon, 4 Dec 2023 18:42:15 -0500 (EST)

branch: master
commit 075f75338e61e654902c3b2297b2713294fe6031
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Tue Dec 5 00:06:14 2023 +0100

    * tp/maintain/setup_converters_code_tables.pl: add include
    command_ids.h in generated cmd_structuring.c.
    
    * tp/Texinfo/XS/main/errors.c, tp/Texinfo/XS/main/debug.c,
    tp/Texinfo/XS/main/extra.c, tp/Texinfo/XS/main/tree_types.h,
    tp/Texinfo/XS/main/utils.c, tp/Texinfo/XS/main/manipulate_tree.c: add
    some const.
    
    * tp/Texinfo/XS/main/unicode.c (compare_strings): make static.
    
    * tp/Texinfo/XS/main/utils.c (section_level_adjusted_command_name):
    implement.
    
    * tp/Texinfo/XS/main/convert_utils.c
    (find_root_command_next_heading_command): implement.
    
    * tp/Texinfo/XS/main/utils.c (is_content_empty),
    tp/Texinfo/XS/structuring_transfo/transformations.c
    (fill_gaps_in_sectioning), tp/Texinfo/XS/main/convert_to_texinfo.c
    (root_heading_command_to_texinfo), tp/Texinfo/XS/main/convert_utils.c
    (find_innermost_accent_contents), tp/Texinfo/XS/main/output_unit.c
    (split_by_node, split_by_section): use element_builtin_data_cmd and
    variables for the flags to get the expected result even with
    user-defined @-commands.
    
    * tp/Texinfo/XS/main/command_stack.c (push_stack_element)
    (pop_stack_element), tp/Texinfo/XS/main/utils.c: move
    push_stack_element and pop_stack_element to command_stack.c.
    
    * tp/Texinfo/XS/structuring_transfo/structuring.c (compare_strings):
    make static.
    
    * tp/Texinfo/XS/structuring_transfo/structuring.c (protect_colon)
    (protect_colon_in_tree, new_complete_menu_master_menu),
    tp/Texinfo/XS/main/manipulate_tree.c (modify_tree)
    (new_asis_command_with_text, protect_text),
    tp/Texinfo/XS/structuring_transfo/transformations.c,
    tp/Texinfo/XS/Makefile.am (libtexinfo_la_SOURCES)
    (StructuringTransfoXS_la_SOURCES, ConvertXS_la_CPPFLAGS): move
    functions from transformations.c to structuring.c and
    manipulate_tree.c to avoid a dependency of structuring.c to
    transformations.c.  Move structuring.c to libtexinfo.la such that
    converters can use functions in structuring.c.
    
    * tp/Texinfo/XS/Makefile.am (libtexinfo_la_SOURCES, EXTRA_DIST),
    tp/Texinfo/XS/main/utils.c: move cmd_structuring.c out of utils.c.
---
 ChangeLog                                          |  49 +++++
 tp/Texinfo/XS/Makefile.am                          |  13 +-
 tp/Texinfo/XS/main/build_perl_info.c               |   2 +-
 tp/Texinfo/XS/main/command_stack.c                 |  29 ++-
 tp/Texinfo/XS/main/command_stack.h                 |   3 +
 tp/Texinfo/XS/main/convert_to_texinfo.c            |  12 +-
 tp/Texinfo/XS/main/convert_utils.c                 | 100 ++++++++-
 tp/Texinfo/XS/main/convert_utils.h                 |   5 +
 tp/Texinfo/XS/main/debug.c                         |   2 +-
 tp/Texinfo/XS/main/errors.c                        |  26 +--
 tp/Texinfo/XS/main/errors.h                        |  18 +-
 tp/Texinfo/XS/main/extra.c                         |  34 +--
 tp/Texinfo/XS/main/extra.h                         |  35 +--
 tp/Texinfo/XS/main/manipulate_tree.c               | 213 +++++++++++++++++-
 tp/Texinfo/XS/main/manipulate_tree.h               |  11 +
 tp/Texinfo/XS/main/output_unit.c                   |  16 +-
 tp/Texinfo/XS/main/tree_types.h                    |   2 +-
 tp/Texinfo/XS/main/unicode.c                       |   2 +-
 tp/Texinfo/XS/main/utils.c                         |  76 +++----
 tp/Texinfo/XS/main/utils.h                         |  14 +-
 tp/Texinfo/XS/structuring_transfo/structuring.c    |  57 ++++-
 tp/Texinfo/XS/structuring_transfo/structuring.h    |   4 +
 .../XS/structuring_transfo/transformations.c       | 237 ++-------------------
 .../XS/structuring_transfo/transformations.h       |   1 -
 tp/maintain/setup_converters_code_tables.pl        |   1 +
 25 files changed, 605 insertions(+), 357 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a105ffe39b..30c8873857 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+2023-12-04  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/maintain/setup_converters_code_tables.pl: add include
+       command_ids.h in generated cmd_structuring.c.
+
+       * tp/Texinfo/XS/main/errors.c, tp/Texinfo/XS/main/debug.c,
+       tp/Texinfo/XS/main/extra.c, tp/Texinfo/XS/main/tree_types.h,
+       tp/Texinfo/XS/main/utils.c, tp/Texinfo/XS/main/manipulate_tree.c: add
+       some const.
+
+       * tp/Texinfo/XS/main/unicode.c (compare_strings): make static.
+
+       * tp/Texinfo/XS/main/utils.c (section_level_adjusted_command_name):
+       implement.
+
+       * tp/Texinfo/XS/main/convert_utils.c
+       (find_root_command_next_heading_command): implement.
+
+       * tp/Texinfo/XS/main/utils.c (is_content_empty),
+       tp/Texinfo/XS/structuring_transfo/transformations.c
+       (fill_gaps_in_sectioning), tp/Texinfo/XS/main/convert_to_texinfo.c
+       (root_heading_command_to_texinfo), tp/Texinfo/XS/main/convert_utils.c
+       (find_innermost_accent_contents), tp/Texinfo/XS/main/output_unit.c
+       (split_by_node, split_by_section): use element_builtin_data_cmd and
+       variables for the flags to get the expected result even with
+       user-defined @-commands.
+
+       * tp/Texinfo/XS/main/command_stack.c (push_stack_element)
+       (pop_stack_element), tp/Texinfo/XS/main/utils.c: move
+       push_stack_element and pop_stack_element to command_stack.c.
+
+       * tp/Texinfo/XS/structuring_transfo/structuring.c (compare_strings):
+       make static.
+
+       * tp/Texinfo/XS/structuring_transfo/structuring.c (protect_colon)
+       (protect_colon_in_tree, new_complete_menu_master_menu),
+       tp/Texinfo/XS/main/manipulate_tree.c (modify_tree)
+       (new_asis_command_with_text, protect_text),
+       tp/Texinfo/XS/structuring_transfo/transformations.c,
+       tp/Texinfo/XS/Makefile.am (libtexinfo_la_SOURCES)
+       (StructuringTransfoXS_la_SOURCES, ConvertXS_la_CPPFLAGS): move
+       functions from transformations.c to structuring.c and
+       manipulate_tree.c to avoid a dependency of structuring.c to
+       transformations.c.  Move structuring.c to libtexinfo.la such that
+       converters can use functions in structuring.c.
+
+       * tp/Texinfo/XS/Makefile.am (libtexinfo_la_SOURCES, EXTRA_DIST),
+       tp/Texinfo/XS/main/utils.c: move cmd_structuring.c out of utils.c.
+
 2023-12-04  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/HTML.pm (command_tree): copy tree in substituted
diff --git a/tp/Texinfo/XS/Makefile.am b/tp/Texinfo/XS/Makefile.am
index af7fa6e22b..dfb5bb3b05 100644
--- a/tp/Texinfo/XS/Makefile.am
+++ b/tp/Texinfo/XS/Makefile.am
@@ -101,6 +101,8 @@ endif
 # by the parser and by converters.  The files in the parsetexi
 # directory correspond to the parser code.  They depend on the files
 # in main but not the other way around.
+# Files in structuring_transfo depend only on the files in main and not
+# the other way around.
 libtexinfo_la_SOURCES= \
                      main/tree_types.h \
                      main/document_types.h \
@@ -133,6 +135,7 @@ libtexinfo_la_SOURCES= \
                      main/node_name_normalization.h \
                      main/command_stack.c \
                      main/command_stack.h \
+                     main/cmd_structuring.c \
                      main/targets.c \
                      main/targets.h \
                      main/utils.c \
@@ -178,12 +181,14 @@ libtexinfo_la_SOURCES= \
                      parsetexi/counter.c \
                      parsetexi/counter.h \
                      parsetexi/source_marks.c \
-                     parsetexi/source_marks.h
+                     parsetexi/source_marks.h \
+                     structuring_transfo/structuring.c \
+                     structuring_transfo/structuring.h
+
 EXTRA_DIST += main/accent_tables_8bit_codepoints.c
 EXTRA_DIST += main/command_data.c
 EXTRA_DIST += main/cmd_normalization.c
 EXTRA_DIST += main/cmd_unicode.c
-EXTRA_DIST += main/cmd_structuring.c
 EXTRA_DIST += main/cmd_symbol.c
 EXTRA_DIST += main/cmd_text.c
 EXTRA_DIST += main/global_commands_types.h
@@ -333,8 +338,6 @@ endif
 
 StructuringTransfoXS_la_SOURCES = \
                     structuring_transfo/StructuringTransfoXS.c \
-                    structuring_transfo/structuring.c \
-                    structuring_transfo/structuring.h \
                     structuring_transfo/transformations.c \
                     structuring_transfo/transformations.h
 
@@ -374,7 +377,7 @@ ConvertXS_la_SOURCES = \
 EXTRA_DIST += convert/ConvertXS.xs
 
 # To locate include files under out-of-source builds.
-ConvertXS_la_CPPFLAGS = -I$(srcdir)/main -I$(srcdir)/convert $(AM_CPPFLAGS) 
$(GNULIB_CPPFLAGS) $(XSLIBS_CPPFLAGS)
+ConvertXS_la_CPPFLAGS = -I$(srcdir)/main -I$(srcdir)/structuring_transfo 
-I$(srcdir)/convert $(AM_CPPFLAGS) $(GNULIB_CPPFLAGS) $(XSLIBS_CPPFLAGS)
 ConvertXS_la_CFLAGS = $(XSLIBS_CFLAGS)
 ConvertXS_la_LIBADD = libtexinfoxs.la libtexinfo.la
 ConvertXS_la_LDFLAGS = $(XSLIBS_LDFLAGS) $(LTLIBICONV) $(LTLIBUNISTRING)
diff --git a/tp/Texinfo/XS/main/build_perl_info.c 
b/tp/Texinfo/XS/main/build_perl_info.c
index 02191f0b45..e33684cdae 100644
--- a/tp/Texinfo/XS/main/build_perl_info.c
+++ b/tp/Texinfo/XS/main/build_perl_info.c
@@ -258,7 +258,7 @@ store_additional_info (const ELEMENT *e, ASSOCIATED_INFO* 
a, char *key,
         {
           KEY_PAIR *k = &a->info[i];
 #define STORE(sv) hv_store (extra, key, strlen (key), sv, 0)
-          char *key = k->key;
+          const char *key = k->key;
           ELEMENT *f = k->element;
 
           if (k->type == extra_deleted)
diff --git a/tp/Texinfo/XS/main/command_stack.c 
b/tp/Texinfo/XS/main/command_stack.c
index 7b398c863b..150c667631 100644
--- a/tp/Texinfo/XS/main/command_stack.c
+++ b/tp/Texinfo/XS/main/command_stack.c
@@ -22,7 +22,7 @@
 #include "utils.h"
 #include "command_stack.h"
 
-/* Generic command stack functions */
+/* Generic stack functions */
 
 void
 reset_command_stack (COMMAND_STACK *stack)
@@ -192,6 +192,33 @@ top_integer_stack (INTEGER_STACK *stack)
   return stack->stack[stack->top - 1];
 }
 
+
+/* accents/elements stacks */
+void
+push_stack_element (ELEMENT_STACK *stack, const ELEMENT *e)
+{
+  if (stack->top >= stack->space)
+    {
+      stack->stack
+        = realloc (stack->stack,
+                   (stack->space += 5) * sizeof (ELEMENT *));
+    }
+
+  stack->stack[stack->top] = e;
+  stack->top++;
+}
+
+const ELEMENT *
+pop_stack_element (ELEMENT_STACK *stack)
+{
+  if (stack->top == 0)
+    fatal ("element stack empty");
+
+  stack->top--;
+  return stack->stack[stack->top +1];
+}
+
+
 /* HTML specific but also used to build perl */
 HTML_DOCUMENT_CONTEXT *
 html_top_document_context (CONVERTER *self)
diff --git a/tp/Texinfo/XS/main/command_stack.h 
b/tp/Texinfo/XS/main/command_stack.h
index 34586b6250..18c7f6c30a 100644
--- a/tp/Texinfo/XS/main/command_stack.h
+++ b/tp/Texinfo/XS/main/command_stack.h
@@ -41,6 +41,9 @@ void push_integer_stack_integer (INTEGER_STACK *stack, int 
value);
 int pop_integer_stack (INTEGER_STACK *stack);
 int top_integer_stack (INTEGER_STACK *stack);
 
+void push_stack_element (ELEMENT_STACK *stack, const ELEMENT *e);
+const ELEMENT *pop_stack_element (ELEMENT_STACK *stack);
+
 HTML_DOCUMENT_CONTEXT *html_top_document_context (CONVERTER *self);
 
 HTML_FORMATTING_CONTEXT *html_top_formatting_context
diff --git a/tp/Texinfo/XS/main/convert_to_texinfo.c 
b/tp/Texinfo/XS/main/convert_to_texinfo.c
index a0e15cc5f2..351b9a3fd1 100644
--- a/tp/Texinfo/XS/main/convert_to_texinfo.c
+++ b/tp/Texinfo/XS/main/convert_to_texinfo.c
@@ -309,10 +309,12 @@ root_heading_command_to_texinfo (const ELEMENT *element)
   const ELEMENT *tree = 0;
   TEXT text;
 
-  if (element->cmd)
+  enum command_id data_cmd = element_builtin_data_cmd (element);
+
+  if (data_cmd)
     {
-      if ((element->cmd == CM_node
-           || (builtin_command_flags (element) & CF_sectioning_heading))
+      if ((data_cmd == CM_node
+           || (builtin_command_data[data_cmd].flags & CF_sectioning_heading))
           && element->args.number > 0)
         tree = element->args.list[0];
     }
@@ -323,12 +325,12 @@ root_heading_command_to_texinfo (const ELEMENT *element)
   if (tree)
     {
       char *tree_txi = convert_contents_to_texinfo (tree);
-      text_printf (&text, "@%s %s", builtin_command_name (element->cmd),
+      text_printf (&text, "@%s %s", builtin_command_name (data_cmd),
                                     tree_txi);
       free (tree_txi);
     }
   else
-   text_printf (&text, "@%s", builtin_command_name (element->cmd));
+   text_printf (&text, "@%s", builtin_command_name (data_cmd));
 
   return (text.text);
 }
diff --git a/tp/Texinfo/XS/main/convert_utils.c 
b/tp/Texinfo/XS/main/convert_utils.c
index e9863bad77..770dede5a5 100644
--- a/tp/Texinfo/XS/main/convert_utils.c
+++ b/tp/Texinfo/XS/main/convert_utils.c
@@ -29,6 +29,7 @@
 #include "builtin_commands.h"
 #include "tree.h"
 #include "extra.h"
+#include "command_stack.h"
 #include "errors.h"
 #include "debug.h"
 #include "utils.h"
@@ -64,9 +65,11 @@ find_innermost_accent_contents (const ELEMENT *element)
     {
       const ELEMENT *arg;
       int i;
+      enum command_id data_cmd = element_builtin_data_cmd (current);
+      unsigned long flags = builtin_command_data[data_cmd].flags;
 
       /* the following can happen if called with a bad tree */
-      if (!current->cmd || !(builtin_command_flags(current) & CF_accent))
+      if (!data_cmd || !(flags & CF_accent))
         return accent_stack;
       push_stack_element (&accent_stack->stack, current);
       /* A bogus accent, that may happen */
@@ -78,11 +81,15 @@ find_innermost_accent_contents (const ELEMENT *element)
       for (i = 0; i < arg->contents.number; i++)
         {
           ELEMENT *content = arg->contents.list[i];
-          if (!(content->cmd && (content->cmd == CM_c
-                                 || content->cmd == CM_comment)))
+          enum command_id content_data_cmd
+             = element_builtin_data_cmd (content);
+          unsigned long content_flags
+            = builtin_command_data[content_data_cmd].flags;
+
+          if (!(content_data_cmd && (content_data_cmd == CM_c
+                                     || content_data_cmd == CM_comment)))
             {
-              if (content->cmd
-                  && builtin_command_flags(content) & CF_accent)
+              if (content_data_cmd && content_flags & CF_accent)
                 {
                   current = content;
                   if (argument)
@@ -717,3 +724,86 @@ output_files_register_closed (OUTPUT_FILES_INFORMATION 
*self,
     }
   fprintf (stderr, "BUG: %s not opened\n", file_path);
 }
+
+ELEMENT *
+find_root_command_next_heading_command (const ELEMENT *root,
+                                  EXPANDED_FORMAT *formats,
+                                  int do_not_ignore_contents,
+                                  int do_not_ignore_index_entries)
+{
+  size_t i;
+
+  if (root->contents.number <= 0)
+    return 0;
+
+  for (i = 0; i < root->contents.number; i++)
+    {
+      ELEMENT *content = root->contents.list[i];
+      enum command_id data_cmd = element_builtin_data_cmd (content);
+
+      if (data_cmd)
+        {
+          unsigned long flags = builtin_command_data[data_cmd].flags;
+          unsigned long other_flags
+               = builtin_command_data[data_cmd].other_flags;
+          if (flags & CF_sectioning_heading)
+            return content;
+          if (content->type == ET_index_entry_command)
+            {
+              if (do_not_ignore_index_entries)
+                return  0;
+              else
+                continue;
+            }
+          if (flags & CF_line)
+            {
+              if (other_flags & CF_formatted_line
+                  || other_flags & CF_formattable_line
+                  || (do_not_ignore_contents
+                      && (content->cmd == CM_contents
+                          || content->cmd == CM_shortcontents
+                          || content->cmd == CM_summarycontents)))
+                return 0;
+              else
+                continue;
+            }
+          else if (flags & CF_nobrace)
+            {
+              if (other_flags & CF_formatted_nobrace)
+                return 0;
+              else
+                continue;
+            }
+          else if (flags & CF_block)
+            {
+              if (other_flags & CF_non_formatted_block
+               || builtin_command_data[data_cmd].data == BLOCK_region
+                /* ignored conditional */
+               || builtin_command_data[data_cmd].data == BLOCK_conditional
+               || (builtin_command_data[data_cmd].data == BLOCK_format_raw
+                   && !format_expanded_p 
+                             (formats, element_command_name (content))))
+                continue;
+              else
+                return 0;
+            }
+          else 
+            { /* brace commands */
+              if (other_flags & CF_non_formatted_brace)
+                continue;
+              else
+                return 0;
+            }
+        }
+      if (content->type == ET_paragraph)
+        return 0;
+      if (content->text.end > 0)
+        {
+          char *text = element_text (content);
+          /* only whitespace characters */
+          if (! text[strspn (text, whitespace_chars)] == '\0')
+            return 0;
+        }
+    }
+  return 0;
+}
diff --git a/tp/Texinfo/XS/main/convert_utils.h 
b/tp/Texinfo/XS/main/convert_utils.h
index f7e5c6a78f..af39999eb6 100644
--- a/tp/Texinfo/XS/main/convert_utils.h
+++ b/tp/Texinfo/XS/main/convert_utils.h
@@ -48,4 +48,9 @@ void output_files_register_closed (OUTPUT_FILES_INFORMATION 
*self,
 void free_output_files_information (OUTPUT_FILES_INFORMATION *self);
 void clear_output_files_information (OUTPUT_FILES_INFORMATION *self);
 
+ELEMENT *find_root_command_next_heading_command (const ELEMENT *root,
+                                  EXPANDED_FORMAT *formats,
+                                  int do_not_ignore_contents,
+                                  int do_not_ignore_index_entries);
+
 #endif
diff --git a/tp/Texinfo/XS/main/debug.c b/tp/Texinfo/XS/main/debug.c
index 90251905c6..f466b2b2db 100644
--- a/tp/Texinfo/XS/main/debug.c
+++ b/tp/Texinfo/XS/main/debug.c
@@ -137,7 +137,7 @@ char *print_associate_info_debug (const ASSOCIATED_INFO 
*info)
   for (i = 0; i < info->info_number; i++)
     {
       KEY_PAIR *k = &info->info[i];
-      char *key = k->key;
+      const char *key = k->key;
       text_printf (&text, "  %s|", key);
       switch (info->info[i].type)
         {
diff --git a/tp/Texinfo/XS/main/errors.c b/tp/Texinfo/XS/main/errors.c
index 30be8cb1a4..904ff22cdf 100644
--- a/tp/Texinfo/XS/main/errors.c
+++ b/tp/Texinfo/XS/main/errors.c
@@ -63,7 +63,7 @@ static void
 message_list_line_error_internal (ERROR_MESSAGE_LIST *error_messages,
                                   enum error_type type, int continuation,
                                   const SOURCE_INFO *cmd_source_info,
-                                  char *format, va_list v)
+                                  const char *format, va_list v)
 {
   char *message;
   TEXT error_line;
@@ -148,7 +148,7 @@ static void
 message_list_document_error_internal (ERROR_MESSAGE_LIST *error_messages,
                                       OPTIONS *conf,
                                       enum error_type type, int continuation,
-                                      char *format, va_list v)
+                                      const char *format, va_list v)
 {
   char *message;
   TEXT error_line;
@@ -219,8 +219,8 @@ message_list_document_error_internal (ERROR_MESSAGE_LIST 
*error_messages,
 
 static void
 line_error_internal (enum error_type type, int continuation,
-                     SOURCE_INFO *cmd_source_info,
-                     char *format, va_list v)
+                     const SOURCE_INFO *cmd_source_info,
+                     const char *format, va_list v)
 {
   message_list_line_error_internal (&error_messages_list,
                       type, continuation, cmd_source_info,
@@ -230,7 +230,7 @@ line_error_internal (enum error_type type, int continuation,
 void
 line_error_ext (enum error_type type, int continuation,
                 SOURCE_INFO *cmd_source_info,
-                char *format, ...)
+                const char *format, ...)
 {
   va_list v;
 
@@ -239,7 +239,7 @@ line_error_ext (enum error_type type, int continuation,
 }
 
 void
-line_error (char *format, ...)
+line_error (const char *format, ...)
 {
   va_list v;
 
@@ -248,7 +248,7 @@ line_error (char *format, ...)
 }
 
 void
-line_warn (char *format, ...)
+line_warn (const char *format, ...)
 {
   va_list v;
 
@@ -257,7 +257,7 @@ line_warn (char *format, ...)
 }
 
 void
-command_warn (ELEMENT *e, char *format, ...)
+command_warn (const ELEMENT *e, const char *format, ...)
 {
   va_list v;
 
@@ -267,7 +267,7 @@ command_warn (ELEMENT *e, char *format, ...)
 
 void
 message_list_command_warn (ERROR_MESSAGE_LIST *error_messages,
-                           ELEMENT *e, char *format, ...)
+                           const ELEMENT *e, const char *format, ...)
 {
   va_list v;
 
@@ -277,7 +277,7 @@ message_list_command_warn (ERROR_MESSAGE_LIST 
*error_messages,
 }
 
 void
-command_error (ELEMENT *e, char *format, ...)
+command_error (const ELEMENT *e, const char *format, ...)
 {
   va_list v;
 
@@ -287,7 +287,7 @@ command_error (ELEMENT *e, char *format, ...)
 
 void
 message_list_command_error (ERROR_MESSAGE_LIST *error_messages,
-                            const ELEMENT *e, char *format, ...)
+                            const ELEMENT *e, const char *format, ...)
 {
   va_list v;
 
@@ -300,7 +300,7 @@ message_list_command_error (ERROR_MESSAGE_LIST 
*error_messages,
 void
 message_list_document_error (ERROR_MESSAGE_LIST *error_messages,
                              OPTIONS *conf,
-                             char *format, ...)
+                             const char *format, ...)
 {
   va_list v;
 
@@ -313,7 +313,7 @@ message_list_document_error (ERROR_MESSAGE_LIST 
*error_messages,
 void
 message_list_document_warn (ERROR_MESSAGE_LIST *error_messages,
                             OPTIONS *conf,
-                            char *format, ...)
+                            const char *format, ...)
 {
   va_list v;
 
diff --git a/tp/Texinfo/XS/main/errors.h b/tp/Texinfo/XS/main/errors.h
index d981f7f866..76253c4091 100644
--- a/tp/Texinfo/XS/main/errors.h
+++ b/tp/Texinfo/XS/main/errors.h
@@ -8,30 +8,30 @@
 #include "options_types.h"
 #include "document_types.h"
 
-void line_error (char *format, ...);
-void line_warn (char *format, ...);
-void command_error (ELEMENT *e, char *format, ...);
-void command_warn (ELEMENT *e, char *format, ...);
+void line_error (const char *format, ...);
+void line_warn (const char *format, ...);
+void command_error (const ELEMENT *e, const char *format, ...);
+void command_warn (const ELEMENT *e, const char *format, ...);
 void wipe_errors (void);
 void forget_errors (void);
 void line_error_ext (enum error_type type, int continuation,
-                     SOURCE_INFO *cmd_source_info, char *format, ...);
+                     SOURCE_INFO *cmd_source_info, const char *format, ...);
 void bug_message (char *format, ...);
 char *prepare_error_line_message (ERROR_MESSAGE *error_message);
 
 void wipe_error_message_list (ERROR_MESSAGE_LIST *error_messages);
 void clear_error_message_list (ERROR_MESSAGE_LIST *error_messages);
 void message_list_command_error (ERROR_MESSAGE_LIST *error_messages,
-                                 const ELEMENT *e, char *format, ...);
+                                 const ELEMENT *e, const char *format, ...);
 void message_list_command_warn (ERROR_MESSAGE_LIST *error_messages,
-                                ELEMENT *e, char *format, ...);
+                                const ELEMENT *e, const char *format, ...);
 
 void message_list_document_error (ERROR_MESSAGE_LIST *error_messages,
                                   OPTIONS *conf,
-                                  char *format, ...);
+                                  const char *format, ...);
 void message_list_document_warn (ERROR_MESSAGE_LIST *error_messages,
                                  OPTIONS *conf,
-                                 char *format, ...);
+                                 const char *format, ...);
 
 extern ERROR_MESSAGE_LIST error_messages_list;
 extern SOURCE_INFO current_source_info;
diff --git a/tp/Texinfo/XS/main/extra.c b/tp/Texinfo/XS/main/extra.c
index f5dd58407d..53a0954621 100644
--- a/tp/Texinfo/XS/main/extra.c
+++ b/tp/Texinfo/XS/main/extra.c
@@ -28,7 +28,8 @@
 
 /* directly used in tree copy, but should not be directly used in general */
 KEY_PAIR *
-get_associated_info_key (ASSOCIATED_INFO *a, char *key, enum extra_type type)
+get_associated_info_key (ASSOCIATED_INFO *a, const char *key,
+                         const enum extra_type type)
 {
   int i;
   for (i = 0; i < a->info_number; i++)
@@ -101,7 +102,7 @@ add_info_element_oot (ELEMENT *e, char *key, ELEMENT *value)
 /* Add an extra key that is a reference to an array of other
    elements (for example, 'section_childs'). */
 void
-add_extra_contents (ELEMENT *e, char *key, ELEMENT_LIST *value)
+add_extra_contents (ELEMENT *e, const char *key, ELEMENT_LIST *value)
 {
   KEY_PAIR *k = get_associated_info_key (&e->extra_info, key,
                                          extra_contents);
@@ -116,7 +117,7 @@ add_extra_contents (ELEMENT *e, char *key, ELEMENT_LIST 
*value)
    NULL in contents for the first contents.number elements.
 */
 void
-add_extra_directions (ELEMENT *e, char *key, ELEMENT *value)
+add_extra_directions (ELEMENT *e, const char *key, ELEMENT *value)
 {
   element_set_empty_contents (value, directions_length);
   KEY_PAIR *k = get_associated_info_key (&e->extra_info, key,
@@ -161,7 +162,7 @@ add_info_string_dup (ELEMENT *e, char *key, char *value)
 }
 
 void
-add_associated_info_integer (ASSOCIATED_INFO *a, char *key, int value)
+add_associated_info_integer (ASSOCIATED_INFO *a, const char *key, int value)
 {
   KEY_PAIR *k = get_associated_info_key (a, key, extra_integer);
   k->integer = value;
@@ -175,7 +176,7 @@ add_extra_integer (ELEMENT *e, char *key, long value)
 }
 
 KEY_PAIR *
-lookup_associated_info (const ASSOCIATED_INFO *a, char *key)
+lookup_associated_info (const ASSOCIATED_INFO *a, const char *key)
 {
   int i;
   for (i = 0; i < a->info_number; i++)
@@ -190,7 +191,7 @@ lookup_associated_info (const ASSOCIATED_INFO *a, char *key)
 }
 
 ELEMENT *
-lookup_extra_element (const ELEMENT *e, char *key)
+lookup_extra_element (const ELEMENT *e, const char *key)
 {
   const KEY_PAIR *k;
   k = lookup_associated_info (&e->extra_info, key);
@@ -209,7 +210,7 @@ lookup_extra_element (const ELEMENT *e, char *key)
 }
 
 char *
-lookup_extra_string (const ELEMENT *e, char *key)
+lookup_extra_string (const ELEMENT *e, const char *key)
 {
   const KEY_PAIR *k;
   k = lookup_associated_info (&e->extra_info, key);
@@ -232,14 +233,14 @@ lookup_extra_string (const ELEMENT *e, char *key)
 }
 
 KEY_PAIR *
-lookup_extra (const ELEMENT *e, char *key)
+lookup_extra (const ELEMENT *e, const char *key)
 {
   return lookup_associated_info (&e->extra_info, key);
 }
 
 /* *ret is negative if not found or not an integer */
 int
-lookup_extra_integer (const ELEMENT *e, char *key, int *ret)
+lookup_extra_integer (const ELEMENT *e, const char *key, int *ret)
 {
   const KEY_PAIR *k;
   k = lookup_associated_info (&e->extra_info, key);
@@ -262,7 +263,7 @@ lookup_extra_integer (const ELEMENT *e, char *key, int *ret)
 
 /* if CREATE is true, create an extra contents element if there is none */
 ELEMENT_LIST *
-lookup_extra_contents (ELEMENT *e, char *key, int create)
+lookup_extra_contents (ELEMENT *e, const char *key, int create)
 {
   ELEMENT_LIST *e_list = 0;
   KEY_PAIR *k = lookup_extra (e, key);
@@ -288,7 +289,7 @@ lookup_extra_contents (ELEMENT *e, char *key, int create)
 
 /* if CREATE is true, create an extra directions element if there is none */
 ELEMENT *
-lookup_extra_directions (ELEMENT *e, char *key, int create)
+lookup_extra_directions (ELEMENT *e, const char *key, int create)
 {
   ELEMENT *contents_e;
   contents_e = lookup_extra_element (e, key);
@@ -301,7 +302,7 @@ lookup_extra_directions (ELEMENT *e, char *key, int create)
 }
 
 ELEMENT *
-lookup_info_element (const ELEMENT *e, char *key)
+lookup_info_element (const ELEMENT *e, const char *key)
 {
   const KEY_PAIR *k;
   k = lookup_associated_info (&e->info_info, key);
@@ -312,13 +313,13 @@ lookup_info_element (const ELEMENT *e, char *key)
 
 
 KEY_PAIR *
-lookup_info (const ELEMENT *e, char *key)
+lookup_info (const ELEMENT *e, const char *key)
 {
   return lookup_associated_info (&e->info_info, key);
 }
 
 char *
-lookup_info_string (const ELEMENT *e, char *key)
+lookup_info_string (const ELEMENT *e, const char *key)
 {
   const KEY_PAIR *k;
   k = lookup_associated_info (&e->info_info, key);
@@ -329,7 +330,8 @@ lookup_info_string (const ELEMENT *e, char *key)
 
 /* only called in tree copy to optimize for speed */
 KEY_PAIR *
-lookup_associated_info_by_index (const ASSOCIATED_INFO *a, char *key, int 
index)
+lookup_associated_info_by_index (const ASSOCIATED_INFO *a,
+                                 const char *key, int index)
 {
   if (index < 0)
     index = a->info_number + index;
@@ -344,7 +346,7 @@ lookup_associated_info_by_index (const ASSOCIATED_INFO *a, 
char *key, int index)
 }
 
 KEY_PAIR *
-lookup_extra_by_index (const ELEMENT *e, char *key, int index)
+lookup_extra_by_index (const ELEMENT *e, const char *key, int index)
 {
   return lookup_associated_info_by_index (&e->extra_info, key, index);
 }
diff --git a/tp/Texinfo/XS/main/extra.h b/tp/Texinfo/XS/main/extra.h
index d8daa15c5a..3480442b7e 100644
--- a/tp/Texinfo/XS/main/extra.h
+++ b/tp/Texinfo/XS/main/extra.h
@@ -21,9 +21,9 @@
 
 void add_extra_element (ELEMENT *e, char *key, ELEMENT *value);
 void add_extra_element_oot (ELEMENT *e, char *key, ELEMENT *value);
-void add_extra_contents (ELEMENT *e, char *key, ELEMENT_LIST *value);
+void add_extra_contents (ELEMENT *e, const char *key, ELEMENT_LIST *value);
 void add_extra_container (ELEMENT *e, char *key, ELEMENT *value);
-void add_extra_directions (ELEMENT *e, char *key, ELEMENT *value);
+void add_extra_directions (ELEMENT *e, const char *key, ELEMENT *value);
 void add_extra_text (ELEMENT *e, char *key, ELEMENT *value);
 void add_extra_misc_args (ELEMENT *e, char *key, ELEMENT *value);
 void add_extra_string (ELEMENT *e, char *key, char *value);
@@ -32,22 +32,23 @@ void add_extra_integer (ELEMENT *e, char *key, long value);
 void add_info_string (ELEMENT *e, char *key, char *value);
 void add_info_string_dup (ELEMENT *e, char *key, char *value);
 void add_info_element_oot (ELEMENT *e, char *key, ELEMENT *value);
-void add_associated_info_integer (ASSOCIATED_INFO *a, char *key, int value);
-KEY_PAIR *lookup_extra (const ELEMENT *e, char *key);
-KEY_PAIR *lookup_info (const ELEMENT *e, char *key);
-ELEMENT *lookup_extra_element (const ELEMENT *e, char *key);
-ELEMENT *lookup_info_element (const ELEMENT *e, char *key);
-ELEMENT_LIST *lookup_extra_contents (ELEMENT *e, char *key, int create);
-ELEMENT *lookup_extra_directions (ELEMENT *e, char *key, int create);
-int lookup_extra_integer (const ELEMENT *e, char *key, int *ret);
-char *lookup_extra_string (const ELEMENT *e, char *key);
-char *lookup_info_string (const ELEMENT *e, char *key);
-
-KEY_PAIR *lookup_associated_info (const ASSOCIATED_INFO *a, char *key);
+void add_associated_info_integer (ASSOCIATED_INFO *a,
+                                  const char *key, int value);
+KEY_PAIR *lookup_extra (const ELEMENT *e, const char *key);
+KEY_PAIR *lookup_info (const ELEMENT *e, const char *key);
+ELEMENT *lookup_extra_element (const ELEMENT *e, const char *key);
+ELEMENT *lookup_info_element (const ELEMENT *e, const char *key);
+ELEMENT_LIST *lookup_extra_contents (ELEMENT *e, const char *key, int create);
+ELEMENT *lookup_extra_directions (ELEMENT *e, const char *key, int create);
+int lookup_extra_integer (const ELEMENT *e, const char *key, int *ret);
+char *lookup_extra_string (const ELEMENT *e, const char *key);
+char *lookup_info_string (const ELEMENT *e, const char *key);
+
+KEY_PAIR *lookup_associated_info (const ASSOCIATED_INFO *a, const char *key);
 
 /* not to be used in general, only when using associated info
    as a temporary holder of information, for speed */
-KEY_PAIR *get_associated_info_key (ASSOCIATED_INFO *a, char *key,
-                                   enum extra_type type);
-KEY_PAIR *lookup_extra_by_index (const ELEMENT *e, char *key, int index);
+KEY_PAIR *get_associated_info_key (ASSOCIATED_INFO *a, const char *key,
+                                   const enum extra_type type);
+KEY_PAIR *lookup_extra_by_index (const ELEMENT *e, const char *key, int index);
 #endif
diff --git a/tp/Texinfo/XS/main/manipulate_tree.c 
b/tp/Texinfo/XS/main/manipulate_tree.c
index 316bd4f2bc..127e64625b 100644
--- a/tp/Texinfo/XS/main/manipulate_tree.c
+++ b/tp/Texinfo/XS/main/manipulate_tree.c
@@ -18,6 +18,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdbool.h>
+#include "uniconv.h"
+#include "unistr.h"
 
 #include "tree_types.h"
 #include "command_ids.h"
@@ -57,7 +60,7 @@ copy_associated_info (ASSOCIATED_INFO *info, ASSOCIATED_INFO* 
new_info)
   for (i = 0; i < info->info_number; i++)
     {
       KEY_PAIR *k_ref = &info->info[i];
-      char *key = k_ref->key;
+      const char *key = k_ref->key;
       ELEMENT *f = k_ref->element;
       ELEMENT *new_extra_element;
       ELEMENT_LIST *new_extra_contents;
@@ -218,7 +221,7 @@ associate_info_references (ASSOCIATED_INFO *info, 
ASSOCIATED_INFO *new_info)
   for (i = 0; i < info->info_number; i++)
     {
       KEY_PAIR *k_ref = &info->info[i];
-      char *key = k_ref->key;
+      const char *key = k_ref->key;
       ELEMENT *f = k_ref->element;
       ELEMENT *new_extra_element;
       int j;
@@ -768,6 +771,212 @@ parse_node_manual (ELEMENT *node, int modify_node)
   return result;
 }
 
+
+
+/* in Common.pm */
+ELEMENT *
+modify_tree (ELEMENT *tree,
+             ELEMENT_LIST *(*operation)(const char *type, ELEMENT *element, 
void* argument),
+             void *argument)
+{
+  if (tree->args.number > 0)
+    {
+      int i;
+      for (i = 0; i < tree->args.number; i++)
+        {
+          ELEMENT_LIST *new_args;
+          new_args = (*operation) ("arg", tree->args.list[i], argument);
+          if (new_args)
+            {
+              /* *operation should take care of destroying removed element */
+              remove_from_args (tree, i);
+              insert_list_slice_into_args (tree, i,
+                                           new_args, 0,
+                                           new_args->number);
+              i += new_args->number -1;
+              destroy_list (new_args);
+            }
+          else
+            modify_tree (tree->args.list[i], operation, argument);
+        }
+    }
+  if (tree->contents.number > 0)
+    {
+      int i;
+      for (i = 0; i < tree->contents.number; i++)
+        {
+          ELEMENT_LIST *new_contents;
+          new_contents = (*operation) ("content", tree->contents.list[i],
+                                       argument);
+          if (new_contents)
+            {
+              /* *operation should take care of destroying removed element */
+              remove_from_contents (tree, i);
+              insert_list_slice_into_contents (tree, i,
+                                              new_contents, 0,
+                                              new_contents->number);
+              i += new_contents->number -1;
+              destroy_list (new_contents);
+            }
+          else
+            modify_tree (tree->contents.list[i], operation, argument);
+        }
+    }
+  if (tree->source_mark_list.number > 0)
+    {
+      int i;
+      for (i = 0; i < tree->source_mark_list.number; i++)
+        {
+          if (tree->source_mark_list.list[i]->element)
+            {
+              ELEMENT_LIST *new_element;
+              new_element = (*operation) ("source_mark",
+                                     tree->source_mark_list.list[i]->element,
+                                          argument);
+              if (new_element)
+                {
+                  /* FIXME destroy previous element? or let (*operation)
+                     do it? */
+                  tree->source_mark_list.list[i]->element
+                      = new_element->list[0];
+                  destroy_list (new_element);
+                }
+            }
+        }
+    }
+  return tree;
+}
+
+ELEMENT *
+new_asis_command_with_text (char *text, ELEMENT *parent, enum element_type 
type)
+{
+  ELEMENT *new_command = new_element (ET_NONE);
+  ELEMENT *brace_command_arg = new_element (ET_brace_command_arg);
+  ELEMENT *text_elt = new_element (type);
+  new_command->cmd = CM_asis;
+  new_command->parent = parent;
+  add_to_element_args (new_command, brace_command_arg);
+  text_append (&text_elt->text, text);
+  add_to_element_contents (brace_command_arg, text_elt);
+  return new_command;
+}
+
+ELEMENT_LIST *
+protect_text (ELEMENT *current, char *to_protect)
+{
+  if (current->text.end > 0 && !(current->type == ET_raw
+                                 || current->type == ET_rawline_arg)
+      && strpbrk (current->text.text, to_protect))
+    {
+      ELEMENT_LIST *container = new_list();
+      char *p = current->text.text;
+      /* count UTF-8 encoded Unicode characters for source marks locations */
+      uint8_t *u8_text = 0;
+      size_t current_position;
+      uint8_t *u8_p = 0;
+      size_t u8_len;
+
+      if (current->source_mark_list.number)
+        {
+          u8_text = u8_strconv_from_encoding (p, "UTF-8",
+                                            iconveh_question_mark);
+          u8_p = u8_text;
+
+          current_position = 0;
+        }
+
+      while (*p)
+        {
+          int leading_nr = strcspn (p, to_protect);
+          ELEMENT *text_elt = new_element (current->type);
+          text_elt->parent = current->parent;
+          if (leading_nr)
+            {
+              text_append_n (&text_elt->text, p, leading_nr);
+              p += leading_nr;
+            }
+          /*
+          Note that it includes for completeness the case of leading_nr == 0
+          although it is unclear that source marks may happen in that case
+          as they are rather associated to the previous element.
+           */
+          if (u8_text)
+            {
+              u8_len = u8_mbsnlen (u8_p, leading_nr);
+              u8_p += u8_len;
+
+              current_position
+                = relocate_source_marks (&(current->source_mark_list),
+                                        text_elt,
+                                        current_position, u8_len);
+            }
+
+          if (leading_nr || text_elt->source_mark_list.number)
+            add_to_element_list (container, text_elt);
+          else
+            destroy_element (text_elt);
+
+          if (*p)
+            {
+              int to_protect_nr = strspn (p, to_protect);
+              if (!strcmp (to_protect, ","))
+                {
+                  int i;
+                  for (i = 0; i < to_protect_nr; i++)
+                    {
+                      ELEMENT *comma = new_element (ET_NONE);
+                      ELEMENT *brace_command_arg
+                           = new_element (ET_brace_command_arg);
+                      comma->cmd = CM_comma;
+                      comma->parent = current->parent;
+                      add_to_element_args (comma, brace_command_arg);
+                      add_to_element_list (container, comma);
+                      if (u8_text)
+                        {
+                          u8_len = u8_mbsnlen (u8_p, 1);
+                          u8_p += u8_len;
+
+                        current_position
+                          = relocate_source_marks 
(&(current->source_mark_list),
+                                                   comma,
+                                                   current_position, u8_len);
+                        }
+                    }
+                  p += to_protect_nr;
+                }
+              else
+                {
+                  ELEMENT *new_command;
+                  char saved = p[to_protect_nr];
+                  p[to_protect_nr] = '\0';
+                  new_command = new_asis_command_with_text(p, current->parent,
+                                                           current->type);
+                  add_to_element_list (container, new_command);
+                  if (u8_text)
+                    {
+                      u8_len = u8_mbsnlen (u8_p, to_protect_nr);
+                      u8_p += u8_len;
+
+                      current_position
+                       = relocate_source_marks (&(current->source_mark_list),
+                                new_command->args.list[0]->contents.list[0],
+                                              current_position, u8_len);
+                    }
+                  p += to_protect_nr;
+                  *p = saved;
+                }
+            }
+        }
+      free (u8_text);
+      destroy_element (current);
+      return container;
+    }
+  else
+    return 0;
+}
+
+
+
 char *
 normalized_menu_entry_internal_node (ELEMENT *entry)
 {
diff --git a/tp/Texinfo/XS/main/manipulate_tree.h 
b/tp/Texinfo/XS/main/manipulate_tree.h
index 157726cb15..10bb0451d3 100644
--- a/tp/Texinfo/XS/main/manipulate_tree.h
+++ b/tp/Texinfo/XS/main/manipulate_tree.h
@@ -36,6 +36,17 @@ NODE_SPEC_EXTRA *parse_node_manual (ELEMENT *node, int 
modify_node);
 
 
 
+ELEMENT *modify_tree (ELEMENT *tree,
+ ELEMENT_LIST *(*operation)(const char *type, ELEMENT *element, void* 
argument),
+                      void *argument);
+
+ELEMENT *new_asis_command_with_text (char *text, ELEMENT *parent,
+                                     enum element_type type);
+
+ELEMENT_LIST *protect_text (ELEMENT *current, char *to_protect);
+
+
+
 char *normalized_menu_entry_internal_node (ELEMENT *entry);
 ELEMENT *normalized_entry_associated_internal_node (ELEMENT *entry,
                                                     LABEL_LIST 
*identifiers_target);
diff --git a/tp/Texinfo/XS/main/output_unit.c b/tp/Texinfo/XS/main/output_unit.c
index 30d048817a..6bda1d1567 100644
--- a/tp/Texinfo/XS/main/output_unit.c
+++ b/tp/Texinfo/XS/main/output_unit.c
@@ -149,12 +149,14 @@ split_by_node (ELEMENT *root)
   for (i = 0; i < root->contents.number; i++)
     {
       ELEMENT *content = root->contents.list[i];
-      if (content->cmd == CM_part)
+      enum command_id data_cmd = element_builtin_data_cmd (content);
+
+      if (data_cmd == CM_part)
         {
           add_to_element_list (pending_parts, content);
           continue;
         }
-      if (content->cmd == CM_node)
+      if (data_cmd == CM_node)
         {
           if (!current->unit_command)
             current->unit_command = content;
@@ -215,23 +217,25 @@ split_by_section (ELEMENT *root)
   for (i = 0; i < root->contents.number; i++)
     {
       ELEMENT *content = root->contents.list[i];
+      enum command_id data_cmd = element_builtin_data_cmd (content);
+      unsigned long flags = builtin_command_data[data_cmd].flags;
+
       ELEMENT *new_section = 0;
-      if (content->cmd == CM_node)
+      if (data_cmd == CM_node)
         {
           ELEMENT *associated_section
             = lookup_extra_element (content, "associated_section");
           if (associated_section)
             new_section = associated_section;
         }
-      else if (content->cmd == CM_part)
+      else if (data_cmd == CM_part)
         {
           ELEMENT *part_associated_section
             = lookup_extra_element (content, "part_associated_section");
           if (part_associated_section)
             new_section = part_associated_section;
         }
-      if (!new_section && content->cmd != CM_node
-          && (CF_root & builtin_command_flags(content)))
+      if (!new_section && data_cmd != CM_node && (CF_root & flags))
         {
           new_section = content;
         }
diff --git a/tp/Texinfo/XS/main/tree_types.h b/tp/Texinfo/XS/main/tree_types.h
index a288f74611..0577a36046 100644
--- a/tp/Texinfo/XS/main/tree_types.h
+++ b/tp/Texinfo/XS/main/tree_types.h
@@ -116,7 +116,7 @@ typedef struct ELEMENT_LIST {
 } ELEMENT_LIST;
 
 typedef struct KEY_PAIR {
-    char *key;
+    const char *key;
     enum extra_type type;
     union {
       struct ELEMENT *element;
diff --git a/tp/Texinfo/XS/main/unicode.c b/tp/Texinfo/XS/main/unicode.c
index 66378f6543..2095f0d1f4 100644
--- a/tp/Texinfo/XS/main/unicode.c
+++ b/tp/Texinfo/XS/main/unicode.c
@@ -162,7 +162,7 @@ unicode_accent (const char *text, const ELEMENT *e)
   return result;
 }
 
-int
+static int
 compare_strings (const void *a, const void *b)
 {
   const char **str_a = (const char **) a;
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index 3298e5e377..48f64da00f 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -42,7 +42,6 @@
 #include "builtin_commands.h"
 #include "utils.h"
 
-#include "cmd_structuring.c"
 #include "options_init_free.c"
 
 #define min_level command_structuring_level[CM_chapter]
@@ -894,7 +893,7 @@ get_cmd_global_uniq_command (GLOBAL_COMMANDS 
*global_commands_ref,
 }
 
 char *
-informative_command_value (ELEMENT *element)
+informative_command_value (const ELEMENT *element)
 {
   ELEMENT *misc_args;
   char *text_arg;
@@ -944,8 +943,8 @@ informative_command_value (ELEMENT *element)
   return 0;
 }
 
-static void
-set_informative_command_value (OPTIONS *options, ELEMENT *element)
+void
+set_informative_command_value (OPTIONS *options, const ELEMENT *element)
 {
   char *value = 0;
   enum command_id cmd = element_builtin_cmd (element);
@@ -1078,32 +1077,6 @@ new_options (void)
 }
 
 
-/* accents/elements stacks */
-void
-push_stack_element (ELEMENT_STACK *stack, const ELEMENT *e)
-{
-  if (stack->top >= stack->space)
-    {
-      stack->stack
-        = realloc (stack->stack,
-                   (stack->space += 5) * sizeof (ELEMENT *));
-    }
-
-  stack->stack[stack->top] = e;
-  stack->top++;
-}
-
-/* currently unused */
-const ELEMENT *
-pop_stack_element (ELEMENT_STACK *stack)
-{
-  if (stack->top == 0)
-    fatal ("element stack empty");
-
-  stack->top--;
-  return stack->stack[stack->top +1];
-}
-
 void
 destroy_accent_stack (ACCENTS_STACK *accent_stack)
 {
@@ -1140,6 +1113,27 @@ section_level (const ELEMENT *section)
   return level;
 }
 
+enum command_id
+section_level_adjusted_command_name (const ELEMENT *element)
+{
+  int status;
+  int heading_level;
+
+  heading_level = lookup_extra_integer (element, "section_level", &status);
+
+  if (status < 0)
+    {
+      bug ("section_level_adjusted_command_name: "
+           "unexpected missing section level");
+    }
+
+  if (command_structuring_level[element->cmd] != heading_level)
+    {
+      return level_to_structuring_command[element->cmd][heading_level];
+    }
+  return element->cmd;
+}
+
 /* corresponding perl function in Common.pm */
 int
 is_content_empty (ELEMENT *tree, int do_not_ignore_index_entries)
@@ -1151,8 +1145,13 @@ is_content_empty (ELEMENT *tree, int 
do_not_ignore_index_entries)
   for (i = 0; i < tree->contents.number; i++)
     {
       ELEMENT *content = tree->contents.list[i];
-      if (content->cmd)
+      enum command_id data_cmd = element_builtin_data_cmd (content);
+
+      if (data_cmd)
         {
+          unsigned long flags = builtin_command_data[data_cmd].flags;
+          unsigned long other_flags
+               = builtin_command_data[data_cmd].other_flags;
           if (content->type == ET_index_entry_command)
             {
               if (do_not_ignore_index_entries)
@@ -1160,23 +1159,24 @@ is_content_empty (ELEMENT *tree, int 
do_not_ignore_index_entries)
               else
                continue;
             }
-          if (builtin_command_flags(content) & CF_line)
+
+          if (flags & CF_line)
             {
-              if (command_other_flags(content) & CF_formatted_line
-                  || command_other_flags(content) & CF_formattable_line)
+              if (other_flags & CF_formatted_line
+                  || other_flags & CF_formattable_line)
                 return 0;
               else
                 continue;
             }
-          else if (builtin_command_flags(content) & CF_nobrace)
+          else if (flags & CF_nobrace)
             {
-              if (command_other_flags(content) & CF_formatted_nobrace)
+              if (other_flags & CF_formatted_nobrace)
                 return 0;
               else
                 continue;
             }
-          else if (command_other_flags(content) & CF_non_formatted_brace
-                   || command_other_flags(content) & CF_non_formatted_block)
+          else if (other_flags & CF_non_formatted_brace
+                   || other_flags & CF_non_formatted_block)
             continue;
           else
             return 0;
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index 16a067dac5..bc556122cd 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -131,8 +131,8 @@ enum command_location {
 
 /* HTML modified state flags */
 #define HMSF_current_root            0x0001
+#define HMSF_shared_conversion_state_integer  0x0002
 /*
-#define HMSF_        0x0002
 #define HMSF_      0x0004
 #define HMSF_     0x0008
 #define HMSF_    0x0010
@@ -172,12 +172,6 @@ typedef struct FILE_SOURCE_INFO_LIST {
 
 extern const char *html_argument_formatting_type_names[];
 
-typedef struct ELEMENT_STACK {
-    const ELEMENT **stack;
-    size_t top;
-    size_t space;
-} ELEMENT_STACK;
-
 typedef struct ACCENTS_STACK {
     ELEMENT_STACK stack;
     ELEMENT *argument;
@@ -208,6 +202,7 @@ INDEX *indices_info_index_by_name (INDEX 
**indices_information, char *name);
 INDEX *ultimate_index (INDEX *index);
 char *read_flag_name (char **ptr);
 int section_level (const ELEMENT *section);
+enum command_id section_level_adjusted_command_name (const ELEMENT *element);
 char *collapse_spaces (char *text);
 char *parse_line_directive (char *line, int *retval, int *out_line_no);
 int is_content_empty (ELEMENT *tree, int do_not_ignore_index_entries);
@@ -219,8 +214,6 @@ void add_string (const char *string, STRING_LIST 
*strings_list);
 void merge_strings (STRING_LIST *strings_list, STRING_LIST *merged_strings);
 size_t find_string (STRING_LIST *strings_list, const char *string);
 
-void push_stack_element (ELEMENT_STACK *stack, const ELEMENT *e);
-const ELEMENT *pop_stack_element (ELEMENT_STACK *stack);
 void destroy_accent_stack (ACCENTS_STACK *accent_stack);
 
 void wipe_index (INDEX *idx);
@@ -254,7 +247,8 @@ char *enumerate_item_representation (char *specification, 
int number);
 ELEMENT *get_global_document_command (GLOBAL_COMMANDS *global_commands,
                                       enum command_id cmd,
                                       enum command_location command_location);
-char *informative_command_value (ELEMENT *element);
+char *informative_command_value (const ELEMENT *element);
+void set_informative_command_value (OPTIONS *options, const ELEMENT *element);
 ELEMENT *set_global_document_command (GLOBAL_COMMANDS *global_commands,
                              OPTIONS *options, enum command_id cmd,
                              enum command_location command_location);
diff --git a/tp/Texinfo/XS/structuring_transfo/structuring.c 
b/tp/Texinfo/XS/structuring_transfo/structuring.c
index 6dd321c026..a054a1a61f 100644
--- a/tp/Texinfo/XS/structuring_transfo/structuring.c
+++ b/tp/Texinfo/XS/structuring_transfo/structuring.c
@@ -33,12 +33,11 @@
 /* for get_label_element section_level enumerate_item_representation
    xasprintf */
 #include "utils.h"
-/* for copy_tree copy_contents and parse_node_manual */
+/* for copy_tree copy_contents parse_node_manual modify_tree protect_text */
 #include "manipulate_tree.h"
 #include "node_name_normalization.h"
 #include "convert_to_texinfo.h"
 #include "targets.h"
-#include "transformations.h"
 #include "translations.h"
 #include "structuring.h"
 
@@ -551,7 +550,7 @@ register_referenced_node (ELEMENT *node, char 
**referenced_identifiers,
   return referenced_identifiers;
 }
 
-int
+static int
 compare_strings (const void *a, const void *b)
 {
   const char **str_a = (const char **) a;
@@ -1986,3 +1985,55 @@ new_master_menu (OPTIONS *options, LABEL_LIST 
*identifiers_target,
     }
 }
 
+ELEMENT_LIST *
+protect_colon (const char *type, ELEMENT *current, void *argument)
+{
+  return protect_text(current, ":");
+}
+
+ELEMENT *
+protect_colon_in_tree (ELEMENT *tree)
+{
+  return modify_tree (tree, &protect_colon, 0);
+}
+
+ELEMENT *
+new_complete_menu_master_menu (OPTIONS *options,
+                               LABEL_LIST *identifiers_target,
+                               ELEMENT *node)
+{
+  ELEMENT *menu_node = new_complete_node_menu (node, 0);
+
+  if (menu_node)
+    {
+      char *normalized = lookup_extra_string (node, "normalized");
+      ELEMENT *associated_section
+          = lookup_extra_element (node, "associated_section");
+      if (normalized && !strcmp (normalized, "Top")
+          && associated_section && associated_section->cmd == CM_top)
+        {
+          ELEMENT_LIST *menus = new_list ();
+          ELEMENT *detailmenu;
+
+          add_to_element_list (menus, menu_node);
+          detailmenu = new_master_menu (options, identifiers_target,
+                                        menus, 0);
+          if (detailmenu)
+            {
+              /* add a blank line before the detailed node listing */
+              ELEMENT *menu_comment = new_element (ET_menu_comment);
+              ELEMENT *preformatted = new_element (ET_preformatted);
+              ELEMENT *empty_line
+                 = new_element (ET_after_menu_description_line);
+
+              add_to_element_contents (menu_node, menu_comment);
+              add_to_element_contents (menu_comment, preformatted);
+              text_append_n (&empty_line->text, "\n", 1);
+              add_to_element_contents (preformatted, empty_line);
+
+              add_to_element_contents (menu_node, detailmenu);
+            }
+        }
+    }
+  return menu_node;
+}
diff --git a/tp/Texinfo/XS/structuring_transfo/structuring.h 
b/tp/Texinfo/XS/structuring_transfo/structuring.h
index 97cc7be30b..7d2c84e194 100644
--- a/tp/Texinfo/XS/structuring_transfo/structuring.h
+++ b/tp/Texinfo/XS/structuring_transfo/structuring.h
@@ -23,5 +23,9 @@ void new_block_command (ELEMENT *element, enum command_id 
cmd);
 ELEMENT *new_master_menu (OPTIONS *options, LABEL_LIST *identifiers_target,
                           ELEMENT_LIST *menus, int use_sections);
 
+ELEMENT *new_complete_menu_master_menu (OPTIONS *options,
+                                        LABEL_LIST *identifiers_target,
+                                        ELEMENT *node);
+ELEMENT *protect_colon_in_tree (ELEMENT *tree);
 
 #endif
diff --git a/tp/Texinfo/XS/structuring_transfo/transformations.c 
b/tp/Texinfo/XS/structuring_transfo/transformations.c
index 1d6f3ad6de..19a3f934b2 100644
--- a/tp/Texinfo/XS/structuring_transfo/transformations.c
+++ b/tp/Texinfo/XS/structuring_transfo/transformations.c
@@ -37,7 +37,8 @@
 #include "errors.h"
 #include "debug.h"
 #include "utils.h"
-/* for copy_contents normalized_menu_entry_internal_node */
+/* for copy_contents normalized_menu_entry_internal_node modify_tree
+   protect_text new_asis_command_with_text */
 #include "manipulate_tree.h"
 #include "structuring.h"
 #include "convert_to_texinfo.h"
@@ -73,20 +74,6 @@ lookup_index_entry (ELEMENT *index_entry_info, INDEX 
**indices_information)
   return result;
 }
 
-ELEMENT *
-new_asis_command_with_text (char *text, ELEMENT *parent, enum element_type 
type)
-{
-  ELEMENT *new_command = new_element (ET_NONE);
-  ELEMENT *brace_command_arg = new_element (ET_brace_command_arg);
-  ELEMENT *text_elt = new_element (type);
-  new_command->cmd = CM_asis;
-  new_command->parent = parent;
-  add_to_element_args (new_command, brace_command_arg);
-  text_append (&text_elt->text, text);
-  add_to_element_contents (brace_command_arg, text_elt);
-  return new_command;
-}
-
 void
 protect_first_parenthesis (ELEMENT *element)
 {
@@ -168,80 +155,6 @@ protect_first_parenthesis (ELEMENT *element)
     }
 }
 
-/* in Common.pm */
-ELEMENT *
-modify_tree (ELEMENT *tree,
-             ELEMENT_LIST *(*operation)(const char *type, ELEMENT *element, 
void* argument),
-             void *argument)
-{
-  if (tree->args.number > 0)
-    {
-      int i;
-      for (i = 0; i < tree->args.number; i++)
-        {
-          ELEMENT_LIST *new_args;
-          new_args = (*operation) ("arg", tree->args.list[i], argument);
-          if (new_args)
-            {
-              /* *operation should take care of destroying removed element */
-              remove_from_args (tree, i);
-              insert_list_slice_into_args (tree, i,
-                                           new_args, 0,
-                                           new_args->number);
-              i += new_args->number -1;
-              destroy_list (new_args);
-            }
-          else
-            modify_tree (tree->args.list[i], operation, argument);
-        }
-    }
-  if (tree->contents.number > 0)
-    {
-      int i;
-      for (i = 0; i < tree->contents.number; i++)
-        {
-          ELEMENT_LIST *new_contents;
-          new_contents = (*operation) ("content", tree->contents.list[i],
-                                       argument);
-          if (new_contents)
-            {
-              /* *operation should take care of destroying removed element */
-              remove_from_contents (tree, i);
-              insert_list_slice_into_contents (tree, i,
-                                              new_contents, 0,
-                                              new_contents->number);
-              i += new_contents->number -1;
-              destroy_list (new_contents);
-            }
-          else
-            modify_tree (tree->contents.list[i], operation, argument);
-        }
-    }
-  if (tree->source_mark_list.number > 0)
-    {
-      int i;
-      for (i = 0; i < tree->source_mark_list.number; i++)
-        {
-          if (tree->source_mark_list.list[i]->element)
-            {
-              ELEMENT_LIST *new_element;
-              new_element = (*operation) ("source_mark",
-                                     tree->source_mark_list.list[i]->element,
-                                          argument);
-              if (new_element)
-                {
-                  /* FIXME destroy previous element? or let (*operation)
-                     do it? */
-                  tree->source_mark_list.list[i]->element
-                      = new_element->list[0];
-                  destroy_list (new_element);
-                }
-            }
-        }
-    }
-  return tree;
-}
-
 /* Add raise/lowersections to be back at the normal level from
    the SECTION level.  The raise/lowersections are added at the
    end of PARENT.
@@ -292,8 +205,10 @@ fill_gaps_in_sectioning (ELEMENT *root, ELEMENT 
*commands_heading_content)
   while (idx < root->contents.number)
     {
       ELEMENT *content = root->contents.list[idx];
-      if (!content->cmd || content->cmd == CM_node
-          || !(CF_root & builtin_command_flags(content)))
+      enum command_id data_cmd = element_builtin_data_cmd (content);
+      unsigned long flags = builtin_command_data[data_cmd].flags;
+
+      if (!data_cmd || data_cmd == CM_node || !(CF_root & flags))
         {
         }
       else if (idx_current_section < 0)
@@ -386,8 +301,10 @@ fill_gaps_in_sectioning (ELEMENT *root, ELEMENT 
*commands_heading_content)
       while (idx_next_section < root->contents.number)
         {
           ELEMENT *content = root->contents.list[idx_next_section];
-          if (content->cmd && content->cmd != CM_node
-              && (CF_root & builtin_command_flags(content)))
+          enum command_id data_cmd = element_builtin_data_cmd (content);
+          unsigned long flags = builtin_command_data[data_cmd].flags;
+
+          if (data_cmd && data_cmd != CM_node && (CF_root & flags))
             break;
           idx_next_section++;
         }
@@ -832,9 +749,11 @@ insert_nodes_for_sectioning_commands (DOCUMENT *document)
   for (idx = 0; idx < root->contents.number; idx++)
     {
       ELEMENT *content = root->contents.list[idx];
-      if (content->cmd && content->cmd != CM_node
-          && content->cmd != CM_part
-          && builtin_command_flags(content) & CF_root)
+      enum command_id data_cmd = element_builtin_data_cmd (content);
+      unsigned long flags = builtin_command_data[data_cmd].flags;
+
+      if (data_cmd && data_cmd != CM_node && data_cmd != CM_part
+          && flags & CF_root)
         {
           ELEMENT *associated_node = lookup_extra_element (content,
                                                  "associated_node");
@@ -1311,132 +1230,6 @@ regenerate_master_menu (DOCUMENT *document, int 
use_sections)
   return 1;
 }
 
-ELEMENT_LIST *
-protect_text (ELEMENT *current, char *to_protect)
-{
-  if (current->text.end > 0 && !(current->type == ET_raw
-                                 || current->type == ET_rawline_arg)
-      && strpbrk (current->text.text, to_protect))
-    {
-      ELEMENT_LIST *container = new_list();
-      char *p = current->text.text;
-      /* count UTF-8 encoded Unicode characters for source marks locations */
-      uint8_t *u8_text = 0;
-      size_t current_position;
-      uint8_t *u8_p = 0;
-      size_t u8_len;
-
-      if (current->source_mark_list.number)
-        {
-          u8_text = u8_strconv_from_encoding (p, "UTF-8",
-                                            iconveh_question_mark);
-          u8_p = u8_text;
-
-          current_position = 0;
-        }
-
-      while (*p)
-        {
-          int leading_nr = strcspn (p, to_protect);
-          ELEMENT *text_elt = new_element (current->type);
-          text_elt->parent = current->parent;
-          if (leading_nr)
-            {
-              text_append_n (&text_elt->text, p, leading_nr);
-              p += leading_nr;
-            }
-          /*
-          Note that it includes for completeness the case of leading_nr == 0
-          although it is unclear that source marks may happen in that case
-          as they are rather associated to the previous element.
-           */
-          if (u8_text)
-            {
-              u8_len = u8_mbsnlen (u8_p, leading_nr);
-              u8_p += u8_len;
-
-              current_position
-                = relocate_source_marks (&(current->source_mark_list),
-                                        text_elt,
-                                        current_position, u8_len);
-            }
-
-          if (leading_nr || text_elt->source_mark_list.number)
-            add_to_element_list (container, text_elt);
-          else
-            destroy_element (text_elt);
-
-          if (*p)
-            {
-              int to_protect_nr = strspn (p, to_protect);
-              if (!strcmp (to_protect, ","))
-                {
-                  int i;
-                  for (i = 0; i < to_protect_nr; i++)
-                    {
-                      ELEMENT *comma = new_element (ET_NONE);
-                      ELEMENT *brace_command_arg
-                           = new_element (ET_brace_command_arg);
-                      comma->cmd = CM_comma;
-                      comma->parent = current->parent;
-                      add_to_element_args (comma, brace_command_arg);
-                      add_to_element_list (container, comma);
-                      if (u8_text)
-                        {
-                          u8_len = u8_mbsnlen (u8_p, 1);
-                          u8_p += u8_len;
-
-                        current_position
-                          = relocate_source_marks 
(&(current->source_mark_list),
-                                                   comma,
-                                                   current_position, u8_len);
-                        }
-                    }
-                  p += to_protect_nr;
-                }
-              else
-                {
-                  ELEMENT *new_command;
-                  char saved = p[to_protect_nr];
-                  p[to_protect_nr] = '\0';
-                  new_command = new_asis_command_with_text(p, current->parent,
-                                                           current->type);
-                  add_to_element_list (container, new_command);
-                  if (u8_text)
-                    {
-                      u8_len = u8_mbsnlen (u8_p, to_protect_nr);
-                      u8_p += u8_len;
-
-                      current_position
-                       = relocate_source_marks (&(current->source_mark_list),
-                                new_command->args.list[0]->contents.list[0],
-                                              current_position, u8_len);
-                    }
-                  p += to_protect_nr;
-                  *p = saved;
-                }
-            }
-        }
-      free (u8_text);
-      destroy_element (current);
-      return container;
-    }
-  else
-    return 0;
-}
-
-ELEMENT_LIST *
-protect_colon (const char *type, ELEMENT *current, void *argument)
-{
-  return protect_text(current, ":");
-}
-
-ELEMENT *
-protect_colon_in_tree (ELEMENT *tree)
-{
-  return modify_tree (tree, &protect_colon, 0);
-}
-
 ELEMENT_LIST *
 protect_comma (const char *type, ELEMENT *current, void *argument)
 {
diff --git a/tp/Texinfo/XS/structuring_transfo/transformations.h 
b/tp/Texinfo/XS/structuring_transfo/transformations.h
index 7f136b4117..5b6b0a21d5 100644
--- a/tp/Texinfo/XS/structuring_transfo/transformations.h
+++ b/tp/Texinfo/XS/structuring_transfo/transformations.h
@@ -11,7 +11,6 @@ void relate_index_entries_to_table_items_in_tree (ELEMENT 
*tree,
                                     INDEX **indices_information);
 void move_index_entries_after_items_in_tree (ELEMENT *tree);
 ELEMENT *reference_to_arg_in_tree (ELEMENT *tree);
-ELEMENT *protect_colon_in_tree (ELEMENT *tree);
 ELEMENT *protect_comma_in_tree (ELEMENT *tree);
 ELEMENT *protect_node_after_label_in_tree (ELEMENT *tree);
 void complete_tree_nodes_menus (ELEMENT *root, int use_sections);
diff --git a/tp/maintain/setup_converters_code_tables.pl 
b/tp/maintain/setup_converters_code_tables.pl
index e1b9971cd8..f2bcf013fb 100755
--- a/tp/maintain/setup_converters_code_tables.pl
+++ b/tp/maintain/setup_converters_code_tables.pl
@@ -202,6 +202,7 @@ my %level_to_structuring_command
 
 open (STRUC, '>', $structuring_file) or die "Open $structuring_file: $!\n";
 
+print STRUC "#include \"command_ids.h\"\n\n";
 print STRUC "int command_structuring_level[] = {\n";
 foreach my $command_name (@commands_order) {
   my $command = $command_name;



reply via email to

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