1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::{MarkdownIt, Node, NodeValue, Renderer};
use crate::parser::block::{BlockRule, BlockState};
#[derive(Debug)]
pub struct ThematicBreak {
pub marker: char,
pub marker_len: usize,
}
impl NodeValue for ThematicBreak {
fn render(&self, node: &Node, fmt: &mut dyn Renderer) {
fmt.cr();
fmt.self_close("hr", &node.attrs);
fmt.cr();
}
}
pub fn add(md: &mut MarkdownIt) {
md.block.add_rule::<HrScanner>();
}
#[doc(hidden)]
pub struct HrScanner;
impl BlockRule for HrScanner {
fn run(state: &mut BlockState, silent: bool) -> bool {
if state.line_indent(state.line) >= 4 { return false; }
let mut chars = state.get_line(state.line).chars();
let marker = if let Some(ch @ ('*' | '-' | '_')) = chars.next() {
ch
} else {
return false;
};
let mut cnt = 1;
for ch in chars {
if ch == marker {
cnt += 1;
} else if ch != ' ' && ch != '\t' {
return false;
}
}
if cnt < 3 { return false; }
if silent { return true; }
let mut node = Node::new(ThematicBreak { marker, marker_len: cnt });
node.srcmap = state.get_map(state.line, state.line);
state.node.children.push(node);
state.line += 1;
true
}
}