.Str;
- my $out = pygment $code, $lang;
- ## Mangle the html to meet our needs
- # Delete the existing div and construct a
inside the
- $out ~~ s:g/'<' \/? 'div' <-[>]>* '>'//;
- $out ~~ s:g/''//;
- $out ~~ s:g/'
'/<\/code><\/pre>/;
- # Rename the classes to match our needs
- $out ~~ s:g/'span class="' (\w+) '"'/span class="hl-{$/[0].lc}"/;
- $text = $match.replace-with: $out;
- }
- $text
-}
diff --git a/lib/Render/Head.rakumod b/lib/Render/Head.rakumod
deleted file mode 100644
index e7eb435..0000000
--- a/lib/Render/Head.rakumod
+++ /dev/null
@@ -1,68 +0,0 @@
-use v6.e.PREVIEW;
-unit module Render::Head;
-
-use HTML::Functional;
-
-use Render::Util;
-use DB::BlogMeta;
-
-sub generate-head(BlogMeta:D $meta, $title?, $description?) is export {
- head [
- meta :charset;
- meta :name, :content;
- meta :author :content;
- do if $title ~~ Str:D {
- title "$title — {$meta.title}";
- } else {
- title $meta.title;
- }
- # Add description, if one exists
- optl $description ~~ Str:D, -> {meta :description :content($description)};
- # Preconnect to all our resource sources
- link :rel :href;
- link :rel :href;
- link :rel :href :crossorigin;
- link :rel :href;
- # Load fonts, Iosevka for code, Open Sans for content, and boxicons for
- # icons
- link :rel,
- :href;
- link :rel,
- :href;
- link :rel,
- :href;
- # Link our style sheets
- link :rel,
- :href;
- link :rel,
- :href;
- link :rel,
- :href;
- ]
-}
-
-sub site-header(BlogMeta:D $meta) is export {
- sub header-link($name, $path, $icon) {
- a :href("$path"), [
- icon $icon;
- ' ';
- span $name;
- ]
- }
- header :class, [
- div :class, [
- # TODO: Use a real image here
- $meta.title
- ];
- div :class, [
- $meta.tagline
- ];
- div :class, [
- header-link 'Index', '/index.html', 'home';
- header-link 'Archive', '/archive.html', 'archive';
- header-link 'Tags', '/tags.html', 'purchase-tag-alt';
- header-link 'About', '/about.html', 'info-circle';
- header-link 'Feed', '/atom.xml', 'rss';
- ];
- ]
-}
diff --git a/lib/Render/Post.rakumod b/lib/Render/Post.rakumod
deleted file mode 100644
index 826582e..0000000
--- a/lib/Render/Post.rakumod
+++ /dev/null
@@ -1,100 +0,0 @@
-use v6.e.PREVIEW;
-unit module Render::Post;
-
-use Render::Util;
-use DB::Post;
-
-use HTML::Functional;
-
-sub post-date(Post:D $post) is export {
- my $datetime = $post.posted-at;
- my $timestamp = sprintf(
- "%s %02d:%02d%s",
- $datetime.yyyy-mm-dd,
- ($datetime.hour % 12) || 12,
- $datetime.minute,
- $datetime.hour < 12 ?? 'am' !! 'pm'
- );
-
- div :class, :title("Posted At $timestamp"), [
- icon 'time';
- ' ';
- $timestamp
- ]
-}
-
-sub post-edit(Post:D $post) is export {
- return [] unless $post.edited-at.elems;
- my $datetime = $post.edited-at.max;
- my $timestamp = sprintf(
- "%s %02d:%02d%s",
- $datetime.yyyy-mm-dd,
- ($datetime.hour % 12) || 12,
- $datetime.minute,
- $datetime.hour < 12 ?? 'am' !! 'pm'
- );
-
- div :class, :title("Last Edited At $timestamp"), [
- icon 'edit';
- ' ';
- $timestamp
- ]
-}
-
-sub post-read-time(Post:D $post) is export {
- my ($slow, $average, $fast) = $post.readtimes;
- div :class, :title, [
- icon 'timer';
- ' ';
- mins-to-string $slow;
- ' ';
- '/';
- ' ';
- mins-to-string $average;
- ' ';
- '/';
- ' ';
- mins-to-string $fast;
- ]
-}
-
-sub post-tag(Str:D $tag) is export {
- span :class, [
- a :href("/tags/$tag.html"), [
- icon 'hash';
- $tag;
- ]
- ]
-}
-
-sub post-tags(Post:D $post) is export {
- my @tags = $post.tags.sort;
- if @tags {
- @tags.=map(*.&post-tag);
- div :class, [
- icon 'purchase-tag-alt';
- ' ';
- intersperse(', ', @tags);
- ]
- } else {
- []
- }
-}
-
-sub post-info(Post:D $post) is export {
- div :class, [
- post-date $post;
- post-edit $post;
- post-read-time $post;
- post-tags $post;
- ];
-}
-
-sub post-header(Post:D $post) is export {
- header :class, [
- div :class, [
- h1 $post.title;
- ];
- post-info $post;
- ]
-}
diff --git a/lib/Render/Util.rakumod b/lib/Render/Util.rakumod
deleted file mode 100644
index 05630a7..0000000
--- a/lib/Render/Util.rakumod
+++ /dev/null
@@ -1,54 +0,0 @@
-use v6.e.PREVIEW;
-unit module Render::Util;
-
-use DB::Post;
-
-use HTML::Functional;
-
-sub opt($test, $item) is export {
- if $test {
- $item
- } else {
- []
- }
-}
-
-sub optl($test, &item) is export {
- if $test {
- item
- } else {
- []
- }
-}
-
-#| Link to the post by the primary slug, if there is one, linking to it by id
-#| otherwise
-sub post-link(Int:D $id, Post:D $post --> Str:D) is export {
- my @slugs = $post.all-slugs;
- if @slugs {
- "/posts/by-slug/{@slugs[*-1]}.html"
- } else {
- "/posts/by-id/$id.html"
- }
-}
-
-sub icon($icon) is export {
- i(:class("bx bx-$icon"))
-}
-
-sub mins-to-string($mins) is export {
- if $mins < 60 {
- $mins.Str ~ "m"
- } else {
- my $h = $mins div 60;
- my $m = $mins mod 60;
- $h.Str ~ "h" ~ $m.Str ~ "m"
- }
-}
-
-sub intersperse (\element, +list) is export {
- gather for list {
- FIRST .take, next;
- take slip element, $_;
- }
-}
diff --git a/projects/Markdown/2025/01-Jan/AdventOfBugs.md b/projects/Markdown/2025/01-Jan/AdventOfBugs.md
deleted file mode 100644
index 3242738..0000000
--- a/projects/Markdown/2025/01-Jan/AdventOfBugs.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# Advent of bugs
-
-Near the start of january, after bumping into some ecosystem issues and lack of
-a personal support library while working on the 2024
-[Advent of Code](https://adventofcode.com/) in Idris, I started working on a
-project to solve all of the Advent of Code problems from all the years in a
-single massive entirely literate Idris project and publish it as an mdbook. I'm
-calling it
-[Idris 2 by Extremely Contrived](https://static.stranger.systems/idris-by-contrived-example/)
-example.
-
-## The Good
-
-This has been an amazingly fun project so far. AoC problems are nice and bite
-sized, giving really good material to work with for incrementally introducing
-more and more complex concepts. I have been following a sort of "weirdness
-budget" for each day's solutions, letting myself build on the already
-established weirdness from previous days. So far I'm 13 days in, and I've
-already had excuses to introduce all sorts of fun concepts, effects, dependent
-pattern matching, indexed type families, and refinement types, just to name a
-few.
-
-Functional programming languages are a lot of fun to model puzzle problems in to
-start with, but the new design space afforded by dependent typing offers a new,
-wonderfully fun challenge of figuring out just what to show off while I'm
-solving the puzzle. There have already been a few problems that I've wound up
-spending a few days on just tweaking and refining until I was pleased with the
-balance between weirdness expenditure and showing off what I want to show off in
-a reasonably approachable way.
-
-A couple of personal favorites of mine so far have been the
-[JSON parser](https://static.stranger.systems/idris-by-contrived-example/Parser/JSON.html),
-and the
-[`Digits` views](https://static.stranger.systems/idris-by-contrived-example/Util/Eff.html).
-The JSON parser is written in a bespoke mini-library for doing effectively
-parsing that I created just for this project, and refining the library to
-optimize for readability of the parsers written in it was an absolute joy. The
-digits views allowing pattern matching on normal integers as if they were lists
-of digits was less fun to write[^1], they are amazingly fun to use.
-
-## The Bad
-
-I've had to write a lot of support code already. I can't really fault the
-language, its a pretty new language in its pre-1.0 stage, in a pretty niche
-area, dependent types are still quite scary to the majority of programmers, and
-ecosystem improvement was a major goal of the project going in. I have already
-had to write several "basic" data structures, and there's no sign the need to do
-so will let up anytime soon[^6].
-
-Honestly the most painful part has been the lack of support for Idris in
-external tooling. Essentially every syntax highlighting library has _completely
-ass_ support for Idris. I managed to eventually sneak proper semantic
-highlighting into mdbook, it even plays nice with mdbook themes, but I had to
-commit horrible, _horrible_ crimes to get this working[^2].
-
-## The Ugly
-
-This isn't exactly a complaint, after all, ecosystem improvement was a goal
-after all, but I've already run into 2 or 3 compiler bugs, a bug in the `pack`
-package manager, and a weird behavior in katla that's a _maybe_ bug.
-
-I busted the part of the compiler that automatically inserts `force` and `delay`
-calls to make interaction between lazy and strict code Just Work™:
-[idris-lang/Idris2#3461](https://github.com/idris-lang/Idris2/issues/3461). I
-had initially thought I had discovered just _one_ compiler bug, but it turns out
-I also stumbled into an unrelated issue in the termination checker![^8]
-
-I broke the [pack](https://github.com/stefan-hoeck/idris2-pack) package manager
-by, apparently, being the first person to try and upload a library to `pack-db`
-with library code in literate files, in my
-[Structures](https://git.sr.ht/~thatonelutenist/Structures) package, checking in
-a new data structure motivated by my advent project, completely breaking the
-automated docs generation:
-[stefan-hoeck/idris2-pack!319](https://github.com/stefan-hoeck/idris2-pack/pull/319).
-This one was especially wild to me, with how popular literate programs are in
-the community, I would have never expected to be the first person to try this.
-
-## Looking Forward
-
-Despite the challenges, this has been a lovely experience so far. I greatly look
-forward to pressing through to completion, whatever it may bring, and have a
-trophy case full of bugs identified/fixed and new libraries to bring to the
-ecosystem.
-
-[^1]: While perfectly understandable, it's not reasonable to expect the compiler
- to be able to reason about primitive "machine" integers like this on its
- own, needing to resort to so much `believe_me` on this one did make me a bit
- sad
-
-[^6]: Well well well, if it isn't the consequences of my actions
-
-[^2]: Do not look at the `build-book` script if you value your sanity
-
-[^8]: Before anyone gets upset here, despite the name, the termination checker
- doesn't actually solve the halting problem. It only automatically accepts a
- subset of the language for which termination is a 'trivial' property, which
- includes most code I've written in the language so far, but not nearly all
- of it.
diff --git a/projects/Markdown/RustPosting.md b/projects/Markdown/RustPosting.md
deleted file mode 100644
index 632d2f1..0000000
--- a/projects/Markdown/RustPosting.md
+++ /dev/null
@@ -1,205 +0,0 @@
-# Rustposting
-
-Some example code with some potential problem characters:
-
-```rust
-let newline_string = "hello \n world";
-let thing = *newline_string;
-```
-
-Here is some example rust code:
-
-```rust
-fn main() {
- // Statements here are executed when the compiled binary is called.
-
- // Print text to the console
- println!("Hello World!");
-}
-```
-
-And a slightly less trivial example:
-
-```rust
-fn main() {
- // Variables can be type annotated.
- let logical: bool = true;
-
- let a_float: f64 = 1.0; // Regular annotation
- let an_integer = 5i32; // Suffix annotation
-
- // Or a default will be used.
- let default_float = 3.0; //
- let default_integer = 7; //
-
- // A type can also be inferred from context.
- let mut inferred_type = 12; // Type i64 is inferred from another line.
- inferred_type = 4294967296i64;
-
- // A mutable variable's value can be changed.
- let mut mutable = 12; // Mutable
- mutable = 21;
-
- // Error! The type of a variable can't be changed.
- mutable = true;
-
- // Variables can be overwritten with shadowing.
- let mutable = true;
-
- /* Compound types - Array and Tuple */
-
- // Array signature consists of Type T and length as [T; length].
- let my_array: [i32; 5] = [1, 2, 3, 4, 5];
-
- // Tuple is a collection of values of different types
- // and is constructed using parentheses ().
- let my_tuple = (5u32, 1u8, true, -5.04f32);
-}
-```
-
-Toss in some type definitions to
-
-```rust
-#[derive(Debug)]
-struct Person {
- name: String,
- age: u8,
-}
-
-// A unit struct
-struct Unit;
-
-// A tuple struct
-struct Pair(i32, f32);
-
-enum WebEvent {
- // An variant may either be
- PageLoad,
- PageUnload,
- // like tuple structs,
- KeyPress(char),
- Paste(String),
- // or c-like structures.
- Click { x: i64, y: i64 },
-}
-
-struct Point {
- x: f64,
- y: f64,
-}
-
-// Implementation block, all associated functions & methods go in here
-impl Point {
- // This is an "associated function" because this function is associated with
- // a particular type, that is, Point.
- //
- // Associated functions don't need to be called with an instance.
- // These functions are generally used like constructors.
- fn origin() -> Point {
- Point { x: 0.0, y: 0.0 }
- }
-
- // Another associated function, taking two arguments:
- fn new(x: f64, y: f64) -> Point {
- Point { x: x, y: y }
- }
-}
-
-```
-
-Modules and imports
-
-```rust
-#![allow(unused_variables)]
-
-use deeply::nested::function as other_function;
-use std::fs::File;
-
-fn function() {
- println!("called function()");
-}
-
-mod deeply {
- pub mod nested {
- pub fn function() {
- println!("called deeply::nested::function()");
- }
- }
-}
-
-struct Val {
- val: f64,
-}
-
-struct GenVal {
- gen_val: T,
-}
-
-// impl of Val
-impl Val {
- fn value(&self) -> &f64 {
- &self.val
- }
-}
-
-impl GenVal {
- fn value(&self) -> &T {
- &self.gen_val
- }
-}
-
-let a = Box::new(5i32);
-
-macro_rules! say_hello {
- () => {
- // The macro will expand into the contents of this block.
- println!("Hello!")
- };
-}
-
-macro_rules! calculate {
- (eval $e:expr) => {
- {
- let val: usize = $e; // Force types to be unsigned integers
- println!("{} = {}", stringify!{$e}, val);
- }
- };
-}
-
-fn give_adult(drink: Option<&str>) {
- // Specify a course of action for each case.
- match drink {
- Some("lemonade") => println!("Yuck! Too sugary."),
- Some(inner) => println!("{}? How nice.", inner),
- None => println!("No drink? Oh well."),
- }
-}
-
-impl Person {
-
- // Gets the area code of the phone number of the person's job, if it exists.
- fn work_phone_area_code(&self) -> Option {
- // It would take a lot more code - try writing it yourself and see which
- // is easier.
- self.job?.phone_number?.area_code
- }
-}
-
-#[cfg(target_family = "unix")]
-#[link(name = "m")]
-extern {
- // this is a foreign function
- // that computes the square root of a single precision complex number
- fn csqrtf(z: Complex) -> Complex;
-
- fn ccosf(z: Complex) -> Complex;
-}
-
-fn main() {
- let raw_p: *const u32 = &10;
-
- unsafe {
- assert!(*raw_p == 10);
- }
-}
-```
diff --git a/resources/code.css b/resources/code.css
index 18edce7..b9d9c48 100644
--- a/resources/code.css
+++ b/resources/code.css
@@ -11,6 +11,7 @@ code {
/* Styling for fenced code blocks */
pre > code {
display: block;
+ white-space: pre-wrap;
padding: 1rem;
border-radius: 0.55rem / 0.5rem;
word-wrap: normal;
diff --git a/resources/colors.css b/resources/colors.css
index 5974f21..54e6cc5 100644
--- a/resources/colors.css
+++ b/resources/colors.css
@@ -53,29 +53,23 @@ a:visited {
.site-tagline {
color: var(--dim-0);
}
-.post-body, .post-header, .post-blurbs, .tags, .tags .tag-blurb-post {
+.post-body, .post-header, .post-blurbs {
background-color: var(--bg-0);
}
-.post-blurb, .tags .tag-blurb {
+.post-blurb {
background-color: var(--bg-1);
}
-:not(.tags) .tag-blurb {
- background-color: var(--bg-0);
-}
-:not(.tags) .tag-blurb-post {
- background-color: var(--bg-1);
-}
-.post-title, .post-blurbs h1 {
+.post-title, .post-blurbs > h1 {
color: var(--green);
}
-.post-body h2, .post-body h3, .post-body h4 {
+.post-body > h2, .post-body > h3, .post-body > h4 {
color: var(--fg-1);
}
blockquote {
background-color: var(--bg-1);
}
-/* Colorization for idris code blocks */
+/* Colorization for code blocks */
code {
color: var(--code-fg-0);
background-color: var(--code-bg-0);
@@ -102,35 +96,3 @@ code {
.hl-data {
color: var(--code-red);
}
-
-/* Colorization for pygments code blocks */
-.hl-kd, .hl-k, .hl-kc, .hl-bp {
- color: var(--code-green);
-}
-.hl-n, .hl-nn {
- color: var(--code-violet);
-}
-.hl-s, .hl-se {
- color: var(--code-cyan);
-}
-.hl-nf, .hl-fm {
- color: var(--code-blue);
-}
-.hl-c1, .hl-cm {
- color: var(--code-dim-0);
-}
-.hl-mf, .hl-mi {
- color: var(--code-magenta);
-}
-.hl-kt, .hl-nb, .hl-nc {
- color: var(--code-orange);
-}
-.hl-cp {
- color: var(--code-red);
-}
-.hl-se {
- font-style: italic;
-}
-.hl-fm, .hl-k, .hl-o, .hl-kp {
- font-weight: bold;
-}
diff --git a/resources/main.css b/resources/main.css
index 4b54d5e..fad0412 100644
--- a/resources/main.css
+++ b/resources/main.css
@@ -2,7 +2,6 @@
font-family: "Open Sans", sans-serif, serif;
/* Variables */
--content-width: 60rem;
- --blurb-width: 45%;
--header-width: 35rem;
--box-padding-vert: 1rem;
--box-padding-horz: 1rem;
@@ -19,13 +18,6 @@
}
}
-/* slightly larger than blurb-width to account for padding/margins */
-@media screen and (max-width: 40rem) {
- :root {
- --blurb-width: 100%;
- }
-}
-
/* Main Body and Post Flexboxs */
body, .post {
display: flex;
@@ -33,9 +25,6 @@ body, .post {
align-items: center;
gap: var(--box-gap);
}
-.post {
- width: 100%;
-}
/* Style the site header */
.site-header {
@@ -86,11 +75,11 @@ body, .post {
border-radius: var(--box-radius);
box-sizing: border-box;
}
-.post-body p {
+.post-body > p {
margin: auto var(--box-margin-horz);
align-self: stretch;
}
-.post-title h1 {
+.post-title > h1 {
margin-top: 0px;
margin-bottom: 0px;
}
@@ -105,7 +94,7 @@ body, .post {
.post-read-time {
text-decoration: underline dotted;
}
-.post-body h2, .post-body h3, .post-body h4 {
+.post-body > h2, .post-body > h3, .post-body > h4 {
text-align: center;
}
.post-blurbs {
@@ -135,56 +124,3 @@ blockquote {
border-radius: var(--box-radius);
padding: var(--box-padding-vert) var(--box-padding-horz);
}
-
-/* Style the tags blurbs and page */
-.tags {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: var(--box-gap);
- max-width: var(--content-width);
- /* min-width: var(--blurb-width); */
- padding: var(--box-padding-vert) var(--box-padding-horz);
- border-radius: var(--box-radius);
- box-sizing: border-box;
-}
-.tag-blurb {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: var(--box-gap);
- border-radius: var(--box-radius);
- box-sizing: border-box;
-}
-.tag-blurb-links {
- display: block;
- border-radius: var(--box-radius);
- border-radius: var(--box-radius);
- display: flex;
- flex-flow: row wrap;
- gap: var(--box-gap);
- align-items: stretch;
- box-sizing: border-box;
- gap: var(--box-gap);
- padding: var(--box-padding-vert) var(--box-padding-horz);
-}
-.tag-blurb-post {
- font-size: 0.8rem;
- width: var(--blurb-width);
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: var(--box-gap);
- box-sizing: border-box;
- flex-shrink: 1;
- flex-grow: 1;
- border-radius: var(--box-radius);
- padding: var(--box-padding-vert) var(--box-padding-horz);
-}
-.tag-blurb-title {
- margin-top: var(--box-margin-vert);
- margin-bottom: 0;
- font-size: 1.5em;
- font-weight: bold;
-}