grug

A static website generator written for Guile Scheme
Log | Files | Refs | README | LICENSE

commit e17d1e847a955dbfce44d4cee8621d222974bfc6
parent 55d561f5c11fe91ca0aacc27755dcdabdf70f29e
Author: Luke Willis <lukejw@loquat.dev>
Date:   Sat,  5 Jul 2025 00:05:57 -0400

Make builders reader-agnostic and add date metadata to example

Diffstat:
Mexample/posts/hello-world.md | 2+-
Mexample/posts/update-situation.md | 2+-
Mgrug/builders.scm | 23+++++++++++++++++------
Mgrug/utils.scm | 9++++++++-
4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/example/posts/hello-world.md b/example/posts/hello-world.md @@ -1,2 +1,2 @@ -`((title . "Hello, world!") (description . "You'll never guess what this post says")) +`((title . "Hello, world!") (date . "2025-07-04") (description . "You'll never guess what this post says")) This is a test post. diff --git a/example/posts/update-situation.md b/example/posts/update-situation.md @@ -1,2 +1,2 @@ -`((title . "Update Situation") (description . "In this post, I talk about another update.")) +`((title . "Update Situation") (date . "2025-07-06") (description . "In this post, I talk about another update.")) Boys, we did it. There's another situation. diff --git a/grug/builders.scm b/grug/builders.scm @@ -1,6 +1,7 @@ (define-module (grug builders) #:use-module (ice-9 pretty-print) #:use-module (ice-9 receive) + #:use-module (srfi srfi-19) #:use-module (htmlprag) #:use-module (grug utils) #:use-module (grug readers) @@ -40,10 +41,10 @@ ;; Build the pages in the given directory and copy them to the site. ;; This is good for things like 'About' or 'Contact' pages. -;; TODO: Don't assume a markdown reader (define* (simple-pages directory #:key (prefix "site") + (reader cmark) (template basic-template)) (display "simple-pages\n") @@ -56,13 +57,13 @@ (string-length directory)))) (output-path (string-append output-dir "/" - (basename path ".md") + (strip-extension path) ".html"))) (unless (file-exists? output-dir) (mkdir output-dir)) (format #t "\t~A -> ~A\n" path output-path) (receive (metadata contents) (load-string-with-metadata path) - (let* ((base-shtml (cmark contents)) + (let* ((base-shtml (reader contents)) (built-shtml (template base-shtml metadata)) (output (shtml->html built-shtml))) (write-string-to-path output output-path))))) @@ -70,10 +71,21 @@ ;; `posts` should be a list of a-lists containing post metadata (define (basic-collection-template posts) + ;; Sort posts by date (should be string in ISO 8601 format) + (sort posts + (lambda (a b) + (string>? (assoc-ref a 'date) + (assoc-ref b 'date)))) + ;; Return shtml for all the posts posts `((h1 "Posts") ,@(map (lambda (post) `(article (h2 (a (@ (href ,(assoc-ref post 'uri))) ,(assoc-ref post 'title))) + ;; Parse ISO 8601 date from 'date and reformat it to look nice + (h3 ,(date->string + (string->date (assoc-ref post 'date) + "~Y~m~d") + "~B ~d, ~Y")) (p ,(assoc-ref post 'description)))) posts))) @@ -81,13 +93,12 @@ ;; ;; Builds prefix/index.html and posts in prefix/post-prefix/. ;; Posts have 'uri added to their metadata. -;; -;; TODO: Don't assume a markdown reader (define* (blog directory #:key (prefix "site") (post-prefix "posts") (metadata `((title . "Recent Posts"))) + (reader cmark) (template basic-template) (collection-template basic-collection-template)) (display "blog\n") @@ -95,7 +106,7 @@ (let ((posts (map (lambda (path) (let* ((output-name - (string-append (basename path ".md") + (string-append (strip-extension path) ".html")) (relative-output-dir (string-append post-prefix diff --git a/grug/utils.scm b/grug/utils.scm @@ -5,10 +5,17 @@ #:use-module (ice-9 ftw) #:use-module (ice-9 rdelim) #:use-module (ice-9 textual-ports) - #:export (ls-recursive + #:export (strip-extension + ls-recursive load-string-with-metadata write-string-to-path)) +;; Essentially basename but automatically removes any extension +(define (strip-extension filename) + (let* ((a (basename filename)) + (b (string-index a #\.))) + (substring a 0 b))) + ;; Return a list of file paths by recursively searching a given directory. ;; This is basically like running `ls -aR`. (define (ls-recursive directory)