use crate::model::Key;
use super::config::MarkdownOptions;
use super::inline::{Inline, Inlines};
use super::node::{ColumnAlignment, Node, ReferenceType};
use super::projector::Projector;
use super::writer::{blocks_to_markdown_sparce, blocks_to_markdown_sparce_skip_frontmatter};
pub trait NodeIter<'a>: Sized {
fn next(&self) -> Option<Self>;
fn child(&self) -> Option<Self>;
fn node(&self) -> Option<Node>;
fn to_markdown(self, parent: &str, options: &MarkdownOptions) -> String {
let blocks = Projector::project(self, parent);
blocks_to_markdown_sparce(&blocks, options)
}
fn to_markdown_skip_frontmatter(self, parent: &str, options: &MarkdownOptions) -> String {
let blocks = Projector::project(self, parent);
blocks_to_markdown_sparce_skip_frontmatter(&blocks, options)
}
fn plain_text(&self) -> String {
self.inlines().iter().map(|i| i.plain_text()).collect()
}
fn to_default_markdown(self) -> String {
self.to_markdown("", &MarkdownOptions::default())
}
fn ref_type(&self) -> Option<ReferenceType> {
self.node().and_then(|node| {
if let Node::Reference(reference) = node {
Some(reference.reference_type)
} else {
None
}
})
}
fn lang(&self) -> Option<String> {
self.node().and_then(|node| {
if let Node::Raw(lang, _) = node {
lang.clone()
} else {
None
}
})
}
fn table_header(&self) -> Option<Vec<Inlines>> {
self.node().and_then(|node| {
if let Node::Table(table) = node {
Some(table.header.clone())
} else {
None
}
})
}
fn table_alignment(&self) -> Option<Vec<ColumnAlignment>> {
self.node().and_then(|node| {
if let Node::Table(table) = node {
Some(table.alignment.clone())
} else {
None
}
})
}
fn table_rows(&self) -> Option<Vec<Vec<Inlines>>> {
self.node().and_then(|node| {
if let Node::Table(table) = node {
Some(table.rows.clone())
} else {
None
}
})
}
fn content(&self) -> Option<String> {
self.node().and_then(|node| {
if let Node::Raw(_, content) = node {
Some(content.clone())
} else {
None
}
})
}
fn ref_text(&self) -> Option<String> {
self.node().and_then(|node| {
if let Node::Reference(reference) = node {
Some(reference.text.clone())
} else {
None
}
})
}
fn ref_key2(&self) -> Option<Key> {
self.node().and_then(|node| {
if let Node::Reference(reference) = node {
Some(reference.key.clone())
} else {
None
}
})
}
fn inlines(&self) -> Inlines {
self.node()
.map(|node| match node {
Node::Section(inlines) => inlines.clone(),
Node::Leaf(inlines) => inlines.clone(),
Node::Item(_, inlines) => inlines.clone(),
Node::Reference(reference) => vec![Inline::Str(reference.text)],
_ => vec![],
})
.unwrap_or_default()
}
fn is_item(&self) -> bool {
matches!(self.node(), Some(Node::Item(_, _)))
}
fn item_checked(&self) -> Option<bool> {
self.node().and_then(|node| {
if let Node::Item(checked, _) = node {
checked
} else {
None
}
})
}
fn is_list(&self) -> bool {
self.is_ordered_list() || self.is_bullet_list()
}
fn is_document(&self) -> bool {
matches!(self.node(), Some(Node::Document(_, _)))
}
fn is_section(&self) -> bool {
matches!(self.node(), Some(Node::Section(_)))
}
fn is_ordered_list(&self) -> bool {
matches!(self.node(), Some(Node::OrderedList()))
}
fn is_bullet_list(&self) -> bool {
matches!(self.node(), Some(Node::BulletList()))
}
fn is_reference(&self) -> bool {
matches!(self.node(), Some(Node::Reference(_)))
}
fn is_horizontal_rule(&self) -> bool {
matches!(self.node(), Some(Node::HorizontalRule()))
}
fn is_raw(&self) -> bool {
matches!(self.node(), Some(Node::Raw(_, _)))
}
fn is_leaf(&self) -> bool {
matches!(self.node(), Some(Node::Leaf(_)))
}
fn is_quote(&self) -> bool {
matches!(self.node(), Some(Node::Quote()))
}
}