1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
;;; Copyright © 2019 - 2023 Jakob L. Kreuze <zerodaysfordays@sdf.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 atom)
#:use-module (haunt html)
#:use-module (haunt page)
#:use-module (haunt post)
#:use-module (haunt site)
#:use-module (haunt utils)
#:use-module (ice-9 match)
#:use-module (jakob builder blog)
#:use-module (jakob utils)
#:use-module (jakob utils sxml)
#:use-module (srfi srfi-19)
#:use-module (srfi srfi-26)
#:use-module (web uri)
#:export (atom-feed))
(define* (post->atom-entry site post #:key (blog-prefix ""))
"Convert POST into an Atom <entry> XML node."
(let ((uri (or (post-ref post 'crosspost)
(post-uri post))))
`(entry
(title ,(post-ref post 'title))
(id ,uri)
(author
(name ,(post-ref post 'author))
,(let ((email (post-ref post 'email)))
(if email `(email ,email) '())))
(updated ,(date->string (post-date post) "~4"))
(link (@ (href ,uri) (rel "alternate")))
(summary (@ (type "html"))
,(sxml->html-string
(append (first-paragraph post)
(if (post-ref post 'crosspost)
`((p "...")
(p "This is a crosspost. Click "
,(hyperlink (post-ref post 'crosspost) "here")
" to read the rest of the article."))
'()))))
,@(map (lambda (enclosure)
`(link (@ (rel "enclosure")
(title ,(enclosure-title enclosure))
(href ,(enclosure-url enclosure))
(type ,(enclosure-mime-type enclosure))
,@(map (match-lambda
((key . value)
(list key value)))
(enclosure-extra enclosure)))))
(post-ref-all post 'enclosure)))))
(define* (atom-feed #:key
(file-name "feed.xml")
(subtitle "Recent Posts")
(filter posts/reverse-chronological)
(max-entries 20)
(blog-prefix ""))
"Minor modification to the 'atom-feed' builder in '(haunt builder atom)' to
add support for cross-posts. See the docstring in that manual for details on the
use of this function."
(lambda (site posts)
(let ((uri (uri->string
(build-uri 'http ;; (site-scheme site)
#:host (site-domain site)
#:path (string-append "/" file-name)))))
(make-page file-name
`(feed (@ (xmlns "http://www.w3.org/2005/Atom"))
(title ,(site-title site))
(id ,uri)
(subtitle ,subtitle)
(updated ,(date->string (current-date) "~4"))
(link (@ (href ,(string-append (site-domain site)
"/" file-name))
(rel "self")))
(link (@ (href ,(site-domain site))))
,@(map (cut post->atom-entry site <>
#:blog-prefix blog-prefix)
(take-up-to max-entries (filter posts))))
(@@ (haunt builder atom) sxml->xml*)))))
|