From 247a1ab9629b0b3e4e33382584d187a7dab5e966 Mon Sep 17 00:00:00 2001 From: paku Date: Sat, 3 Feb 2024 18:46:48 +0900 Subject: [PATCH] Rename flute to piccolo --- README.md | 60 +++++++++++++++--------------- flute-test.asd => piccolo-test.asd | 6 +-- flute.asd => piccolo.asd | 6 +-- src/element-belongs-to.lisp | 2 +- src/package.lisp | 2 +- src/{flute.lisp => piccolo.lisp} | 14 +++---- src/util.lisp | 2 +- t/{flute.lisp => piccolo.lisp} | 14 +++---- 8 files changed, 53 insertions(+), 53 deletions(-) rename flute-test.asd => piccolo-test.asd (58%) rename flute.asd => piccolo.asd (81%) rename src/{flute.lisp => piccolo.lisp} (96%) rename t/{flute.lisp => piccolo.lisp} (98%) diff --git a/README.md b/README.md index 6e2b0e5..5701ac4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Flute +# piccolo -Flute is a beautiful, easily composable HTML5 generation library in Common Lisp. It's +piccolo is a beautiful, easily composable HTML5 generation library in Common Lisp. It's - Simple: the most simplistic syntax, for builtin and customized elements; - Easy to debug: pretty print generated html snippet in REPL; @@ -12,14 +12,14 @@ Flute is a beautiful, easily composable HTML5 generation library in Common Lisp. ## Install and run tests ```lisp -(ql:quickload :flute) -(ql:quickload :flute-test) +(ql:quickload :piccolo) +(ql:quickload :piccolo-test) ``` Then define a new package specifically for HTML generation, in its definition: ```lisp -(defpackage flute-user - (:use :cl :flute)) +(defpackage piccolo-user + (:use :cl :piccolo)) ``` If you don't want to import all symbols, see [H Macro](#h-macro), which provide a similar interface as a tranditional Lisp HTML generation library. @@ -60,11 +60,11 @@ All children will be flattened as if they're given inline. ``` `dog` will be defined as a function that takes `:id` and `:size` keyword arguments. `dog` returns an user-defined element object. Inside it, `children` will be replaced with the children elements you provided when creating this `dog`: ``` -FLUTE-USER> (defparameter *dog1* (dog :id "dog1" :size 20)) +piccolo-USER> (defparameter *dog1* (dog :id "dog1" :size 20)) *DOG1* -FLUTE-USER> *dog1* +piccolo-USER> *dog1*
dog
-FLUTE-USER> (dog :id "dog2" "I am a dog" *) +piccolo-USER> (dog :id "dog2" "I am a dog" *)
I am a dog
dog
@@ -74,14 +74,14 @@ FLUTE-USER> (dog :id "dog2" "I am a dog" *) All elements, both builtin and user defined ones are objects, although they're printed as html snippet in REPL. Their attribute can be accessed by `(element-attrs element)`. Their children can be accessed by `(element-children elements)` and tag name by `(element-tag element)`. You can modify an exising element's attrs and children. If you modify a user defined element, the body you defined in it's `define-element` also re-executed to take effect of the the attrs and children change: ``` -FLUTE-USER> *dog1* +piccolo-USER> *dog1*
dog
-FLUTE-USER> (setf (attr *dog1* :size) 10 - ;; attr is a helper method to set (flute:element-attrs *dog1*) +piccolo-USER> (setf (attr *dog1* :size) 10 + ;; attr is a helper method to set (piccolo:element-attrs *dog1*) (attr *dog1* :id) "dooooog1" (element-children *dog1*) (list "i'm small now")) ("i'm small now") -FLUTE-USER> *dog1* +piccolo-USER> *dog1*
i'm small now dog @@ -90,13 +90,13 @@ FLUTE-USER> *dog1* By default user element is printed as what it expand to. If you have a lot of user defined element nested deeply, you probably want to have a look at the high level: ``` -FLUTE-USER> (let ((*expand-user-element* nil)) +piccolo-USER> (let ((*expand-user-element* nil)) (print *dog1*) (values)) i'm small now ; No value -FLUTE-USER> +piccolo-USER> ``` ## Generate HTML @@ -113,15 +113,15 @@ To generate that and write to file, just create a stream, then `(write element : ## H macro If you don't want to import all the symbols, you can use the `h` macro: ```lisp -(defpackage flute-min +(defpackage piccolo-min (:use :cl) - (:import-from :flute + (:import-from :piccolo :h :define-element)) ``` Then just wrap `h` for all html generation part. In the same examples above, it becomes: ``` lisp -(in-package :flute-min) +(in-package :piccolo-min) (h (html (head (link :rel "...") @@ -138,15 +138,15 @@ Then just wrap `h` for all html generation part. In the same examples above, it (define-element dog (id size) (if (and (realp size) (> size 10)) (h (div :id id :class "big-dog" - flute:children + piccolo:children "dog")) (h (div :id id :class "small-dog" - flute:children + piccolo:children "dog")))) (defparameter *dog2* (dog :id "dog2" :size 20 "some children")) ``` -From version 0.2 (available in Aug 2018 Quicklisp), flute supports css style id and class attribute for builtin elements. For example `div#id-name.class1.class2`, So you can also write: +From version 0.2 (available in Aug 2018 Quicklisp), piccolo supports css style id and class attribute for builtin elements. For example `div#id-name.class1.class2`, So you can also write: ```lisp (h (div#a.b "...")) ;; Provide additional class and attributes @@ -154,7 +154,7 @@ From version 0.2 (available in Aug 2018 Quicklisp), flute supports css style id ``` ## Inline CSS and JavaScript -With help of [cl-css](https://github.com/Inaimathi/cl-css) (available in Quicklisp), You can write inline CSS for the `style` attribute, in a similar syntax like flute: +With help of [cl-css](https://github.com/Inaimathi/cl-css) (available in Quicklisp), You can write inline CSS for the `style` attribute, in a similar syntax like piccolo: ```lisp (div :style (inline-css '(:margin 5px :padding 0px))) ``` @@ -178,12 +178,12 @@ That's all you need to know to define elements and generate html. Please referen # Motivation Currently there're a few HTML generation library in Common Lisp, like [CL-WHO](https://edicl.github.io/cl-who/), [CL-MARKUP](https://github.com/arielnetworks/cl-markup) and [Spinneret](https://github.com/ruricolist/spinneret). They both have good features for generating standard HTML, but not very good at user element (components) that currently widely used in frontend: you need to define all of them as macros and to define components on top of these components, you'll have to make these components more complex macros to composite them. [Spinneret](https://github.com/ruricolist/spinneret) has a `deftag` feature, but `deftag` is still expand to a `defmacro`. -I'd also want to modify the customer component attribute after create it and incorporate it with it's own logic (like the dog size example above), this logic should be any lisp code. This requires provide all element as object, not plain HTML text generation. With this approach, all elements have a same name function to create it, and returns element that you can modify later. These objects are virtual doms and it's very pleasant to write html code and frontend component by just composite element objects as arguments in element creation function calls. Flute's composite feature inspired by [Hiccup](https://github.com/weavejester/hiccup) and [Reagent](https://github.com/reagent-project/reagent) but more powerful -- in flute, user defined elements is real object with attributes and it's own generation logic. +I'd also want to modify the customer component attribute after create it and incorporate it with it's own logic (like the dog size example above), this logic should be any lisp code. This requires provide all element as object, not plain HTML text generation. With this approach, all elements have a same name function to create it, and returns element that you can modify later. These objects are virtual doms and it's very pleasant to write html code and frontend component by just composite element objects as arguments in element creation function calls. piccolo's composite feature inspired by [Hiccup](https://github.com/weavejester/hiccup) and [Reagent](https://github.com/reagent-project/reagent) but more powerful -- in piccolo, user defined elements is real object with attributes and it's own generation logic. # Limitation With the function name approach, it's not possible to support `div.id#class1#class2` style function names. I'm working on some tweak of reader macros in [illusion](https://github.com/ailisp/illusion) library to detect this and convert it to `(div :id "id" :class "class1 class2" ...)` call -The most and major limitation is we don't have a substential subset of Common Lisp in browser so flute can be used in frontend. [Parenscript](https://github.com/vsedach/Parenscript) is essentially a JavaScript semantic in Lisp like syntax. [JSCL](https://github.com/jscl-project/jscl) is promosing, but by now it seems focus on creating a CL REPL on Web and doesn't support `format` or CLOS. Also we lack enough infrastructure to build Common Lisp to JavaScript (might be an asdf plugin) and connect to a browser "Swank" via WebSocket from Emacs. I'll be working these: a full or at least substential subset of Common Lisp to JavaScript Compiler to eventually have a full frontend development environment in Common Lisp. Any help or contribution is welcome. +The most and major limitation is we don't have a substential subset of Common Lisp in browser so piccolo can be used in frontend. [Parenscript](https://github.com/vsedach/Parenscript) is essentially a JavaScript semantic in Lisp like syntax. [JSCL](https://github.com/jscl-project/jscl) is promosing, but by now it seems focus on creating a CL REPL on Web and doesn't support `format` or CLOS. Also we lack enough infrastructure to build Common Lisp to JavaScript (might be an asdf plugin) and connect to a browser "Swank" via WebSocket from Emacs. I'll be working these: a full or at least substential subset of Common Lisp to JavaScript Compiler to eventually have a full frontend development environment in Common Lisp. Any help or contribution is welcome. # API Reference Here is a draft version of API Reference, draft means it will be better organized and moved to a separate HTML doc, but it's content is already quite complete. @@ -239,9 +239,9 @@ The `HTML` element is a little special, it's with `` prefix to ma ;; is defined. ARGS specified the possible keyword ARGS it can take as ;; it's ATTRS. You can either use these ARGS as Lisp arguments in the ;; BODY of its definition and plug in them to the BODY it expand to. -;; You can use FLUTE:CHILDREN to get or set it's children that you give -;; when call function NAME, FLUTE:ATTRS to get or set it's attributes -;; and FLUTE:TAG to get or set it's tag name. +;; You can use piccolo:CHILDREN to get or set it's children that you give +;; when call function NAME, piccolo:ATTRS to get or set it's attributes +;; and piccolo:TAG to get or set it's tag name. ;; Variable *EXPAND-USER-ELEMENT* ;; @@ -312,8 +312,8 @@ The `HTML` element is a little special, it's with `` prefix to ma ;; Macro H &BODY CHILDREN ;; ;; Like a PROGN, except it will replace all html tag SYMBOLs with the same name one -;; in FLUTE PACKAGE, so you don't need to import all of them. As an alternative you -;; can import all or part of html element functions in FLUTE PACKAGE to use them +;; in piccolo PACKAGE, so you don't need to import all of them. As an alternative you +;; can import all or part of html element functions in piccolo PACKAGE to use them ;; without H macro ``` @@ -324,7 +324,7 @@ The `HTML` element is a little special, it's with `` prefix to ma ;; ;; Specify the escape option when generate html, can be :UTF8, :ASCII, :ATTR or NIL. ;; If :UTF8, escape only #\<, #\> and #\& in body, and \" in attribute keys. #\' will -;; in attribute keys will not be escaped since flute will always use double quote for +;; in attribute keys will not be escaped since piccolo will always use double quote for ;; attribute keys. ;; If :ASCII, besides what escaped in :UTF8, also escape all non-ascii characters. ;; If :ATTR, only #\" in attribute values will be escaped. diff --git a/flute-test.asd b/piccolo-test.asd similarity index 58% rename from flute-test.asd rename to piccolo-test.asd index 14cca1b..88b7216 100644 --- a/flute-test.asd +++ b/piccolo-test.asd @@ -1,8 +1,8 @@ -(defsystem flute-test +(defsystem piccolo-test :author "Bo Yao " :license "MIT" - :depends-on (:flute :fiveam) + :depends-on (:piccolo :fiveam) :components ((:module "t" :serial t :components - ((:file "flute"))))) + ((:file "piccolo"))))) diff --git a/flute.asd b/piccolo.asd similarity index 81% rename from flute.asd rename to piccolo.asd index a9bfb80..6141cd7 100644 --- a/flute.asd +++ b/piccolo.asd @@ -1,4 +1,4 @@ -(defsystem flute +(defsystem piccolo :author "Bo Yao " :license "MIT" :version "0.2-dev" @@ -7,11 +7,11 @@ :components ((:file "package") (:file "util") - (:file "flute")))) + (:file "piccolo")))) :description "A beautiful, easilly composable HTML5 generation library" :long-description #.(uiop:read-file-string (uiop:subpathname *load-pathname* "README.md")) - :in-order-to ((test-op (test-op flute-test))) + :in-order-to ((test-op (test-op piccolo-test))) :depends-on (:assoc-utils :let-over-lambda)) diff --git a/src/element-belongs-to.lisp b/src/element-belongs-to.lisp index 96779c4..b8a4969 100644 --- a/src/element-belongs-to.lisp +++ b/src/element-belongs-to.lisp @@ -1,4 +1,4 @@ -(in-package :flute) +(in-package :piccolo) (defparameter *attribute-belongs-to* '((accept input) diff --git a/src/package.lisp b/src/package.lisp index 6a46763..f04bf72 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -1,5 +1,5 @@ (in-package :cl-user) -(defpackage flute +(defpackage piccolo (:use :cl) (:import-from :assoc-utils :alist diff --git a/src/flute.lisp b/src/piccolo.lisp similarity index 96% rename from src/flute.lisp rename to src/piccolo.lisp index 5037d64..2edaeb1 100644 --- a/src/flute.lisp +++ b/src/piccolo.lisp @@ -1,4 +1,4 @@ -(in-package :flute) +(in-package :piccolo) (defclass element () ((tag :initarg :tag @@ -42,7 +42,7 @@ (defvar *escape-html* :utf8 "Specify the escape option when generate html, can be :UTF8, :ASCII, :ATTR or NIL. If :UTF8, escape only #\<, #\> and #\& in body, and \" in attribute keys. #\' will -in attribute keys will not be escaped since flute will always use double quote for +in attribute keys will not be escaped since piccolo will always use double quote for attribute keys. If :ASCII, besides what escaped in :UTF8, also escape all non-ascii characters. If :ATTR, only #\" in attribute values will be escaped. @@ -182,26 +182,26 @@ When given :ASCII and :ATTR, it's possible to insert html text as a children, e. (html-element-p x) (multiple-value-bind (name id class) (collect-id-and-class x) (if (or id class) - (make-!expanded :list (list (find-symbol (string-upcase name) :flute) + (make-!expanded :list (list (find-symbol (string-upcase name) :piccolo) (coerce (append (when id (list :id id)) (when class (list :class class))) 'vector))) - (find-symbol (string-upcase name) :flute)))))) + (find-symbol (string-upcase name) :piccolo)))))) ;;; Experimental ;; (when (find :illusion *features*) ;; (illusion:set-paren-reader -;; :flute +;; :piccolo ;; #'html-element-p ;; (lambda (stream indicator) ;; (multiple-value-bind (name id class) (collect-id-and-class indicator) ;; (if (or id class) -;; (list* (find-symbol (string-upcase name) :flute) +;; (list* (find-symbol (string-upcase name) :piccolo) ;; (coerce (append (when id (list :id)) ;; (when class (list :class class))) ;; 'vector) ;; (illusion:cl-read-list stream)) -;; (cons (find-symbol (string-upcase name) :flute) +;; (cons (find-symbol (string-upcase name) :piccolo) ;; (illusion:cl-read-list stream))))))) (defmethod element-string ((element element)) diff --git a/src/util.lisp b/src/util.lisp index b3bf036..3bdbf3c 100644 --- a/src/util.lisp +++ b/src/util.lisp @@ -1,4 +1,4 @@ -(in-package :flute) +(in-package :piccolo) (defun plist-alist (plist) (loop for (k v) on plist by #'cddr diff --git a/t/flute.lisp b/t/piccolo.lisp similarity index 98% rename from t/flute.lisp rename to t/piccolo.lisp index 4257cb7..5812102 100644 --- a/t/flute.lisp +++ b/t/piccolo.lisp @@ -1,7 +1,7 @@ (in-package :cl-user) -(defpackage flute.test - (:use :cl :flute :fiveam)) -(in-package :flute.test) +(defpackage piccolo.test + (:use :cl :piccolo :fiveam)) +(in-package :piccolo.test) (def-suite builtin-element) (def-suite escape) @@ -336,19 +336,19 @@ (in-suite h-macro) (in-package :cl-user) -(defpackage flute.h-macro.test +(defpackage piccolo.h-macro.test (:use :cl :fiveam) - (:import-from :flute + (:import-from :piccolo :h :element-string :define-element)) -(in-package :flute.h-macro.test) +(in-package :piccolo.h-macro.test) (define-element duck (id color) (h (div :id (format nil "duck~a" id) :style (format nil "color:~a" color) "ga ga ga" - flute:children))) + piccolo:children))) (test h-macro (let ((some-var 3))