cutaneous 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/cutaneous.gemspec +3 -3
- data/lib/cutaneous/engine.rb +25 -8
- data/lib/cutaneous/lexer.rb +13 -5
- data/lib/cutaneous/loader.rb +41 -49
- data/lib/cutaneous.rb +1 -1
- data/test/helper.rb +2 -0
- data/test/test_cache.rb +5 -0
- data/test/test_core.rb +33 -4
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d90ff3764cf47bc3c932b85e5d9833adbb86edcb
|
4
|
+
data.tar.gz: a996afd411cb3e846cd1237c13b49a9ef4e99e17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a01dd50c0274e1fd17d7913d48b0e52913842fbc8ed479442356ff17e83aec31112ae93041b68e47c3c6e4d268f7f33d69c5d4c7975ec6305ee2a5f54abec298
|
7
|
+
data.tar.gz: 8e94956de888f9b8a12a5494245dfc3e242ef33e5ebdf0fd4c61dd443c59a2eb90163fd2890a3fe4e7e188d6a2bda97fd5e664ed7cc4a4d7da0263dbcb660868
|
data/cutaneous.gemspec
CHANGED
@@ -8,14 +8,14 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
9
9
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
10
10
|
s.rubygems_version = '1.3.5'
|
11
|
-
s.required_ruby_version = ">= 1.9.
|
11
|
+
s.required_ruby_version = ">= 1.9.3"
|
12
12
|
|
13
13
|
## Leave these as is they will be modified for you by the rake gemspec task.
|
14
14
|
## If your rubyforge_project name is different, then edit it and comment out
|
15
15
|
## the sub! line in the Rakefile
|
16
16
|
s.name = 'cutaneous'
|
17
|
-
s.version = '0.
|
18
|
-
s.date = '
|
17
|
+
s.version = '0.2.0'
|
18
|
+
s.date = '2014-01-29'
|
19
19
|
s.rubyforge_project = 'cutaneous'
|
20
20
|
|
21
21
|
## Make sure your summary is short. The description may be as long
|
data/lib/cutaneous/engine.rb
CHANGED
@@ -18,8 +18,11 @@ module Cutaneous
|
|
18
18
|
|
19
19
|
alias_method :render, :render_file
|
20
20
|
|
21
|
+
# need an explicit #render_string method so it's possible to distinguish
|
22
|
+
# between a String which is a path to a template & a String which is a
|
23
|
+
# template itself.
|
21
24
|
def render_string(template_string, context, format = default_format)
|
22
|
-
|
25
|
+
render_file(proc_template(template_string), context, format)
|
23
26
|
end
|
24
27
|
|
25
28
|
# Create and cache a file loader on a per-format basis
|
@@ -29,14 +32,24 @@ module Cutaneous
|
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
def template_exists?(relative_path, format)
|
36
|
+
@roots.each do |root|
|
37
|
+
return true if file_loader(format).exists?(root, relative_path)
|
38
|
+
end
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
def template_location(relative_path, format)
|
43
|
+
@roots.each do |root|
|
44
|
+
if (path = file_loader(format).location(root, relative_path))
|
45
|
+
return path
|
46
|
+
end
|
47
|
+
end
|
48
|
+
nil
|
36
49
|
end
|
37
50
|
|
38
|
-
def
|
39
|
-
|
51
|
+
def dynamic_template?(template_string)
|
52
|
+
@syntax.is_dynamic?(template_string)
|
40
53
|
end
|
41
54
|
|
42
55
|
def convert(template, to_syntax, format = default_format)
|
@@ -44,7 +57,11 @@ module Cutaneous
|
|
44
57
|
end
|
45
58
|
|
46
59
|
def convert_string(template_string, to_syntax, format = default_format)
|
47
|
-
|
60
|
+
convert(proc_template(template_string), to_syntax, format)
|
61
|
+
end
|
62
|
+
|
63
|
+
def proc_template(template_string)
|
64
|
+
Proc.new { template_string }
|
48
65
|
end
|
49
66
|
|
50
67
|
protected
|
data/lib/cutaneous/lexer.rb
CHANGED
@@ -24,10 +24,6 @@ module Cutaneous
|
|
24
24
|
template
|
25
25
|
end
|
26
26
|
|
27
|
-
# def script
|
28
|
-
# @script ||= compile
|
29
|
-
# end
|
30
|
-
|
31
27
|
protected
|
32
28
|
|
33
29
|
BRACES ||= /\{|\}/
|
@@ -35,7 +31,7 @@ module Cutaneous
|
|
35
31
|
|
36
32
|
def parse
|
37
33
|
tokens = []
|
38
|
-
scanner = StringScanner.new(
|
34
|
+
scanner = StringScanner.new(template_string)
|
39
35
|
tag_start = syntax.tag_start_pattern
|
40
36
|
tags = syntax.tags
|
41
37
|
token_map = syntax.token_map
|
@@ -84,5 +80,17 @@ module Cutaneous
|
|
84
80
|
expression.gsub!(ESCAPE_STRING, '\\\\\&')
|
85
81
|
[:text, expression]
|
86
82
|
end
|
83
|
+
|
84
|
+
def template_string
|
85
|
+
return read_file_template if @template.respond_to?(:read)
|
86
|
+
return @template.call if @template.respond_to?(:call)
|
87
|
+
@template.to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def read_file_template
|
91
|
+
source = @template.read
|
92
|
+
@template.close if @template.respond_to?(:close)
|
93
|
+
source
|
94
|
+
end
|
87
95
|
end
|
88
96
|
end
|
data/lib/cutaneous/loader.rb
CHANGED
@@ -19,26 +19,22 @@ module Cutaneous
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def template(template)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
template.path = template_path
|
28
|
-
template.loader = self
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def proc_template(lmda)
|
33
|
-
StringLoader.new(self).template(lmda.call)
|
22
|
+
template = open_template(template) if String === template
|
23
|
+
instance = @template_class.new(lexer(template))
|
24
|
+
instance.path = template.path if template.respond_to?(:path)
|
25
|
+
instance.loader = self
|
26
|
+
instance
|
34
27
|
end
|
35
28
|
|
36
|
-
def
|
37
|
-
|
29
|
+
def open_template(template)
|
30
|
+
template_path = path(template)
|
31
|
+
raise UnknownTemplateError.new(@roots, filename(template)) if template_path.nil?
|
32
|
+
# TODO: Make the encoding configurable?
|
33
|
+
TemplateReader.new(template_path, Encoding::UTF_8)
|
38
34
|
end
|
39
35
|
|
40
|
-
def lexer(
|
41
|
-
Lexer.new(
|
36
|
+
def lexer(template)
|
37
|
+
Lexer.new(template, syntax)
|
42
38
|
end
|
43
39
|
|
44
40
|
def path(template_name)
|
@@ -52,40 +48,29 @@ module Cutaneous
|
|
52
48
|
end
|
53
49
|
|
54
50
|
def exists?(template_root, template_name)
|
55
|
-
File.
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
# Converts a template string into a Template instance.
|
60
|
-
#
|
61
|
-
# Because a string template can only come from the engine instance
|
62
|
-
# we need a FileLoader to delegate all future template loading to.
|
63
|
-
class StringLoader < FileLoader
|
64
|
-
def initialize(file_loader)
|
65
|
-
@file_loader = file_loader
|
51
|
+
path = ::File.join(template_root, filename(template_name))
|
52
|
+
::File.exists?(path)
|
66
53
|
end
|
67
54
|
|
68
|
-
def
|
69
|
-
|
55
|
+
def location(template_root, template_name)
|
56
|
+
return ::File.join(template_root, template_name) if exists?(template_root, template_name)
|
57
|
+
nil
|
70
58
|
end
|
71
59
|
|
72
|
-
|
73
|
-
|
74
|
-
|
60
|
+
# An IO-like interface that provides #read and #path methods
|
61
|
+
class TemplateReader
|
62
|
+
def initialize(path, encoding)
|
63
|
+
@path = path
|
64
|
+
@encoding = encoding
|
75
65
|
end
|
76
|
-
end
|
77
|
-
end
|
78
66
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
def initialize(filepath)
|
84
|
-
@path = filepath
|
85
|
-
end
|
67
|
+
def read(*args)
|
68
|
+
::File.open(@path, 'r', external_encoding: @encoding) { |f| f.read }
|
69
|
+
end
|
86
70
|
|
87
|
-
|
88
|
-
|
71
|
+
def path
|
72
|
+
@path
|
73
|
+
end
|
89
74
|
end
|
90
75
|
end
|
91
76
|
|
@@ -119,13 +104,13 @@ module Cutaneous
|
|
119
104
|
class CachedTemplate < Template
|
120
105
|
|
121
106
|
def script
|
122
|
-
|
123
|
-
|
107
|
+
script = nil
|
108
|
+
path = script_path
|
109
|
+
if path && cached?
|
110
|
+
script = File.read(path)
|
124
111
|
else
|
125
112
|
script = super
|
126
|
-
|
127
|
-
f.write(script)
|
128
|
-
end
|
113
|
+
write_cached_script(script, path) unless path.nil?
|
129
114
|
end
|
130
115
|
script
|
131
116
|
end
|
@@ -135,7 +120,7 @@ module Cutaneous
|
|
135
120
|
end
|
136
121
|
|
137
122
|
def template_path
|
138
|
-
|
123
|
+
path
|
139
124
|
end
|
140
125
|
|
141
126
|
def script_path
|
@@ -144,8 +129,15 @@ module Cutaneous
|
|
144
129
|
|
145
130
|
def generate_script_path
|
146
131
|
path = template_path
|
132
|
+
return nil if path.nil?
|
147
133
|
ext = File.extname path
|
148
134
|
path.gsub(/#{ext}$/, ".rb")
|
149
135
|
end
|
136
|
+
|
137
|
+
def write_cached_script(script, path)
|
138
|
+
File.open(script_path, "w") do |f|
|
139
|
+
f.write(script)
|
140
|
+
end
|
141
|
+
end
|
150
142
|
end
|
151
143
|
end
|
data/lib/cutaneous.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/test_cache.rb
CHANGED
@@ -101,4 +101,9 @@ describe Cutaneous do
|
|
101
101
|
script_path = template_path("c", "html", "rb")
|
102
102
|
refute ::File.exists?(script_path), "Template cache should not have created '#{script_path}'"
|
103
103
|
end
|
104
|
+
|
105
|
+
it "doesn't attempt to write a cached script for Proc templates" do
|
106
|
+
context = ContextHash(right: "right")
|
107
|
+
result1 = engine.render(Proc.new { "This is ${right}"}, context)
|
108
|
+
end
|
104
109
|
end
|
data/test/test_core.rb
CHANGED
@@ -35,6 +35,14 @@ describe "Parsers" do
|
|
35
35
|
result.must_equal expected
|
36
36
|
end
|
37
37
|
|
38
|
+
it "will render an object that responds to #read" do
|
39
|
+
template = StringIO.new("This is ${ right }")
|
40
|
+
context = ContextHash(right: "right")
|
41
|
+
result = subject.render(template, context)
|
42
|
+
result.must_equal "This is right"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
38
46
|
it "can convert a template to another syntax" do
|
39
47
|
result = subject.convert('statements1', Cutaneous::SecondPassSyntax)
|
40
48
|
result.must_equal read_template('statements2.html.cut')
|
@@ -194,6 +202,17 @@ describe Cutaneous do
|
|
194
202
|
result.must_equal "right"
|
195
203
|
end
|
196
204
|
|
205
|
+
it "calls #close on any IO instances passed to it" do
|
206
|
+
context = ContextHash(right: "correct")
|
207
|
+
template = MiniTest::Mock.new
|
208
|
+
template.expect(:close, nil)
|
209
|
+
template.expect(:read, "${ right }")
|
210
|
+
template.expect(:path, "/path/to/template.html.cut")
|
211
|
+
result = engine.render(template, context, "rss")
|
212
|
+
template.verify
|
213
|
+
result.must_equal "correct"
|
214
|
+
end
|
215
|
+
|
197
216
|
it "Allows for configuration of the engine's default format" do
|
198
217
|
engine.default_format = "rss"
|
199
218
|
context = ContextHash(right: "right")
|
@@ -208,10 +227,20 @@ describe Cutaneous do
|
|
208
227
|
end
|
209
228
|
|
210
229
|
it "Tests for the existence of a template file for a certain format" do
|
211
|
-
assert engine.template_exists?(
|
212
|
-
assert engine.template_exists?(
|
213
|
-
assert engine.template_exists?(
|
214
|
-
refute engine.template_exists?(
|
230
|
+
assert engine.template_exists?("expressions1", "html")
|
231
|
+
assert engine.template_exists?("other/error", "html")
|
232
|
+
assert engine.template_exists?("include", "rss")
|
233
|
+
refute engine.template_exists?("missing", "rss")
|
234
|
+
end
|
235
|
+
|
236
|
+
it "returns the full path to a template if found" do
|
237
|
+
assert_equal "#{template_root}/expressions1", engine.template_location("expressions1", "html")
|
238
|
+
assert_equal nil, engine.template_location("missing", "rss")
|
239
|
+
end
|
240
|
+
|
241
|
+
it "can determine if a template contains tags for its syntax" do
|
242
|
+
assert engine.dynamic_template?("i am ${dynamic}")
|
243
|
+
refute engine.dynamic_template?("i am not dynamic")
|
215
244
|
end
|
216
245
|
|
217
246
|
it "Passes any instance variables & locals between contexts" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cutaneous
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garry Hill
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Cutaneous is the Ruby templating language designed for use with Spontaneous
|
14
14
|
CMS. It has a simple syntax but powerful features such as Djano style template inheritance
|
@@ -78,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
79
79
|
- - '>='
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: 1.9.
|
81
|
+
version: 1.9.3
|
82
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
83
|
requirements:
|
84
84
|
- - '>='
|
@@ -86,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
86
|
version: '0'
|
87
87
|
requirements: []
|
88
88
|
rubyforge_project: cutaneous
|
89
|
-
rubygems_version: 2.
|
89
|
+
rubygems_version: 2.2.1
|
90
90
|
signing_key:
|
91
91
|
specification_version: 2
|
92
92
|
summary: A Ruby templating language with Django style template inheritance
|