maud/docs/src/views.rs
2019-09-14 13:48:59 +12:00

104 lines
3 KiB
Rust

use comrak::{self, ComrakOptions};
use comrak::nodes::AstNode;
use crate::Page;
use crate::string_writer::StringWriter;
use maud::{DOCTYPE, Markup, PreEscaped, Render, html};
use std::str;
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();
}
}
/// Hack! Comrak wraps a single line of input in `<p>` tags, which is great in
/// general but not suitable for links in the navigation bar.
struct ComrakRemovePTags<'a>(&'a AstNode<'a>, &'a ComrakOptions);
impl<'a> Render for ComrakRemovePTags<'a> {
fn render(&self) -> Markup {
let mut buffer = String::new();
comrak::format_html(self.0, self.1, &mut StringWriter(&mut buffer)).unwrap();
assert!(buffer.starts_with("<p>") && buffer.ends_with("</p>\n"));
PreEscaped(buffer.trim_start_matches("<p>").trim_end_matches("</p>\n").to_string())
}
}
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, &'a AstNode<'a>)],
) -> 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 {
li {
@if other_slug == slug {
b {
(ComrakRemovePTags(other_title, options))
}
} @else {
a href={ (other_slug) ".html" } {
(ComrakRemovePTags(other_title, options))
}
}
}
}
}
ul {
li {
a href="https://docs.rs/maud/" {
"API documentation"
}
}
li {
a href="https://github.com/lambda-fairy/maud" {
"GitHub"
}
}
}
}
main {
@if let Some(title) = page.title {
h2 {
(Comrak(title, options))
}
}
(Comrak(page.content, options))
}
}
}