add tags to model

This commit is contained in:
Maciej Jur 2024-09-23 23:22:37 +02:00
parent de976814f1
commit c74b1499a4
Signed by: kamov
GPG key ID: 191CBFF5F72ECAFD
13 changed files with 380 additions and 320 deletions

View file

@ -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:

View file

@ -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.

View file

@ -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#"
##

View file

@ -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<S>(
// date: &DateTime<Utc>,
// serializer: S,
// ) -> Result<S::Ok, S::Error>
// where
// S: Serializer,
// {
// let s = date.to_rfc3339();
// serializer.serialize_str(&s)
// }
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, 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())
}

View file

@ -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 {

View file

@ -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"),

View file

@ -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<Utc>,
pub desc: Option<String>,
pub scripts: Option<Vec<String>>,
}
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))
}
}
)

View file

@ -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<Utc>,
pub desc: Option<String>,
}
pub fn parse_content(
content: &str,
sack: &MySack,

View file

@ -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,

View file

@ -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 {

53
src/model.rs Normal file
View file

@ -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<Utc>,
pub desc: Option<String>,
pub tags: Option<Vec<String>>,
pub scripts: Option<Vec<String>>,
}
/// Represents a slideshow
#[derive(Deserialize, Debug, Clone)]
pub(crate) struct Slideshow {
pub title: String,
#[serde(with = "isodate")]
pub date: DateTime<Utc>,
pub desc: Option<String>,
}
/// 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<S>(
// date: &DateTime<Utc>,
// serializer: S,
// ) -> Result<S::Ok, S::Error>
// where
// S: Serializer,
// {
// let s = date.to_rfc3339();
// serializer.serialize_str(&s)
// }
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, 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())
}
}

View file

@ -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;
}
}
}

View file

@ -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");
}
}
}