(define split-tag
  (fn
    (expr result)
    (cond
      (not (list? expr))
      (append! result {:expr expr :type "leaf"})
      (empty? expr)
      nil
      (not (= (type-of (first expr)) "symbol"))
      (append! result {:expr expr :type "leaf"})
      (is-html-tag? (symbol-name (first expr)))
      (let
        ((ctag (symbol-name (first expr)))
          (cargs (rest expr))
          (cch (list))
          (cat (list))
          (spreads (list))
          (ckw false))
        (for-each
          (fn
            (a)
            (cond
              (= (type-of a) "keyword")
              (do (set! ckw true) (append! cat a))
              ckw
              (do (set! ckw false) (append! cat a))
              (and
                (list? a)
                (not (empty? a))
                (= (type-of (first a)) "symbol")
                (starts-with? (symbol-name (first a)) "~"))
              (do (set! ckw false) (append! spreads a))
              :else (do (set! ckw false) (append! cch a))))
          cargs)
        (append! result {:spreads spreads :tag ctag :type "open" :attrs cat})
        (for-each (fn (c) (split-tag c result)) cch)
        (append! result {:open-attrs cat :open-spreads spreads :tag ctag :type "close"}))
      :else (append! result {:expr expr :type "expr"}))))
