(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 "" (tag node)) (when (tag-sonu-yeni-satır? (tag node)) (yeni-satır-yaz stream)))