#[derive(Debug, Clone, Default)]
pub struct Attributes {
inner: Vec<(String, String)>,
}
impl Attributes {
#[inline]
pub fn new() -> Self {
Self { inner: Vec::new() }
}
#[inline]
pub fn with_capacity(cap: usize) -> Self {
Self { inner: Vec::with_capacity(cap) }
}
#[inline]
pub fn get(&self, key: &str) -> Option<&String> {
for (k, v) in &self.inner {
if k == key {
return Some(v);
}
}
None
}
#[inline]
pub fn contains_key(&self, key: &str) -> bool {
self.inner.iter().any(|(k, _)| k == key)
}
#[inline]
pub fn insert(&mut self, key: String, value: String) {
for (k, v) in &mut self.inner {
if *k == key {
*v = value;
return;
}
}
self.inner.push((key, value));
}
#[inline]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
#[inline]
pub fn clear(&mut self) {
self.inner.clear();
}
#[inline]
pub fn iter(&self) -> std::slice::Iter<'_, (String, String)> {
self.inner.iter()
}
}
#[derive(Debug, Clone)]
pub struct TailwindData {
pub prefix: Option<String>,
pub suffix: Option<String>,
pub hidden: bool,
}
#[derive(Debug, Clone)]
pub struct ElementNode {
pub attributes: Attributes,
pub tailwind: Option<Box<TailwindData>>,
pub custom_name: Option<String>,
pub depth: usize,
pub index: usize,
pub current_walk_index: usize,
pub child_text_node_index: usize,
pub tag_id: Option<u8>,
pub contains_whitespace: bool,
pub excluded_from_markdown: bool,
pub is_inline: bool,
pub excludes_text_nodes: bool,
pub is_non_nesting: bool,
pub collapses_inner_white_space: bool,
pub spacing: Option<[u8; 2]>,
}
impl ElementNode {
#[inline]
pub fn name(&self) -> &str {
if let Some(ref n) = self.custom_name {
n.as_str()
} else if let Some(id) = self.tag_id {
crate::consts::TAG_NAMES[id as usize]
} else {
""
}
}
}
#[derive(Clone, Copy)]
pub struct TagHandler {
pub is_self_closing: bool,
pub is_non_nesting: bool,
pub collapses_inner_white_space: bool,
pub is_inline: bool,
pub spacing: Option<[u8; 2]>,
pub excludes_text_nodes: bool,
pub needs_attributes: bool,
}
#[derive(Debug, Clone, Default)]
pub struct FilterConfig {
pub include: Option<Vec<String>>,
pub exclude: Option<Vec<String>>,
pub process_children: Option<bool>,
}
#[derive(Debug, Clone, Default)]
pub struct IsolateMainConfig {
}
#[derive(Debug, Clone, Default)]
pub struct FrontmatterConfig {
pub additional_fields: Option<Vec<(String, String)>>,
pub meta_fields: Option<Vec<String>>,
}
#[derive(Debug, Clone, Default)]
pub struct TailwindConfig {
}
#[derive(Debug, Clone, Default)]
pub struct ExtractionConfig {
pub selectors: Vec<String>,
}
#[derive(Debug, Clone)]
pub enum ParsedSelector {
Tag(String),
Class(String),
Id(String),
Attribute { name: String, operator: Option<String>, value: Option<String> },
Compound(Vec<Self>),
}
#[derive(Debug, Clone)]
pub struct ExtractedElement {
pub selector: String,
pub tag_name: String,
pub text_content: String,
pub attributes: Vec<(String, String)>,
}
#[derive(Debug, Clone)]
pub struct TagOverrideConfig {
pub enter: Option<String>,
pub exit: Option<String>,
pub spacing: Option<[u8; 2]>,
pub is_inline: Option<bool>,
pub is_self_closing: Option<bool>,
pub collapses_inner_white_space: Option<bool>,
pub alias_tag_id: Option<u8>,
}
#[derive(Debug, Clone, Default)]
pub struct PluginConfig {
pub filter: Option<FilterConfig>,
pub isolate_main: Option<IsolateMainConfig>,
pub frontmatter: Option<FrontmatterConfig>,
pub tailwind: Option<TailwindConfig>,
pub extraction: Option<ExtractionConfig>,
pub tag_overrides: Option<Vec<(String, TagOverrideConfig)>>,
}
#[derive(Debug, Clone, Default)]
pub struct CleanConfig {
pub urls: bool,
pub fragments: bool,
pub empty_links: bool,
pub blank_lines: bool,
pub redundant_links: bool,
pub self_link_headings: bool,
pub empty_images: bool,
pub empty_link_text: bool,
}
#[derive(Debug, Clone, Default)]
pub struct HTMLToMarkdownOptions {
pub origin: Option<String>,
pub clean_urls: bool,
pub clean: Option<CleanConfig>,
pub plugins: Option<PluginConfig>,
}
pub struct MdreamResult {
pub markdown: String,
pub extracted: Option<Vec<ExtractedElement>>,
pub frontmatter: Option<Vec<(String, String)>>,
}