svenstaro/miniserve

rendering markdown files?

Opened this issue · 6 comments

I use miniserve to browse /usr/share/doc and for this rendering the README.md file github style is great. Many times the whole documentation of a package is in markdown (.md) files.

Since the capability is there I was wondering if an option to allow automatic rendering of markdown files would be a possible/useful feature to add?

It might be too much to ask for in miniserve, but there is the https://github.com/xyproto/algernon web server which can render markdown.

What would be the approximate difference in terms of source code complexity and runtime resource usage between rendering Readme.md and rendering an arbitrary markdown file named differently?

The code might be simple to write and integrate, but there is an added maintenance burden for every new feature, aka feature creep. Tomorrow the next person would want a word/powerpoint renderer.
I agree this is a nice to have feature for markdown, not a must have.

I actually think this would be fine for miniserve. A markdown renderer seems reasonable. We shouldn't add any other specific renderers, though.

Since I had this actually opened in another tab...

/// Load a markdown file, render to HTML, and return the response.
async fn md_path_to_html(path: &Path) -> Result<Response<Body>> {
    // Render Markdown like GitHub
    let mut options = ComrakOptions::default();
    options.ext_autolink = true;
    options.ext_header_ids = None;
    options.ext_table = true;
    options.ext_strikethrough = true;
    options.ext_tagfilter = true;
    options.ext_tasklist = true;
    options.github_pre_lang = true;
    options.ext_header_ids = Some("user-content-".to_string());

    let buf = tokio::fs::read(path).await?;
    let s = String::from_utf8(buf).map_err(|_| Error::MarkdownUtf8)?;
    let html = comrak::markdown_to_html(&s, &options);
    let cfg = HtmlCfg {
        title: String::new(),
        body: html,
    };
    let html = super::render_html(cfg)?;

    Response::builder()
        .status(StatusCode::OK)
        .header(header::CONTENT_LENGTH, html.len() as u64)
        .header(header::CONTENT_TYPE, mime::TEXT_HTML.as_ref())
        .body(Body::from(html))
        .map_err(Error::from)
}

That's the implementation of the basic-http-server
Line 67 in ext.rs

miniserve already renders Markdown using Comrak so this should be rather easy if there are any takers. :)