Skip to content

Instantly share code, notes, and snippets.

@niquola
Last active April 15, 2022 22:40
Show Gist options
  • Save niquola/6863ebca41a2a5aa4a334286be6633e1 to your computer and use it in GitHub Desktop.
Save niquola/6863ebca41a2a5aa4a334286be6633e1 to your computer and use it in GitHub Desktop.
(ns hl
(:require [clojure.string :as str]
;; https://github.com/HealthSamurai/macrocss
[stylo.core :refer [c]]
[rewrite-clj.parser :as p]))
(declare node->html)
(def p (c [:text :gray-500]))
(def key-c (c [:text :green-400]))
(def pattern-c (c [:text :blue-300]))
(def nil-c (c [:text :orange-400]))
(def keyname-c (c [:text :pink-300]))
(def core-fn (c [:text :pink-400]))
(def ns-c (c [:text :purple-400]))
(def java-c (c [:text :red-400]))
(defn render-col [node op cl]
(->
(into [:span [:b {:class p} op]]
(->> (:children node)
(mapv node->html)))
(conj [:b {:class p} cl])))
(def keywords #{'defn 'defonce 'when 'let 'defn- 'def 'defmethod 'defmulti 'ns 'cond 'if 'loop 'fn 'try 'catch 'do 'comment})
(defn node->html [{sv :string-value v :value t :tag :as node}]
(cond
(= :list t) (render-col node "(" ")")
(= :vector t) (render-col node "[" "]")
(= :map t) (render-col node "{" "}")
(:k node) [:b {:class key-c} (str (:k node))]
(:newlines node) (:newlines node)
(:whitespace node) (:whitespace node)
(:pattern node) [:span {:class pattern-c} sv]
(= "nil" sv) [:span {:class nil-c} (:string-value node)]
v (cond
(symbol? v)
(cond
(contains? keywords v)
[:b {:class keyname-c} sv]
(contains? (ns-publics 'clojure.core) v)
[:span {:class core-fn} sv]
(namespace v)
[:span [:span {:class ns-c} (namespace v)] "/" [:span (name v)]]
(or (str/starts-with? sv ".") (str/ends-with? sv ".")
(and (re-find #"\." sv) (not (re-find #"/" sv)))))
[:span {:class java-c} sv]
:else
[:span sv])
(number? v)
[:b {:class (c [:text :blue-400])}
(:string-value node)]
(boolean? v)
[:span {:class (c [:text :pink-400])}
(:string-value node)]
:else
(:string-value node))
(:children node) (into [:span] (mapv node->html (:children node)))
(:lines node) [:span {:class (c [:text :yellow-400])} (pr-str (first (:lines node)))]
:else [:b {:class (c [:text :white] [:px 1] [:py 0.5] [:bg :blue-900])} (str node)]))
(defn render [src]
(node->html (p/parse-string-all src)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment