43 lines
		
	
	
	
		
			1,009 B
		
	
	
	
		
			Common Lisp
		
	
	
	
	
	
			
		
		
	
	
			43 lines
		
	
	
	
		
			1,009 B
		
	
	
	
		
			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 write-nested (start end &body body)
 | 
						|
  `(progn
 | 
						|
     (write-string ,start *output*)
 | 
						|
     ,@body
 | 
						|
     (write-line ,end *output*)))
 | 
						|
 | 
						|
(defun write-simple (start end val)
 | 
						|
  (write-string start *output*)
 | 
						|
  (write-string val *output*)
 | 
						|
  (write-string end *output*))
 | 
						|
 | 
						|
;;;; tag-specific renderers
 | 
						|
 | 
						|
(defun dl (plist)
 | 
						|
  (write-nested "<dl>" "</dl>"
 | 
						|
    (loop for (key val . r) on plist by #'cddr do
 | 
						|
      (write-simple "<dt>" "</dt>" (string-downcase key))
 | 
						|
      (dd val))))
 | 
						|
 | 
						|
(defun dd (v)
 | 
						|
  (if (atom v)
 | 
						|
    (setf v (list v)))
 | 
						|
  (dolist (el v)
 | 
						|
    (write-simple "<dd>" "</dd>" (string el))))
 | 
						|
 |