1
Fork 0
mirror of https://github.com/RGBCube/Site synced 2025-08-01 13:37:49 +00:00

Compare commits

...

9 commits

5 changed files with 241 additions and 24 deletions

View file

@ -23,12 +23,24 @@ site.process([".html"], (pages) => {
document.querySelectorAll("table").forEach((table) => {
const div = document.createElement("div");
div.classList.add("room", "rotated");
table.classList.add("rotated");
div.classList.add("overflow", "rotated");
table.parentNode!.insertBefore(div, table);
div.appendChild(table);
});
document.querySelectorAll(".hljs").forEach((code) => {
const pre = code.parentElement!;
const div = document.createElement("div");
code.classList.add("rotated");
pre.classList.add("rotated");
div.classList.add("overflow", "rotated");
pre.parentNode?.insertBefore(div, pre);
div.appendChild(pre);
});
});
});
@ -36,21 +48,20 @@ site.use(feed({
output: ["/blog.rss"],
query: "type=article",
sort: "date=desc",
sort: "date=asc",
limit: Infinity,
info: {
title: "RGBCube's Blog",
description:
"The blog where RGBCube dumps his schizophrenic ramblings about software and all the likes.",
lang: "en",
generator: false,
},
items: {
title: "=title",
description: "=description",
published: "=date",
content: "$ content",
lang: "en",
content: "$.content",
},
}));

View file

@ -2,7 +2,7 @@
layout: text.vto
---
{{ content }}
<div class="content">{{ content }}</div>
{{ if tags.length !== 0 }}
<p>Tags: {{ tags.join(", ") }}</p>

View file

