Skip to content

Commit

Permalink
tidying up the docs
Browse files Browse the repository at this point in the history
  • Loading branch information
onionpancakes committed Feb 24, 2024
1 parent 510261f commit 84f9abc
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 27 deletions.
41 changes: 21 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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 `<!DOCTYPE html>`. 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 `<!DOCTYPE html>`. 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 "..."]])
Expand All @@ -434,7 +434,7 @@ Use `doctype-html5`. It's just a RawString wrapping `<!DOCTYPE html>`. Because i

### &amp;nbsp;

Use the `nbsp` constant.
Use the `c/nbsp` constant.

```clojure
(c/html [:div "foo" c/nbsp "bar"])
Expand Down Expand Up @@ -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 "<p>content 1</p><p>content 2</p>"]])
[#object[dev.onionpancakes.chassis.core.RawString 0x34e3a7d6 "<p>content 1</p><p>content 2</p>"]])
```

### Macro Calls
Expand All @@ -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 "<ol>"]
[[#object[dev.onionpancakes.chassis.core.OpeningTag 0x6e462cc4 "<ol>"]
([:li 0] [:li 1] [:li 2] [:li 3])]
#object[dev.onionpancakes.chassis.core.RawString 0x7a434ee8 "</ol>"]]
#object[dev.onionpancakes.chassis.core.RawString 0x27b55932 "</ol>"]]

;; 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.
Expand Down
15 changes: 8 additions & 7 deletions src/dev/onionpancakes/chassis/core.clj
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -27,15 +27,16 @@
;; - DFS is implemented using a stack of Iterators. (java.util.Deque<Iterator>)
;; 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
Expand Down

0 comments on commit 84f9abc

Please sign in to comment.