//! Parse markdown text. //! //! Extended from cursive::utils::markup::markdown to add code styles //! TODO: Bring in the full power of termimad (e.g. md tables) in a View; //! implementation of those features (.e.g automatic wrapping within each table //! cell) might be easier in this setting anyway. // TODO use ColorStyle::secondary() etc. over specific enums use cursive::theme::{Effect, PaletteColor, Style}; use cursive::utils::markup::{StyledIndexedSpan, StyledString}; use cursive::utils::span::{IndexedCow, IndexedSpan}; use pulldown_cmark::{self, CowStr, Event, Options, Tag}; pub type Markdown = StyledString; /// Parses the given string as markdown text. /// **Note**: Assumes preprocessing has taken place pub fn parse(input: S) -> StyledString where S: Into, { let input = input.into(); let spans = parse_spans(&input); //let output = build_output(&spans); StyledString::with_spans(input, spans) } pub fn preprocess(input: String) -> String { input .as_str() .trim() .replace("", "**[") .replace("", "]**") } /// Preview markdown of the given length /// Currently removes any color (i.e. code highlighting) to avoid /// the jarring issue of a fragmented highlight style on focused items. pub fn preview(width: usize, input: &StyledString) -> StyledString { let mut w = 0; let mut new_spans = Vec::new(); for span in input.spans_raw() { // Filter newlines if span.width == 0 { w += 1; new_spans.push(drop_color(IndexedSpan { content: IndexedCow::Owned(" ".to_owned()), width: 1, ..*span })); } else { w += span.width; new_spans.push(drop_color(span.clone())); } if w > width { break; } } let mut prev = StyledString::with_spans(input.source(), new_spans); prev.append_plain("..."); prev } fn drop_color(span: StyledIndexedSpan) -> StyledIndexedSpan { IndexedSpan { attr: Style { color: Default::default(), ..span.attr }, ..span } } /// Parse the given markdown text into a list of spans. /// This is a shortcut for `Parser::new(preprocessed_input).collect()`. fn parse_spans(input: &str) -> Vec { Parser::new(input).collect() } /// Iterator that parse a markdown text and outputs styled spans. pub struct Parser<'a> { first: bool, item: Option, in_list: bool, after_code_block: bool, stack: Vec