From 6076d5a2b46cdbcff62d71573571854b415a338f Mon Sep 17 00:00:00 2001 From: Will <83637728+wi11-holdsworth@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:14:52 +1100 Subject: [PATCH 01/17] Initial commit --- LICENSE | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. From 5fe2440107941ba9a62539cb9503ad40a5a5a23d Mon Sep 17 00:00:00 2001 From: wi11-holdsworth <83637728+wi11-holdsworth@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:16:57 +1100 Subject: [PATCH 02/17] site source --- Makefile | 204 +++++++++++++++++++++++++++++ articles/welcome.md | 18 +++ config | 7 + flake.lock | 57 ++++++++ flake.nix | 16 +++ shell.nix | 8 ++ tags/test | 2 + tags/welcome | 1 + templates/article_entry.html | 1 + templates/article_footer.html | 1 + templates/article_header.html | 1 + templates/article_list_footer.html | 1 + templates/article_list_header.html | 1 + templates/article_separator.html | 0 templates/footer.html | 1 + templates/header.html | 1 + templates/index_footer.html | 1 + templates/index_header.html | 1 + templates/tag_entry.html | 1 + templates/tag_index_footer.html | 1 + templates/tag_index_header.html | 1 + templates/tag_list_footer.html | 1 + templates/tag_list_header.html | 1 + templates/tag_separator.html | 1 + 24 files changed, 328 insertions(+) create mode 100644 Makefile create mode 100644 articles/welcome.md create mode 100644 config create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 shell.nix create mode 100644 tags/test create mode 100644 tags/welcome create mode 100644 templates/article_entry.html create mode 100644 templates/article_footer.html create mode 100644 templates/article_header.html create mode 100644 templates/article_list_footer.html create mode 100644 templates/article_list_header.html create mode 100644 templates/article_separator.html create mode 100644 templates/footer.html create mode 100644 templates/header.html create mode 100644 templates/index_footer.html create mode 100644 templates/index_header.html create mode 100644 templates/tag_entry.html create mode 100644 templates/tag_index_footer.html create mode 100644 templates/tag_index_header.html create mode 100644 templates/tag_list_footer.html create mode 100644 templates/tag_list_header.html create mode 100644 templates/tag_separator.html diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9e316cc --- /dev/null +++ b/Makefile @@ -0,0 +1,204 @@ +#!/usr/bin/make -f + +BLOG := $(MAKE) -f $(lastword $(MAKEFILE_LIST)) --no-print-directory +ifneq ($(filter-out help,$(MAKECMDGOALS)),) +include config +endif + +# The following can be configured in config +BLOG_DATE_FORMAT_INDEX ?= %x +BLOG_DATE_FORMAT ?= %x %X +BLOG_TITLE ?= blog +BLOG_DESCRIPTION ?= blog +BLOG_URL_ROOT ?= http://localhost/blog +BLOG_FEED_MAX ?= 20 +BLOG_FEEDS ?= rss atom +BLOG_SRC ?= articles + + +.PHONY: help init build deploy clean + +ARTICLES = $(shell git ls-tree HEAD --name-only -- $(BLOG_SRC)/ 2>/dev/null) +TAGFILES = $(patsubst $(BLOG_SRC)/%.md,tags/%,$(ARTICLES)) + +help: + $(info blogit init|build|deploy|clean) + +init: + mkdir -p $(BLOG_SRC) data templates + printf '
tags: ' > templates/tag_list_header.html + printf '#$$NAME' > templates/tag_entry.html + printf ', ' > templates/tag_separator.html + printf '
' > templates/tag_list_footer.html + printf 'posted: $$DATE_POSTED
edited: $$DATE_EDITED
,;bT}' \
+ -e 'x;/<\/code>/{x;s,\$$,\$,g;$$G;p;d};x' \
+ -e 's,\\\$$,\$,g' \
+ -e '/^####/{s,^####,,;s,$$,
,;H;s,.*,,;x;p;d}' \
+ -e '/^###/{s,^###,,;s,$$,
,;H;s,.*,,;x;p;d}' \
+ -e '/^##/{s,^##,,;s,$$,
,;H;s,.*,,;x;p;d}' \
+ -e '/^#/{s,^#,,;s,$$,
,;H;s,.*,,;x;p;d}' \
+ -e 's,`\([^`]*\)`,\1,g' \
+ -e 's,\*\*\(\([^*<>][^*<>]*\*\?\)*\)\*\*,\1,g' \
+ -e 's,\*\([^*<>][^*<>]*\)\*,\1,g' \
+ -e 's,!\[\([^]]*\)\](\([^)]*\)),
,g' \
+ -e 's,\[\([^]]*\)\](\([^)]*\)),\1,g' \
+ -e '/^- /{s,^- ,,;s,$$, ,;x;/^<\/ul>/{x;bL};p;s,.*,,;bT}' \
+ -e '/^[1-9][0-9]*\. /{s,^[0-9]*\. ,- ,;s,$$,
,;x;/^<\/ol>/{x;bL};p;s,.*,,;bT}' \
+ -e '/^$$/{x;/^$$/d;p;d}' \
+ -e 'x;/^$$/{s,.*,,;bT};x' \
+ -e ':L;$$G;p;d' \
+ -e ':T;p;:t;s,<\([^/>][^>]*\)>\(\(<[^/>][^>]*>\)*\),\2\1>,;/<[^\/>]/bt;x;/^$$/{$${x;p};d};bL' \
+ "$<" | envsubst >> $@; \
+ envsubst < templates/article_footer.html >> $@; \
+ envsubst < templates/footer.html >> $@; \
+
+blog/rss.xml: $(ARTICLES)
+ printf '\n\n\n%s \n%s\n%s \n' \
+ "$(BLOG_TITLE)" "$(BLOG_URL_ROOT)" "$(BLOG_DESCRIPTION)" > $@
+ for f in $(ARTICLES); do \
+ printf '%s ' "$$f"; \
+ git log --diff-filter=A --date="format:%s %a, %d %b %Y %H:%M:%S %z" --pretty=format:'%ad%n' -- "$$f"; \
+ done | sort -k2nr | head -n $(BLOG_FEED_MAX) | cut -d" " -f1,3- | while IFS=" " read -r FILE DATE; do \
+ printf '- \n
%s \n%s\n%s \n%s \n%s \n \n' \
+ "`head -n 1 $$FILE`" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE .md`.html" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE .md`.html" \
+ "$$DATE" \
+ "`sed -n '1d;/^$$/{2{d;b};q};p' < $$FILE`"; \
+ done >> $@
+ printf ' \n \n' >> $@
+
+blog/atom.xml: $(ARTICLES)
+ printf '\n\n%s \n%s \n%s \n\n%s \n\n' \
+ "$(BLOG_TITLE)" "$(BLOG_DESCRIPTION)" "$(shell date +%Y-%m-%dT%H:%M:%SZ)" "$(BLOG_URL_ROOT)" "$(BLOG_URL_ROOT)/atom.xml" "$(BLOG_URL_ROOT)/atom.xml" > $@
+ for f in $(ARTICLES); do \
+ printf '%s ' "$$f"; \
+ git log --diff-filter=A --date="format:%s %Y-%m-%dT%H:%M:%SZ" --pretty=format:'%ad %aN%n' -- "$$f"; \
+ done | sort -k2nr | head -n $(BLOG_FEED_MAX) | cut -d" " -f1,3- | while IFS=" " read -r FILE DATE AUTHOR; do \
+ printf '\n%s \n\n%s \n%s \n%s \n%s \n%s \n \n' \
+ "`head -n 1 $$FILE`" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE .md`.html" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE .md`.html" \
+ "$$DATE" \
+ "`git log -n 1 --date="format:%Y-%m-%dT%H:%M:%SZ" --pretty=format:'%ad' -- "$$FILE"`" \
+ "$$AUTHOR" \
+ "`sed -n '1d;/^$$/{2{d;b};q};p' < $$FILE`"; \
+ done >> $@
+ printf ' \n' >> $@
+
diff --git a/articles/welcome.md b/articles/welcome.md
new file mode 100644
index 0000000..bfc228f
--- /dev/null
+++ b/articles/welcome.md
@@ -0,0 +1,18 @@
+welcome!
+
+the static site generator i'm using to kickstart this blog[1] requires a single post to exist in order to compile, and failing to provide a post sends `make` into an infinite loop.
+
+so without further ado here it is, my first post!
+
+topics to expect once i get myself more organised:
+
+- basic tutorials on setting up self-hosted nixos web services
+- lazy hardware reviews
+- software shenanigans
+- anything else i feel is relevant and useful to the wider web
+
+thanks for stopping by ^.^
+
+[1] [blogit](https://pedantic.software/git/blogit)
+
+;tags: all
diff --git a/config b/config
new file mode 100644
index 0000000..a36760b
--- /dev/null
+++ b/config
@@ -0,0 +1,7 @@
+BLOG_REMOTE:=opal:/srv/fi33buzz
+BLOG_DATE_FORMAT:=%Y/%m/%d %H:%M
+BLOG_DATE_FORMAT_INDEX:=%Y/%m/%d
+BLOG_TITLE:=will holdsworth's blog
+BLOG_URL_ROOT:=https://fi33.buzz
+BLOG_FEED_MAX:=20
+BLOG_FEEDS:=rss atom
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..7ce6dc3
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,57 @@
+{
+ "nodes": {
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 0,
+ "narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=",
+ "path": "/nix/store/irknf7niks2djxz4csh7sr44wwrs082y-source",
+ "type": "path"
+ },
+ "original": {
+ "id": "nixpkgs",
+ "type": "indirect"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..c996dab
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,16 @@
+{
+ inputs.flake-utils.url = "github:numtide/flake-utils";
+
+ outputs = {
+ nixpkgs,
+ flake-utils,
+ ...
+ }:
+ flake-utils.lib.eachDefaultSystem
+ (system:
+ let pkgs = nixpkgs.legacyPackages.${system}; in
+ {
+ devShells.default = import ./shell.nix { inherit pkgs; };
+ }
+ );
+}
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 0000000..cf1447d
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,8 @@
+{ pkgs ? import {} }:
+ pkgs.mkShell {
+ nativeBuildInputs = with pkgs.buildPackages; [
+ gnumake
+ envsubst
+ python312Packages.mat2
+ ];
+}
diff --git a/tags/test b/tags/test
new file mode 100644
index 0000000..bae42c5
--- /dev/null
+++ b/tags/test
@@ -0,0 +1,2 @@
+test1
+test2
diff --git a/tags/welcome b/tags/welcome
new file mode 100644
index 0000000..0702cb5
--- /dev/null
+++ b/tags/welcome
@@ -0,0 +1 @@
+all
diff --git a/templates/article_entry.html b/templates/article_entry.html
new file mode 100644
index 0000000..858c6c4
--- /dev/null
+++ b/templates/article_entry.html
@@ -0,0 +1 @@
+- $DATE - $TITLE
\ No newline at end of file
diff --git a/templates/article_footer.html b/templates/article_footer.html
new file mode 100644
index 0000000..b55125b
--- /dev/null
+++ b/templates/article_footer.html
@@ -0,0 +1 @@
+
posted: $DATE_POSTED
edited: $DATE_EDITED