@ -3,12 +3,21 @@ layout: base.vto
---
<style>
/* Centering */
html,
body {
display: flex;
justify-content: center;
}
.centered {
font-size: large;
display: initial;
width: min(100vw - 2rem, 50rem);
}
/* Make wrapping pretty */
h1,
h2,
h3,
@ -20,21 +29,17 @@ layout: base.vto
text-wrap: pretty;
}
.centered {
font-size: large;
display: initial;
width: min(100vw - 2rem, 50rem);
}
/* Rotate nav, tables and codeblocks so the scrollbar is at the top */
.rotated {
transform: rotateX(180deg);
}
.content {
overflow-wrap: break-word;
/* Make tables and other elements scroll horizontally */
.overflow {
overflow-x: auto;
}
/* Style nav */
nav {
font-size: larger;
word-break: normal;
@ -63,6 +68,11 @@ layout: base.vto
margin-right: 0.6rem;
}
/* Style content */
.content {
overflow-wrap: break-word;
}
a {
color: var(--link);
}
@ -71,10 +81,27 @@ layout: base.vto
font-style: italic;
}
.room {
overflow-x: auto;
blockquote {
border-left: 0.15rem solid var(--foreground);
padding-top: 0.01rem;
padding-bottom: 0.01rem;
padding-left: 1rem;
padding-right: 0.5rem;
}
@media (prefers-color-scheme: dark) {
blockquote {
background-color: #222;
}
}
@media (prefers-color-scheme: light) {
blockquote {
background-color: #EEE;
}
}
/* Style tables */
table {
border-collapse: collapse;
white-space: nowrap;
@ -87,8 +114,8 @@ layout: base.vto
} */
th, td {
border: 0.15em solid var(--foreground);
padding: 0.3em;
border: 0.15rem solid var(--foreground);
padding: 0.3rem;
}
th {
@ -96,9 +123,42 @@ layout: base.vto
color: var(--background);
}
footer {
border-top: 0.15rem solid var(--foreground);
/* Codeblocks */
.rotated:has(pre) {
padding: 0.6rem;
border: 0.15rem solid var(--foreground);
}
pre:has(code) {
margin: 0;
}
@media (prefers-color-scheme: dark) {
.hljs-attr { color: lightblue; }
.hljs-built_in { color: firebrick; }
.hljs-keyword { color: firebrick; }
.hljs-number { color: mediumslateblue; }
.hljs-string { color: limegreen; }
.hljs-title { color: lightcoral; }
.hljs-type { color: aquamarine; }
}
@media (prefers-color-scheme: light) {
.hljs-attr { color: darkblue; }
.hljs-built_in { color: darkred; }
.hljs-keyword { color: darkred; }
.hljs-number { color: darkslateblue; }
.hljs-string { color: darkgreen; }
.hljs-title { color: darkgoldenrod; }
.hljs-type { color: darkcyan; }
}
/* The end */
hr {
border: 0.15rem solid var(--foreground);
}
footer {
display: flex;
justify-content: center;
@ -119,7 +179,8 @@ layout: base.vto
</div>
</nav>
<div class="content">{{ content }}</div>
{{ content }}
<footer>Copyright © RGBCube</footer>
<hr>
<footer>Copyright {{ new Date().getFullYear() }} © RGBCube</footer>
</div>

View file

@ -10,7 +10,7 @@ Are you old? Then you might want to check out my super cool
<a href="/blog.rss">RSS Feed</a> too!
<ul>
{{ for article of search.pages("type=article", "date")}}
{{ for article of search.pages("type=article", "order=asc title=date")}}
<li>
<p>
<a href="{{ article.url }}">{{ article.date.toISOString().slice(0, 10) }}</a>:

145
site/blog/htmnix.md Normal file
View file

@ -0,0 +1,145 @@
---
title: HTMNIX
description: How the absolutely cursed HTMNIX project works.
date: 2024-03-04
tags:
- html
- nix
---
So, you may have seen the [HTMNIX](https://github.com/RGBCube/HTMNIX) project I've
been working on the last few weeks. If not, no worries. Here is a Nix snippet
that uses it:
```nix
<html>
<head>
<title>"Hello, Internet!"<.title>
<.head>
<body>
<p>"Yep, this is 100% Nix!"<.p>
<img.>{src="/foo.png"; alt="Attributes also work!";}
<.body>
<.html>
```
> (hightlight.js shits the bed while highlighting this abomination - just ignore it)
You are probably thinking furiously right now, maybe you've noticed something:
> Aha! In Nix, `<foo>` is used to find stuff from the Nix path like so:
>
> ```nix
> import <nixpkgs> {}
> ```
>
> That means you have to add hundreds of elements to your Nix Path to make this work?
You are somewhat correct. But not quite.
Nix `<foo>` expressions actually boil down to a call of the builtin `__findFile`, like so:
```sh
nix-instantiate --parse --expr "<foo>"
(__findFile __nixPath "foo")
```
> In case you didn't know, [`nix-instantiate`](https://nixos.org/manual/nix/stable/command-ref/nix-instantiate.html)
> is a nice tool to see what your Nix code is desugared and un-precedence'd into.
Aha! So this means we can override the builtin `__findFile` and put whatever we would like in
its place. So this will work:
```nix
let
__findFile = nixPath: name: {
content = "<${name}>";
};
in
<foo>
```
Evaluating this (by running `nix eval -f test.nix`), we get `{ content = "<foo>"; }`
So, then. How do we make it work for multiple tags, all coming after one another
(and attribute sets, strings, etc.)?
Another hack! We need to set the [magic `__functor` attribute](https://noogle.dev/md/tutorials/functors)
of the attrset we return, so we can call our set and have it store the tags inside it (while also
preserving its callability!).
We can do that like so:
```nix
let
__findFile = nixPath: name: {
content = "<${name}>";
__functor = self: next: self // {
content = self.content + next;
};
};
in
<foo>
"bar"
"baz"
```
Great news! When we evaluate this, we get `{ __functor = <LAMBDA>; content = "<foo>barbaz"; }`.
We can also add a case to check if the next element is a tag, and use its content if it is:
```nix
let
__findFile = nixPath: name: {
content = "<${name}>";
__functor = self: next: self // {
content = self.content + (if next ? content then next.content else next);
};
};
in
<foo>
"bar"
"baz"
<endfoo>
```
Enter another hack! We can utilize the `outPath` property that exists on derivations
and gets returned whenever you call `toString` with an attrset that has the property to make our code a little simpler:
```nix
let
__findFile = nixPath: name: {
outPath = "<${name}>";
__functor = self: next: self // {
outPath = self.outPath + toString next;
};
};
in
<foo>
"bar"
"baz"
123
<endfoo>
```
We also got support for other types for free, as well!
These are all the hidden builtins that [HTMNIX](https://github.com/RGBCube/HTMNIX) depends on
and extends upon, making HTML in Nix an actually usable reality. It also
has extra logic like turning attribute sets into HTML tags, which is fairly trivial
compared to actaully discovering these hidden builtins in the first place.
You can read more about it in the project's README and
see [an example site using it](https://github.com/RGBCube/NixSite).
I might even try to port this site to HTMNIX to ensure it is usable with more complex setups :-)
Soon, maybe...
---
Thanks for reading my first ever proper blog post! :-)