Project Definition
How this blog is generated

1 Configuration

All configuration for this example blog is contained inside .dir-locals.el.

((nil . (;; export blog whenever a file in the source directory is changed
         (eval . (ox-blog-mode 1))
         ;; normally :source-directory & :export-directory must be absolute to
         ;; enable exporting from any subdirectory.
         ;; For the demo blog relative paths are possible & required to enable
         ;; exporting the blog independent of where the ox-blog repository lies.
         ;; This only works because export is only ever executed from the
         ;; ./source directory

         (ox-blog-project . (:source-directory "../source/"
                                                         :export-directory "../docs/"
                             :excluded-files (".dir-locals.el")
                             :server-base-url "/ox-blog"
                             :html-head "
<link rel='stylesheet' href='/ox-blog/main.css' type='text/css'/>"
                             :index-head "
<meta name='description' content='ox-blog demo project'>
<link rel='stylesheet' href='/ox-blog/main.css' type='text/css'/>
<link rel='stylesheet' href='/ox-blog/index.css' type='text/css'/>"
                             :html-preamble "
<header>
  <a class='logo' href='/ox-blog/'>home</a>
  <nav>
    <a href='https://www.github.com/niklasfasching/ox-blog'>github</a>
    <a href='about.html'>about</a>
  </nav>
</header>"
                             :html-postamble ""
                             :html-head-include-scripts nil
                             :html-head-include-default-style nil
                             :time-stamp-file nil
                             :with-sub-superscript {}
                             :with-toc nil)))))

The export is started via the export target in the Makefile.

.PHONY: install
install:
        emacs \
                --batch \
                --quick \
                --eval "(require 'package)" \
                --eval '(add-to-list (quote package-archives) (quote ("melpa" . "http://melpa.org/packages/")))' \
                --eval '(setq package-user-dir (concat default-directory ".emacs"))' \
                --eval '(package-initialize)' \
                --eval "(package-refresh-contents)" \
                --eval "(package-install-from-archive (cadr (assoc 'org package-archive-contents)))" \
                --eval "(package-install-from-archive (cadr (assoc 'htmlize package-archive-contents)))"

.PHONY: test
test:
        emacs \
                --batch \
                --quick \
                --eval '(setq package-user-dir (concat default-directory ".emacs"))' \
                --eval '(package-initialize)' \
                --eval '(normal-top-level-add-to-load-path (list "test" "."))' \
                --eval '(mapc (lambda (p) (delete-process p)) (process-list))' \
                --eval '(load "ox-blog-test.el")' \
                --eval '(ert-run-tests-batch-and-exit)'

.PHONY: export
export:
        emacs \
                --batch \
                --quick \
                --eval '(setq package-user-dir (concat default-directory ".emacs"))' \
                --eval '(package-initialize)' \
                --eval '(normal-top-level-add-to-load-path (list "."))' \
                --eval '(mapc (lambda (p) (delete-process p)) (process-list))' \
                --eval '(defun face-spec-set-match-display (&rest args) t)' \
                --eval "(load-theme 'wombat)" \
                --eval "(require 'ox-blog)" \
                --eval '(setq default-directory (expand-file-name "source/"))' \
                --eval '(hack-dir-local-variables-non-file-buffer)' \
                --eval '(let (org-confirm-babel-evaluate) (ox-blog-export :force-export t))'

As you can see face-spec-set-match-display has been overriden to always return t. This is not a requirement of ox-blog but a workaround to a limitation of exporting from emacs --batch.

To export highlighted code blocks a theme has to be loaded. Sadly, emacs --batch claims to have a monochrome display - which makes face definitions restricted to color displays not apply. Overriding face-spec-set-match-display is just a way of getting these faces applied nonetheless.