(define build-code-tokens (fn (expr tokens step-ref indent) (cond (string? expr) (do (append! tokens {:cls "text-emerald-700" :step (get step-ref "v") :text (str "\"" expr "\"")}) (dict-set! step-ref "v" (+ (get step-ref "v") 1))) (number? expr) (do (append! tokens {:cls "text-amber-700" :step (get step-ref "v") :text (str expr)}) (dict-set! step-ref "v" (+ (get step-ref "v") 1))) (= (type-of expr) "keyword") (append! tokens {:cls "text-violet-600" :step (get step-ref "v") :text (str ":" (keyword-name expr))}) (= (type-of expr) "symbol") (let ((name (symbol-name expr))) (append! tokens {:cls (cond (is-html-tag? name) "text-sky-700 font-semibold" (starts-with? name "~") "text-rose-600 font-semibold" :else "text-stone-700") :step (get step-ref "v") :text name})) (list? expr) (when (not (empty? expr)) (let ((head (first expr)) (is-tag (and (= (type-of head) "symbol") (is-html-tag? (symbol-name head)))) (is-comp (and (= (type-of head) "symbol") (starts-with? (symbol-name head) "~"))) (open-step (get step-ref "v"))) (append! tokens {:cls "text-stone-400" :step open-step :text "("}) (build-code-tokens head tokens step-ref indent) (when is-tag (dict-set! step-ref "v" (+ (get step-ref "v") 1))) (for-each (fn (a) (let ((is-child (and (list? a) (not (empty? a)) (= (type-of (first a)) "symbol") (or (is-html-tag? (symbol-name (first a))) (starts-with? (symbol-name (first a)) "~")))) (is-spread (and (list? a) (not (empty? a)) (= (type-of (first a)) "symbol") (starts-with? (symbol-name (first a)) "~")))) (if is-spread (let ((saved (get step-ref "v")) (saved-tokens-len (len tokens))) (append! tokens {:cls "" :step -1 :text " "}) (build-code-tokens a tokens step-ref indent) (let mark-loop ((j saved-tokens-len)) (when (< j (len tokens)) (dict-set! (nth tokens j) "spread" true) (mark-loop (+ j 1)))) (dict-set! step-ref "v" saved)) (if (and is-tag is-child) (do (append! tokens {:cls "" :step -1 :text (str "\n" (join "" (map (fn (_) " ") (range 0 (+ indent 1)))))}) (build-code-tokens a tokens step-ref (+ indent 1))) (do (append! tokens {:cls "" :step -1 :text " "}) (build-code-tokens a tokens step-ref indent)))))) (rest expr)) (append! tokens {:cls "text-stone-400" :step open-step :text ")"}) (when is-tag (dict-set! step-ref "v" (+ (get step-ref "v") 1))))) :else nil)))