Skip to main content

markdown_that/plugins/cmark/block/
code.rs

1//! Indented code block
2//!
3//! Parses anything indented with 4 spaces.
4//!
5//! <https://spec.commonmark.org/0.30/#indented-code-block>
6use crate::parser::block::{BlockRule, BlockState};
7use crate::{MarkdownThat, Node, NodeValue, Renderer};
8
9const CODE_INDENT: i32 = 4;
10
11#[derive(Debug)]
12pub struct CodeBlock {
13    pub content: String,
14}
15
16impl NodeValue for CodeBlock {
17    fn render(&self, node: &Node, fmt: &mut dyn Renderer) {
18        fmt.cr();
19        fmt.open("pre", &[]);
20        fmt.open("code", &node.attrs);
21        fmt.text(&self.content);
22        fmt.close("code");
23        fmt.close("pre");
24        fmt.cr();
25    }
26}
27
28pub fn add(md: &mut MarkdownThat) {
29    md.block.add_rule::<CodeScanner>();
30    md.max_indent = CODE_INDENT;
31}
32
33#[doc(hidden)]
34pub struct CodeScanner;
35impl BlockRule for CodeScanner {
36    fn check(_: &mut BlockState) -> Option<()> {
37        None
38    }
39
40    fn run(state: &mut BlockState) -> Option<(Node, usize)> {
41        if state.line_indent(state.line) < CODE_INDENT {
42            return None;
43        }
44
45        let mut next_line = state.line + 1;
46        let mut last = next_line;
47
48        while next_line < state.line_max {
49            if state.is_empty(next_line) {
50                next_line += 1;
51                continue;
52            }
53
54            if state.line_indent(next_line) >= CODE_INDENT {
55                next_line += 1;
56                last = next_line;
57                continue;
58            }
59
60            break;
61        }
62
63        let (mut content, _mapping) = state.get_lines(
64            state.line,
65            last,
66            CODE_INDENT as usize + state.blk_indent,
67            false,
68        );
69        content += "\n";
70
71        let node = Node::new(CodeBlock { content });
72        //node.srcmap = state.get_map_from_offsets(mapping[0].1, state.line_offsets[last - 1].line_end);
73
74        Some((node, last - state.line))
75    }
76}