Add RSS support to the build doc

Cette révision appartient à :
Sameer Rahmani 2022-08-29 15:46:09 +01:00
Parent 8415ab2e9b
révision cb32a5873e
5 fichiers modifiés avec 159 ajouts et 47 suppressions

Voir le fichier

@ -62,6 +62,17 @@ main docs.")
(defvar fg42/build-output-dir "/build"
"The path to the build directory.")
(defvar fg42/build-docs-title "FG42"
"Title of the generated docs. Like the website title")
(defvar fg42/build-docs-desc "The ultimate editor for true believers"
"Description of the generated docs. Like the website description")
(defvar fg42/build-usage "./builder.el SUBCOMMAND"
"Title of the generated docs. Like the website title")
(defmacro defproject (prject-name &rest details)
"Create a project with the given DETAILS.
@ -111,6 +122,10 @@ The build system will consum these details for various purposes."
(t (print-help ,command-var))))))
(defun print-help (_)
"Print out the usage for the build script"
(message fg42/build-usage))
(defun from-root (path)
"Return the full path of the given PATH in the project root."
(concat fg42/build-project-root path))

Voir le fichier

@ -30,15 +30,14 @@
(fpkg/use mustache)
(fpkg/use ht)
(fpkg/use htmlize)
(fpkg/use ox-rss)
(require 'ox-html)
(require 'ox-rss)
(require 'cubes/all)
(require 'fg42/build/core)
(require 'fg42/build/utils)
(require 'fg42/build/ox-template)
(require 'fg42/build/rss)
(defvar cube-template (from-root "/docs/site/templates/cube.org"))
(defvar cubes-index-template (from-root "/docs/site/templates/cubes.org"))
@ -142,7 +141,24 @@ Not pages."
(->epoch (get-file-global-props file "DATE"))
(get-file-global-props file "TITLE")
(replace-regexp-in-string "\\.org" ".html"
(file-name-nondirectory file)))
(file-name-nondirectory file))
(list file (fg42/exctract-keywords file '("TITLE" "DATE" "DESC" "AUTHOR" "CATEGORY"))))
result)
result)))
files
'())))
(defun get-all-posts-files ()
"Return all the post org files.
Not pages."
(let ((files (all-org-files)))
(seq-reduce
(lambda (result file)
(let ((is-page? (string= (get-file-global-props file "PAGE") "true")))
(if (not is-page?)
;; It's a post
(cons
file
result)
result)))
files
@ -174,26 +190,6 @@ Not pages."
"\n")))
(defun latest-org-list-rss (base-url)
"Return a list of headlines (using BASE-URL) for the RSS."
(let ((posts (get-all-sorted-posts)))
(mapconcat
(lambda (post)
(format "* %s\n:PROPERTIES:\n:RSS_PERMALINK:%s%s/%s?%s\n:END:"
;; Title
(nth 1 post)
base-url
fg42/build-docs-pages-dir
;; Path
(nth 2 post)
;; Hash
(car post)
;; Title
(nth 1 post)))
posts
"\n")))
(defun get-all-categories ()
"Return all the categories of the org files."
(seq-reduce
@ -201,22 +197,22 @@ Not pages."
(lambda (all-cats file)
(if (not (member (file-relative-name file org-directory)
fg42/build-docs-ignore-category-check))
(let ((is-page? (string= (get-file-global-props file "PAGE") "true"))
(cat (get-file-global-props file "CATEGORY"))
(cat-list (car all-cats))
(cat->file (cdr all-cats)))
(let ((is-page? (string= (get-file-global-props file "PAGE") "true"))
(cat (get-file-global-props file "CATEGORY"))
(cat-list (car all-cats))
(cat->file (cdr all-cats)))
(if (not is-page?)
(cons
;; Category list
(if (member cat cat-list) cat-list (sort (cons cat cat-list) 'string<))
;; cat->file
(cons (cons cat
;; Current value of the the given cat (all the files
;; under that category)
(append (list file) (cdr (assoc cat cat->file))))
cat->file))
all-cats))
(if (not is-page?)
(cons
;; Category list
(if (member cat cat-list) cat-list (sort (cons cat cat-list) 'string<))
;; cat->file
(cons (cons cat
;; Current value of the the given cat (all the files
;; under that category)
(append (list file) (cdr (assoc cat cat->file))))
cat->file))
all-cats))
all-cats))
(all-org-files)
'()))
@ -366,12 +362,6 @@ Not pages."
(expand-file-name "site/tags/index.org" build-dir)
`((:links . ,(tags-org-list))))
(message "Creating the rss feed")
(copy-template (from-docs "/templates/rss.org")
(expand-file-name "site/rss.org" build-dir)
`((:base-url . ,base-url)
(:posts . ,(latest-org-list-rss base-url))))
(create-tag-pages build-dir)
(setq org-html-preamble #'preamble-fn)
@ -407,7 +397,7 @@ Not pages."
:htmlized-source nil
:sitemap-folders ignore
:sitemap-style list
:sitemap-title "FG42, The ultimate editor for true believers"
:sitemap-title ,fg42/build-docs-title
:sitemap-filename "sitemap.inc"
:sitemap-sort-files anti-chronologically
:html-format-headline-function headline-format
@ -422,6 +412,7 @@ Not pages."
:rss-extension "xml"
:publishing-directory ,final-dir
:publishing-function (org-rss-publish-to-rss)
:org-rss-use-entry-url-as-guid t
:section-numbers nil
:exclude ".*" ;; To exclude all files...
:include ("rss.org") ;; ... except index.org.
@ -433,9 +424,10 @@ Not pages."
:publishing-directory ,final-dir
:recursive t
:publishing-function org-publish-attachment)
("build" :components ("website" "statics" "rss"))))
("build" :components ("website" "statics"))))
(org-publish-project "build" t nil)
(fg42/rss-create (get-all-sorted-posts) base-url (expand-file-name "rss.xml" final-dir))
(message "Build complete.")))
(provide 'fg42/build/docs)

93
core/fg42/build/rss.el Fichier normal
Voir le fichier

@ -0,0 +1,93 @@
;;; Buid --- The builder for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.0.0
;;
;; 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 thnis program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;; Cubes are the building blocks of any `FG42' editor. Each `cube' is a
;; unit which defines different abilities in a deterministic and idempotent
;; way. Cubes are composable and a composition of cubes creates an editor.
;;
;;; Code:
(require 'seq)
(require 'fg42/build/core)
(defun fg42/rss-map-items (file-and-props link)
"Create a RSS item from the given org FILE with the give http LINK"
(let* ((file (car file-and-props))
(values (cadr file-and-props)))
(format
(concat
" <item>\n"
" <title>%s</title>\n"
" <link>%s</link>\n"
" <author>%s</author>\n"
" <guid isPermaLink=\"false\">%s</guid>\n"
" <pubDate>%s</pubDate>\n"
" <description><![CDATA[%s]]></description>\n"
" </item>\n")
(cadr (assoc "TITLE" values))
link
(or
(cadr (assoc "AUTHOR" values))
fg42/build-author-name)
link
(or
(cadr (assoc "DATE" values))
(error "'DATE' is missing from '%s'" file))
(or
(cadr (assoc "DESC" values))
(error "'DESC' is missing from '%s'" file)))))
(defun fg42/rss-create-item (post base-url)
(fg42/rss-map-items
(car (last post))
(format "%s%s/%s"
base-url
fg42/build-docs-pages-dir
;; Path
(nth 2 post))))
(defun fg42/rss-create (posts base-url dest)
"Create a RSS xml file via POSTS for the give BASE-URL and save to DEST"
(with-temp-file dest
(insert
(format
(concat
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
"<rss version=\"2.0\">\n"
"<channel>\n"
" <title>%s</title>\n"
" <link>%s</link>\n"
" <description>%s</description>\n"
"%s\n"
"</channel>\n"
"</rss>\n")
fg42/build-docs-title
base-url
fg42/build-docs-desc
(mapconcat
(lambda (post)
(fg42/rss-create-item post base-url))
posts)))))
(provide 'fg42/build/rss)
;;; docs.el ends here

Voir le fichier

@ -60,6 +60,18 @@
(get-buffer-global-props prop)))
(defun fg42/exctract-keywords (file keys)
"Create a RSS item from the given org FILE"
(let ((cwd (getenv "PWD"))
(old-org-directory org-directory))
(cd fg42/build-project-root)
(prog1
(with-temp-buffer
(insert-file-contents file)
(org-collect-keywords keys))
(cd cwd))))
(defun pair-file-with-date (file)
"Return a pair for the given FILE with date as car and file as cdr."
(cons

Voir le fichier

@ -19,7 +19,7 @@
<header>
<nav style="text-align: center;">
<a href="/">HOME</a> | <a href="/cubes/">Cubes</a> | <a href="https://devheroes.codes/FG42/FG42">Source</a> | <a href="/categories/">Categories</a> | <a href="/tags/">Tags</a>
<a href="/">HOME</a> | <a href="/cubes/">Cubes</a> | <a href="https://devheroes.codes/FG42/FG42">Source</a> | <a href="/categories/">Categories</a> | <a href="/tags/">Tags</a> | <a href="/index.xml">RSS</a>
</nav>
<hr/>
</header>