Compare commits
2 commits
7f62395071
...
acb2d1991c
Author | SHA1 | Date | |
---|---|---|---|
Adrian Hedqvist | acb2d1991c | ||
Adrian Hedqvist | 97f5fbf901 |
643
Cargo.lock
generated
643
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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"
|
||||
|
|
|
@ -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!")
|
||||
}
|
||||
```
|
||||
|
|
|
@ -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
15
src/hilighting.rs
Normal 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)
|
||||
}
|
|
@ -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
55
src/markdown.rs
Normal 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)
|
||||
}
|
10
src/post.rs
10
src/post.rs
|
@ -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(),
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue