diff options
author | Case Duckworth | 2023-08-24 12:42:22 -0500 |
---|---|---|
committer | Case Duckworth | 2023-08-24 12:42:22 -0500 |
commit | 76b7e6eeaf99e5aeac3d9f651bc548f2c537ce85 (patch) | |
tree | 6bef69a73a9ed2619ac2bfc0a5ee75cc8714a3f7 /lib/types.sls | |
parent | A new start (again) (diff) | |
download | boudin-76b7e6eeaf99e5aeac3d9f651bc548f2c537ce85.tar.gz boudin-76b7e6eeaf99e5aeac3d9f651bc548f2c537ce85.zip |
bleh again
Diffstat (limited to 'lib/types.sls')
-rw-r--r-- | lib/types.sls | 91 |
1 files changed, 88 insertions, 3 deletions
diff --git a/lib/types.sls b/lib/types.sls index 2b4da5d..3f6c07f 100644 --- a/lib/types.sls +++ b/lib/types.sls | |||
@@ -1,7 +1,9 @@ | |||
1 | ;;; (boudin types) --- pages, indeces, and static files | 1 | ;;; (boudin types) --- pages, indeces, and static files |
2 | 2 | ;; | |
3 | ;; All paths are relative to the site directory unless otherwise noted | 3 | ;; All paths are relative to the site directory unless otherwise noted |
4 | 4 | ||
5 | ;;; Pages | ||
6 | |||
5 | (define-record-type page | 7 | (define-record-type page |
6 | (make-page path ; Input path | 8 | (make-page path ; Input path |
7 | dest ; Output path (rel. to output directory) | 9 | dest ; Output path (rel. to output directory) |
@@ -17,14 +19,33 @@ | |||
17 | (meta page-meta set-page-meta!)) | 19 | (meta page-meta set-page-meta!)) |
18 | 20 | ||
19 | (define (page-ref pg key) | 21 | (define (page-ref pg key) |
20 | (assoc-ref key (page-meta pg) (identity #f))) | 22 | (assoc-ref key (page-meta pg) (lambda _ #f))) |
21 | 23 | ||
22 | (define (page-set! pg key val) | 24 | (define (page-set! pg key val) |
23 | (set-page-meta! pg (cons (cons key val) | 25 | (set-page-meta! pg (cons (cons key val) |
24 | (page-meta pg)))) | 26 | (page-meta pg)))) |
25 | 27 | ||
26 | (define (extract-metadata sxml) | 28 | (define (extract-metadata sxml) |
27 | #f) | 29 | (let loop ((tree sxml) |
30 | (acc '())) | ||
31 | (cond | ||
32 | ((not (pair? tree)) | ||
33 | (reverse acc)) | ||
34 | ((and (list? (car tree)) | ||
35 | (eq? (caar tree) '*COMMENT*)) | ||
36 | (loop (cdr tree) | ||
37 | (map (lambda (ln) | ||
38 | (let ((kv (string-split ln ":" 'infix 1))) | ||
39 | (cons (string-trim-both (car kv)) | ||
40 | (string-trim (cdr kv))))) | ||
41 | (string-split (cadar tree) "\n")))) | ||
42 | ((list? (car tree)) | ||
43 | (loop (cdr tree) | ||
44 | (let ((subtree (loop (car tree) '()))) | ||
45 | (if (null? subtree) | ||
46 | acc | ||
47 | (cons subtree acc))))) | ||
48 | (else (loop (cdr tree) acc))))) | ||
28 | 49 | ||
29 | (define (*urlify path) | 50 | (define (*urlify path) |
30 | (normalize-pathname | 51 | (normalize-pathname |
@@ -53,6 +74,20 @@ | |||
53 | (page-set! pg "slug" slug) | 74 | (page-set! pg "slug" slug) |
54 | slug))) | 75 | slug))) |
55 | 76 | ||
77 | (define (*page-mtime pg) | ||
78 | (let ((file (page-path pg))) | ||
79 | (and file | ||
80 | (file-exists? file) | ||
81 | (time->string (seconds->utc-time (file-modification-time file)))))) | ||
82 | |||
83 | (define (page-updated pg) | ||
84 | (let ((meta-date (page-ref pg "date"))) | ||
85 | (or (and meta-date | ||
86 | (find (lambda (fmt) (string->time meta-date fmt)) | ||
87 | (page-date-formats))) | ||
88 | (*page-mtime pg) | ||
89 | (build-time)))) | ||
90 | |||
56 | (define (read-page path) | 91 | (define (read-page path) |
57 | (let ((pg (make-page path #f #f #f #f))) | 92 | (let ((pg (make-page path #f #f #f #f))) |
58 | (set-page-dest! pg ((apply o (page-path-transformers)) path)) | 93 | (set-page-dest! pg ((apply o (page-path-transformers)) path)) |
@@ -69,4 +104,54 @@ | |||
69 | (sxml-display-as-html ((eval/q (page-template)) pg) port)))) | 104 | (sxml-display-as-html ((eval/q (page-template)) pg) port)))) |
70 | 105 | ||
71 | 106 | ||
107 | ;;; Indeces | ||
108 | ;; These are generated pages from collections of other pages. Think index.html, | ||
109 | ;; feed.xml, possibly tag indeces and the like. These pages don't have a source | ||
110 | ;; file, but they have a destination and a template. Because there are | ||
111 | ;; different file formats here and ... stuff, there's also a slot for the index | ||
112 | ;; writer function. Finally, pages and meta are the pages and various other | ||
113 | ;; metadata of the index. | ||
114 | |||
115 | (define-record-type index | ||
116 | (make-index dest ; Relative to (site-dest) | ||
117 | template ; Template to put pages in | ||
118 | writer ; Proc to write sxml out to a file | ||
119 | pages ; Input pages | ||
120 | meta ; Various other metadata | ||
121 | ) | ||
122 | index? | ||
123 | (dest index-dest set-index-dest!) | ||
124 | (template index-template set-index-template!) | ||
125 | (writer index-writer set-index-writer!) | ||
126 | (pages index-pages set-index-pages!) | ||
127 | (meta index-meta set-index-meta!)) | ||
128 | |||
129 | (define (index-ref idx key) | ||
130 | (assoc-ref key (index-meta idx) (lambda _ #f))) | ||
131 | |||
132 | (define (index-set! idx key val) | ||
133 | (set-index-meta! idx (cons (cons key val) | ||
134 | (index-meta idx)))) | ||
135 | |||
136 | (define (index-push! idx pg) | ||
137 | (set-index-pages! idx (cons pg (index-pages idx)))) | ||
138 | |||
139 | (define (index-for-each idx proc) | ||
140 | (for-each proc (index-pages idx))) | ||
141 | |||
142 | (define write-index | ||
143 | (case-lambda | ||
144 | ((idx) (call-with-output-file (index-dest idx) | ||
145 | (lambda (port) (write-index idx (current-output-port))))) | ||
146 | ((idx port) | ||
147 | ((index-writer idx) ((index-template idx) (index-pages idx)) port)))) | ||
148 | |||
149 | |||
150 | ;;; Static files | ||
151 | ;; These are simply copied from the input to the output, possibly with a changed | ||
152 | ;; path. Because these are just files, we don't need a record type. | ||
72 | 153 | ||
154 | (define (static-copy path) | ||
155 | (copy-file path | ||
156 | (make-pathname (site-dest) path) | ||
157 | 'clobber)) | ||