use std::collections::BTreeMap;
use zenith_core::{Document, MdBlock, Node, TextNode, parse_block_markdown, parse_inline_markdown};
pub(super) type MdBlockMap = BTreeMap<String, Vec<MdBlock>>;
pub(super) fn scan_for_markdown_text(doc: &Document) -> bool {
for page in &doc.body.pages {
for node in &page.children {
if node_has_markdown_text(node) {
return true;
}
}
}
false
}
fn node_has_markdown_text(node: &Node) -> bool {
match node {
Node::Text(n) => n.content_format.as_deref() == Some("markdown"),
Node::Frame(n) => n.children.iter().any(node_has_markdown_text),
Node::Group(n) => n.children.iter().any(node_has_markdown_text),
Node::Table(n) => n.rows.iter().any(|row| {
row.cells
.iter()
.any(|cell| cell.children.iter().any(node_has_markdown_text))
}),
Node::Unknown(n) => n.children.iter().any(node_has_markdown_text),
Node::Rect(_)
| Node::Ellipse(_)
| Node::Line(_)
| Node::Code(_)
| Node::Image(_)
| Node::Polygon(_)
| Node::Polyline(_)
| Node::Field(_)
| Node::Footnote(_)
| Node::Toc(_)
| Node::Shape(_)
| Node::Connector(_)
| Node::Instance(_)
| Node::Pattern(_)
| Node::Chart(_) => false,
}
}
pub(super) fn resolve_markdown(doc: &mut Document) -> MdBlockMap {
let mut blocks: MdBlockMap = MdBlockMap::new();
for page in &mut doc.body.pages {
for node in &mut page.children {
resolve_node(node, &mut blocks);
}
}
blocks
}
fn resolve_node(node: &mut Node, blocks: &mut MdBlockMap) {
match node {
Node::Text(n) => resolve_text(n, blocks),
Node::Frame(n) => {
for child in &mut n.children {
resolve_node(child, blocks);
}
}
Node::Group(n) => {
for child in &mut n.children {
resolve_node(child, blocks);
}
}
Node::Table(n) => {
for row in &mut n.rows {
for cell in &mut row.cells {
for child in &mut cell.children {
resolve_node(child, blocks);
}
}
}
}
Node::Unknown(n) => {
for child in &mut n.children {
resolve_node(child, blocks);
}
}
Node::Rect(_)
| Node::Ellipse(_)
| Node::Line(_)
| Node::Code(_)
| Node::Image(_)
| Node::Polygon(_)
| Node::Polyline(_)
| Node::Field(_)
| Node::Footnote(_)
| Node::Toc(_)
| Node::Shape(_)
| Node::Connector(_)
| Node::Instance(_)
| Node::Pattern(_)
| Node::Chart(_) => {}
}
}
fn resolve_text(node: &mut TextNode, blocks: &mut MdBlockMap) {
if node.content_format.as_deref() != Some("markdown") {
return;
}
let content: String = node.spans.iter().map(|s| s.text.as_str()).collect();
blocks.insert(node.id.clone(), parse_block_markdown(&content));
node.spans = parse_inline_markdown(&content);
}