Commit af5c58aa authored by Erik Huelsmann's avatar Erik Huelsmann
Browse files

Simplify page generation loop

Note that the case of 'meets dependencies without delay'
is a special case of 'meets dependencies with delay' --
after all, the delay here is 'zero dependency files'.

Because this is the case, put every file in the delay
buffer and on every iteration try to handle as many
delayed files as possible. At the bare minimum, the one
which already met its deps upon queueing will be rendered.
parent 21905dbb
......@@ -27,6 +27,12 @@
(read-sequence data stream)
(defun file-to-list (path)
(with-open-file (f path :direction :input)
(loop for line = (read-line f nil)
while line
collect line)))
(defun header-lines (lines)
"Returns a list of lines (subset of `lines`)
......@@ -118,6 +124,11 @@
(cons (second plist)
(plist-values (rest (rest plist))))))
(defun alist-from-hash (hash)
(loop for k being each hash-key of hash
using (hash-value v)
collect (cons k v)))
(defmacro with-cl-who-string ((&rest args) &body body)
"Form. Sets up body to be evaluated with cl-who:with-html-output and return the resulting string instead
......@@ -2,6 +2,12 @@
(in-package :cl-site)
(defun check-deps-fn (dependencies)
#'(lambda (processed-pages)
(every (lambda (d)
(member d processed-pages :test #'string=))
(defun make-site (&optional output-dir)
(let ((*output-dir* (or output-dir *output-dir*))
(pages (populate-pages)))
......@@ -10,44 +16,29 @@
(process-static *static-dir* *output-dir*)
(process-static (merge-pathnames #P"static/" *layout-dir*) *output-dir*)
(loop for page in pages
(loop with processed-pages = '()
with delayed-pages = '()
for page in pages
for page-path = (make-path *pages-dir* page t)
for rel-page-path = (enough-namestring page-path *pages-dir*)
for page-lines = (with-open-file (f page-path :direction :input)
(loop for line = (read-line f nil)
while line
collect line))
for page-lines = (file-to-list page-path)
for header = (yaml:parse (format nil "~{~A~%~}" (header-lines page-lines)))
for content = (format nil "~{~A~%~}" (content-lines page-lines))
;; 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
for context = (append (when header
(loop for k being each hash-key of header
using (hash-value v)
collect (cons k v)))
for context = (append (when header (alist-from-hash header)) page)
for dependencies = (cdr (assoc "depends-on" context :test #'string=))
for satisfies-deps-fn = (let ((deps dependencies))
(lambda ()
(every (lambda (d) (member d processed-pages :test #'string=))
for satisfies-deps-p = (funcall satisfies-deps-fn)
unless satisfies-deps-p
collect (list satisfies-deps-fn content context rel-page-path) into delayed-pages
and do (format t "Delayed rendering ~a~%" rel-page-path)
when satisfies-deps-p
do (progn
(format t "Rendering ~A~%" rel-page-path)
(render-page-with-hooks content context))
and collect rel-page-path into processed-pages
and do (loop for resolved-deps-pages =
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 =
(loop for delay in delayed-pages
for satisfies-deps-p = (funcall (car delay))
for satisfies-deps-p = (funcall (car delay) processed-pages)
when satisfies-deps-p
collect delay
and do (progn
(format t "Rendering delayed ~a~%" (fourth delay))
(format t "Rendering ~a~%" (fourth delay))
(push (fourth delay) processed-pages)
(render-page-with-hooks (second delay) (third delay))))
while resolved-deps-pages
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment