This commit adds a heuristics-based syntax highlighter for the `rustc --explain` command. It uses `rsutc_lexer`'s lexer to parse input in tokens, and matches on them to determine their color.
81 lines
2 KiB
Rust
81 lines
2 KiB
Rust
//! A simple markdown parser that can write formatted text to the terminal
|
|
//!
|
|
//! Entrypoint is `MdStream::parse_str(...)`
|
|
|
|
use std::io;
|
|
|
|
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 stdout buffer, optionally with
|
|
/// a formatter for code blocks
|
|
pub fn write_anstream_buf(
|
|
&self,
|
|
buf: &mut Vec<u8>,
|
|
formatter: Option<&(dyn Fn(&str, &mut Vec<u8>) -> io::Result<()> + 'static)>,
|
|
) -> io::Result<()> {
|
|
term::entrypoint(self, buf, formatter)
|
|
}
|
|
}
|
|
|
|
/// Create an anstream buffer with the `Always` color choice
|
|
pub fn create_stdout_bufwtr() -> anstream::Stdout {
|
|
anstream::Stdout::always(std::io::stdout())
|
|
}
|
|
|
|
/// 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)
|
|
}
|
|
}
|