diff --git a/README.md b/README.md
index bc6cdc7..bb23915 100644
--- a/README.md
+++ b/README.md
@@ -318,7 +318,7 @@ Only vectors beginning with keywords are interpreted as elements. A vector can s
```clojure
;; Not elements
-(c/html [0 1 2]) ; => "123"
+(c/html [0 1 2]) ; => "012"
(c/html ["foo" "bar"]) ; => "foobar"
(c/html ^::c/content [:foo :bar]) ; => "foobar"
@@ -424,7 +424,7 @@ Use `token-serializer` and `html-serializer` to access individual tokens and fra
### DOCTYPE
-Use `doctype-html5`. It's just a RawString wrapping ``. Because it's a RawString, it is safe to wrap in a vector to concatenate with the rest of the HTML document.
+Use `c/doctype-html5`. It's just a RawString wrapping ``. Because it's a RawString, it is safe to wrap in a vector to concatenate with the rest of the HTML document.
```clojure
(c/html [c/doctype-html5 [:html "..."]])
@@ -434,7 +434,7 @@ Use `doctype-html5`. It's just a RawString wrapping ``. Because i
###
-Use the `nbsp` constant.
+Use the `c/nbsp` constant.
```clojure
(c/html [:div "foo" c/nbsp "bar"])
@@ -687,25 +687,26 @@ Functions calls, and generally any list values, block compilation traversal. Cal
### Alias Elements
-Alias elements are implemented as `c/resolve-alias` function calls. As a result, they also block compilation. However, the arguments pass to `c/resolve-alias` will be compiled.
+Alias elements are implemented as `c/resolve-alias` (via `c/resolve-alias-with-meta`) function calls. As a result, they also block compilation. However, the arguments pass to `c/resolve-alias` will be compiled.
```clojure
-(defmethod c/resolve-alias ::FooComp
+(defmethod c/resolve-alias ::CompileMyAlias
[_ attrs content]
[:div attrs content])
-(pprint (clojure.walk/macroexpand-all
+(pprint
+ (clojure.walk/macroexpand-all
'(cc/compile
- [::FooComp {:foo "bar"}
+ [::CompileMyAlias {:foo "bar"}
[:p "content 1"]
[:p "content 2"]])))
;; Results in:
-(dev.onionpancakes.chassis.core/resolve-alias
+(dev.onionpancakes.chassis.core/resolve-alias-with-meta
nil
- :user/FooComp
+ :user/CompileMyAlias
{:foo "bar"}
- [#object[dev.onionpancakes.chassis.core.RawString 0x2da06c23 "
content 1
content 2
"]])
+ [#object[dev.onionpancakes.chassis.core.RawString 0x34e3a7d6 "content 1
content 2
"]])
```
### Macro Calls
@@ -714,22 +715,22 @@ Macros are expanded during compilation. Like function calls, those which expand
```clojure
(pprint
- (cc/compile
- [:ol
- (for [i (range 4)]
- [:li i])]))
+ (cc/compile
+ [:ol
+ (for [i (range 4)]
+ [:li i])]))
;; Results in:
-[[#object[dev.onionpancakes.chassis.core.OpeningTag 0xe119f5b ""]
+[[#object[dev.onionpancakes.chassis.core.OpeningTag 0x6e462cc4 ""]
([:li 0] [:li 1] [:li 2] [:li 3])]
- #object[dev.onionpancakes.chassis.core.RawString 0x7a434ee8 "
"]]
+ #object[dev.onionpancakes.chassis.core.RawString 0x27b55932 "
"]]
;; Manually call compile in the inner form to reach inside.
(pprint
- (cc/compile
- [:ol
- (for [i (range 4)]
- (cc/compile [:li i]))]))
+ (cc/compile
+ [:ol
+ (for [i (range 4)]
+ (cc/compile [:li i]))]))
```
Macros which expand into non-lists can participate in compilation. Therefore, it is possible to use macros to abstract element components in a compile friendly way.
diff --git a/src/dev/onionpancakes/chassis/core.clj b/src/dev/onionpancakes/chassis/core.clj
index 6d1f51f..54cfcaf 100644
--- a/src/dev/onionpancakes/chassis/core.clj
+++ b/src/dev/onionpancakes/chassis/core.clj
@@ -1,13 +1,13 @@
(ns dev.onionpancakes.chassis.core)
(defprotocol AttributeValue
- (append-attribute-fragment-to [this sb attr-name] "Appends attribute key and value html fragment."))
+ (append-attribute-fragment-to [this sb attr-name] "Appends attribute key and value HTML fragment."))
(defprotocol AttributeValueFragment
- (^String attribute-value-fragment [this] "Returns attribute value fragment string or nil if none."))
+ (^String attribute-value-fragment [this] "Returns attribute value HTML fragment or nil if none."))
(defprotocol Token
- (append-fragment-to [this sb] "Appends html fragment.")
+ (append-fragment-to [this sb] "Appends HTML fragment.")
(^String fragment [this] "Returns HTML fragment."))
(defprotocol Node
@@ -27,15 +27,16 @@
;; - DFS is implemented using a stack of Iterators. (java.util.Deque)
;; Note that head of stack is held by loop binding rather than the actual head of stack.
;; - Node children returns a value that is as flat as possible
-;; to minimized the depth of search (size of Deque).
-;; See the count varying node-children-n implementations
+;; to minimize the depth of search (size of Deque).
+;; See the varying element-children-n implementations.
;; - Iterables returned by Node children should prefer implementations
;; that are internally indexes to arrays.
;; Iterators over Vectors are fast, Iterators over Seqs are not as fast.
-;; - DFS emits a minimum number of Tokens. Therefore Node children emits
+;; - DFS emits minimum number of Tokens. Therefore Node children return
;; OpeningTag and ClosingTag types as "fat" tokens capturing the bracket,
;; tag name, and tag attributes data into one Token instance.
-;; - Coalesce appends in large chunks showed 20% performance boost compared to
+;; - Coalescing appends in large chunks showed 25% performance boost
+;; (the dev example dropped from 500us to 400us) when compared to
;; to fragmented appends. Interleaving appends with branches and computation
;; is detrimental. Therefore, the code is structured like a decision
;; tree so the branches and computation happens early and the appends are