harper_core/parsers/
oops_all_headings.rs

1use crate::{Span, Token, TokenKind};
2
3use super::Parser;
4
5/// A parser that wraps another, forcing the entirety of the document to be composed of headings.
6pub struct OopsAllHeadings<P: Parser + 'static> {
7    inner: P,
8}
9
10impl<P: Parser + 'static> OopsAllHeadings<P> {
11    pub fn new(inner: P) -> Self {
12        Self { inner }
13    }
14}
15
16impl<P: Parser + 'static> Parser for OopsAllHeadings<P> {
17    fn parse(&self, source: &[char]) -> Vec<Token> {
18        let inner = self.inner.parse(source);
19        let mut output = Vec::with_capacity(inner.capacity());
20
21        output.push(Token {
22            span: Span::default(),
23            kind: TokenKind::HeadingStart,
24        });
25
26        let mut iter = inner.into_iter().peekable();
27
28        while let Some(tok) = iter.next() {
29            let heading_start = if tok.kind.is_paragraph_break()
30                && iter.peek().is_some_and(|t| !t.kind.is_heading_start())
31            {
32                Some(Token {
33                    span: Span::new_with_len(tok.span.end, 0),
34                    kind: TokenKind::HeadingStart,
35                })
36            } else {
37                None
38            };
39
40            output.push(tok);
41
42            if let Some(extra) = heading_start {
43                output.push(extra);
44            }
45        }
46
47        output
48    }
49}