Skip to content

Instantly share code, notes, and snippets.

@d-t-w
Last active June 27, 2019 02:07
Show Gist options
  • Save d-t-w/9215ec00102393d1e063dfa34877fdf0 to your computer and use it in GitHub Desktop.
Save d-t-w/9215ec00102393d1e063dfa34877fdf0 to your computer and use it in GitHub Desktop.
(ns insta.parse-test
(:require [cljs.test :refer-macros [is]]
[devcards.core :refer-macros [deftest]]
[instaparse.core :as insta :refer-macros [defparser]]))
(insta/defparser parser
(str "<S> = template\n\n<FWS> = #'[ \\t\\r\\n]*'\n\n"
""
"when = <'~='> #'[a-zA-Z0-9\\-]+'\n"
"when-not = <'~!'> #'[a-zA-Z0-9\\-]+'\n"
"repeated = <'~*'>\n\n"
""
"text = #'[^~]*'\n"
"variable = <'~$'> #'[a-zA-Z0-9\\-]+'\n\n"
""
"metadata = (when | when-not | repeated | <FWS>)* <FWS> <\":\">\n"
"script = (variable | text)*\n\n"
""
"<template> = [metadata] <FWS> script"))
(deftest parse-test
(is (= [[:metadata [:repeated] [:when-not "new-customer"] [:when "old-customer"] [:when "high-value"]]
[:script
[:text "Your product "]
[:variable "product"]
[:text " will be shipped to you on "]
[:variable "date-year"]
[:text ", thanks! Cost is $"]
[:variable "au-cost"]
[:text "."]]]
(insta/parse parser "~* ~!new-customer ~=old-customer ~=high-value: Your product ~$product will be shipped to you on ~$date-year, thanks! Cost is $~$au-cost."))))
(defn parse-template
[text]
(let [result (insta/parse parser text)]
(if-not (insta/failure? result)
(let [parsed (into {} (map (juxt first rest) result))]
(assoc parsed :variables (filter #(= :variable (first %))
(:script parsed)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment