Skip to main content

sevenmark_parser/parser/markdown/
markdown_header.rs

1use crate::ast::{Element, HeaderElement, Span};
2use crate::parser::ParserInput;
3use crate::parser::element::element_parser;
4use crate::parser::utils::with_depth;
5use winnow::Result;
6use winnow::ascii::line_ending;
7use winnow::combinator::eof;
8use winnow::combinator::{alt, opt, terminated};
9use winnow::prelude::*;
10use winnow::stream::Location as StreamLocation;
11use winnow::token::{literal, take_while};
12
13/// 헤더 파서 - # Header (1-6개의 # 지원, ! 폴딩 지원)
14pub fn markdown_header_parser(parser_input: &mut ParserInput) -> Result<Element> {
15    if parser_input.state.current_depth() > 0 {
16        return Err(winnow::error::ContextError::new());
17    }
18
19    // Check if current position is at line start
20    let current_pos = parser_input.current_token_start();
21    if !parser_input.state.is_at_line_start(current_pos) {
22        return Err(winnow::error::ContextError::new());
23    }
24
25    /*
26    if parser_input.state.inside_header {
27        return Err(winnow::error::ContextError::new());
28    }
29    */
30    let start = parser_input.current_token_start();
31    let (header_marks, is_folded, _, parsed_content) = (
32        take_while(1..=6, '#'),
33        opt(literal('!')),
34        opt(literal(' ')),
35        terminated(
36            |input: &mut ParserInput| {
37                input.state.set_header_context();
38                let result = with_depth(input, element_parser);
39                input.state.unset_header_context();
40                result
41            },
42            alt((line_ending, eof)),
43        ),
44    )
45        .parse_next(parser_input)?;
46
47    let end = parser_input.previous_token_end();
48    let header_level = header_marks.len();
49    let is_folded = is_folded.is_some();
50    let section_index = parser_input.state.next_section_index();
51
52    Ok(Element::Header(HeaderElement {
53        span: Span { start, end },
54        level: header_level,
55        is_folded,
56        section_index,
57        children: parsed_content,
58    }))
59}