From d0eefc4f2ffdf649c836d60570ff5aed87f16995 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Sun, 24 Jun 2018 13:08:30 -0400 Subject: [PATCH] Initial version --- .gitignore | 1 + README.md | 18 +++++++++ flute.asd | 15 +++++++ src/flute.lisp | 103 ++++++++++++++++++++++++++++++++++++++++++++++++ src/test.html | 16 ++++++++ system-test.asd | 8 ++++ t/flute.lisp | 4 ++ 7 files changed, 165 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 flute.asd create mode 100644 src/flute.lisp create mode 100644 src/test.html create mode 100644 system-test.asd create mode 100644 t/flute.lisp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..e4b5b47 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# flute + +[A short, one-line description of the project] + +# Overview + +[A longer description of the project, optionally with sub-sections like +'Features', 'History', 'Motivation', etc.] + +# Usage + +[Examples of usage] + +# License + + + +Licensed under the Specify license here License. diff --git a/flute.asd b/flute.asd new file mode 100644 index 0000000..e3948fa --- /dev/null +++ b/flute.asd @@ -0,0 +1,15 @@ +(defsystem flute + :author "Bo Yao and conflicts with cl symbol, are defined and exported as |time|, |map| + + )) +(in-package :flute) + +(defstruct element tag attrs children) + +(defstruct attrs alist) + +(defun split-attrs-and-chilren (attrs-and-children) + (cond + ((attrs-p (first attrs-and-children)) + (values (first attrs-and-children) (rest attrs-and-children))) + ((alistp (first attrs-and-children)) + (values (make-attrs :alist (first attrs-and-children)) + (rest attrs-and-children))) + ((listp (first attrs-and-children)) + (values (make-attrs :alist (plist-alist (first attrs-and-children))) + (rest attrs-and-children))) + ((hash-table-p (first attrs-and-children)) + (values (make-attrs :alist (hash-alist (first attrs-and-children))) + (rest attrs-and-children))) + ((keywordp (first attrs-and-children)) + (loop for thing on attrs-and-children by #'cddr + for (k v) = thing + when (keywordp k) + collect (cons k v) into attrs + when (not (keywordp k)) + return (values (make-attrs :alist attrs) thing) + finally (return (values (make-attrs :alist attrs) nil)))) + (t + (values (make-attrs :alist nil) attrs-and-children)))) + +(defun plist-alist (plist) + (loop for (k v) on plist by #'cddr + collect (cons k v))) + +(defun alist-plist* (alist) + (mapcan (lambda (kv) + (list (string-downcase (car kv)) + (cdr kv))) + alist)) + +(defmacro define-builtin-element (element-name) + `(defun ,element-name (&rest attrs-and-children) + (multiple-value-bind (attrs children) (split-attrs-and-chilren attrs-and-children) + (make-element :tag (string-downcase (mkstr ',element-name)) :attrs attrs :children children)))) + +(defmacro define-and-export-builtin-elements (&rest element-names) + `(progn + ,@(mapcan (lambda (e) + (list `(define-builtin-element ,e) + `(export ',e))) + element-names))) + +(define-builtin-elements + a abbr address area article aside audio b base bdi bdo blockquote + body br button canvas caption cite code col colgroup data datalist + dd del details dfn dialog div dl dt em embed fieldset figcaption + figure footer form h1 h2 h3 h4 h5 h6 head header hr html i iframe + img input ins kbd label legend li link main |map| mark meta meter nav + noscript object ol optgroup option output p param picture pre progress + q rp rt ruby s samp script section select small source span strong + style sub summary sup svg table tbody td template textarea tfoot th + thead |time| title tr track u ul var video wbr) + +(defmethod print-object ((attrs attrs) stream) + (if (attrs-alist attrs) + (format stream " ~{~a=~s~^ ~}" (alist-plist* (attrs-alist attrs))) + (format stream ""))) + +(defmethod print-object ((element element) stream) + (format stream "<~a~a>" (element-tag element) (element-attrs element)) + (when (element-children element) + (format stream "~%~<~2I~@{~a~^~:@_~}~:>~%" (element-children element))) + (format stream "~%" (element-tag element))) + +(defmethod print-object ((element element) stream) + (if (element-children element) + (format stream (if (rest (element-children element)) + "~@<<~a~a>~2I~:@_~<~@{~a~^~:@_~}~:>~0I~:@_~:>" + "~@<<~a~a>~2I~:_~<~a~:>~0I~:_~:>") + (element-tag element) + (element-attrs element) + (element-children element) + (element-tag element)) + (format stream "<~a~a>" (element-tag element) (element-attrs element)))) + +;; (defmacro! define-element (name (&rest args) &body body) +;; `(defun ,name (&rest g!attrs-and-children))) diff --git a/src/test.html b/src/test.html new file mode 100644 index 0000000..ce06dac --- /dev/null +++ b/src/test.html @@ -0,0 +1,16 @@ + + + + Page Title + + + +

This is a Heading

+

This is a paragraph.

+ will This + + sdf + + break line + + diff --git a/system-test.asd b/system-test.asd new file mode 100644 index 0000000..04a93bc --- /dev/null +++ b/system-test.asd @@ -0,0 +1,8 @@ +(defsystem flute-test + :author "Your Name " + :license "Specify license here" + :depends-on (:flute) + :components ((:module "t" + :serial t + :components + ((:file "flute"))))) diff --git a/t/flute.lisp b/t/flute.lisp new file mode 100644 index 0000000..8ed673f --- /dev/null +++ b/t/flute.lisp @@ -0,0 +1,4 @@ +(in-package :cl-user) +(defpackage flute.test + (:use :cl)) +(in-package :flute.test)