[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
- Prev by Date:
[no subject]
- Next by Date:
branch master updated: * tp/Texinfo/ParserNonXS.pm (_parse_macro_command_line) (_expand_macro_arguments, _expand_linemacro_arguments) (_lookup_macro_parameter, _expand_macro_body, _handle_macro) (_process_macro_block_contents), tp/Texinfo/XS/main/element_types.txt, tp/Texinfo/XS/parsetexi/macro.c (parse_macro_command_line) (lookup_macro_parameter, expand_macro_arguments) (expand_linemacro_arguments, expand_macro_body, handle_macro), tp/Texinfo/XS/parsetexi/parser.c (process_macro_block_contents): put @*macro lin [...]
- Previous by thread:
[no subject]
- Next by thread:
branch master updated: * tp/Texinfo/ParserNonXS.pm (_parse_macro_command_line) (_expand_macro_arguments, _expand_linemacro_arguments) (_lookup_macro_parameter, _expand_macro_body, _handle_macro) (_process_macro_block_contents), tp/Texinfo/XS/main/element_types.txt, tp/Texinfo/XS/parsetexi/macro.c (parse_macro_command_line) (lookup_macro_parameter, expand_macro_arguments) (expand_linemacro_arguments, expand_macro_body, handle_macro), tp/Texinfo/XS/parsetexi/parser.c (process_macro_block_contents): put @*macro lin [...]
- Index(es):