texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Tue, 24 Dec 2024 10:27:07 -0500 (EST)

branch: master
commit 8e028ba7d6e2f7554d5308d4c40fb12541f251bb
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sun Nov 24 12:58:07 2024 +0100

    * tp/Texinfo/Convert/Texinfo.pm (_convert_to_texinfo, _convert_args),
    tp/Texinfo/XS/main/convert_to_texinfo.c (convert_args)
    (convert_to_texinfo_internal): add convert_args for expansion of
    arguments separated by commas.
    
    * tp/Texinfo/Convert/Texinfo.pm (_convert_to_texinfo),
    tp/Texinfo/XS/main/convert_to_texinfo.c (convert_to_texinfo_internal):
    change conditions to group more by type of commands.
---
 ChangeLog                               |  11 +++
 tp/Texinfo/Convert/Texinfo.pm           | 135 +++++++++++++++++++-------------
 tp/Texinfo/XS/main/convert_to_texinfo.c | 122 ++++++++++++++---------------
 tp/Texinfo/command_data.txt             |   1 +
 4 files changed, 152 insertions(+), 117 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5332766de9..482284ef95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2024-11-24  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Convert/Texinfo.pm (_convert_to_texinfo, _convert_args),
+       tp/Texinfo/XS/main/convert_to_texinfo.c (convert_args)
+       (convert_to_texinfo_internal): add convert_args for expansion of
+       arguments separated by commas.
+
+       * tp/Texinfo/Convert/Texinfo.pm (_convert_to_texinfo),
+       tp/Texinfo/XS/main/convert_to_texinfo.c (convert_to_texinfo_internal):
+       change conditions to group more by type of commands.
+
 2024-11-23  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/Text.pm (_convert): check line_commands instead
diff --git a/tp/Texinfo/Convert/Texinfo.pm b/tp/Texinfo/Convert/Texinfo.pm
index f51c3439f0..55ef6382ed 100644
--- a/tp/Texinfo/Convert/Texinfo.pm
+++ b/tp/Texinfo/Convert/Texinfo.pm
@@ -74,6 +74,8 @@ my %brace_commands           = 
%Texinfo::Commands::brace_commands;
 my %root_commands            = %Texinfo::Commands::root_commands;
 my %block_commands           = %Texinfo::Commands::block_commands;
 my %def_commands             = %Texinfo::Commands::def_commands;
+my %nobrace_commands         = %Texinfo::Commands::nobrace_commands;
+my %line_commands            = %Texinfo::Commands::line_commands;
 
 # used in root_heading_command_to_texinfo
 my %sectioning_heading_commands = 
%Texinfo::Commands::sectioning_heading_commands;
@@ -185,9 +187,26 @@ sub root_heading_command_to_texinfo($)
   }
 }
 
+sub _convert_to_texinfo($);
+
+# convert ELEMENT contents as comma separated arguments
+sub _convert_args($)
+{
+  my $element = shift;
+
+  my $result = '';
+  my $arg_nr = 0;
+  foreach my $arg (@{$element->{'contents'}}) {
+    next if ($arg->{'info'} and $arg->{'info'}->{'inserted'});
+    $result .= ',' if ($arg_nr);
+    $arg_nr++;
+    $result .= _convert_to_texinfo($arg);
+  }
+  return $result;
+}
+
 # Following subroutines deal with transforming a texinfo tree into texinfo
 # text.  Should give the text that was used parsed, except for a few cases.
