1use markdown_it::parser::block::{BlockRule, BlockState};
2use markdown_it::Node;
3
4use crate::plugin::{get_line_raw, RawBlock};
5
6/// Parse line comments (//) and HTML comments (<!--)
7pub(crate) struct Rule;
8
9impl BlockRule for Rule {
10 fn run(state: &mut BlockState) -> Option<(Node, usize)> {
11 if state.line >= state.line_max {
12 return None;
13 }
14
15 let line = get_line_raw(state, state.line);
16
17 if !line.starts_with("//") && !line.starts_with("<!--") {
18 return None;
19 }
20
21 let (end_line, is_closed) = if line.starts_with("//") {
22 (state.line, true)
23 } else {
24 find_html_comment_end(state, state.line)
25 };
26
27 if !is_closed {
28 return None;
29 }
30
31 let mut content_lines = Vec::new();
32 for line_idx in state.line..=end_line {
33 content_lines.push(get_line_raw(state, line_idx).to_string());
34 }
35
36 let mut content = content_lines.join("\n");
37 content.push('\n');
38
39 Some((Node::new(RawBlock { content }), end_line - state.line + 1))
40 }
41}
42
43/// Find the end line of an HTML comment and whether it's properly closed
44fn find_html_comment_end(state: &BlockState, start_line: usize) -> (usize, bool) {
45 for line_idx in start_line..state.line_max {
46 let line = get_line_raw(state, line_idx);
47 if line.contains("-->") {
48 return (line_idx, true);
49 }
50 }
51 // Comment never closed
52 (state.line_max - 1, false)
53}