~aasg/haunted-blog

2d7c9c93f974e3b1352b41a85918a5327de6e632 — Aluísio Augusto Silva Gonçalves 1 year, 2 months ago 025c92a
Switch to JSON front matter

This makes the front matter compatible with Pandoc (as YAML is defined
as a superset of JSON).
6 files changed, 59 insertions(+), 23 deletions(-)

M channels.nix
M default.nix
M haunt.scm
M pages/about-site.md
M posts/hello-world.md
A scm/aasg/front-matter/json.scm
M channels.nix => channels.nix +5 -5
@@ 1,17 1,17 @@
let
  bumpDate = "2020-06-19";
  bumpDate = "2020-07-08";
  repos = {
    nixpkgs = rec {
      pname = "nixpkgs-unstable";
      url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
      rev = "1357624fa9edff4add4c535c0606eb673f29966f";
      sha256 = "sha256-FajXbwlvYLhvUQTT4JQUAl5kovL7+wOnAuW+xPuB/10=";
      rev = "4855aa62fa13052fb1a3daea68971503ab07a744";
      sha256 = "sha256-UieMyToFPe0JKdJrWddrESe5i88hdBH4/ycNjokRU58=";
    };
    aasg = rec {
      pname = "aasg-nixexprs";
      url = "https://git.sr.ht/~aasg/nixexprs/archive/${rev}.tar.gz";
      rev = "ea6c36a7d11b4e73353b59b784280e370a697dad";
      sha256 = "sha256-A1sZ13fYb6KguEtK9EaDEli9xAAC9zHOEDCBAXqNsYU=";
      rev = "cd09ce0cd17f5875dbc7bcd47c815dbc84509173";
      sha256 = "sha256-G17/q+s0QAVlk+7Ry7Q3W+A6JmMuxDeLQ4E2K4ZFT4I=";
    };
  };
in

M default.nix => default.nix +2 -0
@@ 19,6 19,8 @@ let
    {
      nativeBuildInputs = [ aasg-pkgs.haunt pkgs.pandoc ];
      LANG = "C.UTF-8";
      GUILE_LOAD_PATH = "${aasg-pkgs.guile-json}/share/guile/site";
      GUILE_COMPILED_LOAD_PATH = "${aasg-pkgs.guile-json}/share/guile/site/site-ccache";
    } ''
    cd ${src}
    export HAUNT_DESTDIR=$out

M haunt.scm => haunt.scm +29 -12
@@ 4,7 4,8 @@
;+ Imports

(add-to-load-path (string-append (dirname (current-filename)) "/scm"))
(use-modules (aasg sxml from-pandoc)
(use-modules (aasg front-matter json)
             (aasg sxml from-pandoc)
             (aasg sxml reparse-extended-markdown)
             (aasg sxml toc)
             (haunt asset)


@@ 219,17 220,33 @@
                    ((new-tree) (reparse-markdown-sxml orig-tree)))
        (values metadata new-tree)))))

(define pandoc-reader
  (let ((read-yaml-preamble (lambda (filename)
                              (call-with-input-file filename (lambda (port)
                                                               (let ((header (read-line port 'concat)))
                                                                 (unless (string=? header "---\n")
                                                                   (unread-string header port)))
                                                               (read-metadata-headers port))))))
    (make-reader
      (make-file-extension-matcher "md")
      (lambda (filename)
        (values (read-yaml-preamble filename) (pandoc-md->sxml filename))))))
(define (make-pandoc-reader)
  (define (parse-date datestring)
    (let loop ((formats '("~Y-~m-~dT~H:~M:~S~z"
                          "~Y-~m-~d ~H:~M:~S"
                          "~Y-~m-~d")))
      (when (null? formats)
        (error "couldn't parse date string: " datestring))
      (catch 'misc-error
             (lambda () (string->date datestring (car formats)))
             (lambda (key caller msg args rest) (loop (cdr formats))))))
  (define (read-front-matter filename)
    (map (lambda (kv)
           (let ((key (string->symbol (car kv)))
                 (value (cdr kv)))
             (cond
               ((eq? 'date key)
                (cons key (parse-date value)))
               ((vector? value)
                (cons key (vector->list value)))
               (else
                 (cons key value)))))
         (call-with-input-file filename read-json-front-matter)))
  (make-reader
    (make-file-extension-matcher "md")
    (lambda (filename)
      (values (read-front-matter filename) (pandoc-md->sxml filename)))))
(define pandoc-reader (make-pandoc-reader))

; Wrap a Haunt reader so that its output includes a table of contents.
(define (with-toc reader)

M pages/about-site.md => pages/about-site.md +2 -2
@@ 1,6 1,6 @@
---
title: About this site
---
{"title": "About this site"}
...

As the site title says, this is Aluísio's highly experimental blog, currently generated by [Haunt], styled with [Classless.css], built with [Nix], and published through [IPFS].
[sourcehut] provides [automated builds] and also hosts the [source code].

M posts/hello-world.md => posts/hello-world.md +4 -4
@@ 1,8 1,8 @@
---
title: (hello "world"); or: an incredible journey
date: 2020-06-14 22:00
toc: true
---
{"title": "(hello \"world\"); or: an incredible journey"
,"date": "2020-06-14 22:00"
,"toc": true}
...

I spent most of last week getting this blog up and running.
Inspired by [Deploying This Site with IPFS and Scheme][elais-blog] I set out (for the nth time) to create someplace I could eventually publish my writings on (and incidentally serve as a hub for my web presence).

A scm/aasg/front-matter/json.scm => scm/aasg/front-matter/json.scm +17 -0
@@ 0,0 1,17 @@
(define-module (aasg front-matter json)
               #:use-module (ice-9 rdelim)
               #:use-module (json)
               #:export (read-json-front-matter))

(define (read-json-front-matter port)
  (if (string=? "---" (read-line port))
      (let loop ((lines '()))
        (let ((line (read-line port)))
          (cond
            ((eof-object? line)
             (error "EOF while reading metadata"))
            ((or (string=? "---" line) (string=? "..." line))
                (json-string->scm (string-join (reverse lines) "\n")))
            (else
              (loop (cons line lines))))))
      '()))