Skip to content

Commit 52c446e

Browse files
committed
Merge pull request #6 from MakeNowJust/version/2.0.0
Release version 2.0.0
2 parents fda3159 + ce8a2d6 commit 52c446e

16 files changed

Lines changed: 576 additions & 416 deletions

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## v2.0.0 (2016-02-09)
2+
3+
Features:
4+
5+
- Support compile time template parsing.
6+
- Added `Crustache::parse_file_static` to parse Mustache file on compile time.
7+
- Added `Crustache::loader` to create `FileSystem` object to use `Crustache::Engine`.
8+
- Added `Crustache::loader_static`, it is compile time version of `Crustache::loader`.
9+
10+
Changes:
11+
12+
- Add type annotation to class constructors for Crystal next compiler.
13+
114
## v1.0.2 (2016-01-13)
215

316
Changes:

shard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: crustache
2-
version: 1.0.2
2+
version: 2.0.0
33

44
authors:
55
- TSUYUSATO Kitsune <make.just.on@gmail.com>

spec/crustache_spec.cr

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,62 @@ describe Crustache do
1919

2020
describe "#parse_file" do
2121
it "should parse a file" do
22-
Crustache.parse_file("#{__DIR__}/view/template.mustache").should be_truthy
22+
tmpl = Crustache.parse_file("#{__DIR__}/view/template.mustache")
23+
tmpl.should be_a Crustache::Template
24+
end
25+
end
26+
27+
describe "#parse_file_static" do
28+
it "should parse a file on compile time" do
29+
tmpl = Crustache.parse_file_static("#{__DIR__}/view/template.mustache")
30+
tmpl.should be_a Crustache::Template
31+
end
32+
end
33+
34+
describe "#loader" do
35+
it "should create loader object" do
36+
loader = Crustache.loader "#{__DIR__}/view/"
37+
38+
loader.load("template").should be_a Crustache::Template
39+
loader.load("template.mustache").should be_a Crustache::Template
40+
loader.load("template_html").should be_a Crustache::Template
41+
loader.load("template_html.html").should be_a Crustache::Template
42+
loader.load("template_test").should be_a Crustache::Template
43+
loader.load("template_test.html").should be_a Crustache::Template
44+
end
45+
46+
it "should create loader object" do
47+
loader = Crustache.loader "#{__DIR__}/view"
48+
49+
loader.load("template").should be_a Crustache::Template
50+
loader.load("template.mustache").should be_a Crustache::Template
51+
loader.load("template_html").should be_a Crustache::Template
52+
loader.load("template_html.html").should be_a Crustache::Template
53+
loader.load("template_test").should be_a Crustache::Template
54+
loader.load("template_test.html").should be_a Crustache::Template
55+
end
56+
end
57+
describe "#loader_static" do
58+
it "should create loader object on compile time" do
59+
loader = Crustache.loader_static "#{__DIR__}/view/"
60+
61+
loader.load("template").should be_a Crustache::Template
62+
loader.load("template.mustache").should be_a Crustache::Template
63+
loader.load("template_html").should be_a Crustache::Template
64+
loader.load("template_html.html").should be_a Crustache::Template
65+
loader.load("template_test").should be_a Crustache::Template
66+
loader.load("template_test.html").should be_a Crustache::Template
67+
end
68+
69+
it "should create loader object on compile time" do
70+
loader = Crustache.loader_static "#{__DIR__}/view"
71+
72+
loader.load("template").should be_a Crustache::Template
73+
loader.load("template.mustache").should be_a Crustache::Template
74+
loader.load("template_html").should be_a Crustache::Template
75+
loader.load("template_html.html").should be_a Crustache::Template
76+
loader.load("template_test").should be_a Crustache::Template
77+
loader.load("template_test.html").should be_a Crustache::Template
2378
end
2479
end
2580

