aboutsummaryrefslogtreecommitdiff
path: root/src/guff/template.cr
diff options
context:
space:
mode:
Diffstat (limited to 'src/guff/template.cr')
-rw-r--r--src/guff/template.cr66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/guff/template.cr b/src/guff/template.cr
new file mode 100644
index 0000000..01a4c86
--- /dev/null
+++ b/src/guff/template.cr
@@ -0,0 +1,66 @@
+module Guff
+ class Template
+ getter :string
+
+ def initialize(@string : String)
+ @tokens = scan(@string)
+ @has_keys = @tokens.select { |t| t.type == :key }.size > 0
+ end
+
+ def run(args = nil : Hash(String, String)?) : String
+ if @has_keys
+ # check template args
+ if args || args.size == 0
+ raise "missing template args: %s" % [@tokens.select { |t|
+ t.type == :key
+ }.join(", ")]
+ end
+
+ # build result
+ String.builder do |r|
+ @tokens.each do |t|
+ r << t.get(args)
+ end
+ end
+ else
+ # no keys, return literal string
+ @string
+ end
+ end
+
+ SCAN_RE = %r{
+ # match key
+ (?:%\{(?<key>[^\}]+)\})
+
+ |
+
+ # match literal value
+ (?<val>[^%]+)
+
+ |
+
+ # match literal percent
+ (?<pct>%)
+ }mx
+
+ private def scan(s : String)
+ r = [] of TemplateToken
+
+ s.scan(SCAN_RE) do |md|
+ if md["key"]?
+ r << TemplateToken.new(:key, md["key"].strip)
+ elsif md["val"]?
+ r << TemplateToken.new(:val, md["val"])
+ elsif md["pct"]?
+ r << TemplateToken.new(:val, "%")
+ else
+ # never reached
+ raise "unknown match: #{md}"
+ end
+ end
+
+ # return result
+ r
+ end
+ end
+end