-
 sub _convert_to_texinfo($)
 {
   my $element = shift;
@@ -203,49 +222,63 @@ sub _convert_to_texinfo($)
   if (defined($element->{'text'})) {
     $result .= $element->{'text'};
   } else {
-    if ($element->{'cmdname'}) {
-      my $cmdname;
-      if (! defined($element->{'cmdname'})) {
-        $cmdname = '';
+    if (defined($element->{'cmdname'})) {
+      my $cmdname = $element->{'cmdname'};
+      my $data_cmdname;
+      if ($cmdname eq 'item' and $element->{'contents'}
+          and $element->{'contents'}->[0]->{'type'}
+          and $element->{'contents'}->[0]->{'type'} eq 'line_arg') {
+        $data_cmdname = 'item_LINE';
       } else {
-        $cmdname = $element->{'cmdname'};
-        $result .= '@'.$cmdname;
-
-        # this is done here otherwise for some constructs, there are
-        # no arguments and the space is not output.
-        if ($element->{'info'}
-            and $element->{'info'}->{'spaces_after_cmd_before_arg'}) {
-            $result
-             .= $element->{'info'}->{'spaces_after_cmd_before_arg'}->{'text'};
-        }
+        $data_cmdname = $cmdname;
+      }
+
+      $result .= '@'.$cmdname;
+
+      if ($element->{'info'}
+          and $element->{'info'}->{'spaces_after_cmd_before_arg'}) {
+          $result
+           .= $element->{'info'}->{'spaces_after_cmd_before_arg'}->{'text'};
       }
-      # arg_line set for line_commands with type special and @macro
-      if ($element->{'info'} and defined($element->{'info'}->{'arg_line'})) {
-        $result .= $element->{'info'}->{'spaces_before_argument'}->{'text'}
-          if $element->{'info'} and 
$element->{'info'}->{'spaces_before_argument'};
+
+      my $spc_before_arg = '';
+      if ($element->{'info'}
+          and $element->{'info'}->{'spaces_before_argument'}) {
+        $spc_before_arg
+          = $element->{'info'}->{'spaces_before_argument'}->{'text'};
+      }
+
+      if ($nobrace_commands{$data_cmdname}) {
+        # the spaces following a command are put in a text element in the
+        # tree, not associated to the command element.
+        # item, tab and headitem are nobrace commands with contents
+        return $result if (!$element->{'contents'});
+     # arg_line set for line_commands with type lineraw that have
+     # arguments and for @macro.
+     # if there is no arg_line, the end of line is in rawline_arg in contents
+     # so the lineraw command should be processed along with other
+     # line commands below
+      } elsif ($element->{'info'} and 
defined($element->{'info'}->{'arg_line'})) {
+        $result .= $spc_before_arg;
         $result .= $element->{'info'}->{'arg_line'};
         if (!$block_commands{$cmdname}) {
           return $result;
         }
-      } elsif ($element->{'contents'}
-               and (exists($brace_commands{$cmdname})
-                    or ($element->{'type'}
-                        and $element->{'type'} eq 'definfoenclose_command'))) {
+      } elsif (exists($brace_commands{$cmdname})
+               or ($element->{'type'}
+                   and $element->{'type'} eq 'definfoenclose_command')) {
+        # contents may not be set for a command without braces.  In that
+        # case it is better if the command is considered as a command without
+        # argument.
+        return $result if (!$element->{'contents'});
         my $braces = 1;
         $braces = 0 if ($element->{'contents'}->[0]->{'type'} eq 
'following_arg');
         $result .= '{' if ($braces);
         if ($cmdname eq 'verb') {
           $result .= $element->{'info'}->{'delimiter'};
         }
-        $result .= $element->{'info'}->{'spaces_before_argument'}->{'text'}
-          if ($element->{'info'} and 
$element->{'info'}->{'spaces_before_argument'});
-        my $arg_nr = 0;
-        foreach my $arg (@{$element->{'contents'}}) {
-          next if ($arg->{'info'} and $arg->{'info'}->{'inserted'});
-          $result .= ',' if ($arg_nr);
-          $arg_nr++;
-          $result .= _convert_to_texinfo($arg);
-        }
+        $result .= $spc_before_arg;
+        $result .= _convert_args($element);
         if ($cmdname eq 'verb') {
           $result .= $element->{'info'}->{'delimiter'};
         }
@@ -254,33 +287,21 @@ sub _convert_to_texinfo($)
       } elsif ($element->{'contents'}
                and ($element->{'contents'}->[0]->{'type'}
                     and $element->{'contents'}->[0]->{'type'} eq 'argument')) {
-        $result .= $element->{'info'}->{'spaces_before_argument'}->{'text'}
-          if $element->{'info'} and 
$element->{'info'}->{'spaces_before_argument'};
-        my $arg_nr = 0;
-        my $argument = $element->{'contents'}->[0];
-        foreach my $arg (@{$argument->{'contents'}}) {
-          next if ($arg->{'info'} and $arg->{'info'}->{'inserted'});
-          $result .= ',' if ($arg_nr);
-          $arg_nr++;
-          $result .= _convert_to_texinfo($arg);
-        }
+        # root commands and block commands that are not def commands
+        $result .= $spc_before_arg;
+        $result .= _convert_args($element->{'contents'}->[0]);
+      } elsif ($line_commands{$data_cmdname}
+               or ($element->{'type'}
+                   and $element->{'type'} eq 'index_entry_command')) {
         # line commands that are not root commands
-      } elsif ($element->{'contents'}
-           and $element->{'contents'}->[0]->{'type'}
-           and $element->{'contents'}->[0]->{'type'} eq 'line_arg') {
-        $result .= $element->{'info'}->{'spaces_before_argument'}->{'text'}
-           if ($element->{'info'} and 
$element->{'info'}->{'spaces_before_argument'});
-        my $arg_nr = 0;
-        foreach my $arg (@{$element->{'contents'}}) {
-          next if ($arg->{'info'} and $arg->{'info'}->{'inserted'});
-          $result .= ',' if ($arg_nr);
-          $arg_nr++;
-          $result .= _convert_to_texinfo($arg);
-        }
+        $result .= $spc_before_arg;
+        $result .= _convert_args($element);
         return $result;
+      } elsif ($def_commands{$data_cmdname}) {
+        # @def* commands (that are also block commands)
+        $result .= $spc_before_arg;
       } else {
-        $result .= $element->{'info'}->{'spaces_before_argument'}->{'text'}
-          if $element->{'info'} and 
$element->{'info'}->{'spaces_before_argument'};
+        warn "BUG: Unknown command type to convert to texinfo: $cmdname\n";
       }
     } else {
       if ($element->{'type'}
@@ -293,11 +314,13 @@ sub _convert_to_texinfo($)
         $result .= $element->{'info'}->{'spaces_before_argument'}->{'text'};
       }
     }
+
     if (defined($element->{'contents'})) {
       foreach my $child (@{$element->{'contents'}}) {
         $result .= _convert_to_texinfo($child);
       }
     }
+
     if ($element->{'info'} and $element->{'info'}->{'spaces_after_argument'}) {
       $result .= $element->{'info'}->{'spaces_after_argument'}->{'text'};
     }
diff --git a/tp/Texinfo/XS/main/convert_to_texinfo.c 
b/tp/Texinfo/XS/main/convert_to_texinfo.c
index ad2a100b39..837793dd70 100644
--- a/tp/Texinfo/XS/main/convert_to_texinfo.c
+++ b/tp/Texinfo/XS/main/convert_to_texinfo.c
@@ -37,16 +37,34 @@
 #include "convert_to_texinfo.h"
 
 
-static void expand_cmd_args_to_texi (const ELEMENT *e, TEXT *result);
 static void convert_to_texinfo_internal (const ELEMENT *e, TEXT *result);
 
 
 #define ADD(x) text_append (result, x)
 
+static void
+convert_args (const ELEMENT *element, TEXT *result)
+{
+  size_t i;
+  size_t arg_nr = 0;
+
+  for (i = 0; i < element->e.c->contents.number; i++)
+    {
+      const ELEMENT *arg = element->e.c->contents.list[i];
+      if (arg->flags & EF_inserted)
+        continue;
+
+      if (arg_nr)
+        ADD(",");
+      arg_nr++;
+      convert_to_texinfo_internal (arg, result);
+    }
+}
+
 static void
 convert_to_texinfo_internal (const ELEMENT *e, TEXT *result)
 {
-  ELEMENT *elt;
+  const ELEMENT *elt;
 
   if (e->flags & EF_inserted || e->type == ET_argument)
     {}
@@ -59,9 +77,8 @@ convert_to_texinfo_internal (const ELEMENT *e, TEXT *result)
     {
       if (e->e.c->cmd)
         {
-          enum command_id cmd = element_builtin_cmd (e);
-          ELEMENT *elt;
-          ELEMENT *spc_before_arg = 0;
+          enum command_id cmd = element_builtin_data_cmd (e);
+          const ELEMENT *spc_before_arg = 0;
 
           if (cmd)
             {
@@ -82,10 +99,21 @@ convert_to_texinfo_internal (const ELEMENT *e, TEXT *result)
               spc_before_arg = e->elt_info[eit_spaces_before_argument];
             }
 
-          /* if there is no arg_line, the end of line is in rawline_arg in args
-             so the ET_lineraw_command args should be processed along with 
other
-             commands in that case */
-          if (e->type == ET_lineraw_command && 
e->e.c->string_info[sit_arg_line])
+          if (builtin_command_data[cmd].flags & CF_nobrace)
+            {
+           /* the spaces following a command are put in a text element in the
+              tree, not associated to the command element. */
+           /* item, tab and headitem are nobrace commands with contents */
+              if (e->e.c->contents.number == 0)
+                return;
+            }
+      /* arg_line set for line_commands with type lineraw that have
+         arguments and for @macro. */
+      /* if there is no arg_line, the end of line is in rawline_arg in contents
+         so the ET_lineraw_command should be processed along with other
+         line commands below */
+          else if (e->type == ET_lineraw_command
+                   && e->e.c->string_info[sit_arg_line])
             {
               const char *arg_line = e->e.c->string_info[sit_arg_line];
               if (spc_before_arg)
@@ -96,13 +124,17 @@ convert_to_texinfo_internal (const ELEMENT *e, TEXT 
*result)
               if (!(builtin_command_data[cmd].flags & CF_block))
                 return;
             }
-          else if (e->e.c->contents.number > 0
-                   && (builtin_command_data[cmd].flags & CF_brace
-                       || builtin_command_data[cmd].flags & CF_INFOENCLOSE))
+          else if (builtin_command_data[cmd].flags & CF_brace
+                   || builtin_command_data[cmd].flags & CF_INFOENCLOSE)
             {
-              size_t i, arg_nr;
               int braces;
 
+       /* contents may not be set for a command without braces.  In that
+          case it is better if the command is considered as a command without
+          argument. */
+              if (e->e.c->contents.number == 0)
+                return;
+
               braces = !(e->e.c->contents.list[0]->type == ET_following_arg);
               if (braces)
                 ADD("{");
@@ -116,18 +148,7 @@ convert_to_texinfo_internal (const ELEMENT *e, TEXT 
*result)
               if (spc_before_arg)
                 ADD((char *)spc_before_arg->e.text->text);
 
-              arg_nr = 0;
-              for (i = 0; i < e->e.c->contents.number; i++)
-                {
-                  ELEMENT *arg = e->e.c->contents.list[i];
-                  if (arg->flags & EF_inserted)
-                    continue;
-
-                  if (arg_nr)
-                    ADD(",");
-                  arg_nr++;
-                  convert_to_texinfo_internal (arg, result);
-                }
+              convert_args (e, result);
 
               if (cmd == CM_verb)
                 {
@@ -142,56 +163,35 @@ convert_to_texinfo_internal (const ELEMENT *e, TEXT 
*result)
           else if (e->e.c->contents.number > 0
                    && e->e.c->contents.list[0]->type == ET_argument)
             {
-              size_t i, arg_nr;
-              ELEMENT *argument = e->e.c->contents.list[0];
+           /* root commands and block commands that are not def commands */
+              const ELEMENT *argument = e->e.c->contents.list[0];
 
               if (spc_before_arg)
                 ADD((char *)spc_before_arg->e.text->text);
 
-              arg_nr = 0;
-              for (i = 0; i < argument->e.c->contents.number; i++)
-                {
-                  ELEMENT *arg = argument->e.c->contents.list[i];
-                  if (arg->flags & EF_inserted)
-                    continue;
-
-                  if (arg_nr)
-                    ADD(",");
-                  arg_nr++;
-                  convert_to_texinfo_internal (arg, result);
-                }
+              convert_args (argument, result);
             }
-          /* line commands that are not root commands */
-          else if (e->e.c->contents.number > 0
-                   && e->e.c->contents.list[0]->type == ET_line_arg)
+          else if (builtin_command_data[cmd].flags & CF_line
+                   || e->type == ET_index_entry_command)
             {
-              size_t i, arg_nr;
-
+          /* line commands that are not root commands */
               if (spc_before_arg)
                 ADD((char *)spc_before_arg->e.text->text);
 
-              arg_nr = 0;
-              for (i = 0; i < e->e.c->contents.number; i++)
-                {
-                  ELEMENT *arg = e->e.c->contents.list[i];
-                  if (arg->flags & EF_inserted)
-                    continue;
-
-                  if (arg_nr)
-                    ADD(",");
-                  arg_nr++;
-                  convert_to_texinfo_internal (arg, result);
-                }
+              convert_args (e, result);
               return;
             }
-          else
-            {
+          else if (builtin_command_data[cmd].flags & CF_def)
+            { /* @def* commands (that are also block commands) */
               if (spc_before_arg)
                 ADD((char *)spc_before_arg->e.text->text);
             }
-          if (builtin_command_data[cmd].flags & CF_brace
-              || builtin_command_data[cmd].flags & CF_INFOENCLOSE)
-            return;
+          else
+            {
+              fprintf (stderr,
+                       "BUG: Unknown command type to convert to texinfo: %s\n",
+                       element_command_name (e));
+            }
         }
       else
         {
diff --git a/tp/Texinfo/command_data.txt b/tp/Texinfo/command_data.txt
index 13493d6f31..cbc3bcae8b 100644
--- a/tp/Texinfo/command_data.txt
+++ b/tp/Texinfo/command_data.txt
@@ -69,6 +69,7 @@ index_entry_command     
internal,line,index_entry_command,contain_basic_inline,n
 # formatting
 noindent                nobrace,preamble,no_paragraph                
NOBRACE_skipspace
 indent                  nobrace,preamble,no_paragraph                
NOBRACE_skipspace
+# Next three commands are also containers
 headitem                nobrace,formatted_nobrace,close_paragraph,no_paragraph 
        NOBRACE_skipspace
 item                    nobrace,formatted_nobrace,close_paragraph,no_paragraph 
        NOBRACE_skipspace
 tab                     nobrace,formatted_nobrace,close_paragraph,no_paragraph 
        NOBRACE_skipspace



reply via email to

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