aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authorXe Iaso <me@christine.website>2022-09-20 21:05:44 -0400
committerXe Iaso <me@christine.website>2022-09-20 21:05:44 -0400
commit67005bc59dd918eadcbd9c7c9285aed0c3422292 (patch)
treede54bbad6aa651d4e56517af56a6773f02766fcf /src/app
parent839c44e535d03f8ae747139acd27109e897c76e4 (diff)
downloadxesite-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.rs169
-rw-r--r--src/app/mod.rs3
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">&lt;<b>{name}</b>&gt; "#), 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(),