diff options
author | Norbert Preining <norbert@preining.info> | 2024-03-17 03:01:42 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2024-03-17 03:01:42 +0000 |
commit | 55140d5421e1ad0024c9acbfa72bd06402c2aa9f (patch) | |
tree | b6c0d76888f025b58f1221d8dadbefb0264e9f6c /support/texlab/crates/parser | |
parent | 966f9ba332e49c29e961cb86e08f97d70eda51f6 (diff) |
CTAN sync 202403170301
Diffstat (limited to 'support/texlab/crates/parser')
-rw-r--r-- | support/texlab/crates/parser/Cargo.toml | 2 | ||||
-rw-r--r-- | support/texlab/crates/parser/src/config.rs | 28 | ||||
-rw-r--r-- | support/texlab/crates/parser/src/latex.rs | 32 | ||||
-rw-r--r-- | support/texlab/crates/parser/src/latex/lexer/commands.rs | 4 | ||||
-rw-r--r-- | support/texlab/crates/parser/src/latex/tests.rs | 69 |
5 files changed, 126 insertions, 9 deletions
diff --git a/support/texlab/crates/parser/Cargo.toml b/support/texlab/crates/parser/Cargo.toml index c3e31b7022..0fd8889899 100644 --- a/support/texlab/crates/parser/Cargo.toml +++ b/support/texlab/crates/parser/Cargo.toml @@ -13,7 +13,7 @@ regex = "1.10.2" rowan = "0.15.15" rustc-hash = "1.1.0" syntax = { path = "../syntax" } -tempfile = "3.8.1" +tempfile = "3.10.1" [dev-dependencies] expect-test = "1.4.1" diff --git a/support/texlab/crates/parser/src/config.rs b/support/texlab/crates/parser/src/config.rs index 3a2e9e3e93..6537d21b0d 100644 --- a/support/texlab/crates/parser/src/config.rs +++ b/support/texlab/crates/parser/src/config.rs @@ -7,6 +7,7 @@ pub struct SyntaxConfig { pub enum_environments: FxHashSet<String>, pub verbatim_environments: FxHashSet<String>, pub citation_commands: FxHashSet<String>, + pub label_reference_commands: FxHashSet<String>, } impl Default for SyntaxConfig { @@ -31,12 +32,18 @@ impl Default for SyntaxConfig { .map(ToString::to_string) .collect(); + let label_reference_commands = DEFAULT_LABEL_REFERENCE_COMMANDS + .iter() + .map(ToString::to_string) + .collect(); + Self { follow_package_links: false, math_environments, enum_environments, verbatim_environments, citation_commands, + label_reference_commands, } } } @@ -155,3 +162,24 @@ static DEFAULT_CITATION_COMMANDS: &[&str] = &[ "citeA", "citeA*", ]; + +static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[ + "ref", + "vref", + "Vref", + "autoref", + "pageref", + "cref", + "cref*", + "Cref", + "Cref*", + "namecref", + "nameCref", + "lcnamecref", + "namecrefs", + "nameCrefs", + "lcnamecrefs", + "labelcref", + "labelcpageref", + "eqref", +]; diff --git a/support/texlab/crates/parser/src/latex.rs b/support/texlab/crates/parser/src/latex.rs index d88eb39556..4a6fabae21 100644 --- a/support/texlab/crates/parser/src/latex.rs +++ b/support/texlab/crates/parser/src/latex.rs @@ -25,6 +25,13 @@ impl Default for ParserContext { } } +#[derive(Debug, Clone, Copy)] +struct KeyOptions { + allow_eq: bool, + allow_parens: bool, + allow_bracks: bool, +} + #[derive(Debug)] struct Parser<'a> { lexer: Lexer<'a>, @@ -309,7 +316,11 @@ impl<'a> Parser<'a> { self.trivia(); match self.peek() { Some(Token::Word | Token::Pipe) => { - self.key(); + self.key_with_opts(KeyOptions { + allow_eq: true, + allow_bracks: false, + allow_parens: true, + }); } Some(_) | None => {} } @@ -340,16 +351,22 @@ impl<'a> Parser<'a> { } fn key(&mut self) { - self.key_with_eq(true); + self.key_with_opts(KeyOptions { + allow_eq: true, + allow_parens: true, + allow_bracks: true, + }); } - fn key_with_eq(&mut self, allow_eq: bool) { + fn key_with_opts(&mut self, options: KeyOptions) { self.builder.start_node(KEY.into()); self.eat(); while let Some(kind) = self.peek() { match kind { Token::Whitespace | Token::LineComment | Token::Word | Token::Pipe => self.eat(), - Token::Eq if allow_eq => self.eat(), + Token::LBrack | Token::RBrack if options.allow_bracks => self.eat(), + Token::LParen | Token::RParen if options.allow_parens => self.eat(), + Token::Eq if options.allow_eq => self.eat(), _ => break, } } @@ -374,7 +391,12 @@ impl<'a> Parser<'a> { fn key_value_pair(&mut self) { self.builder.start_node(KEY_VALUE_PAIR.into()); - self.key_with_eq(false); + self.key_with_opts(KeyOptions { + allow_eq: false, + allow_parens: true, + allow_bracks: false, + }); + if self.peek() == Some(Token::Eq) { self.eat(); self.trivia(); diff --git a/support/texlab/crates/parser/src/latex/lexer/commands.rs b/support/texlab/crates/parser/src/latex/lexer/commands.rs index b6e1d11737..95eef4becd 100644 --- a/support/texlab/crates/parser/src/latex/lexer/commands.rs +++ b/support/texlab/crates/parser/src/latex/lexer/commands.rs @@ -30,9 +30,6 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName { CommandName::Import } "label" => CommandName::LabelDefinition, - "ref" | "vref" | "Vref" | "autoref" | "pageref" | "cref" | "cref*" | "Cref" | "Cref*" - | "namecref" | "nameCref" | "lcnamecref" | "namecrefs" | "nameCrefs" | "lcnamecrefs" - | "labelcref" | "labelcpageref" | "eqref" => CommandName::LabelReference, "crefrange" | "crefrange*" | "Crefrange" | "Crefrange*" => CommandName::LabelReferenceRange, "newlabel" => CommandName::LabelNumber, "newcommand" @@ -81,6 +78,7 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName { "fi" => CommandName::EndBlockComment, "verb" => CommandName::VerbatimBlock, _ if config.citation_commands.contains(name) => CommandName::Citation, + _ if config.label_reference_commands.contains(name) => CommandName::LabelReference, _ => CommandName::Generic, } } diff --git a/support/texlab/crates/parser/src/latex/tests.rs b/support/texlab/crates/parser/src/latex/tests.rs index 6e5019776f..5e1a4044cd 100644 --- a/support/texlab/crates/parser/src/latex/tests.rs +++ b/support/texlab/crates/parser/src/latex/tests.rs @@ -3542,3 +3542,72 @@ fn test_command_subscript() { "#]], ); } + +#[test] +fn test_label_parens() { + check( + r#"\label{foo (bar)}"#, + expect![[r#" + ROOT@0..17 + PREAMBLE@0..17 + LABEL_DEFINITION@0..17 + COMMAND_NAME@0..6 "\\label" + CURLY_GROUP_WORD@6..17 + L_CURLY@6..7 "{" + KEY@7..16 + WORD@7..10 "foo" + WHITESPACE@10..11 " " + L_PAREN@11..12 "(" + WORD@12..15 "bar" + R_PAREN@15..16 ")" + R_CURLY@16..17 "}" + + "#]], + ); +} + +#[test] +fn test_label_brackets() { + check( + r#"\label{foo [bar]}"#, + expect![[r#" + ROOT@0..17 + PREAMBLE@0..17 + LABEL_DEFINITION@0..17 + COMMAND_NAME@0..6 "\\label" + CURLY_GROUP_WORD@6..17 + L_CURLY@6..7 "{" + KEY@7..16 + WORD@7..10 "foo" + WHITESPACE@10..11 " " + L_BRACK@11..12 "[" + WORD@12..15 "bar" + R_BRACK@15..16 "]" + R_CURLY@16..17 "}" + + "#]], + ); +} + +#[test] +fn test_label_brackets_unbalanced() { + check( + r#"\label{foo ]bar[}"#, + expect![[r#" + ROOT@0..17 + PREAMBLE@0..17 + LABEL_DEFINITION@0..17 + COMMAND_NAME@0..6 "\\label" + CURLY_GROUP_WORD@6..17 + L_CURLY@6..7 "{" + KEY@7..16 + WORD@7..10 "foo" + WHITESPACE@10..11 " " + R_BRACK@11..12 "]" + WORD@12..15 "bar" + L_BRACK@15..16 "[" + R_CURLY@16..17 "}" + + "#]], + ); +} |