Skip to main content

sim_codec_doc/markup/
decode.rs

1use std::collections::BTreeMap;
2
3use crate::document::{DocBlockKind, DocValue, decode_document};
4
5use super::expr::format_name;
6use super::{BackendId, Inline, MarkupBlock, MarkupDoc, SourceDoc, Span, SpanState};
7
8/// Decode source text into the shared markup IR using the current lightweight
9/// document parser.
10pub fn decode_markup_doc(source: &str) -> MarkupDoc {
11    MarkupDoc::from_doc_value(&decode_document(source))
12}
13
14impl MarkupDoc {
15    pub(crate) fn from_doc_value(doc: &DocValue) -> Self {
16        let title = doc
17            .blocks
18            .iter()
19            .find(|block| block.kind == DocBlockKind::Heading && block.level == Some(1))
20            .map(|block| block.text.clone());
21        let blocks = doc
22            .blocks
23            .iter()
24            .map(|block| {
25                let span = Some(Span {
26                    start: block.start,
27                    end: block.end,
28                    state: SpanState::Preserved,
29                });
30                match block.kind {
31                    DocBlockKind::Heading => MarkupBlock::Heading {
32                        level: block.level.unwrap_or(1).clamp(1, 6) as u8,
33                        text: vec![Inline::Text(block.text.clone())],
34                        id: None,
35                        span,
36                    },
37                    DocBlockKind::Paragraph => MarkupBlock::Paragraph {
38                        content: vec![Inline::Text(block.text.clone())],
39                        span,
40                    },
41                }
42            })
43            .collect();
44        Self {
45            title,
46            blocks,
47            attrs: BTreeMap::new(),
48            source: Some(SourceDoc {
49                backend: BackendId(format_name(doc.format).to_owned()),
50                text: doc.text.clone(),
51            }),
52        }
53    }
54}