mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Convert unopened square-brackets into a hard error (#5414)
This commit is contained in:
parent
0228462ba1
commit
50dcacea9a
@ -47,14 +47,9 @@ fn markup_exprs(p: &mut Parser, mut at_start: bool, stop_set: SyntaxSet) {
|
||||
debug_assert!(stop_set.contains(SyntaxKind::End));
|
||||
at_start |= p.had_newline();
|
||||
let mut nesting: usize = 0;
|
||||
loop {
|
||||
match p.current() {
|
||||
SyntaxKind::LeftBracket => nesting += 1,
|
||||
SyntaxKind::RightBracket if nesting > 0 => nesting -= 1,
|
||||
_ if p.at_set(stop_set) => break,
|
||||
_ => {}
|
||||
}
|
||||
markup_expr(p, at_start);
|
||||
// Keep going if we're at a nested right-bracket regardless of the stop set.
|
||||
while !p.at_set(stop_set) || (nesting > 0 && p.at(SyntaxKind::RightBracket)) {
|
||||
markup_expr(p, at_start, &mut nesting);
|
||||
at_start = p.had_newline();
|
||||
}
|
||||
}
|
||||
@ -69,15 +64,12 @@ pub(super) fn reparse_markup(
|
||||
) -> Option<Vec<SyntaxNode>> {
|
||||
let mut p = Parser::new(text, range.start, LexMode::Markup);
|
||||
*at_start |= p.had_newline();
|
||||
while p.current_start() < range.end {
|
||||
match p.current() {
|
||||
SyntaxKind::LeftBracket => *nesting += 1,
|
||||
SyntaxKind::RightBracket if *nesting > 0 => *nesting -= 1,
|
||||
SyntaxKind::RightBracket if !top_level => break,
|
||||
SyntaxKind::End => break,
|
||||
_ => {}
|
||||
while !p.end() && p.current_start() < range.end {
|
||||
// If not top-level and at a new RightBracket, stop the reparse.
|
||||
if !top_level && *nesting == 0 && p.at(SyntaxKind::RightBracket) {
|
||||
break;
|
||||
}
|
||||
markup_expr(&mut p, *at_start);
|
||||
markup_expr(&mut p, *at_start, nesting);
|
||||
*at_start = p.had_newline();
|
||||
}
|
||||
(p.balanced && p.current_start() == range.end).then(|| p.finish())
|
||||
@ -86,8 +78,21 @@ pub(super) fn reparse_markup(
|
||||
/// Parses a single markup expression. This includes markup elements like text,
|
||||
/// headings, strong/emph, lists/enums, etc. This is also the entry point for
|
||||
/// parsing math equations and embedded code expressions.
|
||||
fn markup_expr(p: &mut Parser, at_start: bool) {
|
||||
fn markup_expr(p: &mut Parser, at_start: bool, nesting: &mut usize) {
|
||||
match p.current() {
|
||||
SyntaxKind::LeftBracket => {
|
||||
*nesting += 1;
|
||||
p.convert_and_eat(SyntaxKind::Text);
|
||||
}
|
||||
SyntaxKind::RightBracket if *nesting > 0 => {
|
||||
*nesting -= 1;
|
||||
p.convert_and_eat(SyntaxKind::Text);
|
||||
}
|
||||
SyntaxKind::RightBracket => {
|
||||
p.unexpected();
|
||||
p.hint("try using a backslash escape: \\]");
|
||||
}
|
||||
|
||||
SyntaxKind::Text
|
||||
| SyntaxKind::Linebreak
|
||||
| SyntaxKind::Escape
|
||||
@ -108,9 +113,7 @@ fn markup_expr(p: &mut Parser, at_start: bool) {
|
||||
SyntaxKind::RefMarker => reference(p),
|
||||
SyntaxKind::Dollar => equation(p),
|
||||
|
||||
SyntaxKind::LeftBracket
|
||||
| SyntaxKind::RightBracket
|
||||
| SyntaxKind::HeadingMarker
|
||||
SyntaxKind::HeadingMarker
|
||||
| SyntaxKind::ListMarker
|
||||
| SyntaxKind::EnumMarker
|
||||
| SyntaxKind::TermMarker
|
||||
@ -201,7 +204,7 @@ fn equation(p: &mut Parser) {
|
||||
let m = p.marker();
|
||||
p.enter_modes(LexMode::Math, AtNewline::Continue, |p| {
|
||||
p.assert(SyntaxKind::Dollar);
|
||||
math(p, syntax_set!(Dollar, RightBracket, End));
|
||||
math(p, syntax_set!(Dollar, End));
|
||||
p.expect_closing_delimiter(m, SyntaxKind::Dollar);
|
||||
});
|
||||
p.wrap(m, SyntaxKind::Equation);
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 118 B |
@ -136,8 +136,45 @@
|
||||
#}
|
||||
|
||||
--- single-right-bracket ---
|
||||
// Error: 1-2 unexpected closing bracket
|
||||
// Hint: 1-2 try using a backslash escape: \]
|
||||
]
|
||||
|
||||
--- right-bracket-nesting ---
|
||||
[
|
||||
= [ Hi ]]
|
||||
- how [
|
||||
- are ]
|
||||
// Error: 10-11 unexpected closing bracket
|
||||
// Hint: 10-11 try using a backslash escape: \]
|
||||
- error][]
|
||||
[[]]
|
||||
|
||||
--- right-bracket-hash ---
|
||||
// Error: 2-3 unexpected closing bracket
|
||||
#]
|
||||
|
||||
--- right-bracket-in-blocks ---
|
||||
// Error: 3-4 unclosed delimiter
|
||||
// Error: 6-7 unexpected closing bracket
|
||||
// Hint: 6-7 try using a backslash escape: \]
|
||||
[#{]}]
|
||||
|
||||
// Error: 4-5 unexpected closing bracket
|
||||
// Hint: 4-5 try using a backslash escape: \]
|
||||
#[]]
|
||||
|
||||
// Error: 4-5 unclosed delimiter
|
||||
// Error: 7-8 unexpected closing bracket
|
||||
// Hint: 7-8 try using a backslash escape: \]
|
||||
#[#{]}]
|
||||
|
||||
// Error: 2-3 unclosed delimiter
|
||||
// Error: 3-4 unclosed delimiter
|
||||
// Error: 4-5 unexpected closing bracket
|
||||
// Hint: 4-5 try using a backslash escape: \]
|
||||
#{{]}}
|
||||
|
||||
--- content-block-in-markup-scope ---
|
||||
// Content blocks also create a scope.
|
||||
#[#let x = 1]
|
||||
|
Loading…
x
Reference in New Issue
Block a user