diff --git a/build.sh b/build.sh
index b1ee325..de246c8 100755
--- a/build.sh
+++ b/build.sh
@@ -26,25 +26,23 @@ docker build docker/hugo -t build-hugo || exit 1
echo Building thumbnails.
docker run --user "$(id -u):$(id -g)" -v "$IMAGES:/output" build-pictures sh -c "/build.sh /output" || exit 1
-while read -r d
-do
- mkdir -p "$HUGO/$d" || exit 1
- DESIRED_LOCATION=$(basename "$d")
- DEST=$(dirname "$d")
- cp -r "$IMAGES/$DESIRED_LOCATION" "$HUGO/$DEST"
-done < "$IMAGES/image-targets.txt"
+while read -r d; do
+ mkdir -p "$HUGO/$d" || exit 1
+ DESIRED_LOCATION=$(basename "$d")
+ DEST=$(dirname "$d")
+ cp -r "$IMAGES/$DESIRED_LOCATION" "$HUGO/$DEST"
+done <"$IMAGES/image-targets.txt"
echo Building LaTeX.
docker run --user "$(id -u):$(id -g)" -v "$PDFS:/inputs" build-latex sh -c "/build.sh /inputs" || exit 1
-while read -r texfile
-do
- DIR="$HUGO"/$(dirname "$texfile")
- TEXFILE_BASE=$(basename "$texfile")
- PDFFILE=$(basename "$texfile" .tex).pdf
- mkdir -p "$DIR"
- cp "$PDFS/$TEXFILE_BASE" "$DIR/"
- cp "$PDFS/$PDFFILE" "$DIR/"
-done < "$PDFS/pdf-targets.txt"
+while read -r texfile; do
+ DIR="$HUGO"/$(dirname "$texfile")
+ TEXFILE_BASE=$(basename "$texfile")
+ PDFFILE=$(basename "$texfile" .tex).pdf
+ mkdir -p "$DIR"
+ cp "$PDFS/$TEXFILE_BASE" "$DIR/"
+ cp "$PDFS/$PDFFILE" "$DIR/"
+done <"$PDFS/pdf-targets.txt"
echo Building site.
docker run --user "$(id -u):$(id -g)" -v "$HUGO:/hugo" -v "$OUTPUT:/output" build-hugo sh -c "/build.sh /hugo /output" || exit 1
diff --git a/build/all.sh b/build/all.sh
index fd2a616..5597a7d 100755
--- a/build/all.sh
+++ b/build/all.sh
@@ -8,33 +8,31 @@ katex=$5
extraContent=$6
echo "Linking PDFs: $PDF_FOLDER/pdf-targets.txt"
-while IFS= read -r texfile || [[ -n "$r" ]]
-do
- DIR=$(dirname "$texfile")
- TEXFILE_BASE=$(basename "$texfile")
- if [ -z "${TEXFILE_BASE}" ]; then
- echo "Skipping empty line"
- else
- PDFFILE=$(basename "$texfile" .tex).pdf
- mkdir -p "$DIR"
- echo "$TEXFILE_BASE"
- echo "$PDFFILE"
- cp "${pdfs}/$TEXFILE_BASE" "$texfile"
- cp "${pdfs}/$PDFFILE" "$DIR/"
- fi
-done < "${pdfs}/pdf-targets.txt"
+while IFS= read -r texfile || [[ -n $r ]]; do
+ DIR=$(dirname "$texfile")
+ TEXFILE_BASE=$(basename "$texfile")
+ if [ -z "${TEXFILE_BASE}" ]; then
+ echo "Skipping empty line"
+ else
+ PDFFILE=$(basename "$texfile" .tex).pdf
+ mkdir -p "$DIR"
+ echo "$TEXFILE_BASE"
+ echo "$PDFFILE"
+ cp "${pdfs}/$TEXFILE_BASE" "$texfile"
+ cp "${pdfs}/$PDFFILE" "$DIR/"
+ fi
+done <"${pdfs}/pdf-targets.txt"
echo "Linking thumbnails."
-while IFS= read -r d || [[ -n "$d" ]]
-do
- if [ -n "${d}" ]; then
- DIR=$(dirname "$d")
- mkdir -p "$DIR" || exit 1
- DESIRED_LOCATION=$(basename "$d")
- echo "$d -> $DESIRED_LOCATION"
- cp -r "${images}/$DESIRED_LOCATION" "$d"
- fi
-done < "${images}/image-targets.txt"
+while IFS= read -r d || [[ -n $d ]]; do
+ if [ -n "${d}" ]; then
+ DIR=$(dirname "$d")
+ mkdir -p "$DIR" || exit 1
+ DESIRED_LOCATION=$(basename "$d")
+ echo "$d -> $DESIRED_LOCATION"
+ cp -r "${images}/$DESIRED_LOCATION" "$d"
+ fi
+done <"${images}/image-targets.txt"
echo "Linking Anki decks."
mkdir static/AnkiDecks && cp -R "${ankiDecks}/." static/AnkiDecks
@@ -47,12 +45,11 @@ cp -r "$katex/dist/contrib" themes/anatole/assets/contrib
cp "$katex"/dist/*.js themes/anatole/assets/
cp "$katex"/dist/*.css themes/anatole/assets/
-while IFS= read -r file_to_copy
-do
- echo "$file_to_copy"
- sourcefile=$(echo "$file_to_copy" | cut -d ' ' -f 1)
- destfile=$(echo "$file_to_copy" | cut -d ' ' -f 2-)
- cp "$extraContent/$sourcefile" "$destfile"
-done < "$extraContent/map.txt"
+while IFS= read -r file_to_copy; do
+ echo "$file_to_copy"
+ sourcefile=$(echo "$file_to_copy" | cut -d ' ' -f 1)
+ destfile=$(echo "$file_to_copy" | cut -d ' ' -f 2-)
+ cp "$extraContent/$sourcefile" "$destfile"
+done <"$extraContent/map.txt"
/bin/sh "${buildHugo}/run.sh" . ./output
diff --git a/docker/hadolint/build.sh b/docker/hadolint/build.sh
index e8f0a56..d8db0b2 100755
--- a/docker/hadolint/build.sh
+++ b/docker/hadolint/build.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-find /work -type f -name 'Dockerfile' -print0 | xargs -0 -n1 hadolint
\ No newline at end of file
+find /work -type f -name 'Dockerfile' -print0 | xargs -0 -n1 hadolint
diff --git a/docker/hugo/build.sh b/docker/hugo/build.sh
index 6ce5c2d..852ceba 100755
--- a/docker/hugo/build.sh
+++ b/docker/hugo/build.sh
@@ -3,5 +3,5 @@
SOURCE_DIR=$(readlink -f "$1")
OUTPUT_DIR=$(readlink -f "$2")
-rm -rf "${OUTPUT_DIR:?}/*" && \
-hugo --minify --source "$SOURCE_DIR" --destination "$OUTPUT_DIR"
+rm -rf "${OUTPUT_DIR:?}/*" &&
+ hugo --minify --source "$SOURCE_DIR" --destination "$OUTPUT_DIR"
diff --git a/docker/load/build.sh b/docker/load/build.sh
index b522023..1b43a44 100755
--- a/docker/load/build.sh
+++ b/docker/load/build.sh
@@ -7,4 +7,4 @@ cp -Rf /git/. /output || exit 1
chmod -R a+rw /output || exit 1
-touch /sentinels/load.txt
\ No newline at end of file
+touch /sentinels/load.txt
diff --git a/flake.lock b/flake.lock
index 0b74709..b7c9a1b 100644
--- a/flake.lock
+++ b/flake.lock
@@ -104,11 +104,11 @@
"scripts": "scripts_2"
},
"locked": {
- "lastModified": 1696161637,
- "narHash": "sha256-GwkTsWHakdktMrIlaonEGl/+/GxEgC3xpn1QzNNxKhU=",
+ "lastModified": 1696175612,
+ "narHash": "sha256-8V8klzc7T3EdAdS4r8RRjNvTTytQOsvfi7DfK6NFK6M=",
"ref": "refs/heads/main",
- "rev": "f47d539cedfaab677133b53fd4d02e24d2256985",
- "revCount": 14,
+ "rev": "ac0b0180304bce7683dc8b4466a6e92b339c0b7e",
+ "revCount": 15,
"type": "git",
"url": "file:/Users/patrick/Desktop/website/static-site-images"
},
diff --git a/flake.nix b/flake.nix
index 30bbe75..24a831d 100644
--- a/flake.nix
+++ b/flake.nix
@@ -44,51 +44,77 @@
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
+ in let
+ buildHugo = scripts.lib.createShellScript pkgs "hugo" ./docker/hugo/build.sh;
+ in let
+ katex-parts = pkgs.stdenv.mkDerivation {
+ __contentAddressed = true;
+ pname = "katex";
+ version = "0.1.0";
+ src = katex.outputs.packages.${system}.default;
+
+ installPhase = ''
+ mkdir "$out"
+ ls -la .
+ cp -r ./libexec/katex/dist "$out/dist"
+ '';
+ };
+ in let
+ website = pkgs.stdenv.mkDerivation {
+ __contentAddressed = true;
+ pname = "patrickstevens.co.uk";
+ version = "0.1.0";
+
+ src = ./hugo;
+
+ buildInputs = [
+ pkgs.hugo
+ pkgs.html-tidy
+ ];
+
+ buildPhase = ''
+ ${scripts.lib.createShellScript pkgs "all" ./build/all.sh}/run.sh "${pdfs.packages.${system}.default}" "${images.packages.${system}.default}" "${anki-decks.packages.${system}.default}" "${buildHugo}" "${katex-parts}" "${extra-content}"
+ '';
+
+ checkPhase = ''
+ echo "Linting HTML."
+ ${pkgs.html-tidy}/bin/tidy
+ '';
+
+ installPhase = ''
+ mv output $out
+ '';
+ };
in rec {
packages = flake-utils.lib.flattenTree {
gitAndTools = pkgs.gitAndTools;
+ default = website;
};
- defaultPackage =
- let
- buildHugo = scripts.lib.createShellScript pkgs "hugo" ./docker/hugo/build.sh;
- in let
- katex-parts = pkgs.stdenv.mkDerivation {
- __contentAddressed = true;
- pname = "katex";
- version = "0.1.0";
- src = katex.outputs.packages.${system}.default;
-
- installPhase = ''
- mkdir "$out"
- ls -la .
- cp -r ./libexec/katex/dist "$out/dist"
- '';
- };
- in
- pkgs.stdenv.mkDerivation {
- __contentAddressed = true;
- pname = "patrickstevens.co.uk";
- version = "0.1.0";
-
- src = ./hugo;
-
- buildInputs = [
- pkgs.hugo
- pkgs.html-tidy
- ];
-
- buildPhase = ''
- ${scripts.lib.createShellScript pkgs "all" ./build/all.sh}/run.sh "${pdfs.packages.${system}.default}" "${images.packages.${system}.default}" "${anki-decks.packages.${system}.default}" "${buildHugo}" "${katex-parts}" "${extra-content}"
- '';
-
+ checks = {
+ fmt-check = pkgs.stdenvNoCC.mkDerivation {
+ name = "fmt-check";
+ src = ./.;
+ nativeBuildInputs = [pkgs.alejandra pkgs.shellcheck pkgs.shfmt];
checkPhase = ''
- echo "Linting HTML."
- ${pkgs.html-tidy}/bin/tidy
+ find . -type f -name '*.sh' | xargs shfmt -d -s -i 2 -ci
+ alejandra -c .
+ find . -type f -name '*.sh' -exec shellcheck -x {} \;
'';
+ installPhase = "mkdir $out";
+ dontBuild = true;
+ doCheck = true;
+ };
- installPhase = ''
- mv output $out
+ website-check = pkgs.stdenvNoCC.mkDerivation {
+ name = "website-check";
+ src = website;
+ installPhase = "mkdir $out";
+ dontBuild = true;
+ doCheck = true;
+ checkPhase = ''
+ ${pkgs.bash}/bin/bash ${scripts.lib.createShellScript pkgs "linkcheck" ./linkcheck.sh}/run.sh ${pkgs.lynx}/bin/lynx
'';
};
+ };
});
}
diff --git a/hugo/content/anki-decks/index.md b/hugo/content/anki-decks/index.md
index e5cea1b..887dee7 100755
--- a/hugo/content/anki-decks/index.md
+++ b/hugo/content/anki-decks/index.md
@@ -10,9 +10,9 @@ I have deleted almost all of the Anki decks on this page, because I think they w
They were made during a time when I didn't really know how to use Anki appropriately.
Any remaining decks here are CC-BY-SA.
-* [Geography]. You can filter out the `london-tube` tag if you like, or `world-capitals`, or `american-geography`.
+* [Geography] (the deck has a misleading name; it's actually a general Geography deck). You can filter out the `london-tube` tag if you like, or `world-capitals`, or `american-geography`.
This work by Patrick Stevens is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
-[Geography]: /AnkiDecks/Geography.apkg
\ No newline at end of file
+[Geography]: /AnkiDecks/CapitalsOfTheWorld.apkg
\ No newline at end of file
diff --git a/hugo/content/posts/2013-06-26-sylow-theorems.md b/hugo/content/posts/2013-06-26-sylow-theorems.md
index 88b3d96..adb3b58 100644
--- a/hugo/content/posts/2013-06-26-sylow-theorems.md
+++ b/hugo/content/posts/2013-06-26-sylow-theorems.md
@@ -14,7 +14,7 @@ summary: "A fairly long and winding way through a proof of the three Sylow theor
---
(This post is mostly to set up a kind of structure for the website; in particular, to be the first in a series of posts summarising some mathematical results I stumble across.)
-EDIT: There is now [an Anki deck](/AnkiDecks/SylowTheoremsProof.apkg) of this proof, and a [collection of poems][sylow sonnets] summarising it.
+EDIT: There is now a [collection of poems][sylow sonnets] summarising this proof.
In Part IB of the Mathematical Tripos (that is, second-year material), there is a course called Groups, Rings and Modules. I took it in the academic year 2012-2013, when it was lectured by [Imre Leader](https://en.wikipedia.org/wiki/Imre_Leader). He told us that there were three main proofs of the [Sylow theorems](https://en.wikipedia.org/wiki/Sylow_theorems), two of which were horrible and one of which was nice; he presented the "nice" one. At the time, I thought this was the most beautiful proof of anything I'd ever seen, although other people have told me it's a disgusting proof.
diff --git a/hugo/content/posts/2014-09-09-sum-of-two-squares-theorem.md b/hugo/content/posts/2014-09-09-sum-of-two-squares-theorem.md
index 5750627..d9ecd9e 100644
--- a/hugo/content/posts/2014-09-09-sum-of-two-squares-theorem.md
+++ b/hugo/content/posts/2014-09-09-sum-of-two-squares-theorem.md
@@ -12,7 +12,7 @@ aliases:
title: Sum-of-two-squares theorem
---
-*Wherein I detail the most beautiful proof of a theorem I've ever seen, in a bite-size form suitable for an Anki deck. I attach the [Anki deck], which contains the bulleted lines of this post as flashcards.*
+*Wherein I detail the most beautiful proof of a theorem I've ever seen, in a bite-size form suitable for an Anki deck.
# Statement
There's no particularly nice way to motivate this in this context, I'm afraid, so we'll just dive in. I have found this method extremely hard to motivate - a few of the steps are a glorious magic.
@@ -32,8 +32,6 @@ Additionally, we'll call a number which is the sum of two squares a **nice** num
## First implication: if primes 3 mod 4 appear only to even powers…
We prove the result first for the primes, and will then show that niceness is preserved on taking products.
-
-
* Let \\(p=2\\). Then \\(p\\) is trivially the sum of two squares: it is \\(1+1\\).
* Let \\(p\\) be 1 mod 4.
* Then modulo \\(p\\), we have \\(-1\\) is square.
@@ -81,5 +79,4 @@ That ends the proof. Its beauty lies in the way it regards sums of two squares a
[Gaussian integers]: https://en.wikipedia.org/wiki/Gaussian_integers
[UFD]: https://en.wikipedia.org/wiki/Unique_factorization_domain
[irreducible]: https://en.wikipedia.org/wiki/Irreducible_element
-[prime]: https://en.wikipedia.org/wiki/Prime_element
-[Anki deck]: {{< baseurl >}}AnkiDecks/SumOfTwoSquaresTheorem.apkg
+[prime]: https://en.wikipedia.org/wiki/Prime_element
\ No newline at end of file
diff --git a/linkcheck.sh b/linkcheck.sh
new file mode 100644
index 0000000..2a76ed6
--- /dev/null
+++ b/linkcheck.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+bad=0
+
+LYNX=$1
+
+evaluate_file() {
+ target=$1
+ links=$("$LYNX" -dump --listonly -image_links --nonumbers -hiddenlinks=listonly "$target" | awk '
+/Visible links/ {
+found=1
+next
+}
+found { print }
+' | grep 'file:' | cut -d '/' -f 3- | grep -v '#')
+
+ # hurr durrr accidentally quadratic
+ for link in $links; do
+ filename=".$link"
+ if [ -d "$filename" ]; then
+ filename="$filename/index.html"
+ fi
+
+ if ! [ -e "$filename" ]; then
+ echo "File does not exist, while parsing '$target': $filename" >&2
+ bad=1
+ fi
+ done
+}
+
+while IFS= read -d '' -u3 -r file; do
+ evaluate_file "$file"
+done 3< <(find . -type f -name '*.html' -print0)
+
+if [ $bad -eq 1 ]; then
+ exit $bad
+fi