diff options
| author | Ian Wrzesinski <wrzian@umich.edu> | 2024-11-03 20:35:21 -0500 |
|---|---|---|
| committer | Ian Wrzesinski <wrzian@umich.edu> | 2024-11-03 22:04:06 -0500 |
| commit | 2c9728f53b318a6cae092f30ad0956a536af7ccb (patch) | |
| tree | c30909de62b6d2d87c02393542d38b56ddd4beec /crates/typst-syntax | |
| parent | 9d9a1b1e33cdc379200c1d3881c34fe05c496894 (diff) | |
18. Restore list indent behavior
Diffstat (limited to 'crates/typst-syntax')
| -rw-r--r-- | crates/typst-syntax/src/lexer.rs | 8 | ||||
| -rw-r--r-- | crates/typst-syntax/src/parser.rs | 41 |
2 files changed, 22 insertions, 27 deletions
diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs index d09c6f84..1314016f 100644 --- a/crates/typst-syntax/src/lexer.rs +++ b/crates/typst-syntax/src/lexer.rs @@ -69,9 +69,11 @@ impl<'s> Lexer<'s> { self.newline } - /// The number of characters until the most recent newline. - pub fn column(&self) -> usize { - self.s.before().chars().rev().take_while(|&c| !is_newline(c)).count() + /// The number of characters until the most recent newline from an index. + pub fn column(&self, index: usize) -> usize { + let mut s = self.s; // Make a new temporary scanner (cheap). + s.jump(index); + s.before().chars().rev().take_while(|&c| !is_newline(c)).count() } } diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs index b26cc002..5fc621d6 100644 --- a/crates/typst-syntax/src/parser.rs +++ b/crates/typst-syntax/src/parser.rs @@ -1545,11 +1545,7 @@ struct Token { /// Information about a newline if present (currently only relevant in Markup). #[derive(Debug, Clone, Copy)] struct Newline { - /// The column of our token in its line. - /// - /// Note that this is actually the column of the first non-whitespace - /// `SyntaxKind` in the line, so `\n /**/- list` has column 2 (not 6) - /// because the block comment is the first non-space kind. + /// The column of the start of our token in its line. column: Option<usize>, /// Whether any of our newlines were paragraph breaks. parbreak: bool, @@ -1684,10 +1680,6 @@ impl<'s> Parser<'s> { /// The number of characters until the most recent newline from the current /// token, or 0 if it did not follow a newline. - /// - /// Note that this is actually the column of the first non-whitespace - /// `SyntaxKind` in the line, so `\n /**/- list` has column 2 (not 6) - /// because the block comment is the first non-space kind. fn current_column(&self) -> usize { self.token.newline.and_then(|newline| newline.column).unwrap_or(0) } @@ -1852,29 +1844,30 @@ impl<'s> Parser<'s> { let (mut kind, mut node) = lexer.next(); let mut n_trivia = 0; let mut had_newline = false; - let mut newline = Newline { column: None, parbreak: false }; + let mut parbreak = false; while kind.is_trivia() { - if lexer.newline() { - // Newlines are always trivia. - had_newline = true; - newline.parbreak |= kind == SyntaxKind::Parbreak; - if lexer.mode() == LexMode::Markup { - newline.column = Some(lexer.column()); - } - } + had_newline |= lexer.newline(); // Newlines are always trivia. + parbreak |= kind == SyntaxKind::Parbreak; n_trivia += 1; nodes.push(node); start = lexer.cursor(); (kind, node) = lexer.next(); } - if had_newline && nl_mode.stop_at(newline, kind) { - // Insert a temporary `SyntaxKind::End` to halt the parser. - // The actual kind will be restored from `node` later. - kind = SyntaxKind::End; - } - let newline = had_newline.then_some(newline); + let newline = if had_newline { + let column = (lexer.mode() == LexMode::Markup).then(|| lexer.column(start)); + let newline = Newline { column, parbreak }; + if nl_mode.stop_at(newline, kind) { + // Insert a temporary `SyntaxKind::End` to halt the parser. + // The actual kind will be restored from `node` later. + kind = SyntaxKind::End; + } + Some(newline) + } else { + None + }; + Token { kind, node, n_trivia, newline, start, prev_end } } } |
