smart-markdown 0.3.0

Parse and render Markdown to ANSI-styled terminal output with live in-place refresh
Documentation
#[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());
    }
}