Skip to content

Commit

Permalink
Added: RUM support
Browse files Browse the repository at this point in the history
Added: --styles-as-vector option
  • Loading branch information
madvas committed May 15, 2016
1 parent e871d32 commit c9ca459
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 46 deletions.
10 changes: 6 additions & 4 deletions README.md
Expand Up @@ -4,7 +4,7 @@
**Search no more!**


This is command utility and library to **convert JSX snippets to Om/Reagent Clojurescript-style format.**
This is command utility and library to **convert JSX snippets to Om/Reagent/Rum Clojurescript-style format.**
Note, this is by no means to be perfect JS->Cljs compiler, output will often still need touch of your loving
hand, but, hey, most of dirty work will be done :sunglasses:

Expand All @@ -18,7 +18,7 @@ npm install -g jsx-to-clojurescript
```
**As library:**
```
[jsx-to-clojurescript "0.1.7"]
[jsx-to-clojurescript "0.1.8"]
```
**As [Alfred](https://www.alfredapp.com/) workflow (Mac only):**

Expand Down Expand Up @@ -50,15 +50,17 @@ jsx-to-clojurescript -h

-h, --help output usage information
-V, --version output the version number
-t --target [target] Target library (om/reagent). Default om
-t --target [target] Target library (om/reagent/rum). Default om
--ns [string] Namespace for compoments. Default ui
--dom-ns [ns] Namespace for DOM compoments. Default dom
--lib-ns [ns] Target library ns. Default for Om: 'om'. Default for reagent: 'r'
--lib-ns [ns] Target library ns. Default for Om: 'om'. Default for reagent & rum: 'r'
--kebab-tags Convert tags to kebab-case?
--kebab-attrs Convert attributes to kebab-case?
--camel-styles Keep style keys as camelCase
--remove-attr-vals Remove attribute values?
--omit-empty-attrs Omit empty attributes?
--styles-as-vector Keep multiple styles as vector instead of merge


```

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "jsx-to-clojurescript",
"version": "0.1.7",
"version": "0.1.8",
"description": "Command and library to convert JSX snippets to Om/Reagent or other Clojurescript-style format.",
"bin": {
"jsx-to-clojurescript": "jsx-to-clojurescript.js"
Expand Down
2 changes: 1 addition & 1 deletion project.clj
@@ -1,4 +1,4 @@
(defproject jsx-to-clojurescript "0.1.7"
(defproject jsx-to-clojurescript "0.1.8"
:description "Command and library to convert JSX snippets to Om/Reagent or other Clojurescript-style format."
:url "https://github.com/madvas/jsx-to-clojurescript"
:dependencies [[org.clojure/clojure "1.8.0"]
Expand Down
6 changes: 4 additions & 2 deletions src/jsx_to_cljs/cmd.cljs
Expand Up @@ -15,15 +15,16 @@
(version "0.1.0")
(description "Converts JSX string into selected Clojurescript React library format")
(usage "[options] <string>")
(option "-t --target [target]" "Target library (om/reagent). Default om" #"(om|reagent)$" "om")
(option "-t --target [target]" "Target library (om/reagent/rum). Default om" #"(om|reagent|rum)$" "om")
(option "--ns [string]" "Namespace for compoments. Default ui" "ui")
(option "--dom-ns [ns]" "Namespace for DOM compoments. Default dom" "dom")
(option "--lib-ns [ns]" "Target library ns. Default for Om: 'om'. Default for reagent: 'r'")
(option "--lib-ns [ns]" "Target library ns. Default for Om: 'om'. Default for reagent & rum: 'r'")
(option "--kebab-tags" "Convert tags to kebab-case?")
(option "--kebab-attrs" "Convert attributes to kebab-case?")
(option "--camel-styles" "Keep style keys as camelCase")
(option "--remove-attr-vals" "Remove attribute values?")
(option "--omit-empty-attrs" "Omit empty attributes?")
(option "--styles-as-vector" "Keep multiple styles as vector instead of merge")
(parse argv))

(defn default-lib-ns [opts]
Expand All @@ -32,6 +33,7 @@
(condp = (:target opts)
"om" "om"
"reagent" "r"
"rum" "r"
nil)
(if (s/blank? lib-ns) nil lib-ns)))))

Expand Down
86 changes: 48 additions & 38 deletions src/jsx_to_cljs/core.cljs
Expand Up @@ -13,14 +13,28 @@
[(dissoc attrs attr-name) (str tag-suffix s)]
[attrs tag-suffix]))

