Skip to content

Commit

Permalink
Fix parsing \verb command
Browse files Browse the repository at this point in the history
See #828.
  • Loading branch information
pfoerster committed Apr 29, 2023
1 parent b61313e commit 6188ddf
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fix spurious completion results when completing environments ([#883](https://github.com/latex-lsp/texlab/issues/883))
- Fix regression when guessing cursor position after formatting ([#880](https://github.com/latex-lsp/texlab/issues/880))
- Fix parsing `\verb` command ([#828](https://github.com/latex-lsp/texlab/issues/828))

## [5.5.0] - 2023-04-16

Expand Down
40 changes: 35 additions & 5 deletions crates/parser/src/latex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ impl<'a> Parser<'a> {
self.builder.token(kind.into(), text);
}

fn eat_remap(&mut self, kind: SyntaxKind) {
let (_, text) = self.lexer.eat().unwrap();
self.builder.token(kind.into(), text);
}

fn peek(&self) -> Option<Token> {
self.lexer.peek()
}
Expand Down Expand Up @@ -98,7 +103,7 @@ impl<'a> Parser<'a> {
self.eat();
self.builder.finish_node();
}
Token::Word | Token::Comma => self.text(context),
Token::Pipe | Token::Word | Token::Comma => self.text(context),
Token::Eq => self.eat(),
Token::Dollar => self.formula(),
Token::CommandName(name) => match name {
Expand Down Expand Up @@ -141,6 +146,7 @@ impl<'a> Parser<'a> {
CommandName::EnvironmentDefinition => self.environment_definition(),
CommandName::BeginBlockComment => self.block_comment(),
CommandName::EndBlockComment => self.generic_command(),
CommandName::VerbatimBlock => self.verbatim_block(),
CommandName::GraphicsPath => self.graphics_path(),
},
}
Expand All @@ -158,6 +164,7 @@ impl<'a> Parser<'a> {
| Token::Whitespace
| Token::LineComment
| Token::Word
| Token::Pipe
| Token::Comma
) && (context.allow_comma || kind != Token::Comma)
})
Expand Down Expand Up @@ -219,7 +226,7 @@ impl<'a> Parser<'a> {
self.eat();
self.trivia();
match self.peek() {
Some(Token::Word) => {
Some(Token::Word | Token::Pipe) => {
self.key();
}
Some(Token::CommandName(_)) => {
Expand All @@ -244,6 +251,7 @@ impl<'a> Parser<'a> {
| Token::Whitespace
| Token::LineComment
| Token::Word
| Token::Pipe
| Token::Comma
)
})
Expand Down Expand Up @@ -298,7 +306,7 @@ impl<'a> Parser<'a> {
self.eat();
self.trivia();
match self.peek() {
Some(Token::Word) => {
Some(Token::Word | Token::Pipe) => {
self.key();
}
Some(_) | None => {}
Expand Down Expand Up @@ -334,7 +342,12 @@ impl<'a> Parser<'a> {
self.eat();
while self
.peek()
.filter(|&kind| matches!(kind, Token::Whitespace | Token::LineComment | Token::Word))
.filter(|&kind| {
matches!(
kind,
Token::Whitespace | Token::LineComment | Token::Word | Token::Pipe
)
})
.is_some()
{
self.eat();
Expand Down Expand Up @@ -390,7 +403,7 @@ impl<'a> Parser<'a> {
while let Some(kind) = self.peek() {
match kind {
Token::LineBreak | Token::Whitespace | Token::LineComment => self.eat(),
Token::Word => {
Token::Word | Token::Pipe => {
self.key_value_pair();
if self.peek() == Some(Token::Comma) {
self.eat();
Expand Down Expand Up @@ -1116,6 +1129,23 @@ impl<'a> Parser<'a> {

self.builder.finish_node();
}

fn verbatim_block(&mut self) {
self.builder.start_node(GENERIC_COMMAND.into());
self.eat();
self.builder.finish_node();
self.trivia();

if self.peek() == Some(Token::Pipe) {
self.eat_remap(SyntaxKind::VERBATIM);
while let Some(kind) = self.peek() {
self.eat_remap(SyntaxKind::VERBATIM);
if kind == Token::Pipe {
break;
}
}
}
}
}

pub fn parse_latex(text: &str, config: &SyntaxConfig) -> GreenNode {
Expand Down
1 change: 1 addition & 0 deletions crates/parser/src/latex/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ impl<'a> Lexer<'a> {
Token::RParen => SyntaxKind::R_PAREN,
Token::Comma => SyntaxKind::COMMA,
Token::Eq => SyntaxKind::EQUALITY_SIGN,
Token::Pipe => SyntaxKind::WORD,
Token::Word => SyntaxKind::WORD,
Token::Dollar => SyntaxKind::DOLLAR,
Token::CommandName(_) => SyntaxKind::COMMAND_NAME,
Expand Down
1 change: 1 addition & 0 deletions crates/parser/src/latex/lexer/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName {
"graphicspath" => CommandName::GraphicsPath,
"iffalse" => CommandName::BeginBlockComment,
"fi" => CommandName::EndBlockComment,
"verb" => CommandName::VerbatimBlock,
_ if config.citation_commands.contains(name) => CommandName::Citation,
_ => CommandName::Generic,
}
Expand Down
6 changes: 5 additions & 1 deletion crates/parser/src/latex/lexer/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ pub enum Token {
#[token("=")]
Eq,

#[regex(r"[^\s\\%\{\},\$\[\]\(\)=]+")]
#[token("|")]
Pipe,

#[regex(r"[^\s\\%\{\},\$\[\]\(\)=\|]+")]
Word,

#[regex(r"\$\$?")]
Expand Down Expand Up @@ -117,6 +120,7 @@ pub enum CommandName {
GraphicsPath,
BeginBlockComment,
EndBlockComment,
VerbatimBlock,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
source: crates/parser/src/latex.rs
expression: root
input_file: crates/parser/src/test_data/latex/issue_828.txt
---
ROOT@0..51
PREAMBLE@0..51
GENERIC_COMMAND@0..5
COMMAND_NAME@0..5 "\\verb"
VERBATIM@5..6 "|"
VERBATIM@6..17 "<STATEMENT>"
VERBATIM@17..22 " "
VERBATIM@22..24 "if"
VERBATIM@24..25 "("
VERBATIM@25..31 "<expr>"
VERBATIM@31..32 ")"
VERBATIM@32..33 "{"
VERBATIM@33..43 "<body>else"
VERBATIM@43..44 "{"
VERBATIM@44..50 "<body>"
VERBATIM@50..51 "|"

1 change: 1 addition & 0 deletions crates/parser/src/test_data/latex/issue_828.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
\verb|<STATEMENT> if(<expr>){<body>else{<body>|

0 comments on commit 6188ddf

Please sign in to comment.