Commits

Steve Losh committed 9680297

Add values, with filters.

Comments (0)

Files changed (2)

src/dram/parser.clj

           (literal-string)))
 
 
+; Paths -----------------------------------------------------------------------
+(defparser path-char []
+  (choice (letter)
+          (digit)
+          (token #{\_ \-})))
+
+(defparser path-segment []
+  (let->> [contents (many1 (path-char))]
+    (always (apply str contents))))
+
+(defparser path []
+  (let->> [seg (path-segment)
+           segs (many (>> (char \.) (path-segment)))]
+    (always (concat [seg] segs))))
+
+
+; Context Values --------------------------------------------------------------
+(defparser value-filter-arg []
+  (choice (literal)
+          (path)))
+
+(defparser value-filter-args []
+  (char \:)
+  (let->> [arg (value-filter-arg)
+           args (many (>> (char \,) (value-filter-arg)))]
+    (always (concat [arg] args))))
+
+(defparser value-filter []
+  (optional-whitespace)
+  (char \|)
+  (optional-whitespace)
+  (let->> [filter-path (path)
+           filter-args (optional (value-filter-args))]
+    (always {:path filter-path
+             :args (or filter-args [])})))
+
+(defparser value []
+  (let->> [base (choice (literal) (path))
+           filters (many (value-filter))]
+    (always {:type :value
+             :base base
+             :filters filters})))
+
+
 ; Variables -------------------------------------------------------------------
 (defparser variable-open []
   (string "{{")
            (tag-guts)))
 
 
-; Paths -----------------------------------------------------------------------
-(defparser path-char []
-  (choice (letter)
-          (digit)
-          (token #{\_ \-})))
-
-(defparser path-segment []
-  (let->> [contents (many1 (path-char))]
-    (always (apply str contents))))
-
-(defparser path []
-  (let->> [seg (path-segment)
-           segs (many (>> (char \.) (path-segment)))]
-    (always (concat [seg] segs))))
-
-
 ; Extends ---------------------------------------------------------------------
 (defparser tag-extends []
   (between (tag-open) (tag-close)
 ; Raw Text --------------------------------------------------------------------
 (defparser raw-text-char []
   (let->> [ch (any-char)
-           nch (lookahead (optional (token (set "%{"))))]
-    (if (and (= (str ch) "{") nch)
+           nch (lookahead (optional (token #{\{ \%})))]
+    (if (and (= ch \{) nch)
       (never)
       (always ch))))
 

test/dram/test/parser.clj

 
     "\"foo\"" "foo"))
 
+(deftest value-test
+  (letfn [(v [base filters]
+            {:type :value :base base :filters filters})
+          (f [path args]
+            {:path path :args args})]
+    (testing-parser
+      (p/value)
+      "A context value's base can be a path or a literal."
+
+      "42"         (v 42 [])
+      "\"foo\""    (v "foo" [])
+      "user.email" (v ["user" "email"] [])
+      "users.0"    (v ["users" "0"] []))
+
+    (testing-parser
+      (p/value)
+      "A context value can be filtered through one or more filters."
+
+      "42|abs"        (v 42 [(f ["abs"] [])])
+      "42|math.floor" (v 42 [(f ["math" "floor"] [])])
+
+      "\"foo\"|reverse|upper"
+      (v "foo" [(f ["reverse"] [])
+                (f ["upper"] [])])
+
+      "\"foo\"|reverse|upper|custom.dogs"
+      (v "foo" [(f ["reverse"] [])
+                (f ["upper"] [])
+                (f ["custom" "dogs"] [])]))
+
+    (testing-parser
+      (p/value)
+      "Filters can take arguments."
+
+      "total|add:extra.widgets"
+      (v ["total"] [(f ["add"] [["extra" "widgets"]])])
+
+      "description|trim:10"
+      (v ["description"] [(f ["trim"] [10])])
+
+      "description|slice:0,30"
+      (v ["description"] [(f ["slice"] [0 30])])
+
+      "user.join-date|date:\"yyyy-mm\",\"est\""
+      (v ["user" "join-date"] [(f ["date"] ["yyyy-mm" "est"])])
+
+      "number_of_cats|pluralize:\"y,ies\""
+      (v ["number_of_cats"] [(f ["pluralize"] ["y,ies"])])
+
+      "foo|join:\",\"|strip:\" ,.{}\"|slice:20,30,2|length"
+      (v ["foo"] [(f ["join"] [","])
+                  (f ["strip"] [" ,.{}"])
+                  (f ["slice"] [20 30 2])
+                  (f ["length"] [])]))))
+
 (deftest variable-test
   (testing-parser
     (p/variable) "Variables can be simple literals."
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.