markdown_ppp/html_printer/
mod.rs

1mod block;
2pub mod config;
3mod index;
4mod inline;
5mod tests;
6mod util;
7
8use crate::ast::*;
9use pretty::{Arena, DocBuilder};
10use std::{collections::HashMap, rc::Rc};
11
12pub(crate) struct State<'a> {
13    arena: Arena<'a>,
14    config: crate::html_printer::config::Config,
15    // Mapping of footnote labels to their indices in the footnote list.
16    footnote_index: HashMap<String, usize>,
17    // Mapping of link labels to their definitions.
18    link_definitions: HashMap<Vec<Inline>, LinkDefinition>,
19}
20
21impl State<'_> {
22    pub fn new(config: crate::html_printer::config::Config, ast: &Document) -> Self {
23        let (footnote_index, link_definitions) = crate::html_printer::index::get_indicies(ast);
24        let arena = Arena::new();
25        Self {
26            arena,
27            config,
28            footnote_index,
29            link_definitions,
30        }
31    }
32
33    pub fn get_footnote_index(&self, label: &str) -> Option<&usize> {
34        self.footnote_index.get(label)
35    }
36
37    pub fn get_link_definition(&self, label: &Vec<Inline>) -> Option<&LinkDefinition> {
38        self.link_definitions.get(label)
39    }
40}
41
42/// Render the given Markdown AST to HTML.
43pub fn render_html(ast: &Document, config: crate::html_printer::config::Config) -> String {
44    let state = Rc::new(State::new(config, ast));
45    let doc = ast.to_doc(&state);
46
47    let mut buf = Vec::new();
48    doc.render(state.config.width, &mut buf).unwrap();
49    String::from_utf8(buf).unwrap()
50}
51
52trait ToDoc<'a> {
53    fn to_doc(&self, state: &'a State<'a>) -> DocBuilder<'a, Arena<'a>, ()>;
54}
55
56impl<'a> ToDoc<'a> for Document {
57    fn to_doc(&self, state: &'a State<'a>) -> DocBuilder<'a, Arena<'a>, ()> {
58        self.blocks.to_doc(state)
59    }
60}