new-ryuslash.org/publish.el

181 lines
7 KiB
EmacsLisp
Raw Normal View History

;;; publish.el --- Publishing configuration for ryuslash.org -*- lexical-binding: t; -*-
;; Copyright (C) 2020 Tom Willemse
;; Author: Tom Willemse <tom@ryuslash.org>
;; Keywords:
2022-03-20 09:13:28 +01:00
;; Version: 1
;; Package-Requires: (dockerfile-mode htmlize org org-contrib rainbow-delimiters ox-rss)
;; 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 <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(require 'dockerfile-mode)
2020-09-10 10:34:32 +02:00
(require 'ob-dot)
(require 'ox-publish)
(require 'ox-rss)
2020-03-20 07:16:08 +01:00
(require 'rainbow-delimiters)
2020-09-10 10:34:32 +02:00
(require 'subr-x)
2020-03-20 07:16:08 +01:00
(defconst publish-root
(file-name-directory
(or load-file-name
(buffer-file-name)))
"The directory where oni-org was loaded from.")
2020-03-20 07:16:08 +01:00
(add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
(defun publish-calculate-reading-time (buffer)
"Calculate the amount of minutes it would take to read the contents of BUFFER."
(with-current-buffer buffer
(max 1 (/ (count-words (point-min) (point-max)) 228))))
(defun publish-format-reading-time (time)
"Return a string describing TIME."
(format "%d minute%s"
time
(if (= time 1) "" "s")))
(defun publish-extract-summary-from-file (file props)
"Extract a summary from FILE.
PROPS is used as an aid in getting the right information from the file."
(format "* %s\n:PROPERTIES:\n:CUSTOM_ID: %s\n:PUBDATE: %s\n:RSS_PERMALINK: %s\n:END:\n\n%s\n\n[[file:%s][Read More]]\n\n"
(car (org-publish-find-property file :title props))
(file-name-nondirectory file)
(format-time-string "[%Y-%m-%d %a %H:%M]" (org-timestamp-to-time (car (org-publish-find-property file :date props))))
(file-name-nondirectory file)
(car (org-map-entries (lambda () (let ((element-data (cadr (org-element-at-point))))
(buffer-substring-no-properties
(map-elt element-data :contents-begin)
(map-elt element-data :contents-end))))
"summary"
(list file)))
(file-name-nondirectory file)))
(defun publish-get-latest-modified-time (files)
"Get the latest modification time of any file from the list FILES."
(car
(last
(sort (mapcar #'org-publish-cache-mtime-of-src files) #'time-less-p))))
(defun publish-time>= (a b)
"Check if time A is greater than or equal to time B."
(not (time-less-p a b)))
(defun publish-empty-time ()
"Get an empty time value."
(let ((current-time (current-time)))
(time-subtract current-time current-time)))
(defun publish-generate-index (props)
"Generate an index from my posts.
Argument PROPS
."
(let* ((index-file (expand-file-name "posts/index.org"))
(index-generated-time (or (and (file-exists-p index-file)
(org-publish-cache-mtime-of-src index-file))
(publish-empty-time)))
(files (directory-files "posts/" t (rx bos (= 8 digit) "-" (= 4 digit) "-" (one-or-more nonl) (not "~") eos)))
(latest-modification-time (publish-get-latest-modified-time files)))
(if (publish-time>= index-generated-time latest-modification-time)
(message "Not generating index...")
(progn
(message "Generating index...")
(with-temp-buffer
(insert "#+title: ryuslash's blog\n")
(insert "#+options: num:nil\n")
(insert "\n")
(apply 'insert
(mapcar (lambda (file) (publish-extract-summary-from-file file props))
(take 30 (reverse files))))
(write-file "posts/index.org"))))))
(setq org-export-exclude-tags '("noexport" "draft"))
2020-09-10 10:34:32 +02:00
(setq org-confirm-babel-evaluate nil)
(setq org-html-head-include-default-style nil)
2020-09-10 10:34:32 +02:00
(setq org-html-htmlize-output-type 'css)
(setq org-publish-timestamp-directory
(concat default-directory "/.org-timestamps/"))
2020-10-11 03:04:47 +02:00
(setq org-html-html5-fancy t)
(setq org-html-doctype "html5")
(setq org-publish-project-alist
2020-11-23 00:42:12 +01:00
`(("index"
2020-09-10 10:34:32 +02:00
:base-directory "."
:base-extension "org"
:publishing-directory "public/"
:recursive t
2020-11-23 00:42:12 +01:00
:exclude ,(rx string-start
(or "posts/"
(and "README.org" string-end)))
:publishing-function org-html-publish-to-html
:html-head "<link rel=\"stylesheet\" href=\"/assets/css/main.css\" type=\"text/css\"/>"
:html-postamble t
2022-03-20 09:39:55 +01:00
:html-postamble-format (("en" "<p class=\"social social-mastodon\">Find me on <a href=\"https://fosstodon.org/@ryuslash\" rel=\"me\">Mastodon</a></p>
<p class=\"date\">Date: %C</p>
<p class=\"creator\">%c</p>")))
2020-09-10 10:34:32 +02:00
("posts"
:base-directory "posts/"
:base-extension "org"
:publishing-directory "public/posts/"
:recursive t
:publishing-function org-html-publish-to-html
:html-head "<link rel=\"stylesheet\" href=\"/assets/css/main.css\" type=\"text/css\"/>"
:html-preamble (lambda (project)
(let ((buffer (find-file-noselect (buffer-file-name))))
(unless (member (car (org-publish-find-property (buffer-file-name) :title project))
'("ryuslash.org" "ryuslash's blog"))
(publish-format-reading-time
2020-09-10 10:34:32 +02:00
(publish-calculate-reading-time buffer))))))
("rss"
:base-directory "posts/"
:base-extension "org"
:rss-extension "xml"
:preparation-function publish-generate-index
:publishing-directory "public/posts/"
:publishing-function (org-rss-publish-to-rss)
:html-link-home "https://ryuslash.org/posts/"
:html-link-use-abs-url t
:section-numbers nil
:exclude ".*"
:include ("index.org")
:table-of-contents nil)
2020-09-10 10:34:32 +02:00
("assets"
:base-directory "."
:recursive t
:exclude "^public/"
2023-07-26 22:37:32 +02:00
:base-extension "svg\\|png\\|jpg\\|ico"
2020-09-10 10:34:32 +02:00
:publishing-function org-publish-attachment
:publishing-directory "public/")
("all" :components ("index" "rss" "posts" "assets"))))
(defvar publish-feed-url-format
;"https://gitlab.com/ryuslash/ryuslash.org/-/commits/master/%s?feed_token=Rf8otgpS8YEiYakJN4NR&format=atom"
"https://code.ryuslash.org/new-ryuslash.org/atom/%s?h=master"
"Format string for the URL to the pages atom feed.")
(provide 'publish)
;;; publish.el ends here