mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Move heading tests to integration 🚚
This commit is contained in:
parent
1d01b93f67
commit
274e008e2c
@ -34,11 +34,9 @@ fn tree(p: &mut Parser) -> Tree {
|
||||
let mut at_start = true;
|
||||
let mut tree = vec![];
|
||||
while !p.eof() {
|
||||
if let Some(node) = p.span_if(|p| node(p, at_start)) {
|
||||
match node.v {
|
||||
Node::Parbreak => at_start = true,
|
||||
Node::Space => {}
|
||||
_ => at_start = false,
|
||||
if let Some(node) = p.span_if(|p| node(p, &mut at_start)) {
|
||||
if !matches!(node.v, Node::Parbreak | Node::Space) {
|
||||
at_start = false;
|
||||
}
|
||||
tree.push(node);
|
||||
}
|
||||
@ -47,7 +45,7 @@ fn tree(p: &mut Parser) -> Tree {
|
||||
}
|
||||
|
||||
/// Parse a syntax node.
|
||||
fn node(p: &mut Parser, at_start: bool) -> Option<Node> {
|
||||
fn node(p: &mut Parser, at_start: &mut bool) -> Option<Node> {
|
||||
let node = match p.peek()? {
|
||||
// Bracket call.
|
||||
Token::LeftBracket => {
|
||||
@ -64,7 +62,7 @@ fn node(p: &mut Parser, at_start: bool) -> Option<Node> {
|
||||
Token::Underscore => Node::Emph,
|
||||
Token::Tilde => Node::Text("\u{00A0}".into()),
|
||||
Token::Hash => {
|
||||
if at_start {
|
||||
if *at_start {
|
||||
return Some(Node::Heading(heading(p)));
|
||||
} else {
|
||||
Node::Text(p.get(p.peek_span()).into())
|
||||
@ -72,11 +70,8 @@ fn node(p: &mut Parser, at_start: bool) -> Option<Node> {
|
||||
}
|
||||
Token::Backslash => Node::Linebreak,
|
||||
Token::Space(newlines) => {
|
||||
if newlines < 2 {
|
||||
Node::Space
|
||||
} else {
|
||||
Node::Parbreak
|
||||
}
|
||||
*at_start |= newlines > 0;
|
||||
if newlines < 2 { Node::Space } else { Node::Parbreak }
|
||||
}
|
||||
Token::Text(text) => Node::Text(text.into()),
|
||||
Token::Raw(t) => Node::Raw(raw(p, t)),
|
||||
@ -122,8 +117,8 @@ fn heading(p: &mut Parser) -> NodeHeading {
|
||||
|
||||
// Parse the heading contents.
|
||||
let mut contents = vec![];
|
||||
while p.check(|t| !matches!(t, Token::Space(n) if n >= 1)) {
|
||||
if let Some(node) = p.span_if(|p| node(p, false)) {
|
||||
while p.check(|t| !matches!(t, Token::Space(n) if n > 0)) {
|
||||
if let Some(node) = p.span_if(|p| node(p, &mut false)) {
|
||||
contents.push(node);
|
||||
}
|
||||
}
|
||||
|
@ -87,10 +87,6 @@ fn Text(text: &str) -> Node {
|
||||
Node::Text(text.into())
|
||||
}
|
||||
|
||||
fn Heading(level: impl Into<Spanned<u8>>, contents: Tree) -> Node {
|
||||
Node::Heading(NodeHeading { level: level.into(), contents })
|
||||
}
|
||||
|
||||
fn Raw(lang: Option<&str>, lines: &[&str], inline: bool) -> Node {
|
||||
Node::Raw(NodeRaw {
|
||||
lang: lang.map(|id| Ident(id.into())),
|
||||
@ -246,47 +242,6 @@ fn test_parse_simple_nodes() {
|
||||
S(1..2, "unexpected closing brace")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_headings() {
|
||||
// Basics with spans.
|
||||
t!("# a"
|
||||
nodes: [S(0..3, Heading(S(0..1, 0), Template![
|
||||
@S(1..2, Space), S(2..3, Text("a"))
|
||||
]))],
|
||||
spans: true);
|
||||
|
||||
// Multiple hashtags.
|
||||
t!("### three" Heading(2, Template![@Space, Text("three")]));
|
||||
t!("###### six" Heading(5, Template![@Space, Text("six")]));
|
||||
|
||||
// Start of heading.
|
||||
t!("/**/#" Heading(0, Template![@]));
|
||||
t!("[f][# ok]" Call!("f", Args![Template![Heading(0, Template![
|
||||
@Space, Text("ok")
|
||||
])]]));
|
||||
|
||||
// End of heading.
|
||||
t!("# a\nb" Heading(0, Template![@Space, Text("a")]), Space, Text("b"));
|
||||
|
||||
// Continued heading.
|
||||
t!("# a{\n1\n}b" Heading(0, Template![
|
||||
@Space, Text("a"), Block!(Int(1)), Text("b")
|
||||
]));
|
||||
t!("# a[f][\n\n]d" Heading(0, Template![@
|
||||
Space, Text("a"), Call!("f", Args![Template![Parbreak]]), Text("d"),
|
||||
]));
|
||||
|
||||
// No heading.
|
||||
t!(r"\#" Text("#"));
|
||||
t!("Nr. #1" Text("Nr."), Space, Text("#"), Text("1"));
|
||||
t!("[v]#" Call!("v"), Text("#"));
|
||||
|
||||
// Too many hashtags.
|
||||
t!("####### seven"
|
||||
nodes: [Heading(5, Template![@Space, Text("seven")])],
|
||||
warnings: [S(0..7, "section depth should not exceed 6")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw() {
|
||||
// Basic, mostly tested in tokenizer and resolver.
|
||||
|
@ -567,6 +567,7 @@ mod tests {
|
||||
// Test markup tokens.
|
||||
t!(Markup[" a1"]: "*" => Star);
|
||||
t!(Markup: "_" => Underscore);
|
||||
t!(Markup[""]: "###" => Hash, Hash, Hash);
|
||||
t!(Markup["a1/"]: "# " => Hash, Space(0));
|
||||
t!(Markup: "~" => Tilde);
|
||||
t!(Markup[" "]: r"\" => Backslash);
|
||||
|
BIN
tests/ref/headings.png
Normal file
BIN
tests/ref/headings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
40
tests/typ/headings.typ
Normal file
40
tests/typ/headings.typ
Normal file
@ -0,0 +1,40 @@
|
||||
// Number of hashtags.
|
||||
//
|
||||
// warning: 5:1-5:8 section depth should not exceed 6
|
||||
|
||||
# One
|
||||
### Three
|
||||
###### Six
|
||||
####### Seven
|
||||
|
||||
---
|
||||
// Is a heading.
|
||||
|
||||
/**/ # Heading
|
||||
{[## Heading]}
|
||||
[box][### Heading]
|
||||
|
||||
---
|
||||
// Is no heading.
|
||||
//
|
||||
// error: 4:1-4:6 unexpected invalid token
|
||||
|
||||
\# No heading
|
||||
|
||||
Text with # hashtag
|
||||
|
||||
#nope
|
||||
|
||||
---
|
||||
// Heading continues over linebreak.
|
||||
|
||||
# This {
|
||||
"works"
|
||||
}
|
||||
|
||||
# [box][
|
||||
This
|
||||
] too
|
||||
|
||||
# This
|
||||
does not
|
Loading…
x
Reference in New Issue
Block a user