#[derive(Debug, Clone)]
pub enum MarkdownElement {
Heading {
level: u8,
text: String,
},
Paragraph {
text: String,
},
CodeBlock {
#[allow(dead_code)]
language: Option<String>,
lines: Vec<String>,
},
Blockquote {
text: String,
},
OrderedList {
items: Vec<String>,
start: u64,
depth: u8,
},
UnorderedList {
items: Vec<String>,
depth: u8,
},
Table(TableDef),
HtmlBlock {
lines: Vec<String>,
},
HorizontalRule,
TaskList {
items: Vec<TaskItem>,
depth: u8,
},
FootnoteSection {
items: Vec<FootnoteDef>,
},
DefinitionList {
items: Vec<(String, Vec<String>)>,
},
BlankLine,
}
#[derive(Debug, Clone)]
pub struct TaskItem {
pub checked: bool,
pub text: String,
}
#[derive(Debug, Clone)]
pub struct FootnoteDef {
pub id: String,
pub text: String,
}
#[derive(Debug, Clone)]
pub struct TableDef {
pub headers: Vec<String>,
pub alignments: Vec<Alignment>,
pub rows: Vec<Vec<String>>,
}
impl TableDef {
pub fn has_fill_column(&self) -> bool {
self.headers.iter().any(|h| {
let h = h.trim();
h.is_empty()
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Alignment {
Left,
Center,
Right,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn has_fill_column_with_empty_header() {
let td = TableDef {
headers: vec!["col1".into(), "".into()],
alignments: vec![Alignment::Left, Alignment::Left],
rows: vec![],
};
assert!(td.has_fill_column());
}
#[test]
fn no_fill_column_when_all_named() {
let td = TableDef {
headers: vec!["col1".into(), "col2".into()],
alignments: vec![Alignment::Left, Alignment::Left],
rows: vec![],
};
assert!(!td.has_fill_column());
}
#[test]
fn has_fill_column_with_whitespace_only() {
let td = TableDef {
headers: vec!["col1".into(), " ".into()],
alignments: vec![Alignment::Left, Alignment::Left],
rows: vec![],
};
assert!(td.has_fill_column());
}
}