diff options
author | Martin Fischer <martin@push-f.com> | 2022-10-28 08:58:12 +0200 |
---|---|---|
committer | Martin Fischer <martin@push-f.com> | 2022-10-28 12:05:09 +0200 |
commit | 0b699948d33c6b209439e2eb77c60c220130dc6b (patch) | |
tree | 9a042f9c787d4e5854869c31db22644fa040f380 /src/main.rs | |
parent | d2b0892241d9a5bbdf6b701cc7c8c182c9a6c727 (diff) |
implement lua-based templates
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs index 2cd3a5d..e2fea85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,6 @@ use hyper::StatusCode; use hyper::{Body, Server}; use origins::HttpOrigin; use percent_encoding::percent_decode_str; -use pulldown_cmark::html; use pulldown_cmark::Options; use pulldown_cmark::Parser; use serde::Deserialize; @@ -28,6 +27,7 @@ use sputnik::request::SputnikParts; use sputnik::response::SputnikBuilder; use std::convert::Infallible; use std::env; +use std::fmt::Write; use std::path::Path; use std::sync::Arc; @@ -516,14 +516,53 @@ enum RenderMode { Preview, } -fn render_markdown(input: &str, page: &mut Page, _mode: RenderMode) { - let parser = Parser::new_ext(input, Options::all()); +fn render_markdown(text: &str, page: &mut Page, _mode: RenderMode, ctx: &Context) { + let md_options = Options::all(); + page.body.push_str("<div class=markdown-output>"); - html::push_html(&mut page.body, parser); + #[cfg(feature = "lua")] + { + use lua::template::{parse_call_args, Sub}; + + let (text, state) = lua::template::preprocess(text); + let parser = Parser::new_ext(&text, md_options); + let mut out = String::new(); + pulldown_cmark::html::push_html(&mut out, parser); + + let out = state.postprocess(&out, |sub, out| match *sub { + Sub::Raw(raw) => out.write_str(&html_escape(raw)), + Sub::Pre { attrs, content } => { + write!(out, "<pre {attrs}>{}</pre>", html_escape(content)) + } + Sub::StrayToken(_, text) => out.write_str(&html_escape(text)), + Sub::Call(text) => { + let (modfn, args) = parse_call_args(text); + + // TODO: cache module source code to avoid unnecessary git reads for repeated templates + match lua::call(&modfn, args, ctx) { + Ok(output) => out.write_str(&output), + Err(err) => write!( + out, + "<span class=error>{}: {}</span>", + html_escape(modfn.module_name), // TODO: link module + &html_escape(err.to_string()), + ), + } + } + }); + page.body.push_str(&out); + } + #[cfg(not(feature = "lua"))] + { + let parser = Parser::new_ext(text, md_options); + let mut out = String::new(); + pulldown_cmark::html::push_html(&mut out, parser); + page.body.push_str(&out); + } page.body.push_str("</div>"); } -fn get_renderer(path: &Utf8Path) -> Option<fn(&str, &mut Page, RenderMode)> { +fn get_renderer(path: &Utf8Path) -> Option<fn(&str, &mut Page, RenderMode, ctx: &Context)> { match path.extension() { Some("md") => Some(render_markdown), _ => None, |