1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
//! A simple markdown parser that can write formatted text to the terminal
//!
//! Entrypoint is `MdStream::parse_str(...)`
use std::io;
use termcolor::{Buffer, BufferWriter, ColorChoice};
mod parse;
mod term;
/// An AST representation of a Markdown document
#[derive(Clone, Debug, Default, PartialEq)]
pub struct MdStream<'a>(Vec<MdTree<'a>>);
impl<'a> MdStream<'a> {
/// Parse a markdown string to a tokenstream
#[must_use]
pub fn parse_str(s: &str) -> MdStream<'_> {
parse::entrypoint(s)
}
/// Write formatted output to a termcolor buffer
pub fn write_termcolor_buf(&self, buf: &mut Buffer) -> io::Result<()> {
term::entrypoint(self, buf)
}
}
/// Create a termcolor buffer with the `Always` color choice
pub fn create_stdout_bufwtr() -> BufferWriter {
BufferWriter::stdout(ColorChoice::Always)
}
/// A single tokentree within a Markdown document
#[derive(Clone, Debug, PartialEq)]
pub enum MdTree<'a> {
/// Leaf types
Comment(&'a str),
CodeBlock {
txt: &'a str,
lang: Option<&'a str>,
},
CodeInline(&'a str),
Strong(&'a str),
Emphasis(&'a str),
Strikethrough(&'a str),
PlainText(&'a str),
/// [Foo](www.foo.com) or simple anchor <www.foo.com>
Link {
disp: &'a str,
link: &'a str,
},
/// `[Foo link][ref]`
RefLink {
disp: &'a str,
id: Option<&'a str>,
},
/// [ref]: www.foo.com
LinkDef {
id: &'a str,
link: &'a str,
},
/// Break bewtween two paragraphs (double `\n`), not directly parsed but
/// added later
ParagraphBreak,
/// Break bewtween two lines (single `\n`)
LineBreak,
HorizontalRule,
Heading(u8, MdStream<'a>),
OrderedListItem(u16, MdStream<'a>),
UnorderedListItem(MdStream<'a>),
}
impl<'a> From<Vec<MdTree<'a>>> for MdStream<'a> {
fn from(value: Vec<MdTree<'a>>) -> Self {
Self(value)
}
}