mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Ignore escaped brackets for body measure 🐥
This commit is contained in:
parent
37c336063b
commit
bc78974fd2
@ -504,16 +504,22 @@ impl<'s> Parser<'s> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the index of the first unbalanced closing bracket.
|
/// Find the index of the first unbalanced (unescaped) closing bracket.
|
||||||
fn find_closing_bracket(src: &str) -> Option<usize> {
|
fn find_closing_bracket(src: &str) -> Option<usize> {
|
||||||
let mut parens = 0;
|
let mut parens = 0;
|
||||||
|
let mut escaped = false;
|
||||||
for (index, c) in src.char_indices() {
|
for (index, c) in src.char_indices() {
|
||||||
match c {
|
match c {
|
||||||
']' if parens == 0 => return Some(index),
|
'\\' => {
|
||||||
'[' => parens += 1,
|
escaped = !escaped;
|
||||||
']' => parens -= 1,
|
continue;
|
||||||
|
},
|
||||||
|
']' if !escaped && parens == 0 => return Some(index),
|
||||||
|
'[' if !escaped => parens += 1,
|
||||||
|
']' if !escaped => parens -= 1,
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
escaped = false;
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -856,45 +862,53 @@ mod parse_tests {
|
|||||||
T("of"), S, T("a"), S, T("function"), S, T("invocation.")
|
T("of"), S, T("a"), S, T("function"), S, T("invocation.")
|
||||||
]);
|
]);
|
||||||
test_scoped(&scope, "[func][Hello][modifier][Here][end]", tree! [
|
test_scoped(&scope, "[func][Hello][modifier][Here][end]", tree! [
|
||||||
F(func! {
|
F(func! { name => "func", body => tree! [ T("Hello") ] }),
|
||||||
name => "func",
|
F(func! { name => "modifier", body => tree! [ T("Here") ] }),
|
||||||
body => tree! [ T("Hello") ],
|
F(func! { name => "end", body => None }),
|
||||||
}),
|
|
||||||
F(func! {
|
|
||||||
name => "modifier",
|
|
||||||
body => tree! [ T("Here") ],
|
|
||||||
}),
|
|
||||||
F(func! {
|
|
||||||
name => "end",
|
|
||||||
body => None,
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
test_scoped(&scope, "[func][]", tree! [
|
|
||||||
F(func! {
|
|
||||||
name => "func",
|
|
||||||
body => tree! [],
|
|
||||||
})
|
|
||||||
]);
|
]);
|
||||||
|
test_scoped(&scope, "[func][]", tree! [ F(func! { name => "func", body => tree! [] }) ]);
|
||||||
test_scoped(&scope, "[modifier][[func][call]] outside", tree! [
|
test_scoped(&scope, "[modifier][[func][call]] outside", tree! [
|
||||||
F(func! {
|
F(func! {
|
||||||
name => "modifier",
|
name => "modifier",
|
||||||
body => tree! [
|
body => tree! [ F(func! { name => "func", body => tree! [ T("call") ] }) ],
|
||||||
F(func! {
|
|
||||||
name => "func",
|
|
||||||
body => tree! [ T("call") ],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
S, T("outside")
|
S, T("outside")
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test if escaped, but unbalanced parens are correctly parsed.
|
||||||
|
#[test]
|
||||||
|
fn parse_unbalanced_body_parens() {
|
||||||
|
let mut scope = Scope::new();
|
||||||
|
scope.add::<TreeFn>("code");
|
||||||
|
|
||||||
|
test_scoped(&scope, r"My [code][Close \]] end", tree! [
|
||||||
|
T("My"), S, F(func! {
|
||||||
|
name => "code",
|
||||||
|
body => tree! [ T("Close"), S, T("]") ]
|
||||||
|
}), S, T("end")
|
||||||
|
]);
|
||||||
|
test_scoped(&scope, r"My [code][\[ Open] end", tree! [
|
||||||
|
T("My"), S, F(func! {
|
||||||
|
name => "code",
|
||||||
|
body => tree! [ T("["), S, T("Open") ]
|
||||||
|
}), S, T("end")
|
||||||
|
]);
|
||||||
|
test_scoped(&scope, r"My [code][Open \] and \[ close]end", tree! [
|
||||||
|
T("My"), S, F(func! {
|
||||||
|
name => "code",
|
||||||
|
body => tree! [ T("Open"), S, T("]"), S, T("and"), S, T("["), S, T("close") ]
|
||||||
|
}), T("end")
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/// Tests if the parser handles non-ASCII stuff correctly.
|
/// Tests if the parser handles non-ASCII stuff correctly.
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_unicode() {
|
fn parse_unicode() {
|
||||||
let mut scope = Scope::new();
|
let mut scope = Scope::new();
|
||||||
scope.add::<BodylessFn>("func");
|
scope.add::<BodylessFn>("func");
|
||||||
scope.add::<TreeFn>("bold");
|
scope.add::<TreeFn>("bold");
|
||||||
|
|
||||||
test_scoped(&scope, "[func] ⺐.", tree! [
|
test_scoped(&scope, "[func] ⺐.", tree! [
|
||||||
F(func! {
|
F(func! {
|
||||||
name => "func",
|
name => "func",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user