Really silly docs/blog/whatever static site generator (SSG) in Nix.
An example deployment of this repository
pushd $(mktemp -d)
nix build github:kowale/rocs -vv -L
python -m http.server -d result
popd
A minimal flake example (see flake.nix for more)
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
rocs = {
url = "github:kowale/rocs";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, rocs, ... } @ inputs:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in
{
# nix build && python3 -m http.server -d result
packages.${system}.default = rocs.lib.buildSiteAt "";
};
}Each source file is rendered to HTML
by opening a template (see lib/mdToHtml.nix)
in a headless Chromium, in a Nix build sandbox.
It works surprisingly well, apart from all the horrors.
The final result contains no JS whatsoever,
including for highlight.js and KaTeX.
To avoid heavy re-rendering of all files on any change,
source files are evaluated into independent derivations
using forbidden magic of unsafeDiscardStringContext.
# Remove context from string to avoid pulling whole tree as dependency
dir = unsafeDiscardStringContext (
replaceStrings
[ "${root}" ]
[ "" ]
(toString path)
);Directory structure mirrors that of the repository. For example, hello.md is rendered to hello.html. In an attempt to support directories, README.html is copied to index.html, if it exists. Need auto-discovered page index? Generate in pre-commit.
I would like to render with Firefox/Gecko but I couldn't get it to work :( Soon TM
Dependencies defined in ./lib/imports.nix
are vendored at /nix/store
(that is, copied to $out/nix/store).
This includes both runtime CSS or images
and build JS (not pulled in final HTML).
Naturally, build environment is shipped as well, why not.
Template is instructed to not remove its build logic,
and rendered paths are prepended with an underscore (_).
For example, docs/hello.md goes to docs/_/hello.html.
In particular, all paths can be "edited" by adding _ in URL.