Add some basic support for coad snippets
authorLucian Mogosanu <lucian.mogosanu@gmail.com>
Sun, 23 Jun 2019 11:37:58 +0000 (14:37 +0300)
committerLucian Mogosanu <lucian.mogosanu@gmail.com>
Sun, 23 Jun 2019 11:38:21 +0000 (14:38 +0300)
blog.lisp
templates/coad.lisp [new file with mode: 0644]

index b08ba39..a9af93e 100644 (file)
--- a/blog.lisp
+++ b/blog.lisp
 (load (concatenate 'string *lbs-base* "templates/index.lisp"))
 (load (concatenate 'string *lbs-base* "templates/archive.lisp"))
 (load (concatenate 'string *lbs-base* "templates/drafts.lisp"))
+(load (concatenate 'string *lbs-base* "templates/coad.lisp"))
 (load (concatenate 'string *lbs-base* "templates/rss.lisp"))
 
 ;; TLBS functions
 ;;
 ;; TODO: Move them to an ASDF project
-(defun get-plain-text (path)
+(defun get-plain-text (path &key read-header)
   (let ((blist (make-hash-table :test 'equal)))
     (with-open-file (stream path)
-      ; First read the header: ignore everything until the first line
-      ; with three dashes
-      (do ((line (read-line stream) (read-line stream)))
-          ((equal line "---")))
-
-      ; Now read variables and add them to the blist
-      (do ((line (read-line stream) (read-line stream)))
-          ((equal line "---"))
-        (let ((pair (cl-ppcre:split ":\\s*" line :limit 2)))
-          (if (not (cdr pair))
-              (format t "Error parsing line: ~a" line)
-              (setf (gethash (car pair) blist) (cadr pair)))))
-
-      ; Now all that's left to read is the page body
-      ;
-      ; Note that we build a new string with the length exactly equal to
-      ; the file's length minus what we have read so far.
+      (when read-header
+       ;; First read the header: ignore everything until the first line
+       ;; with three dashes
+       (do ((line (read-line stream) (read-line stream)))
+           ((equal line "---")))
+
+       ;; Now read variables and add them to the blist
+       (do ((line (read-line stream) (read-line stream)))
+           ((equal line "---"))
+         (let ((pair (cl-ppcre:split ":\\s*" line :limit 2)))
+           (if (not (cdr pair))
+               (format t "Error parsing line: ~a" line)
+               (setf (gethash (car pair) blist) (cadr pair))))))
+
+      ;; Now all that's left to read is the page body
+      ;;
+      ;; Note that we build a new string with the length exactly equal
+      ;; to the file's length minus what we have read so far.
       (let ((body (make-string (file-length stream))))
         (read-sequence body stream)
         (setf (gethash "body" blist) (string-trim '(#\Nul) body)))
 
-      ; Return the new blist
+      ;; Return the new blist
       blist)))
 
+(defun tlbs-make-blist% (in-path out-path uri &key read-header)
+  (let ((blist (get-plain-text in-path :read-header read-header)))
+    (setf (gethash "in-path" blist) in-path
+          (gethash "out-path" blist) out-path
+          (gethash "uri" blist) uri)
+    blist))
+
 (defun tlbs-make-blist (relative-pathname)
   (let* ((in-path (concat-pathnames (pathname *lbs-base*)
-                                   relative-pathname))
+                                    relative-pathname))
          (out-path (post-out-extension
                     (concat-pathnames (pathname *lbs-site*)
                                       relative-pathname)))
          (uri (namestring (post-out-extension
-                           (concat-pathnames #p"/" relative-pathname))))
-         (blist (get-plain-text in-path)))
-    (setf (gethash "in-path" blist) in-path)
-    (setf (gethash "out-path" blist) out-path)
-    (setf (gethash "uri" blist) uri)
-    blist))
+                           (concat-pathnames #p"/" relative-pathname)))))
+    (tlbs-make-blist% in-path out-path uri :read-header t)))
 
 (defun tlbs-write-blist (blist)
   (with-open-file (out (ensure-directories-exist (gethash "out-path" blist))
     ; continue with normal page processing
     (tlbs-process-page (gethash "out-path" blist) blist)))
 
+(defun tlbs-process-coad-file (in-path relative-pathname &key lang)
+  (let* ((out-path (post-out-extension
+                    (concat-pathnames (pathname *lbs-site*)
+                                      relative-pathname)))
+         (uri (namestring (post-out-extension
+                           (concat-pathnames #p"/" relative-pathname))))
+         (blist (tlbs-make-blist% in-path out-path uri :read-header nil)))
+    ;; Set language
+    (setf (gethash "lang" blist) lang)
+    ;; Make fenced code block
+    (tlbs-make-coad blist)
+    ;; Apply layout
+    (tlbs-make-default blist)
+    ;; write to file
+    (tlbs-write-blist blist)
+    ;; make sure body is erased when done writing
+    ;; XXX: the body might still be needed when generating RSS
+    (setf (gethash "body" blist) nil)
+    ;;
+    nil))
+
 (defun tlbs-process-archive ()
   (tlbs-process-page (merge-pathnames
                       (pathname *lbs-site*)
diff --git a/templates/coad.lisp b/templates/coad.lisp
new file mode 100644 (file)
index 0000000..a0d8462
--- /dev/null
@@ -0,0 +1,31 @@
+;; Tarpit Lisp Blog Scaffolding -- code page generation
+;;
+;; Given the path to a file, turn it into a HTML representation of
+;; itself:
+;;
+;; - read the file -> CODE
+;; - encase CODE in markdown code blocks
+;; - markdown -> html
+;; - encase in selection span
+(defun tlbs-make-coad (blist)
+  (let* ((body (gethash "body" blist))
+         (lang (gethash "lang" blist))
+         (md-code-block
+          (concatenate 'string
+                       (format nil "~4~")
+                       (if lang (format nil " {.~a}" lang) "")
+                       (format nil "~%~a~%" body)
+                       (format nil "~4~"))))
+    ;; Set code block as body
+    (setf (gethash "body" blist) md-code-block)
+    ;; Pandoc
+    (pipe-through-pandoc blist))
+  ;; Encase in shash
+  (let ((new-body
+         (with-output-to-string (out)
+           (cl-who:with-html-output (out nil :indent nil)
+             (cl-who:htm (:span :id "shash"
+                                (cl-who:str (gethash "body" blist))))))))
+    (setf (gethash "body" blist) new-body))
+  blist)
+