From 55ef65a416ec06655b463f61ec0658938e0042a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=C3=A1=C5=A1=20Dujava?= <19737748+jdujava@users.noreply.github.com> Date: Sun, 21 Jul 2024 08:52:18 +0200 Subject: [PATCH] Properly support definition commands from xparse (#148) Additionally, handle command definition without curly braces around the defined command name. Signed-off-by: Jonas Dujava --- grammar.js | 58 +++++++-- src/grammar.json | 255 ++++++++++++++++++++++++++++++++------- src/node-types.json | 219 +++++++++++++++++++++++++++++++++ test/corpus/commands.txt | 61 ++++++++++ 4 files changed, 540 insertions(+), 53 deletions(-) diff --git a/grammar.js b/grammar.js index e0b0e7aa1..7410ee2fa 100644 --- a/grammar.js +++ b/grammar.js @@ -322,6 +322,9 @@ module.exports = grammar({ curly_group_text: $ => seq('{', field('text', $.text), '}'), + curly_group_spec: $ => + seq('{', repeat(choice($._text_content, '=')), '}'), + curly_group_text_list: $ => seq('{', sepBy(field('text', $.text), ','), '}'), @@ -871,6 +874,9 @@ module.exports = grammar({ ), new_command_definition: $ => + choice($._new_command_definition, $._newer_command_definition), + + _new_command_definition: $ => seq( field( 'command', @@ -879,21 +885,15 @@ module.exports = grammar({ '\\newcommand*', '\\renewcommand', '\\renewcommand*', + '\\providecommand', + '\\providecommand*', '\\DeclareRobustCommand', '\\DeclareRobustCommand*', '\\DeclareMathOperator', '\\DeclareMathOperator*', - '\\NewDocumentCommand', - '\\RenewDocumentCommand', - '\\ProvideDocumentCommand', - '\\DeclareDocumentCommand', - '\\NewExpandableDocumentCommand', - '\\RenewExpandableDocumentCommand', - '\\ProvideExpandableDocumentCommand', - '\\DeclareExpandableDocumentCommand', ), ), - field('declaration', $.curly_group_command_name), + field('declaration', choice($.curly_group_command_name, $.command_name)), optional( seq( field('argc', $.brack_group_argc), @@ -903,6 +903,28 @@ module.exports = grammar({ field('implementation', $.curly_group), ), + _newer_command_definition: $ => + prec.right( + seq( + field( + 'command', + choice( + '\\NewDocumentCommand', + '\\RenewDocumentCommand', + '\\ProvideDocumentCommand', + '\\DeclareDocumentCommand', + '\\NewExpandableDocumentCommand', + '\\RenewExpandableDocumentCommand', + '\\ProvideExpandableDocumentCommand', + '\\DeclareExpandableDocumentCommand', + ), + ), + field('declaration', choice($.curly_group_command_name, $.command_name)), + field('spec', $.curly_group_spec), + field('implementation', $.curly_group), + ), + ), + old_command_definition: $ => seq(field('command', '\\def'), field('declaration', $.command_name)), @@ -950,12 +972,28 @@ module.exports = grammar({ ), environment_definition: $ => + choice($._environment_definition, $._newer_environment_definition), + + _environment_definition: $ => seq( field( 'command', choice( '\\newenvironment', '\\renewenvironment', + ), + ), + field('name', $.curly_group_text), + field('argc', optional($.brack_group_argc)), + field('begin', $.curly_group_impl), + field('end', $.curly_group_impl), + ), + + _newer_environment_definition: $ => + seq( + field( + 'command', + choice( '\\NewDocumentEnvironment', '\\RenewDocumentEnvironment', '\\ProvideDocumentEnvironment', @@ -963,7 +1001,7 @@ module.exports = grammar({ ), ), field('name', $.curly_group_text), - field('argc', optional($.brack_group_argc)), + field('spec', $.curly_group_spec), field('begin', $.curly_group_impl), field('end', $.curly_group_impl), ), diff --git a/src/grammar.json b/src/grammar.json index 4d8853427..04b55c0ac 100644 --- a/src/grammar.json +++ b/src/grammar.json @@ -1139,6 +1139,35 @@ } ] }, + "curly_group_spec": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "{" + }, + { + "type": "REPEAT", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_text_content" + }, + { + "type": "STRING", + "value": "=" + } + ] + } + }, + { + "type": "STRING", + "value": "}" + } + ] + }, "curly_group_text_list": { "type": "SEQ", "members": [ @@ -5081,6 +5110,19 @@ ] }, "new_command_definition": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_new_command_definition" + }, + { + "type": "SYMBOL", + "name": "_newer_command_definition" + } + ] + }, + "_new_command_definition": { "type": "SEQ", "members": [ { @@ -5107,51 +5149,27 @@ }, { "type": "STRING", - "value": "\\DeclareRobustCommand" - }, - { - "type": "STRING", - "value": "\\DeclareRobustCommand*" - }, - { - "type": "STRING", - "value": "\\DeclareMathOperator" - }, - { - "type": "STRING", - "value": "\\DeclareMathOperator*" - }, - { - "type": "STRING", - "value": "\\NewDocumentCommand" - }, - { - "type": "STRING", - "value": "\\RenewDocumentCommand" + "value": "\\providecommand" }, { "type": "STRING", - "value": "\\ProvideDocumentCommand" + "value": "\\providecommand*" }, { "type": "STRING", - "value": "\\DeclareDocumentCommand" - }, - { - "type": "STRING", - "value": "\\NewExpandableDocumentCommand" + "value": "\\DeclareRobustCommand" }, { "type": "STRING", - "value": "\\RenewExpandableDocumentCommand" + "value": "\\DeclareRobustCommand*" }, { "type": "STRING", - "value": "\\ProvideExpandableDocumentCommand" + "value": "\\DeclareMathOperator" }, { "type": "STRING", - "value": "\\DeclareExpandableDocumentCommand" + "value": "\\DeclareMathOperator*" } ] } @@ -5160,8 +5178,17 @@ "type": "FIELD", "name": "declaration", "content": { - "type": "SYMBOL", - "name": "curly_group_command_name" + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "curly_group_command_name" + }, + { + "type": "SYMBOL", + "name": "command_name" + } + ] } }, { @@ -5211,6 +5238,89 @@ } ] }, + "_newer_command_definition": { + "type": "PREC_RIGHT", + "value": 0, + "content": { + "type": "SEQ", + "members": [ + { + "type": "FIELD", + "name": "command", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "STRING", + "value": "\\NewDocumentCommand" + }, + { + "type": "STRING", + "value": "\\RenewDocumentCommand" + }, + { + "type": "STRING", + "value": "\\ProvideDocumentCommand" + }, + { + "type": "STRING", + "value": "\\DeclareDocumentCommand" + }, + { + "type": "STRING", + "value": "\\NewExpandableDocumentCommand" + }, + { + "type": "STRING", + "value": "\\RenewExpandableDocumentCommand" + }, + { + "type": "STRING", + "value": "\\ProvideExpandableDocumentCommand" + }, + { + "type": "STRING", + "value": "\\DeclareExpandableDocumentCommand" + } + ] + } + }, + { + "type": "FIELD", + "name": "declaration", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "curly_group_command_name" + }, + { + "type": "SYMBOL", + "name": "command_name" + } + ] + } + }, + { + "type": "FIELD", + "name": "spec", + "content": { + "type": "SYMBOL", + "name": "curly_group_spec" + } + }, + { + "type": "FIELD", + "name": "implementation", + "content": { + "type": "SYMBOL", + "name": "curly_group" + } + } + ] + } + }, "old_command_definition": { "type": "SEQ", "members": [ @@ -5497,6 +5607,19 @@ } }, "environment_definition": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_environment_definition" + }, + { + "type": "SYMBOL", + "name": "_newer_environment_definition" + } + ] + }, + "_environment_definition": { "type": "SEQ", "members": [ { @@ -5512,7 +5635,61 @@ { "type": "STRING", "value": "\\renewenvironment" + } + ] + } + }, + { + "type": "FIELD", + "name": "name", + "content": { + "type": "SYMBOL", + "name": "curly_group_text" + } + }, + { + "type": "FIELD", + "name": "argc", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "brack_group_argc" }, + { + "type": "BLANK" + } + ] + } + }, + { + "type": "FIELD", + "name": "begin", + "content": { + "type": "SYMBOL", + "name": "curly_group_impl" + } + }, + { + "type": "FIELD", + "name": "end", + "content": { + "type": "SYMBOL", + "name": "curly_group_impl" + } + } + ] + }, + "_newer_environment_definition": { + "type": "SEQ", + "members": [ + { + "type": "FIELD", + "name": "command", + "content": { + "type": "CHOICE", + "members": [ { "type": "STRING", "value": "\\NewDocumentEnvironment" @@ -5542,18 +5719,10 @@ }, { "type": "FIELD", - "name": "argc", + "name": "spec", "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "brack_group_argc" - }, - { - "type": "BLANK" - } - ] + "type": "SYMBOL", + "name": "curly_group_spec" } }, { diff --git a/src/node-types.json b/src/node-types.json index af4bd6640..98fca424e 100644 --- a/src/node-types.json +++ b/src/node-types.json @@ -2370,6 +2370,185 @@ } } }, + { + "type": "curly_group_spec", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": false, + "types": [ + { + "type": "acronym_definition", + "named": true + }, + { + "type": "acronym_reference", + "named": true + }, + { + "type": "author_declaration", + "named": true + }, + { + "type": "biblatex_include", + "named": true + }, + { + "type": "bibstyle_include", + "named": true + }, + { + "type": "bibtex_include", + "named": true + }, + { + "type": "block_comment", + "named": true + }, + { + "type": "caption", + "named": true + }, + { + "type": "citation", + "named": true + }, + { + "type": "class_include", + "named": true + }, + { + "type": "color_definition", + "named": true + }, + { + "type": "color_reference", + "named": true + }, + { + "type": "color_set_definition", + "named": true + }, + { + "type": "curly_group", + "named": true + }, + { + "type": "displayed_equation", + "named": true + }, + { + "type": "environment_definition", + "named": true + }, + { + "type": "generic_command", + "named": true + }, + { + "type": "glossary_entry_definition", + "named": true + }, + { + "type": "glossary_entry_reference", + "named": true + }, + { + "type": "graphics_include", + "named": true + }, + { + "type": "hyperlink", + "named": true + }, + { + "type": "import_include", + "named": true + }, + { + "type": "inkscape_include", + "named": true + }, + { + "type": "inline_formula", + "named": true + }, + { + "type": "label_definition", + "named": true + }, + { + "type": "label_number", + "named": true + }, + { + "type": "label_reference", + "named": true + }, + { + "type": "label_reference_range", + "named": true + }, + { + "type": "latex_include", + "named": true + }, + { + "type": "let_command_definition", + "named": true + }, + { + "type": "math_delimiter", + "named": true + }, + { + "type": "new_command_definition", + "named": true + }, + { + "type": "old_command_definition", + "named": true + }, + { + "type": "package_include", + "named": true + }, + { + "type": "paired_delimiter_definition", + "named": true + }, + { + "type": "svg_include", + "named": true + }, + { + "type": "text", + "named": true + }, + { + "type": "text_mode", + "named": true + }, + { + "type": "theorem_definition", + "named": true + }, + { + "type": "tikz_library_import", + "named": true + }, + { + "type": "title_declaration", + "named": true + }, + { + "type": "verbatim_include", + "named": true + } + ] + } + }, { "type": "curly_group_text", "named": true, @@ -3028,6 +3207,16 @@ "named": true } ] + }, + "spec": { + "multiple": false, + "required": false, + "types": [ + { + "type": "curly_group_spec", + "named": true + } + ] } } }, @@ -5135,6 +5324,14 @@ "type": "\\newcommand*", "named": false }, + { + "type": "\\providecommand", + "named": false + }, + { + "type": "\\providecommand*", + "named": false + }, { "type": "\\renewcommand", "named": false @@ -5149,6 +5346,10 @@ "multiple": false, "required": true, "types": [ + { + "type": "command_name", + "named": true + }, { "type": "curly_group_command_name", "named": true @@ -5174,6 +5375,16 @@ "named": true } ] + }, + "spec": { + "multiple": false, + "required": false, + "types": [ + { + "type": "curly_group_spec", + "named": true + } + ] } } }, @@ -9102,6 +9313,14 @@ "type": "\\pnotecite", "named": false }, + { + "type": "\\providecommand", + "named": false + }, + { + "type": "\\providecommand*", + "named": false + }, { "type": "\\pvolcite", "named": false diff --git a/test/corpus/commands.txt b/test/corpus/commands.txt index 2cda67a36..b6d2b2cb4 100644 --- a/test/corpus/commands.txt +++ b/test/corpus/commands.txt @@ -134,6 +134,67 @@ Command definition with default arg (text (placeholder))))) +================================================================================ +Command definition without curly braces +================================================================================ + +\newcommand\foo[1]{#1} + +-------------------------------------------------------------------------------- + +(source_file + (new_command_definition + (command_name) + (brack_group_argc + (argc)) + (curly_group + (text + (placeholder))))) + +================================================================================ +Command definition (xparse) +================================================================================ + +\NewDocumentCommand{\foo}{m}{#1} + +-------------------------------------------------------------------------------- + +(source_file + (new_command_definition + (curly_group_command_name + (command_name)) + (curly_group_spec + (text + (word))) + (curly_group + (text + (placeholder))))) + +================================================================================ +Command definition with optional argument (xparse) +================================================================================ + +\NewDocumentCommand{\foo}{o{default} m}{#1 #2} + +-------------------------------------------------------------------------------- + +(source_file + (new_command_definition + (curly_group_command_name + (command_name)) + (curly_group_spec + (text + (word)) + (curly_group + (text + (word))) + (text + (word))) + (curly_group + (text + (placeholder) + (placeholder))))) + ================================================================================ Author command ================================================================================