use super::custom::CustomNode;
use super::html::HtmlElement;
use std::boxed::Box;
#[derive(Debug, Clone, PartialEq, Default)]
pub enum CodeBlockType {
Indented,
#[default]
Fenced,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub enum HeadingType {
#[default]
Atx,
Setext,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Node {
Document(Vec<Node>),
ThematicBreak,
Heading {
level: u8,
content: Vec<Node>,
heading_type: HeadingType,
},
CodeBlock {
language: Option<String>,
content: String,
block_type: CodeBlockType,
},
HtmlBlock(String),
LinkReferenceDefinition {
label: String,
destination: String,
title: Option<String>,
},
Paragraph(Vec<Node>),
BlockQuote(Vec<Node>),
OrderedList {
start: u32,
items: Vec<ListItem>,
},
UnorderedList(Vec<ListItem>),
Table {
headers: Vec<Node>,
rows: Vec<Vec<Node>>,
},
InlineCode(String),
Emphasis(Vec<Node>),
Strong(Vec<Node>),
Link {
url: String,
title: Option<String>,
content: Vec<Node>,
},
ReferenceLink {
label: String,
content: Vec<Node>,
},
Image {
url: String,
title: Option<String>,
alt: Vec<Node>,
},
Autolink {
url: String,
is_email: bool,
},
HtmlElement(HtmlElement),
HardBreak,
SoftBreak,
Text(String),
Custom(Box<dyn CustomNode>),
}
impl Default for Node {
fn default() -> Self {
Node::Document(vec![])
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ListItem {
Unordered {
content: Vec<Node>,
},
Ordered {
number: Option<u32>,
content: Vec<Node>,
},
}
impl Node {
pub fn is_block(&self) -> bool {
matches!(
self,
Node::Document(_)
| Node::ThematicBreak
| Node::Heading { .. }
| Node::CodeBlock { .. }
| Node::HtmlBlock(_)
| Node::LinkReferenceDefinition { .. }
| Node::Paragraph(_)
| Node::BlockQuote(_)
| Node::OrderedList { .. }
| Node::UnorderedList(_)
| Node::Table { .. }
| Node::Custom(_)
)
}
pub fn is_inline(&self) -> bool {
matches!(
self,
Node::InlineCode(_)
| Node::Emphasis(_)
| Node::Strong(_)
| Node::Link { .. }
| Node::ReferenceLink { .. }
| Node::Image { .. }
| Node::Autolink { .. }
| Node::HtmlElement(_)
| Node::HardBreak
| Node::SoftBreak
| Node::Text(_)
| Node::Custom(_)
)
}
pub fn heading(level: u8, content: Vec<Node>) -> Self {
Node::Heading {
level,
content,
heading_type: HeadingType::default(),
}
}
pub fn code_block(language: Option<String>, content: String) -> Self {
Node::CodeBlock {
language,
content,
block_type: CodeBlockType::default(),
}
}
}