diff options
| author | Jakob L. Kreuze | 2019-07-12 20:10:32 -0400 |
|---|---|---|
| committer | Jakob L. Kreuze | 2019-07-13 19:24:32 -0400 |
| commit | c9a30e04e8603c9796fec663a2d374e41e2e6031 (patch) | |
| tree | 013bb0edb1e7d7285cdc6590e16c0bd209284df4 | |
| parent | ed1e5a14dc8c13a564b784ee0fa618cd2f63835b (diff) | |
Rewrite Haunt configuration.
44 files changed, 2145 insertions, 1151 deletions
diff --git a/haunt/css/jakob.css b/haunt/css/jakob.css deleted file mode 100644 index b8a3846..0000000 --- a/haunt/css/jakob.css +++ /dev/null @@ -1,302 +0,0 @@ -/* Use smaller fonts and line-height on smaller screens. */ - -@media (max-width: 54rem) { - body { - font-size: 14px; - line-height: 160%; - } -} - -@media (max-width: 26rem) { - body { - font-size: 12px; - line-height: 150%; - } -} - -body { - color: #4D4D4D; - background-color: #eee; - font-family: 'Cantarell', serif; - line-height: 140%; - text-rendering: optimizeLegibility; -} - -h1, h2, h3 { - font-family: 'Cantarell', sans; -} - -h1 { - font-size: 150%; - line-height: 110%; -} - -h2 { - font-size: 115%; -} - -h3 { - font-size: 100%; -} - -a { - color: #159957; - text-decoration: none; -} - -pre { - font-family: "Hack", monospace; - font-size: 90%; - line-height: 110%; - background-color: #303539; - padding: 1rem; - color: #f0e9dc; - border-radius: 4px; - overflow-x: scroll; -} - -code { - font-family: "Hack", monospace; -} - -blockquote { - padding-left: 2rem; - border-left: 5px solid #eee; - font-style: italic; -} - -/* Footer */ - -footer { - border-top: 1px solid #ccc; - font-size: 80%; -} - -.copyright { - text-align: center; -} - -.cc-button { - margin-left: 1rem; -} - -/* Navigation */ - -nav { - font-family: "Cantarell", sans; - padding-top: 1rem; - padding-bottom: 1rem; - border-bottom: 1px solid #eee; -} - -nav ul { - list-style-type: none; - margin: 0; - padding: 0; -} - -nav a { - display: inline-block; - color: #000; -} - -nav a:hover { - color: #000; -} - -nav a:visited { - color: #000; -} - -@media (min-width: 800px) { - nav { - margin-bottom: 3rem; - } - - nav ul { - display: inline-block; - } - - nav li { - display: inline; - padding: 1rem; - } - - nav li:first-child { - padding-left: 0; - } -} - -@media (max-width: 800px) { - nav ul { - list-style-type: none; - margin: 0; - padding: 0; - } -} - -/* Container */ - -@media (min-width: 1140px) { - .container { - margin-left: 14rem; - margin-right: 4rem; - max-width: 52rem; - } -} - -@media (min-width: 800px) and (max-width: 1140px) { - .container { - margin-left: 6rem; - margin-right: 4rem; - max-width: 52rem; - } -} - -@media (max-width: 800px) { - .container { - margin: 1rem; - } -} - -.fade-text { - color: #ddd; -} - -/* Summaries */ - -.summary { - margin-bottom: 3rem; -} - -.summary .date { - margin-bottom: 0rem; -} - -.summary p { - margin-top: 1rem; - margin-bottom: 1rem; -} - -/* Posts */ - -.date { - margin-top: -1rem; - margin-bottom: 2rem; - color: #666; -} - -.tags { - margin-top: -2rem; - color: #666; -} - -.tags ul { - display: inline; - list-style: none; - padding-left: 0; -} - -.tags li { - display: inline; - padding-right: 0.5rem; -} - -.post img, .centered-image { - display: block; - max-width: 100%; - height: auto; - margin: 0 auto; - padding: 0px; - border-radius: 4px; -} - -.post video { - display: block; - margin: 0 auto; - padding: 0px; - max-width: 100%; -} - -figcaption { - margin: 1rem 1rem 0 1rem; - color: #717171; - font-style: italic; - font-size: 90%; -} - -.footpara { - display: inline; -} - -.mastodon { - width: 70%; - margin: auto; -} - -.mastodon iframe { - width: 100%; -} - -#MathJax-Element-4-Frame { - padding-right: 8px; -} - -table { - border-spacing: 0; - border-collapse: collapse; -} - -td, th { - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #ddd; -} - -.info { - background-color: #5bc0de; -} - -.good { - background-color: #5cb85c; - border-color: #4cae4c; -} - -.okay { - background-color: #ec971f; - border-color: #d58512; -} - -.bad { - background-color: #dc3545; -} - -.label { - display: inline; - padding: .3em .6em .3em; - font-size: 75%; - font-weight: 700; - line-height: 1; - color: #fff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em; -} - -/* Webmention */ - -ul#webmention-container { - list-style-type: none; -} - -ul#webmention-container img.u-photo { - width: 4rem; - padding: 1rem; - float: left; -} - -ul#webmention-container div.p-author * { - padding-right: 1rem; -} diff --git a/haunt/custom/alias.scm b/haunt/custom/alias.scm deleted file mode 100644 index 388842a..0000000 --- a/haunt/custom/alias.scm +++ /dev/null @@ -1,44 +0,0 @@ -;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> -;;; -;;; This program is free software; you can redistribute it and/or -;;; modify it under the terms of the GNU General Public License as -;;; published by the Free Software Foundation; either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -(define-module (custom alias) - #:use-module (haunt html) - #:use-module (haunt page) - #:export (article-aliases)) - -(define (article-alias alias target) - "Create a page named ALIAS that redirects to TARGET." - (make-page (string-append alias "/index.html") - `((doctype "html") - (html - (head - (title ,target) - (link (@ (rel "canonical") (href ,target))) - (meta (@ (name "robots") (content "noindex"))) - (meta (@ (charset "utf-8"))) - (meta (@ (http-equiv "refresh") - (content ,(string-append "0; " target))))))) - sxml->html)) - -(define (article-aliases aliases) - "Return a procedure that transforms a list of article ALIASES into pages -redirecting from one arbitrary file to another." - (lambda (site posts) - (map (lambda (pair) - (let ((alias (car pair)) - (target (cdr pair))) - (article-alias alias target))) - aliases))) diff --git a/haunt/custom/tag.scm b/haunt/custom/tag.scm deleted file mode 100644 index 3821499..0000000 --- a/haunt/custom/tag.scm +++ /dev/null @@ -1,64 +0,0 @@ -;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> -;;; -;;; This program is free software; you can redistribute it and/or -;;; modify it under the terms of the GNU General Public License as -;;; published by the Free Software Foundation; either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -(define-module (custom tag) - #:use-module (custom theme) - #:use-module (haunt builder blog) - #:use-module (haunt html) - #:use-module (haunt page) - #:use-module (haunt post) - #:export (all-tags - sort-by-tag)) - -(define (tag-counts posts) - "Return an alist of every tag used in POSTS paired with the number of times it -is used." - (sort (map (lambda (tag) (cons (car tag) (length (cdr tag)))) - (posts/group-by-tag posts)) - (lambda (a b) (> (cdr a) (cdr b))))) - -(define (format-tag pair) - "Return an SXML expression for the tag-count pair." - (let* ((tag (car pair)) - (count (cdr pair)) - (target (format #f "/tag-~a.html" tag))) - `(p (a (@ (href ,target)) ,tag) - ,(format #f " (~a)" count)))) - -(define (all-tags) - "Return a procedure creating a page listing all of the tags used in the blog." - (lambda (site posts) - (let ((body (append `((h1 "All Tags")) - (map format-tag (tag-counts posts))))) - (make-page "tags.html" - (with-layout jakob-theme site "All Tags" body) - sxml->html)))) - -(define (sort-by-tag) - "Return a procedure that transforms a list of posts into pages containing only -the posts that have a certain tag." - (lambda (site posts) - (map (lambda (pair) - (let* ((tag-name (car pair)) - (posts (posts/reverse-chronological (cdr pair))) - (title (format #f "Posts tagged as \"~a\"" tag-name)) - (file-name (format #f "tag-~a.html" tag-name)) - (body `(h1 ,(format #f "Tagged as \"~a\"" tag-name)))) - (make-page - file-name - (render-collection jakob-theme site title posts #f) - sxml->html))) - (posts/group-by-tag posts)))) diff --git a/haunt/custom/theme.scm b/haunt/custom/theme.scm deleted file mode 100644 index 64bb87a..0000000 --- a/haunt/custom/theme.scm +++ /dev/null @@ -1,133 +0,0 @@ -;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> -;;; -;;; This program is free software; you can redistribute it and/or -;;; modify it under the terms of the GNU General Public License as -;;; published by the Free Software Foundation; either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -(define-module (custom theme) - #:use-module (custom sxml) - #:use-module (haunt builder blog) - #:use-module (haunt post) - #:use-module (haunt site) - #:use-module (ice-9 match) - #:use-module (srfi srfi-19) - #:export (jakob-theme)) - -(define (first-paragraph post) - (let loop ((sxml (post-sxml post)) - (result '())) - (match sxml - (() (reverse result)) - ((or (('p ...) _ ...) (paragraph _ ...)) - (reverse (cons paragraph result))) - ((head . tail) - (loop tail (cons head result)))))) - -(define %page-style - (list (stylesheet "fonts") - (stylesheet "highlight") - (stylesheet "jakob"))) - -(define %page-meta - '((meta (@ (charset "utf-8"))) - (meta (@ (name "viewport") - (content "width=device-width, initial-scale=1.0"))))) - -(define %page-link - '((link (@ (rel "alternate") - (type "application/atom+xml") - (href "/index.xml"))) - (link (@ (rel "icon") - (type "image/vnd.microsoft.icon") - (href "/favicon.ico"))) - (link (@ (rel "webmention") - (href "https://webmention.io/jakob.space/webmention"))) - (link (@ (rel "pingback") - (href "https://webmention.io/jakob.space/xmlrpc"))) - (link (@ (rel "me") - (href "https://mastodon.sdf.org/@jakob"))) - (link (@ (rel "pgpkey authn") - (href "/gpg.txt"))))) - -(define jakob-theme - (theme #:name "jakob" - #:layout - (lambda (site title body) - `((doctype "html") - (html - (head - (title ,(string-append title " — " (site-title site))) - ,@%page-style - ,@%page-meta - ,@%page-link) - (body - (div (@ (class "container")) - (nav - (ul (li ,(link "Jakob L. Kreuze" "/")) - (li (@ (class "fade-text")) " ") - (li ,(link "About" "/about.html")) - (li ,(link "Projects" "/projects.html")) - (li ,(link "Tags" "/tags.html")) - (li ,(link "Atom" "/atom.xml")))) - ,body - (footer (@ (class "text-center")) - (p (@ (class "copyright")) - "© 2019 Jakob L. Kreuze" - ,%cc-by-sa-button) - (p "Unless otherwise specified, the text and images -on this site are free culture works available under the " ,%cc-by-sa-link " -license.") - (p "This website is built with " - ,(link "Haunt" "http://haunt.dthompson.us") - ", a static site generator written in " - ,(link "Guile Scheme" "https://gnu.org/software/guile") - ".") - (a (@ (href "/weblabels.html") - (rel "jslicense")) - (p "JavaScript license information")))))))) - #:post-template - (lambda (post) - `((h1 (@ (class "title")) - ,(post-ref post 'title)) - (div (@ (class "date")) - ,(date->string (post-date post) "~B ~d, ~Y")) - (div (@ (class "tags")) - (ul - (li "Tagged as" - ,@(map (lambda (tag) - `(li ,(link tag (format #f "/tag-~a.html" tag)))) - (post-ref post 'tags))))) - (div (@ (class "post")) ,(post-sxml post)) - (hr) - (h2 ,(link "Webmentions" "https://indieweb.org/Webmention") " for this Page") - (ul (@ (id "webmention-container"))) - (script (@ (src "/js/webmention.js"))))) - #:collection-template - (lambda (site title posts prefix) - (define (post-uri post) - (string-append "/" (or prefix "") - (site-post-slug site post) ".html")) - `((h1 ,title) - ,(map (lambda (post) - (let ((uri (string-append "/" - (site-post-slug site post) - ".html"))) - `(div (@ (class "summary")) - (h2 (a (@ (href ,uri)) - ,(post-ref post 'title))) - (div (@ (class "date")) - ,(date->string (post-date post) "~B ~d, ~Y")) - (div (@ (class "post")) - ,(first-paragraph post)) - (a (@ (href ,uri)) "read more ➔")))) - posts))))) diff --git a/haunt/data/blogroll.scm b/haunt/data/blogroll.scm new file mode 100644 index 0000000..e7a3d2e --- /dev/null +++ b/haunt/data/blogroll.scm @@ -0,0 +1,866 @@ +'(("Adam Sawicki" + "http://asawicki.info/" + (c++ + game-development + graphics + programming + video-games + windows)) + ("Bit Cannon" + "http://bitcannon.net/" + (linux + rust + programming)) + ("(proclaim λ)" + "http://blog.macrolet.net/" + (common-lisp + functional-programming + hardware + lisp + programming)) + ("Brads Blog" + "http://bradhodge.ca/blog/" + (hardware + retro-tech)) + ("Charlie the Ninja" + "http://charliethe.ninja/" + (bsd + c + game-development + graphics + programming + video-games + x86)) + ("DSASMBLR" + "http://dsasmblr.com/" + (game-hacking + reversing + security + video-games)) + ("Emacs Horrors" + "http://emacshorrors.com/" + (emacs + emacs-lisp + lisp + programming)) + ("Emacs Ninja" + "http://emacsninja.com/" + (emacs + emacs-lisp + lisp + programming)) + ("Fabien Sanglard" + "http://fabiensanglard.net/" + (c + c++ + game-development + graphics + hardware + programming + video-games)) + ("faehnri.ch" + "http://faehnri.ch/" + (c + c++ + game-hacking + reversing + video-games)) + ("gynvael.coldwind//vx.log" + "https://gynvael.coldwind.pl/?blog=1&lang=en" + (capture-the-flag + game-development + programming + reversing + security + video-games)) + ("Michael Nielsen" + "http://michaelnielsen.org/blog/" + (cogsci + math + practices + programming)) + ("steve losh" + "http://stevelosh.com/blog/" + (clojure + common-lisp + game-development + lisp + programming + video-games)) + ("jooru//vx tech blog" + "http://j00ru.vexillium.org/" + (binary-exploitation + malware + operating-systems + reversing + security + windows)) + ("Bob Nystrom" + "http://journal.stuffwithstuff.com/" + (game-development + programming + video-games)) + ("Lambda the Ultimate" + "http://lambda-the-ultimate.org/" + (functional-programming + lisp + programming + scheme)) + ("Zach Beane Common Lisp" + "http://lispblog.xach.com/" + (common-lisp + lisp + programming)) + ("meh." + "http://meh.schizofreni.co/" + (c + linux + programming + rust)) + ("null program" + "http://nullprogram.com/" + (bsd + c + c++ + emacs + emacs-lisp + graphics + linux + lisp + programming + python + x86)) + ("The Official Radare Blog" + "http://radare.today/" + (c + radare2 + programming + reversing)) + ("妖怪世捨て人" + "http://reader.tymoon.eu/" + (common-lisp + game-development + lisp + video-games)) + ("Richard Kallos" + "http://rkallos.com/" + (functional-programming + emacs + erlang + lisp + programming + scheme)) + ("samskivert" + "http://samskivert.com/blog/" + (functional-programming + programming)) + ("The sh3llc0d3rs blog" + "http://sh3llc0d3r.com/" + (binary-exploitation + capture-the-flag + computer-networking + security)) + ("shell-storm" + "http://shell-storm.org/" + (binary-exploitation + c + capture-the-flag + linux + operating-systems + reversing + security)) + ("Technomancy" + "https://technomancy.us/list" + (fennel + game-development + hardware + lisp + lua + programming + video-games)) + ("Vi Hart" + "http://vihart.com/" + (math)) + ("Charles, etc" + "http://www.charlesetc.com/" + (linux + programming + rust)) + ("Notes on Programming" + "http://www.codersnotes.com/notes/" + (graphics + programming + reversing + video-games)) + ("defmacro" + "http://www.defmacro.org/" + (functional-programming + linux + lisp + programming)) + ("Home Page of Evan Miler" + "http://www.evanmiller.org/" + (c + erlang + math + programming + rust + video-games)) + ("Style Warning" + "http://www.stylewarning.com/blog/" + (common-lisp + lisp + math)) + ("WezM.net" + "https://www.wezm.net/" + (programming + rust)) + ("0x90r00t" + "https://0x90r00t.com/" + (binary-exploitation + capture-the-flag + reversing + security)) + ("aixxe" + "https://aixxe.net/" + (game-hacking + linux + reversing + video-games)) + ("Pierre Neidhardts homepage" + "https://ambrevar.xyz/" + (emacs + functional-programming + linux + lisp + programming + scheme)) + ("arp242.net" + "https://arp242.net/" + (linux + programming + python)) + ("The Neo-Babbage Files" + "https://babbagefiles.xyz/" + (emacs + lisp + programming)) + ("Max Bernstein" + "https://bernsteinbear.com/blog/" + (functional-programming + lisp + programming)) + ("dmbaturins blog" + "https://blog.baturin.org/" + (computer-networking + functional-programming + linux + ocaml + programming + python + x86)) + ("Andrew Gallants Blog" + "https://blog.burntsushi.net/" + (linux + programming + rust)) + ("The blog at the bottom of the sea" + "https://blog.demofox.org/" + (crypto + game-development + graphics + math + programming + video-games)) + ("Improved Means for Achieving Deteriorated Ends" + "https://blog.kingcons.io/" + (common-lisp + hardware + lisp + programming + retro-tech)) + ("KRNL386" + "https://blog.krnl386.com/" + (retro-tech + reversing + windows)) + ("Separate Concerns" + "https://blog.separateconcerns.com/" + (c + linux + lua + programming)) + ("Lainblog" + "https://blog.soykaf.com/" + (decentralization + programming + retro-tech)) + ("Bluish Coder" + "https://bluishcoder.co.nz/" + (programming)) + ("Cryogenix" + "https://cryogenix.net/" + (bsd + retro-tech + reversing + x86)) + ("Fedor Indutnys Blog" + "https://darksi.de/" + (binary-exploitation + c++ + crypto + programming + security)) + ("Deftly.net" + "https://deftly.net/" + (bsd + erlang + functional-programming + haskell + programming)) + ("Bill de hÓra" + "https://dehora.net/journal/" + (programming + rust)) + ("/dev/krzaq" + "https://dev.krzaq.cc/" + (c++ + programming + reversing + video-games)) + ("Drew DeVaults Blog" + "https://drewdevault.com/" + (c + go + linux + programming)) + ("fuzzy notepad" + "https://eev.ee/blog/" + (art + c + doom + game-development + programming + python + retro-tech + rust + video-games)) + ("Eli Grey" + "https://eligrey.com/" + (javascript + programming)) + ("https://erkaman.github.io/articles.html" + "graphics" + (math + programming)) + ("The Brain Dump" + "https://floooh.github.io/" + (c + programming + retro-tech + reversing)) + ("Frederik Braun" + "https://frederik-braun.com/archives.html" + (programming + python)) + ("General Protection Fault" + "https://gpfault.net/" + (c++ + graphics + opengl + programming + retro-tech + reversing)) + ("Comfortably Numbered" + "https://hardmath123.github.io/" + (capture-the-flag + functional-programming + linux + lisp + math + programming + python + scheme)) + ("Infinity Plus One" + "https://infinityplusonemath.wordpress.com/" + (math)) + ("jamchambs blog" + "https://jamchamb.github.io/" + (c + hardware + powerpc + programming + retro-tech + reversing)) + ("Daniel Lemires Blog" + "https://lemire.me/blog/" + (math + programming + x86)) + ("Patterns in Cyberspace" + "https://leotindall.com/" + (decentralization + linux + programming + retro-tech + rust)) + ("Marios Lab" + "https://marioslab.io/posts/" + (programming)) + ("Tyler Glaiel" + "https://medium.com/@tglaiel" + (game-development + programming)) + ("Barely Functional" + "https://mgattozzi.com/" + (programming + rust)) + ("Mutos Blog" + "https://muto.ca/" + (emacs + functional-programming + programming + scheme)) + ("Nerderati" + "https://nerderati.com/" + (linux + math + programming + python)) + ("... and another thing ..." + "https://nick.zoic.org/" + (hardware + linux + programming + python)) + ("Nick Cano" + "https://nickcano.com/" + (capture-the-flag + game-hacking + hardware + programming + reversing + video-games)) + ("Nora Sandler" + "https://norasandler.com/" + (c + compilers + programming)) + ("codeblog" + "https://outflux.net/blog/" + (linux + operating-systems + programming)) + ("Objective-See" + "https://objective-see.com/" + (malware + reversing + security)) + ("Matt Pharrs blog" + "https://pharr.org/matt/blog/" + (graphics + programming + x86)) + ("phoenhex team" + "https://phoenhex.re/" + (binary-exploitation + reversing + security)) + ("programming is terrible" + "https://programmingisterrible.com/" + (programming)) + ("./pwnaccelerator BLOG" + "https://pwnaccelerator.github.io/" + (crypto + hardware + reversing + security)) + ("Computable Multiverse" + "https://rakhim.org/" + (emacs + linux + math)) + ("John Ramsden" + "https://ramsdenj.com/" + (bsd + linux)) + ("RETRO.MOE" + "https://retro.moe/" + (hardware + retro-tech)) + ("Rufflewinds Scratchpad" + "https://rufflewind.com/" + (haskell + linux + programming + rust)) + ("Brandon Skerritt" + "https://skerritt.blog/" + (crypto + programming + security)) + ("Causal Agency" + "https://text.causal.agency/" + (c + programming)) + ("η (eta)" + "https://theta.eu.org/posts.html" + (crypto + hardware + linux + programming + rust)) + ("Travis Goodspeeds Blog" + "https://travisgoodspeed.blogspot.com/" + (ham + hardware + reversing + sdr + security)) + ("Two-Bit History" + "https://twobithistory.org/" + (linux + lisp + programming + retro-tech)) + ("Occasionally sane" + "https://vfoley.xyz/" + (emacs + programming + rust + video-games)) + ("vmcall" + "https://vmcall.github.io/" + (game-hacking + programming + reversing + video-games)) + ("/dev/ram0" + "https://wargio.github.io/" + (hardware + programming + radare2 + reversing)) + ("mindless-area" + "https://wbenny.github.io/posts/" + (hardware + reversing + windows)) + ("wingolog" + "https://wingolog.org/" + (functional-programming + linux + lisp + lua + programming + scheme)) + ("Wolf480pl" + "https://wolf480pl.github.io/" + (linux + programming)) + ("Frederic Cambus" + "https://www.cambus.net/" + (bsd + c + programming + x86)) + ("The Digital Antiquarian" + "https://www.filfre.net/" + (hardware + retro-tech + video-games)) + ("Kirsle.net" + "https://www.kirsle.net/" + (crypto + go + programming + security)) + ("Project Nayuki" + "https://www.nayuki.io/" + (art + c + c++ + crypto + math + programming + x86)) + ("Inane Observations" + "https://yingtongli.me/blog/" + (crypto + linux + math + reversing + security + video-games)) + ("zayenz" + "https://zayenz.se/blog" + (programming + rust)) + ("The Stone Zone" + "http://thestone.zone/" + (hardware + lisp + programming + reversing)) + ("David Boddie" + "http://www.boddie.org.uk/david/www-repo/Personal/Updates/index.html" + (programming + python + reversing)) + ("Alicefs website" + "https://alicef.me/" + (gentoo + linux)) + ("~ben" + "https://ben.tild3.org/" + (linux)) + ("0day rocks!" + "https://0day.rocks/" + (crypto + hardware + linux + math + programming + reversing + security + tor)) + ("Eccentric J" + "https://eccentric-j.com/" + (art + clojure + functional-programming + lisp + programming)) + ("Prosthetic Conscience" + "https://jfm.carcosa.net/blog/" + (linux + programming)) + ("Max Justicz" + "https://justi.cz/" + (binary-exploitation + reversing + security)) + ("The Obscuritory" + "https://obscuritory.com/feed/" + (retro-tech + video-games)) + ("Jon Gjengset" + "https://thesquareplanet.com/" + (linux + programming + rust + security)) + ("rtl-sdr.com" + "https://www.rtl-sdr.com/" + (gnuradio + ham + hardware + programming + sdr)) + ("pancake" + "https://medium.com/@trufae" + (c + programming + radare2 + rust)) + ("hexxendmns.motd.org" + "https://hexxendmns.motd.org/" + (doom + linux + mapping + programming + quake + video-games)) + ("Random ASCII – tech blog of Bruce Dawson" + "https://randomascii.wordpress.com/" + (compilers + hardware + powerpc + programming + windows + x86)) + ("David Thompson" + "https://dthompson.us/" + (emacs + guile + guix + linux + programming + scheme)) + ("InvisibleUp" + "https://invisibleup.com/" + (graphics + programming + retro-tech + reversing + video-games)) + ("ancientelectronics" + "https://ancientelectronics.wordpress.com/" + (hardware + retro-tech)) + ("North Coast News" + "https://northcoastsynthesis.com/news/" + (hardware)) + ("Bodil dot lol" + "https://bodil.lol/" + (compilers + programming + rust)) + ("Bits, pixels, cycles and more" + "https://zeux.io/" + (c++ + graphics + programming)) + ("Bill Demirkapis Blog" + "https://d4stiny.github.io/" + (reversing + security)) + ("blitter.net" + "https://blitter.net/" + (hardware + retro-tech + reversing)) + ("Breaking Eggs And Making Omelettes" + "https://multimedia.cx/eggs/feed/" + (programming + retro-tech + reversing + video-games + x86)) + ("Halestroms Peregrinations" + "https://halestrom.net/darksleep/" + (hardware + linux + programming)) + ("VeXation" + "https://log.vexation.ca/" + (malware + programming + retro-tech + reversing + windows)) + ("Skys blog" + "https://byebyesky.github.io/blog/" + (capture-the-flag + hardware + programming + reversing + security)) + ("Something Something Programming" + "https://nickdrozd.github.io/" + (common-lisp + emacs + functional-programming + lisp + math + programming + rust)) + ("evilsocket" + "https://www.evilsocket.net/" + (computer-networking + go + programming + reversing + security)) + ("GovanifY" + "https://govanify.com/post/" + (capture-the-flag + linux + programming + retro-tech + reversing + security)) + ("Code of Connor" + "https://codeofconnor.com/" + (game-development + linux + programming)) + ("cowlark.com" + "http://cowlark.com/" + (hardware + programming + retro-tech)) + ("danluu.com/" + "https://danluu.com/" + (hardware + linux + programming)) + ("PapaTutuWawas Blog" + "https://blog.latinise.me/" + (linux)) + ("Catbolis Blog" + "linux" + (programming + retro-tech)) + ("Tristans Site" + "http://thume.ca/archive.html" + (capture-the-flag + compilers + programming + rust + security)) + ("people.kernel.org" + "https://people.kernel.org/read" + (linux + operating-systems + programming)) + ("TheFloWs security blog" + "https://theofficialflow.github.io/" + (binary-exploitation + hardware + reversing + security)) + ("Christine Dodrills Blog" + "https://christine.website/blog" + (linux + programming)) + ("DustyCloud Brainstorms" + "https://dustycloud.org/blog/" + (functional-programming + lisp + programming + scheme)) + ("Hot Leaves in a Cold Worlds" + "http://www.philipzucker.com/" + (functional-programming + hardware + haskell + math + programming + python)) + ("Youve Reached the Center of the Internet" + "http://blog.benwiener.com/" + (functional-programming + ham + hardware + haskell + programming)) + ("Grievers Notes" + "https://romhack.github.io/doc/" + (programming + retro-tech + reversing + video-games)) + ("samiss blag" + "https://foldmap.ml/~samis/" + (gentoo + guix + linux)) + ("James Technical Notes" + "https://jamestechnotes.com/blog/" + (android + c + functional-programming + guile + guix + linux + programming + scheme)) + ("Aearnus' Realm" + "https://aearnus.github.io/" + '(functional-programming + haskell + math + perl6 + programming + python))) diff --git a/haunt/data/bookmarks.scm b/haunt/data/bookmarks.scm new file mode 100644 index 0000000..3a27614 --- /dev/null +++ b/haunt/data/bookmarks.scm @@ -0,0 +1,184 @@ +'(("Finding and Exploiting Hidden Features of Animal Crossings NES Emulator" + "https://jamchamb.github.io/2018/07/11/animal-crossing-nes-emulator-hacks.html" + (binary-exploitation + c + dolphin + game-hacking + ida + powerpc + retro-tech + reversing + video-games)) + ("Disassembling Jak & Daxter" + "http://www.codersnotes.com/notes/disassembling-jak/" + (lisp + mips + retro-tech + reversing + video-games)) + ("VMU Hackery" + "http://dmitry.gr/index.php?r=05.Projects&proj=25.%20VMU%20Hacking" + (hardware + retro-tech + reversing)) + ("Fixing a bug in an 18 year old Shockwave game" + "https://mattbruv.github.io/ccsr-bugfix/" + (game-hacking + retro-tech + reversing + video-games)) + ("Battletoads text decompression (huffman)" + "https://forums.nesdev.com/viewtopic.php?t=8609" + (6502 + retro-tech + reversing + video-games)) + ("Investigating a recent ebook DRM system (c. 2018)" + "https://yingtongli.me/blog/2019/03/28/drm2.html" + (android + arm + reversing)) + ("Looking inside the box" + "https://anvilventures.com/blog/looking-inside-the-box.html" + (python + reversing)) + ("Adventures in reverse engineering Broadcom NIC firmware" + "https://www.devever.net/~hl/ortega" + (arm + hardware + reversing + x86)) + ("A Great Old-Timey Game-Programming Hack" + "http://blog.moertel.com/posts/2013-12-14-great-old-timey-game-programming-hack.html" + (6502 + game-development + programming + retro-tech + video-games)) + ("CGA in 1024 Colors - a New Mode: the Illustrated Guide" + "https://int10h.org/blog/2015/04/cga-in-1024-colors-new-mode-illustrated/" + (dos + hardware + graphics + retro-tech)) + ("Ubershaders: A Ridiculous Solution to an Impossible Problem" + "https://dolphin-emu.org/blog/2017/07/30/ubershaders/" + (dolphin + graphics + hardware + opengl + programming + video-games)) + ("GDCCs Memory Model" + "http://ipfsgw.greyserv.net/ipns/davidph.greyserv.net/blog/GDCC_Memory_Model.html" + (c + doom + programming + video-games)) + ("What the Hero Sees: Field-of-View for Roguelikes " + "http://journal.stuffwithstuff.com/2015/09/07/what-the-hero-sees/" + (programming + algorithms + dart + game-development + interactive + video-games)) + ("A Constructive Look At TempleOS" + "http://www.codersnotes.com/notes/a-constructive-look-at-templeos/" + (operating-systems + programming)) + ("Guix: A most advanced operating system" + "https://ambrevar.xyz/guix-advance/index.html" + (functional-programming + guile + guix + linux + lisp + programming + scheme)) + ("Lisp Hackers" + "https://leanpub.com/lisphackers/read" + (culture + lisp + practices + programming)) + ("Pascal Costanzas Highly Opinionated Guide to Lisp" + "http://www.p-cos.net/lisp/guide.html" + (common-lisp + lisp + programming)) + ("The Nature of Lisp" + "http://www.defmacro.org/ramblings/lisp.html" + (java + lisp + programming)) + ("A Road to Common Lisp" + "http://stevelosh.com/blog/2018/08/a-road-to-common-lisp/" + (common-lisp + lisp + programming)) + ("Meta-Circular Adventures in Functional Abstraction" + "https://web.archive.org/web/20160609222905/https://chriskohlhepp.wordpress.com/metacircular-adventures-in-functional-abstraction-challenging-clojure-in-common-lisp/" + (common-lisp + functional-programming + lisp + programming)) + ("fibs, lies, and benchmarks" + "https://wingolog.org/archives/2019/06/26/fibs-lies-and-benchmarks" + (functional-programming + lisp + optimization + programming + programming-languages + scheme)) + ("Chaining Functions Without Returning Self" + "https://randompoison.github.io/posts/returning-self/" + (programming + rust)) + ("Implementing a NES Emulator in Rust" + "http://www.michaelburge.us/2019/03/18/nes-design.html" + (6502 + hardware + programming + rust + video-games)) + ("Building a Homebrew Video Game Console" + "https://internalregister.github.io/2019/03/14/Homebrew-Console.html" + (c + hardware + programming + z80)) + ("In Noisy Digital Era, Elegant Internet Still Thrives" + "https://www.npr.org/2012/04/17/150817325/in-noisy-digital-era-elegant-internet-still-thrives" + (culture)) + ("Codecademy vs. The BBC Micro" + "https://twobithistory.org/2019/03/31/bbc-micro.html" + (culture + historical)) + ("Graying Out" + "https://www.tbray.org/ongoing/When/201x/2019/03/11/Lights-Going-Out" + (culture + jabber)) + ("Does Visual Studio Rot the Mind?" + "http://www.charlespetzold.com/etc/DoesVisualStudioRotTheMind.html" + (practices + programming)) + ("Software disenchantment" + "http://tonsky.me/blog/disenchantment/" + (culture + programming)) + ("Writing system software: code comments." + "http://antirez.com/news/124" + (programming)) + ("Indirection Is Not Abstraction" + "https://www.silasreinagel.com/blog/2018/10/30/indirection-is-not-abstraction/" + (programming)) + ("Augmenting Long-term Memory" + "http://augmentingcognition.com/ltm.html" + (cogsci)) + ("The Process of Mastering a Skill" + "https://azeria-labs.com/the-process-of-mastering-a-skill/" + (cogsci)) + ("Writing well" + "http://www.defmacro.org/2016/12/22/writing-well.html" + (writing))) diff --git a/haunt/haunt.scm b/haunt/haunt.scm index 1700068..c5ef247 100644 --- a/haunt/haunt.scm +++ b/haunt/haunt.scm @@ -14,53 +14,16 @@ ;;; along with this program. If not, see ;;; <http://www.gnu.org/licenses/>. -(use-modules (custom alias) - (custom tag) - (custom theme) - (haunt asset) +(use-modules (haunt builder assets) (haunt builder atom) - (haunt builder assets) - (haunt builder blog) - (haunt html) - (haunt page) (haunt post) - (haunt reader) (haunt site) - (sxml simple) + (jakob builder blog) + (jakob builder htaccess) + (jakob builder static-pages) + (jakob reader html-prime) (srfi srfi-19) - (srfi srfi-26) - (ice-9 match)) - -(define (static-page title slug) - "Return a procedure serving statically-defined SXML." - (lambda (site posts) - (let ((file-name (format #f "~a.html" slug)) - (body (load (format #f "~a.scm" slug)))) - (make-page file-name - (with-layout jakob-theme site title body) - sxml->html)))) - -(define (make-slug post) - "Create a post slug from the source's filename." - (let* ((file-name (post-file-name post)) - (splice-start (1+ (string-rindex file-name (cut char=? <> #\/)))) - (splice-end (string-rindex file-name (cut char=? <> #\.)))) - (substring file-name splice-start splice-end))) - -;; Use a temporary reader until my patch makes it into an upstream release. -(define (read-html-post-prime port) - (values (read-metadata-headers port) - (let loop ((ret '())) - (catch 'parser-error - (lambda () - (match (xml->sxml port) - (('*TOP* sxml) (loop (cons sxml ret))))) - (lambda (key . parameters) - (reverse ret)))))) - -(define html-reader-prime - (make-reader (make-file-extension-matcher "html") - (cut call-with-input-file <> read-html-post-prime))) + (srfi srfi-26)) ;; Replace Haunt's default 'string->date* function with one that recognizes the ;; date format that Org uses. @@ -72,70 +35,15 @@ (register-metadata-parser! 'date org-string->date) -(define %collections - `(("Recent Posts" "index.html" ,posts/reverse-chronological))) - -(define %aliases - (list (cons "blog/post/Bad BEHAVIOR" - "/reverse-engineering-babbys-first-archive-format.html") - (cons "blog/post/First Impressions of the Rust Programming Language" - "/first-impressions-of-the-rust-programming-language.html") - (cons "blog/post/Duke on FluidSynth" - "/duke-on-fluidsynth.html") - (cons "posts/analyzing-executable-size-part-0" - "/analyzing-executable-size-part-0.html") - (cons "posts/backdoorctf-2017-funsignals" - "/backdoorctf-2017-funsignals.html") - (cons "posts/bad-behavior" - "/bad-behavior.html") - (cons "posts/challenges-re-writeups-1" - "/challenges-re-writeups-1.html") - (cons "posts/decompilation-by-hand" - "/decompilation-by-hand.html") - (cons "posts/duke-on-fluidsynth" - "/duke-on-fluidsynth.html") - (cons "posts/first-impressions-of-the-kotlin-programming-language" - "/first-impressions-of-the-kotlin-programming-language.html") - (cons "posts/first-impressions-of-the-rust-programming-language" - "/first-impressions-of-the-rust-programming-language.html") - (cons "posts/installing-gentoo-one-month-later" - "/installing-gentoo-one-month-later.html") - (cons "posts/making-your-own-music-player" - "/making-your-own-music-player.html") - (cons "posts/new-ambitions-for-a-new-year" - "/new-ambitions-for-a-new-year.html") - (cons "posts/plaidctf-2019" - "/plaidctf-2019.html") - (cons "posts/reverse-engineering-babbys-first-archive-format" - "/reverse-engineering-babbys-first-archive-format.html") - (cons "posts/sdl-tutorial-part-0x00" - "/sdl-tutorial-part-0x00.html") - (cons "posts/slime-the-world-postmortem" - "/slime-the-world-postmortem.html") - (cons "posts/understand-game-hacking-in-one-post" - "/understand-game-hacking-in-one-post.html"))) - (site #:title "Jakob's Personal Webpage" #:domain "jakob.space" #:default-metadata '((author . "Jakob L. Kreuze") (email . "zerodaysfordays@sdf.lonestar.org")) - #:make-slug make-slug #:readers (list html-reader-prime) - #:builders (list (blog #:theme jakob-theme #:collections %collections) - (article-aliases %aliases) - (atom-feed #:file-name "atom.xml") - (all-tags) - (sort-by-tag) - (static-page "About Me" "about") - (static-page "Projects" "projects") - (static-page "Webmention Outbox" "outbox") - (static-page "JavaScript Web Labels" "weblabels") - (static-directory "css") - (static-directory "fonts") - (static-directory "js") - (static-directory "images") - (lambda (site posts) - (make-asset "other/gpg.txt" "/gpg.txt")) - (lambda (site posts) - (make-asset "images/favicon.ico" "/favicon.ico")))) + #:builders + (list (atom-feed) + (blog) + (htaccess #:handler-404 "pages/404.html") + (static-pages) + (static-directory "static"))) diff --git a/haunt/jakob/builder/blog.scm b/haunt/jakob/builder/blog.scm new file mode 100644 index 0000000..2ed99e3 --- /dev/null +++ b/haunt/jakob/builder/blog.scm @@ -0,0 +1,178 @@ +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +(define-module (jakob builder blog) + #:use-module (haunt html) + #:use-module (haunt page) + #:use-module (haunt post) + #:use-module (haunt utils) + #:use-module (ice-9 format) + #:use-module (ice-9 match) + #:use-module (jakob theme) + #:use-module (jakob utils) + #:use-module (jakob utils sxml) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-19) + #:use-module (srfi srfi-26) + #:export (blog)) + +;;; Commentary: +;;; +;;; In favor of greater flexibility, Haunt's default 'blog' builder was not used +;;; for this site. This modules implements a similar builder, 'blog', with +;;; pagination and support for tag navigation. +;;; +;;; Code: + + +;;; +;;; Rendering. +;;; + +(define (render-article post) + "Return the SHTML for POST's contents." + `(main + (h1 ,(post-ref post 'title)) + (p ,(date->string (post-date post) "~B ~d, ~Y") + " ❖ " + "Tags: " + ,@(intersperse + (map (lambda (tag) + (hyperlink (format #f "/tag-~a.html" tag) tag)) + (post-ref post 'tags)) + ", ")) + (article + ,(post-sxml post)))) + +(define (render-preview post) + "Return the SHTML for a preview of POST." + (let ((crosspost-uri (post-ref post 'crosspost)) + (local-uri (post-uri post))) + `(section + (h2 ,(hyperlink (or crosspost-uri local-uri) (post-ref post 'title))) + (p ,@(maybe-cons* + (date->string (post-date post) "~B ~d, ~Y") + (when crosspost-uri + (list " ⮀ " (hyperlink local-uri "Crosspost"))) + " ❖ Tags: " + (intersperse + (map (lambda (tag) + (hyperlink (format #f "/tag-~a.html" tag) tag)) + (post-ref post 'tags)) + ", "))) + (p ,(first-paragraph post)) + ,(hyperlink (or crosspost-uri local-uri) "read more 🢩")))) + +(define (render-listing posts title previous-page next-page) + "Return SHTML presenting previews for POSTS, with the header TITLE and links +to PREVIOUS-PAGE and NEXT-PAGE." + `((h1 ,title) + ,@(map render-preview posts) + (nav + (@ (id "pagination")) + ,@(maybe-list + (when previous-page + (hyperlink previous-page "🢨 Previous Page")) + (when next-page + (hyperlink next-page "Next Page 🢩")))))) + + +;;; +;;; Creation of permalink pages for individual posts. +;;; + +;; Subdirectory for permalink pages. +(define %prefix "blog") + +(define (post-uri post) + "Return the path of POST relative to the site's base directory." + (let* ((file-name (post-file-name post)) + (splice-start (1+ (string-rindex file-name (cut char=? <> #\/)))) + (splice-end (string-rindex file-name (cut char=? <> #\.))) + (slug (substring file-name splice-start splice-end))) + (string-append %prefix "/" slug ".html"))) + +(define (post->page post) + "Return a Haunt page for POST." + (make-page (post-uri post) + (theme #:title (post-ref post 'title) + #:description (first-paragraph post) + #:keywords (post-ref post 'tags) + #:content (render-article post)) + sxml->html)) + + +;;; +;;; Implementation of pagination. +;;; + +(define %posts-per-page 10) + +(define* (paginate posts #:optional (posts-per-page %posts-per-page)) + "Partition POSTS into list of no more than POSTS-PER-PAGE posts, of the +form (index, posts)." + (let loop ((index 1) + (lst posts) + (result '())) + (if (null? lst) + result + (let ((how-many (min %posts-per-page (length lst)))) + (loop (1+ index) + (drop lst how-many) + (cons (list index (take lst how-many)) + result)))))) + +(define (post-list->pages base-title base-file-name posts) + "Return a list of Haunt pages for POST, with headers containing BASE-TITLE and +output file names beginning with BASE-FILE-NAME." + (define (index->file-name index) + (if (= index 1) + (format #f "~a.html" base-file-name) + (format #f "~a-~a.html" base-file-name index))) + (map (match-lambda + ((index subset) + (let ((title (if (= index 1) + base-title + (format #f "~a — Page ~a" base-title index))) + (previous-page (if (>= (1- index) 1) + (index->file-name (1- index)) + #f)) + (next-page (if (<= (1+ index) (ceiling/ (length posts) + %posts-per-page)) + (index->file-name (1+ index)) + #f))) + (make-page (index->file-name index) + (theme #:title title + #:content + (render-listing subset title + previous-page next-page)) + sxml->html)))) + (paginate posts))) + + +;;; +;;; Builder. +;;; + +(define (blog) + "Return a Haunt build procedure to create permalinks and post listings for all +of the 'post' objects associated with the site." + (lambda (site posts) + (append + (map post->page posts) + (post-list->pages + "Recent Posts" "index" + (posts/reverse-chronological posts))))) diff --git a/haunt/weblabels.scm b/haunt/jakob/builder/htaccess.scm index 9e0851a..fd20eca 100644 --- a/haunt/weblabels.scm +++ b/haunt/jakob/builder/htaccess.scm @@ -14,11 +14,22 @@ ;;; along with this program. If not, see ;;; <http://www.gnu.org/licenses/>. -`((h2 "JavaScript Web Labels") - (table (@ (id "jslicense-labels1")) - (tr (td (a (@ (href "/js/webmention.js")) - (p "/js/webmention.js"))) - (td (a (@ (href "http://www.gnu.org/licenses/gpl-3.0.html")) - (p "GNU General Public License 3.0 or later"))) - (td (a (@ (href "/js/webmention.js")) - (p "/js/webmention.js")))))) +(define-module (jakob builder htaccess) + #:use-module (haunt page) + #:export (htaccess)) + +(define* (htaccess-writer contents #:optional (port (current-output-port))) + (display (string-join contents "\n") port) + (newline port)) + +;; TODO: https://help.dreamhost.com/hc/en-us/articles/215747748-How-can-I-redirect-and-rewrite-my-URLs-with-an-htaccess-file- +(define* (htaccess #:key handler-404) + "Create an .htaccess file at the site's root. + +HANDLER-404 specifies the file name of the page to display for a 404 not found." + (define contents + `(,(if handler-404 + (format #f "ErrorDocument 404 ~a" handler-404)))) + + (lambda (site posts) + (make-page ".htaccess" contents htaccess-writer))) diff --git a/haunt/jakob/builder/outbox.scm b/haunt/jakob/builder/outbox.scm new file mode 100644 index 0000000..851ed88 --- /dev/null +++ b/haunt/jakob/builder/outbox.scm @@ -0,0 +1,51 @@ +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +(define-module (jakob builder outbox) + #:use-module (haunt page) + #:export (outbox)) + +;;; Commentary: +;;; +;;; Implementation of a multi-page Webmention outbox. See +;;; <https://webmention.net/> for details. +;;; +;;; Code: + +;; `((doctype "html") +;; (meta (@ (charset "utf-8"))) +;; (title ,title) +;; (div (@ (class "h-entry")) +;; (img (@ (src ,profile-picture) (class "u-photo") (width "40"))) +;; (a (@ (href ,profile-url) (class "u-url p-name")) ,profile-name)) +;; (p "in reply to:" (a (@ (href ,target-url) (class "u-in-reply-to")) +;; ,target-handle)) +;; (p (@ (class "e-content")) ,content) +;; (p (a (@ (href "self") (class "u-url")) +;; (time (@ (datetime ,datetime) (class "dt-published")) +;; ,datetime-pretty)))) + +;; (define* (htaccess #:key profile-url +;; profile-name +;; profile-picture +;; (comment-dir "webmentions")) +;; "Create a multi-page Webmention outbox, reading comments from COMMENT-DIR." +;; (define contents +;; `(,(if handler-404 +;; (format #f "ErrorDocument 404 ~a" handler-404)))) + +;; (lambda (site posts) +;; (make-page ".htaccess" contents htaccess-writer))) diff --git a/haunt/jakob/builder/static-pages.scm b/haunt/jakob/builder/static-pages.scm new file mode 100644 index 0000000..9089789 --- /dev/null +++ b/haunt/jakob/builder/static-pages.scm @@ -0,0 +1,48 @@ +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +(define-module (jakob builder static-pages) + #:use-module (haunt html) + #:use-module (haunt page) + #:use-module (ice-9 ftw) + #:use-module (jakob builder blog) + #:use-module (srfi srfi-1) + #:export (static-pages)) + +(define* (static-pages) + (lambda (site posts) + (define enter? (const #t)) + + (define (leaf file-name stat memo) + (let* ((dest (if (string-suffix? ".sxml" file-name) + (string-append (string-drop-right file-name + (string-length ".sxml")) + ".html") + file-name)) + (name (first (string-split (basename dest) #\.))) + (sxml (primitive-load file-name)) + ;; (contents (with-layout theme site name sxml)) + (contents sxml) + ) + (cons (make-page dest contents sxml->html) memo))) + + (define (noop file-name stat result) + result) + + (define (err file-name stat errno result) + (error "file processing failed with errno: " file-name errno)) + + (file-system-fold enter? leaf noop noop noop err '() "pages"))) diff --git a/haunt/jakob/reader/html-prime.scm b/haunt/jakob/reader/html-prime.scm new file mode 100644 index 0000000..373edd5 --- /dev/null +++ b/haunt/jakob/reader/html-prime.scm @@ -0,0 +1,44 @@ +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +;;; Commentary: +;;; +;;; Temporary reader containing my changes to 'html-reader'. This module will +;;; remain until Haunt sees another release and, thus, the fixes are available. +;;; +;;; Code: + +(define-module (jakob reader html-prime) + #:use-module (haunt post) + #:use-module (haunt reader) + #:use-module (ice-9 match) + #:use-module (srfi srfi-26) + #:use-module (sxml simple) + #:export (html-reader-prime)) + +(define (read-html-post-prime port) + (values (read-metadata-headers port) + (let loop ((ret '())) + (catch 'parser-error + (lambda () + (match (xml->sxml port) + (('*TOP* sxml) (loop (cons sxml ret))))) + (lambda (key . parameters) + (reverse ret)))))) + +(define html-reader-prime + (make-reader (make-file-extension-matcher "html") + (cut call-with-input-file <> read-html-post-prime))) diff --git a/haunt/jakob/theme.scm b/haunt/jakob/theme.scm new file mode 100644 index 0000000..23d3929 --- /dev/null +++ b/haunt/jakob/theme.scm @@ -0,0 +1,101 @@ +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +(define-module (jakob theme) + #:use-module (ice-9 match) + #:use-module (jakob utils sxml) + #:export (theme)) + + +;;; +;;; SHTML generation in the site's theme. +;;; + +(define %stylesheets '("normalize.css" "fonts.css" "highlight.css" "style.css")) +(define %link-rel '(("alternate" "/index.xml" "application/atom+xml") + ("icon" "/static/image/favicon.ico" "image/vnd.microsoft.icon") + ("me" "https://mastodon.sdf.org/@jakob") + ("webmention" "https://webmention.io/jakob.space/webmention") + ("pingback" "https://webmention.io/jakob.space/xmlrpc") + ("pgpkey authn" "/gpg.txt"))) +(define %nav-bar-tabs '(("About" "/pages/about.html") + ("Projects" "/pages/projects.html") + ("Tags" "/tag.html") + ("Atom" "/feed.xml"))) + +(define %title "Jakob's Personal Webpage") + +(define %header + `(header + ,(hyperlink "/" (image "lambda.svg" "home")) + (nav (ul + ,@(map (lambda (tuple) + `(li ,(apply hyperlink (reverse tuple)))) + %nav-bar-tabs))))) + +(define %footer + `(footer + (div + (p "© 2019 Jakob L. Kreuze") + ,(image "cc-by-sa-4.0.png" + "Creative Commons Attribution-ShareAlike 4.0 International (CC +BY-SA 4.0) Logo")) + (p "Unless otherwise specified, the text and images on this site are free +culture works available under the " + ,(hyperlink "https://creativecommons.org/licenses/by-sa/4.0/" + "Creative Commons Attribution Share-Alike 4.0 +International") + " license.") + (p "This website is built with " + ,(hyperlink "http://haunt.dthompson.us/" "Haunt") + ", a static site generator written in " + ,(hyperlink "https://gnu.org/software/guile" "Guile Scheme") + "."))) + +(define* (theme #:key + (title '()) + (description "") + (keywords '()) + (content '(div ""))) + "Return an SHTML document using the website's theme." + `((doctype "html") + (html + (@ (lang "en")) + + (head + ,(if (null? title) + `(title %title) + `(title ,(string-join (list title %title) " — "))) + + (meta (@ (charset "utf-8"))) + (meta (@ (name "keywords") + (content ,(string-join keywords ", ")))) + (meta (@ (name "description") + (content ,description))) + (meta (@ (name "viewport") + (content "width=device-width, initial-scale=1.0"))) + + ,@(map (lambda (file-name) (stylesheet file-name)) %stylesheets) + + ,@(map (match-lambda + ((rel href) `(link (@ (rel ,rel) (href ,href)))) + ((rel href type) `(link (@ (rel ,rel) (href ,href) (type ,type))))) + %link-rel)) + + (body + ,%header + ,content + ,%footer)))) diff --git a/haunt/jakob/utils.scm b/haunt/jakob/utils.scm new file mode 100644 index 0000000..33f8f93 --- /dev/null +++ b/haunt/jakob/utils.scm @@ -0,0 +1,59 @@ +;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +(define-module (jakob utils) + #:use-module (haunt post) + #:use-module (ice-9 match) + #:use-module (srfi srfi-1) + #:export (maybe-cons* + maybe-list + date->string* + intersperse + first-paragraph)) + +(define (maybe-list . args) + "Create a list of all ARGS that are neither #f nor unspecified." + (remove (lambda (element) + (or (not element) (unspecified? element))) + args)) + +(define (maybe-cons* . args) + "Cons all ARGS that are neither #f nor unspecified." + (apply cons* (apply maybe-list args))) + +(define (date->string* date) + "Convert DATE to human readable string." + (date->string date "~a ~d ~B ~Y")) + +(define (intersperse lst delim) + "Return the elements of LST delimited by DELIM, such that the resultant list +is of an odd length and every second element is DELIM." + (if (<= (length lst) 1) + lst + (cons* (car lst) + delim + (intersperse (cdr lst) delim)))) + +(define (first-paragraph post) + (let loop ((sxml (post-sxml post)) + (result '())) + (match sxml + (() (reverse result)) + ((or (('p ...) _ ...) (paragraph _ ...)) + (reverse (cons paragraph result))) + ((head . tail) + (loop tail (cons head result)))))) + diff --git a/haunt/custom/sxml.scm b/haunt/jakob/utils/sxml.scm index 1fbdc97..c4ce33d 100644 --- a/haunt/custom/sxml.scm +++ b/haunt/jakob/utils/sxml.scm @@ -14,24 +14,25 @@ ;;; along with this program. If not, see ;;; <http://www.gnu.org/licenses/>. -(define-module (custom sxml) - #:export (%cc-by-sa-button - %cc-by-sa-link - link - stylesheet)) +;;; Commentary: +;;; +;;; A number of utility procedure to aid in writing SXML by hand. +;;; +;;; Code: -(define %cc-by-sa-button - '(a (@ (class "cc-button") - (href "https://creativecommons.org/licenses/by-sa/4.0/")) - (img (@ (src "https://licensebuttons.net/l/by-sa/4.0/80x15.png"))))) +(define-module (jakob utils sxml) + #:export (hyperlink + image + stylesheet)) -(define %cc-by-sa-link - '(a (@ (href "https://creativecommons.org/licenses/by-sa/4.0/")) - "Creative Commons Attribution Share-Alike 4.0 International")) +(define (hyperlink target text) + `(a (@ (href ,target)) ,text)) -(define (link name uri) - `(a (@ (href ,uri)) ,name)) +(define* (image filename #:optional description) + (let ((src (string-append "/static/image/" filename))) + (if description + `(img (@ (src ,src) (alt ,description) (title ,description))) + `(img (@ (src ,src)))))) -(define (stylesheet name) - `(link (@ (rel "stylesheet") - (href ,(string-append "/css/" name ".css"))))) +(define (stylesheet file-name) + `(link (@ (rel "stylesheet") (href ,(format #f "/static/css/~a" file-name))))) diff --git a/haunt/js/webmention.js b/haunt/js/webmention.js deleted file mode 100644 index d1bb8e8..0000000 --- a/haunt/js/webmention.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * webmention.js -- Fetch and display mentions from webmention.io. - * Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - */ - -function buildApiUri() { - const snip = /https?:\/\/.*?\//.exec(window.location.href); - const page = window.location.href.substring(snip[0].length); - - // TODO: Build up from aliases, etc. - const aliases = [page]; - - return Array.concat( - ["https://webmention.io/api/mentions.jf2?"], - aliases.flatMap((alias) => { - const ref = "jakob.space"; - return [ - `target[]=http://${ref}/${alias}`, - `target[]=https://${ref}/${alias}` - ]; - }).join("&") - ).join(""); -} - -function getData(url, callback) { - if (fetch) { - fetch(url).then(function(response) { - if (response.status >= 200 && response.status < 300) { - return Promise.resolve(response); - } else { - return Promise.reject(new Error(`Request failed: ${response.statusText}`)); - } - }).then(function(response) { - return response.json(); - }).then(callback); - } else { - let xhr = new XMLHttpRequest(); - xhr.onload = function(data) { - callback(JSON.parse(data)); - } - xhr.onerror = function(error) { - throw new Error(`Request failed: ${error}`); - } - } -} - -function makeComment(comment) { - const strip = (uri) => { - const sep = "://"; - return uri.substring(uri.indexOf(sep) + sep.length); - }; - - const element = (type, attributes) => { - let res = document.createElement(type); - for (const attribute in attributes) { - res.setAttribute(attribute, attributes[attribute]); - } - return res; - }; - - // Create the h-card section. - let avatar = element("img", { - "class": "u-photo", - "src": comment.author.photo - }); - - let authorName = element("a", { - "class": "p-name u-url", - "href": comment.author.url - }); - authorName.textContent = comment.author.name; - - let authorURI = element("a", { - "class": "author_url", - "href": comment.author.url - }); - authorURI.textContent = strip(comment.author.url); - - let hCardContainer = element("div", { - "class": "p-author h-card author" - }); - hCardContainer.appendChild(avatar); - hCardContainer.appendChild(authorName); - hCardContainer.appendChild(authorURI); - - // Create the content section. - let contentContainer = element("div", { - "class": "e-content p-name comment-content", - }); - contentContainer.textContent = comment.content.text; - - // Create the metaline section. - let time = element("time", { - "class": "dt-published", - "datetime": comment.published - }); - time.textContent = (new Date(comment.published)).toString(); - - let linkBack = element("a", { - "class": "u-url", - "href": comment.url - }); - linkBack.appendChild(time); - - let metalineContainer = element("div", { - "class": "metaline" - }); - metalineContainer.appendChild(linkBack); - - // Put it all together. - let wrapper = element("li", { - "class": "p-comment h-cite comment", - }); - wrapper.appendChild(hCardContainer); - wrapper.appendChild(contentContainer); - wrapper.appendChild(metalineContainer); - - return wrapper; -} - -getData(buildApiUri(), (json) => { - json.children - .map(makeComment) - .forEach((elem) => { - document.getElementById("webmention-container").appendChild(elem); - })}); diff --git a/haunt/other/gpg.txt b/haunt/other/gpg.txt deleted file mode 100644 index aaa2630..0000000 --- a/haunt/other/gpg.txt +++ /dev/null @@ -1,190 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mQINBFyL0CEBEACrmHInpe3ZUJ5f0lhgYbvVobjBaSgu6XKt1Lm640XR/d5RmCsh -RS2oJ0zghzRQMx+BBTxr62OmuI8FU9MfU+ySHNJWcyobmGaPH0VG3n6xlkBY9g7l -zm+lccrxpXTd8QH5KRQNUYcL7/aYRNgtqYrYWmkxPSTM2ydFHc+W9wEAZTHLOQsc -aQJold5KJHM7DTwOq21oltLwWKCOL+MfMejjYoYRMT0UE9DduyR1H/cKsF9VvNjV -AHFaxCcibtYK0s5jyq/fVIq8ZqU9AEnwUtspqVzWINaDCbVPL/NzFkjDlzu5Y9Bi -ff9B/Ncd5TmstnsJ9cj6IgYjtwEPLw+aSJNsuzLlQROPDqDM6gaq8v+q8cjk2EH0 -ft0uFlWENf3kfql/WMMn8iVtYon0h9LLI480dQix4+OjNQFVrryPstuA2wTvGqIH -ECYJeI5hLT5EdShHEXGQEE5JAqXhd19lrWfoV0HI7IKnxE2UI+riaUNSJE8VCmIm -Y/e2YU/YFIzbrGOh/q0M2te+4ATrexwyBAxrlzl8gFiM3vTQGwJSIeIIlcVoUbti -/UcywO9pKQlga7AN0oQ0GnmWkGmdLj44wFFuIQSDdkGDyxurh+RPspnSW4HAz3fC -IbC5h9ACGcLWYT3p7JZGiR9SRbAHBDTgBF5F3hV9ORJpZ8ykN1V9iMq9pwARAQAB -tEdKYWtvYiBMLiBLcmV1emUgKGh0dHA6Ly9qYWtvYi5zcGFjZSkgPHplcm9kYXlz -Zm9yZGF5c0BzZGYubG9uZXN0YXIub3JnPokCUwQTAQgAPQIbAwUJAeEzgAIeAQIX -gBYhBMr8F0Od9PwacViMZSdn1f7sIYnvBQJci9d+BQsJCAcCBhUKCQgLAgMWAgEA -CgkQJ2fV/uwhie9HqA//SY9dIX46hjNIQpvWWLq8yKKMPZeC1B81JwyK3vimPrNz -MWeMTJcnmzupNfHXtSaYGh3GlBj6sRONLEGQVS25qBOLgo5TOtPD4V/F4rbqmwRN -scIMmHPN7s/n60if7dF2bOmrasCpkhROj8CCTsaImbFCYQW5kOywkvxP3tPM6sJd -6yIqMeb/LR+7VOYYZuCGx3VTXmLdB4eMtY7fHE3K9iZp4yNYsxib+mgeIFPhsdQ2 -uGC7aGm9XusKVLMx4zGrm0ddZdsQyGosp6Ynd4t+5Xb3PM6UyvTNVwTxh6vEBIMb -yIdz/6tC53xw0RlA86FUH+IY3CQLECjbZDPsjmKkD7KNcckUk11eQkhgMDHxgZAl -v3Qe4qiDb89UdVpkBJJvxjJztgVyjfHwJdsErzktgOZpnBP/TxNlKwmvKaffMe35 -kIzl0RHrQffQlLhWaw6nndsWzD33jqyd6LzVxhLP+s5QKFIC7KN63d0BeUqEQirD -Z6t1oKSaRWbK67MRRdTQ/hPb2wthw1TQ0ANXWMcpOHyyyZj2F64PLT6sWXvaE9Ky -PAUZP2StHWztz6sGyshmCWQot2gROUxbVqyRLxKu158BSbqKbjf2DuwTju8Vtpcn -qXJDE7L9LvuJo79CmGR/4cGN8SVY/yEfXPQh8+tqHJ0asXQ/iJ2pVZk5up9Wnr7R -0DbQNAEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3Jl -YXRlZCB3aXRoIEdJTVD/2wEEEAA1ADUANQA1ADkANQA8AEMAQwA8AFMAWgBQAFoA -UwB7AHEAZwBnAHEAewC6AIUAjwCFAI8AhQC6ARsAsADOALAAsADOALABGwD6AS8A -9gDmAPYBLwD6AcIBYQE5ATkBYQHCAgcBtAGdAbQCBwJ1AjMCMwJ1AxkC8QMZBAwE -DAVwEQA1ADUANQA1ADkANQA8AEMAQwA8AFMAWgBQAFoAUwB7AHEAZwBnAHEAewC6 -AIUAjwCFAI8AhQC6ARsAsADOALAAsADOALABGwD6AS8A9gDmAPYBLwD6AcIBYQE5 -ATkBYQHCAgcBtAGdAbQCBwJ1AjMCMwJ1AxkC8QMZBAwEDAVw/8IAEQgBIADwAwEi -AAIRAQMRAf/EABoAAAIDAQEAAAAAAAAAAAAAAAAEAgMFAQb/2gAIAQEAAAAA0CYA -AcVbAyuMq0t2dDgJnHXgAELWgyS9K1kAAI3ClWvMCvB3rDK5eg3aAABRfZSJ6LHF -kObpmVsJM2gAAEOMKFiseswacz12V+NAAABXW5VUdhB1LZWzm4o6IAAAC0C+htS/ -i+vZiuxVtnYAAACN0Zyu5SvrXU5jUUY6EwAAAz5aE6Vhp3pTmNVZ12iRkAAAx3L2 -OgAV5DlC97NfLSidgAU2r6F4ABhPRRemm1Kii1kAL4UWuAAGI5zO0u52jXS9mvAB -nxnptAAGM1FDSM3Rz3OoaYBzPvT9DOFdMSdyE+5+kZ17rgotU2cV0cxdzhbcEIUw -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 -BC2J8VM1ySLIhdpwOpBmfBui8bkX1s2dedJ+XQ== -=c2uQ ------END PGP PUBLIC KEY BLOCK----- diff --git a/haunt/outbox.scm b/haunt/outbox.scm deleted file mode 100644 index 04ea775..0000000 --- a/haunt/outbox.scm +++ /dev/null @@ -1,57 +0,0 @@ -;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> -;;; -;;; This program is free software; you can redistribute it and/or -;;; modify it under the terms of the GNU General Public License as -;;; published by the Free Software Foundation; either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -(use-modules (srfi srfi-19)) - -(define %comments - `(("https://aaronparecki.com/2018/06/30/11/your-first-webmention" - "@aaronpk" - "<2019-05-11 Sat 17:07>" - (p (@ (class "e-content")) - "Hoo, this comments section is a bit of a mess. " - "Anyway, I'm just testing out Webmentions like everyone else. " - "Don't mind me...")) - ("http://jakob.space/transition-to-haunt.html" - "@jakob" - "<2019-05-12 Sun 12:07>" - (p (@ (class "e-content")) - "Just testing out my Webmention inbox widget.")))) - -(define (h-card) - `(div (@ (class "u-author h-card")) - (img (@ (src "/images/favicon.png") - (class "u-photo"))) - (a (@ (href "http://jakob.space") - (class "u-url p-name")) - (p "Jakob L. Kreuze")))) - -(define (comment target-uri target-handle date sxml) - (let ((date (string->date date "<~Y-~m-~d ~a ~H:~M>"))) - `(li (@ (class "h-entry")) - ,(h-card) - (p "in reply to: " (a (@ (class "u-in-reply-to") - (href ,target-uri)) - ,target-handle)) - ,sxml - (a (@ (href "http://jakob.space/outbox.html") - (class "u-url")) - (time (@ (class "dt-published") - (datetime ,(date->string date "~Y-~m-~dT~H:~M:~S~z"))) - ,(date->string date "~c")))))) - -`((h2 "Webmention Outbox") - (ul (@ (id "webmention-container")) - ,@(map (lambda (args) (apply comment args)) %comments))) diff --git a/haunt/about.scm b/haunt/pages/about.sxml index 46ce42f..8bce651 100644 --- a/haunt/about.scm +++ b/haunt/pages/about.sxml @@ -1,3 +1,5 @@ +;;; -*- scheme -*- + ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> ;;; ;;; This program is free software; you can redistribute it and/or @@ -14,13 +16,13 @@ ;;; along with this program. If not, see ;;; <http://www.gnu.org/licenses/>. -(use-modules (custom sxml)) +(use-modules (jakob utils sxml)) `((h2 "Hey.") (p "I'm still in the process of putting things together, so this page is a bit empty.") (p "For those interested in contacting me, here's my info.") (ul (li "Email: zerodaysfordays at sdf.lonestar.org") - (li "GPG: " ,(link "5A7B 8C4C 70D5 FC3F 5E35 4625 3FE7 8039 D0E5 C118" "/gpg.txt")) + (li "GPG: " ,(hyperlink "5A7B 8C4C 70D5 FC3F 5E35 4625 3FE7 8039 D0E5 C118" "/gpg.txt")) (li "XMPP: jakob at xmpp.is") (li "IRC: tsarfox on freenode.net, and jakob everywhere else. I frequent #lobsters and the #tildetown on the tilde.town internal IRC."))) diff --git a/haunt/projects.scm b/haunt/projects.scm deleted file mode 100644 index 9173aea..0000000 --- a/haunt/projects.scm +++ /dev/null @@ -1,82 +0,0 @@ -;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> -;;; -;;; This program is free software; you can redistribute it and/or -;;; modify it under the terms of the GNU General Public License as -;;; published by the Free Software Foundation; either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -(use-modules (custom sxml)) - -(define %software-projects - '(("Mines" "Dormant" - "https://git.sr.ht/~jakob/mines" - ("Android implementation of the classic video game \"Minesweeper\".")) - ("Rebuild" "Dormant" - "https://git.sr.ht/~jakob/rebuild" - ("An attempt at reimplementing Ken Silverman's Build engine, with the goal of being modular enough to host a modern Blood source port.")) - ("wildmidi" "Dormant" - "https://git.sr.ht/~jakob/wildmidi" - ("A simple [Rust] wrapper around the WildMIDI software synthesizer library.")) - ("Slime the World" "Finished" - "https://git.sr.ht/~jakob/slime-the-world" - ("My entry for the 2018 Autumn Lisp Game Jam; a game about covering everything in slime.")) - ("Nekopack" "Finished" - "https://git.sr.ht/~jakob/nekopack" - ("Tool for extracting game data from Nekopara's XP3 archives.")) - ("skullfuck" "Finished" - "https://git.sr.ht/~jakob/skullfuck" - ("Optimizing compiler for Brainfuck, contained in a single C source file.")) - ("Brisket" "Abandoned" - "https://git.sr.ht/~jakob/brisket" - ("Primitive newsreader script for interacting with NNTP servers.")) - ("Hypodermic" "Abandoned" - "https://git.sr.ht/~jakob/hypodermic" - ("Proof-of-concept shared object injector that will eventually be integrated with PINCE.")) - ("Duke on FluidSynth" "Abandoned" - "https://git.sr.ht/~jakob/duke-on-fluidsynth" - ("Experimental FluidSynth MIDI driver for EDuke32.")))) - -(define %software-contributions - `(("Haiku" "Finished" - "https://www.haiku-os.org/" - ("The Haiku operating system." - (ul (li ,(link "1337: mediaplayer: Implement AppendM3uToPlaylist" - "https://review.haiku-os.org/c/haiku/+/1337")) - (li ,(link "1351: Add mime_db entry for application/vnd.apple.mpegurl (M3U)" - "https://review.haiku-os.org/c/haiku/+/1351"))))))) - -(define %packaging-projects - '(("zerodaysfordays" "Active" - "https://git.sr.ht/~jakob/zerodaysfordays" - ("My personal Gentoo ebuild overlay.")))) - -(define (project name status url description) - (let ((status-class (cond ((string= status "Active") "info") - ((string= status "Finished") "good") - ((string= status "Dormant") "okay") - ((string= status "Abandoned") "bad") - (else "info")))) - `(tr (td ,(link name url)) - (td (span (@ (class ,(string-append "label " status-class))) ,status)) - (td ,@description)))) - -(define (project-section name projects) - `((h2 ,name) - (table - (tbody - ,@(map (lambda (args) (apply project args)) projects))))) - -`((h2 "Projects") - (p "I'm still in the process of putting things together, so this page is a bit empty.") - ,@(project-section "Software" %software-projects) - ,@(project-section "Packaging" %packaging-projects) - ,@(project-section "Other Contributions" %software-contributions)) diff --git a/haunt/css/fonts.css b/haunt/static/css/fonts.css index b17b8fd..05a70c6 100644 --- a/haunt/css/fonts.css +++ b/haunt/static/css/fonts.css @@ -2,28 +2,28 @@ @font-face { font-family: 'Cantarell'; - src: url('/fonts/Cantarell-Bold.otf') format('opentype'); + src: url('/static/font/Cantarell-Bold.otf') format('opentype'); font-weight: bold; font-style: normal; } @font-face { font-family: 'Cantarell'; - src: url('/fonts/Cantarell-BoldOblique.otf') format('opentype'); + src: url('/static/font/Cantarell-BoldOblique.otf') format('opentype'); font-weight: bold; font-style: italic; } @font-face { font-family: 'Cantarell'; - src: url('/fonts/Cantarell-Oblique.otf') format('opentype'); + src: url('/static/font/Cantarell-Oblique.otf') format('opentype'); font-weight: normal; font-style: italic; } @font-face { font-family: 'Cantarell'; - src: url('/fonts/Cantarell-Regular.otf') format('opentype'); + src: url('/static/font/Cantarell-Regular.otf') format('opentype'); font-weight: normal; font-style: normal; } @@ -32,28 +32,28 @@ @font-face { font-family: 'Hack'; - src: url('/fonts/Hack-Bold.ttf'); + src: url('/static/font/Hack-Bold.ttf'); font-weight: bold; font-style: normal; } @font-face { font-family: 'Hack'; - src: url('/fonts/Hack-BoldItalic.ttf'); + src: url('/static/font/Hack-BoldItalic.ttf'); font-weight: bold; font-style: italic; } @font-face { font-family: 'Hack'; - src: url('/fonts/Hack-Italic.ttf'); + src: url('/static/font/Hack-Italic.ttf'); font-weight: normal; font-style: italic; } @font-face { font-family: 'Hack'; - src: url('/fonts/Hack-Regular.ttf'); + src: url('/static/font/Hack-Regular.ttf'); font-weight: normal; font-style: normal; } diff --git a/haunt/css/highlight.css b/haunt/static/css/highlight.css index 401f18d..401f18d 100644 --- a/haunt/css/highlight.css +++ b/haunt/static/css/highlight.css diff --git a/haunt/static/css/normalize.css b/haunt/static/css/normalize.css new file mode 100644 index 0000000..192eb9c --- /dev/null +++ b/haunt/static/css/normalize.css @@ -0,0 +1,349 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/haunt/static/css/style.css b/haunt/static/css/style.css new file mode 100644 index 0000000..b9f7beb --- /dev/null +++ b/haunt/static/css/style.css @@ -0,0 +1,151 @@ +html { + font-family: "Cantarell", sans-serif; +} + +@media (max-width: 54em) { + html { + font-size: 14px; + line-height: 160%; + } +} + +@media (max-width: 26em) { + html { + font-size: 12px; + line-height: 150%; + } +} + +body { + max-width: 54rem; + margin: .5rem auto; + position: relative; +} + +@media (max-width: 54em) { + body { + max-width: 100%; + padding: 0 1rem; + } +} + +/* Top-level header. */ + +body > header { + display: flex; + align-items: center; +} + +@media screen and (max-width: 480px) { + body > header { + flex-direction: column; + flex-wrap: wrap; + justify-content: space-around; + } +} + +body > header > a > img { + max-width: 4rem; +} + +@media screen and (min-width: 480px) { + body > header > a { + padding-right: 1rem; + } +} + +body > header > nav > ul { + list-style-type: none; + padding-left: 0; +} + +@media screen and (min-width: 480px) { + body > header > nav > ul > li { + display: inline-block; + padding: 1rem 2rem; + border-bottom: 2px solid #d2d6dd; + text-align: center; + } + + body > header > nav > ul > li > a { + color: #000; + text-decoration: none; + } +} + +/* Pagination navigation. */ + +#pagination { + display: flex; + justify-content: space-around; +} + +/* Links. */ + +a:link, a:visited { color:#0000EE; } + +/* Figures */ + +figure > img { + display: block; + max-width: 90%; + margin: auto; + + border-radius: 2px; +} + +figure > figcaption { + padding-top: 1rem; +} + +/* Embeds. */ + +.mastodon > iframe, +.peertube > iframe { + display: block; + width: 90%; + min-height: 100%; + margin: auto; + border-radius: 4px; +} + +/* Footnotes. */ + +.footdef { + margin-bottom: 1rem; +} + +.footdef > sup, .footpara { + display: inline; +} + +/* Source code. */ + +pre { + color: #f0e9dc; + font-family: "Hack", monospace; + font-size: 90%; + + background-color: #303539; + border-radius: 4px; + padding: 1rem; + overflow-x: scroll; +} + +/* Footer. */ + +body > footer { + margin-top: 1.2rem; + border-top: 2px solid #d2d6dd; +} + +body > footer > div { + margin-top: 1rem; + display: flex; + align-items: center; +} + +body > footer > div > p { + margin: 0; + padding-right: 1rem; +} diff --git a/haunt/fonts/Cantarell-Bold.otf b/haunt/static/font/Cantarell-Bold.otf Binary files differindex a5b620b..a5b620b 100644 --- a/haunt/fonts/Cantarell-Bold.otf +++ b/haunt/static/font/Cantarell-Bold.otf diff --git a/haunt/fonts/Cantarell-BoldOblique.otf b/haunt/static/font/Cantarell-BoldOblique.otf Binary files differindex 5f49d64..5f49d64 100644 --- a/haunt/fonts/Cantarell-BoldOblique.otf +++ b/haunt/static/font/Cantarell-BoldOblique.otf diff --git a/haunt/fonts/Cantarell-Oblique.otf b/haunt/static/font/Cantarell-Oblique.otf Binary files differindex 70539ed..70539ed 100644 --- a/haunt/fonts/Cantarell-Oblique.otf +++ b/haunt/static/font/Cantarell-Oblique.otf diff --git a/haunt/fonts/Cantarell-Regular.otf b/haunt/static/font/Cantarell-Regular.otf Binary files differindex fca6759..fca6759 100644 --- a/haunt/fonts/Cantarell-Regular.otf +++ b/haunt/static/font/Cantarell-Regular.otf diff --git a/haunt/fonts/Hack-Bold.ttf b/haunt/static/font/Hack-Bold.ttf Binary files differindex 7ff4975..7ff4975 100644 --- a/haunt/fonts/Hack-Bold.ttf +++ b/haunt/static/font/Hack-Bold.ttf diff --git a/haunt/fonts/Hack-BoldItalic.ttf b/haunt/static/font/Hack-BoldItalic.ttf Binary files differindex 3b137d9..3b137d9 100644 --- a/haunt/fonts/Hack-BoldItalic.ttf +++ b/haunt/static/font/Hack-BoldItalic.ttf diff --git a/haunt/fonts/Hack-Italic.ttf b/haunt/static/font/Hack-Italic.ttf Binary files differindex d26198a..d26198a 100644 --- a/haunt/fonts/Hack-Italic.ttf +++ b/haunt/static/font/Hack-Italic.ttf diff --git a/haunt/fonts/Hack-Regular.ttf b/haunt/static/font/Hack-Regular.ttf Binary files differindex 92a90cb..92a90cb 100644 --- a/haunt/fonts/Hack-Regular.ttf +++ b/haunt/static/font/Hack-Regular.ttf diff --git a/haunt/static/image/bad-behavior-debug-prints.png b/haunt/static/image/bad-behavior-debug-prints.png Binary files differnew file mode 100644 index 0000000..538ccec --- /dev/null +++ b/haunt/static/image/bad-behavior-debug-prints.png diff --git a/haunt/static/image/bad-behavior-vanilla-hexen-vulnerability.png b/haunt/static/image/bad-behavior-vanilla-hexen-vulnerability.png Binary files differnew file mode 100644 index 0000000..510cf5f --- /dev/null +++ b/haunt/static/image/bad-behavior-vanilla-hexen-vulnerability.png diff --git a/haunt/static/image/cc-by-sa-4.0.png b/haunt/static/image/cc-by-sa-4.0.png Binary files differnew file mode 100644 index 0000000..003dd0a --- /dev/null +++ b/haunt/static/image/cc-by-sa-4.0.png diff --git a/haunt/static/image/favicon.ico b/haunt/static/image/favicon.ico Binary files differnew file mode 100644 index 0000000..929e6ad --- /dev/null +++ b/haunt/static/image/favicon.ico diff --git a/haunt/static/image/lambda.svg b/haunt/static/image/lambda.svg new file mode 100644 index 0000000..d82b062 --- /dev/null +++ b/haunt/static/image/lambda.svg @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="176.52748" + height="185.1386" + id="svg2"> + <defs + id="defs4"> + <marker + refX="0" + refY="0" + orient="auto" + style="overflow:visible" + id="Arrow1Mstart"> + <path + d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " + transform="matrix(0.4,0,0,0.4,4,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" + id="path3206" /> + </marker> + <marker + refX="0" + refY="0" + orient="auto" + style="overflow:visible" + id="Arrow1Mend"> + <path + d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " + transform="matrix(-0.4,0,0,-0.4,-4,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" + id="path3209" /> + </marker> + <marker + refX="0" + refY="0" + orient="auto" + style="overflow:visible" + id="Arrow1Lstart"> + <path + d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " + transform="matrix(0.8,0,0,0.8,10,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none" + id="path3200" /> + </marker> + </defs> + <path + d="M 47.243238,12.929372 L 47.243238,38.836954 L 68.578895,38.836954 L 77.341753,65.887518 L 12.191803,166.85089 L 44.195288,166.85089 L 90.676538,98.271996 L 121.15605,175.23276 L 169.16127,159.993 L 161.5414,136.37138 L 139.44375,143.22927 L 87.628587,12.929372 L 47.243238,12.929372 z " + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="path2255" /> +</svg> diff --git a/haunt/static/image/making-your-own-music-player-analog-vs-digital.png b/haunt/static/image/making-your-own-music-player-analog-vs-digital.png Binary files differnew file mode 100644 index 0000000..6841598 --- /dev/null +++ b/haunt/static/image/making-your-own-music-player-analog-vs-digital.png diff --git a/haunt/static/image/reverse-engineering-babbys-first-archive-format-basic-parsing.png b/haunt/static/image/reverse-engineering-babbys-first-archive-format-basic-parsing.png Binary files differnew file mode 100644 index 0000000..0513350 --- /dev/null +++ b/haunt/static/image/reverse-engineering-babbys-first-archive-format-basic-parsing.png diff --git a/haunt/static/image/reverse-engineering-babbys-first-archive-format-binary-dump.png b/haunt/static/image/reverse-engineering-babbys-first-archive-format-binary-dump.png Binary files differnew file mode 100644 index 0000000..0a8774c --- /dev/null +++ b/haunt/static/image/reverse-engineering-babbys-first-archive-format-binary-dump.png diff --git a/haunt/static/image/reverse-engineering-babbys-first-archive-format-catching-file-reads.png b/haunt/static/image/reverse-engineering-babbys-first-archive-format-catching-file-reads.png Binary files differnew file mode 100644 index 0000000..2ce8f62 --- /dev/null +++ b/haunt/static/image/reverse-engineering-babbys-first-archive-format-catching-file-reads.png diff --git a/haunt/static/image/reverse-engineering-babbys-first-archive-format-xp3-header.png b/haunt/static/image/reverse-engineering-babbys-first-archive-format-xp3-header.png Binary files differnew file mode 100644 index 0000000..0fac996 --- /dev/null +++ b/haunt/static/image/reverse-engineering-babbys-first-archive-format-xp3-header.png diff --git a/haunt/static/image/sdl-tutorial-part-0x00-finished-window.png b/haunt/static/image/sdl-tutorial-part-0x00-finished-window.png Binary files differnew file mode 100644 index 0000000..4e9a146 --- /dev/null +++ b/haunt/static/image/sdl-tutorial-part-0x00-finished-window.png diff --git a/haunt/static/image/sdl-tutorial-part-0x00-window.png b/haunt/static/image/sdl-tutorial-part-0x00-window.png Binary files differnew file mode 100644 index 0000000..0bbe5fc --- /dev/null +++ b/haunt/static/image/sdl-tutorial-part-0x00-window.png |