use comrak::{self, ComrakOptions}; use comrak::nodes::AstNode; use crate::Page; use maud::{DOCTYPE, Markup, Render, html}; use std::io; use std::str; struct StringWriter<'a>(&'a mut String); impl<'a> io::Write for StringWriter<'a> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { str::from_utf8(buf) .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err)) .map(|s| { self.0.push_str(s); buf.len() }) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } struct Comrak<'a>(&'a AstNode<'a>, &'a ComrakOptions); impl<'a> Render for Comrak<'a> { fn render_to(&self, buffer: &mut String) { comrak::format_html(self.0, self.1, &mut StringWriter(buffer)).unwrap(); } } struct ComrakText<'a>(&'a AstNode<'a>, &'a ComrakOptions); impl<'a> Render for ComrakText<'a> { fn render_to(&self, buffer: &mut String) { comrak::format_commonmark(self.0, self.1, &mut StringWriter(buffer)).unwrap(); } } crate fn main<'a>( options: &'a ComrakOptions, slug: &str, page: Page<'a>, nav: &[(&str, Option<&str>)], ) -> Markup { html! { (DOCTYPE) meta charset="utf-8"; title { @if let Some(title) = page.title { (ComrakText(title, options)) " \u{2013} " } "Maud, a macro for writing HTML" } link rel="stylesheet" href="styles.css"; meta name="theme-color" content="#808"; meta name="viewport" content="width=device-width"; header { h1 { a href="." { "maud" } } } nav { ul { @for &(other_slug, other_title) in nav { @if let Some(title) = other_title { li { @if other_slug == slug { b { (title) } } @else { a href={ (other_slug) ".html" } { (title) } } } } } } ul { li { a href="https://docs.rs/maud/" { "API documentation" } } li { a href="https://github.com/lfairy/maud" { "GitHub" } } } } main { @if let Some(title) = page.title { h2 { (Comrak(title, options)) } } (Comrak(page.content, options)) } } }