|
@@ -4,10 +4,25 @@
|
|
|
(ql:quickload :str)
|
|
|
(ql:quickload :3bmd)
|
|
|
(ql:quickload :3bmd-ext-code-blocks)
|
|
|
-(ql:quickload :cl-ppcre)
|
|
|
+(ql:quickload :cl-mustache)
|
|
|
+(ql:quickload :osicat)
|
|
|
+(ql:quickload :jonathan)
|
|
|
+
|
|
|
(setf 3bmd:*smart-quotes* t)
|
|
|
(setf 3bmd-code-blocks:*code-blocks* t)
|
|
|
|
|
|
+(defun random-color ()
|
|
|
+ ;; A list of W3.css colors... change this if you
|
|
|
+ ;; use some other CSS framework...
|
|
|
+ (nth (random 28)
|
|
|
+ '("red" "purple" "indigo" "light-blue" "aqua"
|
|
|
+ "green" "lime" "khaki" "amber" "deep-orange"
|
|
|
+ "brown" "gray" "pale-red" "pale-green"
|
|
|
+ "pink" "deep-purple" "blue" "cyan" "teal"
|
|
|
+ "light-green" "sand" "yellow" "orange"
|
|
|
+ "blue-gray" "light-gray" "dark-gray"
|
|
|
+ "pale-yellow" "pale-blue")))
|
|
|
+
|
|
|
(defun convert-to-html (md)
|
|
|
(with-output-to-string (stream)
|
|
|
(3bmd:parse-string-and-print-to-stream md stream)))
|
|
@@ -31,30 +46,26 @@
|
|
|
(defun join-links (links)
|
|
|
(str:join " | " links))
|
|
|
|
|
|
-(defun replace-multi (s &rest olds-news)
|
|
|
- (loop for old-new in olds-news
|
|
|
- do (setf s (str:replace-all (first old-new) (second old-new) s)))
|
|
|
- s)
|
|
|
-
|
|
|
-(defun find-summary-template (html)
|
|
|
- (first
|
|
|
- (cl-ppcre:all-matches-as-strings
|
|
|
- "(\\$\\$FOREACH\\$\\$(\\n(\\s*((?!\\$\\$END\\$\\$).)*\\n?)*)\\$\\$END\\\$\\$)"
|
|
|
- html)))
|
|
|
+(defun get-file-size (path)
|
|
|
+ (let ((stat (osicat-posix:stat path)))
|
|
|
+ (osicat-posix:stat-size stat)))
|
|
|
|
|
|
-(defun extract-index-post-template (html)
|
|
|
- (replace-multi (find-summary-template html)
|
|
|
- (list "$$FOREACH$$" "")
|
|
|
- (list "$$END$$" "")))
|
|
|
+(defun get-human-readable-size (size)
|
|
|
+ (let ((units '("B" "KB" "MB" "GB" "TB"))
|
|
|
+ (unit 0))
|
|
|
+ (loop when (< size 1024)
|
|
|
+ return (str:concat
|
|
|
+ (with-output-to-string (out) (format out "~a" (round size)))
|
|
|
+ (nth unit units))
|
|
|
+ do (setf size (/ size 1024))
|
|
|
+ (incf unit))))
|
|
|
|
|
|
(defun fobil ()
|
|
|
(let* ((posts (uiop:directory-files #P"./posts/"))
|
|
|
(pages (uiop:directory-files #P"./pages/"))
|
|
|
- (post-template (uiop:read-file-string #P"./templates/post.html"))
|
|
|
- (page-template (uiop:read-file-string #P"./templates/page.html"))
|
|
|
- (index-template (uiop:read-file-string #P"./templates/index.html"))
|
|
|
- (post-summary-template (extract-index-post-template
|
|
|
- index-template))
|
|
|
+ (post-template (mustache:compile-template #P"./templates/post.html"))
|
|
|
+ (page-template (mustache:compile-template #P"./templates/page.html"))
|
|
|
+ (index-template (mustache:compile-template #P"./templates/index.html"))
|
|
|
(pages-html (loop for page in pages
|
|
|
when (markdown? page)
|
|
|
collect (convert-to-html
|
|
@@ -64,21 +75,20 @@
|
|
|
collect (convert-to-html
|
|
|
(uiop:read-file-string post))))
|
|
|
(pages-names (loop for page in pages
|
|
|
- collect (str:concat
|
|
|
- (pathname-name page)
|
|
|
- ".html")))
|
|
|
+ when (markdown? page)
|
|
|
+ collect (str:concat
|
|
|
+ (pathname-name page) ".html")))
|
|
|
(pages-titles (loop for page-html in pages-html
|
|
|
collect (get-title page-html)))
|
|
|
(posts-titles (loop for post-html in posts-html
|
|
|
collect (get-title post-html)))
|
|
|
- (index-posts "")
|
|
|
(links-for-index '())
|
|
|
(links-for-posts '())
|
|
|
(links-for-pages '())
|
|
|
(posts-names (loop for post in posts
|
|
|
- collect (str:concat
|
|
|
- (pathname-name post)
|
|
|
- ".html"))))
|
|
|
+ when (markdown? post)
|
|
|
+ collect (str:concat
|
|
|
+ (pathname-name post) ".html"))))
|
|
|
(ensure-directories-exist "./out/")
|
|
|
(ensure-directories-exist "./out/pages/")
|
|
|
(ensure-directories-exist "./out/posts/")
|
|
@@ -100,41 +110,61 @@
|
|
|
with links = (join-links links-for-pages)
|
|
|
do (str:to-file
|
|
|
(str:concat "./out/pages/" page-name)
|
|
|
- (replace-multi page-template
|
|
|
- (list "$$TITLE$$" page-title)
|
|
|
- (list "$$CONTENT$$" page-html)
|
|
|
- (list "$$LINKS$$" links))))
|
|
|
+ (with-output-to-string (out)
|
|
|
+ (funcall page-template (list
|
|
|
+ (cons "title" page-title)
|
|
|
+ (cons "content" page-html)
|
|
|
+ (cons "links" links))
|
|
|
+ out))))
|
|
|
(loop for post-name in posts-names
|
|
|
for post-html in posts-html
|
|
|
for post-title in posts-titles
|
|
|
with links = (join-links links-for-posts)
|
|
|
do (str:to-file
|
|
|
(str:concat "./out/posts/" post-name)
|
|
|
- (replace-multi post-template
|
|
|
- (list "$$TITLE$$" post-title)
|
|
|
- (list "$$CONTENT$$" post-html)
|
|
|
- (list "$$LINKS$$" links))))
|
|
|
- (loop for post-title in posts-titles
|
|
|
- for post-html in posts-html
|
|
|
- for post-summary = (get-summary post-html)
|
|
|
- for post-name in posts-names
|
|
|
- for post-link = (make-link
|
|
|
- (str:concat "./posts/" post-name)
|
|
|
- "Read more")
|
|
|
- do
|
|
|
- (setf index-posts
|
|
|
- (str:concat index-posts
|
|
|
- (replace-multi post-summary-template
|
|
|
- (list "$$POST-TITLE$$"
|
|
|
- post-title)
|
|
|
- (list "$$POST-SUMMARY$$"
|
|
|
- post-summary)
|
|
|
- (list "$$POST-LINK$$"
|
|
|
- post-link)))))
|
|
|
- (str:to-file #P"./out/index.html"
|
|
|
- (replace-multi index-template
|
|
|
- (list (find-summary-template index-template)
|
|
|
- index-posts)
|
|
|
- (list "$$LINKS$$" (join-links
|
|
|
- links-for-index))))))
|
|
|
-
|
|
|
+ (with-output-to-string (out)
|
|
|
+ (funcall post-template (list
|
|
|
+ (cons "title" post-title)
|
|
|
+ (cons "content" post-html)
|
|
|
+ (cons "links" links))
|
|
|
+ out))))
|
|
|
+ (let* ((posts-data (loop for post-title in posts-titles
|
|
|
+ for post-html in posts-html
|
|
|
+ for post-summary = (get-summary post-html)
|
|
|
+ for post-name in posts-names
|
|
|
+ for post-link = (make-link
|
|
|
+ (str:concat "./posts/" post-name)
|
|
|
+ "Read more")
|
|
|
+ collect (list (cons "post-title" (get-title post-html))
|
|
|
+ (cons "post-summary" post-summary)
|
|
|
+ (cons "post-link" post-link)))))
|
|
|
+ (str:to-file #P"./out/index.html"
|
|
|
+ (with-output-to-string (out)
|
|
|
+ (funcall index-template
|
|
|
+ (list (cons "links" (join-links links-for-index))
|
|
|
+ (cons "foreach" posts-data))
|
|
|
+ out))))
|
|
|
+ (when (probe-file #P"./files")
|
|
|
+ (let* ((files-template (mustache:compile-template #P"./templates/files.html"))
|
|
|
+ (files-list (jonathan:parse
|
|
|
+ (uiop:read-file-string #P"./files/list.json")))
|
|
|
+ (files-list- (loop for file in files-list
|
|
|
+ for addr = (getf file :|addr|)
|
|
|
+ collect (list (cons "color"
|
|
|
+ (random-color))
|
|
|
+ (cons "addr"
|
|
|
+ (file-namestring addr))
|
|
|
+ (cons "title"
|
|
|
+ (file-namestring addr))
|
|
|
+ (cons "description"
|
|
|
+ (getf file :|description|))
|
|
|
+ (cons "size"
|
|
|
+ (get-human-readable-size
|
|
|
+ (get-file-size addr)))))))
|
|
|
+ (ensure-directories-exist #P"./out/files/")
|
|
|
+ (str:to-file #P"./out/files/index.html"
|
|
|
+ (with-output-to-string (out)
|
|
|
+ (funcall files-template
|
|
|
+ (list (cons "links" (join-links links-for-posts))
|
|
|
+ (cons "foreach" files-list-))
|
|
|
+ out)))))))
|