hsx/src/utils.lisp

59 lines
1.5 KiB
Common Lisp
Raw Normal View History

2024-10-03 00:54:43 +00:00
(defpackage #:hsx/utils
2024-05-31 09:39:25 +00:00
(:use #:cl)
(:import-from #:alexandria
2024-10-03 01:25:30 +00:00
#:alist-hash-table
#:make-keyword
#:symbolicate)
2024-05-31 09:39:25 +00:00
(:export #:escape-html-attribute
2024-10-03 00:54:43 +00:00
#:escape-html-text-content
2024-10-03 01:25:30 +00:00
#:defgroup))
2024-10-03 00:54:43 +00:00
(in-package #:hsx/utils)
2024-05-31 09:39:25 +00:00
(defparameter *text-content-escape-map*
(alist-hash-table
'((#\& . "&")
(#\< . "&lt;")
(#\> . "&gt;")
(#\" . "&quot;")
(#\' . "&#x27;")
(#\/ . "&#x2F;")
(#\` . "&grave;")
(#\= . "&#x3D;"))))
(defparameter *attribute-escape-map*
(alist-hash-table
'((#\" . "&quot;"))))
(defun escape-char (char escape-map)
2024-10-03 00:54:43 +00:00
(or (gethash char escape-map)
2024-05-31 09:39:25 +00:00
char))
2024-10-03 05:17:16 +00:00
(defun escape-string (str escape-map)
(if (stringp str)
(with-output-to-string (out)
2024-05-31 09:39:25 +00:00
(loop
2024-10-03 05:17:16 +00:00
:for c :across str
:do (write (escape-char c escape-map) :stream out :escape nil)))
str))
2024-05-31 09:39:25 +00:00
2024-10-03 05:17:16 +00:00
(defun escape-html-text-content (str)
(escape-string str *text-content-escape-map*))
2024-05-31 09:39:25 +00:00
2024-10-03 05:17:16 +00:00
(defun escape-html-attribute (str)
(escape-string str *attribute-escape-map*))
2024-10-03 00:54:43 +00:00
2024-10-03 01:25:30 +00:00
(defun make-keyword-hash-table (symbols)
(let ((ht (make-hash-table)))
(mapcar (lambda (sym)
(setf (gethash (make-keyword sym) ht) t))
symbols)
ht))
(defmacro defgroup (name &body symbols)
(let ((param-name (symbolicate '* name '*))
(pred-name (symbolicate name '-p)))
`(progn
(defparameter ,param-name (make-keyword-hash-table ',symbols))
(defun ,pred-name (keyword)
(gethash keyword ,param-name)))))