use pulldown_cmark::HeadingLevel;
#[allow(clippy::enum_variant_names)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Block {
Heading {
level: HeadingLevel,
inlines: Vec<Inline>,
},
Paragraph {
inlines: Vec<Inline>,
},
CodeBlock {
language: Option<String>,
content: String,
fenced: bool,
},
BlockQuote {
blocks: Vec<Block>,
},
List {
ordered: bool,
start: Option<u64>,
items: Vec<ListItem>,
},
HorizontalRule,
Table {
col_count: usize,
headers: Vec<Vec<Inline>>,
rows: Vec<Vec<Vec<Inline>>>,
user_widths: Option<Vec<Option<usize>>>,
},
Html(String),
HtmlComment(String),
ImageBlock {
alt: String,
url: String,
},
FootnoteDefinition {
label: String,
blocks: Vec<Block>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ListItem {
pub blocks: Vec<Block>,
pub task: Option<bool>,
pub blank_lines_before: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Inline {
Text(String),
Bold(Vec<Inline>),
Italic(Vec<Inline>),
Strikethrough(Vec<Inline>),
Code(String),
Link {
text: Vec<Inline>,
url: String,
title: Option<String>,
},
Image {
alt: String,
url: String,
},
Highlight(Vec<Inline>),
HtmlComment(String),
FootnoteReference {
label: String,
},
SoftBreak,
HardBreak,
}
pub fn heading_plain_text(inlines: &[Inline]) -> String {
inlines_to_plain(inlines).replace('\n', " ")
}
pub fn inlines_to_plain(inlines: &[Inline]) -> String {
let mut out = String::new();
for inline in inlines {
match inline {
Inline::Text(t) => out.push_str(t),
Inline::Bold(inner)
| Inline::Italic(inner)
| Inline::Strikethrough(inner)
| Inline::Highlight(inner) => {
out.push_str(&inlines_to_plain(inner));
}
Inline::Code(c) => out.push_str(c),
Inline::Link { text, .. } => out.push_str(&inlines_to_plain(text)),
Inline::Image { alt, .. } => out.push_str(alt),
Inline::HtmlComment(_) => {}
Inline::FootnoteReference { .. } => {}
Inline::SoftBreak => out.push(' '),
Inline::HardBreak => out.push('\n'),
}
}
out
}