diff --git a/src/main/lemondronor/circlebot.cljs b/src/main/lemondronor/circlebot.cljs index 75651cd..d4fcb0d 100644 --- a/src/main/lemondronor/circlebot.cljs +++ b/src/main/lemondronor/circlebot.cljs @@ -274,7 +274,7 @@ (def description-templates (map generation/parse-template - [(str "[{registration}|{registration}, a {type},|{militaryregistration}, a military aircraft,|" + [(str "[{registration}|{registration}, {type|a-an},|{militaryregistration}, a military aircraft,|" "{militaryregistration}, a military {type},|" "Aircraft with unknown registration, ICAO {icao}|" "Military aircraft with unknown registration, ICAO {militaryicao}] " diff --git a/src/main/lemondronor/circlebot/generation.cljc b/src/main/lemondronor/circlebot/generation.cljc index 5024cbe..526d4f9 100644 --- a/src/main/lemondronor/circlebot/generation.cljc +++ b/src/main/lemondronor/circlebot/generation.cljc @@ -14,7 +14,7 @@ sequence = <'['> term+ <']'> optional = <'⁇'> no-ws-term choice = <'['> pattern <'|'> pattern (<'|'> pattern)* <']'> - varref = <'{'> #'[a-zA-Z\\_][a-zA-Z0-9\\-\\_\\.]+' <'}'> + varref = <'{'> #'[a-zA-Z\\_][a-zA-Z0-9\\-\\_\\.\\|]+' <'}'> text = #'[^\\{\\[\\]\\|⁇]+' no-ws-text = #'[^\\{\\[\\]\\|⁇\\s]+' ")) @@ -55,12 +55,43 @@ ;; '() ;; (list {:varrefs [var] :text (str (data var))})))) +(def vowels #{"a" "e" "i" "o" "u"}) + +(defn is-consonant? [c] + (not (vowels (string/lower-case c)))) + +(defn starts-with-consonant? [s] + (is-consonant? (subs s 0 1))) + + +(def filters + {:a-an (fn a-an [s] + (if (starts-with-consonant? s) + (str "a " s) + (str "an " s)))}) + + +(defn apply-filter [s filter-name] + (if (nil? filter-name) + s + (let [filter (filters (keyword filter-name))] + (when-not filter + (throw (js/Error. (str "Unknown filter: " filter-name)))) + (filter s)))) + + +(defn parse-varref [s] + (let [[var filter] (string/split s #"\|" 2)] + {:var (keyword var) :filter filter})) + + (defmethod expand% :varref [template data] - (let [var (keyword (second template)) + (let [varref (second template) + {:keys [var filter]} (parse-varref varref) val (data var)] (if (or (nil? val) (= val "")) '() - (list {:varrefs [var] :text (str (data var))})))) + (list {:varrefs [var] :text (apply-filter (str (data var)) filter)})))) (defmethod expand% :text [template data] (list {:varrefs [] :text (second template)})) diff --git a/src/test/lemondronor/circlebot/generation_test.cljs b/src/test/lemondronor/circlebot/generation_test.cljs index afa0101..4873cbb 100644 --- a/src/test/lemondronor/circlebot/generation_test.cljs +++ b/src/test/lemondronor/circlebot/generation_test.cljs @@ -66,12 +66,28 @@ :locality 2}))))) -(deftest var-paths - (is (= "Hello, John" - (generation/generate - [(generation/parse-template "Hello, {person.name}")] - {:person {:name "John"}}))) - (is (= 9 - (generation/generate - [(generation/parse-template "Hello, {person.name}")] - {:person {:age 49}})))) +(deftest is-consonant + (is (generation/is-consonant? "f")) + (is (generation/is-consonant? "F")) + (is (not (generation/is-consonant? "a"))) + (is (not (generation/is-consonant? "A")))) + + +(deftest filters + (let [templates [(generation/parse-template "It is {thing|a-an}")]] + (is (= "It is a bird" + (generation/generate templates {:thing "bird"}))) + (is (= "It is an animal" + (generation/generate templates {:thing "animal"}))) + (is (= "It is an Animal" + (generation/generate templates {:thing "Animal"}))))) + +;; (deftest var-paths +;; (is (= "Hello, John" +;; (generation/generate +;; [(generation/parse-template "Hello, {person.name}")] +;; {:person {:name "John"}}))) +;; (is (= 9 +;; (generation/generate +;; [(generation/parse-template "Hello, {person.name}")] +;; {:person {:age 49}})))) diff --git a/src/test/lemondronor/circlebot_test.cljs b/src/test/lemondronor/circlebot_test.cljs index 81fb406..9ac125b 100644 --- a/src/test/lemondronor/circlebot_test.cljs +++ b/src/test/lemondronor/circlebot_test.cljs @@ -24,6 +24,7 @@ {:icao "71BE34" :registration "HL7634" :callsign nil + :type "A388" :lon -118.416438 :lat 33.937908 :alt 100 @@ -98,5 +99,8 @@ (is (re-find #"military" (-> (circlebot/expand-template data) :text)))) (let [data {:locality "Palmdale", :continent "North America", :military? true, :alt 3200, :speed "161", :normalized-curviness 15.783422690487765, :accuracy "centroid", :country_a "USA", :continent_gid "whosonfirst:continent:102191575", :name "Palmdale", :squawk "5330", :icao "AE1482", :county_a "LO", :county "Los Angeles County", :source "whosonfirst", :gid "whosonfirst:locality:85923493", :curviness 1098.803548060181, :locality_gid "whosonfirst:locality:85923493", :region "California", :militaryicao "AE1482", :region_a "CA", :nearbydistance 7.828, :callsign "RAIDR49", :layer "locality", :mlat? false, :country_gid "whosonfirst:country:85633793", :label "Palmdale, CA, USA", :id "85923493", :lon -118.049183, :region_gid "whosonfirst:region:85688637", :lat 34.649808, :militaryregistration "166765", :county_gid "whosonfirst:county:102086957", :started-circling-time 1576267564959, :distance 6.336, :source_id "85923493", :registration "166765", :confidence 0.5, :country "United States", :postime 1576267555709, :nearbylandmark "Living Faith Foursquare Church"}] (is (re-find #"military" (-> (circlebot/expand-template data) :text)))) - - ) + (testing "a vs. an for type" + (let [data {:registration "TEST" :type "Airbus 380" :locality "Test City"}] + (is (re-find #"an Airbus" (:text (circlebot/expand-template data))))) + (let [data {:registration "TEST" :type "Yoyo 380" :locality "Test City"}] + (is (re-find #"a Yoyo" (:text (circlebot/expand-template data)))))))