spec/view/template.mustache

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
11
Hello {{Mustache}} World!
2+
3+
{{#Cond}}
4+
{{.}}
5+
{{/Cond}}
6+
{{^Inv}}
7+
{{.}}
8+
{{/Inv}}
9+
{{!Comment}}
10+
{{{Raw}}}
11+
{{&Raw}}
12+
{{>Partial}}
13+
{{=de lim=}}

src/crustache.cr

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,46 @@
1-
require "./crustache/*"
1+
require "./crustache/**"
2+
3+
module Crustache
4+
# :nodoc:
5+
OPEN_TAG = "{{".to_slice
6+
# :nodoc:
7+
CLOSE_TAG = "}}".to_slice
8+
9+
DEFAULT_FILENAME = "__str__"
10+
11+
alias Template = Syntax::Template
12+
13+
def self.parse(io : IO, filename = DEFAULT_FILENAME, row = 1)
14+
Parser.new(OPEN_TAG, CLOSE_TAG, io, filename, row).parse
15+
end
16+
17+
def self.parse(string : String, filename = DEFAULT_FILENAME, row = 1)
18+
self.parse MemoryIO.new(string), filename, row
19+
end
20+
21+
def self.parse_file(filename)
22+
self.parse(File.new(filename), filename, 1)
23+
end
24+
25+
macro parse_file_static(filename)
26+
{{ run("./parse_file_static.cr", filename) }}
27+
end
28+
29+
def self.loader(basedir, extension = ViewLoader::EXTENSION)
30+
ViewLoader.new basedir, extension: extension
31+
end
32+
33+
macro loader_static(basedir, extension = [".mustache", ".html", ""])
34+
{{ run("./loader_static.cr", basedir, extension.join("/")) }}
35+
end
36+
37+
def self.render(tmpl, model, fs = HashFileSystem.new)
38+
String.build do |io|
39+
self.render tmpl, model, fs, io
40+
end
41+
end
42+
43+
def self.render(tmpl, model, fs, io)
44+
tmpl.visit Renderer.new OPEN_TAG, CLOSE_TAG, Context.new(model), fs, io
45+
end
46+
end

src/crustache/context.cr

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# :nodoc:
2+
class Crustache::Context(T)
3+
getter parent
4+
5+
def initialize(@context : T, @parent = nil : Context?); end
6+
7+
def lookup(key)
8+
if key == "."
9+
return @context
10+
end
11+
12+
ctx = @context
13+
14+
keys = key.split(".")
15+
size = keys.size
16+
17+
i = 0
18+
while i < size
19+
k = keys[i]
20+
case
21+
# TODO:
22+
# this code dose not works in Crystal v0.7.7:
23+
# when ctx.responds_to?(:has_key?) && ctx.responds_to?(:[])
24+
# Perhaps it is the Crystal's bug.
25+
when ctx.responds_to?(:has_key?)
26+
if ctx.has_key?(k)
27+
if ctx.responds_to?(:[])
28+
ctx = ctx[k]
29+
else
30+
break
31+
end
32+
else
33+
break
34+
end
35+
36+
else
37+
break
38+
end
39+
i += 1
40+
end
41+
42+
if i == size
43+
return ctx
44+
end
45+
46+
if p = @parent
47+
p.lookup key
48+
else
49+
nil
50+
end
51+
end
52+
end

src/crustache/filesystem.cr

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
require "./syntax"
22

33
module Crustache
4-
module FileSystem
4+
abstract class FileSystem
5+
abstract def load(value) : Syntax::Template
6+
57
def load!(value)
68
if tmpl = self.load value
79
return tmpl
@@ -11,9 +13,7 @@ module Crustache
1113
end
1214
end
1315

14-
class HashFileSystem
15-
include FileSystem
16-
16+
class HashFileSystem < FileSystem
1717
def initialize
1818
@tmpls = {} of String => Syntax::Template
1919
end
@@ -27,12 +27,10 @@ module Crustache
2727
end
2828
end
2929

30-
class ViewLoader
31-
include FileSystem
32-
30+
class ViewLoader < FileSystem
3331
EXTENSION = [".mustache", ".html", ""]
3432

35-
def initialize(@basedir, @use_cache = false, @extension = EXTENSION)
33+
def initialize(@basedir : String, @use_cache = false, @extension = EXTENSION : Array(String))
3634
@cache = {} of String => Syntax::Template?
3735
end
3836

src/crustache/indent_io.cr

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require "./parser"
2+
3+
# :nodoc:
4+
class Crustache::IndentIO
5+
include IO
6+
7+
def initialize(@indent : String, @io : IO)
8+
@indent_flag = 0
9+
@eol_flag = true
10+
end
11+
12+
def indent_flag_on
13+
@indent_flag -= 1
14+
end
15+
16+
def indent_flag_off
17+
@indent_flag += 1
18+
end
19+
20+
def read(s : Slice(UInt8))
21+
raise "Unsupported"
22+
end
23+
24+
def write(s)
25+
start = 0
26+
size = Util.size(s)
27+
i = 0
28+
while i < size
29+
if @eol_flag
30+
@io.write s[start, i - start]
31+
@io << @indent
32+
@eol_flag = false
33+
start = i
34+
end
35+
36+
if s[i] == Parser::NEWLINE_N && @indent_flag == 0
37+
@eol_flag = true
38+
end
39+
40+
i += 1
41+
end
42+
43+
@io.write s[start, i - start]
44+
end
45+
end

src/crustache/parse_error.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Crustache
33
getter filename
44
getter row
55

6-
def initialize(@msg, @filename, @row); super(message) end
6+
def initialize(@msg : String, @filename : String, @row : Int32); super(message) end
77

88
def message
99
"#{@filename.inspect} line at #{@row}: #{@msg}"

0 commit comments

Comments
 (0)