main.lisp 2.7 KB
Newer Older
1 2 3
;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
(in-package :cl-site)

4

5 6 7 8 9 10
(defun check-deps-fn (dependencies)
   #'(lambda (processed-pages)
        (every (lambda (d)
                  (member d processed-pages :test #'string=))
               dependencies)))

11 12 13 14 15 16
(defun make-site (&optional (output-dir *output-dir*))
  (let ((pages (populate-pages)))
    (ensure-directories-exist output-dir)
    (format t "Generating site in ~A.~%" output-dir)
    (process-static *static-dir* output-dir)
    (process-static (merge-pathnames #P"static/" *layout-dir*) output-dir)
17

18 19 20
    (loop with processed-pages = '()
          with delayed-pages = '()
          for page in pages
21 22
          for page-path = (make-path *pages-dir* page t)
          for rel-page-path = (enough-namestring page-path *pages-dir*)
23
          for page-lines = (file-to-list page-path)
24 25
          for header = (yaml:parse (format nil "~{~A~%~}" (header-lines page-lines)))
          for content = (format nil "~{~A~%~}" (content-lines page-lines))
26 27 28
          ;; order in the context is very important: for any key appearing twice
          ;;  (e.g. the 'title' key), the first will be selected; by taking the header values
          ;;  first, the default 'title' being the content filename, can be overridden in the page's metadata
29
          for context = (append (when header (alist-from-hash header)) page)
30
          for dependencies = (cdr (assoc "depends-on" context :test #'string=))
31 32 33 34
          for satisfies-deps-fn = (check-deps-fn dependencies)
          for satisfies-deps-p = (funcall satisfies-deps-fn processed-pages)
      do (push (list satisfies-deps-fn content context rel-page-path) delayed-pages)
      do (loop for resolved-deps-pages =
35
                   (loop for delay in delayed-pages
36
                         for satisfies-deps-p = (funcall (car delay) processed-pages)
37 38 39
                         when satisfies-deps-p
                         collect delay
                         and do (progn
40
                                   (format t "Rendering ~a~%" (fourth delay))
41
                                   (push (fourth delay) processed-pages)
42
                                   (render-page-with-hooks (second delay) (third delay))))
43 44 45
               while resolved-deps-pages
               do (setf delayed-pages
                        (set-difference delayed-pages resolved-deps-pages :key #'fourth :test #'string=))))))
46 47 48 49 50 51 52 53 54 55


(defun make-clean (&optional (output-dir *output-dir*))
  (when (probe-file output-dir)
    (uiop:delete-directory-tree
     output-dir
     :validate #'(lambda(dir)
		   (string-equal (first (last (pathname-directory dir)))
				 "output"))))
  (ensure-directories-exist output-dir))