gdritter repos when-computer / a71ca6b
Added feed generation Getty Ritter 9 years ago
5 changed file(s) with 71 addition(s) and 52 deletion(s). Collapse all Expand all
33
44 Number one: I want to force myself to write on a regular
55 basis, mostly regardless of content. It's striking to me that I am
6 ver used to \em{writing}—I probably write a novel's worth on various
6 very used to \em{writing}—I probably write a novel's worth on various
77 chat services every week or so—but when I start to do long-form
88 writing, I tend to waffle and get bogged down in little details
99 and then give up.\ref{blog}
77 ${GEN} tags
88 ${GEN} archive
99 ${GEN} post posts/*
10 ${GEN} feed
2020 (define (outfile chunks)
2121 (define (go rest so-far)
2222 (ensure-folder so-far)
23 (if (null? rest)
24 (++ so-far "/index.html")
25 (go (cdr rest)
26 (++ so-far "/" (as-string (car rest))))))
23 (match rest
24 (() (++ so-far "/index.html"))
25 ((x . xs) (go xs (++ so-far "/" (as-string x))))))
2726 (go chunks "output"))
2827
2928 ;; create a URL from a set of path components
3029 (define (url chunks)
3130 (define (go rest so-far)
3231 (match rest
33 (() so-far)
32 (() (++ so-far "/"))
3433 ((x . xs) (go xs (++ so-far "/" (as-string x))))))
35 (go chunks "/"))
34 (go chunks ""))
3635
3736 ;; Grab all the posts and their metadata from the posts folder,
3837 ;; sorted by creation time. This does unnecessary work right
4544 (stat:mtime (cadr y)))))))
4645 (map (lambda (file-entry)
4746 (let* ((filename (string-append "posts/" (car file-entry)))
48 (metadata (telml-meta (translate-file filename))))
47 (telml (translate-file filename))
48 (metadata (telml-meta telml)))
4949 (make-post filename
5050 (localtime (stat:mtime (cadr file-entry)))
5151 (meta-slug metadata)
5252 (meta-title metadata)
53 (meta-tags metadata))))
53 (meta-tags metadata)
54 (telml-content telml))))
5455 files-sorted)))
5556
5657 ;; Turn a post into an <li> element with appropriate
7576 ,(map post->list-elem posts)))))
7677 (with-output-to-file (outfile '(archive))
7778 (lambda ()
78 (display (sxml->html5 (page "archive" list)))))))
79 (display (sxml->html5 (page (url '(archive)) "archive" list)))))))
7980
8081 ;; Flatten a list
8182 (define (concat list)
108109 ,(map post->list-elem ps)))))
109110 (with-output-to-file (outfile (list 'tag tag))
110111 (lambda ()
111 (display (sxml->html5 (page tag content)))))))
112 (display (sxml->html5 (page (url (list 'tag tag))
113 tag
114 content)))))))
112115
113116 (with-output-to-file (outfile '(tags))
114117 (lambda ()
115 (display (sxml->html5 (page "tags" tag-list)))))
118 (display (sxml->html5 (page (url '(tags))
119 "tags"
120 tag-list)))))
116121
117122 (map mk-tag-page tags)))
123
124 (define (feed)
125 (let ((posts (get-all-posts)))
126 (with-output-to-file "output/feed.xml"
127 (lambda ()
128 (display (serialize-sxml (atom-feed posts)))))))
118129
119130 ;; Load a telml page and turn it into an html page
120131 (define (main pg file out)
124135 (date (localtime (stat:mtime (stat file))))
125136 (ndate (date->string date))
126137 (title (if meta (meta-title meta) pg))
127 (target (if out out
128 (outfile (list ndate (meta-slug meta)))))
129 (display (sxml->html5 (page title (add-tags telml (meta-tags meta))))))
138 (target (outfile (if out out
139 (list ndate (meta-slug meta)))))
140 (url (url (if out out
141 (list ndate (meta-slug meta)))))
142 (display (sxml->html5 (page url
143 title
144 (add-tags telml (meta-tags meta))))))
130145 (format #t "printing to ~a\n" target)
131146 (with-output-to-file target
132147 (lambda () (format #t "~a\n" display)))))
134149 ;; Figure out which page is supposed to be generated
135150 (define (dispatch pg files)
136151 (match pg
137 ("index" (main "index" (car files) (outfile '())))
152 ("index" (main "index" (car files) '()))
138153 ("post" (map (lambda (f) (main "post" f #f)) files))
139154 ("archive" (archive))
140155 ("tags" (tags))
141 ("about" (main "about" "pages/about.telml" (outfile '(about))))))
156 ("about" (main "about" "pages/about.telml" '(about)))
157 ("feed" (feed))))
142158
143159 (let ((args (cdr (command-line))))
144160 (cond ((= (length args) 0)
44 (define (date->string date)
55 (strftime "%Y-%m-%d" date))
66
7 (define (date->tz date)
8 (strftime "%Y-%m-%dT%TZ" date))
9
710 (define (post-url post)
811 (let ((date (date->string (post-time post)))
912 (slug (post-slug post)))
1013 (format #f "/~a/~a/" date slug)))
1114
12 (define (atom-element post content)
13 (let ((url (post-url post)))
15 (define (atom-element post)
16 (let ((url (++ "http://what.happens.when.computer" (post-url post))))
1417 `(entry
15 (title ,(post-title))
18 (title ,(post-title post))
1619 (link (@ (href ,url)))
1720 (id ,url)
18 (updated ,(post-date post))
21 (updated ,(date->tz (post-time post)))
1922 (content (@ (type "html"))
20 ,content))))
21
22 (define (atom-element title url date content)
23 `(entry
24 (title ,title)
25 (link (@ (href ,url)))
26 (id ,url)
27 (updated ,date)
28 (content (@ (type "html"))
29 ,content)))
23 ,(post-content post)))))
3024
3125 (define (atom-feed posts)
32 `(feed (@ (xmlns "htpt://www.w3.org/2005/Atom"))
33 (title "what happens when computer")
34 (link (@ (href "http://what.happens.when.computer/feed/")
35 (rel "self")))
36 (link (@ (href "http://what.happens.when.computer/")))
37 (id "http://what.happens.when.computer/")
38 ,(map (lambda (post) (apply atom-element post)) posts)))
26 (let ((updated (date->tz (post-time (car posts)))))
27 `(feed (@ (xmlns "htpt://www.w3.org/2005/Atom"))
28 (title "what happens when computer")
29 (link (@ (href "http://what.happens.when.computer/feed.xml")
30 (rel "self")))
31 (link (@ (href "http://what.happens.when.computer/")))
32 (updated ,updated)
33 (id "http://what.happens.when.computer/")
34 ,(map (lambda (post) (atom-element post)) posts))))
3935
36 ;; the scss stylesheet
4037 (define stylesheet
4138 '((body
4239 (font-family "Palatino, \"Palatino Linotype\", \"Palatino LT STD\", \"Book Antiqua\", Georgia, serif")
145142 ,(menu-item "about" "/about/"))))
146143
147144 ;; The SXML chunk representing a page on the site
148 (define (page title content)
145 (define (page url title content)
149146 `(html
150147 (head
151148 (meta (@ (http-equiv "Content-Type")
152149 (content "application/xhtml+xml; charset=utf-8;")))
150 (meta (@ (property "og:title")
151 (content ,(++ "what happens when computer: " title))))
152 (meta (@ (property "og:url")
153 (content ,(++ "http://what.happens.when.computer" url))))
154 (meta (@ (property "og:type")
155 (content "website")))
156 (link (@ (href "/feed.xml")
157 (type "application/atom+xml")
158 (rel "alternate")
159 (title "what happens when computer atom feed")))
153160 (style (@ (type "text/css")) ,(scss->css stylesheet))
154161 (script (@ (type "text/javascript")
155162 (src "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML")) "")
161168 (div (@ (class "main")) ,content)
162169 (div (@ (class "footer")) "&copy; 2015 getty ritter"))))
163170
171 ;; if a page has tags, add those tags to the end of the page
164172 (define (add-tags chunk tags)
165173 (define (tag->link tag)
166174 `(a (@ (href ,(format #f "/tag/~a/" tag))
11 (use-modules (srfi srfi-9))
22
3 (define-record-type <meta>
4 (make-meta slug title tags)
5 meta?
6 (slug meta-slug)
7 (title meta-title)
8 (tags meta-tags))
9
103 (define-record-type <post>
11 (make-post file time slug title tags)
4 (make-post file time slug title tags content)
125 post?
13 (file post-file)
14 (time post-time)
15 (slug post-slug)
16 (title post-title)
17 (tags post-tags))
6 (file post-file)
7 (time post-time)
8 (slug post-slug)
9 (title post-title)
10 (tags post-tags)
11 (content post-content))