summaryrefslogtreecommitdiff
path: root/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-11-09 03:02:50 +0000
committerNorbert Preining <norbert@preining.info>2022-11-09 03:02:50 +0000
commit5de83ec843cdc88e6adc42b1fe3f0ec48c52b7f3 (patch)
treeb49f7c180396c8ef389c8fd519370b6d03f4e100 /macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi
parent118cb5bbc5236bf86ca1088b9b3bae04c7b09beb (diff)
CTAN sync 202211090302
Diffstat (limited to 'macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi')
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.c152
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.pm400
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.xs34
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.c395
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.h12
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/close.c141
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.awk28
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.c728
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.txt802
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_ids.h8
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.c79
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.h86
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.c1
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.h1
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.c55
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.h14
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/convert.c9
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/def.c9
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.c24
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.h24
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.txt24
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/end_line.c257
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.c156
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.h16
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/handle_commands.c483
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.c39
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.h1
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.c279
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.h14
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/macro.c41
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/menus.c17
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.c1138
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.h38
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/separator.c102
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/text.c6
-rw-r--r--macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/tree_types.h14
36 files changed, 3124 insertions, 2503 deletions
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.c
index 0a123eeae6..565c42e7b4 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.c
@@ -1,5 +1,5 @@
/*
- * This file was generated automatically by ExtUtils::ParseXS version 3.34 from the
+ * This file was generated automatically by ExtUtils::ParseXS version 3.40 from the
* contents of Parsetexi.xs. Do not edit this file, edit Parsetexi.xs instead.
*
* ANY CHANGES MADE HERE WILL BE LOST!
@@ -7,6 +7,8 @@
*/
#line 1 "parsetexi/Parsetexi.xs"
+#include <config.h>
+
/* Avoid namespace conflicts. */
#define context perl_context
@@ -24,7 +26,7 @@
#include "indices.h"
#include "input.h"
-#line 28 "parsetexi/Parsetexi.c"
+#line 30 "parsetexi/Parsetexi.c"
#ifndef PERL_UNUSED_VAR
# define PERL_UNUSED_VAR(var) if (0) var = var
#endif
@@ -168,7 +170,7 @@ S_croak_xs_usage(const CV *const cv, const char *const params)
# define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
#endif
-#line 172 "parsetexi/Parsetexi.c"
+#line 174 "parsetexi/Parsetexi.c"
XS_EUPXS(XS_Texinfo__Parser_init); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Texinfo__Parser_init)
@@ -191,23 +193,6 @@ XS_EUPXS(XS_Texinfo__Parser_init)
}
-XS_EUPXS(XS_Texinfo__Parser_dump_errors); /* prototype to pass -Wmissing-prototypes */
-XS_EUPXS(XS_Texinfo__Parser_dump_errors)
-{
- dVAR; dXSARGS;
- if (items != 0)
- croak_xs_usage(cv, "");
- {
- char * RETVAL;
- dXSTARG;
-
- RETVAL = dump_errors();
- sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
- }
- XSRETURN(1);
-}
-
-
XS_EUPXS(XS_Texinfo__Parser_wipe_errors); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Texinfo__Parser_wipe_errors)
{
@@ -241,17 +226,37 @@ XS_EUPXS(XS_Texinfo__Parser_parse_file)
}
+XS_EUPXS(XS_Texinfo__Parser_parse_piece); /* prototype to pass -Wmissing-prototypes */
+XS_EUPXS(XS_Texinfo__Parser_parse_piece)
+{
+ dVAR; dXSARGS;
+ if (items != 2)
+ croak_xs_usage(cv, "string, line_nr");
+ {
+ char * string = (char *)SvPV_nolen(ST(0))
+;
+ int line_nr = (int)SvIV(ST(1))
+;
+
+ parse_piece(string, line_nr);
+ }
+ XSRETURN_EMPTY;
+}
+
+
XS_EUPXS(XS_Texinfo__Parser_parse_string); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Texinfo__Parser_parse_string)
{
dVAR; dXSARGS;
- if (items != 1)
- croak_xs_usage(cv, "string");
+ if (items != 2)
+ croak_xs_usage(cv, "string, line_nr");
{
char * string = (char *)SvPV_nolen(ST(0))
;
+ int line_nr = (int)SvIV(ST(1))
+;
- parse_string(string);
+ parse_string(string, line_nr);
}
XSRETURN_EMPTY;
}
@@ -261,13 +266,15 @@ XS_EUPXS(XS_Texinfo__Parser_parse_text); /* prototype to pass -Wmissing-prototyp
XS_EUPXS(XS_Texinfo__Parser_parse_text)
{
dVAR; dXSARGS;
- if (items != 1)
- croak_xs_usage(cv, "string");
+ if (items != 2)
+ croak_xs_usage(cv, "string, line_nr");
{
char * string = (char *)SvPV_nolen(ST(0))
;
+ int line_nr = (int)SvIV(ST(1))
+;
- parse_text(string);
+ parse_text(string, line_nr);
}
XSRETURN_EMPTY;
}
@@ -588,8 +595,8 @@ XS_EUPXS(XS_Texinfo__Parser_conf_set_IGNORE_SPACE_AFTER_BRACED_COMMAND_NAME)
}
-XS_EUPXS(XS_Texinfo__Parser_set_novalidate); /* prototype to pass -Wmissing-prototypes */
-XS_EUPXS(XS_Texinfo__Parser_set_novalidate)
+XS_EUPXS(XS_Texinfo__Parser_set_DOC_ENCODING_FOR_INPUT_FILE_NAME); /* prototype to pass -Wmissing-prototypes */
+XS_EUPXS(XS_Texinfo__Parser_set_DOC_ENCODING_FOR_INPUT_FILE_NAME)
{
dVAR; dXSARGS;
if (items != 1)
@@ -598,14 +605,14 @@ XS_EUPXS(XS_Texinfo__Parser_set_novalidate)
int i = (int)SvIV(ST(0))
;
- set_novalidate(i);
+ set_DOC_ENCODING_FOR_INPUT_FILE_NAME(i);
}
XSRETURN_EMPTY;
}
-XS_EUPXS(XS_Texinfo__Parser_set_documentlanguage); /* prototype to pass -Wmissing-prototypes */
-XS_EUPXS(XS_Texinfo__Parser_set_documentlanguage)
+XS_EUPXS(XS_Texinfo__Parser_conf_set_input_file_name_encoding); /* prototype to pass -Wmissing-prototypes */
+XS_EUPXS(XS_Texinfo__Parser_conf_set_input_file_name_encoding)
{
dVAR; dXSARGS;
if (items != 1)
@@ -614,7 +621,39 @@ XS_EUPXS(XS_Texinfo__Parser_set_documentlanguage)
char * value = (char *)SvPV_nolen(ST(0))
;
- set_documentlanguage(value);
+ conf_set_input_file_name_encoding(value);
+ }
+ XSRETURN_EMPTY;
+}
+
+
+XS_EUPXS(XS_Texinfo__Parser_conf_set_locale_encoding); /* prototype to pass -Wmissing-prototypes */
+XS_EUPXS(XS_Texinfo__Parser_conf_set_locale_encoding)
+{
+ dVAR; dXSARGS;
+ if (items != 1)
+ croak_xs_usage(cv, "value");
+ {
+ char * value = (char *)SvPV_nolen(ST(0))
+;
+
+ conf_set_locale_encoding(value);
+ }
+ XSRETURN_EMPTY;
+}
+
+
+XS_EUPXS(XS_Texinfo__Parser_conf_set_documentlanguage_override); /* prototype to pass -Wmissing-prototypes */
+XS_EUPXS(XS_Texinfo__Parser_conf_set_documentlanguage_override)
+{
+ dVAR; dXSARGS;
+ if (items != 1)
+ croak_xs_usage(cv, "value");
+ {
+ char * value = (char *)SvPV_nolen(ST(0))
+;
+
+ conf_set_documentlanguage_override(value);
}
XSRETURN_EMPTY;
}
@@ -635,6 +674,41 @@ XS_EUPXS(XS_Texinfo__Parser_set_debug)
XSRETURN_EMPTY;
}
+
+XS_EUPXS(XS_Texinfo__Parser_set_accept_internalvalue); /* prototype to pass -Wmissing-prototypes */
+XS_EUPXS(XS_Texinfo__Parser_set_accept_internalvalue)
+{
+ dVAR; dXSARGS;
+ if (items != 0)
+ croak_xs_usage(cv, "");
+ {
+
+ set_accept_internalvalue();
+ }
+ XSRETURN_EMPTY;
+}
+
+
+XS_EUPXS(XS_Texinfo__Parser_get_errors); /* prototype to pass -Wmissing-prototypes */
+XS_EUPXS(XS_Texinfo__Parser_get_errors)
+{
+ dVAR; dXSARGS;
+ if (items != 0)
+ croak_xs_usage(cv, "");
+ {
+ AV * RETVAL;
+
+ RETVAL = get_errors();
+ {
+ SV * RETVALSV;
+ RETVALSV = newRV((SV*)RETVAL);
+ RETVALSV = sv_2mortal(RETVALSV);
+ ST(0) = RETVALSV;
+ }
+ }
+ XSRETURN(1);
+}
+
#ifdef __cplusplus
extern "C"
#endif
@@ -664,11 +738,11 @@ XS_EXTERNAL(boot_Texinfo__Parser)
#endif
(void)newXSproto_portable("Texinfo::Parser::init", XS_Texinfo__Parser_init, file, "$$");
- (void)newXSproto_portable("Texinfo::Parser::dump_errors", XS_Texinfo__Parser_dump_errors, file, "");
(void)newXSproto_portable("Texinfo::Parser::wipe_errors", XS_Texinfo__Parser_wipe_errors, file, "");
(void)newXSproto_portable("Texinfo::Parser::parse_file", XS_Texinfo__Parser_parse_file, file, "$");
- (void)newXSproto_portable("Texinfo::Parser::parse_string", XS_Texinfo__Parser_parse_string, file, "$");
- (void)newXSproto_portable("Texinfo::Parser::parse_text", XS_Texinfo__Parser_parse_text, file, "$");
+ (void)newXSproto_portable("Texinfo::Parser::parse_piece", XS_Texinfo__Parser_parse_piece, file, "$$");
+ (void)newXSproto_portable("Texinfo::Parser::parse_string", XS_Texinfo__Parser_parse_string, file, "$$");
+ (void)newXSproto_portable("Texinfo::Parser::parse_text", XS_Texinfo__Parser_parse_text, file, "$$");
(void)newXSproto_portable("Texinfo::Parser::store_value", XS_Texinfo__Parser_store_value, file, "$$");
(void)newXSproto_portable("Texinfo::Parser::wipe_values", XS_Texinfo__Parser_wipe_values, file, "");
(void)newXSproto_portable("Texinfo::Parser::reset_context_stack", XS_Texinfo__Parser_reset_context_stack, file, "");
@@ -687,9 +761,13 @@ XS_EXTERNAL(boot_Texinfo__Parser)
(void)newXSproto_portable("Texinfo::Parser::conf_set_show_menu", XS_Texinfo__Parser_conf_set_show_menu, file, "$");
(void)newXSproto_portable("Texinfo::Parser::conf_set_CPP_LINE_DIRECTIVES", XS_Texinfo__Parser_conf_set_CPP_LINE_DIRECTIVES, file, "$");
(void)newXSproto_portable("Texinfo::Parser::conf_set_IGNORE_SPACE_AFTER_BRACED_COMMAND_NAME", XS_Texinfo__Parser_conf_set_IGNORE_SPACE_AFTER_BRACED_COMMAND_NAME, file, "$");
- (void)newXSproto_portable("Texinfo::Parser::set_novalidate", XS_Texinfo__Parser_set_novalidate, file, "$");
- (void)newXSproto_portable("Texinfo::Parser::set_documentlanguage", XS_Texinfo__Parser_set_documentlanguage, file, "$");
+ (void)newXSproto_portable("Texinfo::Parser::set_DOC_ENCODING_FOR_INPUT_FILE_NAME", XS_Texinfo__Parser_set_DOC_ENCODING_FOR_INPUT_FILE_NAME, file, "$");
+ (void)newXSproto_portable("Texinfo::Parser::conf_set_input_file_name_encoding", XS_Texinfo__Parser_conf_set_input_file_name_encoding, file, "$");
+ (void)newXSproto_portable("Texinfo::Parser::conf_set_locale_encoding", XS_Texinfo__Parser_conf_set_locale_encoding, file, "$");
+ (void)newXSproto_portable("Texinfo::Parser::conf_set_documentlanguage_override", XS_Texinfo__Parser_conf_set_documentlanguage_override, file, "$");
(void)newXSproto_portable("Texinfo::Parser::set_debug", XS_Texinfo__Parser_set_debug, file, "$");
+ (void)newXSproto_portable("Texinfo::Parser::set_accept_internalvalue", XS_Texinfo__Parser_set_accept_internalvalue, file, "");
+ (void)newXSproto_portable("Texinfo::Parser::get_errors", XS_Texinfo__Parser_get_errors, file, "");
#if PERL_VERSION_LE(5, 21, 5)
# if PERL_VERSION_GE(5, 9, 0)
if (PL_unitcheckav)
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.pm b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.pm
index ee88072f24..25f3672ae1 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.pm
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.pm
@@ -1,4 +1,4 @@
-# Copyright 2014-2020 Free Software Foundation, Inc.
+# Copyright 2014-2022 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -13,7 +13,35 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# Since there are different parser implementation, XS and NonXS, it is
+# better to have the Texinfo::Parser packages define only the parser
+# API functions. Constants, functions useful in both parsers, and other
+# functions useful in other codes are better defined in other Texinfo
+# modules.
+
# File to be loaded in conjunction with Parsetexi.xs module
+#
+# FIXME two customization keys are duplicated from the main parser in
+# gdt(), which are set and used by the NonXS parser, 'kbdinputstyle'
+# and 'clickstyle'. The XS parser does not set nor use those keys, so
+# their values are not passed to gdt().
+# As long as there is no other code that sets those keys to another value than
+# their default value, and that there are no translated strings containing the
+# @-commands whose output is modified by those customization keys, however,
+# the difference between the parsers won't have any visible effect.
+
+# In general, the Parser works with character strings decoded from the
+# command line, from input files or from the parsed document and returns
+# character strings. There are exceptions for the following files and
+# directory names that are binary strings:
+# * the input file name passed through parse_texi_file is a binary string
+# * the 'file_name' values in 'source_info' from convert_errors and in
+# the tree elements 'source_info' are returned as binary strings
+#
+# The following parser information is directly determined from the
+# input file name as binary strings
+# ->{'info'}->{'input_file_name'}
+# ->{'info'}->{'input_directory'}
package Texinfo::Parser;
@@ -21,26 +49,32 @@ use 5.00405;
use strict;
use warnings;
-require Exporter;
+# To check if there is no erroneous autovivification
+#no autovivification qw(fetch delete exists store strict);
+
+use Storable qw(dclone); # standard in 5.007003
+use Encode qw(decode);
use Texinfo::Common;
-use Texinfo::Encoding;
-use Texinfo::Convert::NodeNameNormalization;
use Texinfo::Report;
+use Texinfo::Convert::NodeNameNormalization;
+use Texinfo::Translations;
+
+require Exporter;
-our @ISA = qw(Exporter DynaLoader Texinfo::Report);
+our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
parser
- parse_texi_text
- parse_texi_line
parse_texi_file
+ parse_texi_line
+ parse_texi_piece
+ parse_texi_text
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
-our @EXPORT = qw(
-
-);
+my %parser_default_configuration =
+ (%Texinfo::Common::default_parser_customization_values);
sub get_conf($$)
{
@@ -49,17 +83,11 @@ sub get_conf($$)
return $self->{$var};
}
-my %parser_default_configuration =
- (%Texinfo::Common::default_parser_state_configuration,
- %Texinfo::Common::default_parser_customization_values);
-
-use Storable qw(dclone); # standard in 5.007003
-
sub simple_parser {
goto &parser;
}
-# Stub for Texinfo::Parser::parser
+# Initialize the parser
sub parser (;$$)
{
my $conf = shift;
@@ -69,33 +97,27 @@ sub parser (;$$)
reset_parser ();
if (defined($conf)) {
foreach my $key (keys (%$conf)) {
- # Copy conf to parser object. Not used in parser module itself
- # but some settings may be used elsewhere, especially in
- # Structuring.pm.
- if ($key ne 'values' and ref($conf->{$key})) {
+ # Copy conf to parser object.
+ # we keep registrar instead of copying on purpose, to reuse the object
+ if ($key ne 'values' and $key ne 'registrar' and ref($conf->{$key})) {
$parser->{$key} = dclone($conf->{$key});
} else {
$parser->{$key} = $conf->{$key};
}
- if ($key eq 'include_directories') {
- foreach my $d (@{$conf->{'include_directories'}}) {
+ if ($key eq 'INCLUDE_DIRECTORIES') {
+ foreach my $d (@{$conf->{'INCLUDE_DIRECTORIES'}}) {
add_include_directory ($d);
}
} elsif ($key eq 'values') {
- # This is used by Texinfo::Report::gdt for substituted values
- for my $v (keys %{$conf->{'values'}}) {
- if (!ref($conf->{'values'}->{$v})) {
- store_value ($v, $conf->{'values'}->{$v});
- } elsif (ref($conf->{'values'}->{$v}) eq 'HASH') {
- store_value ($v, "<<HASH VALUE>>");
- } elsif (ref($conf->{'values'}->{$v}) eq 'ARRAY') {
- store_value ($v, "<<ARRAY VALUE>>");
- } else {
- store_value ($v, "<<UNKNOWN VALUE>>");
- }
- }
- } elsif ($key eq 'expanded_formats') {
+ for my $v (keys %{$conf->{'values'}}) {
+ if (ref($conf->{'values'}->{$v}) eq '') {
+ store_value ($v, $conf->{'values'}->{$v});
+ } else {
+ warn "bug: non-scalar \@value\n";
+ }
+ }
+ } elsif ($key eq 'EXPANDED_FORMATS') {
clear_expanded_formats ();
for my $f (@{$conf->{$key}}) {
@@ -103,11 +125,7 @@ sub parser (;$$)
}
} elsif ($key eq 'documentlanguage') {
if (defined ($conf->{$key})) {
- set_documentlanguage ($conf->{$key});
- }
- } elsif ($key eq 'info') {
- if (defined($conf->{$key}->{'novalidate'})) {
- set_novalidate($conf->{$key}->{'novalidate'});
+ conf_set_documentlanguage_override ($conf->{$key});
}
} elsif ($key eq 'FORMAT_MENU') {
if ($conf->{$key} eq 'menu') {
@@ -120,11 +138,17 @@ sub parser (;$$)
} elsif ($key eq 'CPP_LINE_DIRECTIVES') {
conf_set_CPP_LINE_DIRECTIVES($conf->{$key});
} elsif ($key eq 'DEBUG') {
- set_debug($conf->{$key}) if $conf->{'key'};
- } elsif ($key eq 'in_gdt'
- or $key eq 'ENABLE_ENCODING'
- or defined($Texinfo::Common::default_structure_customization_values{$key})) {
- # no action needed
+ set_debug($conf->{$key}) if $conf->{$key};
+ } elsif ($key eq 'DOC_ENCODING_FOR_INPUT_FILE_NAME') {
+ set_DOC_ENCODING_FOR_INPUT_FILE_NAME ($conf->{$key});
+ } elsif ($key eq 'INPUT_FILE_NAME_ENCODING' and defined($conf->{$key})) {
+ conf_set_input_file_name_encoding ($conf->{$key});
+ } elsif ($key eq 'LOCALE_ENCODING' and defined($conf->{$key})) {
+ conf_set_locale_encoding ($conf->{$key});
+ } elsif ($key eq 'accept_internalvalue') {
+ set_accept_internalvalue();
+ } elsif ($key eq 'registrar' or $key eq 'COMMAND_LINE_ENCODING') {
+ # no action needed, only used in perl code
} else {
warn "ignoring parser configuration value \"$key\"\n";
}
@@ -133,12 +157,10 @@ sub parser (;$$)
bless $parser;
- $parser->Texinfo::Report::new;
-
return $parser;
}
-# Record any @menu elements under $root in the 'menus' array of $node.
+# Record any @menu elements under $root in the extra 'menus' array of $node.
sub _find_menus_of_node {
my $node = shift;
my $root = shift;
@@ -147,7 +169,7 @@ sub _find_menus_of_node {
my $contents = $root->{'contents'};
foreach my $child (@{$contents}) {
if ($child->{'cmdname'} and $child->{'cmdname'} eq 'menu') {
- push @{$node->{'menus'}}, $child;
+ push @{$node->{'extra'}->{'menus'}}, $child;
}
}
}
@@ -155,13 +177,10 @@ sub _find_menus_of_node {
# Set 'menus' array for each node. This accounts for malformed input where
# the number of sectioning commands between @node and @menu is not exactly 1.
-sub _complete_node_menus {
+sub _associate_node_menus {
my $self = shift;
my $root = shift;
- if (!defined $self->{'nodes'}) {
- $self->{'nodes'} = [];
- }
my $node;
foreach my $child (@{$root->{'contents'}}) {
if ($child->{'cmdname'} and $child->{'cmdname'} eq 'node') {
@@ -171,106 +190,88 @@ sub _complete_node_menus {
}
}
-sub get_parser_info {
+sub _get_error_registrar($)
+{
my $self = shift;
+ if (not $self->{'registrar'}) {
+ $self->{'registrar'} = Texinfo::Report::new();
+ }
+ my $registrar = $self->{'registrar'};
+ my $configuration_information = $self;
+ return $registrar, $configuration_information;
+}
- my ($TARGETS, $INTL_XREFS, $FLOATS,
- $INDEX_NAMES, $ERRORS, $GLOBAL_INFO, $GLOBAL_INFO2);
+# done after all the parsings. Part may not make much sense for parse_texi_line,
+# we nevertheless do it in any case to do the same as in ParserNonXS
+sub _set_errors_node_lists_labels_indices($)
+{
+ my $self = shift;
- $TARGETS = build_label_list ();
- $INTL_XREFS = build_internal_xref_list ();
- $FLOATS = build_float_list ();
+ my $TARGETS = build_label_list ();
+ $self->{'targets'} = $TARGETS;
+
+ _get_errors ($self);
+ # Setup labels info and nodes list based on 'targets'
+ Texinfo::Convert::NodeNameNormalization::set_nodes_list_labels($self,
+ $self->{'registrar'}, $self);
- $INDEX_NAMES = build_index_data ();
+ my $INDEX_NAMES = build_index_data ();
$self->{'index_names'} = $INDEX_NAMES;
+ Texinfo::Translations::complete_indices ($self);
+}
+
+sub get_parser_info {
+ my $self = shift;
+
+ my ($INTL_XREFS, $FLOATS, $ERRORS, $GLOBAL_INFO, $GLOBAL_INFO2);
+ $INTL_XREFS = build_internal_xref_list ();
+ $FLOATS = build_float_list ();
$GLOBAL_INFO = build_global_info ();
$GLOBAL_INFO2 = build_global_info2 ();
- $self->{'targets'} = $TARGETS;
- $self->{'labels'} = {};
$self->{'internal_references'} = $INTL_XREFS;
$self->{'floats'} = $FLOATS;
$self->{'info'} = $GLOBAL_INFO;
- $self->{'extra'} = $GLOBAL_INFO2;
-
- # Propagate these settings from 'info' hash to 'values' hash.
- # The 'values' hash is not otherwise used. Maybe we should use
- # the 'info' hash for this instead in the pure Perl code.
- for my $txi_flag ('txiindexatsignignore', 'txiindexbackslashignore',
- 'txiindexhyphenignore', 'txiindexlessthanignore') {
- if ($self->{'info'}->{$txi_flag}) {
- $self->{'values'}->{$txi_flag} = 1;
- }
- }
+ $self->{'commands_info'} = $GLOBAL_INFO2;
- _get_errors ($self);
- Texinfo::Common::complete_indices ($self);
+ _set_errors_node_lists_labels_indices($self);
}
use File::Basename; # for fileparse
-# Handle 'IGNORE_BEFORE_SETFILENAME' conf value.
-# Put everything before @setfilename in a special type. This allows
-# ignoring everything before @setfilename.
-sub _maybe_ignore_before_setfilename {
- my ($self, $text_root) = @_;
-
- if ($self->{'IGNORE_BEFORE_SETFILENAME'} and $text_root
- and $self->{'extra'}->{'setfilename'}
- and $self->{'extra'}->{'setfilename'}->{'parent'} eq $text_root) {
- my $before_setfilename = {'type' => 'preamble_before_setfilename',
- 'parent' => $text_root,
- 'contents' => []};
- while (@{$text_root->{'contents'}}
- and (!$text_root->{'contents'}->[0]->{'cmdname'}
- or $text_root->{'contents'}->[0]->{'cmdname'} ne 'setfilename')) {
- my $content = shift @{$text_root->{'contents'}};
- $content->{'parent'} = $before_setfilename;
- push @{$before_setfilename->{'contents'}}, $content;
- }
- if (!@{$text_root->{'contents'}}) {
- # not found
- #splice @{$text_root->{'contents'}}, 0, 0, @$before_setfilename;
- $text_root->{'contents'} = $before_setfilename->{'contents'};
- } else {
- unshift (@{$text_root->{'contents'}}, $before_setfilename)
- if (@{$before_setfilename->{'contents'}});
- }
- }
-}
-
# Replacement for Texinfo::Parser::parse_texi_file
sub parse_texi_file ($$)
{
my $self = shift;
- my $file_name = shift;
+ my $input_file_path = shift;
my $tree_stream;
- my $status = parse_file ($file_name);
+ my $status = parse_file ($input_file_path);
if ($status) {
- # TODO: internationalise this message?
- $self->document_error(sprintf("could not open %s: %s", $file_name, $!));
+ my ($registrar, $configuration_information) = _get_error_registrar($self);
+ my $input_file_name = $input_file_path;
+ my $encoding = $self->get_conf('COMMAND_LINE_ENCODING');
+ if (defined($encoding)) {
+ $input_file_name = decode($encoding, $input_file_path);
+ }
+ $registrar->document_error($configuration_information,
+ sprintf(__("could not open %s: %s"), $input_file_name, $!));
return undef;
}
my $TREE = build_texinfo_tree ();
get_parser_info ($self);
- _complete_node_menus ($self, $TREE);
-
- my $text_root;
- if ($TREE->{'type'} eq 'text_root') {
- $text_root = $TREE;
- } elsif ($TREE->{'contents'} and $TREE->{'contents'}->[0]
- and $TREE->{'contents'}->[0]->{'type'} eq 'text_root') {
- $text_root = $TREE->{'contents'}->[0];
- }
- _maybe_ignore_before_setfilename($self, $text_root);
+ _associate_node_menus ($self, $TREE);
+
+ my $before_node_section = $TREE->{'contents'}->[0];
+
+ Texinfo::Common::rearrange_tree_beginning($self, $before_node_section);
############################################################
- my ($basename, $directories, $suffix) = fileparse($file_name);
+ my ($basename, $directories, $suffix) = fileparse($input_file_path);
$self->{'info'}->{'input_file_name'} = $basename;
$self->{'info'}->{'input_directory'} = $directories;
@@ -278,77 +279,113 @@ sub parse_texi_file ($$)
}
# Copy the errors into the error list in Texinfo::Report.
-# TODO: Could we just access the error list directly instead of going
-# through Texinfo::Report line_error?
sub _get_errors($)
{
my $self = shift;
- my $ERRORS;
- my $tree_stream = dump_errors();
- eval $tree_stream;
+ my ($registrar, $configuration_information) = _get_error_registrar($self);
+
+ my $ERRORS = get_errors ();
+
for my $error (@{$ERRORS}) {
if ($error->{'type'} eq 'error') {
- $self->line_error ($error->{'message'}, $error->{'line_nr'});
+ $registrar->line_error ($configuration_information,
+ $error->{'message'}, $error->{'source_info'});
} else {
- $self->line_warn ($error->{'message'}, $error->{'line_nr'});
+ $registrar->line_warn ($configuration_information,
+ $error->{'message'}, $error->{'source_info'});
}
}
}
+
+# Replacement for Texinfo::Parser::parse_texi_piece
+#
+# Used in tests under tp/t.
+sub parse_texi_piece($$;$$$$)
+{
+ my $self = shift;
+ my $text = shift;
+ my $lines_nr = shift;
+ my $file = shift;
+ my $macro = shift;
+ my $fixed_line_number = shift;
+
+ return undef if (!defined($text));
+
+ $lines_nr = 1 if (not defined($lines_nr));
+
+ $self = parser() if (!defined($self));
+
+ # make sure that internal byte buffer is in UTF-8 before we pass
+ # it in to the XS code.
+ utf8::upgrade($text);
+
+ parse_piece($text, $lines_nr);
+ my $tree = build_texinfo_tree ();
+
+ get_parser_info($self);
+ _associate_node_menus ($self, $tree);
+
+ return $tree;
+}
+
# Replacement for Texinfo::Parser::parse_texi_text
#
# Used in tests under tp/t.
sub parse_texi_text($$;$$$$)
{
- my $self = shift;
- my $text = shift;
- my $lines_nr = shift;
- my $file = shift;
- my $macro = shift;
- my $fixed_line_number = shift;
-
- return undef if (!defined($text));
-
- $self = parser() if (!defined($self));
-
- # make sure that internal byte buffer is in UTF-8 before we pass
- # it in to the XS code.
- utf8::upgrade($text);
-
- parse_text($text);
- my $tree = build_texinfo_tree ();
- my $INDEX_NAMES = build_index_data ();
- $self->{'index_names'} = $INDEX_NAMES;
-
- for my $index (keys %$INDEX_NAMES) {
- if ($INDEX_NAMES->{$index}->{'merged_in'}) {
- $self->{'merged_indices'}-> {$index}
- = $INDEX_NAMES->{$index}->{'merged_in'};
- }
- }
+ my $self = shift;
+ my $text = shift;
+ my $lines_nr = shift;
+ my $file = shift;
+ my $macro = shift;
+ my $fixed_line_number = shift;
+
+ return undef if (!defined($text));
+
+ $lines_nr = 1 if (not defined($lines_nr));
+
+ $self = parser() if (!defined($self));
+
+ # make sure that internal byte buffer is in UTF-8 before we pass
+ # it in to the XS code.
+ utf8::upgrade($text);
- get_parser_info($self);
- _complete_node_menus ($self, $tree);
- return $tree;
+ parse_text($text, $lines_nr);
+ my $tree = build_texinfo_tree ();
+
+ get_parser_info($self);
+
+ _associate_node_menus ($self, $tree);
+
+ my $before_node_section = $tree->{'contents'}->[0];
+
+ Texinfo::Common::rearrange_tree_beginning($self, $before_node_section);
+ return $tree;
}
# Replacement for Texinfo::Parser::parse_texi_line
sub parse_texi_line($$;$$$$)
{
- my $self = shift;
- my $text = shift;
- my $lines_nr = shift;
- my $file = shift;
- my $macro = shift;
- my $fixed_line_number = shift;
-
- return undef if (!defined($text));
-
- $self = parser() if (!defined($self));
- utf8::upgrade($text);
- parse_string($text);
- my $tree = build_texinfo_tree ();
- return $tree;
+ my $self = shift;
+ my $text = shift;
+ my $lines_nr = shift;
+ my $file = shift;
+ my $macro = shift;
+ my $fixed_line_number = shift;
+
+ return undef if (!defined($text));
+
+ $lines_nr = 1 if (not defined($lines_nr));
+
+ $self = parser() if (!defined($self));
+ utf8::upgrade($text);
+ parse_string($text, $lines_nr);
+ my $tree = build_texinfo_tree ();
+
+ _set_errors_node_lists_labels_indices($self);
+
+ return $tree;
}
# Public interfaces of Texinfo::Parser
@@ -356,11 +393,6 @@ sub indices_information($)
{
my $self = shift;
- my $INDEX_NAMES;
- if (!$self->{'index_names'}) {
- $INDEX_NAMES = build_index_data ();
- $self->{'index_names'} = $INDEX_NAMES;
- }
return $self->{'index_names'};
}
@@ -379,20 +411,28 @@ sub internal_references_information($)
sub global_commands_information($)
{
my $self = shift;
- return $self->{'extra'};
+ return $self->{'commands_info'};
}
-sub global_informations($)
+sub global_information($)
{
my $self = shift;
return $self->{'info'};
}
-# Setup labels and nodes info and return labels
sub labels_information($)
{
- goto &Texinfo::Common::labels_information;
+ my $self = shift;
+ return $self->{'labels'}, $self->{'targets'}, $self->{'nodes'};
+}
+
+sub registered_errors($)
+{
+ my $self = shift;
+ return $self->{'registrar'};
}
1;
__END__
+
+The POD documentation of Texinfo::Parser is in Texinfo::ParserNonXS.
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.xs b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.xs
index 66cd76e145..d5972061fa 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.xs
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/Parsetexi.xs
@@ -1,3 +1,5 @@
+#include <config.h>
+
/* Avoid namespace conflicts. */
#define context perl_context
@@ -24,9 +26,6 @@ init (texinfo_uninstalled, srcdir)
int texinfo_uninstalled
char *srcdir
-char *
-dump_errors ()
-
void
wipe_errors ()
@@ -35,12 +34,19 @@ parse_file(filename)
char * filename
void
-parse_string(string)
+parse_piece(string, line_nr)
+ char * string
+ int line_nr
+
+void
+parse_string(string, line_nr)
char * string
+ int line_nr
void
-parse_text(string)
+parse_text(string, line_nr)
char * string
+ int line_nr
void
store_value (name, value)
@@ -101,11 +107,25 @@ void
conf_set_IGNORE_SPACE_AFTER_BRACED_COMMAND_NAME (int i)
void
-set_novalidate (int i)
+set_DOC_ENCODING_FOR_INPUT_FILE_NAME (int i)
+
+void
+conf_set_input_file_name_encoding (value)
+ char *value
void
-set_documentlanguage (value)
+conf_set_locale_encoding (value)
+ char *value
+
+void
+conf_set_documentlanguage_override (value)
char *value
void
set_debug (int i)
+
+void
+set_accept_internalvalue()
+
+AV *
+get_errors ()
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.c
index f85ceff097..8066dcad0c 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.c
@@ -1,4 +1,4 @@
-/* Copyright 2010-2021 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,6 +21,11 @@
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
+/* Avoid warnings about Perl headers redefining symbols that gnulib
+ redefined already. */
+#if defined _WIN32 && !defined __CYGWIN__
+ #undef free
+#endif
#include "XSUB.h"
#undef context
@@ -44,11 +49,9 @@ ELEMENT *Root;
#define LOCALEDIR DATADIR "/locale"
-/* Use the uninstalled locales dir.
- NB the texinfo.mo files are not actually created here, only the
- texinfo_document.mo files, which aren't used by parsetexi.
- Hence, error messages will be translated only when the program is
- installed. */
+/* Use the uninstalled locales dir. Currently unused.
+ The texinfo.mo files are not actually created here, only the
+ texinfo_document.mo files, which aren't used by parsetexi. */
static void
find_locales_dir (char *builddir)
{
@@ -83,11 +86,9 @@ init (int texinfo_uninstalled, char *builddir)
{
setlocale (LC_ALL, "");
- /* Use installed or uninstalled translation files for gettext. */
- if (texinfo_uninstalled)
- find_locales_dir (builddir);
- else
- bindtextdomain (PACKAGE, LOCALEDIR);
+ /* Note: this uses the installed translations even when running an
+ uninstalled program. */
+ bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
@@ -141,42 +142,102 @@ reset_parser_except_conf (void)
void
reset_parser (void)
{
+ /* NOTE: Do not call 'malloc' or 'free' in this function or in any function
+ called in this file. Since this file (api.c) includes the Perl headers,
+ we get the Perl redefinitions, which we do not want, as we don't use
+ them throughout the rest of the program. */
+
debug ("!!!!!!!!!!!!!!!! RESETTING THE PARSER !!!!!!!!!!!!!!!!!!!!!");
reset_parser_except_conf ();
wipe_values ();
clear_expanded_formats ();
+ clear_include_directories ();
reset_conf ();
+
+ global_documentlanguage_fixed = 0;
+ set_documentlanguage (0);
+
+ doc_encoding_for_input_file_name = 1;
+ set_input_file_name_encoding (0);
+ set_locale_encoding (0);
+
+ global_accept_internalvalue = 0;
}
-/* Set ROOT to root of tree obtained by parsing FILENAME. */
+/* Determine directory path based on file name.
+ Set ROOT to root of tree obtained by parsing FILENAME.
+ Used for parse_texi_file. */
int
parse_file (char *filename)
{
+ /*
debug_output = 0;
- Root = parse_texi_file (filename);
+ */
+ char *p, *q;
+ char c;
+
+ int status;
+
+ status = input_push_file (filename);
+ if (status)
+ return status;
+
+ /* Strip off a leading directory path, by looking for the last
+ '/' in filename. */
+ p = 0;
+ q = strchr (filename, '/');
+ while (q)
+ {
+ p = q;
+ q = strchr (q + 1, '/');
+ }
+
+ if (p)
+ {
+ c = *p;
+ *p = '\0';
+ add_include_directory (filename);
+ *p = c;
+ }
+
+ Root = parse_texi_document ();
if (Root)
return 0;
return 1;
}
+/* Used for parse_texi_text. STRING should be a UTF-8 buffer. */
+void
+parse_text (char *string, int line_nr)
+{
+ reset_parser_except_conf ();
+ input_push_text_with_line_nos (strdup (string), line_nr);
+ Root = parse_texi_document ();
+}
+
/* Set ROOT to root of tree obtained by parsing the Texinfo code in STRING.
STRING should be a UTF-8 buffer. Used for parse_texi_line. */
void
-parse_string (char *string)
+parse_string (char *string, int line_nr)
{
+ ELEMENT *root_elt = new_element (ET_root_line);
+
reset_parser_except_conf ();
- input_push_text (strdup (string), 0);
- Root = parse_texi (new_element (ET_root_line));
+ input_push_text_with_line_nos (strdup (string), line_nr);
+ Root = parse_texi (root_elt, root_elt);
}
-/* Used for parse_texi_text. STRING should be a UTF-8 buffer. */
+/* Used for parse_texi_piece. STRING should be a UTF-8 buffer. */
void
-parse_text (char *string)
+parse_piece (char *string, int line_nr)
{
+ ELEMENT *before_node_section = setup_document_root_and_before_node_section ();
+ ELEMENT *document_root = before_node_section->parent;
+
reset_parser_except_conf ();
- input_push_text_with_line_nos (strdup (string), 1);
- Root = parse_texi (new_element (ET_text_root));
+ input_push_text_with_line_nos (strdup (string), line_nr);
+ Root = parse_texi (document_root, before_node_section);
}
@@ -245,6 +306,19 @@ build_node_spec (NODE_SPEC_EXTRA *value)
return newRV_inc ((SV *)hv);
}
+/* Used to create a "Perl-internal" string that represents a sequence
+ of Unicode codepoints with no specific encoding. */
+static SV *
+newSVpv_utf8 (char *str, STRLEN len)
+{
+ SV *sv;
+ dTHX;
+
+ sv = newSVpv (str, len);
+ SvUTF8_on (sv);
+ return sv;
+}
+
/* Set E->hv and 'hv' on E's descendants. e->parent->hv is assumed
to already exist. */
static void
@@ -280,46 +354,11 @@ element_to_perl_hash (ELEMENT *e)
sv = newSVpv (command_name(e->cmd), 0);
hv_store (e->hv, "cmdname", strlen ("cmdname"), sv, 0);
- /* TODO: Same optimizations as for 'type'. */
+ /* Note we could optimize the call to newSVpv here and
+ elsewhere by passing an appropriate second argument. */
}
- /* A lot of special cases for when an empty contents array should be
- created. Largely by trial and error to match the Perl code. Some of
- them don't make sense, like @arrow{}, @image, or for accent commands. */
- if (e->contents.number > 0
- || e->type == ET_text_root
- || e->type == ET_root_line
- || e->type == ET_bracketed
- || e->type == ET_bracketed_def_content
- || e->type == ET_line_arg
- || e->cmd == CM_image
- || e->cmd == CM_item && e->parent && e->parent->type == ET_row
- || e->cmd == CM_headitem && e->parent && e->parent->type == ET_row
- || e->cmd == CM_tab && e->parent && e->parent->type == ET_row
- || e->cmd == CM_anchor
- || e->cmd == CM_macro
- || e->cmd == CM_multitable
- || e->type == ET_menu_entry_name
- || e->type == ET_menu_entry_description
- || e->type == ET_brace_command_arg
- || e->type == ET_brace_command_context
- || e->type == ET_block_line_arg
- || e->type == ET_before_item
- || e->type == ET_inter_item
- || e->cmd == CM_TeX
- || e->type == ET_elided
- || e->type == ET_elided_block
- || e->type == ET_preformatted
- || e->type == ET_paragraph
- || (command_flags(e) & CF_root)
- || (command_data(e->cmd).flags & CF_brace
- && (command_data(e->cmd).data >= 0
- || command_data(e->cmd).data == BRACE_style
- || command_data(e->cmd).data == BRACE_context
- || command_data(e->cmd).data == BRACE_other
- || command_data(e->cmd).data == BRACE_accent
- ))
- || e->cmd == CM_node)
+ if (e->contents.number > 0)
{
AV *av;
int i;
@@ -353,22 +392,8 @@ element_to_perl_hash (ELEMENT *e)
if (e->text.space > 0)
{
- sv = newSVpv (e->text.text, e->text.end);
- if (e->cmd != CM_value)
- hv_store (e->hv, "text", strlen ("text"), sv, 0);
- else
- hv_store (e->hv, "type", strlen ("type"), sv, 0);
-
- SvUTF8_on (sv);
- /* The strings here have to be in UTF-8 to start with.
- This leads to an unnecessary round trip with "@documentencoding
- ISO-8859-1" for Info and plain text output, when we first convert the
- characters in the input file to UTF-8, and convert them back again for
- the output.
-
- The alternative is to leave the UTF-8 flag off, and hope that Perl
- interprets 8-bit encodings like ISO-8859-1 correctly. See
- "How does Perl store UTF-8 strings?" in "man perlguts". */
+ sv = newSVpv_utf8 (e->text.text, e->text.end);
+ hv_store (e->hv, "text", strlen ("text"), sv, 0);
}
if (e->extra_number > 0)
@@ -434,7 +459,7 @@ element_to_perl_hash (ELEMENT *e)
case extra_string:
{ /* A simple string. */
char *value = (char *) f;
- STORE(newSVpv (value, 0));
+ STORE(newSVpv_utf8 (value, 0));
break;
}
case extra_integer:
@@ -456,15 +481,14 @@ element_to_perl_hash (ELEMENT *e)
{
if (f->contents.list[j]->text.end > 0)
{
- av_push (av,
- newSVpv (f->contents.list[j]->text.text,
- f->contents.list[j]->text.end));
+ SV *sv = newSVpv_utf8 (f->contents.list[j]->text.text,
+ f->contents.list[j]->text.end);
+ av_push (av, sv);
}
else
{
/* Empty strings permitted. */
- av_push (av,
- newSVpv ("", 0));
+ av_push (av, newSVpv ("", 0));
}
}
break;
@@ -528,8 +552,10 @@ element_to_perl_hash (ELEMENT *e)
hv_store (type, "content", strlen ("content"),
build_perl_array (&eft->content->contents), 0);
if (eft->normalized)
- hv_store (type, "normalized", strlen ("normalized"),
- newSVpv (eft->normalized, 0), 0);
+ {
+ SV *sv = newSVpv_utf8 (eft->normalized, 0);
+ hv_store (type, "normalized", strlen ("normalized"), sv, 0);
+ }
STORE(newRV_inc ((SV *)type));
break;
}
@@ -545,30 +571,29 @@ element_to_perl_hash (ELEMENT *e)
newRV_inc((SV *)extra), 0);
}
- if (e->line_nr.line_nr
- && !(command_flags(e) & CF_INFOENCLOSE))
+ if (e->source_info.line_nr)
{
#define STORE(key, sv) hv_store (hv, key, strlen (key), sv, 0)
- LINE_NR *line_nr = &e->line_nr;
+ SOURCE_INFO *source_info = &e->source_info;
HV *hv = newHV ();
- hv_store (e->hv, "line_nr", strlen ("line_nr"),
+ hv_store (e->hv, "source_info", strlen ("source_info"),
newRV_inc((SV *)hv), 0);
- if (line_nr->file_name)
+ if (source_info->file_name)
{
- STORE("file_name", newSVpv (line_nr->file_name, 0));
+ STORE("file_name", newSVpv (source_info->file_name, 0));
}
else
STORE("file_name", newSVpv ("", 0));
- if (line_nr->line_nr)
+ if (source_info->line_nr)
{
- STORE("line_nr", newSViv (line_nr->line_nr));
+ STORE("line_nr", newSViv (source_info->line_nr));
}
- if (line_nr->macro)
+ if (source_info->macro)
{
- STORE("macro", newSVpv (line_nr->macro, 0));
+ STORE("macro", newSVpv_utf8 (source_info->macro, 0));
}
else
STORE("macro", newSVpv ("", 0));
@@ -579,6 +604,13 @@ element_to_perl_hash (ELEMENT *e)
HV *
build_texinfo_tree (void)
{
+ if (! Root)
+ /* use an empty element with contents if there is nothing.
+ This should only happen if the input file was not opened
+ or no parse_* function was called after initialization
+ and should not happen with the current calling code.
+ */
+ Root = new_element (ET_NONE);
element_to_perl_hash (Root);
return Root->hv;
}
@@ -689,7 +721,7 @@ build_single_index_data (INDEX *i)
hv = (HV *) i->hv;
}
- STORE("name", newSVpv (i->name, 0));
+ STORE("name", newSVpv_utf8 (i->name, 0));
STORE("in_code", i->in_code ? newSViv(1) : newSViv(0));
if (i->merged_in)
@@ -711,7 +743,7 @@ build_single_index_data (INDEX *i)
hv_store (ultimate->contained_hv, i->name, strlen (i->name),
newSViv (1), 0);
- STORE("merged_in", newSVpv (ultimate->name, 0));
+ STORE("merged_in", newSVpv_utf8 (ultimate->name, 0));
if (i->contained_hv)
{
@@ -753,17 +785,17 @@ build_single_index_data (INDEX *i)
e = &i->index_entries[j];
entry = newHV ();
- STORE2("index_name", newSVpv (i->name, 0));
+ STORE2("index_name", newSVpv_utf8 (i->name, 0));
STORE2("index_at_command",
newSVpv (command_name(e->index_at_command), 0));
STORE2("index_type_command",
newSVpv (command_name(e->index_type_command), 0));
- STORE2("command",
+ STORE2("entry_element",
newRV_inc ((SV *)e->command->hv));
- STORE2("number", newSViv (entry_number));
+ STORE2("entry_number", newSViv (entry_number));
if (e->region)
{
- STORE2("region", newRV_inc ((SV *)e->region->hv));
+ STORE2("entry_region", newRV_inc ((SV *)e->region->hv));
}
if (e->content)
{
@@ -787,14 +819,14 @@ build_single_index_data (INDEX *i)
if (contents_array)
{
/* Copy the reference to the array. */
- STORE2("content", newRV_inc ((SV *)(AV *)SvRV(*contents_array)));
+ STORE2("entry_content", newRV_inc ((SV *)(AV *)SvRV(*contents_array)));
STORE2("content_normalized",
newRV_inc ((SV *)(AV *)SvRV(*contents_array)));
}
else
{
- STORE2("content", newRV_inc ((SV *)newAV ()));
+ STORE2("entry_content", newRV_inc ((SV *)newAV ()));
STORE2("content_normalized", newRV_inc ((SV *)newAV ()));
}
}
@@ -802,18 +834,29 @@ build_single_index_data (INDEX *i)
; /* will be set in Texinfo::Common::complete_indices */
if (e->node)
- STORE2("node", newRV_inc ((SV *)e->node->hv));
+ STORE2("entry_node", newRV_inc ((SV *)e->node->hv));
if (e->sortas)
- STORE2("sortas", newSVpv (e->sortas, 0));
+ STORE2("sortas", newSVpv_utf8 (e->sortas, 0));
- /* Skip these as these entries do not refer to the place in the document
- where the index commands occurred. */
- if (!lookup_extra (e->command, "seeentry")
- && !lookup_extra (e->command, "seealso"))
- {
- av_push (entries, newRV_inc ((SV *)entry));
- entry_number++;
- }
+ /* Create ignored_chars hash. */
+ {
+#define STORE3(key) hv_store (hv, key, strlen (key), newSViv(1), 0)
+ HV *hv = newHV ();
+ if (e->ignored_chars.backslash)
+ STORE3("\\");
+ if (e->ignored_chars.hyphen)
+ STORE3("-");
+ if (e->ignored_chars.lessthan)
+ STORE3("<");
+ if (e->ignored_chars.atsign)
+ STORE3("@");
+#undef STORE3
+
+ STORE2("index_ignore_chars", newRV_inc ((SV *)hv));
+ }
+
+ av_push (entries, newRV_inc ((SV *)entry));
+ entry_number++;
/* We set this now because the index data structures don't
exist at the time that the main tree is built. */
@@ -861,7 +904,7 @@ build_index_data (void)
/* Return object to be used as $self->{'info'} in the Perl code, retrievable
- with the 'global_informations' function. */
+ with the 'global_information' function. */
HV *
build_global_info (void)
{
@@ -892,22 +935,6 @@ build_global_info (void)
}
}
- if (global_info.novalidate)
- {
- hv_store (hv, "novalidate", strlen ("novalidate"),
- newSVpv ("1", 0), 0);
- }
-
- char *txi_flags[] = { "txiindexatsignignore", "txiindexbackslashignore",
- "txiindexhyphenignore", "txiindexlessthanignore", 0};
- char **p;
-
- for (p = txi_flags; (*p); p++)
- {
- if (fetch_value (*p))
- hv_store (hv, *p, strlen (*p), newSVpv ("1", 0), 0);
- }
-
return hv;
}
@@ -958,6 +985,7 @@ build_global_info2 (void)
BUILD_GLOBAL_UNIQ(oddfootingmarks);
BUILD_GLOBAL_UNIQ(shorttitlepage);
BUILD_GLOBAL_UNIQ(title);
+ BUILD_GLOBAL_UNIQ(novalidate);
#undef BUILD_GLOBAL_UNIQ
/* NOTE: Same list in handle_commands.c:register_global_command. */
@@ -1001,7 +1029,7 @@ build_global_info2 (void)
BUILD_GLOBAL_ARRAY(detailmenu);
BUILD_GLOBAL_ARRAY(part);
- /* from Common.pm %document_settable_at_commands */
+ /* from Common.pm %document_settable_multiple_at_commands */
BUILD_GLOBAL_ARRAY(allowcodebreaks);
BUILD_GLOBAL_ARRAY(clickstyle);
BUILD_GLOBAL_ARRAY(codequotebacktick);
@@ -1029,3 +1057,114 @@ set_debug (int value)
debug_output = value;
}
+void
+conf_set_documentlanguage_override (char *value)
+{
+ set_documentlanguage_override (value);
+}
+
+
+void
+set_DOC_ENCODING_FOR_INPUT_FILE_NAME (int i)
+{
+ doc_encoding_for_input_file_name = i;
+}
+
+void
+conf_set_input_file_name_encoding (char *value)
+{
+ set_input_file_name_encoding (value);
+}
+
+void
+conf_set_locale_encoding (char *value)
+{
+ set_locale_encoding (value);
+}
+
+
+static SV *
+build_source_info_hash (SOURCE_INFO source_info)
+{
+ HV *hv;
+
+ dTHX;
+
+ hv = newHV ();
+
+ if (source_info.file_name)
+ {
+ hv_store (hv, "file_name", strlen ("file_name"),
+ newSVpv (source_info.file_name, 0), 0);
+ }
+ else
+ {
+ hv_store (hv, "file_name", strlen ("file_name"),
+ newSVpv ("", 0), 0);
+ }
+ if (source_info.line_nr)
+ {
+ hv_store (hv, "line_nr", strlen ("line_nr"),
+ newSViv (source_info.line_nr), 0);
+ }
+ if (source_info.macro)
+ {
+ hv_store (hv, "macro", strlen ("macro"),
+ newSVpv_utf8 (source_info.macro, 0), 0);
+ }
+ else
+ {
+ hv_store (hv, "macro", strlen ("macro"),
+ newSVpv_utf8 ("", 0), 0);
+ }
+
+ return newRV_inc ((SV *) hv);
+}
+
+static SV *
+convert_error (int i)
+{
+ ERROR_MESSAGE e;
+ HV *hv;
+ SV *msg;
+
+ dTHX;
+
+ e = error_list[i];
+ hv = newHV ();
+
+ msg = newSVpv_utf8 (e.message, 0);
+
+ hv_store (hv, "message", strlen ("message"), msg, 0);
+ hv_store (hv, "type", strlen ("type"),
+ e.type == error ? newSVpv("error", strlen("error"))
+ : newSVpv("warning", strlen("warning")),
+ 0);
+
+ hv_store (hv, "source_info", strlen ("source_info"),
+ build_source_info_hash(e.source_info), 0);
+
+ return newRV_inc ((SV *) hv);
+
+}
+
+/* Errors */
+AV *
+get_errors (void)
+{
+ AV *av;
+ int i;
+
+ dTHX;
+
+ av = newAV ();
+
+ for (i = 0; i < error_number; i++)
+ {
+ SV *sv = convert_error (i);
+ av_push (av, sv);
+ }
+
+ return av;
+
+}
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.h
index 7843680255..626c3b4c7d 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/api.h
@@ -5,15 +5,21 @@ extern ELEMENT *Root;
int init (int texinfo_uninstalled, char *srcdir_in);
-void parse_text (char *);
-void parse_string(char *);
int parse_file (char *filename);
+void parse_piece (char *, int line_nr);
+void parse_string (char *, int line_nr);
+void parse_text (char *, int line_nr);
void reset_parser (void);
void reset_parser_except_conf (void);
void set_debug (int);
void wipe_values (void);
void reset_context_stack (void);
+void set_DOC_ENCODING_FOR_INPUT_FILE_NAME (int i);
+void conf_set_input_file_name_encoding (char *value);
+void conf_set_locale_encoding (char *value);
+void conf_set_documentlanguage_override (char *value);
+
HV *build_texinfo_tree (void);
AV *build_label_list (void);
AV *build_internal_xref_list (void);
@@ -21,6 +27,6 @@ HV *build_float_list (void);
HV *build_index_data (void);
HV *build_global_info (void);
HV *build_global_info2 (void);
-
+AV *get_errors (void);
#endif
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/close.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/close.c
index 2568be2052..08b2113a08 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/close.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/close.c
@@ -23,7 +23,7 @@
/* Possibly print an error message, and return CURRENT->parent. */
static ELEMENT *
close_brace_command (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command)
{
@@ -37,10 +37,10 @@ close_brace_command (ELEMENT *current,
if (0)
{
yes:
- if (closed_command)
+ if (closed_block_command)
command_error (current,
"@end %s seen before @%s closing brace",
- command_name(closed_command),
+ command_name(closed_block_command),
command_name(current->cmd));
else if (interrupting_command)
command_error (current,
@@ -67,14 +67,14 @@ yes:
paragraphs. */
ELEMENT *
close_all_style_commands (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command)
{
while (current->parent
&& (command_flags(current->parent) & CF_brace)
&& !(command_data(current->parent->cmd).data == BRACE_context))
current = close_brace_command (current->parent,
- closed_command, interrupting_command);
+ closed_block_command, interrupting_command);
return current;
}
@@ -163,7 +163,7 @@ close_command_cleanup (ELEMENT *current)
int have_leading_spaces = 0;
ELEMENT *before_item = 0;
if (current->contents.number >= 2
- && current->contents.list[0]->type == ET_empty_line_after_command
+ && current->contents.list[0]->type == ET_ignorable_spaces_after_command
&& current->contents.list[1]->type == ET_before_item)
{
have_leading_spaces = 1;
@@ -178,10 +178,8 @@ close_command_cleanup (ELEMENT *current)
if (before_item)
{
/* Reparent @end from a ET_before_item to the block command */
- KEY_PAIR *k = lookup_extra (current, "end_command");
- ELEMENT *e = k ? k->value : 0;
- if (k && last_contents_child (before_item)
- && last_contents_child (before_item) == e)
+ ELEMENT *e = last_contents_child (before_item);
+ if (e && e->cmd == CM_end)
{
add_to_element_contents (current,
pop_element_from_contents (before_item));
@@ -221,7 +219,7 @@ close_command_cleanup (ELEMENT *current)
&& (e->cmd != CM_c && e->cmd != CM_comment
&& e->cmd != CM_end)
|| e->type != ET_NONE
- && e->type != ET_empty_line_after_command)
+ && e->type != ET_ignorable_spaces_after_command)
{
empty_format = 0;
break;
@@ -237,9 +235,34 @@ close_command_cleanup (ELEMENT *current)
}
}
+void
+pop_block_command_contexts (enum command_id cmd)
+{
+ if (command_data(cmd).flags & CF_preformatted
+ || command_data(cmd).data == BLOCK_menu)
+ {
+ if (pop_context () != ct_preformatted)
+ fatal ("preformatted context expected");
+ }
+ else if (command_data(cmd).data == BLOCK_format_raw)
+ {
+ if (pop_context () != ct_rawpreformatted)
+ fatal ("rawpreformatted context expected");
+ }
+ else if (cmd == CM_displaymath)
+ {
+ if (pop_context () != ct_math)
+ fatal ("math context expected");
+ }
+ else if (command_data(cmd).data == BLOCK_region)
+ {
+ pop_region ();
+ }
+}
+
ELEMENT *
close_current (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command)
{
/* Element is a command */
@@ -249,19 +272,27 @@ close_current (ELEMENT *current,
if (command_flags(current) & CF_brace)
{
if (command_data(current->cmd).data == BRACE_context)
- pop_context ();
- current = close_brace_command (current,
- closed_command, interrupting_command);
+ {
+ if (current->cmd == CM_math)
+ {
+ if (pop_context () != ct_math)
+ fatal ("math context expected");
+ }
+ else if (pop_context () != ct_brace_command)
+ fatal ("context brace command context expected");
+ }
+ current = close_brace_command (current, closed_block_command,
+ interrupting_command);
}
else if (command_flags(current) & CF_block)
{
enum command_id cmd = current->cmd;
ELEMENT *parent = 0;
- if (closed_command)
+ if (closed_block_command)
{
line_error ("`@end' expected `%s', but saw `%s'",
command_name(current->cmd),
- command_name(closed_command));
+ command_name(closed_block_command));
}
else if (interrupting_command)
{
@@ -282,15 +313,7 @@ close_current (ELEMENT *current,
(parent));
}
}
- if (command_data(cmd).flags
- & (CF_preformatted | CF_menu | CF_format_raw))
- {
- pop_context ();
- }
- if (command_data(cmd).data == BLOCK_region)
- {
- pop_region ();
- }
+ pop_block_command_contexts (cmd);
if (!parent)
parent = current->parent;
current = parent;
@@ -312,7 +335,7 @@ close_current (ELEMENT *current,
command_error (current, "misplaced {");
if (current->contents.number > 0
&& current->contents.list[0]->type
- == ET_empty_spaces_before_argument)
+ == ET_internal_spaces_before_argument)
{
/* remove spaces element from tree and update extra values */
abort_empty_line (&current, 0);
@@ -322,10 +345,6 @@ close_current (ELEMENT *current,
break;
case ET_menu_comment:
case ET_menu_entry_description:
- c = pop_context ();
- if (c != ct_preformatted)
- fatal ("preformatted context expected");
-
/* Remove empty menu_comment */
if (current->type == ET_menu_comment
&& current->contents.number == 0)
@@ -362,64 +381,42 @@ close_current (ELEMENT *current,
return current;
}
-/* Return lowest level ancestor of CURRENT containing a CLOSED_COMMAND
- element. Set CLOSED_ELEMENT to the element itself. INTERRUPTING is used in
+/* Return lowest level ancestor of CURRENT containing a CLOSED_BLOCK_COMMAND
+ element, or the lowest level ancestor if CLOSED_BLOCK_COMMAND is 0.
+ Set CLOSED_BLOCK_ELEMENT to the last closed element. INTERRUPTING is used in
close_brace_command to display an error message. Remove a context from
- context stack if it was added by this command. */
+ context stack if CLOSED_BLOCK_COMMAND is not 0 and a context was added
+ by the CLOSED_BLOCK_COMMAND.
+ CLOSED_BLOCK_COMMAND should be the id of a block command.
+ */
ELEMENT *
-close_commands (ELEMENT *current, enum command_id closed_command,
+close_commands (ELEMENT *current, enum command_id closed_block_command,
ELEMENT **closed_element, enum command_id interrupting)
{
*closed_element = 0;
- current = end_paragraph (current, closed_command, interrupting);
- current = end_preformatted (current, closed_command, interrupting);
+ current = end_paragraph (current, closed_block_command, interrupting);
+ current = end_preformatted (current, closed_block_command, interrupting);
while (current->parent
- && (!closed_command || current->cmd != closed_command)
+ && (!closed_block_command || current->cmd != closed_block_command)
/* Stop if in a root command. */
- && !(current->cmd && command_flags(current) & CF_root))
+ && !(current->cmd && command_flags(current) & CF_root)
+ /* Stop if at a type at the root */
+ && !(current->type == ET_before_node_section))
{
close_command_cleanup (current);
- current = close_current (current, closed_command, interrupting);
+ current = close_current (current, closed_block_command, interrupting);
}
- if (closed_command && current->cmd == closed_command)
+ if (closed_block_command && current->cmd == closed_block_command)
{
- if (command_data(current->cmd).flags & CF_preformatted)
- {
- if (pop_context () != ct_preformatted)
- fatal ("preformatted context expected");
- }
- else if (command_data(current->cmd).flags & CF_format_raw)
- {
- if (pop_context () != ct_rawpreformatted)
- fatal ("rawpreformatted context expected");
- // TODO: pop expanded formats stack
- }
- else if (command_data(current->cmd).flags & CF_menu)
- {
- enum context c;
- c = pop_context ();
- if (c != ct_menu && c != ct_preformatted)
- fatal ("menu or preformatted context expected");
- }
- else if (current->cmd == CM_math || current->cmd == CM_displaymath)
- {
- enum context c;
- c = pop_context ();
- if (c != ct_math)
- fatal ("math context expected");
- }
-
- if (command_data(current->cmd).data == BLOCK_region)
- pop_region ();
-
+ pop_block_command_contexts (current->cmd);
*closed_element = current;
current = current->parent;
}
- else if (closed_command)
+ else if (closed_block_command)
{
- line_error ("unmatched `@end %s'", command_name(closed_command));
+ line_error ("unmatched `@end %s'", command_name(closed_block_command));
}
return current;
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.awk b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.awk
index 9974d1aefb..133a1c044e 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.awk
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.awk
@@ -118,12 +118,13 @@ BEGIN {
}
commands[c] = $2
data[c] = $3
+ args_nr[c] = $4
}
END {
print "COMMAND builtin_command_data[] = {" > CD
- print "0, 0, 0," > CD
+ print "0, 0, 0, 0," > CD
# We want the output sorted so we can use bsearch
PROCINFO["sorted_in"]="@ind_str_asc"
@@ -152,7 +153,30 @@ END {
} else {
command_data = "0"
}
- print "\"" c2 "\", " flags ", " command_data "," > CD
+
+ if (args_nr[c] != "") {
+ args_nr_data = args_nr[c]
+ } else {
+ # backward compatibility, remove when updated
+ where_digit = match(data[c], /^[0-9]$/)
+ if (where_digit != 0) {
+ args_nr_data = data[c]
+ } else {
+ where = 0
+ if (commands[c] != "") {
+ where = match(commands[c], /block/)
+ if (where == 0) {
+ where = match(commands[c], /^nobrace$/)
+ }
+ }
+ if (where != 0 || command_data == "BRACE_noarg") {
+ args_nr_data = "0"
+ } else {
+ args_nr_data = "1"
+ }
+ }
+ }
+ print "\"" c2 "\", " flags ", " command_data ", " args_nr_data "," > CD
}
print "};" > CD
print "};" > CI
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.c
index 7d0e5a0976..19a2a22cf2 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.c
@@ -1,362 +1,370 @@
COMMAND builtin_command_data[] = {
-0, 0, 0,
-"\t", CF_nobrace, 0,
-"\n", CF_nobrace, 0,
-"\x20", CF_nobrace, 0,
-"!", CF_nobrace, 0,
-"\"", CF_brace | CF_accent, BRACE_accent,
-"&", CF_nobrace, 0,
-"'", CF_brace | CF_accent, BRACE_accent,
-"*", CF_nobrace, 0,
-",", CF_brace | CF_accent, BRACE_accent,
-"-", CF_nobrace, 0,
-".", CF_nobrace, 0,
-"/", CF_nobrace, 0,
-":", CF_nobrace, 0,
-"=", CF_brace | CF_accent, BRACE_accent,
-"?", CF_nobrace, 0,
-"@", CF_nobrace, 0,
-"AA", CF_brace, 0,
-"AE", CF_brace, 0,
-"DH", CF_brace, 0,
-"H", CF_brace | CF_accent, BRACE_accent,
-"L", CF_brace, 0,
-"LaTeX", CF_brace, 0,
-"O", CF_brace, 0,
-"OE", CF_brace, 0,
-"TH", CF_brace, 0,
-"TeX", CF_brace, 0,
-"U", CF_brace, 1,
-"\\", CF_nobrace, 0,
-"^", CF_brace | CF_accent, BRACE_accent,
-"`", CF_brace | CF_accent, BRACE_accent,
-"aa", CF_brace, 0,
-"abbr", CF_brace, 2,
-"acronym", CF_brace, 2,
-"ae", CF_brace, 0,
-"afivepaper", CF_line, LINE_skipline,
-"afourlatex", CF_line, LINE_skipline,
-"afourpaper", CF_line, LINE_skipline,
-"afourwide", CF_line, LINE_skipline,
-"alias", CF_line, 2,
-"allowcodebreaks", CF_line | CF_global, 1,
-"ampchar", CF_brace, 0,
-"anchor", CF_brace, 1,
-"appendix", CF_root | CF_line | CF_sectioning, LINE_line,
-"appendixsec", CF_root | CF_line | CF_sectioning, LINE_line,
-"appendixsection", CF_root | CF_line | CF_sectioning, LINE_line,
-"appendixsubsec", CF_root | CF_line | CF_sectioning, LINE_line,
-"appendixsubsubsec", CF_root | CF_line | CF_sectioning, LINE_line,
-"arrow", CF_brace, 0,
-"asis", CF_brace, BRACE_style,
-"atchar", CF_brace, 0,
-"author", CF_line | CF_global, LINE_line,
-"b", CF_brace, BRACE_style,
-"backslashchar", CF_brace, 0,
-"bsixpaper", CF_line, LINE_skipline,
-"bullet", CF_brace, 0,
-"bye", CF_line, LINE_skipline,
-"c", CF_line, LINE_lineraw,
-"caption", CF_brace, BRACE_context,
-"cartouche", CF_block, 0,
-"center", CF_line, LINE_line,
-"centerchap", CF_root | CF_line | CF_sectioning | CF_deprecated, LINE_line,
-"chapheading", CF_line | CF_sectioning, LINE_line,
-"chapter", CF_root | CF_line | CF_sectioning, LINE_line,
-"cite", CF_brace, BRACE_style,
-"clear", CF_line, LINE_special,
-"click", CF_brace, 0,
-"clicksequence", CF_brace, BRACE_style,
-"clickstyle", CF_line | CF_global, LINE_special,
-"code", CF_brace | CF_code_style, BRACE_style,
-"codequotebacktick", CF_line | CF_global, 1,
-"codequoteundirected", CF_line | CF_global, 1,
-"columnfractions", CF_line, 1,
-"comma", CF_brace, 0,
-"command", CF_brace | CF_code_style, BRACE_style,
-"comment", CF_line, LINE_lineraw,
-"contents", CF_line | CF_global, LINE_skipline,
-"copying", CF_block | CF_global_unique, BLOCK_region,
-"copyright", CF_brace, 0,
-"defcodeindex", CF_line, 1,
-"defcv", CF_block | CF_def, 0,
-"defcvx", CF_line | CF_def, LINE_line,
-"deffn", CF_block | CF_def, 0,
-"deffnx", CF_line | CF_def, LINE_line,
-"defindex", CF_line, 1,
-"definfoenclose", CF_line | CF_deprecated, 3,
-"defivar", CF_block | CF_def | CF_def_alias, 0,
-"defivarx", CF_line | CF_def | CF_def_alias, LINE_line,
-"defmac", CF_block | CF_def | CF_def_alias, 0,
-"defmacx", CF_line | CF_def | CF_def_alias, LINE_line,
-"defmethod", CF_block | CF_def | CF_def_alias, 0,
-"defmethodx", CF_line | CF_def | CF_def_alias, LINE_line,
-"defop", CF_block | CF_def, 0,
-"defopt", CF_block | CF_def | CF_def_alias, 0,
-"defoptx", CF_line | CF_def | CF_def_alias, LINE_line,
-"defopx", CF_line | CF_def, LINE_line,
-"defspec", CF_block | CF_def | CF_def_alias, 0,
-"defspecx", CF_line | CF_def | CF_def_alias, LINE_line,
-"deftp", CF_block | CF_def, 0,
-"deftpx", CF_line | CF_def, LINE_line,
-"deftypecv", CF_block | CF_def, 0,
-"deftypecvx", CF_line | CF_def, LINE_line,
-"deftypefn", CF_block | CF_def, 0,
-"deftypefnnewline", CF_line | CF_global, 1,
-"deftypefnx", CF_line | CF_def, LINE_line,
-"deftypefun", CF_block | CF_def | CF_def_alias, 0,
-"deftypefunx", CF_line | CF_def | CF_def_alias, LINE_line,
-"deftypeivar", CF_block | CF_def | CF_def_alias, 0,
-"deftypeivarx", CF_line | CF_def | CF_def_alias, LINE_line,
-"deftypemethod", CF_block | CF_def | CF_def_alias, 0,
-"deftypemethodx", CF_line | CF_def | CF_def_alias, LINE_line,
-"deftypeop", CF_block | CF_def, 0,
-"deftypeopx", CF_line | CF_def, LINE_line,
-"deftypevar", CF_block | CF_def | CF_def_alias, 0,
-"deftypevarx", CF_line | CF_def | CF_def_alias, LINE_line,
-"deftypevr", CF_block | CF_def, 0,
-"deftypevrx", CF_line | CF_def, LINE_line,
-"defun", CF_block | CF_def | CF_def_alias, 0,
-"defunx", CF_line | CF_def | CF_def_alias, LINE_line,
-"defvar", CF_block | CF_def | CF_def_alias, 0,
-"defvarx", CF_line | CF_def | CF_def_alias, LINE_line,
-"defvr", CF_block | CF_def, 0,
-"defvrx", CF_line | CF_def, LINE_line,
-"detailmenu", CF_block | CF_menu | CF_global, 0,
-"dfn", CF_brace, BRACE_style,
-"dh", CF_brace, 0,
-"dircategory", CF_line, LINE_line,
-"direntry", CF_block | CF_menu, 0,
-"display", CF_block | CF_preformatted, 0,
-"displaymath", CF_block, 0,
-"dmn", CF_brace, 1,
-"docbook", CF_block | CF_format_raw, 0,
-"documentdescription", CF_block | CF_global_unique, BLOCK_region,
-"documentencoding", CF_line | CF_global, LINE_text,
-"documentlanguage", CF_line | CF_global, LINE_text,
-"dotaccent", CF_brace | CF_accent, BRACE_accent,
-"dotless", CF_brace | CF_accent, BRACE_accent,
-"dots", CF_brace, 0,
-"email", CF_brace, 2,
-"emph", CF_brace, BRACE_style,
-"end", CF_line, LINE_text,
-"enddots", CF_brace, 0,
-"enumerate", CF_block | CF_blockitem, 1,
-"env", CF_brace | CF_code_style, BRACE_style,
-"equiv", CF_brace, 0,
-"error", CF_brace, 0,
-"errormsg", CF_brace, 1,
-"euro", CF_brace, 0,
-"evenfooting", CF_line | CF_global_unique, LINE_lineraw,
-"evenfootingmarks", CF_line | CF_global_unique, 1,
-"evenheading", CF_line | CF_global_unique, LINE_lineraw,
-"evenheadingmarks", CF_line | CF_global_unique, 1,
-"everyfooting", CF_line | CF_global_unique, LINE_lineraw,
-"everyfootingmarks", CF_line | CF_global_unique, 1,
-"everyheading", CF_line | CF_global_unique, LINE_lineraw,
-"everyheadingmarks", CF_line | CF_global_unique, 1,
-"example", CF_block | CF_preformatted | CF_preformatted_code, BLOCK_variadic,
-"exampleindent", CF_line | CF_global, 1,
-"exclamdown", CF_brace, 0,
-"exdent", CF_line, LINE_line,
-"expansion", CF_brace, 0,
-"file", CF_brace | CF_code_style, BRACE_style,
-"finalout", CF_line, LINE_skipline,
-"firstparagraphindent", CF_line | CF_global, 1,
-"float", CF_block, 2,
-"flushleft", CF_block, 0,
-"flushright", CF_block, 0,
-"fonttextsize", CF_line | CF_global_unique, 1,
-"footnote", CF_brace | CF_global, BRACE_context,
-"footnotestyle", CF_line | CF_global_unique, 1,
-"format", CF_block | CF_preformatted, 0,
-"frenchspacing", CF_line | CF_global, 1,
-"ftable", CF_block | CF_blockitem, 1,
-"geq", CF_brace, 0,
-"group", CF_block, 0,
-"guillemetleft", CF_brace, 0,
-"guillemetright", CF_brace, 0,
-"guillemotleft", CF_brace, 0,
-"guillemotright", CF_brace, 0,
-"guilsinglleft", CF_brace, 0,
-"guilsinglright", CF_brace, 0,
-"hashchar", CF_brace, 0,
-"heading", CF_line | CF_sectioning, LINE_line,
-"headings", CF_line | CF_global, 1,
-"headitem", CF_other, OTHER_skipspace,
-"headitemfont", CF_brace, BRACE_style,
-"html", CF_block | CF_format_raw, 0,
-"hyphenation", CF_brace | CF_global, BRACE_other,
-"i", CF_brace, BRACE_style,
-"ifclear", CF_block, BLOCK_conditional,
-"ifcommanddefined", CF_block, BLOCK_conditional,
-"ifcommandnotdefined", CF_block, BLOCK_conditional,
-"ifdocbook", CF_block, BLOCK_conditional,
-"ifhtml", CF_block, BLOCK_conditional,
-"ifinfo", CF_block, BLOCK_conditional,
-"ifnotdocbook", CF_block, BLOCK_conditional,
-"ifnothtml", CF_block, BLOCK_conditional,
-"ifnotinfo", CF_block, BLOCK_conditional,
-"ifnotplaintext", CF_block, BLOCK_conditional,
-"ifnottex", CF_block, BLOCK_conditional,
-"ifnotxml", CF_block, BLOCK_conditional,
-"ifplaintext", CF_block, BLOCK_conditional,
-"ifset", CF_block, BLOCK_conditional,
-"iftex", CF_block, BLOCK_conditional,
-"ifxml", CF_block, BLOCK_conditional,
-"ignore", CF_block, BLOCK_raw,
-"image", CF_brace, 5,
-"include", CF_line, LINE_text,
-"indent", CF_other, OTHER_skipspace,
-"indentedblock", CF_block, 0,
-"indicateurl", CF_brace | CF_code_style, 1,
-"inforef", CF_brace | CF_ref | CF_deprecated, 3,
-"inlinefmt", CF_brace | CF_inline, 2,
-"inlinefmtifelse", CF_brace | CF_inline, 3,
-"inlineifclear", CF_brace | CF_inline, 2,
-"inlineifset", CF_brace | CF_inline, 2,
-"inlineraw", CF_brace | CF_inline, 2,
-"insertcopying", CF_line | CF_global, LINE_skipline,
-"item", CF_other, OTHER_skipspace,
-"item_LINE", CF_line, LINE_line,
-"itemize", CF_block | CF_blockitem, 1,
-"itemx", CF_line, LINE_line,
-"kbd", CF_brace | CF_code_style, BRACE_style,
-"kbdinputstyle", CF_line | CF_global, 1,
-"key", CF_brace, BRACE_other,
-"l", CF_brace, 0,
-"lbracechar", CF_brace, 0,
-"leq", CF_brace, 0,
-"lisp", CF_block | CF_preformatted | CF_preformatted_code, 0,
-"listoffloats", CF_line | CF_global, LINE_line,
-"lowersections", CF_line, LINE_skipline,
-"macro", CF_block, BLOCK_raw,
-"majorheading", CF_line | CF_sectioning, LINE_line,
-"math", CF_brace, BRACE_context,
-"menu", CF_block | CF_menu, 0,
-"minus", CF_brace, 0,
-"multitable", CF_block | CF_blockitem, BLOCK_multitable,
-"need", CF_line, 1,
-"node", CF_root | CF_line, LINE_line,
-"noindent", CF_other, OTHER_skipspace,
-"novalidate", CF_line | CF_global_unique, LINE_skipline,
-"o", CF_brace, 0,
-"oddfooting", CF_line | CF_global_unique, LINE_lineraw,
-"oddfootingmarks", CF_line | CF_global_unique, 1,
-"oddheading", CF_line | CF_global_unique, LINE_lineraw,
-"oddheadingmarks", CF_line | CF_global_unique, 1,
-"oe", CF_brace, 0,
-"ogonek", CF_brace | CF_accent, BRACE_accent,
-"option", CF_brace | CF_code_style, BRACE_style,
-"ordf", CF_brace, 0,
-"ordm", CF_brace, 0,
-"page", CF_line, LINE_skipline,
-"pagesizes", CF_line | CF_global_unique, LINE_line,
-"paragraphindent", CF_line | CF_global, 1,
-"part", CF_root | CF_line | CF_sectioning | CF_global, LINE_line,
-"point", CF_brace, 0,
-"pounds", CF_brace, 0,
-"print", CF_brace, 0,
-"printindex", CF_line | CF_global, 1,
-"pxref", CF_brace | CF_ref, 5,
-"questiondown", CF_brace, 0,
-"quotation", CF_block, 1,
-"quotedblbase", CF_brace, 0,
-"quotedblleft", CF_brace, 0,
-"quotedblright", CF_brace, 0,
-"quoteleft", CF_brace, 0,
-"quoteright", CF_brace, 0,
-"quotesinglbase", CF_brace, 0,
-"r", CF_brace, BRACE_style,
-"raggedright", CF_block, 0,
-"raisesections", CF_line, LINE_skipline,
-"rbracechar", CF_brace, 0,
-"ref", CF_brace | CF_ref, 5,
-"refill", CF_other | CF_deprecated, OTHER_noarg,
-"registeredsymbol", CF_brace, 0,
-"result", CF_brace, 0,
-"ringaccent", CF_brace | CF_accent, BRACE_accent,
-"rmacro", CF_block, BLOCK_raw,
-"samp", CF_brace | CF_code_style, BRACE_style,
-"sansserif", CF_brace, BRACE_style,
-"sc", CF_brace, BRACE_style,
-"section", CF_root | CF_line | CF_sectioning, LINE_line,
-"seealso", CF_brace, 1,
-"seeentry", CF_brace, 1,
-"set", CF_line, LINE_special,
-"setchapternewpage", CF_line | CF_global_unique, 1,
-"setfilename", CF_line | CF_global_unique, LINE_text,
-"settitle", CF_line | CF_global_unique, LINE_line,
-"shortcaption", CF_brace, BRACE_context,
-"shortcontents", CF_line | CF_global, LINE_skipline,
-"shorttitlepage", CF_line | CF_global_unique, LINE_line,
-"slanted", CF_brace, BRACE_style,
-"smallbook", CF_line, LINE_skipline,
-"smalldisplay", CF_block | CF_preformatted, 0,
-"smallexample", CF_block | CF_preformatted | CF_preformatted_code, 0,
-"smallformat", CF_block | CF_preformatted, 0,
-"smallindentedblock", CF_block, 0,
-"smalllisp", CF_block | CF_preformatted | CF_preformatted_code, 0,
-"smallquotation", CF_block, 1,
-"sortas", CF_brace, 1,
-"sp", CF_line, 1,
-"ss", CF_brace, 0,
-"strong", CF_brace, BRACE_style,
-"sub", CF_brace, BRACE_style,
-"subentry", CF_line, LINE_line,
-"subheading", CF_line | CF_sectioning, LINE_line,
-"subsection", CF_root | CF_line | CF_sectioning, LINE_line,
-"subsubheading", CF_line | CF_sectioning, LINE_line,
-"subsubsection", CF_root | CF_line | CF_sectioning, LINE_line,
-"subtitle", CF_line | CF_global, LINE_line,
-"summarycontents", CF_line | CF_global, LINE_skipline,
-"sup", CF_brace, BRACE_style,
-"syncodeindex", CF_line, 2,
-"synindex", CF_line, 2,
-"t", CF_brace | CF_code_style, BRACE_other,
-"tab", CF_other, OTHER_skipspace,
-"table", CF_block | CF_blockitem, 1,
-"tex", CF_block | CF_format_raw, 0,
-"textdegree", CF_brace, 0,
-"th", CF_brace, 0,
-"thischapter", CF_other | CF_in_heading, OTHER_noarg,
-"thischaptername", CF_other | CF_in_heading, OTHER_noarg,
-"thischapternum", CF_other | CF_in_heading, OTHER_noarg,
-"thisfile", CF_other | CF_in_heading, OTHER_noarg,
-"thispage", CF_other | CF_in_heading, OTHER_noarg,
-"thistitle", CF_other | CF_in_heading, OTHER_noarg,
-"tie", CF_brace, 0,
-"tieaccent", CF_brace | CF_accent, BRACE_accent,
-"title", CF_line | CF_global_unique, LINE_line,
-"titlefont", CF_brace | CF_global, 1,
-"titlepage", CF_block | CF_global_unique, BLOCK_region,
-"today", CF_brace, 0,
-"top", CF_root | CF_line | CF_sectioning | CF_global_unique, LINE_line,
-"u", CF_brace | CF_accent, BRACE_accent,
-"ubaraccent", CF_brace | CF_accent, BRACE_accent,
-"udotaccent", CF_brace | CF_accent, BRACE_accent,
-"unmacro", CF_line, LINE_special,
-"unnumbered", CF_root | CF_line | CF_sectioning, LINE_line,
-"unnumberedsec", CF_root | CF_line | CF_sectioning, LINE_line,
-"unnumberedsubsec", CF_root | CF_line | CF_sectioning, LINE_line,
-"unnumberedsubsubsec", CF_root | CF_line | CF_sectioning, LINE_line,
-"uref", CF_brace, 3,
-"urefbreakstyle", CF_line | CF_global, 1,
-"url", CF_brace, 3,
-"v", CF_brace | CF_accent, BRACE_accent,
-"value", CF_brace, 0,
-"var", CF_brace, BRACE_style,
-"verb", CF_brace | CF_code_style, BRACE_other,
-"verbatim", CF_block, BLOCK_raw,
-"verbatiminclude", CF_line, LINE_text,
-"vskip", CF_line, LINE_lineraw,
-"vtable", CF_block | CF_blockitem, 1,
-"w", CF_brace, BRACE_other,
-"xml", CF_block | CF_format_raw, 0,
-"xref", CF_brace | CF_ref, 5,
-"xrefautomaticsectiontitle", CF_line | CF_global, 1,
-"{", CF_nobrace, 0,
-"|", CF_nobrace, 0,
-"}", CF_nobrace, 0,
-"~", CF_brace | CF_accent, BRACE_accent,
+0, 0, 0, 0,
+"\t", CF_nobrace, NOBRACE_symbol, 0,
+"\n", CF_nobrace, NOBRACE_symbol, 0,
+"\x20", CF_nobrace, NOBRACE_symbol, 0,
+"!", CF_nobrace, NOBRACE_symbol, 0,
+"\"", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"&", CF_nobrace, NOBRACE_symbol, 0,
+"'", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"*", CF_nobrace, NOBRACE_symbol, 0,
+",", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"-", CF_nobrace, NOBRACE_symbol, 0,
+".", CF_nobrace, NOBRACE_symbol, 0,
+"/", CF_nobrace, NOBRACE_symbol, 0,
+":", CF_nobrace, NOBRACE_symbol, 0,
+"=", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"?", CF_nobrace, NOBRACE_symbol, 0,
+"@", CF_nobrace, NOBRACE_symbol, 0,
+"AA", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"AE", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"DH", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"H", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"L", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"LaTeX", CF_brace, BRACE_noarg, 0,
+"O", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"OE", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"TH", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"TeX", CF_brace, BRACE_noarg, 0,
+"U", CF_brace, BRACE_arguments, 1,
+"\\", CF_nobrace, NOBRACE_symbol, 0,
+"^", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"`", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"aa", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"abbr", CF_brace | CF_contain_simple_text, BRACE_arguments, 2,
+"acronym", CF_brace | CF_contain_simple_text, BRACE_arguments, 2,
+"ae", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"afivepaper", CF_line | CF_global_unique, LINE_skipline, 1,
+"afourlatex", CF_line | CF_global_unique, LINE_skipline, 1,
+"afourpaper", CF_line | CF_global_unique, LINE_skipline, 1,
+"afourwide", CF_line | CF_global_unique, LINE_skipline, 1,
+"alias", CF_line | CF_contain_plain_text, LINE_specific, 2,
+"allowcodebreaks", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"ampchar", CF_brace, BRACE_noarg, 0,
+"anchor", CF_brace | CF_contain_simple_text, BRACE_arguments, 1,
+"appendix", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"appendixsec", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"appendixsection", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"appendixsubsec", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"appendixsubsubsec", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"arrow", CF_brace, BRACE_noarg, 0,
+"asis", CF_brace, BRACE_style_other, 1,
+"atchar", CF_brace, BRACE_noarg, 0,
+"author", CF_line | CF_global | CF_contain_simple_text, LINE_line, 1,
+"b", CF_brace, BRACE_style_other, 1,
+"backslashchar", CF_brace, BRACE_noarg, 0,
+"bsixpaper", CF_line | CF_global_unique, LINE_skipline, 1,
+"bullet", CF_brace, BRACE_noarg, 0,
+"bye", CF_line, LINE_skipline, 1,
+"c", CF_line, LINE_lineraw, 1,
+"caption", CF_brace | CF_close_paragraph, BRACE_context, 1,
+"cartouche", CF_block | CF_close_paragraph, 0, 0,
+"center", CF_line | CF_close_paragraph, LINE_line, 1,
+"centerchap", CF_line | CF_root | CF_sectioning_heading | CF_deprecated, LINE_line, 1,
+"chapheading", CF_line | CF_sectioning_heading | CF_close_paragraph, LINE_line, 1,
+"chapter", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"cite", CF_brace, BRACE_style_other, 1,
+"clear", CF_line, LINE_special, 1,
+"click", CF_brace, BRACE_noarg, 0,
+"clicksequence", CF_brace, BRACE_style_other, 1,
+"clickstyle", CF_line | CF_global, LINE_special, 1,
+"code", CF_brace, BRACE_style_code, 1,
+"codequotebacktick", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"codequoteundirected", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"columnfractions", CF_line | CF_contain_plain_text, LINE_specific, 1,
+"comma", CF_brace, BRACE_noarg, 0,
+"command", CF_brace, BRACE_style_code, 1,
+"comment", CF_line, LINE_lineraw, 1,
+"contents", CF_line | CF_close_paragraph | CF_global, LINE_skipline, 1,
+"copying", CF_block | CF_close_paragraph | CF_global_unique, BLOCK_region, 0,
+"copyright", CF_brace, BRACE_noarg, 0,
+"defcodeindex", CF_line | CF_contain_plain_text, LINE_specific, 1,
+"defcv", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"defcvx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"deffn", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"deffnx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"defindex", CF_line | CF_contain_plain_text, LINE_specific, 1,
+"definfoenclose", CF_line | CF_contain_plain_text | CF_deprecated, LINE_specific, 3,
+"defivar", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"defivarx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"defmac", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"defmacx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"defmethod", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"defmethodx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"defop", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"defopt", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"defoptx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"defopx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"defspec", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"defspecx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"deftp", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"deftpx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"deftypecv", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"deftypecvx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"deftypefn", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"deftypefnnewline", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"deftypefnx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"deftypefun", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"deftypefunx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"deftypeivar", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"deftypeivarx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"deftypemethod", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"deftypemethodx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"deftypeop", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"deftypeopx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"deftypevar", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"deftypevarx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"deftypevr", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"deftypevrx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"defun", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"defunx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"defvar", CF_block | CF_def | CF_def_alias | CF_close_paragraph, BLOCK_def, 0,
+"defvarx", CF_line | CF_def | CF_def_alias | CF_close_paragraph, LINE_line, 1,
+"defvr", CF_block | CF_def | CF_close_paragraph, BLOCK_def, 0,
+"defvrx", CF_line | CF_def | CF_close_paragraph, LINE_line, 1,
+"detailmenu", CF_block | CF_close_paragraph | CF_global, BLOCK_menu, 0,
+"dfn", CF_brace, BRACE_style_other, 1,
+"dh", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"dircategory", CF_line | CF_close_paragraph | CF_contain_simple_text, LINE_line, 1,
+"direntry", CF_block | CF_close_paragraph, BLOCK_menu, 0,
+"display", CF_block | CF_close_paragraph | CF_preformatted, BLOCK_preformatted, 0,
+"displaymath", CF_block | CF_close_paragraph | CF_math, BLOCK_math, 0,
+"dmn", CF_brace | CF_contain_plain_text, BRACE_other, 1,
+"docbook", CF_block, BLOCK_format_raw, 0,
+"documentdescription", CF_block | CF_close_paragraph | CF_global_unique, BLOCK_region, 0,
+"documentencoding", CF_line | CF_global | CF_contain_plain_text, LINE_text, 1,
+"documentlanguage", CF_line | CF_global | CF_contain_plain_text | CF_contain_plain_text, LINE_text, 1,
+"dotaccent", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"dotless", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"dots", CF_brace, BRACE_noarg, 0,
+"email", CF_brace | CF_contain_simple_text, BRACE_arguments, 2,
+"emph", CF_brace, BRACE_style_other, 1,
+"end", CF_line | CF_contain_plain_text, LINE_text, 1,
+"enddots", CF_brace, BRACE_noarg, 0,
+"enumerate", CF_block | CF_close_paragraph | CF_blockitem | CF_contain_simple_text, BLOCK_item_container, 1,
+"env", CF_brace, BRACE_style_code, 1,
+"equiv", CF_brace, BRACE_noarg, 0,
+"error", CF_brace, BRACE_noarg, 0,
+"errormsg", CF_brace | CF_contain_simple_text, BRACE_arguments, 1,
+"euro", CF_brace, BRACE_noarg, 0,
+"evenfooting", CF_line | CF_global | CF_heading_spec | CF_contain_simple_text, LINE_line, 1,
+"evenfootingmarks", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"evenheading", CF_line | CF_global | CF_heading_spec | CF_contain_simple_text, LINE_line, 1,
+"evenheadingmarks", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"everyfooting", CF_line | CF_global | CF_heading_spec | CF_contain_simple_text, LINE_line, 1,
+"everyfootingmarks", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"everyheading", CF_line | CF_global | CF_heading_spec | CF_contain_simple_text, LINE_line, 1,
+"everyheadingmarks", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"example", CF_block | CF_close_paragraph | CF_preformatted | CF_preformatted_code | CF_variadic | CF_contain_simple_text, BLOCK_preformatted, 0,
+"exampleindent", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"exclamdown", CF_brace, BRACE_noarg, 0,
+"exdent", CF_line | CF_close_paragraph, LINE_line, 1,
+"expansion", CF_brace, BRACE_noarg, 0,
+"file", CF_brace, BRACE_style_code, 1,
+"finalout", CF_line, LINE_skipline, 1,
+"firstparagraphindent", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"float", CF_block | CF_close_paragraph | CF_contain_simple_text, BLOCK_float, 2,
+"flushleft", CF_block | CF_close_paragraph, 0, 0,
+"flushright", CF_block | CF_close_paragraph, 0, 0,
+"fonttextsize", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"footnote", CF_brace | CF_global, BRACE_context, 1,
+"footnotestyle", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"format", CF_block | CF_close_paragraph | CF_preformatted, BLOCK_preformatted, 0,
+"frenchspacing", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"ftable", CF_block | CF_close_paragraph | CF_blockitem | CF_contain_simple_text, BLOCK_item_line, 1,
+"geq", CF_brace, BRACE_noarg, 0,
+"group", CF_block | CF_close_paragraph, 0, 0,
+"guillemetleft", CF_brace, BRACE_noarg, 0,
+"guillemetright", CF_brace, BRACE_noarg, 0,
+"guillemotleft", CF_brace, BRACE_noarg, 0,
+"guillemotright", CF_brace, BRACE_noarg, 0,
+"guilsinglleft", CF_brace, BRACE_noarg, 0,
+"guilsinglright", CF_brace, BRACE_noarg, 0,
+"hashchar", CF_brace, BRACE_noarg, 0,
+"heading", CF_line | CF_sectioning_heading | CF_close_paragraph, LINE_line, 1,
+"headings", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"headitem", CF_nobrace | CF_close_paragraph, NOBRACE_skipspace, 1,
+"headitemfont", CF_brace, BRACE_style_other, 1,
+"html", CF_block, BLOCK_format_raw, 0,
+"hyphenation", CF_brace | CF_global | CF_contain_plain_text, BRACE_arguments, 1,
+"i", CF_brace, BRACE_style_other, 1,
+"ifclear", CF_block, BLOCK_conditional, 0,
+"ifcommanddefined", CF_block, BLOCK_conditional, 0,
+"ifcommandnotdefined", CF_block, BLOCK_conditional, 0,
+"ifdocbook", CF_block, BLOCK_conditional, 0,
+"ifhtml", CF_block, BLOCK_conditional, 0,
+"ifinfo", CF_block, BLOCK_conditional, 0,
+"iflatex", CF_block, BLOCK_conditional, 0,
+"ifnotdocbook", CF_block, BLOCK_conditional, 0,
+"ifnothtml", CF_block, BLOCK_conditional, 0,
+"ifnotinfo", CF_block, BLOCK_conditional, 0,
+"ifnotlatex", CF_block, BLOCK_conditional, 0,
+"ifnotplaintext", CF_block, BLOCK_conditional, 0,
+"ifnottex", CF_block, BLOCK_conditional, 0,
+"ifnotxml", CF_block, BLOCK_conditional, 0,
+"ifplaintext", CF_block, BLOCK_conditional, 0,
+"ifset", CF_block, BLOCK_conditional, 0,
+"iftex", CF_block, BLOCK_conditional, 0,
+"ifxml", CF_block, BLOCK_conditional, 0,
+"ignore", CF_block, BLOCK_raw, 0,
+"image", CF_brace | CF_contain_simple_text, BRACE_arguments, 5,
+"include", CF_line | CF_contain_plain_text, LINE_text, 1,
+"indent", CF_nobrace, NOBRACE_skipspace, 0,
+"indentedblock", CF_block | CF_close_paragraph, 0, 0,
+"indicateurl", CF_brace, BRACE_style_code, 1,
+"inforef", CF_brace | CF_ref | CF_contain_simple_text | CF_deprecated, BRACE_arguments, 3,
+"inlinefmt", CF_brace, BRACE_inline, 2,
+"inlinefmtifelse", CF_brace, BRACE_inline, 3,
+"inlineifclear", CF_brace, BRACE_inline, 2,
+"inlineifset", CF_brace, BRACE_inline, 2,
+"inlineraw", CF_brace, BRACE_inline, 2,
+"insertcopying", CF_line | CF_close_paragraph | CF_global, LINE_skipline, 1,
+"item", CF_nobrace | CF_close_paragraph, NOBRACE_skipspace, 1,
+"item_LINE", CF_line | CF_close_paragraph | CF_contain_simple_text, LINE_line, 1,
+"itemize", CF_block | CF_close_paragraph | CF_blockitem | CF_contain_simple_text, BLOCK_item_container, 1,
+"itemx", CF_line | CF_close_paragraph | CF_contain_simple_text, LINE_line, 1,
+"kbd", CF_brace, BRACE_style_code, 1,
+"kbdinputstyle", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"key", CF_brace | CF_contain_plain_text, BRACE_style_code, 1,
+"l", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"latex", CF_block, BLOCK_format_raw, 0,
+"lbracechar", CF_brace, BRACE_noarg, 0,
+"leq", CF_brace, BRACE_noarg, 0,
+"lisp", CF_block | CF_close_paragraph | CF_preformatted | CF_preformatted_code, BLOCK_preformatted, 0,
+"listoffloats", CF_line | CF_close_paragraph | CF_global | CF_contain_simple_text, LINE_line, 1,
+"lowersections", CF_line, LINE_skipline, 1,
+"macro", CF_block, BLOCK_raw, 0,
+"majorheading", CF_line | CF_sectioning_heading | CF_close_paragraph, LINE_line, 1,
+"math", CF_brace | CF_math | CF_contain_simple_text, BRACE_context, 1,
+"menu", CF_block | CF_close_paragraph, BLOCK_menu, 0,
+"microtype", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"minus", CF_brace, BRACE_noarg, 0,
+"multitable", CF_block | CF_close_paragraph | CF_blockitem | CF_contain_simple_text, BLOCK_multitable, 0,
+"need", CF_line | CF_close_paragraph | CF_contain_plain_text, LINE_specific, 1,
+"node", CF_line | CF_root | CF_contain_simple_text, LINE_line, 4,
+"noindent", CF_nobrace, NOBRACE_skipspace, 0,
+"novalidate", CF_line | CF_global_unique, LINE_skipline, 1,
+"o", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"oddfooting", CF_line | CF_global | CF_heading_spec | CF_contain_simple_text, LINE_line, 1,
+"oddfootingmarks", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"oddheading", CF_line | CF_global | CF_heading_spec | CF_contain_simple_text, LINE_line, 1,
+"oddheadingmarks", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"oe", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"ogonek", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"option", CF_brace, BRACE_style_code, 1,
+"ordf", CF_brace, BRACE_noarg, 0,
+"ordm", CF_brace, BRACE_noarg, 0,
+"page", CF_line | CF_close_paragraph, LINE_skipline, 1,
+"pagesizes", CF_line | CF_global_unique | CF_contain_plain_text, LINE_line, 1,
+"paragraphindent", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"part", CF_line | CF_root | CF_sectioning_heading | CF_global, LINE_line, 1,
+"point", CF_brace, BRACE_noarg, 0,
+"pounds", CF_brace, BRACE_noarg, 0,
+"print", CF_brace, BRACE_noarg, 0,
+"printindex", CF_line | CF_close_paragraph | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"pxref", CF_brace | CF_ref | CF_contain_simple_text, BRACE_arguments, 5,
+"questiondown", CF_brace, BRACE_noarg, 0,
+"quotation", CF_block | CF_close_paragraph | CF_contain_simple_text, BLOCK_quotation, 1,
+"quotedblbase", CF_brace, BRACE_noarg, 0,
+"quotedblleft", CF_brace, BRACE_noarg, 0,
+"quotedblright", CF_brace, BRACE_noarg, 0,
+"quoteleft", CF_brace, BRACE_noarg, 0,
+"quoteright", CF_brace, BRACE_noarg, 0,
+"quotesinglbase", CF_brace, BRACE_noarg, 0,
+"r", CF_brace, BRACE_style_no_code, 1,
+"raggedright", CF_block | CF_close_paragraph, 0, 0,
+"raisesections", CF_line, LINE_skipline, 1,
+"rbracechar", CF_brace, BRACE_noarg, 0,
+"ref", CF_brace | CF_ref | CF_contain_simple_text, BRACE_arguments, 5,
+"refill", CF_nobrace | CF_deprecated, NOBRACE_other, 1,
+"registeredsymbol", CF_brace, BRACE_noarg, 0,
+"result", CF_brace, BRACE_noarg, 0,
+"ringaccent", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"rmacro", CF_block, BLOCK_raw, 0,
+"samp", CF_brace, BRACE_style_code, 1,
+"sansserif", CF_brace, BRACE_style_other, 1,
+"sc", CF_brace, BRACE_style_other, 1,
+"section", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"seealso", CF_brace | CF_contain_simple_text, BRACE_arguments, 1,
+"seeentry", CF_brace | CF_contain_simple_text, BRACE_arguments, 1,
+"set", CF_line, LINE_special, 1,
+"setchapternewpage", CF_line | CF_global_unique | CF_contain_plain_text, LINE_specific, 1,
+"setfilename", CF_line | CF_close_paragraph | CF_global_unique | CF_contain_plain_text, LINE_text, 1,
+"settitle", CF_line | CF_global_unique | CF_contain_simple_text, LINE_line, 1,
+"shortcaption", CF_brace | CF_close_paragraph | CF_contain_simple_text, BRACE_context, 1,
+"shortcontents", CF_line | CF_close_paragraph | CF_global, LINE_skipline, 1,
+"shorttitlepage", CF_line | CF_global_unique | CF_contain_simple_text, LINE_line, 1,
+"slanted", CF_brace, BRACE_style_other, 1,
+"smallbook", CF_line | CF_global_unique, LINE_skipline, 1,
+"smalldisplay", CF_block | CF_close_paragraph | CF_preformatted, BLOCK_preformatted, 0,
+"smallexample", CF_block | CF_close_paragraph | CF_preformatted | CF_preformatted_code, BLOCK_preformatted, 0,
+"smallformat", CF_block | CF_close_paragraph | CF_preformatted, BLOCK_preformatted, 0,
+"smallindentedblock", CF_block | CF_close_paragraph, 0, 0,
+"smalllisp", CF_block | CF_close_paragraph | CF_preformatted | CF_preformatted_code, BLOCK_preformatted, 0,
+"smallquotation", CF_block | CF_close_paragraph | CF_contain_simple_text, BLOCK_quotation, 1,
+"sortas", CF_brace | CF_contain_plain_text, BRACE_arguments, 1,
+"sp", CF_line | CF_close_paragraph | CF_contain_plain_text, LINE_specific, 1,
+"ss", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"strong", CF_brace, BRACE_style_other, 1,
+"sub", CF_brace, BRACE_style_other, 1,
+"subentry", CF_line | CF_contain_simple_text, LINE_line, 1,
+"subheading", CF_line | CF_sectioning_heading | CF_close_paragraph, LINE_line, 1,
+"subsection", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"subsubheading", CF_line | CF_sectioning_heading | CF_close_paragraph, LINE_line, 1,
+"subsubsection", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"subtitle", CF_line | CF_global | CF_contain_simple_text, LINE_line, 1,
+"summarycontents", CF_line | CF_close_paragraph | CF_global, LINE_skipline, 1,
+"sup", CF_brace, BRACE_style_other, 1,
+"syncodeindex", CF_line | CF_contain_plain_text, LINE_specific, 2,
+"synindex", CF_line | CF_contain_plain_text, LINE_specific, 2,
+"t", CF_brace, BRACE_style_code, 1,
+"tab", CF_nobrace | CF_close_paragraph, NOBRACE_skipspace, 1,
+"table", CF_block | CF_close_paragraph | CF_blockitem | CF_contain_simple_text, BLOCK_item_line, 1,
+"tex", CF_block, BLOCK_format_raw, 0,
+"textdegree", CF_brace, BRACE_noarg, 0,
+"th", CF_brace | CF_letter_no_arg, BRACE_noarg, 0,
+"thischapter", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thischaptername", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thischapternum", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thisfile", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thispage", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thissection", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thissectionname", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thissectionnum", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"thistitle", CF_nobrace | CF_in_heading_spec, NOBRACE_other, 1,
+"tie", CF_brace, BRACE_noarg, 0,
+"tieaccent", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"title", CF_line | CF_global_unique | CF_contain_simple_text, LINE_line, 1,
+"titlefont", CF_brace | CF_close_paragraph | CF_global | CF_contain_simple_text, BRACE_other, 1,
+"titlepage", CF_block | CF_close_paragraph | CF_global_unique, BLOCK_region, 0,
+"today", CF_brace, BRACE_noarg, 0,
+"top", CF_line | CF_root | CF_sectioning_heading | CF_global_unique, LINE_line, 1,
+"txiinternalvalue", CF_internal | CF_brace, INTERNAL_brace, 1,
+"u", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"ubaraccent", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"udotaccent", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"unmacro", CF_line, LINE_special, 1,
+"unnumbered", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"unnumberedsec", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"unnumberedsubsec", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"unnumberedsubsubsec", CF_line | CF_root | CF_sectioning_heading, LINE_line, 1,
+"uref", CF_brace | CF_contain_simple_text, BRACE_arguments, 3,
+"urefbreakstyle", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"url", CF_brace | CF_contain_simple_text, BRACE_arguments, 3,
+"v", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
+"value", CF_brace, BRACE_special, 1,
+"var", CF_brace, BRACE_style_other, 1,
+"verb", CF_brace, BRACE_special, 1,
+"verbatim", CF_block | CF_close_paragraph, BLOCK_raw, 0,
+"verbatiminclude", CF_line | CF_close_paragraph | CF_contain_plain_text, LINE_text, 1,
+"vskip", CF_line, LINE_lineraw, 1,
+"vtable", CF_block | CF_close_paragraph | CF_blockitem | CF_contain_simple_text, BLOCK_item_line, 1,
+"w", CF_brace | CF_contain_simple_text, BRACE_special, 1,
+"xml", CF_block, BLOCK_format_raw, 0,
+"xref", CF_brace | CF_ref | CF_contain_simple_text, BRACE_arguments, 5,
+"xrefautomaticsectiontitle", CF_line | CF_global | CF_contain_plain_text, LINE_specific, 1,
+"{", CF_nobrace, NOBRACE_symbol, 0,
+"|", CF_nobrace | CF_in_heading_spec, NOBRACE_symbol, 1,
+"}", CF_nobrace, NOBRACE_symbol, 0,
+"~", CF_brace | CF_accent | CF_contain_plain_text, BRACE_accent, 1,
};
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.txt b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.txt
index e5d5643a46..db884cb5fb 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.txt
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_data.txt
@@ -15,41 +15,76 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Information from tp/Texinfo/Common.pm
+# this information is used to setup both the XS Parser commands
+# builtin_command_data and the perl Parser commands classification
+# hashes.
+
+# Some documentation of the flags (second column) is in commands.h.
+
+##############################################################
+# Internal commands
+# invalid if not accept_internalvalue set in configuration
+txiinternalvalue internal,brace INTERNAL_brace
+
+# nobrace:
+# commands never taking braces nor arguments on the line
+#
+# symbol: non-alphabetical one letter commands without braces.
+# skipspace: following spaces are skipped.
+# other: other.
-# Not in Common.pm
-value brace
##############################################################
# no brace commands - single letter commands
-* nobrace
+* nobrace NOBRACE_symbol
# space
-\x20 nobrace
-\t nobrace
-\n nobrace
-- nobrace
-| nobrace
-/ nobrace
-: nobrace
-! nobrace
-? nobrace
-. nobrace
-@ nobrace
-& nobrace
-} nobrace
-{ nobrace
-\\ nobrace
+\x20 nobrace NOBRACE_symbol
+\t nobrace NOBRACE_symbol
+\n nobrace NOBRACE_symbol
+- nobrace NOBRACE_symbol
+| nobrace,in_heading_spec NOBRACE_symbol
+/ nobrace NOBRACE_symbol
+: nobrace NOBRACE_symbol
+! nobrace NOBRACE_symbol
+? nobrace NOBRACE_symbol
+. nobrace NOBRACE_symbol
+@ nobrace NOBRACE_symbol
+& nobrace NOBRACE_symbol
+} nobrace NOBRACE_symbol
+{ nobrace NOBRACE_symbol
+\\ nobrace NOBRACE_symbol
##########################################################
#
# line commands
#
##########################################################
-node line LINE_line
+
+# commands taking a line as argument or no argument.
+# index commands are added dynamically.
+#
+# The values signification is:
+# special: no value and macro expansion, all the line is used, and
+# analysed during parsing (_parse_special_misc_command)
+# lineraw: no value and macro expansion, the line is kept as-is, not
+# analysed
+# skipline: no argument, everything else on the line is skipped
+# text: the line is parsed as texinfo, and the argument is converted
+# to simple text with convert_to_text allowing only a few @-commands
+# line: the line is parsed as texinfo
+# specific: the line is parsed as texinfo and the result should be plain
+# text maybe followed by a comment; the result is analysed
+# during parsing (parse_line_command_args).
+#
+# Beware that @item may be a 'line' command or a 'nobrace' command
+# depending on the context.
+
+# line commands number of arguments is only set for LINE_specific commands
+# and is not used anywhere in the code, it is here as documentation only
bye line LINE_skipline
-end line LINE_text
-# set, clear
+end line,contain_plain_text LINE_text
+# set, clear, special argument
set line LINE_special
clear line LINE_special
unmacro line LINE_special
@@ -57,119 +92,148 @@ unmacro line LINE_special
c line LINE_lineraw
comment line LINE_lineraw
# special
-definfoenclose line,deprecated 3
-alias line 2
+definfoenclose line,contain_plain_text,deprecated LINE_specific 3
+alias line,contain_plain_text LINE_specific 2
# number of arguments is not known in advance.
-columnfractions line 1
-# file names
-setfilename line,global_unique LINE_text
-verbatiminclude line LINE_text
-include line LINE_text
-
-raisesections line LINE_skipline
-lowersections line LINE_skipline
-contents line,global LINE_skipline
-shortcontents line,global LINE_skipline
-summarycontents line,global LINE_skipline
-insertcopying line,global LINE_skipline
-clickstyle line,global LINE_special
+columnfractions line,contain_plain_text LINE_specific
+# file names.
+setfilename line,close_paragraph,global_unique,contain_plain_text LINE_text
+verbatiminclude line,close_paragraph,contain_plain_text LINE_text
+include line,contain_plain_text LINE_text
+
+raisesections line LINE_skipline
+lowersections line LINE_skipline
+contents line,close_paragraph,global LINE_skipline
+shortcontents line,close_paragraph,global LINE_skipline
+summarycontents line,close_paragraph,global LINE_skipline
+insertcopying line,close_paragraph,global LINE_skipline
+# arg should be an @-command
+clickstyle line,global LINE_special
# more relevant in preamble
-documentencoding line,global LINE_text
-novalidate line,global_unique LINE_skipline
-dircategory line LINE_line
-# with direntry is significant
-pagesizes line,global_unique LINE_line
-# or one? 200mm,150mm 11.5in
+documentencoding line,global,contain_plain_text LINE_text
+novalidate line,global_unique LINE_skipline
+# Position with regard with direntry is significant
+dircategory line,close_paragraph,contain_simple_text LINE_line
+# arg like 200mm,150mm or 11.5in
+pagesizes line,global_unique,contain_plain_text LINE_line
finalout line LINE_skipline
-paragraphindent line,global 1
+# arg none asis
# or a number and forbids anything else on the line
-firstparagraphindent line,global 1
-frenchspacing line,global 1
-codequoteundirected line,global 1
-codequotebacktick line,global 1
-xrefautomaticsectiontitle line,global 1
-deftypefnnewline line,global 1
-fonttextsize line,global_unique 1
-allowcodebreaks line,global 1
-exampleindent line,global 1
-footnotestyle line,global_unique 1
-urefbreakstyle line,global 1
-afourpaper line LINE_skipline
-afivepaper line LINE_skipline
-afourlatex line LINE_skipline
-afourwide line LINE_skipline
-bsixpaper line LINE_skipline
-headings line,global 1
-setchapternewpage line,global_unique 1
-
-# only relevant in TeX, and special
-everyheading line,global_unique LINE_lineraw
-everyfooting line,global_unique LINE_lineraw
-evenheading line,global_unique LINE_lineraw
-evenfooting line,global_unique LINE_lineraw
-oddheading line,global_unique LINE_lineraw
-oddfooting line,global_unique LINE_lineraw
-
-smallbook line LINE_skipline
-syncodeindex line 2
-synindex line 2
-defindex line 1
-defcodeindex line 1
-documentlanguage line,global LINE_text
-kbdinputstyle line,global 1
-everyheadingmarks line,global_unique 1
-everyfootingmarks line,global_unique 1
-evenheadingmarks line,global_unique 1
-oddheadingmarks line,global_unique 1
-evenfootingmarks line,global_unique 1
-oddfootingmarks line,global_unique 1
+paragraphindent line,global,contain_plain_text LINE_specific 1
+# arg none insert
+firstparagraphindent line,global,contain_plain_text LINE_specific 1
+# arg on off
+frenchspacing line,global,contain_plain_text LINE_specific 1
+# arg on off
+codequoteundirected line,global,contain_plain_text LINE_specific 1
+# arg on off
+codequotebacktick line,global,contain_plain_text LINE_specific 1
+# arg on off
+xrefautomaticsectiontitle line,global,contain_plain_text LINE_specific 1
+# arg on off
+deftypefnnewline line,global,contain_plain_text LINE_specific 1
+# arg 10 11
+fonttextsize line,global_unique,contain_plain_text LINE_specific 1
+# arg false or true
+allowcodebreaks line,global,contain_plain_text LINE_specific 1
+# arg asis or a number
+exampleindent line,global,contain_plain_text LINE_specific 1
+# args end and separate, nothing else on the line
+footnotestyle line,global_unique,contain_plain_text LINE_specific 1
+# arg after|before|none
+urefbreakstyle line,global,contain_plain_text LINE_specific 1
+smallbook line,global_unique LINE_skipline
+afourpaper line,global_unique LINE_skipline
+afivepaper line,global_unique LINE_skipline
+afourlatex line,global_unique LINE_skipline
+afourwide line,global_unique LINE_skipline
+bsixpaper line,global_unique LINE_skipline
+# arg off on single double singleafter doubleafter
+# interacts with setchapternewpage
+headings line,global,contain_plain_text LINE_specific 1
+# arg off on odd
+setchapternewpage line,global_unique,contain_plain_text LINE_specific 1
+# arg on off
+microtype line,global,contain_plain_text LINE_specific 1
+
+everyheading line,global,heading_spec,contain_simple_text LINE_line
+everyfooting line,global,heading_spec,contain_simple_text LINE_line
+evenheading line,global,heading_spec,contain_simple_text LINE_line
+evenfooting line,global,heading_spec,contain_simple_text LINE_line
+oddheading line,global,heading_spec,contain_simple_text LINE_line
+oddfooting line,global,heading_spec,contain_simple_text LINE_line
+
+# args are index identifiers
+syncodeindex line,contain_plain_text LINE_specific 2
+synindex line,contain_plain_text LINE_specific 2
+# one identifier arg
+defindex line,contain_plain_text LINE_specific 1
+# one identifier arg
+defcodeindex line,contain_plain_text LINE_specific 1
+# language code arg
+documentlanguage line,global,contain_plain_text,contain_plain_text LINE_text
+# arg code example distinct
+kbdinputstyle line,global,contain_plain_text LINE_specific 1
+# arg top bottom
+everyheadingmarks line,global_unique,contain_plain_text LINE_specific 1
+everyfootingmarks line,global_unique,contain_plain_text LINE_specific 1
+evenheadingmarks line,global_unique,contain_plain_text LINE_specific 1
+oddheadingmarks line,global_unique,contain_plain_text LINE_specific 1
+evenfootingmarks line,global_unique,contain_plain_text LINE_specific 1
+oddfootingmarks line,global_unique,contain_plain_text LINE_specific 1
# formatting
-center line LINE_line
-printindex line,global 1
-listoffloats line,global LINE_line
+center line,close_paragraph LINE_line
+printindex line,close_paragraph,global,contain_plain_text LINE_specific 1
+listoffloats line,close_paragraph,global,contain_simple_text LINE_line
# especially in titlepage
# shorttitle
-shorttitlepage line,global_unique LINE_line
-settitle line,global_unique LINE_line
-author line,global LINE_line
-subtitle line,global LINE_line
-title line,global_unique LINE_line
-sp line 1
-page line LINE_skipline
-need line 1
+shorttitlepage line,global_unique,contain_simple_text LINE_line
+settitle line,global_unique,contain_simple_text LINE_line
+author line,global,contain_simple_text LINE_line
+subtitle line,global,contain_simple_text LINE_line
+title line,global_unique,contain_simple_text LINE_line
+# numerical arg
+sp line,close_paragraph,contain_plain_text LINE_specific 1
+page line,close_paragraph LINE_skipline
+# one numerical/real arg
+need line,close_paragraph,contain_plain_text LINE_specific 1
# not valid for info (should be in @iftex)
vskip line LINE_lineraw
-exdent line LINE_line
+exdent line,close_paragraph LINE_line
-item_LINE line LINE_line
-itemx line LINE_line
+# or nobrace skipspace, depending on the context
+item_LINE line,close_paragraph,contain_simple_text LINE_line
+itemx line,close_paragraph,contain_simple_text LINE_line
-subentry line LINE_line
+subentry line,contain_simple_text LINE_line
##########################################################
#
-# miscellaneous commands
+# no brace commands - miscellaneous commands
#
##########################################################
# formatting
-noindent other OTHER_skipspace
-indent other OTHER_skipspace
-headitem other OTHER_skipspace
-item other OTHER_skipspace
-tab other OTHER_skipspace
+noindent nobrace NOBRACE_skipspace
+indent nobrace NOBRACE_skipspace
+headitem nobrace,close_paragraph NOBRACE_skipspace
+item nobrace,close_paragraph NOBRACE_skipspace
+tab nobrace,close_paragraph NOBRACE_skipspace
# only valid in heading or footing
-thischapter other,in_heading OTHER_noarg
-thischaptername other,in_heading OTHER_noarg
-thischapternum other,in_heading OTHER_noarg
-thisfile other,in_heading OTHER_noarg
-thispage other,in_heading OTHER_noarg
-thistitle other,in_heading OTHER_noarg
+thischapter nobrace,in_heading_spec NOBRACE_other
+thischaptername nobrace,in_heading_spec NOBRACE_other
+thischapternum nobrace,in_heading_spec NOBRACE_other
+thissection nobrace,in_heading_spec NOBRACE_other
+thissectionname nobrace,in_heading_spec NOBRACE_other
+thissectionnum nobrace,in_heading_spec NOBRACE_other
+thisfile nobrace,in_heading_spec NOBRACE_other
+thispage nobrace,in_heading_spec NOBRACE_other
+thistitle nobrace,in_heading_spec NOBRACE_other
# obsolete @-commands.
-refill other,deprecated OTHER_noarg
+refill nobrace,deprecated NOBRACE_other
@@ -180,269 +244,285 @@ refill other,deprecated OTHER_noarg
##########################################################
# letter_no_arg_commands
-aa brace 0
-AA brace 0
-ae brace 0
-oe brace 0
-AE brace 0
-OE brace 0
-o brace 0
-O brace 0
-ss brace 0
-l brace 0
-L brace 0
-DH brace 0
-dh brace 0
-TH brace 0
-th brace 0
+aa brace,letter_no_arg BRACE_noarg
+AA brace,letter_no_arg BRACE_noarg
+ae brace,letter_no_arg BRACE_noarg
+oe brace,letter_no_arg BRACE_noarg
+AE brace,letter_no_arg BRACE_noarg
+OE brace,letter_no_arg BRACE_noarg
+o brace,letter_no_arg BRACE_noarg
+O brace,letter_no_arg BRACE_noarg
+ss brace,letter_no_arg BRACE_noarg
+l brace,letter_no_arg BRACE_noarg
+L brace,letter_no_arg BRACE_noarg
+DH brace,letter_no_arg BRACE_noarg
+dh brace,letter_no_arg BRACE_noarg
+TH brace,letter_no_arg BRACE_noarg
+th brace,letter_no_arg BRACE_noarg
# no arg commands
-TeX brace 0
-LaTeX brace 0
-bullet brace 0
-copyright brace 0
-registeredsymbol brace 0
-dots brace 0
-enddots brace 0
-equiv brace 0
-error brace 0
-expansion brace 0
-arrow brace 0
-minus brace 0
-point brace 0
-print brace 0
-result brace 0
-today brace 0
-exclamdown brace 0
-questiondown brace 0
-pounds brace 0
-ordf brace 0
-ordm brace 0
-atchar brace 0
-ampchar brace 0
-lbracechar brace 0
-rbracechar brace 0
-backslashchar brace 0
-hashchar brace 0
-comma brace 0
-euro brace 0
-geq brace 0
-leq brace 0
-tie brace 0
-textdegree brace 0
-click brace 0
-quotedblleft brace 0
-quotedblright brace 0
-quoteleft brace 0
-quoteright brace 0
-quotedblbase brace 0
-quotesinglbase brace 0
-guillemetleft brace 0
-guillemetright brace 0
-guillemotleft brace 0
-guillemotright brace 0
-guilsinglleft brace 0
-guilsinglright brace 0
+TeX brace BRACE_noarg
+LaTeX brace BRACE_noarg
+bullet brace BRACE_noarg
+copyright brace BRACE_noarg
+registeredsymbol brace BRACE_noarg
+dots brace BRACE_noarg
+enddots brace BRACE_noarg
+equiv brace BRACE_noarg
+error brace BRACE_noarg
+expansion brace BRACE_noarg
+arrow brace BRACE_noarg
+minus brace BRACE_noarg
+point brace BRACE_noarg
+print brace BRACE_noarg
+result brace BRACE_noarg
+today brace BRACE_noarg
+exclamdown brace BRACE_noarg
+questiondown brace BRACE_noarg
+pounds brace BRACE_noarg
+ordf brace BRACE_noarg
+ordm brace BRACE_noarg
+atchar brace BRACE_noarg
+ampchar brace BRACE_noarg
+lbracechar brace BRACE_noarg
+rbracechar brace BRACE_noarg
+backslashchar brace BRACE_noarg
+hashchar brace BRACE_noarg
+comma brace BRACE_noarg
+euro brace BRACE_noarg
+geq brace BRACE_noarg
+leq brace BRACE_noarg
+tie brace BRACE_noarg
+textdegree brace BRACE_noarg
+click brace BRACE_noarg
+quotedblleft brace BRACE_noarg
+quotedblright brace BRACE_noarg
+quoteleft brace BRACE_noarg
+quoteright brace BRACE_noarg
+quotedblbase brace BRACE_noarg
+quotesinglbase brace BRACE_noarg
+guillemetleft brace BRACE_noarg
+guillemetright brace BRACE_noarg
+guillemotleft brace BRACE_noarg
+guillemotright brace BRACE_noarg
+guilsinglleft brace BRACE_noarg
+guilsinglright brace BRACE_noarg
# accent commands - can be called with or without braces
-\" brace,accent BRACE_accent
-~ brace,accent BRACE_accent
-^ brace,accent BRACE_accent
-` brace,accent BRACE_accent
-' brace,accent BRACE_accent
-, brace,accent BRACE_accent
-= brace,accent BRACE_accent
-ringaccent brace,accent BRACE_accent
-H brace,accent BRACE_accent
-dotaccent brace,accent BRACE_accent
-u brace,accent BRACE_accent
-ubaraccent brace,accent BRACE_accent
-udotaccent brace,accent BRACE_accent
-v brace,accent BRACE_accent
-ogonek brace,accent BRACE_accent
-tieaccent brace,accent BRACE_accent
-dotless brace,accent BRACE_accent
+\" brace,accent,contain_plain_text BRACE_accent
+~ brace,accent,contain_plain_text BRACE_accent
+^ brace,accent,contain_plain_text BRACE_accent
+` brace,accent,contain_plain_text BRACE_accent
+' brace,accent,contain_plain_text BRACE_accent
+, brace,accent,contain_plain_text BRACE_accent
+= brace,accent,contain_plain_text BRACE_accent
+ringaccent brace,accent,contain_plain_text BRACE_accent
+H brace,accent,contain_plain_text BRACE_accent
+dotaccent brace,accent,contain_plain_text BRACE_accent
+u brace,accent,contain_plain_text BRACE_accent
+ubaraccent brace,accent,contain_plain_text BRACE_accent
+udotaccent brace,accent,contain_plain_text BRACE_accent
+v brace,accent,contain_plain_text BRACE_accent
+ogonek brace,accent,contain_plain_text BRACE_accent
+tieaccent brace,accent,contain_plain_text BRACE_accent
+dotless brace,accent,contain_plain_text BRACE_accent
# Style commands
-asis brace BRACE_style
-cite brace BRACE_style
-clicksequence brace BRACE_style
-dfn brace BRACE_style
-emph brace BRACE_style
-sc brace BRACE_style
-t brace BRACE_style
-var brace BRACE_style
-headitemfont brace BRACE_style
-code brace,code_style BRACE_style
-command brace,code_style BRACE_style
-env brace,code_style BRACE_style
-file brace,code_style BRACE_style
-kbd brace,code_style BRACE_style
-option brace,code_style BRACE_style
-samp brace,code_style BRACE_style
-strong brace BRACE_style
-sub brace BRACE_style
-sup brace BRACE_style
-
-# Regular font style commands
-r brace BRACE_style
-i brace BRACE_style
-b brace BRACE_style
-sansserif brace BRACE_style
-slanted brace BRACE_style
-
-U brace 1
-dmn brace 1
-titlefont brace,global 1
-
-w brace BRACE_other
-key brace BRACE_other
-
-hyphenation brace,global BRACE_other
-anchor brace 1
-errormsg brace 1
-sortas brace 1
-seeentry brace 1
-seealso brace 1
-
-# more code style commands
-indicateurl brace,code_style 1
-verb brace,code_style BRACE_other
-t brace,code_style BRACE_other
+asis brace BRACE_style_other
+i brace BRACE_style_other
+b brace BRACE_style_other
+sansserif brace BRACE_style_other
+slanted brace BRACE_style_other
+cite brace BRACE_style_other
+clicksequence brace BRACE_style_other
+dfn brace BRACE_style_other
+emph brace BRACE_style_other
+sc brace BRACE_style_other
+var brace BRACE_style_other
+headitemfont brace BRACE_style_other
+strong brace BRACE_style_other
+sub brace BRACE_style_other
+sup brace BRACE_style_other
+
+# code style commands
+code brace BRACE_style_code
+command brace BRACE_style_code
+env brace BRACE_style_code
+file brace BRACE_style_code
+indicateurl brace BRACE_style_code
+kbd brace BRACE_style_code
+key brace,contain_plain_text BRACE_style_code
+option brace BRACE_style_code
+samp brace BRACE_style_code
+t brace BRACE_style_code
+
+# No code style commands
+r brace BRACE_style_no_code
+
+# in this category, the leading and trailing spaces are put in specific
+# text with type, but commas do not delimitate arguments.
+# As other arguments brace_commands, they can only contain simple text,
+# ie not ref, footnote, titlefont, anchor, verb.
+# Parsers have specific checks for U content.
+U brace BRACE_arguments 1
+hyphenation brace,global,contain_plain_text BRACE_arguments 1
+anchor brace,contain_simple_text BRACE_arguments 1
+errormsg brace,contain_simple_text BRACE_arguments 1
+sortas brace,contain_plain_text BRACE_arguments 1
+seeentry brace,contain_simple_text BRACE_arguments 1
+seealso brace,contain_simple_text BRACE_arguments 1
+
+# Leading and trailing spaces kept in main text.
+# verb is treated especially, it should not matter much in which category it is.
+# value also is treated especially.
+value brace BRACE_special
+verb brace BRACE_special
+w brace,contain_simple_text BRACE_special
+
+# other brace commands, leading and trailing spaces kept in main text
+dmn brace,contain_plain_text BRACE_other 1
+titlefont brace,close_paragraph,global,contain_simple_text BRACE_other 1
# context brace commands - commands that enclose full texts
+# not in the main document context. They can contain multiple paragraphs.
footnote brace,global BRACE_context
-caption brace BRACE_context
-shortcaption brace BRACE_context
-math brace BRACE_context
+caption brace,close_paragraph BRACE_context
+shortcaption brace,close_paragraph,contain_simple_text BRACE_context
+# Commands that enclose math content, and, because of that, are not in the
+# main document context.
+math brace,math,contain_simple_text BRACE_context
# explained commands
-abbr brace 2
-acronym brace 2
+abbr brace,contain_simple_text BRACE_arguments 2
+acronym brace,contain_simple_text BRACE_arguments 2
+# leading space is ignored in inline brace commands, not trailing space
# inline format command
-inlineraw brace,inline 2
-inlinefmt brace,inline 2
-inlinefmtifelse brace,inline 3
+inlineraw brace BRACE_inline 2
+inlinefmt brace BRACE_inline 2
+inlinefmtifelse brace BRACE_inline 3
# inline conditional commands
-inlineifclear brace,inline 2
-inlineifset brace,inline 2
+inlineifclear brace BRACE_inline 2
+inlineifset brace BRACE_inline 2
-email brace 2
+email brace,contain_simple_text BRACE_arguments 2
-uref brace 3
-url brace 3
-inforef brace,ref,deprecated 3
+uref brace,contain_simple_text BRACE_arguments 3
+url brace,contain_simple_text BRACE_arguments 3
+inforef brace,ref,contain_simple_text,deprecated BRACE_arguments 3
-xref brace,ref 5
-ref brace,ref 5
-pxref brace,ref 5
-image brace 5
+xref brace,ref,contain_simple_text BRACE_arguments 5
+ref brace,ref,contain_simple_text BRACE_arguments 5
+pxref brace,ref,contain_simple_text BRACE_arguments 5
+image brace,contain_simple_text BRACE_arguments 5
##########################################################
+# commands delimiting blocks, with an @end.
# def* commands
-deffn block,def
-defvr block,def
-deftypefn block,def
-deftypeop block,def
-deftypevr block,def
-defcv block,def
-deftypecv block,def
-defop block,def
-deftp block,def
+deffn block,def,close_paragraph BLOCK_def
+defvr block,def,close_paragraph BLOCK_def
+deftypefn block,def,close_paragraph BLOCK_def
+deftypeop block,def,close_paragraph BLOCK_def
+deftypevr block,def,close_paragraph BLOCK_def
+defcv block,def,close_paragraph BLOCK_def
+deftypecv block,def,close_paragraph BLOCK_def
+defop block,def,close_paragraph BLOCK_def
+deftp block,def,close_paragraph BLOCK_def
# shortcuts
-defun block,def,def_alias
-defmac block,def,def_alias
-defspec block,def,def_alias
-defvar block,def,def_alias
-defopt block,def,def_alias
-deftypefun block,def,def_alias
-deftypevar block,def,def_alias
-defivar block,def,def_alias
-deftypeivar block,def,def_alias
-defmethod block,def,def_alias
-deftypemethod block,def,def_alias
+defun block,def,def_alias,close_paragraph BLOCK_def
+defmac block,def,def_alias,close_paragraph BLOCK_def
+defspec block,def,def_alias,close_paragraph BLOCK_def
+defvar block,def,def_alias,close_paragraph BLOCK_def
+defopt block,def,def_alias,close_paragraph BLOCK_def
+deftypefun block,def,def_alias,close_paragraph BLOCK_def
+deftypevar block,def,def_alias,close_paragraph BLOCK_def
+defivar block,def,def_alias,close_paragraph BLOCK_def
+deftypeivar block,def,def_alias,close_paragraph BLOCK_def
+defmethod block,def,def_alias,close_paragraph BLOCK_def
+deftypemethod block,def,def_alias,close_paragraph BLOCK_def
# def*x
-deffnx line,def LINE_line
-defvrx line,def LINE_line
-deftypefnx line,def LINE_line
-deftypeopx line,def LINE_line
-deftypevrx line,def LINE_line
-defcvx line,def LINE_line
-deftypecvx line,def LINE_line
-defopx line,def LINE_line
-deftpx line,def LINE_line
+deffnx line,def,close_paragraph LINE_line
+defvrx line,def,close_paragraph LINE_line
+deftypefnx line,def,close_paragraph LINE_line
+deftypeopx line,def,close_paragraph LINE_line
+deftypevrx line,def,close_paragraph LINE_line
+defcvx line,def,close_paragraph LINE_line
+deftypecvx line,def,close_paragraph LINE_line
+defopx line,def,close_paragraph LINE_line
+deftpx line,def,close_paragraph LINE_line
# shortcuts
-defunx line,def,def_alias LINE_line
-defmacx line,def,def_alias LINE_line
-defspecx line,def,def_alias LINE_line
-defvarx line,def,def_alias LINE_line
-defoptx line,def,def_alias LINE_line
-deftypefunx line,def,def_alias LINE_line
-deftypevarx line,def,def_alias LINE_line
-defivarx line,def,def_alias LINE_line
-deftypeivarx line,def,def_alias LINE_line
-defmethodx line,def,def_alias LINE_line
-deftypemethodx line,def,def_alias LINE_line
-
-multitable block,blockitem BLOCK_multitable
-
-# menu commands
-menu block,menu
-detailmenu block,menu,global
-direntry block,menu
+defunx line,def,def_alias,close_paragraph LINE_line
+defmacx line,def,def_alias,close_paragraph LINE_line
+defspecx line,def,def_alias,close_paragraph LINE_line
+defvarx line,def,def_alias,close_paragraph LINE_line
+defoptx line,def,def_alias,close_paragraph LINE_line
+deftypefunx line,def,def_alias,close_paragraph LINE_line
+deftypevarx line,def,def_alias,close_paragraph LINE_line
+defivarx line,def,def_alias,close_paragraph LINE_line
+deftypeivarx line,def,def_alias,close_paragraph LINE_line
+defmethodx line,def,def_alias,close_paragraph LINE_line
+deftypemethodx line,def,def_alias,close_paragraph LINE_line
+
+multitable block,close_paragraph,blockitem,contain_simple_text BLOCK_multitable
+
+# menu commands in which menu entry and menu comments appear
+menu block,close_paragraph BLOCK_menu
+detailmenu block,close_paragraph,global BLOCK_menu
+direntry block,close_paragraph BLOCK_menu
# align commands
-raggedright block
-flushleft block
-flushright block
+raggedright block,close_paragraph
+flushleft block,close_paragraph
+flushright block,close_paragraph
+indentedblock block,close_paragraph
+smallindentedblock block,close_paragraph
-cartouche block
-group block
-indentedblock block
-smallindentedblock block
+cartouche block,close_paragraph
+group block,close_paragraph
# region commands
-titlepage block,global_unique BLOCK_region
-copying block,global_unique BLOCK_region
-documentdescription block,global_unique BLOCK_region
+titlepage block,close_paragraph,global_unique BLOCK_region
+copying block,close_paragraph,global_unique BLOCK_region
+documentdescription block,close_paragraph,global_unique BLOCK_region
# preformatted commands
-example block,preformatted,preformatted_code BLOCK_variadic
-smallexample block,preformatted,preformatted_code
-lisp block,preformatted,preformatted_code
-smalllisp block,preformatted,preformatted_code
-display block,preformatted
-smalldisplay block,preformatted
-format block,preformatted
-smallformat block,preformatted
+example block,close_paragraph,preformatted,preformatted_code,variadic,contain_simple_text BLOCK_preformatted
+smallexample block,close_paragraph,preformatted,preformatted_code BLOCK_preformatted
+lisp block,close_paragraph,preformatted,preformatted_code BLOCK_preformatted
+smalllisp block,close_paragraph,preformatted,preformatted_code BLOCK_preformatted
+display block,close_paragraph,preformatted BLOCK_preformatted
+smalldisplay block,close_paragraph,preformatted BLOCK_preformatted
+format block,close_paragraph,preformatted BLOCK_preformatted
+smallformat block,close_paragraph,preformatted BLOCK_preformatted
# format raw commands
-html block,format_raw
-tex block,format_raw
-xml block,format_raw
-docbook block,format_raw
+html block BLOCK_format_raw
+tex block BLOCK_format_raw
+xml block BLOCK_format_raw
+docbook block BLOCK_format_raw
+latex block BLOCK_format_raw
# raw commands
-verbatim block BLOCK_raw
-ignore block BLOCK_raw
-macro block BLOCK_raw
-rmacro block BLOCK_raw
-
-table block,blockitem 1
-ftable block,blockitem 1
-vtable block,blockitem 1
-itemize block,blockitem 1
-enumerate block,blockitem 1
-quotation block 1
-smallquotation block 1
-
-float block 2
-displaymath block 0
+verbatim block,close_paragraph BLOCK_raw
+ignore block BLOCK_raw
+macro block BLOCK_raw
+rmacro block BLOCK_raw
+
+table block,close_paragraph,blockitem,contain_simple_text BLOCK_item_line 1
+ftable block,close_paragraph,blockitem,contain_simple_text BLOCK_item_line 1
+vtable block,close_paragraph,blockitem,contain_simple_text BLOCK_item_line 1
+itemize block,close_paragraph,blockitem,contain_simple_text BLOCK_item_container 1
+enumerate block,close_paragraph,blockitem,contain_simple_text BLOCK_item_container 1
+quotation block,close_paragraph,contain_simple_text BLOCK_quotation 1
+smallquotation block,close_paragraph,contain_simple_text BLOCK_quotation 1
+
+float block,close_paragraph,contain_simple_text BLOCK_float 2
+
+displaymath block,close_paragraph,math BLOCK_math
##################################################################
# Conditional commands
@@ -458,6 +538,8 @@ ifinfo block BLOCK_conditional
ifnotinfo block BLOCK_conditional
ifplaintext block BLOCK_conditional
ifnotplaintext block BLOCK_conditional
+iflatex block BLOCK_conditional
+ifnotlatex block BLOCK_conditional
ifset block BLOCK_conditional
ifclear block BLOCK_conditional
ifcommanddefined block BLOCK_conditional
@@ -465,27 +547,27 @@ ifcommandnotdefined block BLOCK_conditional
##########################################################
# Root commands
-node root,line LINE_line
-top root,line,sectioning,global_unique LINE_line
-chapter root,line,sectioning LINE_line
-unnumbered root,line,sectioning LINE_line
-chapheading line,sectioning LINE_line
-appendix root,line,sectioning LINE_line
-section root,line,sectioning LINE_line
-unnumberedsec root,line,sectioning LINE_line
-heading line,sectioning LINE_line
-appendixsec root,line,sectioning LINE_line
-subsection root,line,sectioning LINE_line
-unnumberedsubsec root,line,sectioning LINE_line
-subheading line,sectioning LINE_line
-appendixsubsec root,line,sectioning LINE_line
-subsubsection root,line,sectioning LINE_line
-unnumberedsubsubsec root,line,sectioning LINE_line
-subsubheading line,sectioning LINE_line
-appendixsubsubsec root,line,sectioning LINE_line
-
-part root,line,sectioning,global LINE_line
-appendixsection root,line,sectioning LINE_line
-majorheading line,sectioning LINE_line
-centerchap root,line,sectioning,deprecated LINE_line
+node line,root,contain_simple_text LINE_line 4
+top line,root,sectioning_heading,global_unique LINE_line
+chapter line,root,sectioning_heading LINE_line
+unnumbered line,root,sectioning_heading LINE_line
+chapheading line,sectioning_heading,close_paragraph LINE_line
+appendix line,root,sectioning_heading LINE_line
+section line,root,sectioning_heading LINE_line
+unnumberedsec line,root,sectioning_heading LINE_line
+heading line,sectioning_heading,close_paragraph LINE_line
+appendixsec line,root,sectioning_heading LINE_line
+subsection line,root,sectioning_heading LINE_line
+unnumberedsubsec line,root,sectioning_heading LINE_line
+subheading line,sectioning_heading,close_paragraph LINE_line
+appendixsubsec line,root,sectioning_heading LINE_line
+subsubsection line,root,sectioning_heading LINE_line
+unnumberedsubsubsec line,root,sectioning_heading LINE_line
+subsubheading line,sectioning_heading,close_paragraph LINE_line
+appendixsubsubsec line,root,sectioning_heading LINE_line
+
+part line,root,sectioning_heading,global LINE_line
+appendixsection line,root,sectioning_heading LINE_line
+majorheading line,sectioning_heading,close_paragraph LINE_line
+centerchap line,root,sectioning_heading,deprecated LINE_line
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_ids.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_ids.h
index 1201e40484..a2c8542ad2 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_ids.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/command_ids.h
@@ -226,9 +226,11 @@ CM_ifcommandnotdefined,
CM_ifdocbook,
CM_ifhtml,
CM_ifinfo,
+CM_iflatex,
CM_ifnotdocbook,
CM_ifnothtml,
CM_ifnotinfo,
+CM_ifnotlatex,
CM_ifnotplaintext,
CM_ifnottex,
CM_ifnotxml,
@@ -257,6 +259,7 @@ CM_kbd,
CM_kbdinputstyle,
CM_key,
CM_l,
+CM_latex,
CM_lbracechar,
CM_leq,
CM_lisp,
@@ -266,6 +269,7 @@ CM_macro,
CM_majorheading,
CM_math,
CM_menu,
+CM_microtype,
CM_minus,
CM_multitable,
CM_need,
@@ -356,6 +360,9 @@ CM_thischaptername,
CM_thischapternum,
CM_thisfile,
CM_thispage,
+CM_thissection,
+CM_thissectionname,
+CM_thissectionnum,
CM_thistitle,
CM_tie,
CM_tieaccent,
@@ -364,6 +371,7 @@ CM_titlefont,
CM_titlepage,
CM_today,
CM_top,
+CM_txiinternalvalue,
CM_u,
CM_ubaraccent,
CM_udotaccent,
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.c
index e0caffd149..943afa42fa 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.c
@@ -22,6 +22,12 @@
#include "commands.h"
#include "errors.h"
+/* FIXME pass global_accept_internalvalue to lookup_command instead of
+ * #include parser.h to get the global variable value? */
+
+/* for global_accept_internalvalue */
+#include "parser.h"
+
#include "command_data.c"
COMMAND *user_defined_command_data = 0;
@@ -67,7 +73,18 @@ lookup_command (char *cmdname)
compare_command_fn);
if (c)
- return c - &builtin_command_data[0];
+ {
+ enum command_id cmd;
+ cmd = c - &builtin_command_data[0];
+
+ /* txiinternalvalue is invalid if the corresponding configuration
+ * is not set */
+ if (cmd == CM_txiinternalvalue && !global_accept_internalvalue) {
+ return 0;
+ }
+
+ return cmd;
+ }
return 0;
@@ -90,6 +107,7 @@ add_texinfo_command (char *name)
user_defined_command_data[user_defined_number].cmdname = strdup (name);
user_defined_command_data[user_defined_number].flags = 0;
user_defined_command_data[user_defined_number].data = 0;
+ user_defined_command_data[user_defined_number].args_number = 0;
return ((enum command_id) user_defined_number++) | USER_COMMAND_BIT;
}
@@ -112,68 +130,15 @@ wipe_user_commands (void)
user_defined_number = 0;
}
-/* Commands that terminate a paragraph. */
-/* We may replace this function with a macro, or represent this infomation in
- command_data. */
-int
-close_paragraph_command (enum command_id cmd)
-{
- if (cmd == CM_verbatim)
- return 1;
-
- /* Block commands except 'raw' and 'conditional'. */
-
- if (command_data(cmd).flags & CF_block)
- {
- if (command_data(cmd).data == BLOCK_conditional
- || command_data(cmd).data == BLOCK_raw)
- return 0;
- if (command_data(cmd).flags & CF_format_raw)
- return 0;
-
- return 1;
- }
-
- if (cmd == CM_titlefont
- || cmd == CM_insertcopying
- || cmd == CM_sp
- || cmd == CM_verbatiminclude
- || cmd == CM_page
- || cmd == CM_item
- || cmd == CM_itemx
- || cmd == CM_tab
- || cmd == CM_headitem
- || cmd == CM_printindex
- || cmd == CM_listoffloats
- || cmd == CM_center
- || cmd == CM_dircategory
- || cmd == CM_contents
- || cmd == CM_shortcontents
- || cmd == CM_summarycontents
- || cmd == CM_caption
- || cmd == CM_shortcaption
- || cmd == CM_setfilename
- || cmd == CM_exdent)
- return 1;
-
- if ((command_data(cmd).flags & CF_sectioning)
- && !(command_data(cmd).flags & CF_root))
- return 1;
-
- if ((command_data(cmd).flags & CF_def))
- return 1;
-
- return 0;
-}
-
int
close_preformatted_command (enum command_id cmd_id)
{
- return cmd_id != CM_sp && close_paragraph_command (cmd_id);
+ return cmd_id != CM_sp
+ && command_data(cmd_id).flags & CF_close_paragraph;
}
int
item_line_command (enum command_id cmd_id)
{
- return cmd_id == CM_table || cmd_id == CM_ftable || cmd_id == CM_vtable;
+ return command_data(cmd_id).data == BLOCK_item_line;
}
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.h
index 92078a4c4d..60a119e284 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/commands.h
@@ -19,7 +19,8 @@
typedef struct command_struct {
char *cmdname;
unsigned long flags; /* Up to 32 flags */
- int data; /* Number of arguments for brace or line commands. */
+ int data; /* type of command. */
+ int args_number; /* Number of arguments for brace or line commands. */
} COMMAND;
extern COMMAND builtin_command_data[];
@@ -38,7 +39,6 @@ enum command_id lookup_command (char *cmdname);
#define command_flags(e) (!(e) ? 0 : (command_data((e)->cmd).flags))
#define command_name(cmd) (command_data(cmd).cmdname)
-int close_paragraph_command (enum command_id cmd_id);
int close_preformatted_command (enum command_id cmd_id);
int item_line_command (enum command_id cmd_id);
enum command_id add_texinfo_command (char *name);
@@ -49,44 +49,56 @@ void wipe_user_commands (void);
#define CF_line 0x0001
#define CF_deprecated 0x0002
+/* commands that should only appear at the root level and contain up to
+ the next root command. @node and sectioning commands. */
#define CF_root 0x0004
-#define CF_sectioning 0x0008
+/* sectioning and heading commands */
+#define CF_sectioning_heading 0x0008
#define CF_brace 0x0010
+/* CF_letter_no_arg is not used in XS parser, used in perl */
#define CF_letter_no_arg 0x0020
#define CF_accent 0x0040
-#define CF_style 0x0080
-/* CF_code_style is set for brace commands only. */
-#define CF_code_style 0x0100
+/* CF_math is not used in XS parser, used in perl */
+#define CF_math 0x0080
+/* commands with an unlimited number of arguments */
+#define CF_variadic 0x0100
#define CF_INFOENCLOSE 0x0200
-#define CF_in_heading 0x0400
+/* in_heading_spec only valid in heading or footing specifications */
+#define CF_in_heading_spec 0x0400
#define CF_ref 0x0800
#define CF_ALIAS 0x1000
#define CF_block 0x2000
-#define CF_raw 0x4000
-#define CF_format_raw 0x8000
-#define CF_global 0x00010000
+/* in_heading_spec commands are only valid in heading_spec */
+#define CF_heading_spec 0x4000
+/* CF_internal is not used in code, but it should be kept as internal
+ * commands marker */
+#define CF_internal 0x8000
+#define CF_global 0x00010000
#define CF_def 0x00020000
#define CF_def_alias 0x00040000
-#define CF_menu 0x00080000
-#define CF_align 0x00100000
-#define CF_other 0x00200000
+/* only accept plain text, ie only accent, symbol and glyph commands */
+#define CF_contain_plain_text 0x00080000
+/* CF_close_paragraph commands force closing an opened paragraph */
+#define CF_close_paragraph 0x00100000
+/* for commands containing simple text only, corresponding to paragraph
+ text without @ref, @footnote, @titlefont, @anchor nor @verb. */
+#define CF_contain_simple_text 0x00200000
#define CF_preformatted 0x00400000
#define CF_preformatted_code 0x00800000
+/* CF_item_container is not used */
#define CF_item_container 0x01000000
+/* CF_item_line is not used */
#define CF_item_line 0x02000000
#define CF_nobrace 0x04000000
+/* blockitem commands have a possible content before an item */
#define CF_blockitem 0x08000000
+/* CF_inline is not used */
#define CF_inline 0x10000000
#define CF_MACRO 0x20000000
#define CF_index_entry_command 0x40000000
#define CF_global_unique 0x80000000
-/* NOTE: We've run out of spaces for flags, but some of these may not
- be used, or may not be necessary.
- CF_code_style, CF_deprecated are hardly used.
-
- Candidates for flags:
- CF_close_paragraph
+/* NOTE: We often run out of spaces for flags
Could combine CF_MACRO, CF_ALIAS, and CF_INFOENCLOSE into 2 bits.
*/
@@ -95,24 +107,48 @@ void wipe_user_commands (void);
#define LINE_special -1
#define LINE_lineraw -2
#define LINE_skipline -3
+#define LINE_specific -4
#define LINE_text -6
#define LINE_line -7
-/* Types of other command (has CF_other flag). */
-#define OTHER_skipspace -1
-#define OTHER_noarg -2
+/* Types of command without brace nor argument on line (has CF_nobrace flag). */
+#define NOBRACE_symbol 0
+#define NOBRACE_skipspace -1
+#define NOBRACE_other -2
/* Types of block command (CF_block). */
#define BLOCK_conditional -1
#define BLOCK_raw -2
#define BLOCK_multitable -3
#define BLOCK_region -4
-#define BLOCK_variadic -5
+#define BLOCK_item_line -5
+/* not used in code but consistent with type in perl hash */
+#define BLOCK_item_container -6
+/* not used in code but consistent with type in perl hash */
+#define BLOCK_quotation -7
+#define BLOCK_float -8
+#define BLOCK_menu -9
+#define BLOCK_format_raw -10
+/* not used in code but consistent with type in perl hash */
+#define BLOCK_def -11
+/* not used in code but consistent with type in perl hash */
+#define BLOCK_preformatted -12
+/* not used in code but consistent with type in perl hash */
+#define BLOCK_math -13
/* Types of brace command (CF_brace). */
+#define BRACE_arguments 1
+#define BRACE_noarg 0
#define BRACE_context -1 /* Can enclose paragraph breaks. */
#define BRACE_accent -2
-#define BRACE_style -3
-#define BRACE_other -4
+#define BRACE_style_other -3
+#define BRACE_style_code -5
+#define BRACE_style_no_code -6
+#define BRACE_other -7
+#define BRACE_special -8
+#define BRACE_inline -9
+
+/* Types of internal commands (CF_internal). */
+#define INTERNAL_brace -1
#endif
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.c
index 4d734942bb..5797e12853 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.c
@@ -47,4 +47,5 @@ reset_conf (void)
conf.show_menu = 1;
conf.cpp_line_directives = 1;
conf.ignore_space_after_braced_command_name = 1;
+ conf.doc_encoding_for_input_file_name = 1;
}
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.h
index 7efcb566b3..33ce3b7fbf 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/conf.h
@@ -20,6 +20,7 @@ typedef struct CONF {
int show_menu;
int cpp_line_directives;
int ignore_space_after_braced_command_name;
+ int doc_encoding_for_input_file_name;
} CONF;
extern CONF conf;
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.c
index b3fca7afc5..0ecd1dec6e 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.c
@@ -19,6 +19,7 @@
#include "parser.h"
static enum context *stack;
+static enum command_id *commands_stack;
static size_t top; /* One above last pushed context. */
static size_t space;
@@ -29,20 +30,24 @@ reset_context_stack (void)
}
void
-push_context (enum context c)
+push_context (enum context c, enum command_id cmd)
{
if (top >= space)
{
stack = realloc (stack, (space += 5) * sizeof (enum context));
+ commands_stack
+ = realloc (commands_stack, (space += 5) * sizeof (enum command_id));
}
- debug (">>>>>>>>>>>>>>>>>PUSHING STACK AT %d -- %s", top,
+ debug (">>>>>>>>>>>>>>>>>PUSHING STACK AT %d -- %s @%s", top,
c == ct_preformatted ? "preformatted"
: c == ct_line ? "line"
: c == ct_def ? "def"
- : c == ct_menu ? "menu"
- : "");
- stack[top++] = c;
+ : c == ct_brace_command ? "brace_command"
+ : "", command_name(cmd));
+ stack[top] = c;
+ commands_stack[top] = cmd;
+ top++;
}
enum context
@@ -64,6 +69,21 @@ current_context (void)
return stack[top - 1];
}
+enum command_id
+current_context_command (void)
+{
+ int i;
+
+ if (top == 0)
+ return CM_NONE;
+ for (i = top -1; i >= 0; i--)
+ {
+ if (commands_stack[i] != CM_NONE)
+ return commands_stack[i];
+ }
+ return CM_NONE;
+}
+
/* The valid regions are 'titlepage', 'copying', and 'documentdescription'.
This stack isn't used that much. */
@@ -119,3 +139,28 @@ current_region (void)
return region_stack[region_top - 1];
}
+
+
+/* used for @kbd */
+int
+in_preformatted_context_not_menu()
+{
+ int i;
+
+ if (top == 0)
+ return 0;
+ for (i = top -1; i >= 0; i--)
+ {
+ enum context ct;
+ enum command_id cmd;
+ ct = stack[i];
+ if (ct != ct_line && ct != ct_preformatted)
+ return 0;
+ cmd = commands_stack[i];
+ if (command_data(cmd).flags & CF_block
+ && command_data(cmd).data != BLOCK_menu
+ && ct == ct_preformatted)
+ return 1;
+ }
+ return 0;
+}
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.h
index 9b4f93317c..3d8444e657 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/context_stack.h
@@ -24,26 +24,23 @@ enum context {
ct_def,
ct_preformatted,
ct_rawpreformatted,
- ct_menu,
ct_math,
- ct_footnote,
- ct_caption,
- ct_shortcaption,
+ ct_brace_command,
ct_inlineraw
};
/* Contexts where an empty line doesn't start a new paragraph. */
#define in_paragraph_context(c) \
!((c) == ct_math \
- || (c) == ct_menu \
|| (c) == ct_def \
|| (c) == ct_preformatted \
|| (c) == ct_rawpreformatted \
|| (c) == ct_inlineraw)
-void push_context (enum context c);
-enum context pop_context ();
+void push_context (enum context c, enum command_id cmd);
+enum context pop_context (void);
enum context current_context (void);
+enum command_id current_context_command (void);
void reset_context_stack (void);
@@ -53,4 +50,7 @@ ELEMENT *current_region (void);
enum command_id current_region_cmd (void);
void reset_region_stack (void);
+
+
+int in_preformatted_context_not_menu(void);
#endif
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/convert.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/convert.c
index b932855c27..697f5a2bfb 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/convert.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/convert.c
@@ -164,15 +164,6 @@ convert_to_texinfo_internal (ELEMENT *e, TEXT *result)
}
if (e->type == ET_bracketed)
ADD("}");
-
- // TODO: raw block command
- if (command_flags (e) & CF_block)
- {
- ADD("@end ");
- ADD(command_name(e->cmd));
- if (command_data(e->cmd).data != BLOCK_raw)
- ADD("\n");
- }
}
return;
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/def.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/def.c
index b2bddb205f..bea4544d14 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/def.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/def.c
@@ -75,7 +75,6 @@ next_bracketed_or_word (ELEMENT *current, int *i)
if (current->contents.list[*i]->type != ET_spaces
&& current->contents.list[*i]->type != ET_spaces_inserted
&& current->contents.list[*i]->type != ET_spaces_at_end
- && current->contents.list[*i]->type != ET_empty_spaces_after_command
&& current->contents.list[*i]->type != ET_delimiter)
break;
(*i)++;
@@ -98,7 +97,6 @@ next_bracketed_or_word_agg (ELEMENT *current, int *i)
if (e->type == ET_spaces
|| e->type == ET_spaces_inserted
|| e->type == ET_spaces_at_end
- || e->type == ET_empty_spaces_after_command
|| e->type == ET_delimiter)
{
if (num > 0)
@@ -180,8 +178,6 @@ split_delimiters (ELEMENT *current, int starting_idx)
if (e->type != ET_NONE
|| e->text.end == 0)
continue;
- if (e->type == ET_empty_spaces_after_command)
- continue;
p = e->text.text;
while (1)
@@ -274,11 +270,6 @@ parse_def (enum command_id command, ELEMENT *current)
ret = malloc (sizeof (DEF_INFO));
memset (ret, 0, sizeof (DEF_INFO));
- if (current->contents.number > 0
- && (current->contents.list[0]->type == ET_empty_spaces_after_command
- || current->contents.list[0]->type == ET_empty_line_after_command))
- contents_idx++;
-
split_def_args (current, contents_idx);
/* Check for "def alias" - for example @defun for @deffn. */
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.c
index d76fcb481a..99d8dab9c2 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.c
@@ -8,24 +8,19 @@ char *element_type_names[] = {
"definfoenclose_command",
"empty_line",
"raw",
-"last_raw_newline",
-"empty_line_after_command",
-"empty_spaces_after_command",
+"ignorable_spaces_after_command",
"spaces_at_end",
-"empty_space_at_end_def_bracketed",
-"space_at_end_block_command",
-"empty_spaces_before_argument",
-"empty_spaces_after_close_brace",
-"empty_spaces_before_paragraph",
-"preamble_text",
+"spaces_after_close_brace",
+"spaces_before_paragraph",
+"text_before_beginning",
"space_at_end_menu_node",
-"after_description_line",
+"after_menu_description_line",
"spaces",
"spaces_inserted",
-"text_root",
"document_root",
"root_line",
-"preamble",
+"before_node_section",
+"preamble_before_beginning",
"preamble_before_setfilename",
"paragraph",
"preformatted",
@@ -42,7 +37,10 @@ char *element_type_names[] = {
"menu_entry_node",
"menu_entry_description",
"menu_comment",
-"menu_star",
+"internal_menu_star",
+"internal_spaces_after_command",
+"internal_spaces_before_argument",
+"internal_spaces_before_brace_in_index",
"macro_name",
"macro_arg",
"before_item",
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.h
index 9a6fb59c9b..c18e6c5a6e 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.h
@@ -11,24 +11,19 @@ ET_space_command_arg,
ET_definfoenclose_command,
ET_empty_line,
ET_raw,
-ET_last_raw_newline,
-ET_empty_line_after_command,
-ET_empty_spaces_after_command,
+ET_ignorable_spaces_after_command,
ET_spaces_at_end,
-ET_empty_space_at_end_def_bracketed,
-ET_space_at_end_block_command,
-ET_empty_spaces_before_argument,
-ET_empty_spaces_after_close_brace,
-ET_empty_spaces_before_paragraph,
-ET_preamble_text,
+ET_spaces_after_close_brace,
+ET_spaces_before_paragraph,
+ET_text_before_beginning,
ET_space_at_end_menu_node,
-ET_after_description_line,
+ET_after_menu_description_line,
ET_spaces,
ET_spaces_inserted,
-ET_text_root,
ET_document_root,
ET_root_line,
-ET_preamble,
+ET_before_node_section,
+ET_preamble_before_beginning,
ET_preamble_before_setfilename,
ET_paragraph,
ET_preformatted,
@@ -45,7 +40,10 @@ ET_menu_entry_separator,
ET_menu_entry_node,
ET_menu_entry_description,
ET_menu_comment,
-ET_menu_star,
+ET_internal_menu_star,
+ET_internal_spaces_after_command,
+ET_internal_spaces_before_argument,
+ET_internal_spaces_before_brace_in_index,
ET_macro_name,
ET_macro_arg,
ET_before_item,
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.txt b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.txt
index 68764f6af1..ee7034193a 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.txt
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/element_types.txt
@@ -26,26 +26,21 @@ definfoenclose_command
# For text elements
empty_line
raw
-last_raw_newline
-empty_line_after_command
-empty_spaces_after_command
+ignorable_spaces_after_command
spaces_at_end
-empty_space_at_end_def_bracketed
-space_at_end_block_command
-empty_spaces_before_argument
-empty_spaces_after_close_brace
-empty_spaces_before_paragraph
-preamble_text
+spaces_after_close_brace
+spaces_before_paragraph
+text_before_beginning
space_at_end_menu_node
-after_description_line
+after_menu_description_line
spaces
spaces_inserted
# Other special types
-text_root
document_root
root_line
-preamble
+before_node_section
+preamble_before_beginning
preamble_before_setfilename
paragraph
preformatted
@@ -64,7 +59,10 @@ menu_entry_node
menu_entry_description
menu_comment
# Used internally
-menu_star
+internal_menu_star
+internal_spaces_after_command
+internal_spaces_before_argument
+internal_spaces_before_brace_in_index
macro_name
macro_arg
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/end_line.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/end_line.c
index 4556780052..87ca036edd 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/end_line.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/end_line.c
@@ -1,5 +1,5 @@
/* end_line.c -- what to do at the end of a whole line of input */
-/* Copyright 2010-2019 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -364,6 +364,8 @@ parse_line_command_args (ELEMENT *line_command)
user_defined_command_data[new_cmd].flags |= CF_ALIAS;
user_defined_command_data[new_cmd].data = existing_cmd;
+ user_defined_command_data[new_cmd].args_number
+ = command_data(existing_cmd).args_number;
/* Note the data field is an int, existing_cmd is
enum command_id, so would have problems if enum command_id
were wider than an int. */
@@ -415,7 +417,8 @@ parse_line_command_args (ELEMENT *line_command)
user_defined_command_data[new_cmd].flags
|= (CF_INFOENCLOSE | CF_brace);
- user_defined_command_data[new_cmd].data = BRACE_style;
+ user_defined_command_data[new_cmd].data = BRACE_style_other;
+ user_defined_command_data[new_cmd].args_number = 1;
ADD_ARG(new_command); free (new_command);
ADD_ARG(start); free (start);
@@ -721,6 +724,7 @@ parse_line_command_args (ELEMENT *line_command)
case CM_codequoteundirected:
case CM_codequotebacktick:
case CM_deftypefnnewline:
+ case CM_microtype:
{
if (!strcmp (line, "on") || !strcmp (line, "off"))
{
@@ -778,8 +782,8 @@ kdbinputstyle_invalid:
case CM_headings:
{
if (!strcmp (line, "off") || !strcmp (line, "on")
- || !strcmp (line, "double") || !strcmp (line, "singleafter")
- || !strcmp (line, "doubleafter"))
+ || !strcmp (line, "single") || !strcmp (line, "double")
+ || !strcmp (line, "singleafter") || !strcmp (line, "doubleafter"))
{
ADD_ARG(line);
}
@@ -802,13 +806,11 @@ kdbinputstyle_invalid:
}
/* NODE->contents is the Texinfo for the specification of a node. This
- function sets three fields on the returned object:
+ function sets two fields on the returned object:
manual_content - Texinfo tree for a manual name extracted from the
node specification.
node_content - Texinfo tree for the node name on its own
- normalized - a string with the node name after HTML node name
- normalization is applied
Objects returned from this function are used as an 'extra' key in a
few places: the elements of a 'nodes_manuals' array (itself an extra key),
@@ -1002,9 +1004,7 @@ parse_float_type (ELEMENT *current)
ELEMENT *
end_line_starting_block (ELEMENT *current)
{
- enum context c;
- c = pop_context ();
- if (c != ct_line)
+ if (pop_context () != ct_line)
fatal ("line context expected");
if (current->parent->cmd == CM_multitable)
@@ -1078,23 +1078,12 @@ end_line_starting_block (ELEMENT *current)
if (counter_value (&count_remaining_args, current) != -1)
counter_pop (&count_remaining_args);
- /* Don't consider empty argument of block @-command as argument,
- reparent them as contents. */
- if (current->args.list[0]->contents.number > 0
- && current->args.list[0]->contents.list[0]->type
- == ET_empty_line_after_command)
- {
- ELEMENT *e = remove_from_contents (current->args.list[0], 0);
- insert_into_contents (current, e, 0);
- destroy_element (pop_element_from_args (current));
- }
-
if (current->cmd == CM_float)
{
char *type = "";
KEY_PAIR *k;
EXTRA_FLOAT_TYPE *eft;
- current->line_nr = line_nr;
+ current->source_info = current_source_info;
if (current->args.number >= 2)
{
NODE_SPEC_EXTRA *float_label;
@@ -1134,13 +1123,15 @@ end_line_starting_block (ELEMENT *current)
if (current->args.number > 0
&& current->args.list[0]->contents.number > 0)
{
+ ELEMENT *g;
if (current->args.list[0]->contents.number > 1)
command_error (current, "superfluous argument to @%s",
command_name(current->cmd));
- ELEMENT *g = current->args.list[0]->contents.list[0];
+ g = current->args.list[0]->contents.list[0];
/* Check if @enumerate specification is either a single
letter or a string of digits. */
- if (g->text.end == 1 && isalpha (g->text.text[0])
+ if (g->text.end == 1
+ && isalpha ((unsigned char) g->text.text[0])
|| (g->text.end > 0
&& !*(g->text.text
+ strspn (g->text.text, "0123456789"))))
@@ -1165,7 +1156,7 @@ end_line_starting_block (ELEMENT *current)
{
ELEMENT *e = k->value;
if (!(command_flags(e) & CF_brace)
- || (command_data(e->cmd).data == 0))
+ || (command_data(e->cmd).data == BRACE_noarg))
{
command_error (current,
"command @%s not accepting argument in brace "
@@ -1244,10 +1235,21 @@ end_line_starting_block (ELEMENT *current)
|| current->args.list[0]->contents.number == 0))
{
ELEMENT *e;
+ ELEMENT *block_line_arg;
+ if (last_args_child(current)
+ && last_args_child(current)->type == ET_block_line_arg)
+ {
+ block_line_arg = last_args_child(current);
+ }
+ else
+ {
+ block_line_arg = new_element (ET_block_line_arg);
+ insert_into_args (current, block_line_arg, 0);
+ }
e = new_element (ET_command_as_argument_inserted);
e->cmd = CM_bullet;
- insert_into_args (current, e, 0);
+ insert_into_contents (block_line_arg, e, 0);
add_extra_element (current, "command_as_argument", e);
}
else if (item_line_command (current->cmd)
@@ -1268,7 +1270,7 @@ end_line_starting_block (ELEMENT *current)
}
} /* CF_blockitem */
- if (command_flags(current) & CF_menu)
+ if (command_data(current->cmd).data == BLOCK_menu)
{
/* Start reading a menu. Processing will continue in
handle_menu in menus.c. */
@@ -1277,9 +1279,16 @@ end_line_starting_block (ELEMENT *current)
add_to_element_contents (current, menu_comment);
current = menu_comment;
debug ("MENU_COMMENT OPEN");
- push_context (ct_preformatted);
}
- current = begin_preformatted (current);
+ if (command_data(current->cmd).data == BLOCK_format_raw
+ && format_expanded_p (command_name(current->cmd)))
+ {
+ ELEMENT *rawpreformatted = new_element (ET_rawpreformatted);
+ add_to_element_contents (current, rawpreformatted);
+ current = rawpreformatted;
+ }
+ if (command_data(current->cmd).data != BLOCK_raw)
+ current = begin_preformatted (current);
return current;
}
@@ -1291,10 +1300,9 @@ end_line_misc_line (ELEMENT *current)
{
enum command_id cmd;
int arg_type;
- enum context c;
ELEMENT *misc_cmd;
char *end_command = 0;
- enum command_id end_id;
+ enum command_id end_id = CM_NONE;
int included_file = 0;
isolate_last_space (current);
@@ -1307,14 +1315,12 @@ end_line_misc_line (ELEMENT *current)
arg_type = command_data(cmd).data;
- /* Check 'line' is top of the context stack */
- c = pop_context ();
- if (c != ct_line)
+ if (pop_context () != ct_line)
fatal ("line context expected");
debug ("MISC END %s", command_name(cmd));
- if (arg_type > 0)
+ if (arg_type == LINE_specific)
{
ELEMENT *args = parse_line_command_args (current);
if (args)
@@ -1381,31 +1387,18 @@ end_line_misc_line (ELEMENT *current)
free (end_command); end_command = 0;
}
}
- if (end_command)
- {
- add_extra_string (current, "command_argument",
- end_command);
- }
+ /* If there is superfluous text after @end argument, set
+ superfluous_arg such that the error message triggered by an
+ unexpected @-command on the @end line is issued below. Note
+ that superfluous_arg may also be true if it was set above. */
if (end_command
- && (superfluous_arg
- || line[strspn (line, whitespace_chars)] != '\0'))
- {
- char *line, *line2;
- line = convert_to_texinfo (current->args.list[0]);
-
- line2 = line;
- line2 += strspn (line2, whitespace_chars);
- free (read_command_name (&line2));
- command_error (current,
- "superfluous argument to @end %s: "
- "%s", end_command, line2);
- superfluous_arg = 0; /* Don't issue another error
- message below. */
- free (line);
- }
+ && line[strspn (line, whitespace_chars)] != '\0')
+ superfluous_arg = 1;
}
}
- else
+ /* if superfluous_arg is set there is a similar and somewhat
+ better error message below */
+ else if (!superfluous_arg)
{
command_error (current, "bad argument to @end: %s", line);
}
@@ -1417,10 +1410,12 @@ end_line_misc_line (ELEMENT *current)
else if (current->cmd == CM_include)
{
int status;
- char *fullpath;
+ char *fullpath, *sys_filename;
debug ("Include %s", text);
- fullpath = locate_include_file (text);
+ sys_filename = encode_file_name (text);
+ fullpath = locate_include_file (sys_filename);
+
if (!fullpath)
{
command_error (current,
@@ -1438,7 +1433,6 @@ end_line_misc_line (ELEMENT *current)
}
else
included_file = 1;
- free (fullpath);
}
}
else if (current->cmd == CM_verbatiminclude)
@@ -1498,6 +1492,8 @@ end_line_misc_line (ELEMENT *current)
static char *known_encodings[] = {
"shift_jis",
"latin1",
+ "latin-1",
+ "utf8",
0
};
for (i = 0; (known_encodings[i]); i++)
@@ -1516,11 +1512,16 @@ end_line_misc_line (ELEMENT *current)
struct encoding_map {
char *from; char *to;
};
+ /* The map mimics Encode::find_encoding()->name() result.
+ Even when the alias is not good, such as 'utf-8-strict'
+ for 'utf-8', use the same mapping for consistency with the
+ perl Parser */
static struct encoding_map map[] = {
"utf-8", "utf-8-strict",
"us-ascii", "ascii",
"shift_jis", "shiftjis",
- "latin1", "iso-8859-1"
+ "latin1", "iso-8859-1",
+ "latin-1", "iso-8859-1"
};
for (i = 0; i < sizeof map / sizeof *map; i++)
{
@@ -1539,7 +1540,7 @@ end_line_misc_line (ELEMENT *current)
{
command_warn (current, "unrecognized encoding name `%s'",
text);
- /* Texinfo::Encoding calls Encode::Alias, so knows
+ /* the Perl Parser calls Encode::find_encoding, so knows
about more encodings than what we know about here.
TODO: Check when perl_encoding could be defined when
texinfo_encoding isn't.
@@ -1548,7 +1549,8 @@ end_line_misc_line (ELEMENT *current)
}
- /* Set input_encoding from perl_encoding */
+ /* Set input_encoding from perl_encoding. In the perl parser,
+ lc(Encode::find_encoding()->mime_name()) is used */
input_encoding = 0;
if (perl_encoding)
{
@@ -1560,12 +1562,11 @@ end_line_misc_line (ELEMENT *current)
"utf-8-strict","utf-8",
"ascii", "us-ascii",
"shiftjis", "shift_jis",
- "latin-1", "iso-8859-1",
"iso-8859-1", "iso-8859-1",
"iso-8859-2", "iso-8859-2",
"iso-8859-15", "iso-8859-15",
- "koi8-r", "koi8",
- "koi8-u", "koi8",
+ "koi8-r", "koi8-r",
+ "koi8-u", "koi8-u",
};
input_encoding = perl_encoding;
for (i = 0; i < sizeof map / sizeof *map; i++)
@@ -1600,7 +1601,7 @@ end_line_misc_line (ELEMENT *current)
just check if the language code looks right. */
p = text;
- while (isalpha (*p))
+ while (isalpha ((unsigned char) *p))
p++;
if (*p && *p != '_')
{
@@ -1625,7 +1626,7 @@ end_line_misc_line (ELEMENT *current)
p = q;
/* Language code should be of the form LL_CC,
language code followed by country code. */
- while (isalpha (*p))
+ while (isalpha ((unsigned char) *p))
p++;
if (*p || p - q > 4)
{
@@ -1636,10 +1637,7 @@ end_line_misc_line (ELEMENT *current)
}
}
}
-
- free (global_documentlanguage);
- global_documentlanguage = strdup (text);
- /* FIXME: check customization variable */
+ set_documentlanguage (text);
}
}
if (superfluous_arg)
@@ -1648,16 +1646,15 @@ end_line_misc_line (ELEMENT *current)
p = convert_to_texinfo (args_child_by_index(current, 0));
texi_line = p;
- while (isspace (*texi_line))
+ while (isspace ((unsigned char) *texi_line))
texi_line++;
/* Trim leading and trailing whitespace. */
p1 = strchr (texi_line, '\0');
if (p1 > texi_line)
{
- while (p1 > texi_line && isspace (p1[-1]))
+ while (p1 > texi_line && isspace ((unsigned char) p1[-1]))
p1--;
- c = *p1;
*p1 = '\0';
}
command_error (current, "bad argument to @%s: %s",
@@ -1695,9 +1692,9 @@ end_line_misc_line (ELEMENT *current)
/* Copy the first 'node_content' array, to avoid the complication
of it being referenced in two different places.
This might be better with a separate function. */
+ int i;
label = new_element (0);
- int i;
for (i = 0; i<nodes_manuals[0]->node_content->contents.number;
i++)
@@ -1708,7 +1705,17 @@ end_line_misc_line (ELEMENT *current)
}
register_label (current, label);
}
-
+ if (current_part
+ && !lookup_extra (current_part, "part_associated_section"))
+ {
+ /* we only associate a part to the following node if the
+ part is not already associate to a sectioning command,
+ but the part can be associated to the sectioning command later
+ if a sectioning command follows the node. */
+ add_extra_element (current, "node_preceding_part", current_part);
+ add_extra_element (current_part, "part_following_node",
+ current);
+ }
current_node = current;
}
else if (current->cmd == CM_listoffloats)
@@ -1750,6 +1757,18 @@ end_line_misc_line (ELEMENT *current)
current->args.list[0]);
current->type = ET_index_entry_command;
}
+ /* if there is a brace command interrupting an index or subentry
+ command, replace the internal internal_spaces_before_brace_in_index
+ text type with its final type depending on whether there is
+ text after the brace command. */
+ if ((command_flags(current) & CF_index_entry_command
+ || current->cmd == CM_subentry))
+ {
+ if (lookup_extra (current, "sortas")
+ || lookup_extra (current, "seealso")
+ || lookup_extra (current, "seeentry"))
+ set_non_ignored_space_in_index_before_command(current->args.list[0]);
+ }
}
}
@@ -1768,6 +1787,17 @@ end_line_misc_line (ELEMENT *current)
if (command_data(end_id).data != BLOCK_conditional)
{
ELEMENT *closed_command;
+ /* here close some empty types. Typically empty preformatted
+ that would have been closed anyway in _close_commands, but
+ also other types (rawpreformatted, before_item), some which
+ may also have been closed anyway. */
+ if (!current->cmd && current->type != ET_NONE
+ && (current->contents.number == 0) && current->parent)
+ {
+ current = current->parent;
+ destroy_element (pop_element_from_contents (current));
+ debug ("popping at end command");
+ }
/* This closes tree elements (e.g. paragraphs) until we reach
end_command. It can print an error if another block command
is found first. */
@@ -1776,20 +1806,18 @@ end_line_misc_line (ELEMENT *current)
destroy_element_and_children (end_elt);
else
{
- add_extra_element (closed_command, "end_command", end_elt);
close_command_cleanup (closed_command);
add_to_element_contents (closed_command, end_elt);
- if (command_flags(closed_command) & CF_menu
- && current_context () == ct_menu)
+ if (command_data(closed_command->cmd).data == BLOCK_menu
+ && command_data(current_context_command()).data == BLOCK_menu)
{
ELEMENT *e;
debug ("CLOSE menu but still in menu context");
e = new_element (ET_menu_comment);
add_to_element_contents (current, e);
current = e;
- push_context (ct_preformatted);
}
}
if (close_preformatted_command (end_id))
@@ -1827,7 +1855,8 @@ end_line_misc_line (ELEMENT *current)
}
else
{
- pop_context (); /* ct_line */;
+ if (pop_context () != ct_line)
+ fatal ("line context expected");
current = current->parent;
@@ -1876,7 +1905,7 @@ end_line_misc_line (ELEMENT *current)
current);
if (current->cmd == CM_top)
{
- line_error_ext (1, &current_part->line_nr,
+ line_error_ext (1, &current_part->source_info,
"@part should not be associated with @top");
}
current_part = 0;
@@ -1934,8 +1963,6 @@ end_line (ELEMENT *current)
else
current = current->parent;
- pop_context (); //ct_preformatted
-
current = current->parent->parent;
e = new_element (ET_menu_comment);
add_to_element_contents (current, e);
@@ -1945,12 +1972,11 @@ end_line (ELEMENT *current)
add_to_element_contents (current, e);
current = e;
- e = new_element (ET_after_description_line);
+ e = new_element (ET_after_menu_description_line);
text_append (&e->text, empty_line->text.text);
destroy_element (empty_line);
add_to_element_contents (current, e);
- push_context (ct_preformatted);
debug ("MENU: END DESCRIPTION, OPEN COMMENT");
}
else if (in_paragraph_context (current_context ()))
@@ -2036,14 +2062,13 @@ end_line (ELEMENT *current)
current = last_contents_child(current);
else
{
+ ELEMENT *e;
/* This should not happen */
bug ("description or menu comment not in preformatted");
- ELEMENT *e;
e = new_element (ET_preformatted);
add_to_element_contents (current, e);
current = e;
}
- push_context (ct_preformatted);
}
else
{
@@ -2054,7 +2079,6 @@ end_line (ELEMENT *current)
e = new_element (ET_preformatted);
add_to_element_contents (current, e);
current = e;
- push_context (ct_preformatted);
debug ("THEN MENU_COMMENT OPEN");
}
{
@@ -2123,6 +2147,9 @@ end_line (ELEMENT *current)
free (stripped);
}
+ /* in case there are no arguments at all, it needs to be called here. */
+ abort_empty_line (&current, NULL);
+
def_info = parse_def (def_command, current);
/* Record the index entry if def_info is not empty. */
@@ -2166,8 +2193,9 @@ end_line (ELEMENT *current)
|| def_command == CM_deftypeivar
|| def_command == CM_deftypecv))
{
- add_extra_string_dup (current->parent, "documentlanguage",
- global_documentlanguage);
+ if (global_documentlanguage)
+ add_extra_string_dup (current->parent, "documentlanguage",
+ global_documentlanguage);
}
else
{
@@ -2197,55 +2225,10 @@ end_line (ELEMENT *current)
current = end_line_starting_block (current);
}
- /* after an "@end verbatim" */
- else if (current->contents.number
- && last_contents_child(current)->type == ET_empty_line_after_command
- && contents_child_by_index(current, -2)
- && contents_child_by_index(current, -2)->cmd == CM_verbatim)
- {
- /*
- if we are after a @end verbatim, we must restart a preformatted if needed,
- since there is no @end command explicitly associated to raw commands
- it won't be done elsewhere.
- */
-
- current = begin_preformatted (current);
- }
else if (current->type == ET_line_arg)
{
current = end_line_misc_line (current);
}
- else if (current->contents.number == 1
- && current->contents.list[0]->type == ET_empty_line_after_command
- || current->contents.number == 2
- && current->contents.list[0]->type == ET_empty_line_after_command
- && (current->contents.list[1]->cmd == CM_c
- || current->contents.list[1]->cmd == CM_comment))
- {
- if (current->type == ET_preformatted
- || current->type == ET_rawpreformatted)
- {
- /* Empty line after a @menu, or before a preformatted. Reparent
- to the menu or other format. */
- ELEMENT *parent, *to_reparent;
-
- parent = current->parent;
- if (parent->type == ET_menu_comment
- && parent->contents.number == 1)
- {
- parent = parent->parent;
- }
- to_reparent = pop_element_from_contents (parent);
- debug ("LINE AFTER COMMAND IN PREFORMATTED");
- while (current->contents.number > 0)
- {
- ELEMENT *e;
- e = remove_from_contents (current, 0);
- add_to_element_contents (parent, e);
- }
- add_to_element_contents (parent, to_reparent);
- }
- }
/* 'line' or 'def' at top of "context stack" - this happens when
line commands are nested (always incorrectly?) */
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.c
index 522bd3434d..fafaf9c9d4 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.c
@@ -1,4 +1,4 @@
-/* Copyright 2010-2021 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -28,6 +28,26 @@
#include "input.h"
#include "text.h"
+/* wrappers for asprintf and vasprintf */
+int
+xvasprintf (char **ptr, const char *template, va_list ap)
+{
+ int ret;
+ ret = vasprintf (ptr, template, ap);
+ if (ret < 0)
+ abort (); /* out of memory */
+ return ret;
+}
+
+int
+xasprintf (char **ptr, const char *template, ...)
+{
+ va_list v;
+ va_start (v, template);
+ return xvasprintf (ptr, template, v);
+}
+
+
void bug (char *message)
{
fprintf (stderr, "texi2any (XS parser): bug: %s\n", message);
@@ -40,25 +60,19 @@ void fatal (char *message)
}
-typedef struct {
- char *message;
- enum error_type type;
- LINE_NR line_nr;
-} ERROR_MESSAGE;
-
-static ERROR_MESSAGE *error_list = 0;
-static size_t error_number = 0;
+ERROR_MESSAGE *error_list = 0;
+size_t error_number = 0;
static size_t error_space = 0;
static void
-line_error_internal (enum error_type type, LINE_NR *cmd_line_nr,
+line_error_internal (enum error_type type, SOURCE_INFO *cmd_source_info,
char *format, va_list v)
{
char *message;
#ifdef ENABLE_NLS
- vasprintf (&message, gettext(format), v);
+ xvasprintf (&message, gettext(format), v);
#else
- vasprintf (&message, format, v);
+ xvasprintf (&message, format, v);
#endif
if (!message) fatal ("vasprintf failed");
@@ -70,25 +84,25 @@ line_error_internal (enum error_type type, LINE_NR *cmd_line_nr,
error_list[error_number].message = message;
error_list[error_number].type = type;
- if (cmd_line_nr)
+ if (cmd_source_info)
{
- if (cmd_line_nr->line_nr)
- error_list[error_number++].line_nr = *cmd_line_nr;
+ if (cmd_source_info->line_nr)
+ error_list[error_number++].source_info = *cmd_source_info;
else
- error_list[error_number++].line_nr = line_nr;
+ error_list[error_number++].source_info = current_source_info;
}
else
- error_list[error_number++].line_nr = line_nr;
+ error_list[error_number++].source_info = current_source_info;
}
void
-line_error_ext (enum error_type type, LINE_NR *cmd_line_nr,
+line_error_ext (enum error_type type, SOURCE_INFO *cmd_source_info,
char *format, ...)
{
va_list v;
va_start (v, format);
- line_error_internal (type, cmd_line_nr, format, v);
+ line_error_internal (type, cmd_source_info, format, v);
}
void
@@ -115,7 +129,7 @@ command_warn (ELEMENT *e, char *format, ...)
va_list v;
va_start (v, format);
- line_error_internal (warning, &e->line_nr, format, v);
+ line_error_internal (warning, &e->source_info, format, v);
}
void
@@ -124,7 +138,7 @@ command_error (ELEMENT *e, char *format, ...)
va_list v;
va_start (v, format);
- line_error_internal (error, &e->line_nr, format, v);
+ line_error_internal (error, &e->source_info, format, v);
}
void
@@ -142,12 +156,13 @@ bug_message_internal (char *format, va_list v)
fprintf (stderr, "You found a bug: ");
vfprintf (stderr, format, v);
fprintf (stderr, "\n");
- if (line_nr.file_name)
+ if (current_source_info.file_name)
{
fprintf (stderr,
- "last location %s:%d", line_nr.file_name, line_nr.line_nr);
- if (line_nr.macro)
- fprintf (stderr, " (possibly involving @%s)", line_nr.macro);
+ "last location %s:%d", current_source_info.file_name,
+ current_source_info.line_nr);
+ if (current_source_info.macro)
+ fprintf (stderr, " (possibly involving @%s)", current_source_info.macro);
fprintf (stderr, "\n");
}
exit (1);
@@ -161,94 +176,3 @@ bug_message (char *format, ...)
va_start (v, format);
bug_message_internal (format, v);
}
-
-static int indent = 0;
-
-/* Output INDENT spaces. */
-static void
-dump_indent (TEXT *text)
-{
- int i;
-
- for (i = 0; i < indent; i++)
- text_append_n (text, " ", 1);
-}
-
-/* Ouput S escaping single quotes and backslashes, so that
- Perl can read it in when it is surrounded by single quotes. */
-void
-dump_string (char *s, TEXT *text)
-{
- while (*s)
- {
- if (*s == '\''
- || *s == '\\')
- text_append_n (text, "\\", 1);
- text_append_n (text, s++, 1);
- }
-}
-
-static void
-dump_line_nr (LINE_NR *line_nr, TEXT *text)
-{
- text_append_n (text, "{\n", 2);
- indent += 2;
-
- dump_indent (text);
- text_printf (text, "'file_name' => '%s',\n",
- line_nr->file_name ?
- line_nr->file_name : "");
-
- if (line_nr->line_nr)
- {
- dump_indent (text);
- text_append (text, "'line_nr' => ");
- text_printf (text, "%d", line_nr->line_nr);
- text_append (text, ",\n");
- }
-
- /* TODO: macro. */
- if (line_nr->macro)
- {
- dump_indent (text);
- text_append (text, "'macro' => ");
- text_printf (text, "'%s'", line_nr->macro);
- text_append (text, ",\n");
- }
- else
- {
- dump_indent (text);
- text_append (text, "'macro' => ''\n");
- }
-
-
- indent -= 2;
- dump_indent (text);
- text_append_n (text, "},\n", 3);
-}
-
-char *
-dump_errors (void)
-{
- int i;
- static TEXT t;
-
- text_reset (&t);
- text_append (&t, "$ERRORS = [\n");
- for (i = 0; i < error_number; i++)
- {
- text_append (&t, "{ 'message' =>\n'");
- dump_string (error_list[i].message, &t);
- text_append (&t, "',\n");
- text_printf (&t, "'type' => '%s',", error_list[i].type == error ? "error"
- : "warning");
- text_append (&t, "'line_nr' => ");
- dump_line_nr (&error_list[i].line_nr, &t);
- text_append (&t, "},\n");
- }
- text_append (&t, "];\n");
-
- return t.text;
-}
-
-
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.h
index 733d1372a5..b3f8ad4f35 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/errors.h
@@ -3,6 +3,10 @@
#define ERRORS_H
#include "tree_types.h"
+#include <stdarg.h>
+
+int xasprintf (char **ptr, const char *template, ...);
+int xvasprintf (char **ptr, const char *template, va_list ap);
void fatal (char *);
void bug (char *);
@@ -14,9 +18,17 @@ void line_warn (char *format, ...);
void command_error (ELEMENT *e, char *format, ...);
void command_warn (ELEMENT *e, char *format, ...);
void wipe_errors (void);
-void line_error_ext (enum error_type type, LINE_NR *cmd_line_nr,
+void line_error_ext (enum error_type type, SOURCE_INFO *cmd_source_info,
char *format, ...);
void bug_message (char *format, ...);
-char *dump_errors (void);
+typedef struct {
+ char *message;
+ enum error_type type;
+ SOURCE_INFO source_info;
+} ERROR_MESSAGE;
+
+extern ERROR_MESSAGE *error_list;
+extern size_t error_number;
+
#endif
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/handle_commands.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/handle_commands.c
index fa3ce138f3..94c95eb69f 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/handle_commands.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/handle_commands.c
@@ -55,8 +55,7 @@ check_no_text (ELEMENT *current)
after_paragraph = 1;
break;
}
- else if (t == ET_preformatted
- || t == ET_rawpreformatted)
+ else if (t == ET_preformatted)
{
for (j = 0; j < f->contents.number; j++)
{
@@ -78,7 +77,7 @@ check_no_text (ELEMENT *current)
return after_paragraph;
}
-/* noarg skipspace */
+/* symbol skipspace other */
ELEMENT *
handle_other_command (ELEMENT *current, char **line_inout,
enum command_id cmd, int *status)
@@ -90,20 +89,36 @@ handle_other_command (ELEMENT *current, char **line_inout,
*status = STILL_MORE_TO_PROCESS;
arg_spec = command_data(cmd).data;
- if (arg_spec == OTHER_noarg)
+ if (arg_spec != NOBRACE_skipspace)
{
- if (command_data(cmd).flags & CF_in_heading)
+ misc = new_element (ET_NONE);
+ misc->cmd = cmd;
+ add_to_element_contents (current, misc);
+ if (command_data(cmd).flags & CF_in_heading_spec
+ && !(command_data(current_context_command()).flags & CF_heading_spec))
{
line_error ("@%s should only appear in heading or footing",
command_name(cmd));
}
- misc = new_element (ET_NONE);
- misc->cmd = cmd;
- add_to_element_contents (current, misc);
- register_global_command (misc);
- if (close_preformatted_command(cmd))
- current = begin_preformatted (current);
+ if (arg_spec == NOBRACE_symbol)
+ {
+ if (cmd == CM_BACKSLASH && current_context () != ct_math)
+ {
+ line_warn ("@\\ should only appear in math context");
+ }
+ if (cmd == CM_NEWLINE)
+ {
+ current = end_line (current);
+ *status = GET_A_NEW_LINE;
+ }
+ }
+ else /* NOBRACE_other */
+ {
+ register_global_command (misc);
+ if (close_preformatted_command(cmd))
+ current = begin_preformatted (current);
+ }
}
else
{
@@ -148,88 +163,78 @@ handle_other_command (ELEMENT *current, char **line_inout,
/* In a @multitable */
else if ((parent = item_multitable_parent (current)))
{
- if (cmd != CM_item && cmd != CM_headitem
- && cmd != CM_tab)
- {
- line_error ("@%s not meaningful inside @%s block",
- command_name(cmd),
- command_name(parent->cmd));
- }
+ int max_columns = 0;
+ KEY_PAIR *prototypes;
+
+ prototypes = lookup_extra (parent, "prototypes");
+ if (prototypes)
+ max_columns = prototypes->value->contents.number;
else
{
- int max_columns = 0;
- KEY_PAIR *prototypes;
-
- prototypes = lookup_extra (parent, "prototypes");
+ prototypes = lookup_extra(parent, "columnfractions");
if (prototypes)
- max_columns = prototypes->value->contents.number;
- else
{
- prototypes = lookup_extra(parent, "columnfractions");
+ prototypes = lookup_extra((ELEMENT *) prototypes->value,
+ "misc_args");
if (prototypes)
- {
- prototypes = lookup_extra((ELEMENT *) prototypes->value,
- "misc_args");
- if (prototypes)
- max_columns = prototypes->value->contents.number;
- }
+ max_columns = prototypes->value->contents.number;
}
+ }
- if (max_columns == 0)
- {
- line_warn ("@%s in empty multitable",
- command_name(cmd));
- }
- else if (cmd == CM_tab)
+ if (max_columns == 0)
+ {
+ line_warn ("@%s in empty multitable",
+ command_name(cmd));
+ }
+ else if (cmd == CM_tab)
+ {
+ ELEMENT *row;
+ row = last_contents_child (parent);
+ if (row->type == ET_before_item)
+ line_error ("@tab before @item");
+ else if (counter_value (&count_cells, row)
+ >= max_columns)
{
- ELEMENT *row;
- row = last_contents_child (parent);
- if (row->type == ET_before_item)
- line_error ("@tab before @item");
- else if (counter_value (&count_cells, row)
- >= max_columns)
- {
- line_error ("too many columns in multitable item"
- " (max %d)", max_columns);
- }
- else
- {
- counter_inc (&count_cells);
- misc = new_element (ET_NONE);
- misc->cmd = cmd;
- add_to_element_contents (row, misc);
- current = misc;
- debug ("TAB");
-
- add_extra_integer (current, "cell_number",
- counter_value (&count_cells, row));
- }
+ line_error ("too many columns in multitable item"
+ " (max %d)", max_columns);
}
- else /* @item or @headitem */
+ else
{
- ELEMENT *row;
-
- debug ("ROW");
- row = new_element (ET_row);
- add_to_element_contents (parent, row);
-
- /* Note that the "row_number" extra value,
- isn't actually used anywhere at present. */
- add_extra_integer (row, "row_number",
- parent->contents.number - 1);
-
+ counter_inc (&count_cells);
misc = new_element (ET_NONE);
misc->cmd = cmd;
add_to_element_contents (row, misc);
current = misc;
+ debug ("TAB");
- if (counter_value (&count_cells, parent) != -1)
- counter_pop (&count_cells);
- counter_push (&count_cells, row, 1);
add_extra_integer (current, "cell_number",
counter_value (&count_cells, row));
}
}
+ else /* @item or @headitem */
+ {
+ ELEMENT *row;
+
+ debug ("ROW");
+ row = new_element (ET_row);
+ add_to_element_contents (parent, row);
+
+ /* Note that the "row_number" extra value,
+ isn't actually used anywhere at present. */
+ add_extra_integer (row, "row_number",
+ parent->contents.number - 1);
+
+ misc = new_element (ET_NONE);
+ misc->cmd = cmd;
+ add_to_element_contents (row, misc);
+ current = misc;
+
+ if (counter_value (&count_cells, parent) != -1)
+ counter_pop (&count_cells);
+ counter_push (&count_cells, row, 1);
+ add_extra_integer (current, "cell_number",
+ counter_value (&count_cells, row));
+ }
current = begin_preformatted (current);
} /* In @multitable */
else if (cmd == CM_tab)
@@ -244,61 +249,18 @@ handle_other_command (ELEMENT *current, char **line_inout,
current = begin_preformatted (current);
}
if (misc)
- misc->line_nr = line_nr;
+ misc->source_info = current_source_info;
}
else
{
misc = new_element (ET_NONE);
misc->cmd = cmd;
- misc->line_nr = line_nr;
+ misc->source_info = current_source_info;
add_to_element_contents (current, misc);
}
- start_empty_line_after_command (current, &line, misc);
- if (cmd == CM_indent || cmd == CM_noindent)
- {
- /* Start a new paragraph if not in one already. */
- int spaces;
- ELEMENT *paragraph;
-
- /* Check if if we should change an ET_empty_line_after_command
- element to ET_empty_spaces_after_command by looking ahead
- to see what comes next. */
- if (!strchr (line, '\n'))
- {
- char *line2;
- input_push_text (strdup (line), 0);
- line2 = new_line ();
- if (line2)
- line = line2;
- }
- spaces = strspn (line, whitespace_chars);
- if (spaces > 0)
- {
- char saved = line[spaces];
- line[spaces] = '\0';
- current = merge_text (current, line);
- line[spaces] = saved;
- line += spaces;
- }
- if (*line
- && last_contents_child(current)->type
- == ET_empty_line_after_command)
- {
- last_contents_child(current)->type
- = ET_empty_spaces_after_command;
- }
- paragraph = begin_paragraph (current);
- if (paragraph)
- current = paragraph;
- if (!*line)
- {
- *status = GET_A_NEW_LINE;
- goto funexit;
- }
- }
+ start_empty_line_after_command (current, &line, 0);
}
-funexit:
*line_inout = line;
return current;
}
@@ -320,17 +282,10 @@ handle_line_command (ELEMENT *current, char **line_inout,
{
ELEMENT *closed_elt; /* Not used */
current = close_commands (current, 0, &closed_elt, cmd);
- if (current->type == ET_text_root)
- {
- if (cmd != CM_bye)
- {
- /* Use document_root when we have nodes or sections. */
- ELEMENT *new_root = new_element (ET_document_root);
- add_to_element_contents (new_root, current);
- current = new_root;
- }
- }
- else
+ /* if parse_texi_line is called on a line with a node/section then
+ it will directly be in the root_line, otherwise it is not directly
+ in the root, but in another container */
+ if (current->type != ET_root_line)
{
current = current->parent;
if (!current)
@@ -339,14 +294,14 @@ handle_line_command (ELEMENT *current, char **line_inout,
}
/* Look up information about this command ( skipline text
- line lineraw (a number) ). */
+ line lineraw specific ). */
arg_spec = command_data(cmd).data;
/* All the cases using the raw line.
TODO: I don't understand what the difference is between these.
LINE_skipline is used where the command takes no argument at all. */
if (arg_spec == LINE_skipline || arg_spec == LINE_lineraw
- || arg_spec == LINE_special)
+ || arg_spec == LINE_special)
{
ELEMENT *args = 0;
enum command_id equivalent_cmd = 0;
@@ -375,16 +330,16 @@ handle_line_command (ELEMENT *current, char **line_inout,
if (!strchr (line, '\n'))
{
char *line2;
- LINE_NR save_ln;
+ SOURCE_INFO save_src_info;
input_push_text (strdup (line), 0);
- save_ln = line_nr;
+ save_src_info = current_source_info;
line2 = new_line ();
if (line2)
{
line = line2;
- line_nr = save_ln;
+ current_source_info = save_src_info;
}
}
@@ -443,22 +398,19 @@ handle_line_command (ELEMENT *current, char **line_inout,
destroy_element_and_children (misc);
misc = new_element (ET_NONE);
misc->cmd = equivalent_cmd;
- misc->line_nr = line_nr;
+ misc->source_info = current_source_info;
line_args = new_element (ET_line_arg);
add_to_element_args (misc, line_args);
add_extra_misc_args (misc, "misc_args", args);
-
add_extra_string_dup (misc, "spaces_before_argument", " ");
+ add_extra_string_dup (line_args, "spaces_after_argument", "\n");
+
e = new_element (ET_NONE);
text_append (&e->text, arg);
add_to_element_contents (line_args, e);
- e = new_element (ET_spaces_at_end);
- text_append_n (&e->text, "\n", 1);
- add_to_element_contents (line_args, e);
-
add_to_element_contents (current, misc);
}
else
@@ -498,10 +450,6 @@ handle_line_command (ELEMENT *current, char **line_inout,
{
global_info.sections_level--;
}
- else if (cmd == CM_novalidate)
- {
- global_info.novalidate = 1;
- }
if (misc)
register_global_command (misc);
@@ -544,7 +492,7 @@ handle_line_command (ELEMENT *current, char **line_inout,
}
misc = new_element (ET_NONE);
misc->cmd = (cmd == CM_item_LINE) ? CM_item : CM_itemx;
- misc->line_nr = line_nr;
+ misc->source_info = current_source_info;
add_to_element_contents (current, misc);
}
else
@@ -552,7 +500,7 @@ handle_line_command (ELEMENT *current, char **line_inout,
/* Add to contents */
misc = new_element (ET_NONE);
misc->cmd = cmd;
- misc->line_nr = line_nr;
+ misc->source_info = current_source_info;
if (cmd == CM_subentry)
{
@@ -588,7 +536,7 @@ handle_line_command (ELEMENT *current, char **line_inout,
add_to_element_contents (current, misc);
- if (command_data(cmd).flags & CF_sectioning)
+ if (command_data(cmd).flags & CF_sectioning_heading)
{
if (global_info.sections_level)
{
@@ -604,6 +552,7 @@ handle_line_command (ELEMENT *current, char **line_inout,
char *base_name;
int base_len;
int after_paragraph;
+ char *val;
/* Find the command with "x" stripped from the end, e.g.
deffnx -> deffn. */
@@ -621,8 +570,14 @@ handle_line_command (ELEMENT *current, char **line_inout,
add_extra_string (misc, "def_command", base_name);
after_paragraph = check_no_text (current);
- push_context (ct_def);
+ push_context (ct_def, cmd);
misc->type = ET_def_line;
+
+ /* Check txidefnamenospace flag */
+ val = fetch_value ("txidefnamenospace");
+ if (val)
+ add_extra_integer (misc, "omit_def_name_space", 1);
+
if (current->cmd == base_command)
{
ELEMENT *e = pop_element_from_contents (current);
@@ -647,15 +602,17 @@ handle_line_command (ELEMENT *current, char **line_inout,
arg = new_element (ET_line_arg);
add_to_element_args (current, arg);
- if (cmd == CM_node)
+ /* LINE_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 (command_data (current->cmd).data != LINE_specific
+ && command_data (current->cmd).args_number > 1)
{
- /* At most three comma-separated arguments to @node. This
- is the only (non-block) line command taking comma-separated
- arguments. Its arguments will be gathered the same as
- those of some block line commands and brace commands. */
- counter_push (&count_remaining_args, current, 3);
+ counter_push (&count_remaining_args,
+ current,
+ command_data (current->cmd).args_number - 1);
}
- else if (cmd == CM_author)
+ if (cmd == CM_author)
{
ELEMENT *parent = current;
int found = 0;
@@ -700,7 +657,7 @@ handle_line_command (ELEMENT *current, char **line_inout,
/* add 'line' to context_stack. This will be the
case while we read the argument on this line. */
if (!(command_data(cmd).flags & CF_def))
- push_context (ct_line);
+ push_context (ct_line, cmd);
start_empty_line_after_command (current, &line, misc);
}
@@ -726,6 +683,7 @@ static struct expanded_format expanded_formats[] = {
"tex", 0,
"xml", 0,
"info", 1,
+ "latex", 0,
};
void
@@ -811,16 +769,19 @@ handle_block_command (ELEMENT *current, char **line_inout,
{
p += strspn (p, whitespace_chars);
/* Check for a comment at the end of the line. */
- if (memcmp (p, "@c", 2) == 0)
+ if (*p)
{
- p += 2;
- if (memcmp (p, "omment", 6) == 0)
- p += 7;
- if (*p && *p != '@' && !strchr (whitespace_chars, *p))
- goto bad_value; /* @c or @comment not terminated. */
+ if (memcmp (p, "@c", 2) == 0)
+ {
+ p += 2;
+ if (memcmp (p, "omment", 6) == 0)
+ p += 7;
+ if (*p && *p != '@' && !strchr (whitespace_chars, *p))
+ goto bad_value; /* @c or @comment not terminated. */
+ }
+ else
+ goto bad_value; /* Trailing characters on line. */
}
- else if (*p)
- goto bad_value; /* Trailing characters on line. */
}
if (1)
{
@@ -897,7 +858,8 @@ handle_block_command (ELEMENT *current, char **line_inout,
else
{
ELEMENT *block = 0;
- if (flags & CF_menu
+ ELEMENT *bla; /* block line arg element */
+ if (command_data(cmd).data == BLOCK_menu
&& (current->type == ET_menu_comment
|| current->type == ET_menu_entry_description))
{
@@ -906,8 +868,6 @@ handle_block_command (ELEMENT *current, char **line_inout,
if (current->contents.number == 0)
destroy_element (pop_element_from_contents (menu));
- if (pop_context () != ct_preformatted)
- fatal ("preformatted context expected");
if (menu->type == ET_menu_entry)
menu = menu->parent;
current = menu;
@@ -916,19 +876,24 @@ handle_block_command (ELEMENT *current, char **line_inout,
if (flags & CF_def)
{
ELEMENT *def_line;
- push_context (ct_def);
+ push_context (ct_def, cmd);
block = new_element (ET_NONE);
block->cmd = cmd;
- block->line_nr = line_nr;
+ block->source_info = current_source_info;
add_to_element_contents (current, block);
current = block;
+
def_line = new_element (ET_def_line);
- def_line->line_nr = line_nr;
+ def_line->source_info = current_source_info;
add_to_element_contents (current, def_line);
current = def_line;
add_extra_string_dup (current, "def_command", command_name(cmd));
add_extra_string_dup (current, "original_def_cmdname",
command_name(cmd));
+ /* Check txidefnamenospace flag */
+ char *val = fetch_value ("txidefnamenospace");
+ if (val)
+ add_extra_integer (current, "omit_def_name_space", 1);
}
else
{
@@ -940,115 +905,73 @@ handle_block_command (ELEMENT *current, char **line_inout,
}
/* Check if 'block args command' */
- if (command_data(cmd).data != BLOCK_raw)
+ if (command_data(cmd).flags & CF_preformatted)
+ push_context (ct_preformatted, cmd);
+ else if (cmd == CM_displaymath)
+ push_context (ct_math, cmd);
+ else if (command_data(cmd).data == BLOCK_format_raw)
{
- if (command_data(cmd).flags & CF_preformatted)
- push_context (ct_preformatted);
- else if (cmd == CM_displaymath)
- push_context (ct_math);
- else if (command_data(cmd).flags & CF_format_raw)
+ push_context (ct_rawpreformatted, cmd);
+ }
+ else if (command_data(cmd).data == BLOCK_region)
+ {
+ if (current_region_cmd ())
{
- push_context (ct_rawpreformatted);
- if (!format_expanded_p (command_name(cmd)))
- {
- ELEMENT *e;
- enum command_id dummy;
- char *line_dummy;
+ line_error ("region %s inside region %s is not allowed",
+ command_name(cmd),
+ command_name(current_region_cmd ()));
+ }
+ push_region (block);
+ }
- e = new_element (ET_elided_block);
- add_to_element_contents (current, e);
- line_dummy = line;
- while (!is_end_current_command (current,
- &line_dummy, &dummy))
- {
- line = new_line ();
- if (!line)
- {
- line = "";
- break;
- }
- line_dummy = line;
- }
- e = new_element (ET_empty_line_after_command);
- text_append_n (&e->text, "\n", 1);
- add_to_element_contents (current, e);
+ if (command_data(cmd).data == BLOCK_menu)
+ {
+ push_context (ct_preformatted, cmd);
- e = new_element (ET_empty_line);
- text_append (&e->text, "");
- add_to_element_contents (current, e);
- goto funexit;
- }
- }
- else if (command_data(cmd).data == BLOCK_region)
+ if (cmd == CM_direntry)
+ add_to_contents_as_array (&global_info.dircategory_direntry,
+ block);
+
+ if (current_node)
{
- if (current_region_cmd ())
+ if (cmd == CM_direntry && conf.show_menu)
{
- line_error ("region %s inside region %s is not allowed",
- command_name(cmd),
- command_name(current_region_cmd ()));
+ line_warn ("@direntry after first node");
}
- push_region (block);
- }
-
- if (command_data(cmd).flags & CF_menu)
- {
- if (current_context () == ct_preformatted)
- push_context (ct_preformatted);
- else
- push_context (ct_menu);
-
- if (cmd == CM_direntry)
- add_to_contents_as_array (&global_info.dircategory_direntry,
- block);
-
- if (current_node)
+ else if (cmd == CM_menu)
{
- if (cmd == CM_direntry && conf.show_menu)
- {
- line_warn ("@direntry after first node");
- }
- else if (cmd == CM_menu)
- {
- if (!(command_flags(current->parent) & CF_root))
- line_warn ("@menu in invalid context");
- /* Add to array of menus for current node. Currently
- done in Perl code. */
- }
+ if (!(command_flags(current->parent) & CF_root))
+ line_warn ("@menu in invalid context");
+ /* Add to array of menus for current node. Currently
+ done in Perl code. */
}
}
+ }
+
+ if (cmd == CM_itemize || cmd == CM_enumerate)
+ counter_push (&count_items, current, 0);
- if (cmd == CM_itemize || cmd == CM_enumerate)
- counter_push (&count_items, current, 0);
- /* Note that no equivalent thing is done in the Perl code, because
- 'item_count' is assumed to start at 0. */
-
- {
- ELEMENT *bla = new_element (ET_block_line_arg);
- add_to_element_args (current, bla);
-
- if (command_data (current->cmd).data > 1)
- {
- counter_push (&count_remaining_args,
- current,
- command_data (current->cmd).data - 1);
- }
- else if (command_data (current->cmd).data == BLOCK_variadic)
- {
- /* Unlimited args */
- counter_push (&count_remaining_args, current,
- COUNTER_VARIADIC);
- }
-
- current = bla;
- if (!(command_data(cmd).flags & CF_def))
- push_context (ct_line);
-
- /* Note that an ET_empty_line_after_command gets reparented in the
- contents in 'end_line'. */
-
- }
+ bla = new_element (ET_block_line_arg);
+ add_to_element_args (current, bla);
+
+ if (command_data (current->cmd).args_number > 1)
+ {
+ counter_push (&count_remaining_args,
+ current,
+ command_data (current->cmd).args_number - 1);
+ }
+ else if (command_data (current->cmd).flags & CF_variadic)
+ {
+ /* Unlimited args */
+ counter_push (&count_remaining_args, current,
+ COUNTER_VARIADIC);
}
- block->line_nr = line_nr;
+
+ current = bla;
+ if (!(command_data(cmd).flags & CF_def))
+ push_context (ct_line, cmd);
+
+ block->source_info = current_source_info;
register_global_command (block);
start_empty_line_after_command (current, &line, block);
}
@@ -1070,7 +993,7 @@ handle_brace_command (ELEMENT *current, char **line_inout, enum command_id cmd)
/* The line number information is only ever used for brace commands
if the command is given with braces, but it's easier just to always
store the information. */
- e->line_nr = line_nr;
+ e->source_info = current_source_info;
add_to_element_contents (current, e);
@@ -1092,28 +1015,10 @@ handle_brace_command (ELEMENT *current, char **line_inout, enum command_id cmd)
}
else if (cmd == CM_kbd)
{
- if (current_context () == ct_preformatted
- && global_kbdinputstyle != kbd_distinct
- || global_kbdinputstyle == kbd_code)
+ if (kbd_formatted_as_code(current))
{
add_extra_integer (e, "code", 1);
}
- else if (global_kbdinputstyle == kbd_example)
- {
- /* TODO: Understand what is going on here. */
- ELEMENT *tmp = current->parent;
- while (tmp->parent
- && (command_flags(tmp->parent) & CF_brace)
- && command_data(tmp->parent->cmd).data != BRACE_context)
- {
- if (command_flags(tmp->parent) & CF_code_style)
- {
- add_extra_integer (e, "code", 1);
- break;
- }
- tmp = tmp->parent->parent;
- }
- }
}
else if (command_data(cmd).flags & CF_INFOENCLOSE)
{
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.c
index f1dbc521f5..537bb833b8 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.c
@@ -1,4 +1,4 @@
-/* Copyright 2010-2019 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -121,7 +121,7 @@ add_index (char *name, int in_code)
idx = add_index_internal (name, in_code);
/* For example, "rq" -> "rqindex". */
- asprintf (&cmdname, "%s%s", name, "index");
+ xasprintf (&cmdname, "%s%s", name, "index");
add_index_command (cmdname, idx);
free (cmdname);
}
@@ -296,6 +296,7 @@ enter_index_entry (enum command_id index_type_command,
entry->content = content;
entry->command = current;
entry->number = idx->index_number;
+ entry->ignored_chars = global_info.ignored_chars;
k = lookup_extra (current, "sortas");
if (k)
@@ -324,6 +325,40 @@ enter_index_entry (enum command_id index_type_command,
line_warn ("entry for index `%s' outside of any node", idx->name);
}
+/* turn spaces that are ignored before @-commands like @sortas{} and
+ @seeentry{} back to regular spaces if there is content after the @-command
+ */
+void
+set_non_ignored_space_in_index_before_command (ELEMENT *content)
+{
+ ELEMENT *e;
+ ELEMENT *pending_spaces_element = 0;
+ int i;
+ for (i = 0; i < content->contents.number; i++)
+ {
+ /* could also be, but it does not seems to be needed here:
+ e = contents_child_by_index (content, i); */
+ e = content->contents.list[i];
+ if (e->type == ET_internal_spaces_before_brace_in_index)
+ {
+ pending_spaces_element = e;
+ /* set to "spaces_at_end" in case there are only spaces after */
+ e->type = ET_spaces_at_end;
+ }
+ else if (pending_spaces_element
+ && ! (e->cmd == CM_sortas
+ || e->cmd == CM_seeentry
+ || e->cmd == CM_seealso
+ || e->type == ET_spaces_after_close_brace)
+ && (! check_space_element(e)))
+ {
+ pending_spaces_element->type = ET_NONE;
+ pending_spaces_element = 0;
+ }
+ }
+}
+
+
INDEX *
ultimate_index (INDEX *index)
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.h
index 043042d3e2..dc17890f39 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/indices.h
@@ -16,4 +16,5 @@ void enter_index_entry (enum command_id index_type_command,
ELEMENT *content);
INDEX *ultimate_index (INDEX *index);
void wipe_indices (void);
+void set_non_ignored_space_in_index_before_command (ELEMENT *content);
#endif
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.c
index f97edbfd4e..c8730b4d6a 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.c
@@ -1,4 +1,4 @@
-/* Copyright 2010-2020 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -13,8 +13,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#define _GNU_SOURCE
-
#include <config.h>
#include <stdlib.h>
@@ -45,18 +43,30 @@ typedef struct {
enum input_type type;
FILE *file;
- LINE_NR line_nr;
+ SOURCE_INFO source_info;
char *text; /* Input text to be parsed as Texinfo. */
char *ptext; /* How far we are through 'text'. Used to split 'text'
into lines. */
} INPUT;
+static char *input_pushback_string;
+
enum character_encoding input_encoding;
+static char *input_encoding_name;
+static iconv_t reverse_iconv; /* used in encode_file_name */
+
void
set_input_encoding (char *encoding)
{
+ free (input_encoding_name); input_encoding_name = strdup (encoding);
+ if (reverse_iconv)
+ {
+ iconv_close (reverse_iconv);
+ reverse_iconv = (iconv_t) 0;
+ }
+
if (!strcasecmp (encoding, "utf-8"))
input_encoding = ce_utf8;
else if (!strcmp (encoding, "iso-8859-1")
@@ -82,20 +92,7 @@ int input_number = 0;
int input_space = 0;
/* Current filename and line number. Used for reporting. */
-LINE_NR line_nr;
-
-/* Change the line number of filename of the top input source. Used to
- record a #line directive. If FILENAME is non-null, it should hbae
- been returned from save_string. */
-void
-save_line_directive (int line_nr, char *filename)
-{
- INPUT *top = &input_stack[input_number - 1];
- if (line_nr)
- top->line_nr.line_nr = line_nr;
- if (filename)
- top->line_nr.file_name = filename;
-}
+SOURCE_INFO current_source_info;
/* Collect text from the input sources until a newline is found. This is used
instead of next_text when we need to be sure we get an entire line of
@@ -164,16 +161,61 @@ text_buffer_iconv (TEXT *buf, iconv_t iconv_state,
}
+static char *
+encode_with_iconv (iconv_t our_iconv, char *s)
+{
+ static TEXT t;
+ ICONV_CONST char *inptr; size_t bytes_left;
+ size_t iconv_ret;
+
+ t.end = 0;
+ inptr = s;
+ bytes_left = strlen (s);
+ text_alloc (&t, 10);
+
+ while (1)
+ {
+ iconv_ret = text_buffer_iconv (&t, our_iconv,
+ &inptr, &bytes_left);
+
+ /* Make sure libiconv flushes out the last converted character.
+ This is required when the conversion is stateful, in which
+ case libiconv might not output the last character, waiting to
+ see whether it should be combined with the next one. */
+ if (iconv_ret != (size_t) -1
+ && text_buffer_iconv (&t, our_iconv, 0, 0) != (size_t) -1)
+ /* Success: all of input converted. */
+ break;
+
+ if (bytes_left == 0)
+ break;
+
+ switch (errno)
+ {
+ case E2BIG:
+ text_alloc (&t, t.space + 20);
+ break;
+ case EILSEQ:
+ default:
+ fprintf(stderr, "%s:%d: encoding error at byte 0x%2x\n",
+ current_source_info.file_name, current_source_info.line_nr,
+ *(unsigned char *)inptr);
+ inptr++; bytes_left--;
+ break;
+ }
+ }
+
+ t.text[t.end] = '\0';
+ return strdup (t.text);
+}
+
/* Return conversion of S according to input_encoding. This function
frees S. */
static char *
convert_to_utf8 (char *s)
{
iconv_t our_iconv = (iconv_t) -1;
- static TEXT t;
- ICONV_CONST char *inptr; size_t bytes_left;
- size_t iconv_ret;
- enum character_encoding enc;
+ char *ret;
/* Convert from @documentencoding to UTF-8.
It might be possible not to convert to UTF-8 and use an 8-bit encoding
@@ -182,7 +224,8 @@ convert_to_utf8 (char *s)
file, then we'd have to keep track of which strings needed the UTF-8 flag
and which didn't. */
- /* Initialize conversions for the first time. */
+ /* Initialize conversions for the first time. iconv_open returns
+ (iconv_t) -1 on failure so these should only be called once. */
if (iconv_validate_utf8 == (iconv_t) 0)
iconv_validate_utf8 = iconv_open ("UTF-8", "UTF-8");
if (iconv_from_latin1 == (iconv_t) 0)
@@ -231,55 +274,96 @@ convert_to_utf8 (char *s)
return s;
}
- t.end = 0;
- inptr = s;
- bytes_left = strlen (s);
- text_alloc (&t, 10);
+ ret = encode_with_iconv (our_iconv, s);
+ free (s);
+ return ret;
+}
- while (1)
- {
- iconv_ret = text_buffer_iconv (&t, our_iconv,
- &inptr, &bytes_left);
- /* Make sure libiconv flushes out the last converted character.
- This is required when the conversion is stateful, in which
- case libiconv might not output the last character, waiting to
- see whether it should be combined with the next one. */
- if (iconv_ret != (size_t) -1
- && text_buffer_iconv (&t, our_iconv, 0, 0) != (size_t) -1)
- /* Success: all of input converted. */
- break;
+int doc_encoding_for_input_file_name = 1;
+char *input_file_name_encoding = 0;
+char *locale_encoding = 0;
- if (bytes_left == 0)
- break;
+void
+set_input_file_name_encoding (char *value)
+{
+ free (input_file_name_encoding);
+ input_file_name_encoding = value ? strdup (value) : 0;
+}
- switch (errno)
+void
+set_locale_encoding (char *value)
+{
+ free (locale_encoding);
+ locale_encoding = value ? strdup (value) : 0;
+}
+
+/* Reverse the decoding of the filename to the input encoding, to retrieve
+ the bytes that were present in the original Texinfo file. Return
+ value is freed by free_small_strings. */
+char *
+encode_file_name (char *filename)
+{
+ if (!reverse_iconv)
+ {
+ if (input_file_name_encoding)
{
- case E2BIG:
- text_alloc (&t, t.space + 20);
- break;
- case EILSEQ:
- default:
- fprintf(stderr, "%s:%d: encoding error at byte 0x%2x\n",
- line_nr.file_name, line_nr.line_nr, *(unsigned char *)inptr);
- inptr++; bytes_left--;
- break;
+ reverse_iconv = iconv_open (input_file_name_encoding, "UTF-8");
+ }
+ else if (doc_encoding_for_input_file_name)
+ {
+ if (input_encoding != ce_utf8 && input_encoding_name)
+ {
+ reverse_iconv = iconv_open (input_encoding_name, "UTF-8");
+ }
+ }
+ else if (locale_encoding)
+ {
+ reverse_iconv = iconv_open (locale_encoding, "UTF-8");
}
}
+ if (reverse_iconv && reverse_iconv != (iconv_t) -1)
+ {
+ char *s, *conv;
+ conv = encode_with_iconv (reverse_iconv, filename);
+ s = save_string (conv);
+ free (conv);
+ return s;
+ }
+ else
+ {
+ return save_string (filename);
+ }
+}
- free (s);
- t.text[t.end] = '\0';
- return strdup (t.text);
+/* Change the line number of filename of the top input source. Used to
+ record a #line directive. */
+void
+save_line_directive (int line_nr, char *filename)
+{
+ char *f = 0;
+ INPUT *top;
+
+ if (filename)
+ f = encode_file_name (filename);
+
+ top = &input_stack[input_number - 1];
+ if (line_nr)
+ top->source_info.line_nr = line_nr;
+ if (filename)
+ top->source_info.file_name = f;
}
+
+
int
expanding_macro (char *macro)
{
int i;
for (i = 0; i < input_number; i++)
{
- if (input_stack[i].line_nr.macro
- && !strcmp (input_stack[i].line_nr.macro, macro))
+ if (input_stack[i].source_info.macro
+ && !strcmp (input_stack[i].source_info.macro, macro))
{
return 1;
}
@@ -289,6 +373,15 @@ expanding_macro (char *macro)
char *save_string (char *string);
+void
+input_pushback (char *string)
+{
+ if (input_pushback_string)
+ fprintf (stderr,
+ "texi2any (XS module): bug: input_pushback called twice\n");
+ input_pushback_string = string;
+}
+
/* Return value to be freed by caller. Return null if we are out of input. */
char *
next_text (void)
@@ -298,6 +391,14 @@ next_text (void)
size_t n;
FILE *input_file;
+ if (input_pushback_string)
+ {
+ char *s;
+ s = input_pushback_string;
+ input_pushback_string = 0;
+ return s;
+ }
+
while (input_number > 0)
{
/* Check for pending input. */
@@ -321,10 +422,10 @@ next_text (void)
else
i->ptext = p; /* The next time, we will pop the input source. */
- if (!i->line_nr.macro)
- i->line_nr.line_nr++;
+ if (!i->source_info.macro)
+ i->source_info.line_nr++;
- line_nr = i->line_nr;
+ current_source_info = i->source_info;
return new;
@@ -339,7 +440,7 @@ next_text (void)
{
/* Add a newline at the end of the file if one is missing. */
char *line2;
- asprintf (&line2, "%s\n", line);
+ xasprintf (&line2, "%s\n", line);
free (line);
line = line2;
}
@@ -349,8 +450,8 @@ next_text (void)
if (comment)
*comment = '\0';
- i->line_nr.line_nr++;
- line_nr = i->line_nr;
+ i->source_info.line_nr++;
+ current_source_info = i->source_info;
return convert_to_utf8 (line);
}
@@ -370,7 +471,7 @@ next_text (void)
{
if (fclose (input_stack[input_number - 1].file) == EOF)
fprintf (stderr, "error on closing %s: %s",
- input_stack[input_number - 1].line_nr.file_name,
+ input_stack[input_number - 1].source_info.file_name,
strerror (errno));
}
}
@@ -398,9 +499,9 @@ input_push (char *text, char *macro, char *filename, int line_number)
if (!macro)
line_number--;
- input_stack[input_number].line_nr.line_nr = line_number;
- input_stack[input_number].line_nr.file_name = save_string (filename);
- input_stack[input_number].line_nr.macro = save_string (macro);
+ input_stack[input_number].source_info.line_nr = line_number;
+ input_stack[input_number].source_info.file_name = save_string (filename);
+ input_stack[input_number].source_info.macro = save_string (macro);
input_number++;
}
@@ -455,9 +556,9 @@ input_push_text (char *text, char *macro)
char *filename = 0;
if (input_number > 0)
{
- filename = input_stack[input_number - 1].line_nr.file_name;
+ filename = input_stack[input_number - 1].source_info.file_name;
}
- input_push (text, macro, filename, line_nr.line_nr);
+ input_push (text, macro, filename, current_source_info.line_nr);
}
}
@@ -520,6 +621,17 @@ add_include_directory (char *filename)
filename[len - 1] = '\0';
}
+void
+clear_include_directories (void)
+{
+ int i;
+ for (i = 0; i < include_dirs_number; i++)
+ {
+ free (include_dirs[i]);
+ }
+ include_dirs_number = 0;
+}
+
/* Return value to be freed by caller. */
char *
locate_include_file (char *filename)
@@ -528,11 +640,9 @@ locate_include_file (char *filename)
struct stat dummy;
int i, status;
- /* Checks if filename is absolute or relative to current directory.
- TODO: Could use macros in top-level config.h for this. */
- /* TODO: The Perl code (in Common.pm, 'locate_include_file') handles
- a volume in a path (like "A:"), possibly more general treatment
- with File::Spec module. */
+ /* Checks if filename is absolute or relative to current directory. */
+ /* Note: the Perl code (in Common.pm, 'locate_include_file') handles
+ a volume in a path (like "A:") using the File::Spec module. */
if (!memcmp (filename, "/", 1)
|| !memcmp (filename, "../", 3)
|| !memcmp (filename, "./", 2))
@@ -545,7 +655,7 @@ locate_include_file (char *filename)
{
for (i = 0; i < include_dirs_number; i++)
{
- asprintf (&fullpath, "%s/%s", include_dirs[i], filename);
+ xasprintf (&fullpath, "%s/%s", include_dirs[i], filename);
status = stat (fullpath, &dummy);
if (status == 0)
return fullpath;
@@ -560,11 +670,17 @@ locate_include_file (char *filename)
int
input_push_file (char *filename)
{
- FILE *stream;
+ FILE *stream = 0;
+ char *p, *q;
- stream = fopen (filename, "r");
- if (!stream)
- return errno;
+ if (!strcmp (filename, "-"))
+ stream = stdin;
+ else
+ {
+ stream = fopen (filename, "r");
+ if (!stream)
+ return errno;
+ }
if (input_number == input_space)
{
@@ -574,7 +690,6 @@ input_push_file (char *filename)
}
/* Strip off a leading directory path. */
- char *p, *q;
p = 0;
q = strchr (filename, '/');
while (q)
@@ -589,9 +704,9 @@ input_push_file (char *filename)
input_stack[input_number].type = IN_file;
input_stack[input_number].file = stream;
- input_stack[input_number].line_nr.file_name = filename;
- input_stack[input_number].line_nr.line_nr = 0;
- input_stack[input_number].line_nr.macro = 0;
+ input_stack[input_number].source_info.file_name = filename;
+ input_stack[input_number].source_info.line_nr = 0;
+ input_stack[input_number].source_info.macro = 0;
input_stack[input_number].text = 0;
input_stack[input_number].ptext = 0;
input_number++;
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.h
index 6a906c0b47..9cf758e030 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/input.h
@@ -13,17 +13,29 @@ void input_push (char *text, char *macro, char *filename, int line_number);
void input_push_text (char *line, char *macro);
void input_push_text_with_line_nos (char *text, int starting);
int input_push_file (char *filename);
+void input_pushback (char *line);
void input_reset_input_stack (void);
int expanding_macro (char *macro);
int top_file_index (void);
+
char *locate_include_file (char *filename);
+char *encode_file_name (char *filename);
void set_input_encoding (char *encoding);
void add_include_directory (char *filename);
+void clear_include_directories (void);
char *save_string (char *string);
void free_small_strings (void);
-extern LINE_NR line_nr;
+extern SOURCE_INFO current_source_info;
extern int input_number;
+
+extern int doc_encoding_for_input_file_name;
+extern char *input_file_name_encoding;
+extern char *locale_encoding;
+
+void set_input_file_name_encoding (char *value);
+void set_locale_encoding (char *value);
+
#endif
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/macro.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/macro.c
index 292e4cc08a..e2b65432b1 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/macro.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/macro.c
@@ -1,4 +1,4 @@
-/* Copyright 2010-2019 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -13,8 +13,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#define _GNU_SOURCE
-
#include <config.h>
#include <stdlib.h>
#include <string.h>
@@ -87,7 +85,7 @@ parse_macro_command_line (enum command_id cmd, char **line_inout,
macro = new_element (ET_NONE);
macro->cmd = cmd;
- macro->line_nr = line_nr;
+ macro->source_info = current_source_info;
add_extra_string (macro, "arg_line", strdup (line));
/* Note this extra value isn't used much, so it might be possible
@@ -659,6 +657,23 @@ store_value (char *name, char *value)
v->name = strdup (name);
v->value = strdup (value);
+
+ /* Internal Texinfo flag */
+ if (!strncmp (name, "txi", 3))
+ {
+ int val = (strcmp(value, "0") != 0);
+ if (!strcmp (name, "txiindexbackslashignore"))
+ global_info.ignored_chars.backslash = val;
+ else if (!strcmp (name, "txiindexhyphenignore"))
+ global_info.ignored_chars.hyphen = val;
+ else if (!strcmp (name, "txiindexlessthanignore"))
+ global_info.ignored_chars.lessthan = val;
+ else if (!strcmp (name, "txiindexatsignignore"))
+ global_info.ignored_chars.atsign = val;
+
+ /* also: txicodequotebacktick, txicodequoteundirected,
+ txicommandconditionals. Deal with them here? */
+ }
}
void
@@ -673,6 +688,21 @@ clear_value (char *name)
value_list[i].value[0] = '\0';
}
}
+ /* Internal Texinfo flag */
+ if (!strncmp (name, "txi", 3))
+ {
+ if (!strcmp (name, "txiindexbackslashignore"))
+ global_info.ignored_chars.backslash = 0;
+ else if (!strcmp (name, "txiindexhyphenignore"))
+ global_info.ignored_chars.hyphen = 0;
+ else if (!strcmp (name, "txiindexlessthanignore"))
+ global_info.ignored_chars.lessthan = 0;
+ else if (!strcmp (name, "txiindexatsignignore"))
+ global_info.ignored_chars.atsign = 0;
+
+ /* also: txicodequotebacktick, txicodequoteundirected,
+ txicommandconditionals. Deal with them here? */
+ }
}
char *
@@ -685,6 +715,9 @@ fetch_value (char *name)
return value_list[i].value;
}
+ /* special value always returned as 1 to mark that @ifcommandnotdefined
+ is implemented. Note that in most cases it is also set from perl
+ using the configuration passed to the parser */
if (!strcmp (name, "txicommandconditionals"))
return "1";
return 0;
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/menus.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/menus.c
index dce4b749c4..394f2edf5b 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/menus.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/menus.c
@@ -51,7 +51,8 @@ register_extra_menu_entry_information (ELEMENT *current)
isolate_last_space (arg);
parsed_entry_node = parse_node_manual (arg);
- if (!parsed_entry_node)
+ if (!parsed_entry_node->manual_content
+ && !parsed_entry_node->node_content)
{
if (conf.show_menu)
line_error ("empty node name in menu entry");
@@ -77,14 +78,13 @@ enter_menu_entry_node (ELEMENT *current)
description = new_element (ET_menu_entry_description);
add_to_element_args (current, description);
register_extra_menu_entry_information (current);
- current->line_nr = line_nr;
+ current->source_info = current_source_info;
remember_internal_xref (current);
current = description;
preformatted = new_element (ET_preformatted);
add_to_element_contents (current, preformatted);
current = preformatted;
- push_context (ct_preformatted);
return current;
}
@@ -111,16 +111,16 @@ handle_menu (ELEMENT **current_inout, char **line_inout)
abort_empty_line (&current, 0);
line++; /* Past the '*'. */
- star = new_element (ET_menu_star);
+ star = new_element (ET_internal_menu_star);
text_append (&star->text, "*");
add_to_element_contents (current, star);
- /* The ET_menu_star element won't appear in the final tree. */
+ /* The ET_internal_menu_star element won't appear in the final tree. */
}
/* A space after a "*" at the beginning of a line. */
else if (strchr (whitespace_chars, *line)
&& current->contents.number > 0
- && last_contents_child(current)->type == ET_menu_star)
+ && last_contents_child(current)->type == ET_internal_menu_star)
{
ELEMENT *menu_entry, *leading_text, *entry_name;
int leading_spaces;
@@ -158,9 +158,6 @@ handle_menu (ELEMENT **current_inout, char **line_inout)
current = current->parent->parent->parent;
}
- if (pop_context () != ct_preformatted)
- fatal ("preformatted context expected");
-
menu_entry = new_element (ET_menu_entry);
leading_text = new_element (ET_menu_entry_leading_text);
entry_name = new_element (ET_menu_entry_name);
@@ -175,7 +172,7 @@ handle_menu (ELEMENT **current_inout, char **line_inout)
}
/* A "*" followed by anything other than a space. */
else if (current->contents.number > 0
- && last_contents_child(current)->type == ET_menu_star)
+ && last_contents_child(current)->type == ET_internal_menu_star)
{
debug ("ABORT MENU STAR");
last_contents_child(current)->type = ET_NONE;
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.c
index 65498f0267..8a85a14c2e 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.c
@@ -1,4 +1,4 @@
-/* Copyright 2010-2019 Free Software Foundation, Inc.
+/* Copyright 2010-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,11 +24,11 @@
#include "input.h"
-const char *whitespace_chars = " \t\f\r\n";
+const char *whitespace_chars = " \t\v\f\r\n";
const char *digit_chars = "0123456789";
// [^\S\r\n] in Perl
-const char *whitespace_chars_except_newline = " \t\f";
+const char *whitespace_chars_except_newline = " \t\v\f";
/* Check if the contents of S2 appear at S1). */
int
@@ -48,10 +48,10 @@ read_command_name (char **ptr)
char *ret = 0;
q = p;
- if (!isalnum (*q))
+ if (!isalnum ((unsigned char) *q))
return 0; /* Invalid. */
- while (isalnum (*q) || *q == '-' || *q == '_')
+ while (isalnum ((unsigned char) *q) || *q == '-' || *q == '_')
q++;
ret = strndup (p, q - p);
p = q;
@@ -68,7 +68,7 @@ read_flag_name (char **ptr)
char *ret = 0;
q = p;
- if (!isalnum (*q) && *q != '-' && *q != '_')
+ if (!isalnum ((unsigned char) *q) && *q != '-' && *q != '_')
return 0; /* Invalid. */
while (!strchr (whitespace_chars, *q)
@@ -87,6 +87,27 @@ element_type_name (ELEMENT *e)
return element_type_names[(e)->type];
}
+/* Return 1 if the element expansion is all whitespace */
+int
+check_space_element (ELEMENT *e)
+{
+ if (!(
+ e->cmd == CM_SPACE
+ || e->cmd == CM_TAB
+ || e->cmd == CM_NEWLINE
+ || e->cmd == CM_c
+ || e->cmd == CM_comment
+ || e->cmd == CM_COLON
+ || (!e->cmd && !e->type && e->text.end == 0)
+ || (e->text.end > 0
+ && !*(e->text.text + strspn (e->text.text, whitespace_chars)))
+ ))
+ {
+ return 0;
+ }
+ return 1;
+}
+
/* Current node, section and part. */
@@ -136,20 +157,35 @@ COUNTER count_cells;
GLOBAL_INFO global_info;
char *global_clickstyle = 0;
char *global_documentlanguage = 0;
+int global_documentlanguage_fixed = 0;
+int global_accept_internalvalue = 0;
enum kbd_enum global_kbdinputstyle = kbd_distinct;
+/* Set the document language unless it was set on the texi2any command line. */
void
set_documentlanguage (char *value)
{
+ if (!global_documentlanguage_fixed)
+ {
+ free (global_documentlanguage);
+ global_documentlanguage = value ? strdup (value) : 0;
+ }
+}
+
+void
+set_documentlanguage_override (char *value)
+{
free (global_documentlanguage);
- global_documentlanguage = strdup (value);
+ global_documentlanguage = value ? strdup (value) : 0;
+ global_documentlanguage_fixed = 1;
}
+
void
-set_novalidate (int value)
+set_accept_internalvalue()
{
- global_info.novalidate = value;
+ global_accept_internalvalue = 1;
}
/* Record the information from a command of global effect. */
@@ -162,8 +198,8 @@ register_global_command (ELEMENT *current)
if (command_data(cmd).flags & CF_global)
{
- if (!current->line_nr.line_nr)
- current->line_nr = line_nr;
+ if (!current->source_info.line_nr)
+ current->source_info = current_source_info;
switch (cmd)
{
#define GLOBAL_CASE(cmx) \
@@ -184,7 +220,7 @@ register_global_command (ELEMENT *current)
GLOBAL_CASE(detailmenu);
GLOBAL_CASE(part);
- /* from Common.pm %document_settable_at_commands */
+ /* from Common.pm %document_settable_multiple_at_commands */
GLOBAL_CASE(allowcodebreaks);
GLOBAL_CASE(clickstyle);
GLOBAL_CASE(codequotebacktick);
@@ -198,6 +234,7 @@ register_global_command (ELEMENT *current)
GLOBAL_CASE(frenchspacing);
GLOBAL_CASE(headings);
GLOBAL_CASE(kbdinputstyle);
+ GLOBAL_CASE(microtype);
GLOBAL_CASE(paragraphindent);
GLOBAL_CASE(shortcontents);
GLOBAL_CASE(urefbreakstyle);
@@ -214,8 +251,8 @@ register_global_command (ELEMENT *current)
{
ELEMENT **where = 0;
- if (!current->line_nr.line_nr)
- current->line_nr = line_nr;
+ if (!current->source_info.line_nr)
+ current->source_info = current_source_info;
switch (cmd)
{
case CM_setfilename:
@@ -253,6 +290,13 @@ register_global_command (ELEMENT *current)
GLOBAL_UNIQUE_CASE(oddfootingmarks);
GLOBAL_UNIQUE_CASE(shorttitlepage);
GLOBAL_UNIQUE_CASE(title);
+ GLOBAL_UNIQUE_CASE(novalidate);
+ GLOBAL_UNIQUE_CASE(afourpaper);
+ GLOBAL_UNIQUE_CASE(afourlatex);
+ GLOBAL_UNIQUE_CASE(afourwide);
+ GLOBAL_UNIQUE_CASE(afivepaper);
+ GLOBAL_UNIQUE_CASE(bsixpaper);
+ GLOBAL_UNIQUE_CASE(smallbook);
#undef GLOBAL_UNIQUE_CASE
/* NOTE: Same list in api.c:build_global_info2 and wipe_global_info. */
default:
@@ -277,9 +321,12 @@ void
wipe_global_info (void)
{
free (global_clickstyle);
- free (global_documentlanguage);
global_clickstyle = strdup ("arrow");
- global_documentlanguage = strdup ("");
+ if (!global_documentlanguage_fixed)
+ {
+ free (global_documentlanguage);
+ global_documentlanguage = 0;
+ }
global_kbdinputstyle = kbd_distinct;
free (global_info.input_perl_encoding);
@@ -312,54 +359,41 @@ wipe_global_info (void)
GLOBAL_CASE(frenchspacing);
GLOBAL_CASE(headings);
GLOBAL_CASE(kbdinputstyle);
+ GLOBAL_CASE(microtype);
GLOBAL_CASE(paragraphindent);
GLOBAL_CASE(shortcontents);
GLOBAL_CASE(urefbreakstyle);
GLOBAL_CASE(xrefautomaticsectiontitle);
#undef GLOBAL_CASE
+
+ /* clear the rest of the fields */
memset (&global_info, 0, sizeof (global_info));
global_info.input_perl_encoding = strdup ("utf-8");
global_info.input_encoding_name = strdup ("utf-8");
}
+ELEMENT *
+setup_document_root_and_before_node_section ()
+{
+ ELEMENT *before_node_section = new_element (ET_before_node_section);
+ ELEMENT *document_root = new_element (ET_document_root);
+ add_to_element_contents (document_root, before_node_section);
+ return before_node_section;
+}
+
ELEMENT *
-parse_texi_file (char *filename)
+parse_texi_document (void)
{
- char *p, *q;
char *linep, *line = 0;
- ELEMENT *root = new_element (ET_text_root);
- ELEMENT *preamble = 0;
- char c;
-
- int status;
-
- status = input_push_file (filename);
- if (status)
- return 0;
-
- /* Strip off a leading directory path, by looking for the last
- '/' in filename. */
- p = 0;
- q = strchr (filename, '/');
- while (q)
- {
- p = q;
- q = strchr (q + 1, '/');
- }
-
- if (p)
- {
- c = *p;
- *p = '\0';
- add_include_directory (filename);
- *p = c;
- }
+ ELEMENT *before_node_section = setup_document_root_and_before_node_section ();
+ ELEMENT *preamble_before_beginning = 0;
+ ELEMENT *document_root = before_node_section->parent;
- /* Put all lines up to a line starting "\input" inside a "preamble"
- element. */
+ /* Put all the empty lines up to a line starting "\input" inside a
+ "preamble_before_beginning" element. */
while (1)
{
ELEMENT *l;
@@ -369,28 +403,28 @@ parse_texi_file (char *filename)
if (!line)
break;
- linep = line;
+ linep = line;
linep += strspn (linep, whitespace_chars);
if (*linep && !looking_at (linep, "\\input"))
{
- /* This line is not part of the preamble. Shove back
- into input stream. */
- input_push (line, 0, line_nr.file_name, line_nr.line_nr);
+ /* This line is not part of the preamble_before_beginning.
+ Push back into input stream. */
+ input_pushback (line);
break;
}
- if (!preamble)
- preamble = new_element (ET_preamble);
+ if (!preamble_before_beginning)
+ preamble_before_beginning = new_element (ET_preamble_before_beginning);
- l = new_element (ET_preamble_text);
+ l = new_element (ET_text_before_beginning);
text_append (&l->text, line);
- add_to_element_contents (preamble, l);
+ add_to_element_contents (preamble_before_beginning, l);
}
- if (preamble)
- add_to_element_contents (root, preamble);
+ if (preamble_before_beginning)
+ add_to_element_contents (before_node_section, preamble_before_beginning);
- return parse_texi (root);
+ return parse_texi (document_root, before_node_section);
}
@@ -399,7 +433,7 @@ begin_paragraph_p (ELEMENT *current)
{
return (current->type == ET_NONE /* "True for @-commands" */
|| current->type == ET_before_item
- || current->type == ET_text_root
+ || current->type == ET_before_node_section
|| current->type == ET_document_root
|| current->type == ET_brace_command_context)
&& in_paragraph_context (current_context ());
@@ -426,7 +460,7 @@ begin_paragraph (ELEMENT *current)
if (child->type == ET_empty_line
|| child->type == ET_paragraph)
break;
- if (close_paragraph_command(child->cmd))
+ if (command_data(child->cmd).flags & CF_close_paragraph)
break;
if (child->cmd == CM_indent
|| child->cmd == CM_noindent)
@@ -455,32 +489,23 @@ begin_paragraph (ELEMENT *current)
ELEMENT *
begin_preformatted (ELEMENT *current)
{
- if (current_context() == ct_preformatted
- || current_context() == ct_rawpreformatted)
+ if (current_context() == ct_preformatted)
{
- ELEMENT *e;
- enum element_type et;
-
- if (current_context() == ct_preformatted)
- et = ET_preformatted;
- else
- et = ET_rawpreformatted;
- e = new_element (et);
- add_to_element_contents (current, e);
- current = e;
- debug ("PREFORMATTED %s", et == ET_preformatted ? "preformatted"
- : "rawpreformatted");
+ ELEMENT *preformatted = new_element (ET_preformatted);
+ add_to_element_contents (current, preformatted);
+ current = preformatted;
+ debug ("PREFORMATTED");
}
return current;
}
ELEMENT *
end_paragraph (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command)
{
- current = close_all_style_commands (current,
- closed_command, interrupting_command);
+ current = close_all_style_commands (current, closed_block_command,
+ interrupting_command);
if (current->type == ET_paragraph)
{
debug ("CLOSE PARA");
@@ -492,17 +517,14 @@ end_paragraph (ELEMENT *current,
ELEMENT *
end_preformatted (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command)
{
- current = close_all_style_commands (current,
- closed_command, interrupting_command);
- if (current->type == ET_preformatted
- || current->type == ET_rawpreformatted)
+ current = close_all_style_commands (current, closed_block_command,
+ interrupting_command);
+ if (current->type == ET_preformatted)
{
- debug ("CLOSE PREFORMATTED %s",
- current->type == ET_preformatted ? "preformatted"
- : "rawpreformatted");
+ debug ("CLOSE PREFORMATTED");
if (current->contents.number == 0)
{
current = current->parent;
@@ -529,10 +551,10 @@ merge_text (ELEMENT *current, char *text)
char *additional = 0;
if (last_child
- && (last_child->type == ET_empty_line_after_command
- || last_child->type == ET_empty_spaces_after_command
- || last_child->type == ET_empty_spaces_before_argument
- || last_child->type == ET_empty_spaces_after_close_brace))
+ && (last_child->type == ET_ignorable_spaces_after_command
+ || last_child->type == ET_internal_spaces_after_command
+ || last_child->type == ET_internal_spaces_before_argument
+ || last_child->type == ET_spaces_after_close_brace))
{
no_merge_with_following_text = 1;
}
@@ -558,16 +580,11 @@ merge_text (ELEMENT *current, char *text)
if (last_child
/* There is a difference between the text being defined and empty,
and not defined at all. The latter is true for 'brace_command_arg'
- elements. We need either to make sure that we initialize all elements
+ elements. We need either to make sure that we initialize all elements
with text_append (&e->text, "") where we want merging with following
- text, or treat as a special case here.
- Unfortunately we can't make a special case for
- ET_empty_spaces_before_argument, because abort_empty_line above
- produces such an element that shouldn't be merged with. */
+ text, or treat as a special case here. */
&& (last_child->text.space > 0
- && !strchr (last_child->text.text, '\n')
- ) /* || last_child->type == ET_empty_spaces_before_argument) */
- && last_child->cmd != CM_value
+ && !strchr (last_child->text.text, '\n'))
&& !no_merge_with_following_text)
{
/* Append text to contents */
@@ -600,19 +617,13 @@ abort_empty_line (ELEMENT **current_inout, char *additional_spaces)
if (last_child
&& (last_child->type == ET_empty_line
- || last_child->type == ET_empty_line_after_command
- || last_child->type == ET_empty_spaces_before_argument
- || last_child->type == ET_empty_spaces_after_close_brace))
+ || last_child->type == ET_ignorable_spaces_after_command
+ || last_child->type == ET_internal_spaces_after_command
+ || last_child->type == ET_internal_spaces_before_argument
+ || last_child->type == ET_spaces_after_close_brace))
{
- ELEMENT *owning_element = 0, *e;
- KEY_PAIR *k;
-
retval = 1;
- k = lookup_extra (last_child, "command");
- if (k)
- owning_element = (ELEMENT *) k->value;
-
debug ("ABORT EMPTY %s additional text |%s| "
"current |%s|",
element_type_name(last_child),
@@ -623,29 +634,28 @@ abort_empty_line (ELEMENT **current_inout, char *additional_spaces)
/* Remove element altogether if it's empty. */
if (last_child->text.end == 0)
{
- e = pop_element_from_contents (current);
+ ELEMENT *e = pop_element_from_contents (current);
destroy_element (e);
}
else if (last_child->type == ET_empty_line)
{
last_child->type = begin_paragraph_p (current)
- ? ET_empty_spaces_before_paragraph : ET_NONE;
+ ? ET_spaces_before_paragraph : ET_NONE;
}
- else if (last_child->type == ET_empty_line_after_command
- || last_child->type == ET_empty_spaces_before_argument)
+ else if (last_child->type == ET_internal_spaces_after_command
+ || last_child->type == ET_internal_spaces_before_argument)
{
- if (owning_element)
- {
- /* Remove element from main tree. */
- ELEMENT *e = pop_element_from_contents (current);
- add_extra_string_dup (owning_element, "spaces_before_argument",
- e->text.text);
- destroy_element (e);
- }
- else
- {
- last_child->type = ET_empty_spaces_after_command;
- }
+ /* Remove element from main tree. It will still be referenced in
+ the 'extra' hash as 'spaces_before_argument'. */
+ ELEMENT *owning_element;
+ KEY_PAIR *k;
+ ELEMENT *e = pop_element_from_contents (current);
+
+ k = lookup_extra (last_child, "spaces_associated_command");
+ owning_element = (ELEMENT *) k->value;
+ add_extra_string_dup (owning_element, "spaces_before_argument",
+ e->text.text);
+ destroy_element (e);
}
}
else
@@ -659,11 +669,13 @@ static void
isolate_last_space_internal (ELEMENT *current)
{
ELEMENT *last_elt;
+ char *text;
+ int text_len;
last_elt = last_contents_child (current);
- char *text = element_text (last_elt);
+ text = element_text (last_elt);
- int text_len = last_elt->text.end;
+ text_len = last_elt->text.end;
/* If text all whitespace */
if (text[strspn (text, whitespace_chars)] == '\0')
@@ -725,14 +737,17 @@ isolate_trailing_space (ELEMENT *current, enum element_type spaces_type)
i--)
trailing_spaces++;
- new_spaces = new_element (spaces_type);
- text_append_n (&new_spaces->text,
- text + text_len - trailing_spaces,
- trailing_spaces);
- text[text_len - trailing_spaces] = '\0';
- last_elt->text.end -= trailing_spaces;
-
- add_to_element_contents (current, new_spaces);
+ if (trailing_spaces)
+ {
+ new_spaces = new_element (spaces_type);
+ text_append_n (&new_spaces->text,
+ text + text_len - trailing_spaces,
+ trailing_spaces);
+ text[text_len - trailing_spaces] = '\0';
+ last_elt->text.end -= trailing_spaces;
+
+ add_to_element_contents (current, new_spaces);
+ }
}
}
@@ -760,7 +775,8 @@ isolate_last_space (ELEMENT *current)
text = element_text (last_elt);
if (!text || !*text
|| (last_elt->type && (!current->type
- || current->type != ET_line_arg)))
+ || (current->type != ET_line_arg
+ && current->type != ET_block_line_arg))))
return;
text_len = last_elt->text.end;
@@ -775,11 +791,12 @@ isolate_last_space (ELEMENT *current)
}
-/* Add an "ET_empty_line_after_command" element containing the whitespace at
- the beginning of the rest of the line. This element can be later changed to
- a "ET_empty_spaces_after_command" element in 'abort_empty_line' if more
- text follows on the line. Used after line commands or commands starting
- a block. */
+/* Add an "ET_ignorable_spaces_after_command" element containing the
+ whitespace at the beginning of the rest of the line after skipspaces
+ commands, if COMMAND is 0. Otherwise add an
+ "ET_internal_spaces_after_command", container, after line commands
+ or commands starting a block, that will end up in COMMAND extra spaces
+ value. */
void
start_empty_line_after_command (ELEMENT *current, char **line_inout,
ELEMENT *command)
@@ -789,22 +806,45 @@ start_empty_line_after_command (ELEMENT *current, char **line_inout,
int len;
len = strspn (line, whitespace_chars_except_newline);
- e = new_element (ET_empty_line_after_command);
+ e = new_element (ET_ignorable_spaces_after_command);
add_to_element_contents (current, e);
text_append_n (&e->text, line, len);
line += len;
if (command)
- add_extra_element (e, "command", command);
+ {
+ add_extra_element (e, "spaces_associated_command", command);
+ e->type = ET_internal_spaces_after_command;
+ }
*line_inout = line;
}
-/* If the parent element takes a command as an argument, like
- @itemize @bullet. */
+/* if kbd should be formatted as code */
int
-command_with_command_as_argument (ELEMENT *current)
+kbd_formatted_as_code (ELEMENT *current)
+{
+ if (global_kbdinputstyle == kbd_code)
+ {
+ return 1;
+ }
+ else if (global_kbdinputstyle == kbd_example)
+ {
+ if (in_preformatted_context_not_menu ())
+ return 0;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+
+/* If the container can hold a command as an argument, determined as
+ parent element taking a command as an argument, like
+ @itemize @bullet, and the command as argument being the only content. */
+int
+parent_of_command_as_argument (ELEMENT *current)
{
return current->type == ET_block_line_arg
&& (current->parent->cmd == CM_itemize
@@ -812,6 +852,24 @@ command_with_command_as_argument (ELEMENT *current)
&& (current->contents.number == 1);
}
+/* register a command like @bullet with @itemize, or @asis with @table */
+void
+register_command_as_argument (ELEMENT *cmd_as_arg)
+{
+ debug ("FOR PARENT @%s command_as_argument @%s",
+ command_name(cmd_as_arg->parent->parent->cmd),
+ command_name(cmd_as_arg->cmd));
+ if (!cmd_as_arg->type)
+ cmd_as_arg->type = ET_command_as_argument;
+ add_extra_element (cmd_as_arg->parent->parent,
+ "command_as_argument", cmd_as_arg);
+ if (cmd_as_arg->cmd == CM_kbd
+ && kbd_formatted_as_code(cmd_as_arg->parent->parent)) {
+ add_extra_integer (cmd_as_arg->parent->parent,
+ "command_as_argument_kbd_code", 1);
+ }
+}
+
/* Check if line is "@end ..." for current command. If so, advance LINE. */
int
is_end_current_command (ELEMENT *current, char **line,
@@ -855,7 +913,7 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
/* Check whether outer command can contain cmd. Commands are
classified according to what commands they can contain:
- accents
+ plain text
full text
simple text
full line
@@ -865,8 +923,7 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
int ok = 0; /* Whether nesting is allowed. */
- /* Whether command is a "simple text" command. Use a variable
- to avoid repeating a complex conditional. */
+ /* Whether command is a "simple text" command */
int simple_text_command = 0;
enum command_id outer = current->parent->cmd;
@@ -875,27 +932,16 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
// much TODO here.
- if ((outer_flags & CF_line
- && (command_data(outer).data >= 0
- || (command_data(outer).data == LINE_line
- && !(outer_flags & (CF_def | CF_sectioning)))
- || command_data(outer).data == LINE_text)
- && outer != CM_center
- && outer != CM_exdent)
- || ((outer_flags & CF_brace)
- && !(outer_flags & CF_inline)
- && command_data(outer).data > 0)
- || outer == CM_shortcaption
- || outer == CM_math
- || (outer_flags & CF_index_entry_command)
- || (outer_flags & CF_block
- && !(outer_flags & CF_def)
- && command_data(outer).data != BLOCK_raw
- && command_data(outer).data != BLOCK_conditional))
+ if (outer_flags & CF_contain_simple_text
+ /* not in CF_contain_simple_text since index entry flags are not set
+ in command_data.txt, and also index commands are dynamically added */
+ || outer_flags & CF_index_entry_command)
{
simple_text_command = 1;
}
+ /* first three conditions check if in the main contents of the commands
+ or in the arguments where there is checking of nesting */
if (outer_flags & CF_root && current->type != ET_line_arg)
ok = 1;
else if (outer_flags & CF_block
@@ -905,12 +951,14 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
|| outer == CM_itemx)
&& current->type != ET_line_arg)
ok = 1;
- else if (outer_flags & CF_accent)
+ else if (outer_flags & CF_contain_plain_text)
{
- if (cmd_flags & (CF_nobrace | CF_accent))
+ if ((cmd_flags & CF_accent)
+ || (cmd_flags & CF_nobrace
+ && command_data(cmd).data == NOBRACE_symbol))
ok = 1;
else if (cmd_flags & CF_brace
- && command_data(cmd).data == 0)
+ && command_data(cmd).data == BRACE_noarg)
ok = 1; /* glyph command */
if (cmd == CM_c || cmd == CM_comment)
ok = 1;
@@ -918,7 +966,9 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
else if (simple_text_command
/* "full text commands" */
|| (outer_flags & CF_brace)
- && command_data(outer).data == BRACE_style
+ && (command_data(outer).data == BRACE_style_other
+ || command_data(outer).data == BRACE_style_code
+ || command_data(outer).data == BRACE_style_no_code)
/* "full line commands" */
|| outer == CM_center
|| outer == CM_exdent
@@ -928,15 +978,20 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
|| (!current->parent->cmd && current_context () == ct_def)
/* "full line no refs commands" */
- || (outer_flags & (CF_sectioning | CF_def))
+ || (outer_flags & (CF_sectioning_heading | CF_def))
|| (!current->parent->cmd && current_context () == ct_def))
{
/* Start by checking if the command is allowed inside a "full text
command" - this is the most permissive. */
- if (cmd_flags & CF_nobrace)
- ok = 1;
+ /* in the perl parser the checks are not dynamic as in this function,
+ a hash is used and modified when defining the definfoencose command */
+ /* all the brace commands, not the definfoenclose commands, which
+ should be consistent with the perl parser */
if (cmd_flags & CF_brace && !(cmd_flags & CF_INFOENCLOSE))
ok = 1;
+ if (cmd_flags & CF_nobrace && command_data(cmd).data == NOBRACE_symbol)
+ ok = 1;
+ /* selected line commands */
else if (cmd == CM_c
|| cmd == CM_comment
|| cmd == CM_refill
@@ -946,17 +1001,30 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
|| cmd == CM_clear
|| cmd == CM_end)
ok = 1;
- else if (cmd_flags & CF_format_raw)
+ /* selected block commands */
+ else if (cmd_flags & CF_block
+ && (command_data(cmd).data == BLOCK_format_raw
+ || command_data(cmd).data == BLOCK_conditional))
ok = 1;
+ /* not valid in these commands, only right in @float */
if (cmd == CM_caption || cmd == CM_shortcaption)
ok = 0;
- if (cmd_flags & CF_block
- && command_data(cmd).data == BLOCK_conditional)
- ok = 1;
+
+ if (cmd_flags & CF_in_heading_spec)
+ { /* in heading commands can only appear in headings and style
+ brace commands */
+ ok = 0;
+ if (outer_flags & CF_heading_spec
+ || (outer_flags & CF_brace
+ && (command_data(outer).data == BRACE_style_other
+ || command_data(outer).data == BRACE_style_code
+ || command_data(outer).data == BRACE_style_no_code)))
+ ok = 1;
+ }
/* Now add more restrictions for "full line no refs" commands and "simple
- text" commands. */
- if (outer_flags & (CF_sectioning | CF_def)
+ text" commands on valid brace commands. */
+ if (outer_flags & (CF_sectioning_heading | CF_def)
|| (!current->parent->cmd && current_context () == ct_def)
|| simple_text_command)
{
@@ -968,7 +1036,7 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
ok = 0;
}
- /* Exceptions for "simple text commands" only. */
+ /* Exceptions for "simple text commands" only for brace commands. */
if (simple_text_command)
{
if (cmd == CM_xref
@@ -1007,7 +1075,10 @@ check_valid_nesting (ELEMENT *current, enum command_id cmd)
}
/* *LINEP is a pointer into the line being processed. It is advanced past any
- bytes processed. Return 0 when we need to read a new line. */
+ bytes processed.
+ Return 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 when @bye was found */
int
process_remaining_on_line (ELEMENT **current_inout, char **line_inout)
{
@@ -1016,21 +1087,20 @@ process_remaining_on_line (ELEMENT **current_inout, char **line_inout)
char *line_after_command;
int retval = STILL_MORE_TO_PROCESS;
enum command_id end_cmd;
- char *p;
enum command_id cmd = CM_NONE;
+ /* remains set only if command is unknown, otherwise cmd is used */
+ char *command = 0;
- /********* BLOCK_raw or (ignored) BLOCK_conditional ******************/
- /* If in raw block, or ignored conditional block. */
+ /********* BLOCK_raw ******************/
if (command_flags(current) & CF_block
- && (command_data(current->cmd).data == BLOCK_raw
- || command_data(current->cmd).data == BLOCK_conditional))
+ && (command_data(current->cmd).data == BLOCK_raw))
{
+ char *p = line;
/* Check if we are using a macro within a macro. */
if (current->cmd == CM_macro || current->cmd == CM_rmacro)
{
enum command_id cmd = 0;
- char *p = line;
p += strspn (p, whitespace_chars);
if (!strncmp (p, "@macro", strlen ("@macro")))
{
@@ -1054,42 +1124,12 @@ process_remaining_on_line (ELEMENT **current_inout, char **line_inout)
goto funexit;
}
}
-
- /* Else check for nested @ifset (so that @end ifset doesn't
- end the outermost @ifset). */
- if (current->cmd == CM_ifclear || current->cmd == CM_ifset
- || current->cmd == CM_ifcommanddefined
- || current->cmd == CM_ifcommandnotdefined)
- {
- ELEMENT *e;
- char *p = line;
- p += strspn (p, whitespace_chars);
- if (*p == '@'
- && !strncmp (p + 1, command_name(current->cmd),
- strlen (command_name(current->cmd))))
- {
- line = p + 1;
- p += strlen (command_name(current->cmd));
- e = new_element (ET_NONE);
- e->cmd = current->cmd;
- add_extra_string (e, "line", strdup (line));
- add_to_element_contents (current, e);
- current = e;
- retval = GET_A_NEW_LINE;
- goto funexit;
- }
- }
-
/* Else check if line is "@end ..." for current command. */
- p = line;
- if (is_end_current_command (current, &line, &end_cmd))
+ if (is_end_current_command (current, &p, &end_cmd))
{
- ELEMENT *last_child;
- char *tmp = 0;
+ ELEMENT *e;
- last_child = last_contents_child (current);
-
- if (strchr (whitespace_chars, *p))
+ if (strchr (whitespace_chars, *line))
{
ELEMENT *e;
int n = strspn (line, whitespace_chars);
@@ -1100,42 +1140,6 @@ process_remaining_on_line (ELEMENT **current_inout, char **line_inout)
line_warn ("@end %s should only appear at the "
"beginning of a line", command_name(end_cmd));
}
- else if (last_child
- && last_child->type == ET_raw
- && current->cmd != CM_verbatim)
- {
- if (last_child->text.end > 0
- && last_child->text.text[last_child->text.end - 1] == '\n')
- {
- ELEMENT *lrn;
- last_child->text.text[--last_child->text.end] = '\0';
- lrn = new_element (ET_last_raw_newline);
- text_append (&lrn->text, "\n");
- add_to_element_contents (current, lrn);
- }
- }
-
- /* 'line' is now advanced past the "@end ...". Check if
- there's anything after it. */
- p = line + strspn (line, whitespace_chars);
- if (*p && *p != '@')
- goto superfluous_arg;
- if (*p)
- {
- p++;
- tmp = read_command_name (&p);
- if (tmp && (!strcmp (tmp, "c") || !strcmp (tmp, "comment")))
- {
- }
- else if (*p && p[strspn (p, whitespace_chars)])
- {
-superfluous_arg:
- line_warn ("superfluous argument to @end %s: %s",
- command_name (current->cmd), line);
- }
- free (tmp);
- }
-
/* For macros, define a new macro (unless we are in a nested
macro definition). */
@@ -1157,14 +1161,14 @@ superfluous_arg:
macro = lookup_macro (existing);
if (macro)
{
- line_error_ext (1, &current->line_nr,
+ line_error_ext (1, &current->source_info,
"macro `%s' previously defined", name);
- line_error_ext (1, &macro->element->line_nr,
+ line_error_ext (1, &macro->element->source_info,
"here is the previous definition of `%s'", name);
}
else if (!(existing & USER_COMMAND_BIT))
{
- line_error_ext (1, &current->line_nr,
+ line_error_ext (1, &current->source_info,
"redefining Texinfo language command: @%s",
name);
}
@@ -1176,66 +1180,111 @@ superfluous_arg:
}
}
- current = current->parent;
- /* Check for conditionals. */
- if (command_data(end_cmd).flags & CF_block
- && command_data(end_cmd).data == BLOCK_conditional)
- {
- /* Remove an ignored block. */
- ELEMENT *popped;
- popped = pop_element_from_contents (current);
- if (popped->cmd != end_cmd)
- fatal ("command mismatch for ignored block");
-
- /* Ignore until end of line */
- if (!strchr (line, '\n'))
- {
- line = new_line ();
- debug ("IGNORE CLOSE LINE");
- }
- destroy_element_and_children (popped);
+ debug ("CLOSED raw %s", command_name(end_cmd));
+ /* start a new line for the @end line (without the first spaces on
+ the line that have already been put in a raw container).
+ This is normally done at the beginning of a line, but not here,
+ as we directly got the line. As the @end is processed just below,
+ an empty line will not appear in the output, but it is needed to
+ avoid a duplicate warning on @end not appearing at the beginning
+ of the line */
+ e = new_element (ET_empty_line);
+ add_to_element_contents (current, e);
+ }
+ else /* save the line verbatim */
+ {
+ ELEMENT *e;
+ e = new_element (ET_raw);
+ text_append (&e->text, line);
+ add_to_element_contents (current, e);
- debug ("CLOSED conditional %s", command_name(end_cmd));
- retval = GET_A_NEW_LINE;
- goto funexit;
- }
- else
- {
- ELEMENT *e;
- int n;
+ retval = GET_A_NEW_LINE;
+ goto funexit;
+ }
+ } /********* BLOCK_raw *************/
+ /********* (ignored) BLOCK_conditional ******************/
+ else if (command_flags(current) & CF_block
+ && (command_data(current->cmd).data == BLOCK_conditional))
+ {
+ char *p = line;
- debug ("CLOSED raw %s", command_name(end_cmd));
- e = new_element (ET_empty_line_after_command);
- n = strspn (line, whitespace_chars_except_newline);
- text_append_n (&e->text, line, n);
- line += n;
+ /* check for nested @ifset (so that @end ifset doesn't end the
+ the outermost @ifset). It is discarded when the outermost is.*/
+ if (current->cmd == CM_ifclear || current->cmd == CM_ifset
+ || current->cmd == CM_ifcommanddefined
+ || current->cmd == CM_ifcommandnotdefined)
+ {
+ ELEMENT *e;
+ p += strspn (p, whitespace_chars);
+ if (*p == '@'
+ && !strncmp (p + 1, command_name(current->cmd),
+ strlen (command_name(current->cmd))))
+ {
+ e = new_element (ET_NONE);
+ e->cmd = current->cmd;
add_to_element_contents (current, e);
+ current = e;
+ retval = GET_A_NEW_LINE;
+ goto funexit;
}
}
- else /* save the line verbatim */
+
+ /* Else check if line is "@end ..." for current command. */
+ if (is_end_current_command (current, &line, &end_cmd))
{
- ELEMENT *last = last_contents_child (current);
- /* Append to existing element only if the text is all
- whitespace. */
- if (last && last->type == ET_empty_line_after_command
- && line[strspn (line, whitespace_chars)] == '\0'
- && !strchr (last->text.text, '\n'))
+ char *tmp = 0;
+ ELEMENT *popped;
+
+ /* check whitespaces at the beginning of the line */
+ if (strchr (whitespace_chars, *p))
{
- text_append (&last->text, line);
+ line_warn ("@end %s should only appear at the "
+ "beginning of a line", command_name(end_cmd));
}
- else
+
+ current = current->parent;
+
+ /* Remove an ignored block. */
+ popped = pop_element_from_contents (current);
+ if (popped->cmd != end_cmd)
+ fatal ("command mismatch for ignored block");
+
+ /* 'line' is now advanced past the "@end ...". Check if
+ there's anything after it. */
+ p = line + strspn (line, whitespace_chars);
+ if (*p && *p != '@')
+ goto superfluous_arg;
+ if (*p)
{
- ELEMENT *e;
- e = new_element (ET_raw);
- text_append (&e->text, line);
- add_to_element_contents (current, e);
+ p++;
+ tmp = read_command_name (&p);
+ if (tmp && (!strcmp (tmp, "c") || !strcmp (tmp, "comment")))
+ {
+ }
+ else if (*p && p[strspn (p, whitespace_chars)])
+ {
+superfluous_arg:
+ line_warn ("superfluous argument to @end %s: %s",
+ command_name(end_cmd), line);
+ }
+ free (tmp);
}
- retval = GET_A_NEW_LINE;
- goto funexit;
+ /* Ignore until end of line */
+ if (!strchr (line, '\n'))
+ {
+ line = new_line ();
+ debug ("IGNORE CLOSE LINE");
+ }
+ destroy_element_and_children (popped);
+
+ debug ("CLOSED conditional %s", command_name(end_cmd));
}
- } /********* BLOCK_raw or (ignored) BLOCK_conditional *************/
+ /* anything remaining on the line and any other line is ignored here */
+ retval = GET_A_NEW_LINE;
+ goto funexit;
+ } /********* (ignored) BLOCK_conditional *************/
/* Check if parent element is 'verb' */
else if (current->parent && current->parent->cmd == CM_verb)
@@ -1294,6 +1343,42 @@ superfluous_arg:
retval = GET_A_NEW_LINE; goto funexit; /* Get next line. */
}
} /* CM_verb */
+ else if (command_flags(current) & CF_block
+ && command_data(current->cmd).data == BLOCK_format_raw
+ && !format_expanded_p (command_name(current->cmd)))
+ {
+ ELEMENT *e;
+ enum command_id dummy;
+ char *line_dummy;
+ int n;
+
+ e = new_element (ET_elided_block);
+ add_to_element_contents (current, e);
+ line_dummy = line;
+ while (!is_end_current_command (current, &line_dummy,
+ &dummy))
+ {
+ line = new_line ();
+ if (!line)
+ {
+ line = "";
+ break;
+ }
+ line_dummy = line;
+ }
+
+ /* start a new line for the @end line, this is normally done
+ at the beginning of a line, but not here, as we directly
+ got the lines. */
+ e = new_element (ET_empty_line);
+ add_to_element_contents (current, e);
+
+ n = strspn (line, whitespace_chars_except_newline);
+ text_append_n (&e->text, line, n);
+ line += n;
+ /* It is important to let the processing continue from here, such that
+ the @end is catched and handled below, as the condition has not changed */
+ } /* ignored raw format */
/* Skip empty lines. If we reach the end of input, continue in case there
is an @include. */
@@ -1339,30 +1424,18 @@ superfluous_arg:
}
else
{
- char *command = read_command_name (&line_after_command);
+ command = read_command_name (&line_after_command);
cmd = 0;
if (command)
{
- ELEMENT *paragraph;
-
cmd = lookup_command (command);
- if (!cmd)
+ /* known command */
+ if (cmd)
{
- line_error ("unknown command `%s'", command);
- debug ("COMMAND (UNKNOWN) %s", command);
free (command);
-
- abort_empty_line (&current, 0);
- paragraph = begin_paragraph (current);
- if (paragraph)
- current = paragraph;
-
- line = line_after_command;
- retval = STILL_MORE_TO_PROCESS;
- goto funexit;
}
- free (command);
+ /* command holds the unknown command name if !cmd && command */
}
else
{
@@ -1374,7 +1447,7 @@ superfluous_arg:
cmd = command_data(cmd).data;
}
- /* Handle user-defined macros before anything else because their expansion
+ /* Handle user-defined macros before anything else because their expansion
may lead to changes in the line. */
if (cmd && (command_data(cmd).flags & CF_MACRO))
{
@@ -1384,112 +1457,188 @@ superfluous_arg:
free (allocated_line);
allocated_line = next_text ();
line = allocated_line;
+ retval = STILL_MORE_TO_PROCESS;
+ goto funexit;
}
-
- /* Cases that may "lead to command closing": brace commands that don't
- need a brace: accent commands.
- @definfoenclose. */
- /* This condition is only checked immediately after the command opening,
- otherwise the current element is in the 'args' and not right in the
- command container. */
- else if (command_flags(current) & CF_brace && *line != '{')
+ /* expand value if it actually expands and changes the line. It is
+ considered again together with other commands below for all the other cases
+ which may need a well formed tree, which is not needed nor available here,
+ and early value expansion may be needed to provide with an argument. */
+ else if (cmd == CM_value)
{
- if (command_with_command_as_argument (current->parent))
- {
- debug ("FOR PARENT @%s command_as_argument @%s",
- command_name(current->parent->parent->cmd),
- command_name(current->cmd));
- if (!current->type)
- current->type = ET_command_as_argument;
- add_extra_element (current->parent->parent,
- "command_as_argument", current);
- current = current->parent;
- }
- else if (command_flags(current) & CF_accent)
+ char *expanded_line = line_after_command;
+ if (conf.ignore_space_after_braced_command_name)
+ expanded_line += strspn (expanded_line, whitespace_chars);
+ if (*expanded_line == '{')
{
- if (strchr (whitespace_chars_except_newline, *line))
+ char *flag;
+
+ expanded_line++;
+ flag = read_flag_name (&expanded_line);
+ if (flag)
{
- if (isalpha (command_name(current->cmd)[0]))
- /* e.g. @dotaccent */
+ if (*expanded_line == '}')
{
- char *p; char *s;
- KEY_PAIR *k;
- p = line + strspn (line, whitespace_chars_except_newline);
- k = lookup_extra (current, "spaces");
- if (!k)
- {
- asprintf (&s, "%.*s", (int) (p - line), line);
- add_extra_string (current, "spaces", s);
- }
- else
+ char *value;
+ value = fetch_value (flag);
+
+ if (value)
{
- asprintf (&s, "%s%.*s",
- (char *) k->value,
- (int) (p - line), p);
- free (k->value);
- k->value = (ELEMENT *) s;
+ expanded_line++; /* past '}' */
+ input_push_text (strdup (expanded_line), current_source_info.macro);
+ input_push_text (strdup (value), current_source_info.macro);
+
+ /* Move 'line' to end of string so next input to
+ be processed is taken from input stack. */
+ line = expanded_line + strlen (expanded_line);
+ retval = STILL_MORE_TO_PROCESS;
}
- line = p;
- }
- else
- {
- line_warn ("accent command `@%s' must not be followed "
- "by whitespace", command_name(current->cmd));
- current = current->parent;
+ free (flag);
+ if (value)
+ goto funexit;
}
}
- else if (*line == '@')
- {
- line_error ("use braces to give a command as an argument "
- "to @%s", command_name(current->cmd));
- current = current->parent;
- }
- else if (*line != '\0' && *line != '\n' && *line != '\r')
- {
- ELEMENT *e, *e2;
- debug ("ACCENT");
- e = new_element (ET_following_arg);
- add_to_element_args (current, e);
- e2 = new_element (ET_NONE);
- text_append_n (&e2->text, line, 1);
- add_to_element_contents (e, e2);
-
- if (current->cmd == CM_dotless
- && *line != 'i' && *line != 'j')
- {
- line_error ("@dotless expects `i' or `j' as argument, "
- "not `%c'", *line);
- }
- if (isalpha (command_name(current->cmd)[0]))
- e->type = ET_space_command_arg;
- while (current->contents.number > 0)
- destroy_element (pop_element_from_contents (current));
- line++;
- current = current->parent;
- }
- else
+ }
+ }
+
+ /* special case for @-command as argument of @itemize or @*table.
+ The normal case for those are to be identifier only, not a true command
+ with argument, so can be followed by anything. If followed by
+ braces, will be handled as a normal brace command.
+
+ Need to be done as early as possible such that no other condition
+ prevail and lead to a missed command */
+ if (command_flags(current) & CF_brace && *line != '{'
+ && parent_of_command_as_argument (current->parent))
+ {
+ register_command_as_argument (current);
+ current = current->parent;
+ }
+
+ /* command but before an opening brace, otherwise current
+ would be an argument type and not the command, and a new
+ @-command was found. This means that the current->cmd
+ argument (an opening brace, or a character after spaces for
+ accent commands) was not found and there is already a new command.
+
+ It would have been nice to allow for comments, but there is no
+ container in the tree to put them when after command and before brace
+ or argument for accent commands. */
+
+ if (command_flags(current) & CF_brace && (cmd || command))
+ {
+ line_error ("@%s expected braces",
+ command_name(current->cmd));
+ current = current->parent;
+ }
+
+ /* Handle unknown command. */
+ if (!cmd && command)
+ {
+ ELEMENT *paragraph;
+
+ line_error ("unknown command `%s'", command);
+ debug ("COMMAND (UNKNOWN) %s", command);
+ free (command);
+ abort_empty_line (&current, 0);
+ paragraph = begin_paragraph (current);
+ if (paragraph)
+ current = paragraph;
+
+ line = line_after_command;
+ retval = STILL_MORE_TO_PROCESS;
+ goto funexit;
+ }
+
+ /* Brace commands not followed immediately by a brace
+ opening. In particular cases that may lead to "command closing"
+ or following character association with an @-command, for accent
+ commands */
+ /* This condition can only happen immediately after the command opening,
+ otherwise the current element is in the 'args' and not right in the
+ command container. */
+ if (command_flags(current) & CF_brace && *line != '{')
+ {
+ if (strchr (whitespace_chars, *line)
+ && ((command_flags(current) & CF_accent)
+ || conf.ignore_space_after_braced_command_name))
+ {
+ char *p; char *s;
+ int whitespaces_len;
+ int additional_newline = 0;
+ KEY_PAIR *k;
+ whitespaces_len = strspn (line, whitespace_chars);
+
+ for (int i = 0; i < whitespaces_len; i++)
+ {
+ if (*(line + i) == '\n')
+ {
+ line_warn ("command `@%s' must not be followed by new line",
+ command_name(current->cmd));
+ additional_newline = 1;
+ break;
+ }
+ }
+
+ k = lookup_extra (current, "spaces");
+ if (!k)
+ {
+ p = line + whitespaces_len;
+ xasprintf (&s, "%.*s", (int) (p - line), line);
+ add_extra_string (current, "spaces", s);
+ line = p;
+ }
+ else
+ {
+ /* only ignore spaces and one newline, two newlines lead to
+ an empty line before the brace or argument which is incorrect. */
+ char *previous_value = (char *) k->value;
+ if (additional_newline && strchr ("\n", *previous_value))
+ {
+ line_error ("@%s expected braces",
+ command_name(current->cmd));
+ current = current->parent;
+ }
+ else
+ {
+ p = line + whitespaces_len;
+ xasprintf (&s, "%s%.*s",
+ previous_value,
+ (int) (p - line), line);
+ free (k->value);
+ k->value = (ELEMENT *) s;
+ line = p;
+ }
+ }
+ }
+ /* special case for accent commands, use following character except @
+ * as argument */
+ else if ((command_flags(current) & CF_accent)
+ && *line != '\0' && *line != '@')
+ {
+ ELEMENT *e, *e2;
+ debug ("ACCENT");
+ e = new_element (ET_following_arg);
+ add_to_element_args (current, e);
+ e2 = new_element (ET_NONE);
+ text_append_n (&e2->text, line, 1);
+ add_to_element_contents (e, e2);
+
+ if (current->cmd == CM_dotless
+ && *line != 'i' && *line != 'j')
{
- debug ("STRANGE ACC");
- line_warn ("accent command `@%s' must not be followed by "
- "new line", command_name(current->cmd));
- current = current->parent;
+ line_error ("@dotless expects `i' or `j' as argument, "
+ "not `%c'", *line);
}
- goto funexit;
+ while (current->contents.number > 0)
+ destroy_element (pop_element_from_contents (current));
+ line++;
+ current = current->parent;
}
else
{
- if (conf.ignore_space_after_braced_command_name)
- {
- char *p;
- p = line + strspn (line, whitespace_chars);
- if (p != line)
- {
- line = p;
- goto funexit;
- }
- }
line_error ("@%s expected braces",
- command_name(current->cmd));
+ command_name(current->cmd));
current = current->parent;
}
}
@@ -1505,12 +1654,13 @@ superfluous_arg:
line = line_after_command;
debug ("COMMAND %s", command_name(cmd));
- /* @value */
- if (cmd == CM_value)
+ /* @value not expanded (expansion is done above), and @txiinternalvalue */
+ if ((cmd == CM_value) || (cmd == CM_txiinternalvalue))
{
char *arg_start;
char *flag;
- line += strspn (line, whitespace_chars);
+ if (conf.ignore_space_after_braced_command_name)
+ line += strspn (line, whitespace_chars);
if (*line != '{')
goto value_invalid;
@@ -1530,51 +1680,64 @@ superfluous_arg:
{
char *value;
value_valid:
- value = fetch_value (flag);
- if (!value)
+ if (cmd == CM_value)
{
- /* Add element for unexpanded @value.
- This is not necessarily an error - in
- Texinfo::Report::gdt we deliberately pass
- in undefined values. */
- ELEMENT *value_elt;
-
- line_warn ("undefined flag: %s", flag);
- /* Note: In the Perl code, this warning is conditional on
- in_gdt setting, but the only effect that this possibly has
- is on speed, as these warnings would not be printed to the
- user. */
+ value = fetch_value (flag);
+ if (!value)
+ {
+ /* Add element for unexpanded @value.
+ This should be an error, but still leave a tree element
+ for the converters to handle */
+ ELEMENT *value_elt;
- abort_empty_line (&current, NULL);
- value_elt = new_element (ET_NONE);
- value_elt->cmd = CM_value;
- text_append (&value_elt->text, flag);
+ line_warn ("undefined flag: %s", flag);
- /* In the Perl code, the name of the flag is stored in
- the "type" field. We need to store in 'text' instead
- and then output it as the type in
- dump_perl.c / api.c. */
+ abort_empty_line (&current, NULL);
+ value_elt = new_element (ET_NONE);
+ value_elt->cmd = CM_value;
+ add_extra_string_dup (value_elt, "flag", flag);
- add_to_element_contents (current, value_elt);
+ add_to_element_contents (current, value_elt);
- line++; /* past '}' */
- retval = STILL_MORE_TO_PROCESS;
+ line++; /* past '}' */
+ retval = STILL_MORE_TO_PROCESS;
+ }
+ /* expansion of value already done above
+ else
+ {
+ value is set
+ }
+ */
+ free (flag);
+ goto funexit;
}
else
- {
+ { /* CM_txiinternalvalue */
+ ELEMENT *txiinternalvalue_elt, *txiinternalvalue_arg;
+
+ abort_empty_line (&current, NULL);
+ txiinternalvalue_elt = new_element (ET_NONE);
+ txiinternalvalue_elt->cmd = CM_txiinternalvalue;
+
+ /* FIXME or ET_misc_arg? */
+ txiinternalvalue_arg = new_element (ET_NONE);
+
+ text_append (&txiinternalvalue_arg->text, flag);
+ add_to_element_args (txiinternalvalue_elt, txiinternalvalue_arg);
+
+ add_to_element_contents (current, txiinternalvalue_elt);
+
line++; /* past '}' */
- input_push_text (strdup (line), line_nr.macro);
- input_push_text (strdup (value), line_nr.macro);
- line += strlen (line);
retval = STILL_MORE_TO_PROCESS;
+
+ free (flag);
+ goto funexit;
}
- free (flag);
- goto funexit;
}
else
{
value_invalid:
- line_error ("bad syntax for @value");
+ line_error ("bad syntax for @%s", command_name(cmd));
retval = STILL_MORE_TO_PROCESS;
goto funexit;
}
@@ -1591,7 +1754,7 @@ value_invalid:
break;
}
if (!msg)
- line_warn ("@%s is obsolete.", command_name(cmd));
+ line_warn ("@%s is obsolete", command_name(cmd));
else
line_warn ("@%s is obsolete; %s", command_name(cmd), msg);
/* note: will have to translate msg if string translation with
@@ -1633,7 +1796,12 @@ value_invalid:
/* check command doesn't start a paragraph */
/* TODO store this in cmd->flags. */
- if (!(command_data(cmd).flags & (CF_line | CF_other | CF_block)
+ if (!((command_data(cmd).flags & (CF_line | CF_block))
+ || (command_data(cmd).flags & CF_nobrace
+ && (command_data(cmd).data == NOBRACE_skipspace
+ /* FIXME NOBRACE_other should probably start a paragraph
+ except for refill */
+ || command_data(cmd).data == NOBRACE_other))
|| cmd == CM_titlefont
|| cmd == CM_caption
|| cmd == CM_shortcaption
@@ -1652,7 +1820,7 @@ value_invalid:
if (cmd)
{
- if (close_paragraph_command (cmd))
+ if (command_data(cmd).flags & CF_close_paragraph)
current = end_paragraph (current, 0, 0);
if (close_preformatted_command (cmd))
current = end_preformatted (current, 0, 0);
@@ -1663,16 +1831,33 @@ value_invalid:
|| cmd == CM_seealso
|| cmd == CM_subentry)
&& current->contents.number > 0
- && last_contents_child(current)->text.end > 0)
+ && last_contents_child(current)->text.end > 0
+ /* it is important to check if in an index command, as otherwise
+ the internal space type is not processed and remains as is in
+ the final tree. */
+ && (command_flags(current->parent) & CF_index_entry_command
+ || current->parent->cmd == CM_subentry))
{
- isolate_trailing_space (current, ET_empty_spaces_before_argument);
+ if (cmd == CM_subentry)
+ {
+ isolate_trailing_space (current, ET_spaces_at_end);
+ }
+ else
+ /* an internal and temporary space type that is converted to
+ a normal space without type if followed by text or a
+ "spaces_at_end" if followed by spaces only when the
+ index or subentry command is done. */
+ {
+ isolate_trailing_space (current, ET_internal_spaces_before_brace_in_index);
+ }
}
if (cmd == CM_item && item_line_parent (current))
cmd = CM_item_LINE;
/* We could possibly have done this before check_valid_nesting. */
- if (command_data(cmd).flags & CF_other)
+ /* No-brace command */
+ if (command_data(cmd).flags & CF_nobrace)
{
int status;
current = handle_other_command (current, &line, cmd, &status);
@@ -1708,26 +1893,6 @@ value_invalid:
{
current = handle_brace_command (current, &line, cmd);
}
- /* No-brace command */
- else if (command_data(cmd).flags & CF_nobrace)
- {
- ELEMENT *nobrace;
-
- nobrace = new_element (ET_NONE);
- nobrace->cmd = cmd;
- add_to_element_contents (current, nobrace);
-
- if (cmd == CM_BACKSLASH && current_context () != ct_math)
- {
- line_warn ("@\\ should only appear in math context");
- }
- if (cmd == CM_NEWLINE)
- {
- current = end_line (current);
- retval = GET_A_NEW_LINE;
- goto funexit;
- }
- }
}
/* "Separator" character */
else if (*line != '\0' && strchr ("{}@,:\t.\f", *line))
@@ -1811,8 +1976,8 @@ check_line_directive (char *line)
return 0;
/* Check input is coming directly from a file. */
- if (!line_nr.file_name || !line_nr.file_name
- || (line_nr.macro && *line_nr.macro))
+ if (!current_source_info.file_name || !current_source_info.file_name
+ || (current_source_info.macro && *current_source_info.macro))
return 0;
p += strspn (p, " \t");
@@ -1859,11 +2024,12 @@ check_line_directive (char *line)
return 1;
}
-/* Pass in and return root of a "Texinfo tree". */
+/* Pass in and return root of a "Texinfo tree". Starting point for adding
+ to the tree is current_elt */
ELEMENT *
-parse_texi (ELEMENT *root_elt)
+parse_texi (ELEMENT *root_elt, ELEMENT *current_elt)
{
- ELEMENT *current = root_elt;
+ ELEMENT *current = current_elt;
static char *allocated_line;
char *line;
@@ -1877,13 +2043,16 @@ parse_texi (ELEMENT *root_elt)
debug_nonl ("NEW LINE %s", line);
- /* If not in 'raw' or 'conditional' and parent isn't a 'verb', collect
+ /* If not in 'raw' or 'conditional' and parent isn't a 'verb',
+ and not an ignored raw format, collect
leading whitespace and save as an "ET_empty_line" element. This
element type can be changed in 'abort_empty_line' when more text is
read. */
- if (!((command_flags(current) & CF_block)
- && (command_data(current->cmd).data == BLOCK_raw
- || command_data(current->cmd).data == BLOCK_conditional)
+ if (!(((command_flags(current) & CF_block)
+ && ((command_data(current->cmd).data == BLOCK_raw
+ || command_data(current->cmd).data == BLOCK_conditional)
+ || (command_data(current->cmd).data == BLOCK_format_raw
+ && !format_expanded_p (command_name(current->cmd)))))
|| current->parent && current->parent->cmd == CM_verb)
&& current_context () != ct_def)
{
@@ -1897,7 +2066,7 @@ parse_texi (ELEMENT *root_elt)
if (current->contents.number > 0
&& last_contents_child(current)->type
- == ET_empty_spaces_before_argument)
+ == ET_internal_spaces_before_argument)
{
/* Remove this element and update 'extra' values. */
abort_empty_line (&current, 0);
@@ -1921,7 +2090,10 @@ parse_texi (ELEMENT *root_elt)
if (status == FINISHED_TOTALLY)
goto finished_totally;
if (!line)
- break;
+ {
+ current = end_line (current);
+ break;
+ }
}
}
finished_totally:
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.h
index 9cc2f240b4..7303a53357 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/parser.h
@@ -35,7 +35,6 @@ typedef struct GLOBAL_INFO {
char *input_encoding_name;
char *input_perl_encoding;
int sections_level;
- int novalidate;
ELEMENT dircategory_direntry; /* an array of elements */
/* Elements that should be unique. */
@@ -63,6 +62,13 @@ typedef struct GLOBAL_INFO {
ELEMENT *evenfootingmarks;
ELEMENT *oddfootingmarks;
ELEMENT *shorttitlepage;
+ ELEMENT *novalidate;
+ ELEMENT *afourpaper;
+ ELEMENT *afourlatex;
+ ELEMENT *afourwide;
+ ELEMENT *afivepaper;
+ ELEMENT *bsixpaper;
+ ELEMENT *smallbook;
/* Arrays of elements */
ELEMENT footnotes;
@@ -88,22 +94,26 @@ typedef struct GLOBAL_INFO {
ELEMENT frenchspacing;
ELEMENT headings;
ELEMENT kbdinputstyle;
+ ELEMENT microtype;
ELEMENT paragraphindent;
ELEMENT shortcontents;
ELEMENT urefbreakstyle;
ELEMENT xrefautomaticsectiontitle;
+
+ /* Ignored characters for index sort key */
+ IGNORED_CHARS ignored_chars;
} GLOBAL_INFO;
/* In close.c */
void close_command_cleanup (ELEMENT *current);
-ELEMENT *close_commands (ELEMENT *current, enum command_id closed_command,
+ELEMENT *close_commands (ELEMENT *current, enum command_id closed_block_command,
ELEMENT **closed_element, enum command_id);
ELEMENT *close_all_style_commands (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command);
ELEMENT *close_current (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command);
/* In end_line.c */
@@ -132,20 +142,22 @@ ELEMENT *handle_separator (ELEMENT *current, char separator,
char **line_inout);
/* In parser.c */
-ELEMENT *parse_texi (ELEMENT *root_elt);
+ELEMENT *parse_texi (ELEMENT *root_elt, ELEMENT *current_elt);
void push_conditional_stack (enum command_id cond);
enum command_id pop_conditional_stack (void);
extern size_t conditional_number;
-ELEMENT *parse_texi_file (char *filename);
+ELEMENT *parse_texi_document (void);
int abort_empty_line (ELEMENT **current_inout, char *additional);
ELEMENT *end_paragraph (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command);
void isolate_last_space (ELEMENT *current);
-int command_with_command_as_argument (ELEMENT *current);
+int kbd_formatted_as_code (ELEMENT *current);
+int parent_of_command_as_argument (ELEMENT *current);
+void register_command_as_argument (ELEMENT *cmd_as_arg);
ELEMENT *begin_preformatted (ELEMENT *current);
ELEMENT *end_preformatted (ELEMENT *current,
- enum command_id closed_command,
+ enum command_id closed_block_command,
enum command_id interrupting_command);
char *read_command_name (char **ptr);
char *read_flag_name (char **ptr);
@@ -157,8 +169,10 @@ int format_expanded_p (char *format);
int is_end_current_command (ELEMENT *current, char **line,
enum command_id *end_cmd);
void set_documentlanguage (char *);
-void set_novalidate (int value);
+void set_documentlanguage_override (char *value);
+void set_accept_internalvalue (void);
char *element_type_name (ELEMENT *e);
+int check_space_element (ELEMENT *e);
/* Return values */
#define GET_A_NEW_LINE 0
@@ -176,6 +190,8 @@ extern ELEMENT *current_part;
extern GLOBAL_INFO global_info;
extern char *global_clickstyle;
extern char *global_documentlanguage;
+extern int global_documentlanguage_fixed;
+extern int global_accept_internalvalue;
enum kbd_enum {kbd_none, kbd_code, kbd_example, kbd_distinct };
extern enum kbd_enum global_kbdinputstyle;
@@ -185,6 +201,8 @@ void wipe_global_info (void);
extern COUNTER count_remaining_args, count_items, count_cells;
+ELEMENT *setup_document_root_and_before_node_section (void);
+
/* In multitable.c */
ELEMENT *item_line_parent (ELEMENT *current);
ELEMENT *item_multitable_parent (ELEMENT *current);
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/separator.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/separator.c
index b509de3d6a..dd1c49b60a 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/separator.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/separator.c
@@ -37,7 +37,7 @@ handle_open_brace (ELEMENT *current, char **line_inout)
command = current->cmd;
counter_push (&count_remaining_args, current,
- command_data(current->cmd).data);
+ command_data(current->cmd).args_number);
counter_dec (&count_remaining_args);
arg = new_element (ET_NONE);
@@ -105,16 +105,16 @@ handle_open_brace (ELEMENT *current, char **line_inout)
switch (command)
{
case CM_footnote:
- push_context (ct_footnote);
+ push_context (ct_brace_command, command);
break;
case CM_caption:
- push_context (ct_caption);
+ push_context (ct_brace_command, command);
break;
case CM_shortcaption:
- push_context (ct_shortcaption);
+ push_context (ct_brace_command, command);
break;
case CM_math:
- push_context (ct_math);
+ push_context (ct_math, command);
break;
default:
fatal ("no context for command");
@@ -124,10 +124,10 @@ handle_open_brace (ELEMENT *current, char **line_inout)
ELEMENT *e;
int n;
n = strspn (line, whitespace_chars_except_newline);
- e = new_element (ET_empty_spaces_before_argument);
+ e = new_element (ET_internal_spaces_before_argument);
text_append_n (&e->text, line, n);
add_to_element_contents (current, e);
- add_extra_element (e, "command", current->parent);
+ add_extra_element (e, "spaces_associated_command", current->parent);
line += n;
}
current->type = ET_brace_command_context;
@@ -136,19 +136,19 @@ handle_open_brace (ELEMENT *current, char **line_inout)
{
current->type = ET_brace_command_arg;
- /* Commands which are said to take a positive number of arguments
- disregard leading and trailing whitespace. */
- if (command_data(command).data > 0)
+ /* Commands that disregard leading whitespace. */
+ if (command_data(command).data == BRACE_arguments
+ || command_data(command).data == BRACE_inline)
{
ELEMENT *e;
- e = new_element (ET_empty_spaces_before_argument);
+ e = new_element (ET_internal_spaces_before_argument);
/* See comment in parser.c:merge_text */
text_append (&e->text, "");
add_to_element_contents (current, e);
- add_extra_element (e, "command", current);
+ add_extra_element (e, "spaces_associated_command", current);
if (command == CM_inlineraw)
- push_context (ct_inlineraw);
+ push_context (ct_inlineraw, command);
}
}
debug ("OPENED");
@@ -164,13 +164,13 @@ handle_open_brace (ELEMENT *current, char **line_inout)
/* We need the line number here in case @ protects the
end of the line. */
if (current->parent->parent->type == ET_def_line)
- current->line_nr = line_nr;
+ current->source_info = current_source_info;
- e = new_element (ET_empty_spaces_before_argument);
+ e = new_element (ET_internal_spaces_before_argument);
text_append (&e->text, ""); /* See comment in parser.c:merge_text */
add_to_element_contents (current, e);
debug ("BRACKETED in def/multitable");
- add_extra_element (e, "command", current);
+ add_extra_element (e, "spaces_associated_command", current);
}
else if (current->type == ET_rawpreformatted)
{
@@ -183,7 +183,7 @@ handle_open_brace (ELEMENT *current, char **line_inout)
|| current_context() == ct_inlineraw)
{
ELEMENT *b = new_element (ET_bracketed);
- b->line_nr = line_nr;
+ b->source_info = current_source_info;
add_to_element_contents (current, b);
current = b;
debug ("BRACKETED in math");
@@ -193,7 +193,7 @@ handle_open_brace (ELEMENT *current, char **line_inout)
line_error ("misplaced {");
if (current->contents.number > 0
&& last_contents_child(current)->type
- == ET_empty_spaces_before_argument)
+ == ET_internal_spaces_before_argument)
{
/* FIXME: Is this right? */
remove_from_contents (current, 0);
@@ -207,9 +207,6 @@ handle_open_brace (ELEMENT *current, char **line_inout)
/* Return 1 if an element is all whitespace.
Note that this function isn't completely reliable because it
doesn't look deep into the element tree.
- In the perl code it calls
- Texinfo::Convert::NodeNameNormalization::normalize_node,
- and checks that the result isn't all hyphens.
*/
int
check_empty_expansion (ELEMENT *e)
@@ -218,19 +215,7 @@ check_empty_expansion (ELEMENT *e)
for (i = 0; i < e->contents.number; i++)
{
ELEMENT *f = e->contents.list[i];
- if (!(
- f->cmd == CM_SPACE
- || f->cmd == CM_TAB
- || f->cmd == CM_NEWLINE
- || f->cmd == CM_c
- || f->cmd == CM_comment
- || f->cmd == CM_COLON
- || f->type == ET_empty_spaces_before_argument
- || f->type == ET_spaces_at_end
- || (!f->cmd && !f->type && f->text.end == 0)
- || (f->text.end > 0
- && !*(f->text.text + strspn (f->text.text, whitespace_chars)))
- ))
+ if (!check_space_element(f))
{
return 0;
}
@@ -256,15 +241,18 @@ handle_close_brace (ELEMENT *current, char **line_inout)
enum command_id closed_command;
if (command_data(current->parent->cmd).data == BRACE_context)
{
- (void) pop_context ();
- /* The Perl code here checks that the popped context and the
- parent command match as strings. */
+ if (current->parent->cmd == CM_math)
+ {
+ if (pop_context () != ct_math)
+ fatal ("math context expected");
+ }
+ else if (pop_context () != ct_brace_command)
+ fatal ("context brace command context expected");
}
- else if (command_data(current->parent->cmd).data > 0)
+ /* determine if trailing spaces are ignored */
+ else if (command_data(current->parent->cmd).data == BRACE_arguments)
{
- /* @inline* always have end spaces considered as normal text */
- if (!(command_flags(current->parent) & CF_inline))
- isolate_last_space (current);
+ isolate_last_space (current);
}
closed_command = current->parent->cmd;
@@ -272,14 +260,14 @@ handle_close_brace (ELEMENT *current, char **line_inout)
counter_pop (&count_remaining_args);
if (current->contents.number > 0
- && command_data(closed_command).data == 0)
+ && command_data(closed_command).data == BRACE_noarg)
line_warn ("command @%s does not accept arguments",
command_name(closed_command));
if (closed_command == CM_anchor)
{
NODE_SPEC_EXTRA *parsed_anchor;
- current->parent->line_nr = line_nr;
+ current->parent->source_info = current_source_info;
parsed_anchor = parse_node_manual (current);
if (check_node_label (parsed_anchor, CM_anchor))
{
@@ -398,14 +386,14 @@ handle_close_brace (ELEMENT *current, char **line_inout)
}
}
}
- else if ((command_data(closed_command).flags & CF_inline)
+ else if ((command_data(closed_command).data == BRACE_inline)
|| closed_command == CM_abbr
|| closed_command == CM_acronym)
{
if (current->parent->cmd == CM_inlineraw)
{
if (ct_inlineraw != pop_context ())
- fatal ("expected inlineraw context");
+ fatal ("inlineraw context expected");
}
if (current->parent->args.number == 0
|| current->parent->args.list[0]->contents.number == 0)
@@ -459,14 +447,10 @@ handle_close_brace (ELEMENT *current, char **line_inout)
}
}
- else if (command_with_command_as_argument (current->parent->parent)
+ else if (parent_of_command_as_argument (current->parent->parent)
&& current->contents.number == 0)
{
- debug ("FOR PARENT ... command_as_argument_braces ...");
- if (!current->parent->type)
- current->parent->type = ET_command_as_argument;
- add_extra_element (current->parent->parent->parent,
- "command_as_argument", current->parent);
+ register_command_as_argument (current->parent);
}
else if (current->parent->cmd == CM_sortas
|| current->parent->cmd == CM_seeentry
@@ -510,7 +494,7 @@ handle_close_brace (ELEMENT *current, char **line_inout)
|| current->parent->cmd == CM_seealso)
{
ELEMENT *e;
- e = new_element (ET_empty_spaces_after_close_brace);
+ e = new_element (ET_spaces_after_close_brace);
text_append (&e->text, "");
add_to_element_contents (current->parent->parent, e);
}
@@ -528,10 +512,7 @@ handle_close_brace (ELEMENT *current, char **line_inout)
goto funexit;
}
/* context brace command (e.g. @footnote) when there is a paragraph inside */
- else if (current_context() == ct_footnote
- || current_context() == ct_caption
- || current_context() == ct_shortcaption
- || current_context() == ct_math)
+ else if (current_context() == ct_brace_command)
{
current = end_paragraph (current, 0, 0);
if (current->parent
@@ -539,7 +520,8 @@ handle_close_brace (ELEMENT *current, char **line_inout)
&& (command_data(current->parent->cmd).data == BRACE_context))
{
enum command_id closed_command;
- (void) pop_context ();
+ if (pop_context () != ct_brace_command)
+ fatal ("context brace command context expected");
debug ("CLOSING(context command)");
closed_command = current->parent->cmd;
counter_pop (&count_remaining_args);
@@ -576,7 +558,7 @@ handle_comma (ELEMENT *current, char **line_inout)
type = current->type;
current = current->parent;
- if (command_flags(current) & CF_inline)
+ if (command_data(current->cmd).data == BRACE_inline)
{
KEY_PAIR *k;
int expandp = 0;
@@ -729,10 +711,10 @@ inlinefmtifelse_done:
new_arg = new_element (type);
add_to_element_args (current, new_arg);
current = new_arg;
- e = new_element (ET_empty_spaces_before_argument);
+ e = new_element (ET_internal_spaces_before_argument);
text_append (&e->text, ""); /* See comment in parser.c:merge_text */
add_to_element_contents (current, e);
- add_extra_element (e, "command", current);
+ add_extra_element (e, "spaces_associated_command", current);
funexit:
*line_inout = line;
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/text.c b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/text.c
index 224464f529..7427560c5f 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/text.c
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/text.c
@@ -1,4 +1,4 @@
-/* Copyright 2014-2021 Free Software Foundation, Inc.
+/* Copyright 2014-2022 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,8 +31,6 @@ text_alloc (TEXT *t, size_t len)
t->space = t->end + len;
if (t->space < 10)
t->space = 10;
- /* This makes a huge difference under Valgrind, is not noticable
- otherwise. */
t->space *= 2;
t->text = realloc (t->text, t->space);
if (!t->text)
@@ -47,7 +45,7 @@ text_printf (TEXT *t, char *format, ...)
char *s;
va_start (v, format);
- vasprintf (&s, format, v);
+ xvasprintf (&s, format, v);
text_append (t, s);
free (s);
va_end (v);
diff --git a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/tree_types.h b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/tree_types.h
index 3f9f78209f..66e84cf956 100644
--- a/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/tree_types.h
+++ b/macros/texinfo/texinfo/tp/Texinfo/XS/parsetexi/tree_types.h
@@ -52,11 +52,11 @@ typedef struct ELEMENT_LIST {
size_t space;
} ELEMENT_LIST;
-typedef struct LINE_NR {
+typedef struct SOURCE_INFO {
int line_nr;
char *file_name;
char *macro;
-} LINE_NR;
+} SOURCE_INFO;
typedef struct ELEMENT {
enum command_id cmd;
@@ -65,7 +65,7 @@ typedef struct ELEMENT {
ELEMENT_LIST args;
ELEMENT_LIST contents;
struct ELEMENT *parent;
- LINE_NR line_nr;
+ SOURCE_INFO source_info;
KEY_PAIR *extra;
size_t extra_number;
@@ -77,6 +77,13 @@ typedef struct ELEMENT {
everywhere; */
} ELEMENT;
+typedef struct IGNORED_CHARS {
+ int backslash;
+ int hyphen;
+ int lessthan;
+ int atsign;
+} IGNORED_CHARS;
+
typedef struct {
char *index_name;
char *index_prefix;
@@ -90,6 +97,7 @@ typedef struct {
int number; /* Index of entry in containing index, 1-based. */
ELEMENT *region;
char *sortas; /* the sort key for the index */
+ IGNORED_CHARS ignored_chars;
} INDEX_ENTRY;
typedef struct INDEX {