diff --git a/content/posts/lambda-calculus/index.md b/content/posts/lambda-calculus/index.md index 67d028e..e87127b 100644 --- a/content/posts/lambda-calculus/index.md +++ b/content/posts/lambda-calculus/index.md @@ -1,6 +1,7 @@ --- title: Lambda calculus is the DNA of all computation date: 2024-09-07T20:32:00.281Z +tags: [lambda calculus, fun] desc: > Lambda calculus can be used to express any computation, but what does it entail? As it turns out first class functions are the single most powerful abstraction. scripts: diff --git a/content/posts/remember-forums.md b/content/posts/remember-forums.md index 1a19557..8e7851c 100644 --- a/content/posts/remember-forums.md +++ b/content/posts/remember-forums.md @@ -1,6 +1,7 @@ --- title: Remember forums? date: 2024-09-21T19:14:29.799Z +tags: [thought, internet] desc: > It feels to me like forums are slowly getting forgotten, replaced with more high-paced services like Discord or Twitter. In my opinion this isn't a good thing at all. diff --git a/src/html/home.rs b/src/html/home.rs index 24e5322..ae13b66 100644 --- a/src/html/home.rs +++ b/src/html/home.rs @@ -2,7 +2,7 @@ use camino::Utf8Path; use hauchiwa::Sack; use hypertext::{html_elements, maud, maud_move, GlobalAttributes, Raw, Renderable}; -use crate::{html::Post, text::md::parse, Link, LinkDate, MyData}; +use crate::{model::Post, text::md::parse, Link, LinkDate, MyData}; const INTRO: &str = r#" ## かもし diff --git a/src/html/isodate.rs b/src/html/isodate.rs deleted file mode 100644 index e3d3812..0000000 --- a/src/html/isodate.rs +++ /dev/null @@ -1,24 +0,0 @@ -//! This module is supplementary to Serde, it allows you tu parse JS dates. - -use chrono::{DateTime, Utc}; -use serde::{self, Deserialize, Deserializer}; - -// pub fn serialize( -// date: &DateTime, -// serializer: S, -// ) -> Result -// where -// S: Serializer, -// { -// let s = date.to_rfc3339(); -// serializer.serialize_str(&s) -// } - -pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let s = String::deserialize(deserializer)?; - let dt = chrono::DateTime::parse_from_rfc3339(&s).map_err(serde::de::Error::custom)?; - Ok(dt.into()) -} diff --git a/src/html/misc.rs b/src/html/misc.rs index 62e46bb..a616301 100644 --- a/src/html/misc.rs +++ b/src/html/misc.rs @@ -4,7 +4,7 @@ use camino::Utf8Path; use hauchiwa::Outline; use hypertext::{html_elements, maud_move, GlobalAttributes, Raw, Renderable}; -use crate::{html::Wiki, Link, MySack}; +use crate::{model::Wiki, Link, MySack}; /// Render the outline for a document pub(crate) fn show_outline(outline: Outline) -> impl Renderable { diff --git a/src/html/mod.rs b/src/html/mod.rs index 73b4150..84d86fe 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -1,6 +1,5 @@ mod head; mod home; -mod isodate; mod list; mod misc; pub mod post; @@ -16,11 +15,8 @@ use hypertext::{html_elements, maud, maud_move, GlobalAttributes, Raw, Renderabl pub(crate) use home::home; use post::article; -pub(crate) use post::Post; -pub(crate) use slideshow::Slideshow; -pub(crate) use wiki::Wiki; -use crate::{LinkDate, MySack}; +use crate::{model::Post, LinkDate, MySack}; fn navbar() -> impl Renderable { static ITEMS: &[(&str, &str)] = &[ @@ -219,11 +215,11 @@ pub fn as_html( outline: Outline, bibliography: Bibliography, ) -> String { - flox(&meta.title, parsed, sack, outline, bibliography) + flox(meta, parsed, sack, outline, bibliography) } pub(crate) fn flox( - title: &str, + meta: &Post, parsed: &str, sack: &MySack, outline: Outline, @@ -248,7 +244,7 @@ pub(crate) fn flox( pre #output {} } } - (article(title, parsed, sack, outline, bibliography)) + (article(meta, parsed, sack, outline, bibliography)) } ), String::from("Flox"), diff --git a/src/html/post.rs b/src/html/post.rs index 5d60e13..b3b34f7 100644 --- a/src/html/post.rs +++ b/src/html/post.rs @@ -1,21 +1,9 @@ use camino::Utf8Path; -use chrono::{DateTime, Utc}; use hauchiwa::{Bibliography, Outline}; use hayagriva::Library; -use hypertext::{html_elements, maud_move, GlobalAttributes, Raw, Renderable}; -use serde::Deserialize; +use hypertext::{html_elements, maud_move, rsx, rsx_move, GlobalAttributes, Raw, Renderable}; -use crate::MySack; - -/// Represents a simple post. -#[derive(Deserialize, Debug, Clone)] -pub struct Post { - pub title: String, - #[serde(with = "super::isodate")] - pub date: DateTime, - pub desc: Option, - pub scripts: Option>, -} +use crate::{model::Post, MySack}; pub fn parse_content( content: &str, @@ -52,7 +40,7 @@ where { let main = maud_move!( main { - (article(&meta.title, parsed, sack, outline, bibliography)) + (article(meta, parsed, sack, outline, bibliography)) } ); @@ -60,7 +48,7 @@ where } pub fn article<'p, 's, 'html>( - title: &'p str, + meta: &'p Post, parsed: &'p str, _: &'s MySack, outline: Outline, @@ -84,17 +72,37 @@ where (crate::html::misc::show_outline(outline)) } - article .wiki-article /*class:list={classlist)*/ { - header class="markdown" { - h1 #top { (title) } - } - section .wiki-article__markdown.markdown { - (Raw(parsed)) - } + (paper_page(meta, parsed, bibliography)) + } + ) +} - @if let Some(bib) = bibliography.0 { - (crate::html::misc::emit_bibliography(bib)) +fn paper_page<'a>(meta: &'a Post, parsed: &'a str, bib: Bibliography) -> impl Renderable + 'a { + maud_move!( + article .wiki-article { + header { + h1 #top { + (&meta.title) } + div .line { + div .date { + (meta.date.format("%Y-%m-%d").to_string()) + } + @if let Some(ref tags) = meta.tags { + ul .tags { + @for tag in tags { + li { (tag) } + } + } + } + } + } + section .wiki-article__markdown.markdown { + (Raw(parsed)) + } + + @if let Some(bib) = bib.0 { + (crate::html::misc::emit_bibliography(bib)) } } ) diff --git a/src/html/slideshow.rs b/src/html/slideshow.rs index 969cca7..b839a5b 100644 --- a/src/html/slideshow.rs +++ b/src/html/slideshow.rs @@ -1,13 +1,11 @@ use std::fmt::Write; use camino::Utf8Path; -use chrono::{DateTime, Utc}; use hauchiwa::{Bibliography, Outline}; use hayagriva::Library; use hypertext::{html_elements, maud, GlobalAttributes, Raw, Renderable}; -use serde::Deserialize; -use crate::MySack; +use crate::{model::Slideshow, MySack}; const CSS: &str = r#" .slides img { @@ -17,15 +15,6 @@ const CSS: &str = r#" } "#; -/// Represents a slideshow -#[derive(Deserialize, Debug, Clone)] -pub(crate) struct Slideshow { - pub title: String, - #[serde(with = "super::isodate")] - pub date: DateTime, - pub desc: Option, -} - pub fn parse_content( content: &str, sack: &MySack, diff --git a/src/html/wiki.rs b/src/html/wiki.rs index a83dc10..4effb48 100644 --- a/src/html/wiki.rs +++ b/src/html/wiki.rs @@ -2,15 +2,8 @@ use camino::Utf8Path; use hauchiwa::{Bibliography, Outline}; use hayagriva::Library; use hypertext::{html_elements, maud_move, GlobalAttributes, Raw, Renderable}; -use serde::Deserialize; -use crate::MySack; - -/// Represents a wiki page -#[derive(Deserialize, Debug, Clone)] -pub struct Wiki { - pub title: String, -} +use crate::{model::Wiki, MySack}; pub fn parse_content( content: &str, diff --git a/src/main.rs b/src/main.rs index 30026d3..6ab2599 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod html; +mod model; mod text; mod ts; @@ -8,8 +9,8 @@ use camino::{Utf8Path, Utf8PathBuf}; use chrono::{DateTime, Datelike, Utc}; use clap::{Parser, ValueEnum}; use hauchiwa::{Collection, Processor, Sack, Website}; -use html::{Post, Slideshow, Wiki}; use hypertext::Renderable; +use model::{Post, Slideshow, Wiki}; #[derive(Parser, Debug, Clone)] struct Args { diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 0000000..50174d5 --- /dev/null +++ b/src/model.rs @@ -0,0 +1,53 @@ +use chrono::{DateTime, Utc}; +use serde::Deserialize; + +/// Represents a simple post. +#[derive(Deserialize, Debug, Clone)] +pub struct Post { + pub title: String, + #[serde(with = "isodate")] + pub date: DateTime, + pub desc: Option, + pub tags: Option>, + pub scripts: Option>, +} + +/// Represents a slideshow +#[derive(Deserialize, Debug, Clone)] +pub(crate) struct Slideshow { + pub title: String, + #[serde(with = "isodate")] + pub date: DateTime, + pub desc: Option, +} + +/// Represents a wiki page +#[derive(Deserialize, Debug, Clone)] +pub struct Wiki { + pub title: String, +} + +mod isodate { + use chrono::{DateTime, Utc}; + use serde::{self, Deserialize, Deserializer}; + + // pub fn serialize( + // date: &DateTime, + // serializer: S, + // ) -> Result + // where + // S: Serializer, + // { + // let s = date.to_rfc3339(); + // serializer.serialize_str(&s) + // } + + pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + let dt = chrono::DateTime::parse_from_rfc3339(&s).map_err(serde::de::Error::custom)?; + Ok(dt.into()) + } +} diff --git a/styles/_markdown.scss b/styles/_markdown.scss index 64bb521..d8ffd56 100644 --- a/styles/_markdown.scss +++ b/styles/_markdown.scss @@ -1,191 +1,200 @@ .markdown { - h1 { - font-size: 2.5rem; - } + h1 { + font-size: 2.5rem; + } - h2 { - font-size: 1.8rem; - } + h2 { + font-size: 1.8rem; + } - h3 { - font-size: 1.5rem; - } + h3 { + font-size: 1.5rem; + } - h4, > h5, > h6 { - font-size: 1.2rem; - } + h4, + > h5, + > h6 { + font-size: 1.2rem; + } - p { - margin: 0.5em 0; - hyphens: auto; - text-align: justify; - line-height: 1.5em; - } + p { + margin: 0.5em 0; + hyphens: auto; + text-align: justify; + line-height: 1.5em; + } - ul, ol { - padding-left: 1em; + ul, + ol { + padding-left: 1em; - ul, ol { - padding-left: 1em; - } - } + ul, + ol { + padding-left: 1em; + } + } - li { - line-height: 1.5em; - } + li { + line-height: 1.5em; + } - a { - color: var(--c-primary); - font-family: var(--serif); - font-weight: 500; - font-style: italic; - text-decoration: unset; + a { + color: var(--c-primary); + font-family: var(--serif); + font-weight: 500; + font-style: italic; + text-decoration: unset; - &:hover { - text-decoration: underline; - } - } + &:hover { + text-decoration: underline; + } + } - > h1, > h2, > h3, > h4, > h5, > h6 { - margin-bottom: 0.5em; - font-family: var(--serif); - font-weight: 500; + > h1, + > h2, + > h3, + > h4, + > h5, + > h6 { + margin-bottom: 0.5em; + font-family: var(--serif); + font-weight: 500; - &:not(:first-child) { - margin-top: 1em; - } - } + &:not(:first-child) { + margin-top: 1em; + } + } + img:not([class]) { + max-width: 100%; + height: auto; + margin-block: 1em; + } - img:not([class]) { - max-width: 100%; - height: auto; - margin-block: 1em; - } + blockquote { + position: relative; + margin: 1em 2em; - blockquote { - position: relative; - margin: 1em 2em; + &::before { + content: ""; + display: block; + position: absolute; + left: -1em; + width: 4px; + height: 100%; + background-color: var(--c-secondary); + border-radius: 2px; + } + } - &::before { - content: ""; - display: block; - position: absolute; - left: -1em; - width: 4px; - height: 100%; - background-color: var(--c-secondary); - border-radius: 2px; - } - } + > table { + margin: 1em auto 1em auto; + border-collapse: collapse; + overflow-x: auto; - > table { - margin: 1em auto 1em auto; - border-collapse: collapse; - overflow-x: auto; + th, + td { + padding: 0.2em 0.5em; + border: 1px solid #dbdbdb; + } - th, td { - padding: 0.2em 0.5em; - border: 1px solid #dbdbdb; - } + th { + background-color: #f3f3f3; + } - th { - background-color: #f3f3f3; - } + p { + white-space: pre-line; + } + } - p { - white-space: pre-line; - } - } + code { + font-family: var(--monospace); + } - code { - font-family: var(--monospace); - } + :not(pre) > code { + padding-inline: 0.25em; + background-color: white; + border-radius: 0.33em; + border: 1px dashed lightgray; + } - :not(pre) > code { - padding-inline: 0.25em; - background-color: white; - border-radius: 0.33em; - border: 1px dashed lightgray; - } + .listing { + position: relative; + margin: 1em -1em; + border-width: 0.25em 0; + border-style: solid; - .listing { - position: relative; - margin: 1em -1em; - border-width: 0.25em 0; - border-style: solid; + @media (min-width: 600px) { + margin: 1em 0.5em; + border-width: 0.25rem; + border-radius: 0.5rem; + } - @media (min-width: 600px) { - margin: 1em 0.5em; - border-width: 0.25rem; - border-radius: 0.5rem; - } + &::before { + content: attr(data-lang); + display: block; + top: 0; + right: 0; + position: absolute; + padding: 0.1em 0.2em 0 0.3em; + border-radius: 0 0 0 0.5rem; + } - &::before { - content: attr(data-lang); - display: block; - top: 0; - right: 0; - position: absolute; - padding: 0.1em 0.2em 0 0.3em; - border-radius: 0 0 0 0.5rem; - } + pre { + padding: 0.5em; + max-width: 100%; + overflow-x: auto; + tab-size: 2; - pre { - padding: 0.5em; - max-width: 100%; - overflow-x: auto; - tab-size: 2; + > code { + display: block; + line-height: 1.5em; + } + } + } - > code { - display: block; - line-height: 1.5em; - } - } - } + .math-display { + margin-block: 1em; + font-size: 1.1em; + overflow-x: auto; + overflow-y: hidden; + } - .math-display { - margin-block: 1em; - font-size: 1.1em; - overflow-x: auto; - overflow-y: hidden; - } + .marginnote { + display: block; + margin: 1em 1.5em; + padding-block: 0.5em; + border-block: 1px dashed gray; + color: gray; - .marginnote { - display: block; - margin: 1em 1.5em; - padding-block: 0.5em; - border-block: 1px dashed gray; - color: gray; + @media (min-width: 38em) { + float: right; + clear: right; + max-width: 14rem; + margin-right: 0; + text-align: justify; + hyphens: auto; + } - @media (min-width: 38em) { - float: right; - clear: right; - max-width: 14rem; - margin-right: 0; - text-align: justify; - hyphens: auto; - } + @media (min-width: 80em) { + margin: 2em -17rem; + } - @media (min-width: 80em) { - margin: 2em -17rem; - } + a { + color: var(--c-primary); + } + } - a { - color: var(--c-primary); - } - } + // TODO: clean this + .md-icon { + display: inline-block; + height: 1.2em; + width: auto; + vertical-align: middle; + margin: 0.1em 0; - // TODO: clean this - .md-icon { - display: inline-block; - height: 1.2em; - width: auto; - vertical-align: middle; - margin: 0.1em 0; - - &.big { - height: 4em; - } - } + &.big { + height: 4em; + } + } } diff --git a/styles/layouts/_page.scss b/styles/layouts/_page.scss index f2f9248..5358667 100644 --- a/styles/layouts/_page.scss +++ b/styles/layouts/_page.scss @@ -1,115 +1,148 @@ $bp-m: 58rem; $bp-l: 80rem; - .wiki-main { - position: relative; - display: grid; - grid-template-columns: auto minmax(0, 1fr); + position: relative; + display: grid; + grid-template-columns: auto minmax(0, 1fr); - @media (min-width: $bp-m) { - grid-template-columns: 16rem minmax(0, 1fr); - } + @media (min-width: $bp-m) { + grid-template-columns: 16rem minmax(0, 1fr); + } - @media (min-width: $bp-l) { - grid-template-columns: 16rem minmax(0, 1fr) 16rem; - } + @media (min-width: $bp-l) { + grid-template-columns: 16rem minmax(0, 1fr) 16rem; + } } .wiki-aside { - position: absolute; - width: 16rem; - height: 100%; - transition: margin-left linear 0.1s; - background-color: var(--c-bg-main); - z-index: 5; + position: absolute; + width: 16rem; + height: 100%; + transition: margin-left linear 0.1s; + background-color: var(--c-bg-main); + z-index: 5; - @media (min-width: $bp-m) { - position: static; - background-color: unset; - } + @media (min-width: $bp-m) { + position: static; + background-color: unset; + } - .link-tree { - position: sticky; - top: 0; - } + .link-tree { + position: sticky; + top: 0; + } - &__slider { - position: absolute; - top: 0.5em; - right: -2em; - cursor: pointer; + &__slider { + position: absolute; + top: 0.5em; + right: -2em; + cursor: pointer; - @media (min-width: $bp-m) { - display: none; - } - } + @media (min-width: $bp-m) { + display: none; + } + } } #wiki-aside-shown { - &:checked { - ~ .wiki-aside { - box-shadow: var(--shadow-m); + &:checked { + ~ .wiki-aside { + box-shadow: var(--shadow-m); - @media (min-width: $bp-m) { - box-shadow: unset; - } + @media (min-width: $bp-m) { + box-shadow: unset; + } - > .wiki-aside__slider { - transform: rotate(180deg); - } - } - } + > .wiki-aside__slider { + transform: rotate(180deg); + } + } + } - &:not(:checked) { - ~ .wiki-aside { - margin-left: -16rem; + &:not(:checked) { + ~ .wiki-aside { + margin-left: -16rem; - @media (min-width: $bp-m) { - margin-left: unset; - } - } - } + @media (min-width: $bp-m) { + margin-left: unset; + } + } + } } .wiki-icon { - max-height: 1.5em; - max-width: 1.5em; + max-height: 1.5em; + max-width: 1.5em; } .wiki-article { - min-width: 0; - margin-inline: auto; - padding: 1em; - padding-top: 2em; - background-color: white; - transition: margin ease-in-out 0.2s, padding ease-in-out 0.2s; + min-width: 0; + margin-inline: auto; + padding: 1em; + padding-top: 2em; + background-color: white; + transition: + margin ease-in-out 0.2s, + padding ease-in-out 0.2s; - @media (min-width: $bp-m) { - max-width: min(100%, 50em); - height: fit-content; - margin-block: 1em; - padding-top: 1em; - border-radius: 0.5em; - box-shadow: var(--shadow-l); - } + @media (min-width: $bp-m) { + max-width: min(100%, 50em); + height: fit-content; + margin-block: 1em; + padding-top: 1em; + border-radius: 0.5em; + box-shadow: var(--shadow-l); + } - @media (min-width: $bp-l) { - margin-block: 2em; - padding: 2em; - } + @media (min-width: $bp-l) { + margin-block: 2em; + padding: 2em; + } - &__markdown { - max-width: calc(100vw - 2em); - } + header { + margin-bottom: 1em; - &.has-icon { - background-position: top right; - background-repeat: no-repeat; - background-size: 20% auto; + h1 { + font-size: 2.5rem; + font-family: var(--serif); + font-weight: 500; + line-height: 1em; + margin-bottom: 0.3em; + } - &.icon-haskell { - background-image: url("/static/sketch/haskell.png"); - } - } + .line { + display: flex; + flex-direction: row; + gap: 0.5em; + } + + .tags { + display: inline; + list-style: none; + padding: 0px; + + li { + display: inline; + + &:not(:last-child)::after { + content: ", "; + } + } + } + } + + &__markdown { + max-width: calc(100vw - 2em); + } + + &.has-icon { + background-position: top right; + background-repeat: no-repeat; + background-size: 20% auto; + + &.icon-haskell { + background-image: url("/static/sketch/haskell.png"); + } + } }