Skip to content

Commit

Permalink
Fix parsing labels with brackets and parens (#1017)
Browse files Browse the repository at this point in the history
  • Loading branch information
pfoerster authored Feb 18, 2024
1 parent cd47344 commit a6ab77c
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- When `workspace/didChangeConfiguration` contains the configuration of multiple LSP servers, `texlab` will try
to extract the `texlab` configuration instead of falling back to the default settings
([#1003](https://github.com/latex-lsp/texlab/issues/1003))
- Allow brackets and parentheses in label names and similar constructs ([#1016](https://github.com/latex-lsp/texlab/issues/1016))

## [5.12.3] - 2024-01-27

Expand Down
32 changes: 27 additions & 5 deletions crates/parser/src/latex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down Expand Up @@ -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 => {}
}
Expand Down Expand Up @@ -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,
}
}
Expand All @@ -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();
Expand Down
69 changes: 69 additions & 0 deletions crates/parser/src/latex/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 "}"
"#]],
);
}

0 comments on commit a6ab77c

Please sign in to comment.