Recently Written · git

coleslaw

Emacs mode for the "Coleslaw" site generator written in Common Lisp.

git clone https://github.com/equwal/coleslaw

Log | Files | Refs


src/config.lisp (4225 bytes)

1 (in-package :coleslaw)
2 
3 (defclass blog ()
4   ((author          :initarg :author         :reader author)
5    (charset         :initarg :charset        :reader charset)
6    (deploy-dir      :initarg :deploy-dir     :reader deploy-dir)
7    (domain          :initarg :domain         :reader domain)
8    (excerpt-sep     :initarg :excerpt-sep    :reader excerpt-sep)
9    (feeds           :initarg :feeds          :reader feeds)
10    (name-fn         :initarg :name-fn        :reader name-fn)
11    (lang            :initarg :lang           :reader lang)
12    (license         :initarg :license        :reader license)
13    (page-ext        :initarg :page-ext       :reader page-ext)
14    (plugins         :initarg :plugins        :reader plugins)
15    (repo            :initarg :repo           :accessor repo-dir)
16    (routing         :initarg :routing        :reader routing)
17    (separator       :initarg :separator      :reader separator)
18    (sitenav         :initarg :sitenav        :reader sitenav)
19    (staging-dir     :initarg :staging-dir    :reader staging-dir)
20    (theme           :initarg :theme          :reader theme)
21    (title           :initarg :title          :reader title))
22   (:default-initargs
23    :feeds        nil
24    :license      nil
25    :plugins      '((rsync "-avz" "--delete" "--exclude" ".git/" "--exclude" ".gitignore" "--copy-links"))
26    :sitenav      nil
27    :excerpt-sep  "<!--more-->"
28    :name-fn      'identity
29    :charset      "UTF-8"
30    :lang         "en"
31    :page-ext     "html"
32    :separator    ";;;;;"
33    :staging-dir  "/tmp/coleslaw"))
34 
35 (defun dir-slot-reader (config name)
36   "Take CONFIG and NAME, and return a directory pathname for the matching SLOT."
37   (ensure-directory-pathname (slot-value config name)))
38 
39 (defmethod deploy-dir  ((config blog)) (dir-slot-reader config 'deploy-dir))
40 (defmethod repo-dir    ((config blog)) (dir-slot-reader config 'repo))
41 (defmethod staging-dir ((config blog)) (dir-slot-reader config 'staging-dir))
42 
43 (defparameter *config* nil
44   "A variable to store the blog configuration and plugin settings.")
45 
46 (define-condition plugin-conf-error ()
47   ((plugin  :initarg :plugin :reader plugin)
48    (message :initarg :message :reader message))
49   (:report (lambda (condition stream)
50              (format stream "~A: ~A" (plugin condition) (message condition))))
51   (:documentation "Condition to signal when the plugin is misconfigured."))
52 
53 (defun enable-plugin (name args)
54   "Given a plugin, NAME, compile+load it and call its ENABLE function with ARGS."
55   (flet ((plugin-path (sym)
56            (if (probe-file (repo-path "plugins/~(~A~).lisp" sym))
57                (repo-path "plugins/~(~A~)" sym)
58                (app-path "plugins/~(~A~)" sym)))
59          (plugin-package (sym)
60            (format nil "~:@(coleslaw-~A~)" sym)))
61     (let ((file (plugin-path name)))
62       (multiple-value-bind (output-file error)
63           (ignore-errors (compile-file file :verbose nil :print nil))
64         (when error
65           (warn "Error while compiling plugin ~A: ~A.~%" name error))
66         (load (or output-file file) :verbose t)))
67     (let ((package (find-package (plugin-package name))))
68       (apply (find-symbol "ENABLE" package) args))))
69 
70 (defun load-plugins (plugins)
71   "Compile and load the listed PLUGINS. It is expected that matching *.lisp files
72 are in the plugins folder in coleslaw's source directory."
73   (setf *injections* nil)
74   (dolist (plugin plugins)
75     (destructuring-bind (name &rest args) plugin
76       (enable-plugin name args))))
77 
78 (defun discover-config-path (repo-path)
79   "Check the supplied REPO-PATH for a .coleslawrc and if one
80 doesn't exist, use the .coleslawrc in the home directory."
81   (let ((repo-config (rel-path repo-path ".coleslawrc")))
82     (if (file-exists-p repo-config)
83         repo-config
84         (rel-path (user-homedir-pathname) ".coleslawrc"))))
85 
86 (defun load-config (&optional (repo-dir ""))
87   "Find and load the coleslaw configuration from .coleslawrc. REPO-DIR will be
88 preferred over the home directory if provided."
89   (with-open-file (in (discover-config-path repo-dir) :external-format :utf-8)
90     (let ((config-form (read in)))
91       (setf *config* (construct 'blog config-form)
92             (repo-dir *config*) repo-dir)))
93   (load-plugins (plugins *config*)))