diff options
| author | Xe Iaso <me@christine.website> | 2022-09-20 21:05:44 -0400 |
|---|---|---|
| committer | Xe Iaso <me@christine.website> | 2022-09-20 21:05:44 -0400 |
| commit | 67005bc59dd918eadcbd9c7c9285aed0c3422292 (patch) | |
| tree | de54bbad6aa651d4e56517af56a6773f02766fcf /src/app | |
| parent | 839c44e535d03f8ae747139acd27109e897c76e4 (diff) | |
| download | xesite-67005bc59dd918eadcbd9c7c9285aed0c3422292.tar.xz xesite-67005bc59dd918eadcbd9c7c9285aed0c3422292.zip | |
move markdown and templates into a dedicated crate
This does not move the ructe templates around, only the newer Maud ones.
The only template I can't move easily is the salary history one, but I
should get rid of that anyways.
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/markdown.rs | 169 | ||||
| -rw-r--r-- | src/app/mod.rs | 3 |
2 files changed, 1 insertions, 171 deletions
diff --git a/src/app/markdown.rs b/src/app/markdown.rs deleted file mode 100644 index 9c3266e..0000000 --- a/src/app/markdown.rs +++ /dev/null @@ -1,169 +0,0 @@ -use crate::app::Config; -use crate::templates::Html; -use color_eyre::eyre::{Result, WrapErr}; -use comrak::nodes::{Ast, AstNode, NodeValue}; -use comrak::plugins::syntect::SyntectAdapter; -use comrak::{ - format_html_with_plugins, markdown_to_html_with_plugins, parse_document, Arena, ComrakOptions, - ComrakPlugins, -}; -use lazy_static::lazy_static; -use lol_html::{element, html_content::ContentType, rewrite_str, RewriteStrSettings}; -use std::cell::RefCell; -use std::sync::Arc; -use url::Url; - -lazy_static! { - static ref SYNTECT_ADAPTER: SyntectAdapter<'static> = SyntectAdapter::new("base16-mocha.dark"); -} - -pub fn render(cfg: Arc<Config>, inp: &str) -> Result<String> { - let mut options = ComrakOptions::default(); - - options.extension.autolink = true; - options.extension.table = true; - options.extension.description_lists = true; - options.extension.superscript = true; - options.extension.strikethrough = true; - options.extension.footnotes = true; - - options.render.unsafe_ = true; - - let arena = Arena::new(); - let root = parse_document(&arena, inp, &options); - - let mut plugins = ComrakPlugins::default(); - plugins.render.codefence_syntax_highlighter = Some(&*SYNTECT_ADAPTER); - - iter_nodes(root, &|node| { - let mut data = node.data.borrow_mut(); - match &mut data.value { - &mut NodeValue::Link(ref mut link) => { - let base = Url::parse("https://xeiaso.net/")?; - let u = base.join(std::str::from_utf8(&link.url.clone())?)?; - if u.scheme() != "conversation" { - return Ok(()); - } - let parent = node.parent().unwrap(); - node.detach(); - let mut message = vec![]; - for child in node.children() { - format_html_with_plugins(child, &options, &mut message, &plugins)?; - } - let message = std::str::from_utf8(&message)?; - let mut message = markdown_to_html_with_plugins(message, &options, &plugins); - crop_letters(&mut message, 3); - message.drain((message.len() - 5)..); - let mood = without_first(u.path()); - let name = u.host_str().unwrap_or("Mara"); - - let mut html = vec![]; - crate::templates::mara(&mut html, mood, name, Html(message.trim().into()))?; - - let new_node = arena.alloc(AstNode::new(RefCell::new(Ast::new( - NodeValue::HtmlInline(html), - )))); - parent.append(new_node); - - Ok(()) - } - _ => Ok(()), - } - })?; - - let mut html = vec![]; - format_html_with_plugins(root, &options, &mut html, &plugins).unwrap(); - - let html = String::from_utf8(html).wrap_err("post is somehow invalid UTF-8")?; - - let html = rewrite_str(&html, RewriteStrSettings{ - element_content_handlers: vec![ - element!("xeblog-conv", |el| { - let name = el.get_attribute("name").expect("wanted xeblog-conv to contain name"); - let name_lower = name.clone().to_lowercase(); - let mood = el.get_attribute("mood").expect("wanted xeblog-conv to contain mood"); - - el.before(&format!(r#" -<div class="conversation"> - <div class="conversation-picture conversation-smol"> - <picture> - <source srcset="https://cdn.xeiaso.net/file/christine-static/stickers/{name_lower}/{mood}.avif" type="image/avif"> - <source srcset="https://cdn.xeiaso.net/file/christine-static/stickers/{name_lower}/{mood}.webp" type="image/webp"> - <img src="https://cdn.xeiaso.net/file/christine-static/stickers/{name_lower}/{mood}.png" alt="{name} is {mood}"> - </picture> - </div> - <div class="conversation-chat"><<b>{name}</b>> "#), ContentType::Html); - el.after("</div></div>", ContentType::Html); - - el.remove_and_keep_content(); - Ok(()) - }), - element!("xeblog-picture", |el| { - let path = el.get_attribute("path").expect("wanted xeblog-picture to contain path"); - el.replace(&crate::tmpl::xeblog_picture(path).0, ContentType::Html); - Ok(()) - }), - element!("xeblog-hero", |el| { - let file = el.get_attribute("file").expect("wanted xeblog-hero to contain file"); - el.replace(&crate::tmpl::xeblog_hero(file, el.get_attribute("prompt"), el.get_attribute("ai")).0, ContentType::Html); - Ok(()) - }), - element!("xeblog-salary-history", |el| { - el.replace(&crate::tmpl::xeblog_salary_history(cfg.clone()).0, ContentType::Html); - - Ok(()) - }), - element!("xeblog-sticker", |el| { - let name = el.get_attribute("name").expect("wanted xeblog-sticker to contain name"); - let mood = el.get_attribute("mood").expect("wanted xeblog-sticker to contain mood"); - el.replace(&crate::tmpl::xeblog_sticker(name, mood).0, ContentType::Html); - - Ok(()) - }), - element!("xeblog-slide", |el| { - let name = el.get_attribute("name").expect("wanted xeblog-slide to contain name"); - let essential = el.get_attribute("essential").is_some(); - el.replace(&crate::tmpl::xeblog_slide(name, essential).0, ContentType::Html); - - Ok(()) - }), - element!("xeblog-talk-warning", |el| { - el.replace(&crate::tmpl::xeblog_talk_warning().0, ContentType::Html); - Ok(()) - }), - ], - ..RewriteStrSettings::default() - }).unwrap(); - - Ok(html) -} - -fn iter_nodes<'a, F>(node: &'a AstNode<'a>, f: &F) -> Result<()> -where - F: Fn(&'a AstNode<'a>) -> Result<()>, -{ - f(node)?; - for c in node.children() { - iter_nodes(c, f)?; - } - Ok(()) -} - -fn without_first(string: &str) -> &str { - string - .char_indices() - .nth(1) - .and_then(|(i, _)| string.get(i..)) - .unwrap_or("") -} - -fn crop_letters(s: &mut String, pos: usize) { - match s.char_indices().nth(pos) { - Some((pos, _)) => { - s.drain(..pos); - } - None => { - s.clear(); - } - } -} diff --git a/src/app/mod.rs b/src/app/mod.rs index 5b8e719..9a331a4 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -5,7 +5,6 @@ use std::{fs, path::PathBuf, sync::Arc}; use tracing::{error, instrument}; pub mod config; -pub mod markdown; pub mod poke; pub use config::*; @@ -64,7 +63,7 @@ pub async fn init(cfg: PathBuf) -> Result<State> { let cfg: Arc<Config> = Arc::new(serde_dhall::from_file(cfg).parse()?); let sb = cfg.signalboost.clone(); let resume = fs::read_to_string(cfg.clone().resume_fname.clone())?; - let resume: String = markdown::render(cfg.clone(), &resume)?; + let resume: String = xesite_markdown::render(&resume)?; let mi = mi::Client::new( cfg.clone().mi_token.clone(), crate::APPLICATION_NAME.to_string(), |
