[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
branch master updated: * tp/Texinfo/ParserNonXS.pm (_handle_other_comman
From: |
Patrice Dumas |
Subject: |
branch master updated: * tp/Texinfo/ParserNonXS.pm (_handle_other_command) (_handle_line_command, _handle_block_command, _handle_brace_command) (_process_remaining_on_line): split handle_*_command out of _process_remaining_on_line as in the XS parser. |
Date: |
Fri, 03 Mar 2023 04:34:47 -0500 |
This is an automated email from the git hooks/post-receive script.
pertusus pushed a commit to branch master
in repository texinfo.
The following commit(s) were added to refs/heads/master by this push:
new f2668ff4ea * tp/Texinfo/ParserNonXS.pm (_handle_other_command)
(_handle_line_command, _handle_block_command, _handle_brace_command)
(_process_remaining_on_line): split handle_*_command out of
_process_remaining_on_line as in the XS parser.
f2668ff4ea is described below
commit f2668ff4ea8ba7542d68967e6318d3f22250b20a
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Fri Mar 3 10:34:38 2023 +0100
* tp/Texinfo/ParserNonXS.pm (_handle_other_command)
(_handle_line_command, _handle_block_command, _handle_brace_command)
(_process_remaining_on_line): split handle_*_command out of
_process_remaining_on_line as in the XS parser.
---
ChangeLog | 7 +
tp/Texinfo/ParserNonXS.pm | 1225 ++++++++++++++++++++++++---------------------
2 files changed, 649 insertions(+), 583 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f7aa4c4380..e0b2c8afa8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-03-03 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/ParserNonXS.pm (_handle_other_command)
+ (_handle_line_command, _handle_block_command, _handle_brace_command)
+ (_process_remaining_on_line): split handle_*_command out of
+ _process_remaining_on_line as in the XS parser.
+
2023-03-03 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/ParserNonXS.pm (_end_line_menu_entry, _end_line),
diff --git a/tp/Texinfo/ParserNonXS.pm b/tp/Texinfo/ParserNonXS.pm
index e29e937b8a..3d9ba843b4 100644
--- a/tp/Texinfo/ParserNonXS.pm
+++ b/tp/Texinfo/ParserNonXS.pm
@@ -4958,14 +4958,642 @@ sub _handle_menu_entry_separators($$$$$$)
return $retval;
}
-my $STILL_MORE_TO_PROCESS = 0;
-my $GET_A_NEW_LINE = 1;
-my $FINISHED_TOTALLY = -1;
-
# return values:
# $STILL_MORE_TO_PROCESS: when there is more to process on the line
# $GET_A_NEW_LINE: when we need to read a new line
# $FINISHED_TOTALLY: found @bye, end of processing
+
+my $STILL_MORE_TO_PROCESS = 0;
+my $GET_A_NEW_LINE = 1;
+my $FINISHED_TOTALLY = -1;
+
+sub _handle_other_command($$$$$)
+{
+ my $self = shift;
+ my $current = shift;
+ my $command = shift;
+ my $line = shift;
+ my $source_info = shift;
+
+ my $retval = $STILL_MORE_TO_PROCESS;
+
+ # symbol skipspace other
+ my $arg_spec = $nobrace_commands{$command};
+ my $misc;
+
+ if ($arg_spec ne 'skipspace') {
+ $misc = {'cmdname' => $command, 'parent' => $current};
+ push @{$current->{'contents'}}, $misc;
+
+ if ($in_heading_spec_commands{$command}) {
+ # TODO use a more generic system for check of @-command nesting
+ # in command on context stack
+ my $top_context_command = $self->_top_context_command();
+ if (not defined($top_context_command)
+ or not $heading_spec_commands{$top_context_command}) {
+ $self->_line_error(
+ sprintf(__("\@%s should only appear in heading or footing"),
+ $command), $source_info);
+ }
+ }
+ if ($arg_spec eq 'symbol') {
+ # TODO generalize?
+ if ($command eq '\\' and $self->_top_context() ne 'ct_math') {
+ $self->_line_warn(sprintf(
+ __("\@%s should only appear in math context"),
+ $command), $source_info);
+ }
+ if ($command eq "\n") {
+ $current = _end_line($self, $current, $source_info);
+ $retval = $GET_A_NEW_LINE;
+ }
+ } else { # other
+ _register_global_command($self, $misc, $source_info);
+ $current = _begin_preformatted($self, $current)
+ if ($close_preformatted_commands{$command});
+ }
+ } else {
+ if ($command eq 'item'
+ or $command eq 'headitem' or $command eq 'tab') {
+ my $parent;
+ # @itemize or @enumerate
+ if ($parent = _item_container_parent($current)) {
+ if ($command eq 'item') {
+ print STDERR "ITEM_CONTAINER\n" if ($self->{'DEBUG'});
+ $parent->{'items_count'}++;
+ $misc = { 'cmdname' => $command, 'parent' => $parent,
+ 'extra' =>
+ {'item_number' => $parent->{'items_count'}} };
+ push @{$parent->{'contents'}}, $misc;
+ $current = $parent->{'contents'}->[-1];
+ } else {
+ $self->_line_error(sprintf(__(
+ "\@%s not meaningful inside `\@%s' block"),
+ $command, $parent->{'cmdname'}), $source_info);
+ }
+ $current = _begin_preformatted($self, $current);
+ # @*table
+ } elsif ($parent = _item_line_parent($current)) {
+ # @item and _item_line_parent is explicitly avoided in the if above
+ $self->_line_error(sprintf(__(
+ "\@%s not meaningful inside `\@%s' block"),
+ $command, $parent->{'cmdname'}), $source_info);
+ $current = _begin_preformatted($self, $current);
+ # @multitable
+ } elsif ($parent = _item_multitable_parent($current)) {
+ if (!$parent->{'extra'}->{'max_columns'}) {
+ $self->_line_warn(
+ sprintf(__("\@%s in empty multitable"),
+ $command), $source_info);
+ } elsif ($command eq 'tab') {
+ my $row = $parent->{'contents'}->[-1];
+ die if (!$row->{'type'});
+ if ($row->{'type'} eq 'before_item') {
+ $self->_line_error(__("\@tab before \@item"), $source_info);
+ } elsif ($row->{'cells_count'} >=
$parent->{'extra'}->{'max_columns'}) {
+ $self->_line_error(sprintf(__(
+ "too many columns in multitable item (max %d)"),
+ $parent->{'extra'}->{'max_columns'}), $source_info);
+ } else {
+ $row->{'cells_count'}++;
+ $misc = { 'cmdname' => $command,
+ 'parent' => $row,
+ 'contents' => [],
+ 'extra' =>
+ {'cell_number' => $row->{'cells_count'}} };
+ push @{$row->{'contents'}}, $misc;
+ $current = $row->{'contents'}->[-1];
+ print STDERR "TAB\n" if ($self->{'DEBUG'});
+ }
+ } else {
+ print STDERR "ROW\n" if ($self->{'DEBUG'});
+ $parent->{'rows_count'}++;
+ my $row = { 'type' => 'row', 'contents' => [],
+ 'cells_count' => 1,
+ 'extra' => {'row_number' => $parent->{'rows_count'} },
+ 'parent' => $parent };
+ push @{$parent->{'contents'}}, $row;
+ $misc = { 'cmdname' => $command,
+ 'parent' => $row,
+ 'contents' => [],
+ 'extra' => {'cell_number' => 1}};
+ push @{$row->{'contents'}}, $misc;
+ $current = $row->{'contents'}->[-1];
+ }
+ $current = _begin_preformatted($self, $current);
+ } elsif ($command eq 'tab') {
+ $self->_line_error(__(
+ "ignoring \@tab outside of multitable"), $source_info);
+ $current = _begin_preformatted($self, $current);
+ } else {
+ $self->_line_error(sprintf(__(
+ "\@%s outside of table or list"), $command), $source_info);
+ $current = _begin_preformatted($self, $current);
+ }
+ $misc->{'source_info'} = $source_info if (defined($misc));
+ } else {
+ $misc = { 'cmdname' => $command, 'parent' => $current,
+ 'source_info' => $source_info };
+ push @{$current->{'contents'}}, $misc;
+ if (($command eq 'indent' or $command eq 'noindent')
+ and _in_paragraph($self, $current)) {
+ $self->_line_warn(sprintf(__("\@%s is useless inside of a paragraph"),
+ $command),
+ $source_info);
+ }
+ }
+ $line = _start_empty_line_after_command($line, $current, undef);
+ }
+ return ($current, $line, $retval);
+}
+
+sub _handle_line_command($$$$$)
+{
+ my $self = shift;
+ my $current = shift;
+ my $command = shift;
+ my $line = shift;
+ my $source_info = shift;
+
+ my $retval = $STILL_MORE_TO_PROCESS;
+
+ if ($root_commands{$command} or $command eq 'bye') {
+ $current = _close_commands($self, $current, $source_info, undef,
+ $command);
+ # if the root command happens in a Texinfo fragment going through
+ # parse_texi_line we are directly in the root_line document
+ # root container (in this case _close_commands returned immediately),
+ # and there is no parent for $current.
+ # In any other situation, _close_command stops at the preceding
+ # root command or in before_node_section, both being in the document
+ # root container, so that there is a parent for $current, the document
+ # root container.
+ if (!defined($current->{'parent'})) {
+ if ($current->{'type'} ne 'root_line') {
+ $self->_bug_message("no parent element", $source_info, $current);
+ die;
+ } else {
+ # TODO do we want to error out if there is a root command in
+ # Texinfo fragment processed with parse_texi_text (and therefore
+ # here in root_line)?
+ # $self->_line_error(sprintf(__(
+ # "\@%s should not appear in Texinfo parsed as a short fragment"),
+ # $command), $source_info);
+ }
+ } else {
+ # in a root command or before_node_section, get to the document root
+ # container.
+ $current = $current->{'parent'};
+ }
+ }
+
+ # text line lineraw special specific
+ my $arg_spec = $self->{'line_commands'}->{$command};
+ my $misc;
+
+ # all the cases using the raw line
+ if ($arg_spec eq 'lineraw' or $arg_spec eq 'special') {
+ my $ignored = 0;
+ if ($command eq 'insertcopying') {
+ my $parent = $current;
+ while ($parent) {
+ if ($parent->{'cmdname'} and $parent->{'cmdname'} eq 'copying') {
+ $self->_line_error(
+ sprintf(__("\@%s not allowed inside `\@%s' block"),
+ $command, $parent->{'cmdname'}), $source_info);
+ $ignored = 1;
+ last;
+ }
+ $parent = $parent->{'parent'};
+ }
+ }
+
+ # Complete the line if there was a user macro expansion.
+ # NOTE the source marks (mostly end of macro/value expansion) will
+ # be associated to the previous element in $current, as the command being
+ # considered has not been added already, although the end of macro
+ # expansion is located after the command opening. Wrongly placed
+ # mark sources are unavoidable, as the line is not parsed as usual
+ # and macro/value expansion happen here in advance and not while
+ # the remaining of the line is parsed.
+ # TODO add information on the mark source to communicate that the
+ # placement of mark sources is approximate?
+ if ($line !~ /\n/) {
+ my ($new_line, $new_line_source_info)
+ = _new_line($self, $current);
+ $line .= $new_line if (defined($new_line));
+ }
+ $misc = {'cmdname' => $command,
+ 'parent' => $current};
+ my $args = [];
+ my $has_comment;
+ if ($arg_spec eq 'lineraw') {
+ $args = [ $line ];
+ } elsif ($arg_spec eq 'special') {
+ ($args, $has_comment)
+ = _parse_special_misc_command($self, $line, $command, $source_info);
+ $misc->{'info'} = {'arg_line' => $line};
+ # FIXME add a check on @clickstyle argument at that point?
+ }
+
+ # if using the @set txi* instead of a proper @-command, replace
+ # by the tree obtained with the @-command. Even though
+ # _end_line is called below, as $current is not line_arg
+ # there should not be anything done in addition than what is
+ # done for @clear or @set.
+ if (($command eq 'set' or $command eq 'clear')
+ and scalar(@$args) >= 1
+ and $set_flag_command_equivalent{$args->[0]}) {
+ my $arg;
+ if ($command eq 'set') {
+ $arg = 'on';
+ } else {
+ $arg = 'off';
+ }
+ # note that those commands are line 'specific' type.
+ $command = $set_flag_command_equivalent{$args->[0]};
+ $misc = {'cmdname' => $command,
+ 'parent' => $current,
+ 'source_info' => $source_info,
+ 'extra' => {'misc_args' => [$arg],},
+ 'info' => {'spaces_before_argument' => {'text' => ' '}}};
+ my $misc_line_args = {'type' => 'line_arg',
+ 'parent' => $misc,
+ 'info' => {'spaces_after_argument'
+ => {'text' => "\n",}}};
+ $misc->{'args'} = [$misc_line_args];
+ $misc_line_args->{'contents'} = [
+ { 'text' => $arg,
+ 'parent' => $misc_line_args, },
+ ];
+ push @{$current->{'contents'}}, $misc;
+ } else {
+ if (!$ignored) {
+ push @{$current->{'contents'}}, $misc;
+ if (scalar(@$args)) {
+ $misc->{'args'} = [];
+ foreach my $arg (@$args) {
+ push @{$misc->{'args'}},
+ { 'type' => 'misc_arg', 'text' => $arg,
+ 'parent' => $current->{'contents'}->[-1] };
+ }
+ }
+ } else {
+ $misc = undef;
+ }
+ }
+ if ($command eq 'raisesections') {
+ $self->{'sections_level'}++;
+ } elsif ($command eq 'lowersections') {
+ $self->{'sections_level'}--;
+ }
+ _register_global_command($self, $misc, $source_info)
+ if $misc;
+ # the end of line is ignored for special commands
+ if ($arg_spec ne 'special' or !$has_comment) {
+ $current = _end_line($self, $current, $source_info);
+ }
+
+ if ($command eq 'bye') {
+ return ($current, $line, $FINISHED_TOTALLY);
+ # goto funexit; # used in XS code
+ }
+ # Even if _end_line is called, it is not done since there is
+ # no line_arg
+ $current = _begin_preformatted($self, $current)
+ if ($close_preformatted_commands{$command});
+ return ($current, $line, $GET_A_NEW_LINE);
+ # goto funexit; # used in XS code
+ } else {
+ # $arg_spec is text, line or specific
+ # @item or @itemx in @table
+ if ($command eq 'item' or $command eq 'itemx') {
+ my $parent;
+ print STDERR "ITEM_LINE\n" if ($self->{'DEBUG'});
+ if ($parent = _item_line_parent($current)) {
+ $current = $parent;
+ _gather_previous_item($self, $current, $command, $source_info);
+ } else {
+ $self->_line_error(sprintf(__(
+ "\@%s outside of table or list"), $command), $source_info);
+ $current = _begin_preformatted($self, $current);
+ }
+ $misc = { 'cmdname' => $command, 'parent' => $current };
+ push @{$current->{'contents'}}, $misc;
+ $misc->{'source_info'} = $source_info;
+ } else {
+ $misc = { 'cmdname' => $command, 'source_info' => $source_info };
+ if ($command eq 'subentry') {
+ my $parent = $current->{'parent'};
+ if (!_is_index_element($self, $parent)) {
+ $self->_line_warn(
+ sprintf(__("\@%s should only appear in an index entry"),
+ $command), $source_info);
+ }
+ $parent->{'extra'} = {} if (!defined($parent->{'extra'}));
+ $parent->{'extra'}->{'subentry'} = $misc;
+ my $subentry_level = 1;
+ if ($parent->{'cmdname'} eq 'subentry') {
+ $subentry_level = $parent->{'extra'}->{'level'} + 1;
+ }
+ $misc->{'extra'} = {'level' => $subentry_level};
+ if ($subentry_level > 2) {
+ $self->_line_error(__(
+ "no more than two levels of index subentry are allowed"),
+ $source_info);
+ }
+ # Do not make the @subentry element a child of the index
+ # command. This means that spaces are preserved properly
+ # when converting back to Texinfo.
+ $current = _end_line($self, $current, $source_info);
+ } elsif ($sectioning_heading_commands{$command}) {
+ if ($self->{'sections_level'}) {
+ $misc->{'extra'} = {'sections_level' => $self->{'sections_level'}};
+ }
+ }
+ push @{$current->{'contents'}}, $misc;
+ $misc->{'parent'} = $current;
+ # def*x
+ if ($def_commands{$command}) {
+ my $base_command = $command;
+ $base_command =~ s/x$//;
+ # check that the def*x is first after @def*, no paragraph
+ # in-between.
+ my $after_paragraph = _check_no_text($current);
+ $self->_push_context('ct_def', $command);
+ $current->{'contents'}->[-1]->{'type'} = 'def_line';
+ $current->{'contents'}->[-1]->{'extra'}
+ = {'def_command' => $base_command,
+ 'original_def_cmdname' => $command};
+ if (defined($self->{'values'}->{'txidefnamenospace'})) {
+ $current->{'contents'}->[-1]{'extra'}
+ ->{'omit_def_name_space'} = 1;
+ }
+ if ($current->{'cmdname'}
+ and $current->{'cmdname'} eq $base_command) {
+ # popped element should be the same as $misc
+ _pop_element_from_contents($self, $current);
+ _gather_def_item($self, $current, $command);
+ push @{$current->{'contents'}}, $misc;
+ }
+ if (!$current->{'cmdname'}
+ or ($current->{'cmdname'} ne $base_command
+ and $current->{'cmdname'} ne 'defblock')
+ or $after_paragraph) {
+ $self->_line_error(sprintf(__(
+ "must be after `\@%s' to use `\@%s'"),
+ $base_command, $command), $source_info);
+ $current->{'contents'}->[-1]->{'extra'}->{'not_after_command'} = 1;
+ }
+ }
+ }
+ $current = $current->{'contents'}->[-1];
+ $current->{'args'} = [{ 'type' => 'line_arg',
+ 'parent' => $current }];
+ if ($self->{'basic_inline_commands'}
+ and $self->{'basic_inline_commands'}->{$command}) {
+ push @{$self->{'nesting_context'}->{'basic_inline_stack_on_line'}},
+ $command;
+ }
+
+ # 'specific' commands arguments are handled in a specific way.
+ # The only other line commands that have more than one argument is
+ # node, so the following condition only applies to node
+ if ($self->{'line_commands'}->{$command} ne 'specific'
+ and $commands_args_number{$command}
+ and $commands_args_number{$command} > 1) {
+ $current->{'remaining_args'} = $commands_args_number{$command} - 1;
+ }
+ if ($command eq 'author') {
+ my $parent = $current;
+ my $found;
+ while ($parent->{'parent'}) {
+ $parent = $parent->{'parent'};
+ last if ($parent->{'type'}
+ and $parent->{'type'} eq 'brace_command_context');
+ if ($parent->{'cmdname'}) {
+ if ($parent->{'cmdname'} eq 'titlepage') {
+ $current->{'extra'} = {} if (!$current->{'extra'});
+ $current->{'extra'}->{'titlepage'} = $parent;
+ $found = 1;
+ } elsif ($parent->{'cmdname'} eq 'quotation' or
+ $parent->{'cmdname'} eq 'smallquotation') {
+ $parent->{'extra'} = {} if (!$parent->{'extra'});
+ push @{$parent->{'extra'}->{'authors'}}, $current;
+ $current->{'extra'} = {} if (!$current->{'extra'});
+ $current->{'extra'}->{'quotation'} = $parent;
+ $found = 1;
+ }
+ last if ($found);
+ }
+ }
+ if (!$found) {
+ $self->_line_warn(sprintf(__(
+ "\@%s not meaningful outside `\@titlepage' and `\@quotation'
environments"),
+ $command), $current->{'source_info'});
+ }
+ } elsif ($command eq 'dircategory' and $self->{'current_node'}) {
+ $self->_line_warn(__("\@dircategory after first node"),
+ $source_info);
+ } elsif ($command eq 'printindex') {
+ # Record that @printindex occurs in this node so we know it
+ # is an index node.
+ if ($self->{'current_node'}) {
+ $self->{'current_node'}->{'extra'} = {}
+ if (!$self->{'current_node'}->{'extra'});
+ $self->{'current_node'}->{'extra'}->{'isindex'} = 1;
+ }
+ }
+
+ $current = $current->{'args'}->[-1];
+ $self->_push_context('ct_line', $command)
+ unless ($def_commands{$command});
+ $line = _start_empty_line_after_command($line, $current, $misc);
+ }
+ _register_global_command($self, $misc, $source_info)
+ if $misc;
+ if ($command eq 'dircategory') {
+ push @{$self->{'info'}->{'dircategory_direntry'}}, $misc;
+ }
+ return ($current, $line, $retval);
+}
+
+sub _handle_block_command($$$$$)
+{
+ my $self = shift;
+ my $current = shift;
+ my $command = shift;
+ my $line = shift;
+ my $source_info = shift;
+
+ my $retval = $STILL_MORE_TO_PROCESS;
+
+ if ($command eq 'macro' or $command eq 'rmacro') {
+ my $macro = _parse_macro_command_line($self, $command, $line,
+ $current, $source_info);
+ push @{$current->{'contents'}}, $macro;
+ $current = $current->{'contents'}->[-1];
+ return ($current, $line, $GET_A_NEW_LINE);
+ # goto funexit; # used in XS code
+ } else {
+ my $block;
+ # a menu command closes a menu_comment, but not the other
+ # block commands. This won't catch menu commands buried in
+ # other formats (that are incorrect anyway).
+ if ($block_commands{$command} eq 'menu' and $current->{'type'}
+ and ($current->{'type'} eq 'menu_comment'
+ or $current->{'type'} eq 'menu_entry_description')) {
+
+ # This is, in general, caused by @detailmenu within @menu
+ if ($current->{'type'} eq 'menu_comment') {
+ $current = _close_container($self, $current);
+ } else { # menu_entry_description
+ $current = _close_container($self, $current);
+ if ($current->{'type'} and $current->{'type'} eq 'menu_entry') {
+ $current = $current->{'parent'};
+ } else {
+ $self->_bug_message("menu description parent not a menu_entry",
+ $source_info, $current);
+ die;
+ }
+ }
+ }
+ # the def command holds a line_def* which corresponds with the
+ # definition line. This allows to have a treatement similar
+ # with def*x.
+ if ($def_commands{$command}) {
+ $self->_push_context('ct_def', $command);
+ $block = { 'parent' => $current,
+ 'cmdname' => $command,
+ 'contents' => [] };
+ push @{$current->{'contents'}}, $block;
+ $current = $current->{'contents'}->[-1];
+ push @{$current->{'contents'}}, {
+ 'type' => 'def_line',
+ 'parent' => $current,
+ 'source_info' => $source_info,
+ 'extra' =>
+ {'def_command' => $command,
+ 'original_def_cmdname' => $command}
+ };
+ if (defined($self->{'values'}->{'txidefnamenospace'})) {
+ $current->{'contents'}->[-1]->{'extra'}
+ ->{'omit_def_name_space'} = 1;
+ }
+ } else {
+ $block = { 'cmdname' => $command,
+ 'parent' => $current,
+ };
+ push @{$current->{'contents'}}, $block;
+ }
+ $current = $current->{'contents'}->[-1];
+
+ if ($preformatted_commands{$command}) {
+ $self->_push_context('ct_preformatted', $command);
+ } elsif ($math_commands{$command}) {
+ $self->_push_context('ct_math', $command);
+ } elsif ($block_commands{$command} eq 'format_raw') {
+ $self->_push_context('ct_rawpreformatted', $command);
+ }
+ if ($block_commands{$command} eq 'region') {
+ push @{$self->{'nesting_context'}->{'regions_stack'}}, $command;
+ }
+ if ($block_commands{$command} eq 'menu') {
+ $self->_push_context('ct_preformatted', $command);
+ push @{$self->{'info'}->{'dircategory_direntry'}}, $block
+ if ($command eq 'direntry');
+ if ($self->{'current_node'}) {
+ if ($command eq 'direntry') {
+ if ($self->{'FORMAT_MENU'} eq 'menu') {
+ $self->_line_warn(__("\@direntry after first node"),
+ $source_info);
+ }
+ } elsif ($command eq 'menu') {
+ if (!(defined $current->{'parent'}->{'cmdname'})
+ or $root_commands{$current->{'parent'}->{'cmdname'}}) {
+ $self->{'current_node'}->{'extra'} = {}
+ if (!defined($self->{'current_node'}->{'extra'}));
+ $self->{'current_node'}->{'extra'}->{'menus'} = []
+ if (!defined($self->{'current_node'}->{'extra'}->{'menus'}));
+ push @{$self->{'current_node'}->{'extra'}->{'menus'}}, $current;
+ } else {
+ $self->_line_warn(__("\@menu in invalid context"),
+ $source_info);
+ }
+ }
+ }
+ }
+ # cleaner, and more similar to XS parser, but not required, would have
+ # been initialized automatically.
+ $current->{'items_count'} = 0
+ if ($block_commands{$command}
+ and $block_commands{$command} eq 'item_container');
+
+ $current->{'args'} = [ {
+ 'type' => 'block_line_arg',
+ 'parent' => $current } ];
+
+ if ($commands_args_number{$command}) {
+ if ($commands_args_number{$command} - 1 > 0) {
+ $current->{'remaining_args'}
+ = $commands_args_number{$command} - 1;
+ }
+ } elsif ($variadic_commands{$command}) {
+ $current->{'remaining_args'} = -1; # unlimited args
+ }
+ $current = $current->{'args'}->[-1];
+ $self->_push_context('ct_line', $command)
+ unless ($def_commands{$command});
+ if ($self->{'basic_inline_commands'}->{$command}) {
+ push @{$self->{'nesting_context'}->{'basic_inline_stack_block'}},
+ $command;
+ }
+ $block->{'source_info'} = $source_info;
+ _register_global_command($self, $block, $source_info);
+ $line = _start_empty_line_after_command($line, $current, $block);
+ }
+ return ($current, $line, $retval);
+}
+
+sub _handle_brace_command($$$$)
+{
+ my $self = shift;
+ my $current = shift;
+ my $command = shift;
+ my $source_info = shift;
+
+ print STDERR "OPEN BRACE \@$command\n"
+ if ($self->{'DEBUG'});
+ push @{$current->{'contents'}}, { 'cmdname' => $command,
+ 'parent' => $current,
+ };
+ $current->{'contents'}->[-1]->{'source_info'} = $source_info;
+ if ($in_index_commands{$command}
+ and !_is_index_element($self, $current->{'parent'})) {
+ $self->_line_warn(
+ sprintf(__("\@%s should only appear in an index entry"),
+ $command), $source_info);
+ }
+ $current = $current->{'contents'}->[-1];
+ if ($command eq 'click') {
+ $current->{'extra'} = {} if (!$current->{'extra'});
+ $current->{'extra'}->{'clickstyle'} = $self->{'clickstyle'};
+ } elsif ($command eq 'kbd'
+ and _kbd_formatted_as_code($self, $current)) {
+ $current->{'extra'} = {} if (!$current->{'extra'});
+ $current->{'extra'}->{'code'} = 1;
+ }
+ if ($self->{'definfoenclose'}->{$command}) {
+ $current->{'type'} = 'definfoenclose_command';
+ $current->{'extra'} = {} if (!$current->{'extra'});
+ $current->{'extra'}->{'begin'}
+ = $self->{'definfoenclose'}->{$command}->[0];
+ $current->{'extra'}->{'end'}
+ = $self->{'definfoenclose'}->{$command}->[1];
+ }
+ return $current;
+}
+
sub _process_remaining_on_line($$$$)
{
my $self = shift;
@@ -5555,590 +6183,21 @@ sub _process_remaining_on_line($$$$)
if (defined($nobrace_commands{$command})
and ($command ne 'item' or !_item_line_parent($current))) {
- # symbol skipspace other
- my $arg_spec = $nobrace_commands{$command};
- my $misc;
-
- if ($arg_spec ne 'skipspace') {
- $misc = {'cmdname' => $command, 'parent' => $current};
- push @{$current->{'contents'}}, $misc;
-
- if ($in_heading_spec_commands{$command}) {
- # TODO use a more generic system for check of @-command nesting
- # in command on context stack
- my $top_context_command = $self->_top_context_command();
- if (not defined($top_context_command)
- or not $heading_spec_commands{$top_context_command}) {
- $self->_line_error(
- sprintf(__("\@%s should only appear in heading or footing"),
- $command), $source_info);
- }
- }
- if ($arg_spec eq 'symbol') {
- # TODO generalize?
- if ($command eq '\\' and $self->_top_context() ne 'ct_math') {
- $self->_line_warn(sprintf(
- __("\@%s should only appear in math context"),
- $command), $source_info);
- }
- if ($command eq "\n") {
- $current = _end_line($self, $current, $source_info);
- return ($current, $line, $source_info, $GET_A_NEW_LINE);
- # goto funexit; # used in XS code
- }
- } else { # other
- _register_global_command($self, $misc, $source_info);
- $current = _begin_preformatted($self, $current)
- if ($close_preformatted_commands{$command});
- }
- } else {
- if ($command eq 'item'
- or $command eq 'headitem' or $command eq 'tab') {
- my $parent;
- # @itemize or @enumerate
- if ($parent = _item_container_parent($current)) {
- if ($command eq 'item') {
- print STDERR "ITEM_CONTAINER\n" if ($self->{'DEBUG'});
- $parent->{'items_count'}++;
- $misc = { 'cmdname' => $command, 'parent' => $parent,
- 'extra' =>
- {'item_number' => $parent->{'items_count'}} };
- push @{$parent->{'contents'}}, $misc;
- $current = $parent->{'contents'}->[-1];
- } else {
- $self->_line_error(sprintf(__(
- "\@%s not meaningful inside `\@%s' block"),
- $command, $parent->{'cmdname'}), $source_info);
- }
- $current = _begin_preformatted($self, $current);
- # @*table
- } elsif ($parent = _item_line_parent($current)) {
- # @item and _item_line_parent is explicitly avoided in the if above
- $self->_line_error(sprintf(__(
- "\@%s not meaningful inside `\@%s' block"),
- $command, $parent->{'cmdname'}), $source_info);
- $current = _begin_preformatted($self, $current);
- # @multitable
- } elsif ($parent = _item_multitable_parent($current)) {
- if (!$parent->{'extra'}->{'max_columns'}) {
- $self->_line_warn(
- sprintf(__("\@%s in empty multitable"),
- $command), $source_info);
- } elsif ($command eq 'tab') {
- my $row = $parent->{'contents'}->[-1];
- die if (!$row->{'type'});
- if ($row->{'type'} eq 'before_item') {
- $self->_line_error(__("\@tab before \@item"), $source_info);
- } elsif ($row->{'cells_count'} >=
$parent->{'extra'}->{'max_columns'}) {
- $self->_line_error(sprintf(__(
- "too many columns in multitable item (max %d)"),
- $parent->{'extra'}->{'max_columns'}), $source_info);
- } else {
- $row->{'cells_count'}++;
- $misc = { 'cmdname' => $command,
- 'parent' => $row,
- 'contents' => [],
- 'extra' =>
- {'cell_number' => $row->{'cells_count'}} };
- push @{$row->{'contents'}}, $misc;
- $current = $row->{'contents'}->[-1];
- print STDERR "TAB\n" if ($self->{'DEBUG'});
- }
- } else {
- print STDERR "ROW\n" if ($self->{'DEBUG'});
- $parent->{'rows_count'}++;
- my $row = { 'type' => 'row', 'contents' => [],
- 'cells_count' => 1,
- 'extra' => {'row_number' => $parent->{'rows_count'}
},
- 'parent' => $parent };
- push @{$parent->{'contents'}}, $row;
- $misc = { 'cmdname' => $command,
- 'parent' => $row,
- 'contents' => [],
- 'extra' => {'cell_number' => 1}};
- push @{$row->{'contents'}}, $misc;
- $current = $row->{'contents'}->[-1];
- }
- $current = _begin_preformatted($self, $current);
- } elsif ($command eq 'tab') {
- $self->_line_error(__(
- "ignoring \@tab outside of multitable"), $source_info);
- $current = _begin_preformatted($self, $current);
- } else {
- $self->_line_error(sprintf(__(
- "\@%s outside of table or list"), $command), $source_info);
- $current = _begin_preformatted($self, $current);
- }
- $misc->{'source_info'} = $source_info if (defined($misc));
- } else {
- $misc = { 'cmdname' => $command, 'parent' => $current,
- 'source_info' => $source_info };
- push @{$current->{'contents'}}, $misc;
- if (($command eq 'indent' or $command eq 'noindent')
- and _in_paragraph($self, $current)) {
- $self->_line_warn(sprintf(__("\@%s is useless inside of a
paragraph"),
- $command),
- $source_info);
- }
- }
- $line = _start_empty_line_after_command($line, $current, undef);
- }
+ ($current, $line, $retval)
+ = _handle_other_command($self, $current, $command, $line,
$source_info);
+ # in the XS parser return here if GET_A_NEW_LINE or FINISHED_TOTALLY
# line commands
} elsif (defined($self->{'line_commands'}->{$command})) {
- if ($root_commands{$command} or $command eq 'bye') {
- $current = _close_commands($self, $current, $source_info, undef,
- $command);
- # if the root command happens in a Texinfo fragment going through
- # parse_texi_line we are directly in the root_line document
- # root container (in this case _close_commands returned immediately),
- # and there is no parent for $current.
- # In any other situation, _close_command stops at the preceding
- # root command or in before_node_section, both being in the document
- # root container, so that there is a parent for $current, the document
- # root container.
- if (!defined($current->{'parent'})) {
- if ($current->{'type'} ne 'root_line') {
- $self->_bug_message("no parent element", $source_info, $current);
- die;
- } else {
- # TODO do we want to error out if there is a root command in
- # Texinfo fragment processed with parse_texi_text (and therefore
- # here in root_line)?
- # $self->_line_error(sprintf(__(
- # "\@%s should not appear in Texinfo parsed as a short fragment"),
- # $command), $source_info);
- }
- } else {
- # in a root command or before_node_section, get to the document root
- # container.
- $current = $current->{'parent'};
- }
- }
-
- # text line lineraw special specific
- my $arg_spec = $self->{'line_commands'}->{$command};
- my $misc;
-
- # all the cases using the raw line
- if ($arg_spec eq 'lineraw' or $arg_spec eq 'special') {
- my $ignored = 0;
- if ($command eq 'insertcopying') {
- my $parent = $current;
- while ($parent) {
- if ($parent->{'cmdname'} and $parent->{'cmdname'} eq 'copying') {
- $self->_line_error(
- sprintf(__("\@%s not allowed inside `\@%s' block"),
- $command, $parent->{'cmdname'}), $source_info);
- $ignored = 1;
- last;
- }
- $parent = $parent->{'parent'};
- }
- }
-
- # Complete the line if there was a user macro expansion.
- # NOTE the source marks (mostly end of macro/value expansion) will
- # be associated to the previous element in $current, as the command
being
- # considered has not been added already, although the end of macro
- # expansion is located after the command opening. Wrongly placed
- # mark sources are unavoidable, as the line is not parsed as usual
- # and macro/value expansion happen here in advance and not while
- # the remaining of the line is parsed.
- # TODO add information on the mark source to communicate that the
- # placement of mark sources is approximate?
- if ($line !~ /\n/) {
- my ($new_line, $new_line_source_info)
- = _new_line($self, $current);
- $line .= $new_line if (defined($new_line));
- }
- $misc = {'cmdname' => $command,
- 'parent' => $current};
- my $args = [];
- my $has_comment;
- if ($arg_spec eq 'lineraw') {
- $args = [ $line ];
- } elsif ($arg_spec eq 'special') {
- ($args, $has_comment)
- = _parse_special_misc_command($self, $line, $command, $source_info);
- $misc->{'info'} = {'arg_line' => $line};
- # FIXME add a check on @clickstyle argument at that point?
- }
-
- # if using the @set txi* instead of a proper @-command, replace
- # by the tree obtained with the @-command. Even though
- # _end_line is called below, as $current is not line_arg
- # there should not be anything done in addition than what is
- # done for @clear or @set.
- if (($command eq 'set' or $command eq 'clear')
- and scalar(@$args) >= 1
- and $set_flag_command_equivalent{$args->[0]}) {
- my $arg;
- if ($command eq 'set') {
- $arg = 'on';
- } else {
- $arg = 'off';
- }
- # note that those commands are line 'specific' type.
- $command = $set_flag_command_equivalent{$args->[0]};
- $misc = {'cmdname' => $command,
- 'parent' => $current,
- 'source_info' => $source_info,
- 'extra' => {'misc_args' => [$arg],},
- 'info' => {'spaces_before_argument' => {'text' => ' '}}};
- my $misc_line_args = {'type' => 'line_arg',
- 'parent' => $misc,
- 'info' => {'spaces_after_argument'
- => {'text' => "\n",}}};
- $misc->{'args'} = [$misc_line_args];
- $misc_line_args->{'contents'} = [
- { 'text' => $arg,
- 'parent' => $misc_line_args, },
- ];
- push @{$current->{'contents'}}, $misc;
- } else {
- if (!$ignored) {
- push @{$current->{'contents'}}, $misc;
- if (scalar(@$args)) {
- $misc->{'args'} = [];
- foreach my $arg (@$args) {
- push @{$misc->{'args'}},
- { 'type' => 'misc_arg', 'text' => $arg,
- 'parent' => $current->{'contents'}->[-1] };
- }
- }
- } else {
- $misc = undef;
- }
- }
- if ($command eq 'raisesections') {
- $self->{'sections_level'}++;
- } elsif ($command eq 'lowersections') {
- $self->{'sections_level'}--;
- }
- _register_global_command($self, $misc, $source_info)
- if $misc;
- # the end of line is ignored for special commands
- if ($arg_spec ne 'special' or !$has_comment) {
- $current = _end_line($self, $current, $source_info);
- }
-
- if ($command eq 'bye') {
- return ($current, $line, $source_info, $FINISHED_TOTALLY);
- # goto funexit; # used in XS code
- }
- # Even if _end_line is called, it is not done since there is
- # no line_arg
- $current = _begin_preformatted($self, $current)
- if ($close_preformatted_commands{$command});
- return ($current, $line, $source_info, $GET_A_NEW_LINE);
- # goto funexit; # used in XS code
- } else {
- # $arg_spec is text, line or specific
- # @item or @itemx in @table
- if ($command eq 'item' or $command eq 'itemx') {
- my $parent;
- print STDERR "ITEM_LINE\n" if ($self->{'DEBUG'});
- if ($parent = _item_line_parent($current)) {
- $current = $parent;
- _gather_previous_item($self, $current, $command, $source_info);
- } else {
- $self->_line_error(sprintf(__(
- "\@%s outside of table or list"), $command), $source_info);
- $current = _begin_preformatted($self, $current);
- }
- $misc = { 'cmdname' => $command, 'parent' => $current };
- push @{$current->{'contents'}}, $misc;
- $misc->{'source_info'} = $source_info;
- } else {
- $misc = { 'cmdname' => $command, 'source_info' => $source_info };
- if ($command eq 'subentry') {
- my $parent = $current->{'parent'};
- if (!_is_index_element($self, $parent)) {
- $self->_line_warn(
- sprintf(__("\@%s should only appear in an index entry"),
- $command), $source_info);
- }
- $parent->{'extra'} = {} if (!defined($parent->{'extra'}));
- $parent->{'extra'}->{'subentry'} = $misc;
- my $subentry_level = 1;
- if ($parent->{'cmdname'} eq 'subentry') {
- $subentry_level = $parent->{'extra'}->{'level'} + 1;
- }
- $misc->{'extra'} = {'level' => $subentry_level};
- if ($subentry_level > 2) {
- $self->_line_error(__(
- "no more than two levels of index subentry are allowed"),
- $source_info);
- }
- # Do not make the @subentry element a child of the index
- # command. This means that spaces are preserved properly
- # when converting back to Texinfo.
- $current = _end_line($self, $current, $source_info);
- } elsif ($sectioning_heading_commands{$command}) {
- if ($self->{'sections_level'}) {
- $misc->{'extra'} = {'sections_level' =>
$self->{'sections_level'}};
- }
- }
- push @{$current->{'contents'}}, $misc;
- $misc->{'parent'} = $current;
- # def*x
- if ($def_commands{$command}) {
- my $base_command = $command;
- $base_command =~ s/x$//;
- # check that the def*x is first after @def*, no paragraph
- # in-between.
- my $after_paragraph = _check_no_text($current);
- $self->_push_context('ct_def', $command);
- $current->{'contents'}->[-1]->{'type'} = 'def_line';
- $current->{'contents'}->[-1]->{'extra'}
- = {'def_command' => $base_command,
- 'original_def_cmdname' => $command};
- if (defined($self->{'values'}->{'txidefnamenospace'})) {
- $current->{'contents'}->[-1]{'extra'}
- ->{'omit_def_name_space'} = 1;
- }
- if ($current->{'cmdname'}
- and $current->{'cmdname'} eq $base_command) {
- # popped element should be the same as $misc
- _pop_element_from_contents($self, $current);
- _gather_def_item($self, $current, $command);
- push @{$current->{'contents'}}, $misc;
- }
- if (!$current->{'cmdname'}
- or ($current->{'cmdname'} ne $base_command
- and $current->{'cmdname'} ne 'defblock')
- or $after_paragraph) {
- $self->_line_error(sprintf(__(
- "must be after `\@%s' to use `\@%s'"),
- $base_command, $command), $source_info);
- $current->{'contents'}->[-1]->{'extra'}->{'not_after_command'} =
1;
- }
- }
- }
- $current = $current->{'contents'}->[-1];
- $current->{'args'} = [{ 'type' => 'line_arg',
- 'parent' => $current }];
- if ($self->{'basic_inline_commands'}
- and $self->{'basic_inline_commands'}->{$command}) {
- push @{$self->{'nesting_context'}->{'basic_inline_stack_on_line'}},
- $command;
- }
-
- # 'specific' commands arguments are handled in a specific way.
- # The only other line commands that have more than one argument is
- # node, so the following condition only applies to node
- if ($self->{'line_commands'}->{$command} ne 'specific'
- and $commands_args_number{$command}
- and $commands_args_number{$command} > 1) {
- $current->{'remaining_args'} = $commands_args_number{$command} - 1;
- }
- if ($command eq 'author') {
- my $parent = $current;
- my $found;
- while ($parent->{'parent'}) {
- $parent = $parent->{'parent'};
- last if ($parent->{'type'}
- and $parent->{'type'} eq 'brace_command_context');
- if ($parent->{'cmdname'}) {
- if ($parent->{'cmdname'} eq 'titlepage') {
- $current->{'extra'} = {} if (!$current->{'extra'});
- $current->{'extra'}->{'titlepage'} = $parent;
- $found = 1;
- } elsif ($parent->{'cmdname'} eq 'quotation' or
- $parent->{'cmdname'} eq 'smallquotation') {
- $parent->{'extra'} = {} if (!$parent->{'extra'});
- push @{$parent->{'extra'}->{'authors'}}, $current;
- $current->{'extra'} = {} if (!$current->{'extra'});
- $current->{'extra'}->{'quotation'} = $parent;
- $found = 1;
- }
- last if ($found);
- }
- }
- if (!$found) {
- $self->_line_warn(sprintf(__(
- "\@%s not meaningful outside `\@titlepage' and `\@quotation'
environments"),
- $command), $current->{'source_info'});
- }
- } elsif ($command eq 'dircategory' and $self->{'current_node'}) {
- $self->_line_warn(__("\@dircategory after first node"),
- $source_info);
- } elsif ($command eq 'printindex') {
- # Record that @printindex occurs in this node so we know it
- # is an index node.
- if ($self->{'current_node'}) {
- $self->{'current_node'}->{'extra'} = {}
- if (!$self->{'current_node'}->{'extra'});
- $self->{'current_node'}->{'extra'}->{'isindex'} = 1;
- }
- }
-
- $current = $current->{'args'}->[-1];
- $self->_push_context('ct_line', $command)
- unless ($def_commands{$command});
- $line = _start_empty_line_after_command($line, $current, $misc);
- }
- _register_global_command($self, $misc, $source_info)
- if $misc;
- if ($command eq 'dircategory') {
- push @{$self->{'info'}->{'dircategory_direntry'}}, $misc;
- }
+ ($current, $line, $retval)
+ = _handle_line_command($self, $current, $command, $line, $source_info);
+ # in the XS parser return here if GET_A_NEW_LINE or FINISHED_TOTALLY
# @-command with matching @end opening
} elsif (exists($block_commands{$command})) {
- if ($command eq 'macro' or $command eq 'rmacro') {
- my $macro = _parse_macro_command_line($self, $command, $line,
- $current, $source_info);
- push @{$current->{'contents'}}, $macro;
- $current = $current->{'contents'}->[-1];
- return ($current, $line, $source_info, $GET_A_NEW_LINE);
- # goto funexit; # used in XS code
- } else {
- my $block;
- # a menu command closes a menu_comment, but not the other
- # block commands. This won't catch menu commands buried in
- # other formats (that are incorrect anyway).
- if ($block_commands{$command} eq 'menu' and $current->{'type'}
- and ($current->{'type'} eq 'menu_comment'
- or $current->{'type'} eq 'menu_entry_description')) {
-
- # This is, in general, caused by @detailmenu within @menu
- if ($current->{'type'} eq 'menu_comment') {
- $current = _close_container($self, $current);
- } else { # menu_entry_description
- $current = _close_container($self, $current);
- if ($current->{'type'} and $current->{'type'} eq 'menu_entry') {
- $current = $current->{'parent'};
- } else {
- $self->_bug_message("menu description parent not a menu_entry",
- $source_info, $current);
- die;
- }
- }
- }
- # the def command holds a line_def* which corresponds with the
- # definition line. This allows to have a treatement similar
- # with def*x.
- if ($def_commands{$command}) {
- $self->_push_context('ct_def', $command);
- $block = { 'parent' => $current,
- 'cmdname' => $command,
- 'contents' => [] };
- push @{$current->{'contents'}}, $block;
- $current = $current->{'contents'}->[-1];
- push @{$current->{'contents'}}, {
- 'type' => 'def_line',
- 'parent' => $current,
- 'source_info' => $source_info,
- 'extra' =>
- {'def_command' => $command,
- 'original_def_cmdname' =>
$command}
- };
- if (defined($self->{'values'}->{'txidefnamenospace'})) {
- $current->{'contents'}->[-1]->{'extra'}
- ->{'omit_def_name_space'} = 1;
- }
- } else {
- $block = { 'cmdname' => $command,
- 'parent' => $current,
- };
- push @{$current->{'contents'}}, $block;
- }
- $current = $current->{'contents'}->[-1];
-
- if ($preformatted_commands{$command}) {
- $self->_push_context('ct_preformatted', $command);
- } elsif ($math_commands{$command}) {
- $self->_push_context('ct_math', $command);
- } elsif ($block_commands{$command} eq 'format_raw') {
- $self->_push_context('ct_rawpreformatted', $command);
- }
- if ($block_commands{$command} eq 'region') {
- push @{$self->{'nesting_context'}->{'regions_stack'}}, $command;
- }
- if ($block_commands{$command} eq 'menu') {
- $self->_push_context('ct_preformatted', $command);
- push @{$self->{'info'}->{'dircategory_direntry'}}, $block
- if ($command eq 'direntry');
- if ($self->{'current_node'}) {
- if ($command eq 'direntry') {
- if ($self->{'FORMAT_MENU'} eq 'menu') {
- $self->_line_warn(__("\@direntry after first node"),
- $source_info);
- }
- } elsif ($command eq 'menu') {
- if (!(defined $current->{'parent'}->{'cmdname'})
- or $root_commands{$current->{'parent'}->{'cmdname'}}) {
- $self->{'current_node'}->{'extra'} = {}
- if (!defined($self->{'current_node'}->{'extra'}));
- $self->{'current_node'}->{'extra'}->{'menus'} = []
- if (!defined($self->{'current_node'}->{'extra'}->{'menus'}));
- push @{$self->{'current_node'}->{'extra'}->{'menus'}},
$current;
- } else {
- $self->_line_warn(__("\@menu in invalid context"),
- $source_info);
- }
- }
- }
- }
- # cleaner, and more similar to XS parser, but not required, would have
- # been initialized automatically.
- $current->{'items_count'} = 0
- if ($block_commands{$command}
- and $block_commands{$command} eq 'item_container');
-
- $current->{'args'} = [ {
- 'type' => 'block_line_arg',
- 'parent' => $current } ];
-
- if ($commands_args_number{$command}) {
- if ($commands_args_number{$command} - 1 > 0) {
- $current->{'remaining_args'}
- = $commands_args_number{$command} - 1;
- }
- } elsif ($variadic_commands{$command}) {
- $current->{'remaining_args'} = -1; # unlimited args
- }
- $current = $current->{'args'}->[-1];
- $self->_push_context('ct_line', $command)
- unless ($def_commands{$command});
- if ($self->{'basic_inline_commands'}->{$command}) {
- push @{$self->{'nesting_context'}->{'basic_inline_stack_block'}},
- $command;
- }
- $block->{'source_info'} = $source_info;
- _register_global_command($self, $block, $source_info);
- $line = _start_empty_line_after_command($line, $current, $block);
- }
+ ($current, $line, $retval)
+ = _handle_block_command($self, $current, $command, $line, $source_info);
+ # in the XS parser return here if GET_A_NEW_LINE
} elsif (defined($self->{'brace_commands'}->{$command})) {
- print STDERR "OPEN BRACE \@$command\n"
- if ($self->{'DEBUG'});
- push @{$current->{'contents'}}, { 'cmdname' => $command,
- 'parent' => $current,
- };
- $current->{'contents'}->[-1]->{'source_info'} = $source_info;
- if ($in_index_commands{$command}
- and !_is_index_element($self, $current->{'parent'})) {
- $self->_line_warn(
- sprintf(__("\@%s should only appear in an index entry"),
- $command), $source_info);
- }
- $current = $current->{'contents'}->[-1];
- if ($command eq 'click') {
- $current->{'extra'} = {} if (!$current->{'extra'});
- $current->{'extra'}->{'clickstyle'} = $self->{'clickstyle'};
- } elsif ($command eq 'kbd'
- and _kbd_formatted_as_code($self, $current)) {
- $current->{'extra'} = {} if (!$current->{'extra'});
- $current->{'extra'}->{'code'} = 1;
- }
- if ($self->{'definfoenclose'}->{$command}) {
- $current->{'type'} = 'definfoenclose_command';
- $current->{'extra'} = {} if (!$current->{'extra'});
- $current->{'extra'}->{'begin'}
- = $self->{'definfoenclose'}->{$command}->[0];
- $current->{'extra'}->{'end'}
- = $self->{'definfoenclose'}->{$command}->[1];
- }
+ $current = _handle_brace_command($self, $current, $command,
$source_info);
}
} elsif ($separator_match) {
my $separator = $separator_match;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- branch master updated: * tp/Texinfo/ParserNonXS.pm (_handle_other_command) (_handle_line_command, _handle_block_command, _handle_brace_command) (_process_remaining_on_line): split handle_*_command out of _process_remaining_on_line as in the XS parser.,
Patrice Dumas <=
- Prev by Date:
branch master updated: * tp/Texinfo/ParserNonXS.pm (_end_line_menu_entry, _end_line), tp/Texinfo/XS/parsetexi/end_line.c (end_line), tp/Texinfo/XS/parsetexi/menus.c (end_line_menu_entry): put code handling end of menu entry from end_line in its own function end_line_menu_entry.
- Next by Date:
branch master updated: * tp/Texinfo/ParserNonXS.pm (_process_remaining_on_line), tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line), tp/Texinfo/XS/parsetexi/handle_commands.c (handle_line_command): for @item, there is a difference between the command name, and the name used to access data information, which is item_LINE. Check preferentially command data with the modified name and use the original name in messages and command name checks. Pass both the original command and the data access name to han [...]
- Previous by thread:
branch master updated: * tp/Texinfo/ParserNonXS.pm (_end_line_menu_entry, _end_line), tp/Texinfo/XS/parsetexi/end_line.c (end_line), tp/Texinfo/XS/parsetexi/menus.c (end_line_menu_entry): put code handling end of menu entry from end_line in its own function end_line_menu_entry.
- Next by thread:
branch master updated: * tp/Texinfo/ParserNonXS.pm (_process_remaining_on_line), tp/Texinfo/XS/parsetexi/parser.c (process_remaining_on_line), tp/Texinfo/XS/parsetexi/handle_commands.c (handle_line_command): for @item, there is a difference between the command name, and the name used to access data information, which is item_LINE. Check preferentially command data with the modified name and use the original name in messages and command name checks. Pass both the original command and the data access name to han [...]
- Index(es):