# My publish.el configuration ## Preamble This is the [[literate configuration]] source for my publish.el file - what I use to publish my digital garden to the web. The source code blocks that you see here get tangled together with [[org-babel]] to make up the real publish.el file. See also [[How I publish my wiki with org-publish]] for some more info. ## Contents # Table of Contents 1. [Preamble](#Preamble) 2. [Contents](#Contents) 3. [Setup required packages](#Setup%20required%20packages) 4. [Various bits of config](#Various%20bits%20of%20config) 5. [Misc helper functions](#Misc%20helper%20functions) 6. [RSS output](#RSS%20output) 7. [Sitemap](#Sitemap) 8. [Amending the org files before export](#Amending%20the%20org%20files%20before%20export) 1. [Backlinks](#Backlinks) 9. [HTML-output related](#HTML-output%20related) 1. [HTML preamble](#HTML%20preamble) 2. [HTML postamble](#HTML%20postamble) 3. [HTML head extra](#HTML%20head%20extra) 4. [IndieWeb markup](#IndieWeb%20markup) 5. [HTML template](#HTML%20template) 10. [org-publish project configuration and calling](#org-publish%20project%20configuration%20and%20calling) 1. [Configuration](#Configuration) 2. [Triggering the publish](#Triggering%20the%20publish) 11. [Graph-related](#Graph-related) ## Setup required packages ```emacs-lisp (require 'package) (package-initialize) (setq package-archives '(("melpa" . "https://melpa.org/packages/") ("elpa" . "https://elpa.gnu.org/packages/") ("org" . "http://orgmode.org/elpa/"))) (unless package-archive-contents (package-refresh-contents)) (unless (package-installed-p 'use-package) (package-install 'use-package)) (require 'use-package) (setq use-package-always-ensure t) (use-package htmlize) (use-package org-roam :init (setq org-roam-v2-ack t)) (use-package s) (use-package ox-rss) (use-package citeproc) (load "~/.emacs.d/private/commonplace-lib/commonplace-lib.el") (require 'ox-publish) (require 'ox-html) (require 'ox-rss) (require 'citeproc) ;(require 'oc-csl) ;(require 'oc-biblatex) (require 'htmlize) (require 'org-roam) (require 's) (require 'find-lisp) (require 'commonplace-lib) ``` ## Various bits of config Set where the exported files ultimately get published to. ```emacs-lisp (setq commonplace/publish-url "https://commonplace.doubleloop.net") ``` Don't create backup files (those ending with ~) during the publish process. ```emacs-lisp (setq make-backup-files nil) ``` I don't think I'm currently using this? ```emacs-lisp (setq org-cite-export-processors '((latex csl) (t csl))) ``` ## Misc helper functions TODO: presumably I can move these to the end of the file? (Or perhaps extract out somewhere else.) ```emacs-lisp (defun commonplace/format-date (date-str) (let ((year (substring date-str 0 4)) (month (substring date-str 4 6)) (day (substring date-str 6 8))) (format "%s/%s/%s" day month year))) ``` ```emacs-lisp (defun silence (orig-func &rest args) (let ((inhibit-message t)) (apply orig-func args))) (defun commonplace/slugify-export-output-file-name-html (output-file) "Gets the title of the org file and uses this (slugified) for the output filename. This is mainly to override org-roam's default filename convention of `timestamp-title_of_your_note`." (let* ((title (commonplace/get-title (buffer-file-name (buffer-base-buffer)))) (directory (file-name-directory output-file)) (slug (commonplace/slugify-title title))) (concat directory slug ".html"))) (defun org-publish-ignore-mode-hooks (orig-func &rest args) (let ((lexical-binding nil)) (cl-letf (((symbol-function #'run-mode-hooks) #'ignore)) (apply orig-func args)))) ``` ## RSS output For generating an RSS feed for recent changes to my garden. See https://writepermission.com/org-blogging-rss-feed.html ```emacs-lisp (defun commonplace/generate-org-for-rss-feed (title sitemap) "Generate a sitemap of posts that is exported as a RSS feed. TITLE is the title of the RSS feed. SITEMAP is an internal representation for the files to include. PROJECT is the current project." (let* ((posts (cdr sitemap)) (last-hundred (seq-subseq posts 0 (min (length posts) 100)))) (concat "#+TITLE: " title "\n\n" (org-list-to-subtree (cons (car sitemap) last-hundred))))) (defun commonplace/format-rss-feed-entry (entry _style project) "Format ENTRY for the posts RSS feed in PROJECT." (let* ((title (org-publish-find-title entry project)) (link (concat (file-name-sans-extension entry) ".html")) (pubdate (format-time-string (car org-time-stamp-formats) (org-publish-find-date entry project)))) (format "%s :properties: :rss_permalink: %s :pubdate: %s :end:\n" title link pubdate))) (defun commonplace/publish-rss-feed (plist filename dir) "Publish PLIST to RSS when FILENAME is rss.org. DIR is the location of the output." ; org-roam-timestamps--on-save was causing an error (remove-hook 'before-save-hook #'org-roam-timestamps--on-save) (if (equal "recentchanges-feed.org" (file-name-nondirectory filename)) (org-rss-publish-to-rss plist filename dir))) ``` ## Sitemap Though the functions are called 'sitemap', this actually produces my Recent Changes file. ([[Making a recent changes page on my wiki]]) I originally got this from https://vicarie.in/posts/blogging-with-org.html. ```emacs-lisp (defun commonplace/sitemap-format-entry (entry _style project) "Return string for each ENTRY in PROJECT." (format "@@html:@@ %s @@html:@@ [[file:%s][%s]] @@html:@@" (format-time-string "%d %h %Y" (org-publish-find-date entry project)) entry (org-publish-find-title entry project))) (defun commonplace/recent-changes-sitemap-function (title sitemap) (let* ((posts (cdr sitemap)) (last-hundred (seq-subseq posts 0 (min (length posts) 100)))) (concat "#+TITLE: " title "\n\n" (org-list-to-org (cons (car sitemap) last-hundred))))) ``` ## Amending the org files before export There's some bits and pieces that I want added to every page as it exists on the web. But I don't want them in my org files locally. So here I add these extra bits to the org file just prior to export kicking in. Define the function: ```emacs-lisp (defun commonplace/add-extra-sections (backend) (when (org-roam-node-at-point) (save-excursion (goto-char (point-max)) (insert "\n* Elsewhere\n\n** In my garden") (commonplace/collect-backlinks-string backend) (insert "\n** In the Agora\n\n") (insert (commonplace/link-to-agora (org-roam-node-at-point))) (insert "\n** Mentions\n\n") (insert "#+BEGIN_EXPORT html
#+END_EXPORT")))) ``` And then add a hook for this to run: ```emacs-lisp (add-hook 'org-export-before-processing-hook 'commonplace/add-extra-sections) ``` ### Backlinks Very important - to include backlinks to the current page. The backlink information comes out of org-roam. See: https://org-roam.readthedocs.io/en/master/org_export/ ```emacs-lisp (defun commonplace/collect-backlinks-string (backend) "Insert backlinks into the end of the org file before parsing it." (when (org-roam-node-at-point) (goto-char (point-max)) ;; Add a new header for the references (insert "\nNotes that link to this note (AKA [[file:backlinks.org][backlinks]]).\n") (let* ((backlinks (org-roam-backlinks-get (org-roam-node-at-point) :unique t))) (dolist (backlink backlinks) (let* ((source-node (org-roam-backlink-source-node backlink)) (point (org-roam-backlink-point backlink))) (insert (format "- [[id:%s][%s]]\n" (org-roam-node-id source-node) (org-roam-node-title source-node)))))))) ``` #### Agora link I syndicate all my content to the [[Agora]] - so here I add a link to the content on the Agora. ```emacs-lisp (defun commonplace/link-to-agora (org-roam-node-at-point) (let* ((title (org-roam-node-title org-roam-node-at-point)) (slug (commonplace/slugify-title title))) (concat "- [[https://anagora.org/" slug "][Anagora - " title "]] "))) ``` ## HTML-output related The org-publish uses [[org-export]] to do the actual conversion from org files to the desired output. For my web publish, I want HTML. So we're using the HTML backend. Here I have a bunch of functions and variables that determine how the exported HTML output looks. ### HTML preamble TODO: This could do with a tidy-up. I see I've got lots of tailwind classes in here - I might want to strip those out at some point. ```emacs-lisp (setq commonplace/preamble " ") ``` ### HTML postamble TODO: not sure I really need this postamble anymore. Or perhaps update it a bit. ```emacs-lisp (setq commonplace/postamble "Recent changes. Source. Peer Production License. ") ``` ### HTML head extra TODO: I'd like to remove the unpkg stuff. ```emacs-lisp (setq commonplace/head-extra " ") ``` ### IndieWeb markup Currently just adding e-content. I could do a lot more here I'm sure. (Like marking up the title, for example?) ```emacs-lisp (defun commonplace/filter-body (text backend info) (when (org-export-derived-backend-p backend 'html) (unless (org-export-derived-backend-p backend 'rss) (concat "%s
\n" (concat "\n" (org-html-close-tag "br" nil info) "\n" "%s\n")) (org-export-data subtitle info)) ""))))) (if (or ctime-date mtime-date) (concat "