1
0
Fork 0

Compare commits

...

2 commits

Author SHA1 Message Date
Adrian Hedqvist acb2d1991c Code hilighting 2023-06-18 11:34:08 +02:00
Adrian Hedqvist 97f5fbf901 Update deps 2023-06-18 09:51:36 +02:00
9 changed files with 475 additions and 268 deletions

643
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -13,13 +13,14 @@ color-eyre = "0.6.1"
glob = "0.3.0"
hyper = { version = "0.14.19", features = ["full"] }
lazy_static = "1.4.0"
opentelemetry = { version = "0.18.0", features = ["metrics"] }
opentelemetry = { version = "0.19.0", features = ["metrics"] }
prometheus = { version = "0.13.3", features = ["process"] }
pulldown-cmark = "0.9.2"
regex = "1.7.2"
serde = "1.0.144"
serde_derive = "1.0.144"
serde_json = "1.0.85"
syntect = "5.0.0"
tera = { version = "1.17.0", features = ["builtins"] }
tokio = { version = "1.19.2", features = ["full"] }
toml = "0.7.3"

View file

@ -12,3 +12,11 @@ here have a squid kid miku to test relative paths:
modified post test, see if docker skips build using
its cache if only a post has changed.
code hilighting test:
```rs
fn main() {
println!("Hello world!")
}
```

View file

@ -31,7 +31,7 @@ pub fn render_atom_feed(state: &AppState) -> Result<String> {
posts: &posts,
};
let ctx = tera::Context::from_serialize(&feed)?;
let ctx = tera::Context::from_serialize(feed)?;
Ok(state.tera.render("atom.xml", &ctx)?)
}
@ -58,7 +58,7 @@ pub fn render_atom_tag_feed(tag: &Tag, state: &AppState) -> Result<String> {
posts: &posts,
};
let ctx = tera::Context::from_serialize(&feed)?;
let ctx = tera::Context::from_serialize(feed)?;
Ok(state.tera.render("atom.xml", &ctx)?)
}

15
src/hilighting.rs Normal file
View file

@ -0,0 +1,15 @@
use syntect::{highlighting::ThemeSet, parsing::SyntaxSet};
use tracing::error;
pub fn hilight(content: &str, lang: &str) -> color_eyre::Result<String> {
let ss = SyntaxSet::load_defaults_newlines();
let s = ss.find_syntax_by_extension(lang).unwrap_or_else(|| {
error!("Syntax not found for language: {}", lang);
ss.find_syntax_plain_text()
});
let ts = ThemeSet::load_defaults();
let theme = ts.themes.first_key_value().unwrap().1; // TODO
let res = syntect::html::highlighted_html_for_string(content, &ss, s, theme)?;
Ok(res)
}

View file

@ -14,6 +14,8 @@ use tracing_subscriber::{prelude::*, EnvFilter};
mod feed;
mod handlers;
mod hilighting;
mod markdown;
mod post;
mod tag;

55
src/markdown.rs Normal file
View file

@ -0,0 +1,55 @@
use color_eyre::Result;
use pulldown_cmark::Event;
use pulldown_cmark::Tag;
use pulldown_cmark::{Options, Parser};
use crate::hilighting;
pub fn render_markdown_to_html(markdown: &str) -> Result<String> {
let options = Options::all();
let mut content_html = String::new();
let parser = Parser::new_ext(markdown, options);
let mut code_block = false;
let mut code_lang = None;
let mut code_accumulator = String::new();
let mut events = Vec::new();
for event in parser {
match event {
Event::Text(text) => {
if code_block {
code_accumulator.push_str(&text);
}
else {
events.push(Event::Text(text));
}
}
Event::Start(Tag::CodeBlock(kind)) => {
code_block = true;
if let pulldown_cmark::CodeBlockKind::Fenced(lang) = kind {
code_lang = Some(lang);
}
}
Event::End(Tag::CodeBlock(_)) => {
code_block = false;
let lang = code_lang.take().unwrap_or("".into());
let res = hilighting::hilight(&code_accumulator, &lang).unwrap();
events.push(Event::Html(res.into()));
code_accumulator.clear();
}
_ => events.push(event),
}
}
events.retain(|e| match e {
Event::Text(t) | Event::Html(t) => !t.is_empty(),
_ => true,
});
pulldown_cmark::html::push_html(&mut content_html, events.into_iter());
Ok(content_html)
}

View file

@ -11,7 +11,7 @@ use tokio::fs;
use tracing::{instrument, log::*};
use crate::{AppState, WebsiteError};
use crate::{AppState, WebsiteError, markdown};
#[derive(Deserialize, Debug, Default)]
pub struct TomlFrontMatter {
@ -103,12 +103,8 @@ pub async fn load_post(slug: &str) -> color_eyre::eyre::Result<Post> {
let tomlfm = tomlfm.expect("Missing frontmatter");
let content = content.map(|c| {
let options = Options::all();
let mut content_html = String::new();
let parser = Parser::new_ext(&c, options);
html::push_html(&mut content_html, parser);
content_html
});
markdown::render_markdown_to_html(&c)
}).transpose()?;
Ok(Post::new(
slug.to_string(),

View file

@ -12,9 +12,10 @@
<li>✅ app metrics (page hits, etc)</li>
<li>✅ tests</li>
<li>✅ page aliases (redirects, for back-compat with old routes)</li>
<li>⬜ sass compilation (using rsass? grass?)</li>
<li>✅ rss/atom/jsonfeed (atom is good enough for now)</li>
<li>✅ proper error handling (i guess??)</li>
<li>✅ code hilighting? (good enough for now, gotta figure out themes n' stuff later)</li>
<li>⬜ sass compilation (using rsass? grass?)</li>
<li>⬜ fancy styling</li>
<li>⬜ other pages???</li>
<li>⬜ graphviz to svg rendering??</li>