summaryrefslogtreecommitdiff
path: root/support/texlab/crates/parser
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/parser')
-rw-r--r--support/texlab/crates/parser/Cargo.toml2
-rw-r--r--support/texlab/crates/parser/src/config.rs28
-rw-r--r--support/texlab/crates/parser/src/latex.rs32
-rw-r--r--support/texlab/crates/parser/src/latex/lexer/commands.rs4
-rw-r--r--support/texlab/crates/parser/src/latex/tests.rs69
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 "}"
+
+ "#]],
+ );
+}