diff options
Diffstat (limited to 'src/üretim.lisp')
-rw-r--r-- | src/üretim.lisp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/üretim.lisp b/src/üretim.lisp new file mode 100644 index 0000000..3b3530d --- /dev/null +++ b/src/üretim.lisp @@ -0,0 +1,64 @@ +(in-package :html-jen) + +(defparameter *indent* 0) +(defparameter *indent-increment* 2) +(defparameter *satır-başı* t) + +(defgeneric node->html (node &optional stream) + (:method (node &optional (stream *standard-output*)) + (write-string node stream)) + (:documentation "NODE u STREAM e yazar")) + +(defun tag-başı-yeni-satır? (tag) + (case tag + ((:html :head :body :div :ol :ul :link) t) + ((:title :p :b :i :code :li) nil))) + +(defun tag-sonu-yeni-satır? (tag) + (case tag + ((:html :head :body :div :ol :ul :li :p :title :pre :h1 :h2 :h3 :h4 :h5 :h6) t) + ((:b :i :code) nil))) + +(defun yeni-satır-yaz (stream) + (write-char #\Newline stream) + (setf *satır-başı* t)) + +;;;; https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html +;;; TODO geliştirme mümkün... ama şimdilik yeter (#\" """) (#\' "'") +(defun kaçışlı-içerik-yazdır (metin stream) + (loop :for karakter :across metin + :do (case karakter + (#\< (write-string "<" stream)) + (#\> (write-string ">" stream)) + (#\& (write-string "&" stream)) + (t (write-char karakter stream))))) + +(defmethod node->html :before ((node node) &optional (stream *standard-output*)) + (unless (not *satır-başı*) + (loop :for i :from 0 :below *indent* + :do (write-char #\Space stream))) + (if (null (props node)) + (format stream "<~a>" (tag node)) + (loop :initially (format stream "<~a" (tag node)) + :for (k v) :on (props node) :by #'cddr + :do (format stream " ~a=\"~a\"" k v) + :finally (write-char #\> stream))) + (setf *satır-başı* nil) + (when (tag-başı-yeni-satır? (tag node)) + (yeni-satır-yaz stream))) + +(defmethod node->html ((node node) &optional (stream *standard-output*)) + (if (null (children node)) + (kaçışlı-içerik-yazdır (value node) stream) + (let ((*indent* (+ *indent* *indent-increment*))) + (loop :for child :in (children node) + :do (node->html child stream))))) + +(defmethod node->html :after ((node node) &optional (stream *standard-output*)) + (unless (not *satır-başı*) + (loop :for i :from 0 :below *indent* + :do (write-char #\Space stream))) + (format stream "</~a>" (tag node)) + (when (tag-sonu-yeni-satır? (tag node)) + (yeni-satır-yaz stream))) + |