cl-scopes/web/dom.lisp

61 lines
1.2 KiB
Common Lisp

;;;; cl-scopes/web/dom - "Data Output Model" = simple and dedicated HTML generator
(defpackage :scopes/web/dom
(:use :common-lisp)
(:local-nicknames (:alx :alexandria))
(:export #:render #:dl))
(in-package :scopes/web/dom)
;;;; basic / common stuff
(defvar *output* nil)
(defmacro render (&body body)
`(let ((*output* (make-string-output-stream)))
,@body
(get-output-stream-string *output*)))
(defmacro put-string (s)
`(write-string ,s *output*))
(defmacro put-char (c)
`(write-char ,c *output*))
(defmacro nested (tag attrs &body body)
`(progn
(start ,tag ,attrs)
,@body
(end ,tag t)))
(defun terminal (tag attrs val)
(start tag attrs)
(put-string val)
(end tag))
(defun start (tag &optional attrs)
(put-char #\<)
(put-string tag)
(put-char #\>))
(defun end (tag &optional newline)
(put-string "</")
(put-string tag)
(put-char #\>)
(if newline
(put-char #\Newline)))
;;;; tag-specific renderers
(defun dl (plist)
(nested "dl" nil
(loop for (key val . r) on plist by #'cddr do
(terminal "dt" nil (string-downcase key))
(dd val))))
(defun dd (v)
(if (atom v)
(setf v (list v)))
(dolist (el v)
(terminal "dd" nil (string el))))