my website
1{
2 description = "chfour's website";
3
4 inputs.flake-utils.url = "github:numtide/flake-utils";
5
6 outputs = { self, nixpkgs, flake-utils }:
7 flake-utils.lib.eachSystem flake-utils.lib.allSystems
8 (system:
9 let
10 pkgs = nixpkgs.legacyPackages.${system};
11 selfPkgs = self.packages.${system};
12
13 subsetWoff2 = with pkgs; (src: { pname ? src.pname + "-subset", unicodes, extraArgs ? [] }: src.overrideAttrs (old: {
14 inherit pname;
15
16 passthru = {
17 unicodeRanges = unicodes;
18 };
19
20 nativeBuildInputs = (old.nativeBuildInputs or []) ++ (with python312Packages; [ fonttools brotli ]);
21 postInstall = (old.postInstall or "") + ''
22 for f in $out/share/fonts/woff2/*; do
23 ${python312Packages.fonttools}/bin/fonttools subset "$f" \
24 --unicodes=${lib.escapeShellArg unicodes} \
25 ${lib.escapeShellArgs extraArgs} \
26 --flavor=woff2 --output-file="$f"
27 done
28 '';
29 }));
30 in {
31 packages.inter-woff2 = pkgs.inter.overrideAttrs (old: {
32 pname = "inter-woff2";
33 installPhase = ''
34 runHook preInstall
35 mkdir -p $out/share/fonts/woff2
36 cp web/InterVariable*.woff2 $out/share/fonts/woff2
37 runHook postInstall
38 '';
39 });
40
41 # lib.strings.concatStringsSep ", " packages.x86_64-linux.inter-fast.unicodeRanges
42 # suboptimal the way it is atm. whatever
43 packages.inter-fast = subsetWoff2 selfPkgs.inter-woff2 {
44 pname = "inter-fast";
45 unicodes = [
46 # stolen from googel fonts and modified
47 "U+0000-00FF" "U+0131" "U+0152-0153" "U+02BB-02BC"
48 "U+02C6" "U+02DA" "U+02DC" "U+0304" "U+0308" "U+0329"
49 "U+2000-206F" "U+20AC" "U+2122" "U+2191" "U+2193"
50 "U+2212" "U+2215" "U+FEFF" "U+FFFD" "U+0394" "U+0398"
51 "U+0104" "U+0106" "U+0118" "U+0141" "U+0143" "U+00D3"
52 "U+015A" "U+0179" "U+017B" "U+0105" "U+0107" "U+0119"
53 "U+0142" "U+0144" "U+00F3" "U+015B" "U+017A" "U+017C"
54 ];
55 extraArgs = [ "--layout-features+=cv10,zero,tnum" ];
56 };
57
58 packages.website-fonts = pkgs.stdenvNoCC.mkDerivation {
59 name = "website-fonts"; # i tried pname => attribute 'name' missing ??
60
61 phases = [ "installPhase" ]; # eh?
62
63 installPhase = ''
64 runHook preInstall
65
66 mkdir -p $out
67
68 # subset
69 for f in ${selfPkgs.inter-fast}/share/fonts/woff2/*.woff2; do
70 f_="''${f##*/}"
71 cp "$f" "$out/''${f_%*.woff2}.fast.woff2"
72 done
73 # full
74 for f in ${selfPkgs.inter-woff2}/share/fonts/woff2/*.woff2; do
75 cp "$f" "$out"
76 done
77
78 runHook postInstall
79 '';
80 };
81
82 packages.buildblog = pkgs.writeShellApplication {
83 name = "buildblog";
84 runtimeInputs = with pkgs; [ jq pandoc ];
85 text = builtins.readFile ./buildblog.sh; # eh?
86 };
87
88 packages.autorebuild = pkgs.writeShellApplication {
89 name = "autorebuild";
90 runtimeInputs = with pkgs; [ selfPkgs.buildblog pkgs.inotify-tools ];
91 text = ''
92 [ -z "''${1+x}" ] && echo "usage: $0 blog-dir" && exit 1
93
94 rebuild() {
95 time buildblog "$1"
96 }
97 rebuild "$@"
98 last=$(date +%s)
99 inotifywait -r -m "$1" \
100 -e modify -e create -e delete -e moved_to \
101 --excludei '/index.html|highlighting.css' \
102 | while read -r mod; do
103 echo "$mod"
104 now=$(date +%s)
105 [ $((now - last)) -ge 2 ] && rebuild "$@" || echo '< 2s, skipping'
106 last=$now
107 done
108 '';
109 };
110
111 packages.website = pkgs.stdenvNoCC.mkDerivation {
112 name = "chfour-website";
113
114 buildInputs = [ selfPkgs.website-fonts ];
115
116 nativeBuildInputs = [ selfPkgs.buildblog ];
117
118 src = ./src;
119
120 buildPhase = ''
121 runHook preBuild
122
123 ln -sf ${selfPkgs.website-fonts} ./fonts
124 ${selfPkgs.buildblog}/bin/buildblog blog/
125 rm blog/template_{index,page}.html
126 sed -i \
127 "s|/nix/store/VERY5p3c14lsecretv4luereplaceme0-chfour-website|$out|" \
128 index.html
129
130 runHook postBuild
131 '';
132
133 installPhase = ''
134 runHook preInstall
135
136 mkdir -p $out/var/www
137 cp -r * $out/var/www
138
139 runHook postInstall
140 '';
141 };
142
143 packages.caddyfile = pkgs.stdenvNoCC.mkDerivation {
144 name = "chfour-website-caddyfile";
145 src = ./Caddyfile;
146
147 buildInputs = [ selfPkgs.website ];
148
149 nativeBuildInputs = [ pkgs.caddy ];
150
151 unpackPhase = ''
152 runHook preUnpack
153 cp --no-preserve=mode $src ./Caddyfile
154 runHook postUnpack
155 '';
156
157 buildPhase = let
158 websitePath = toString selfPkgs.website.out;
159 in ''
160 runHook preBuild
161
162 sed -i \
163 "s|./src/|${websitePath}/var/www/|;/#!PROD-SNIP$/d" \
164 Caddyfile
165
166 # https://github.com/caddyserver/caddy/pull/5547#issuecomment-1555940637
167 cat >> Caddyfile <<EOF
168 header -Last-modified
169 header Etag \`"${builtins.baseNameOf websitePath}"\`
170 EOF
171
172 caddy fmt --overwrite Caddyfile
173
174 runHook postBuild
175 '';
176
177 nativeCheckInputs = [ pkgs.caddy ];
178
179 checkPhase = ''
180 runHook preCheck
181 caddy validate --config Caddyfile
182 runHook postCheck
183 '';
184
185 installPhase = ''
186 runHook preInstall
187 mkdir -p $out/etc/caddy/
188 cp Caddyfile $out/etc/caddy/
189 runHook postInstall
190 '';
191 };
192 }
193 );
194}