(defn ^:private replace-set-state-calls [attrs new-call]
(defn ^:private replace-set-state-calls [attrs new-call-ns new-call]
(w/postwalk (fn [x]
(if (and (seq? x)
(symbol? (first x))
(= (-> (first x) name cs/->kebab-case) "set-state"))
(concat `(~new-call ~'this) (rest x))
(concat `(~(symbol new-call-ns new-call) ~'this) (rest x))
x)) attrs))

(defn ^:private reagentize-el [tag attrs children dom-tag? {:keys [omit-empty-attrs kebab-attrs lib-ns]}]
(let [id (get attrs :id)
class-attr-name (if kebab-attrs :class-name :className)
class-name (get attrs class-attr-name)
[attrs tag-suffix] (-> [attrs ""]
(move-attr->tag-suffix :id (str "#" id))
(move-attr->tag-suffix class-attr-name (u/join-classes class-name)))
tag (if dom-tag? (-> tag name (str tag-suffix) keyword)
tag)]
(cond-> [tag]
(or (not omit-empty-attrs)
(seq attrs)) (conj (replace-set-state-calls attrs lib-ns 'set-state))
true (concat children))))

(defprotocol TargetLibrary
(element [this tag attrs children dom-tag? node opts]))

Expand All @@ -29,24 +43,19 @@
(element [_ tag attrs children _ _ {:keys [omit-empty-attrs lib-ns]}]
(cond-> `(~tag)
(or (not omit-empty-attrs)
(seq attrs)) (concat [(replace-set-state-calls attrs (symbol lib-ns 'set-state!))])
(seq attrs)) (concat [(replace-set-state-calls attrs lib-ns 'set-state!)])
true (concat children))))

(defrecord Reagent []
TargetLibrary
(element [_ tag attrs children dom-tag? _ {:keys [omit-empty-attrs kebab-attrs lib-ns]}]
(let [id (get attrs :id)
class-attr-name (if kebab-attrs :class-name :className)
class-name (get attrs class-attr-name)
[attrs tag-suffix] (-> [attrs ""]
(move-attr->tag-suffix :id (str "#" id))
(move-attr->tag-suffix class-attr-name (u/join-classes class-name)))
tag (if dom-tag? (-> tag name (str tag-suffix) keyword)
tag)]
(into [] (cond-> [tag]
(or (not omit-empty-attrs)
(seq attrs)) (conj (replace-set-state-calls attrs (symbol lib-ns 'set-state)))
true (concat children))))))
(element [_ tag attrs children dom-tag? _ opts]
(into [] (reagentize-el tag attrs children dom-tag? opts))))

(defrecord Rum []
TargetLibrary
(element [_ tag attrs children dom-tag? _ opts]
(let [f (if dom-tag? vec identity)]
(f (reagentize-el tag attrs children dom-tag? opts)))))

(defmulti ast-node (fn [type node target opts] type))

Expand Down Expand Up @@ -115,11 +124,14 @@
(defmethod ast-node "Program" [& args]
(remove-excess-do (apply create-do-form args)))

(defmethod ast-node "JSXAttribute" [_ {:keys [name value]} _ _]
(defmethod ast-node "JSXAttribute" [_ {:keys [name value]} _ {:keys [styles-as-vector]}]
(let [value (if (and (= name "style")
(vector? value))
(with-meta (concat '(merge) value)
{:type :styles-merge})
(with-meta
(if-not styles-as-vector
(concat '(merge) value)
value)
{:type :styles-merge})
value)]
{(keyword name) value}))

Expand Down Expand Up @@ -239,33 +251,29 @@

(def jsx->om (partial jsx->target (Om.)))
(def jsx->reagent (partial jsx->target (Reagent.)))
(def jsx->rum (partial jsx->target (Rum.)))

(defmulti transform-jsx (fn [target-str & _] target-str))

(defmethod transform-jsx "om"
[_ & args]
(apply jsx->om args))

(defmethod transform-jsx "reagent"
[_ & args]
(apply jsx->reagent args))
(defmethod transform-jsx "om" [_ & args] (apply jsx->om args))
(defmethod transform-jsx "reagent" [_ & args] (apply jsx->reagent args))
(defmethod transform-jsx "rum" [_ & args] (apply jsx->rum args))


; Don't have tests yet, this is temporary to try out in REPL
(comment
(jsx->om t0)
(jsx->reagent t1 opts)
(jsx->om t2 opts)
(jsx->reagent t2 opts)
(jsx->rum t2 opts)
(jsx->rum t3 opts)
(jsx->om t3 opts)
(jsx->reagent t3 opts)
(jsx->om t4 opts)
(jsx->reagent t4 opts)
(jsx->reagent t5 opts)
(jsx->om t5 opts)
(jsx->om t6 opts)
(jsx->rum t6 opts)
(jsx->om t8 opts)
(jsx->om t9 opts)
(jsx->rum t9 opts)
(jsx->om t10 opts)
(jsx->reagent t11 opts)
(jsx->om t12 opts)
Expand All @@ -274,22 +282,22 @@
(jsx->reagent t15 opts)
(jsx->om t16 opts)
(jsx->reagent t17 opts)
(jsx->reagent t18 opts)
(jsx->rum t18 opts)
(jsx->reagent t19 opts)
(jsx->reagent t20 opts)
(jsx->rum t20 opts)
(jsx->reagent t21 opts)
(jsx->reagent t22 opts)
(jsx->rum t22 opts)
(jsx->reagent t23 opts)
(jsx->om t24 opts)
(jsx->reagent t25 opts)
(jsx->om t26 opts)
(jsx->reagent t27 opts)
(jsx->reagent t28 opts)
(jsx->rum t28 opts)
(jsx->reagent t29 opts)
(jsx->om t30 opts)
(jsx->om t31 opts)
(jsx->rum t31 opts)
(jsx->om t32 opts)
(jsx->om t33 opts)
(jsx->rum t33 opts)
(jsx->ast t33))

(comment
Expand Down Expand Up @@ -327,13 +335,15 @@
(def t31 "function _onPress(someParam, someOther) {\n // Animate the update\n var a = 1;\n LayoutAnimation.spring();\n this.setState({w: this.state.w + 15, h: this.state.h + 15})\n }")
(def t32 "var leftStyle = this.state.index === 0 ? {flex: 1} : {width: 20};\n var middleStyle = this.state.index === 2 ? {width: 20} : {flex: 1};")
(def t33 "const myConst = {some: 34};\n\nfunction explode(size) {\n\tvar earth = \"planet\";\n\tvar foo = \"bar\";\n\treturn boom(earth) * size + myConst;\n}\n\nexplode(42);")
(def t34 "function isDropZone(gesture){ //Step 2\n var dz = this.state.dropZoneValues;\n return gesture.moveY > dz.y && gesture.moveY < dz.y + dz.height;\n }")
(def opts {:ns "u"
:dom-ns "d"
:kebab-tags true
:kebab-attrs true
:camel-styles true
:remove-attr-vals false
:omit-empty-attrs true
:lib-ns "lib"})))
:lib-ns "lib"
:styles-as-vector true})))


0 comments on commit c9ca459

Please sign in to comment.