From bf3341850b8d7d3f01af2492c101997dd8b0c365 Mon Sep 17 00:00:00 2001 From: Maciej Jur Date: Sun, 25 Aug 2024 12:13:07 +0200 Subject: [PATCH] flox article --- content/projects/flox.md | 48 ++++++++++++++++++++++++++++++++ src/html/mod.rs | 60 +++++++++++++++++++++++++++++++++++++--- src/html/post.rs | 34 ++++++++++++++++------- src/main.rs | 10 ++----- 4 files changed, 130 insertions(+), 22 deletions(-) create mode 100644 content/projects/flox.md diff --git a/content/projects/flox.md b/content/projects/flox.md new file mode 100644 index 0000000..e856773 --- /dev/null +++ b/content/projects/flox.md @@ -0,0 +1,48 @@ +--- +title: Flox +date: 2024-08-25T09:59:41Z +desc: > + Small functional language written in Rust and compiled to WebAssembly +--- + +## Grammar + +``` +Program ::= Sequence "EOF" +Sequence ::= Expression? (";" Expression)* + +Expression ::= Data + | Match + | Let + | If + | While + | Return + | Block + | Assignment + +Data ::= "data" IDENTIFIER ("|" IDENTIFIER (IDENTIFIER)*)* +Match ::= "match" Expression ( "|" Expression IDENTIFIER* "->" Expression )* +Let ::= "let" IDENTIFIER (IDENTIFIER)* "=" Expression +If ::= "if" Expression Expression ("else" Expression)? +While ::= "while" Expression Expression +Return ::= "return" Expression? +Block ::= "{" Sequence "}" +Assignment ::= Call ("=" Assignment)? +Call ::= Index (Index)* +Index ::= Primary ("." IDENTIFIER)? + +Primary ::= IDENTIFIER + | NUMBER + | STRING + | "true" + | "false" + | "nil" + | Lambda + | Parenthesized + | Array + +Lambda ::= "fn" IDENTIFIER+ "->" Expression +Parenthesized ::= "(" (Expression ("," Expression)*)? ")" +Array ::= "[" (Expression ("," Expression)*)? "]" +Arguments ::= "(" (Expression ("," Expression)*)? ")" +``` diff --git a/src/html/mod.rs b/src/html/mod.rs index 2a19ef0..4c557ca 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -10,13 +10,16 @@ mod head; use std::collections::HashMap; -use camino::Utf8Path; -use chrono::Datelike; -use hauchiwa::{LinkDate, Sack}; +use camino::{Utf8Path, Utf8PathBuf}; +use chrono::{DateTime, Datelike, Utc}; +use hauchiwa::{Bibliography, Content, Link, LinkDate, Linkable, Outline, Sack}; +use hayagriva::Library; use hypertext::{html_elements, maud, maud_move, GlobalAttributes, Raw, Renderable}; pub(crate) use home::home; +use post::article; pub(crate) use post::Post; +use serde::Deserialize; pub(crate) use slideshow::Slideshow; pub(crate) use wiki::Wiki; @@ -215,8 +218,56 @@ where } -pub(crate) fn editor<'s, 'html>(sack: &'s Sack) -> impl Renderable + 'html +/// Represents a simple post. +#[derive(Deserialize, Debug, Clone)] +pub(crate) struct Flox { + pub(crate) title: String, + #[serde(with = "isodate")] + pub(crate) date: DateTime, + pub(crate) desc: Option, +} + +impl Content for Flox { + fn parse_content( + content: &str, + sack: &Sack, + path: &Utf8Path, + library: Option<&Library>, + ) -> (String, Outline, Bibliography) { + crate::text::md::parse(content, sack, path, library) + } + + fn as_html( + &self, + parsed: &str, + sack: &Sack, + outline: Outline, + bibliography: Bibliography, + ) -> String { + flox(&self.title, parsed, sack, outline, bibliography).render().into() + } + + fn as_link(&self, path: Utf8PathBuf) -> Option { + Some(Linkable::Date(LinkDate { + link: Link { + path, + name: self.title.to_owned(), + desc: self.desc.to_owned(), + }, + date: self.date.to_owned(), + })) + } +} + +pub(crate) fn flox<'p, 's, 'html>( + title: &'p str, + parsed: &'p str, + sack: &'s Sack, + outline: Outline, + bibliography: Bibliography, +) -> impl Renderable + 'html where + 'p: 'html, 's: 'html, { page( @@ -238,6 +289,7 @@ where pre #output {} } } + (article(title, parsed, sack, outline, bibliography)) } script type="module" { (Raw("import 'editor';")) } ), diff --git a/src/html/post.rs b/src/html/post.rs index 5dc2257..062c655 100644 --- a/src/html/post.rs +++ b/src/html/post.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use camino::{Utf8Path, Utf8PathBuf}; use chrono::{DateTime, Utc}; use hauchiwa::{Bibliography, Content, Link, LinkDate, Linkable, Outline, Sack}; @@ -59,9 +57,28 @@ where 's: 'html, 'p: 'html, { - let heading = metadata.title.clone(); - let main = maud_move!( - main .wiki-main { + let main = maud_move!( + main { + (article(&metadata.title, parsed, sack, outline, bibliography)) + } + ); + + crate::html::page(sack, main, metadata.title.clone()) +} + +pub fn article<'p, 's, 'html>( + title: &'p str, + parsed: &'p str, + _: &'s Sack, + outline: Outline, + bibliography: Bibliography, +) -> impl Renderable + 'html +where + 's: 'html, + 'p: 'html, +{ + maud_move!( + div .wiki-main { // Slide in/out for mobile input #wiki-aside-shown type="checkbox" hidden; @@ -76,7 +93,7 @@ where article .wiki-article /*class:list={classlist)*/ { header class="markdown" { - h1 #top { (heading) } + h1 #top { (title) } } section .wiki-article__markdown.markdown { (Raw(parsed)) @@ -87,8 +104,5 @@ where } } } - ); - - crate::html::page(sack, main, metadata.title.clone()) + ) } - diff --git a/src/main.rs b/src/main.rs index 04986b5..2dddd1f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ mod ts; use clap::{Parser, ValueEnum}; use hauchiwa::Website; -use html::{Post, Slideshow, Wiki}; +use html::{Flox, Post, Slideshow, Wiki}; use hypertext::Renderable; #[derive(Parser, Debug, Clone)] @@ -27,7 +27,7 @@ fn main() { .content::("content/posts/**/*", ["md", "mdx"].into()) .content::("content/slides/**/*", ["md", "lhs"].into()) .content::("content/wiki/**/*", ["md"].into()) - .content::("content/projects/**/*", ["md"].into()) + .content::("content/projects/flox.md", ["md"].into()) .js("search", "./js/search/dist/search.js") .js("photos", "./js/vanilla/photos.js") .js("reveal", "./js/vanilla/reveal.js") @@ -40,12 +40,6 @@ fn main() { |sack| crate::html::search(sack).render().to_owned().into(), "search/index.html".into(), ) - .add_virtual_linked( - |sack| crate::html::editor(sack).render().to_owned().into(), - "projects/flox/index.html".into(), - "Flox".into(), - "Small functional language written in Rust and compiled to WebAssembly.".into() - ) .add_virtual( |sack| crate::html::to_list(sack, sack.get_links("projects/**/*.html"), "Projects".into()), "projects/index.html".into(),