Home | GitHub

Blog Build Script

Table of Contents

exec sh -c "cp make.org src/make.org && emacs make.org -Q --batch -l org --eval '(org-babel-tangle)' && ./make.el \"\$@\""

The above is the literal shebang for this program :)

Publishing System Setup

Load the org publishing system and configure package management.

;; Load the publishing system
(require 'ox-publish)

(setq package-user-dir (expand-file-name "./.packages"))
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("elpa" . "https://elpa.gnu.org/packages/")))

;; Initialize the package system
(package-initialize)
(unless package-archive-contents
  (package-refresh-contents))

;; Install dependencies
(package-install 'htmlize)

Output Directory Configuration

Parse command line arguments to allow custom output directory.

;; Parse command line arguments
(message "DEBUG: command-line-args-left = %S" command-line-args-left)
(setq output-dir (or (car command-line-args-left) "/var/www/blog"))
(message "DEBUG: output-dir = %s" output-dir)

;; Ensure output directory exists
(make-directory output-dir t)
(message "DEBUG: Created directory %s" output-dir)

HTML Customization

Configure the HTML output with custom stylesheets and interactive functionality.

;; Customize the HTML output
(setq org-html-validation-link nil            ;; Don't show validation link
      org-html-head-include-scripts nil       ;; Use our own scripts
      org-html-head-include-default-style nil ;; Use our own styles
      org-html-head "
<link rel='stylesheet' href='/resources/modus-operandi-tinted.css' media='(prefers-color-scheme: light)'/>
<link rel='stylesheet' href='/resources/modus-vivendi-tinted.css' media='(prefers-color-scheme: dark)'/>
<link rel='stylesheet' href='/resources/style.css'/>
<script src='/resources/hyperscript-v0.9.14.js'></script>
<script type='text/hyperscript'>
  on click from <#table-of-contents > h2/>
    toggle .show on #table-of-contents
  end
  on click from <.outline-2 > h2, .outline-3 > h3, .outline-4 > h4, .outline-5 > h5, .outline-6 > h6/>
    toggle .folded on the parentElement of it
  end
  on click from <#table-of-contents a/>
    set target to the first <${its @href}/>
    repeat while target exists
      remove .folded from target
      set target to target.parentElement
    end
  end
</script>")

Helper Functions

Define helper functions for building HTML elements.

(defun <a> (title href)
  (format "<a href=%s>%s</a>" href title))

(defun <top> (&rest links)
  (format "<div>%s</div>" (string-join links " | ")))

(defun <preamble> (info)
  "Custom preamble that adds links to all pages"
  (let ((file (plist-get info :input-file)))
    (apply
     '<top>
     `(,@(unless (string-match-p "index\\.org$" file)
           (list (<a> "Home" "/")))
       ,(<a> "GitHub" "https://github.com/garlic0x1")))))

Publishing Configuration

Define the publishing targets for resources, images, and main content.

;; Define the publishing project
(setq org-publish-project-alist
      (list
       (list "resources"
             :recursive t
             :base-directory "./src/resources"
             :publishing-directory (concat output-dir "/resources")
             :base-extension "css\\|js\\|html"
             :publishing-function 'org-publish-attachment)
       (list "images"
             :recursive t
             :base-directory "./src/images"
             :publishing-directory (concat output-dir "/images")
             :base-extension "png\\|jpg\\|jpeg\\|gif\\|svg\\|webp"
             :publishing-function 'org-publish-attachment)
       (list "main"
             :recursive t
             :base-directory "./src"
             :publishing-directory output-dir
             :publishing-function 'org-html-publish-to-html
             :with-author nil
             :with-creator t
             :with-toc t
             :section-numbers nil
             :time-stamp-file nil
             :html-preamble '<preamble>)))

Build Execution

Run the publishing system and report completion.

;; Generate the site output
(org-publish-all t)

(message "Build complete!")

Usage

To build the blog:

./make.org [output-dir]

Default output directory is /var/www

Emacs 30.2 (Org mode 9.7.11)