| 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)) |