Port the site to GNU Emacs + Org mode (using org-publish)
[~bandali/bndl.org] / publish.el
1 ;; Inspiration: https://gitlab.com/ambrevar/ambrevar.gitlab.io.
2
3 ;; TODO: use git time-stamps
4
5 (require 'ox-publish)
6 (require 'seq)
7
8 (add-to-list 'load-path ".")
9
10 (add-to-list 'load-path "../xah-replace-pairs")
11 (require 'xah-replace-pairs)
12
13 (defun aminb--readfile (filepath)
14 "Return filepath's content."
15 (with-temp-buffer
16 (insert-file-contents filepath)
17 (buffer-string)))
18
19 (defun aminb--find-replace (match-with replace-with string)
20 "Return the string resulting from replacing `match-with' with
21 `replace-with' in `string'."
22 (when (string-match match-with string)
23 (replace-match replace-with nil nil string)))
24
25 (defun aminb--my-html-body-light-filter (output backend info)
26 "Make adjustments needed for dark/light mode <input> tag to work."
27 (when (eq backend 'html)
28 (aminb--find-replace
29 "</body>\n"
30 "</div>\n</body>\n"
31 (aminb--find-replace
32 "<body>\n"
33 "<body>\n<input class=\"light-off\" id=\"light-off\" type=\"checkbox\">\n<div class=\"page\">"
34 output))))
35
36 (add-to-list 'org-export-filter-final-output-functions
37 'aminb--my-html-body-light-filter)
38
39 ;; re-defining this (originally in `ox-html.el') to add `?g'
40 (defun org-html-format-spec (info)
41 "Return format specification for preamble and postamble.
42 INFO is a plist used as a communication channel."
43 (let ((timestamp-format (plist-get info :html-metadata-timestamp-format))
44 (git-repo "<a href=\"https://git.sr.ht/~aminb/aminb.org/commit/?id=%s\">@%s</a>")
45 (git-rev (shell-command-to-string "git rev-parse HEAD"))
46 (git-rev-short (shell-command-to-string "git rev-parse --short HEAD")))
47 `((?t . ,(org-export-data (plist-get info :title) info))
48 (?s . ,(org-export-data (plist-get info :subtitle) info))
49 (?d . ,(org-export-data (org-export-get-date info timestamp-format)
50 info))
51 (?T . ,(format-time-string timestamp-format))
52 (?a . ,(org-export-data (plist-get info :author) info))
53 (?e . ,(mapconcat
54 (lambda (e) (format "<a href=\"mailto:%s\">%s</a>" e e))
55 (split-string (plist-get info :email) ",+ *")
56 ", "))
57 (?g . ,(format git-repo git-rev git-rev-short))
58 (?c . ,(plist-get info :creator))
59 (?C . ,(let ((file (plist-get info :input-file)))
60 (format-time-string timestamp-format
61 (and file (nth 5 (file-attributes file))))))
62 (?v . ,(or (plist-get info :html-validation-link) "")))))
63
64 ;; timestamps can be used to avoid rebuilding everything
65 ;; should probably be put inside the public/ directory
66 (setq org-publish-use-timestamps-flag t
67 org-publish-timestamp-directory "./")
68
69 ;; get rid of index.html~ and other backup files that may be created during generation
70 (setq make-backup-files nil)
71
72 (setq org-export-with-section-numbers nil
73 org-export-with-smart-quotes t
74 org-export-with-email t
75 org-export-with-date t
76 org-export-with-tags 'not-in-toc
77 org-export-with-toc t)
78
79 (setq org-html-divs '((preamble "header" "preamble")
80 (content "main" "content")
81 (postamble "footer" "postamble"))
82 ;; TODO: link last update to commit history of file
83 org-html-preamble t
84 org-html-postamble t
85 org-html-preamble-format `(("en" ,(aminb--readfile "partials/preamble.html")))
86 org-html-postamble-format `(("en" ,(aminb--readfile "partials/postamble.html")))
87 org-html-container-element "section"
88 org-html-metadata-timestamp-format "%Y-%m-%d"
89 org-html-checkbox-type 'html
90 org-html-html5-fancy t
91 ;; use custom css
92 ;; this removes the dependency on `htmlize',
93 ;; but we also lose syntax highlighting.
94 org-html-htmlize-output-type nil
95 org-html-validation-link nil
96 org-html-doctype "html5")
97
98 (setq org-publish-project-alist
99 (list
100 (list "site-org"
101 :base-directory "./source/"
102 :exclude "macros.org"
103 :recursive t
104 :publishing-function '(org-html-publish-to-html)
105 :publishing-directory "./public/"
106 :html-head-include-default-style nil
107 :html-head-include-scripts nil)
108 (list "site-static"
109 :base-directory "source/"
110 :exclude "\\.org\\'"
111 :base-extension 'any
112 :publishing-directory "./public"
113 :publishing-function 'org-publish-attachment
114 :recursive t)
115 (list "site" :components '("site-org"))))
116
117 (defun aminb/publish ()
118 (org-publish-all))