public
Last active

A static page generator

  • Download Gist
regenerate.lisp
Common Lisp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
;;;; regenerate.lisp - script for regenerating [redacted] static HTML from template files.
 
(ql:quickload "cl-emb")
(ql:quickload "cl-fad")
(ql:quickload "cl-ppcre")
 
(defparameter *configuration* '() "plist containing config parameters passed to EMB templates.")
(defparameter *essays* '() "plist containing essay descriptors generated by `defessay'.")
(defconstant +default-properties+ '(:title nil :url nil :orig-title nil :orig-url nil :date nil :orig-date nil :alt-translations nil :translators nil :editors nil :disabled nil :additional-html nil :part-of-hnp nil :description ""))
 
(defun make-environment ()
(append (list :conf *configuration*) (list :essays *essays*)))
 
;;; Data processing code
(defun defessay (essay-id &rest properties)
"Defines an essay by putting it's data into global *environment* variable, which will be an environment for
EMB templates. Please define essays from oldest to newest, to ensure proper order when iterating (from newest to
oldest."
(push (append properties +default-properties+) *essays*)
(push essay-id *essays*))
 
;;; Regeneration code
 
(defun template-to-generate-file-from-p (path)
"Returns t if given file should generate a corresponding HTML in source."
(not (or (search "templates/" (namestring path))
(search "data/" (namestring path)))))
 
(defun sass-file-p (path)
"Returns t if file has .scss extension (SASS stylesheet)."
(ppcre:scan "\.scss$" (namestring path)))
 
(defun file-or-dir-to-delete-p (path)
"Returns t if given file or directory should be deleted when cleaning."
(let ((name (namestring path)))
(not (or (search "img/" name)
(search "js/" name)
(search "css/" name)
(ppcre:scan "humans.txt$" name)
(ppcre:scan "site/$" name)))))
 
(defun make-group-template-path (pathname)
(pathname (cl-ppcre:regex-replace "src/([A-Za-z]*)/.*" (namestring pathname) "src/templates/\\1\.html")))
 
(defun make-destination-path (pathname)
(pathname (cl-ppcre:regex-replace "src/" (namestring pathname) "site/")))
 
(defun process-template (pathname)
(let ((content (cl-emb:execute-emb pathname
:env (make-environment))))
(cl-emb:execute-emb (make-group-template-path pathname)
:env (append (list :content content)
(make-environment)))))
 
(defun save-file (content pathname)
(ensure-directories-exist pathname)
(with-open-file (stream pathname :direction :output
:if-exists :overwrite
:if-does-not-exist :create)
(format stream content)))
 
(defun generate-file (pathname)
(save-file (process-template pathname)
(make-destination-path pathname))
(format t "Regenerated successfuly: ~A (from ~A)~%" (make-destination-path pathname) pathname))
 
(defun del-dir-or-file-noerror (pathname)
(format t "Deleting: ~A~%" pathname)
(ignore-errors (fad:delete-directory-and-files pathname)))
 
(defun delete-old-files ()
(ignore-errors
(fad:walk-directory "site" 'del-dir-or-file-noerror :test 'file-or-dir-to-delete-p :if-does-not-exist :ignore :directories t)))
 
(defun make-css-file-name (name)
(cl-ppcre:regex-replace "\.scss$" name ".css"))
 
(defun generate-css (pathname)
(let* ((name (namestring pathname))
(command (format nil "/home/temporal/lib/sass/bin/sass --style expanded ~A:~A" name (make-css-file-name name))))
(format t "Running command: ~A~%" command)
#+LINUX(asdf:run-shell-command command)))
 
(defun regenerate ()
"Regenerate all static HTML from template files in src/ directory, and put them in site/ directory."
(format t "Deleting old files...~%")
(delete-old-files)
 
(format t "Cleaning template environment...~%")
(setf *essays* '())
 
(format t "Loading essay data...~%")
(load "src/data/essays.lisp")
(format t "Loaded ~A essay descriptors.~%" (/ (length *essays*) 2))
 
(format t "Regenerating static HTML files...~%")
(fad:walk-directory "src" 'generate-file :test 'template-to-generate-file-from-p)
 
(format t "Regenerating CSS files...~%")
(fad:walk-directory "site/css" 'generate-css :test 'sass-file-p)
 
(format t "Done!~%"))
 
(defun file-test (pathname)
(let ((in (open pathname)))
(format t "~a~%" (read-line in))
(close in)))

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.