diff options
Diffstat (limited to 'src/guff/template.cr')
-rw-r--r-- | src/guff/template.cr | 66 |
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 |