Skip to content

Instantly share code, notes, and snippets.

@dupuchba
Forked from seltzer1717/parsehtml.clj
Created October 24, 2017 16:00
Show Gist options
  • Save dupuchba/5d0ad5f69d02d43d83400173cca5cc8a to your computer and use it in GitHub Desktop.
Save dupuchba/5d0ad5f69d02d43d83400173cca5cc8a to your computer and use it in GitHub Desktop.
Converts Bootstrap HTML to ClojureScript Om Code
;; Converts Bootstrap HTML into ClojureScript Om code
;; Formats output as well
;; Useful when you want to mock a Bootstrap layout but then convert to ClojureScript Om code.
(ns com.seltzer1717.term.server.parsehtml
(:import
(java.io
FileReader
FileWriter
BufferedReader
BufferedWriter)
(javax.swing.text.html
HTMLEditorKit
HTMLEditorKit$ParserCallback
HTML$Tag
HTML$UnknownTag
HTML$Attribute)
(javax.swing.text.html.parser ParserDelegator)))
(defn convert [in out]
(let [buff-reader (BufferedReader. (FileReader. in))
buff-writer (BufferedWriter. (FileWriter. out))
indent-size (atom 0)
indentation (char-array " ")
tag-text (atom "")
start-tag (fn [tag]
(if (not= "HTML" (.toUpperCase (.toString tag)))
(do (.newLine buff-writer)
(.write buff-writer indentation 0 @indent-size)))
(->> tag
(.toString)
(.toLowerCase)
(str "(dom/")
(.write buff-writer))
(swap! indent-size + 2))
attr-print (fn [atts]
(let [att-names (.getAttributeNames atts)
size (atom (.getAttributeCount atts))]
(.newLine buff-writer)
(.write buff-writer indentation 0 @indent-size)
(.write buff-writer "#js{")
(swap! indent-size + 4)
(while (.hasMoreElements att-names)
(let [att-name (.nextElement att-names)
name-adj (if (= "class" (.toString att-name)) "className" att-name)
att-value (.getAttribute atts att-name)]
(.write buff-writer (str ":" name-adj " " "\"" att-value "\""))
(swap! size dec)
(if (pos? @size)
(do (.newLine buff-writer)
(.write buff-writer indentation 0 @indent-size)))))
(.write buff-writer "}")
(swap! indent-size - 4)))
callback (proxy [HTMLEditorKit$ParserCallback] []
(handleComment [chars pos]
(if (not (.isEmpty (.trim (String. chars))))
(do (.newLine buff-writer)
(.write buff-writer indentation 0 @indent-size)
(.write buff-writer ";; ")
(.write buff-writer (.trim (String. chars))))))
(handleEndTag [tag pos]
(if (not (.isEmpty (.trim @tag-text)))
(do (.newLine buff-writer)
(.write buff-writer indentation 0 @indent-size)
(.write buff-writer (str "\"" (.trim @tag-text) "\""))))
(swap! tag-text (constantly ""))
(.write buff-writer ")")
(swap! indent-size - 2))
(handleError [msg pos])
(handleSimpleTag [tag atts pos]
(let [tag-name (.toString tag)
newtag? (contains? #{"label" "button" "nav"} (.toString tag-name))
endtag? (= "true" (.getAttribute atts HTML$Attribute/ENDTAG))]
(if newtag?
(if endtag?
(do (if (not (.isEmpty (.trim @tag-text)))
(do (.newLine buff-writer)
(.write buff-writer indentation 0 @indent-size)
(.write buff-writer (str "\"" (.trim @tag-text) "\""))))
(swap! tag-text (constantly ""))
(.write buff-writer ")")
(swap! indent-size - 2))
(do (start-tag tag)
(attr-print atts)))
(do (start-tag tag)
(attr-print atts)
(if (not (.isEmpty (.trim @tag-text)))
(do (.newLine buff-writer)
(.write buff-writer indentation 0 @indent-size)
(.write buff-writer (str "\"" (.trim @tag-text) "\""))))
(swap! tag-text (constantly ""))
(swap! indent-size - 2)
(.write buff-writer ")")))))
(handleStartTag [tag atts pos]
(start-tag tag)
(attr-print atts))
(handleText [chars pos]
(swap! tag-text str (String. chars))))
parser (ParserDelegator.)]
(.parse parser buff-reader callback true)
(.flush buff-writer)
(.close buff-writer)
(.close buff-reader)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment