Begin work on command line version (cljs)
authorJoel Holdbrooks <cjholdbrooks@gmail.com>
Wed, 14 Aug 2013 01:20:57 +0000 (18:20 -0700)
committerJoel Holdbrooks <cjholdbrooks@gmail.com>
Sat, 17 Aug 2013 21:54:09 +0000 (14:54 -0700)
bin/.gitkeep [new file with mode: 0644]
project.clj
src/clj/frak.clj [moved from src/frak.clj with 89% similarity]
src/cljs/frak/cli.cljs [new file with mode: 0644]

diff --git a/bin/.gitkeep b/bin/.gitkeep
new file mode 100644 (file)
index 0000000..e69de29
index 1f68073c046f7bba92899827a241183cf6c15285..521e26dc2a59a2b6e22d4e207d475d0761067d9a 100644 (file)
@@ -3,6 +3,24 @@
   :url "http://github.com/noprompt/frak"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
-  :dependencies [[org.clojure/clojure "1.4.0"]]
+  :dependencies [[org.clojure/clojure "1.5.1"]]
+  :plugins [[lein-cljsbuild "0.3.2"]]
+  :source-paths ["src/clj"]
   :profiles {:dev {:dependencies [[criterium "0.4.1"]]}}
-  :main frak.cli )
+  :cljsbuild {:crossovers [frak]
+              :crossover-path "crossovers"
+              :crossover-jar true
+              :builds [{:id "dev"
+                        :source-paths ["src/clj" "src/cljs"]
+                        :compiler {:output-to "bin/frak.dev.js"
+                                   :optimizations :simple
+                                   :pretty-print true
+                                   :target :nodejs}}
+                       
+                       {:id "prod"
+                        :source-paths ["src/clj" "src/cljs"]
+                        :compiler {:output-to "bin/frak.prod.js"
+                                   :optimizations :simple
+                                   :pretty-print false
+                                   :target :nodejs}}]}
+  :main frak.cli)
similarity index 89%
rename from src/frak.clj
rename to src/clj/frak.clj
index 44cac86b9408a14d325d575e0919fe14b13d2d9e..928859fdc750da9b751a2f2346ff289abf9d915e 100644 (file)
 (defn pattern
   "Construct a regular expression from a collection of strings."
   ([strs]
-     (pattern strs false))
-  ([strs capture?]
+     (pattern strs {:capture? false, :exact? false}))
+  ([strs opts]
      {:pre [(every? string? strs)]}
-     (binding [*capture* capture?]
-       (-> strs build-trie render-trie str re-pattern))))
+     (let [pattern (binding [*capture* (:capture? opts)]
+                     (-> strs build-trie render-trie str))]
+       (re-pattern (if (:exact? opts)
+                     (str "^" pattern "$")
+                     pattern)))))
diff --git a/src/cljs/frak/cli.cljs b/src/cljs/frak/cli.cljs
new file mode 100644 (file)
index 0000000..478a21e
--- /dev/null
@@ -0,0 +1,52 @@
+(ns frak.cli
+  (:require [clojure.string :as s]
+            [frak]))
+
+(def FLAGS
+  [[["-e" "--exact"] "Generated pattern requires an exact match"]
+   [["-c" "--capture"] "Generated pattern captures"]
+   [["-h" "--help"] "Display this help message"]])
+
+(def flag-re (frak/pattern (mapcat first FLAGS)))
+
+(defn parse-args [args]
+  (split-with #(re-matches flag-re %) args))
+
+(defn flag-val [s]
+  (condp re-seq s
+    #"-(?:e|-exact)" {:exact? true}
+    #"-(?:c|-capture)" {:capture? true}
+    #"-(?:h|-help)" {:help? true}
+    {}))
+
+(defn flags->opts [flags]
+  (reduce
+   (fn [m flag]
+     (merge m (flag-val flag)))
+   {}
+   flags))
+
+(def summary 
+  (reduce
+   (fn [message [flags info]]
+     (format "%s\t%s\t%s\n" message (s/join ", " flags) info))
+   "Usage: frak <flags*> <strings+>\n\n"
+   FLAGS))
+
+(defn exit [code]
+  (.exit js/process code))
+
+(defn help []
+  (println summary)
+  (exit 0))
+
+(defn start
+  [& args]
+  (let [[flags words] (parse-args args)
+        opts (flags->opts flags)]
+    (if (or (empty? args) (:help? opts))
+      (help)
+      (let [pat (str (frak/pattern words opts))]
+        (println (subs pat 1 (dec (count pat))))))))
+
+(set! *main-cli-fn* start)