summaryrefslogtreecommitdiff
path: root/haunt/jakob/builder/atom.scm
blob: 88523722eb9226aedc7b2ecd1cbefc9320cc9666 (plain)
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*)))))