Org Configuration
My current solution is based on derivatives of my previous publishing
configuration as well as this post around publishing with Github
Actions. It relies on running emacs in batch mode to generate the
website, with all the configuration in publish.el
with a helper script
publi.sh
to build locally or on Github.
Build script (publi.sh
)
#!/bin/sh set -x set -e LOCAL=0 FORCE=0 for arg in "$@" do case $arg in -l|--local) LOCAL=1 shift ;; -f|--force) FORCE=1 shift ;; esac done INCLUDE="$@" git config --global user.email "bhalla.kunal@gmail.com" git config --global user.name "Kunal Bhalla" DATE_MARKER=$(date) HOST=$(hostname) if [ $LOCAL != 1 ] then set +x echo "+ TARGET_REPO=<redacted>" TARGET_REPO="https://kunalb:$API_TOKEN@github.com/kunalb/kunalb.github.io.git" set -x else TARGET_REPO="git@github.com:kunalb/explog.git" fi cd "$(dirname "$0")" if [ ! -d "build" ] then set +x echo "git clone <redacted> build" git clone $TARGET_REPO build set -x fi INCLUDE=$INCLUDE FORCE=$FORCE LOCAL=$LOCAL emacs --batch -l publish.el if [ $LOCAL != 1 ] then cd build git add . && git commit -am "$DATE_MARKER: Built on $HOST" set +x echo "git push <redacted>" git push $TARGET_REPO set -x fi
Elisp to export everything (publish.el
)
;;; Publish expLog ;; Local build (setq localp (string= "1" (getenv "LOCAL"))) (setq forcep (string= "1" (getenv "FORCE"))) (setq include (getenv "INCLUDE")) (setq package-check-signature nil) ;; Enable debugging for better stack traces (setq debug-on-error t) ;; Set up packages (setq package-archives '(("melpa" . "http://melpa.org/packages/") ("elpa" . "http://elpa.gnu.org/packages/") ("nongnu" . "http://elpa.nongnu.org/nongnu/"))) (package-initialize) (unless localp (package-refresh-contents)) (package-install 'htmlize) (package-install 'org-contrib) (with-temp-buffer (url-insert-file-contents "https://raw.githubusercontent.com/emacsmirror/ox-rss/80b5001c3d1c10b578d799bd8ff49e9267a2d5ff/ox-rss.el") (eval-buffer)) (require 'org) (require 'ox-publish) (require 'ox-rss) (require 'htmlize) (require 'subr-x) ;; Include options (setq include-options (if (not (string-empty-p include)) `(:exclude ".*" :include ,(split-string include)) '())) ;; Basic settings (setq make-backup-files nil) (setq org-confirm-babel-evaluate nil) (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (python . t))) (setq org-export-global-macros '((margin . "@@html:<span class='margin'>@@$1@@html:</span>@@") (notice . "@@html:<span class='notice'>@@$1@@html:</span>@@"))) (defun repeat-string (str num) (apply 'concat (make-list num str))) (setq root-directory (expand-file-name default-directory)) (defun create-preamble (options) (let* ((current-file-name (plist-get options :input-file)) (current-file-depth (- (length (split-string (file-relative-name current-file-name root-directory) "\/")) 2))) (if (not (string-suffix-p "org/index.org" (plist-get options :input-file))) (concat "<div>< <a href='" (repeat-string "../" current-file-depth) "index.html'>expLog</a></div>")))) (defun create-header (options) (let* ((current-file-name (plist-get options :input-file)) (current-file-depth (- (length (split-string (file-relative-name current-file-name root-directory) "\/")) 2))) (concat "<link rel=\"stylesheet\" href='" (repeat-string "../" current-file-depth) "static/style.css' />" ))) (defun custom-header (fn &rest args) (let ((res (apply fn args))) (concat res (create-header (car args))))) (advice-add 'org-html--build-head :around #'custom-header) ;; Publish the actual website (org-publish `("expLog" :base-directory "org" :publishing-directory "build" :base-extension "org" :recursive t :htmlized-source t :publishing-function org-html-publish-to-html :with-author nil :with-toc nil :section-numbers nil :html-validation-link nil :html-head-include-scripts nil :html-postamble nil :html5-fancy t :html-head-extra " <script data-goatcounter='https://knl.goatcounter.com/count' async src='//gc.zgo.at/count.js'></script> " :html-preamble ,'create-preamble ,@include-options ) (or forcep (not localp))) (if (null include-options) ;; Copy over static resources (org-publish '("static" :base-directory "org/static" :publishing-directory "build/static" :base-extension any :recursive t :publishing-function org-publish-attachment) (or forcep (not localp)))) (if (null include-options) ;; RSS (org-publish '("rss" :base-directory "org" :base-extension "org" :html-link-home "https://explog.in/" :html-link-use-abs-url t :rss-extension "xml" :publishing-directory "build" :publishing-function (org-rss-publish-to-rss) :section-numbers nil :exclude ".*" :include ("rss.org") :table-of-contents nil) (or forcep (not localp))))
Github Action (.github/workflows/publish.yml
)
name: Publish on: push: workflow_dispatch: jobs: publish-explog: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - name: Install software run: sudo apt-get install emacs git - name: Install python dependencies run: | python3 -m pip install --upgrade pip pip install matplotlib - name: Build new site run: ./publi.sh -f env: API_TOKEN: ${{ secrets.API_TOKEN }}
Updates
- 2022-01-10: Extracted CSS into a separate file.
- 2021-07-05: Resurrected RSS feed.
- 2021-05-22: First steps towards automation and simplification.
- 2021-01-21: One of the most stable designs; on internet archive.
- 2016-10-27: A white version; on internet archive.