temple 0.10.2 → 0.10.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fdf456fd2d277a110681cc1d0dd228bba3b75306b3caa78fb12ad668a7665c6
4
- data.tar.gz: 7dfdd5001be5c652254aab301e391d7652c0bc1e44a00ee9fe5002c1899e99c1
3
+ metadata.gz: a2dfc92778763412687b4c4cefce7f8f01975463a4237b96e3931d246cfc9953
4
+ data.tar.gz: 782b6af3993bdb5179153a5eb6b12304de17f6d6b5661f64671a0aad52649dfe
5
5
  SHA512:
6
- metadata.gz: 4d5847567944020f1be6ddf6b96b056ff0154cb26b00e71d4c736337cddc3e1ceb402ef4eabc3fa8a150ec56fd560cb0ac22358c8f1673bc2dfabb8407a482b9
7
- data.tar.gz: f8f766aeb193a7bf781297dff7628d2e9d09840a241130f4a04f60b72e16d237c965f327696788e29f58ddadc1ce843392a52619363fc19dc5da66966d42ed09
6
+ metadata.gz: 18269f8d2621a71d0eaf4050e56365cb1b734c4d14cda063503e308fe353808f81de4794b3226cbc0698327a8108d5c225500d19346bf04dce761783cd57374b
7
+ data.tar.gz: ddd93041cc83790c7c610a67401d8b10bad033bdeb1f209e3d87a056c67dc855d8f2861bb8d2dfceb087d787938020e91c4211539ae6b2da41eb2f0d36988caa
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ 0.10.3
2
+
3
+ * Remove test files from the gem package (#146)
4
+ * Add DynamicMerger filter (#147)
5
+
1
6
  0.10.2
2
7
 
3
8
  * Fix Sinatra capture_generator problem (#145)
data/Rakefile CHANGED
@@ -3,16 +3,3 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
  task default: :spec
6
-
7
- begin
8
- require 'rcov/rcovtask'
9
- Rcov::RcovTask.new do |t|
10
- t.libs << 'lib' << 'test'
11
- t.pattern = 'test/**/test_*.rb'
12
- t.verbose = false
13
- end
14
- rescue LoadError
15
- task :rcov do
16
- abort "RCov is not available. In order to run rcov, you must: gem install rcov"
17
- end
18
- end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+ module Temple
3
+ module Filters
4
+ # Compile [:multi, [:static, 'foo'], [:dynamic, 'bar']] to [:dynamic, '"foo#{bar}"']
5
+ class DynamicMerger < Filter
6
+ def on_multi(*exps)
7
+ exps = exps.dup
8
+ result = [:multi]
9
+ buffer = []
10
+
11
+ until exps.empty?
12
+ type, arg = exps.first
13
+ if type == :dynamic && arg.count("\n") == 0
14
+ buffer << exps.shift
15
+ elsif type == :static && exps.size > (count = arg.count("\n")) &&
16
+ exps[1, count].all? { |e| e == [:newline] }
17
+ (1 + count).times { buffer << exps.shift }
18
+ elsif type == :newline && exps.size > (count = count_newline(exps)) &&
19
+ exps[count].first == :static && count == exps[count].last.count("\n")
20
+ (count + 1).times { buffer << exps.shift }
21
+ else
22
+ result.concat(merge_dynamic(buffer))
23
+ buffer = []
24
+ result << compile(exps.shift)
25
+ end
26
+ end
27
+ result.concat(merge_dynamic(buffer))
28
+
29
+ result.size == 2 ? result[1] : result
30
+ end
31
+
32
+ private
33
+
34
+ def merge_dynamic(exps)
35
+ # Merge exps only when they have both :static and :dynamic
36
+ unless exps.any? { |type,| type == :static } && exps.any? { |type,| type == :dynamic }
37
+ return exps
38
+ end
39
+
40
+ strlit_body = String.new
41
+ exps.each do |type, arg|
42
+ case type
43
+ when :static
44
+ strlit_body << arg.dump.sub!(/\A"/, '').sub!(/"\z/, '').gsub('\n', "\n")
45
+ when :dynamic
46
+ strlit_body << "\#{#{arg}}"
47
+ when :newline
48
+ # newline is added by `gsub('\n', "\n")`
49
+ else
50
+ raise "unexpected type #{type.inspect} is given to #merge_dynamic"
51
+ end
52
+ end
53
+ [[:dynamic, "%Q\0#{strlit_body}\0"]]
54
+ end
55
+
56
+ def count_newline(exps)
57
+ count = 0
58
+ exps.each do |exp|
59
+ if exp == [:newline]
60
+ count += 1
61
+ else
62
+ return count
63
+ end
64
+ end
65
+ return count
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Temple
3
- VERSION = '0.10.2'
3
+ VERSION = '0.10.3'
4
4
  end
data/lib/temple.rb CHANGED
@@ -50,6 +50,7 @@ module Temple
50
50
  autoload :StaticMerger, 'temple/filters/static_merger'
51
51
  autoload :StringSplitter, 'temple/filters/string_splitter'
52
52
  autoload :DynamicInliner, 'temple/filters/dynamic_inliner'
53
+ autoload :DynamicMerger, 'temple/filters/dynamic_merger'
53
54
  autoload :Escapable, 'temple/filters/escapable'
54
55
  autoload :Eraser, 'temple/filters/eraser'
55
56
  autoload :Validator, 'temple/filters/validator'
data/temple.gemspec CHANGED
@@ -12,8 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.summary = 'Template compilation framework in Ruby'
13
13
 
14
14
  s.require_paths = %w(lib)
15
- s.files = `git ls-files`.split("\n")
16
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec)/}) }
17
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
17
  s.license = 'MIT'
19
18
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: temple
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Magnus Holm
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-05-27 00:00:00.000000000 Z
12
+ date: 2023-10-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: tilt
@@ -96,6 +96,7 @@ files:
96
96
  - lib/temple/filters/code_merger.rb
97
97
  - lib/temple/filters/control_flow.rb
98
98
  - lib/temple/filters/dynamic_inliner.rb
99
+ - lib/temple/filters/dynamic_merger.rb
99
100
  - lib/temple/filters/encoding.rb
100
101
  - lib/temple/filters/eraser.rb
101
102
  - lib/temple/filters/escapable.rb
@@ -133,31 +134,6 @@ files:
133
134
  - lib/temple/templates/tilt.rb
134
135
  - lib/temple/utils.rb
135
136
  - lib/temple/version.rb
136
- - spec/engine_spec.rb
137
- - spec/erb_spec.rb
138
- - spec/filter_spec.rb
139
- - spec/filters/code_merger_spec.rb
140
- - spec/filters/control_flow_spec.rb
141
- - spec/filters/dynamic_inliner_spec.rb
142
- - spec/filters/eraser_spec.rb
143
- - spec/filters/escapable_spec.rb
144
- - spec/filters/multi_flattener_spec.rb
145
- - spec/filters/static_analyzer_spec.rb
146
- - spec/filters/static_merger_spec.rb
147
- - spec/filters/string_splitter_spec.rb
148
- - spec/generator_spec.rb
149
- - spec/grammar_spec.rb
150
- - spec/html/attribute_merger_spec.rb
151
- - spec/html/attribute_remover_spec.rb
152
- - spec/html/attribute_sorter_spec.rb
153
- - spec/html/fast_spec.rb
154
- - spec/html/pretty_spec.rb
155
- - spec/map_spec.rb
156
- - spec/mixins/dispatcher_spec.rb
157
- - spec/mixins/grammar_dsl_spec.rb
158
- - spec/spec_helper.rb
159
- - spec/static_analyzer_spec.rb
160
- - spec/utils_spec.rb
161
137
  - temple.gemspec
162
138
  homepage: https://github.com/judofyr/temple
163
139
  licenses:
@@ -178,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
154
  - !ruby/object:Gem::Version
179
155
  version: '0'
180
156
  requirements: []
181
- rubygems_version: 3.2.5
157
+ rubygems_version: 3.4.10
182
158
  signing_key:
183
159
  specification_version: 4
184
160
  summary: Template compilation framework in Ruby
data/spec/engine_spec.rb DELETED
@@ -1,189 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require 'spec_helper'
3
-
4
- class Callable1
5
- def call(exp)
6
- exp
7
- end
8
- end
9
-
10
- class Callable2
11
- def call(exp)
12
- exp
13
- end
14
- end
15
-
16
- class MySpecialFilter
17
- def initialize(opts = {})
18
- end
19
-
20
- def call(exp)
21
- exp
22
- end
23
- end
24
-
25
- class TestEngine < Temple::Engine
26
- use(:Parser) do |input|
27
- [:static, input]
28
- end
29
- use :MyFilter1, proc {|exp| exp }
30
- use :MyFilter2, proc {|exp| exp }
31
- use Temple::HTML::Pretty, pretty: true
32
- filter :MultiFlattener
33
- generator :ArrayBuffer
34
- use(:BeforeBeforeLast) { MySpecialFilter }
35
- use :BeforeLast, Callable1.new
36
- use(:Last) { Callable2.new }
37
- end
38
-
39
- describe Temple::Engine do
40
- it 'should build chain' do
41
- expect(TestEngine.chain.size).to eq(9)
42
-
43
- expect(TestEngine.chain[0].first).to eq(:Parser)
44
- expect(TestEngine.chain[0].size).to eq(2)
45
- expect(TestEngine.chain[0].last).to be_a(Proc)
46
-
47
- expect(TestEngine.chain[1].first).to eq(:MyFilter1)
48
- expect(TestEngine.chain[1].size).to eq(2)
49
- expect(TestEngine.chain[1].last).to be_a(Proc)
50
-
51
- expect(TestEngine.chain[2].first).to eq(:MyFilter2)
52
- expect(TestEngine.chain[2].size).to eq(2)
53
- expect(TestEngine.chain[2].last).to be_a(Proc)
54
-
55
- expect(TestEngine.chain[3].first).to eq(:'Temple::HTML::Pretty')
56
- expect(TestEngine.chain[3].size).to eq(2)
57
- expect(TestEngine.chain[3].last).to be_a(Proc)
58
-
59
- expect(TestEngine.chain[4].first).to eq(:MultiFlattener)
60
- expect(TestEngine.chain[4].size).to eq(2)
61
- expect(TestEngine.chain[4].last).to be_a(Proc)
62
-
63
- expect(TestEngine.chain[5].first).to eq(:ArrayBuffer)
64
- expect(TestEngine.chain[5].size).to eq(2)
65
- expect(TestEngine.chain[5].last).to be_a(Proc)
66
-
67
- expect(TestEngine.chain[6].first).to eq(:BeforeBeforeLast)
68
- expect(TestEngine.chain[6].size).to eq(2)
69
- expect(TestEngine.chain[6].last).to be_a(Proc)
70
-
71
- expect(TestEngine.chain[7].first).to eq(:BeforeLast)
72
- expect(TestEngine.chain[7].size).to eq(2)
73
- expect(TestEngine.chain[7].last).to be_a(Proc)
74
-
75
- expect(TestEngine.chain[8].first).to eq(:Last)
76
- expect(TestEngine.chain[8].size).to eq(2)
77
- expect(TestEngine.chain[8].last).to be_a(Proc)
78
- end
79
-
80
- it 'should instantiate chain' do
81
- call_chain = TestEngine.new.send(:call_chain)
82
- expect(call_chain[0]).to be_a(Method)
83
- expect(call_chain[1]).to be_a(Method)
84
- expect(call_chain[2]).to be_a(Method)
85
- expect(call_chain[3]).to be_a(Temple::HTML::Pretty)
86
- expect(call_chain[4]).to be_a(Temple::Filters::MultiFlattener)
87
- expect(call_chain[5]).to be_a(Temple::Generators::ArrayBuffer)
88
- expect(call_chain[6]).to be_a(MySpecialFilter)
89
- expect(call_chain[7]).to be_a(Callable1)
90
- expect(call_chain[8]).to be_a(Callable2)
91
- end
92
-
93
- it 'should have #append' do
94
- engine = TestEngine.new
95
- call_chain = engine.send(:call_chain)
96
- expect(call_chain.size).to eq(9)
97
-
98
- engine.append :MyFilter3 do |exp|
99
- exp
100
- end
101
-
102
- expect(TestEngine.chain.size).to eq(9)
103
- expect(engine.chain.size).to eq(10)
104
- expect(engine.chain[9].first).to eq(:MyFilter3)
105
- expect(engine.chain[9].size).to eq(2)
106
- expect(engine.chain[9].last).to be_a(Proc)
107
-
108
- call_chain = engine.send(:call_chain)
109
- expect(call_chain.size).to eq(10)
110
- expect(call_chain[9]).to be_a(Method)
111
- end
112
-
113
- it 'should have #prepend' do
114
- engine = TestEngine.new
115
- call_chain = engine.send(:call_chain)
116
- expect(call_chain.size).to eq(9)
117
-
118
- engine.prepend :MyFilter0 do |exp|
119
- exp
120
- end
121
-
122
- expect(TestEngine.chain.size).to eq(9)
123
- expect(engine.chain.size).to eq(10)
124
- expect(engine.chain[0].first).to eq(:MyFilter0)
125
- expect(engine.chain[0].size).to eq(2)
126
- expect(engine.chain[0].last).to be_a(Proc)
127
- expect(engine.chain[1].first).to eq(:Parser)
128
-
129
- call_chain = engine.send(:call_chain)
130
- expect(call_chain.size).to eq(10)
131
- expect(call_chain[0]).to be_a(Method)
132
- end
133
-
134
- it 'should have #after' do
135
- engine = TestEngine.new
136
- engine.after :Parser, :MyFilter0 do |exp|
137
- exp
138
- end
139
- expect(TestEngine.chain.size).to eq(9)
140
- expect(engine.chain.size).to eq(10)
141
- expect(engine.chain[0].first).to eq(:Parser)
142
- expect(engine.chain[1].first).to eq(:MyFilter0)
143
- expect(engine.chain[2].first).to eq(:MyFilter1)
144
- end
145
-
146
- it 'should have #before' do
147
- engine = TestEngine.new
148
- engine.before :MyFilter1, :MyFilter0 do |exp|
149
- exp
150
- end
151
- expect(TestEngine.chain.size).to eq(9)
152
- expect(engine.chain.size).to eq(10)
153
- expect(engine.chain[0].first).to eq(:Parser)
154
- expect(engine.chain[1].first).to eq(:MyFilter0)
155
- expect(engine.chain[2].first).to eq(:MyFilter1)
156
- end
157
-
158
- it 'should have #remove' do
159
- engine = TestEngine.new
160
- engine.remove :MyFilter1
161
- expect(TestEngine.chain.size).to eq(9)
162
- expect(engine.chain.size).to eq(8)
163
- expect(engine.chain[0].first).to eq(:Parser)
164
- expect(engine.chain[1].first).to eq(:MyFilter2)
165
-
166
- engine = TestEngine.new
167
- engine.remove /Last/
168
- expect(engine.chain.size).to eq(6)
169
- end
170
-
171
- it 'should have #replace' do
172
- engine = TestEngine.new
173
- engine.replace :Parser, :MyParser do |exp|
174
- exp
175
- end
176
- expect(engine.chain.size).to eq(9)
177
- expect(engine.chain[0].first).to eq(:MyParser)
178
- end
179
-
180
- it 'should work with inheritance' do
181
- inherited_engine = Class.new(TestEngine)
182
- expect(inherited_engine.chain.size).to eq(9)
183
- inherited_engine.append :MyFilter3 do |exp|
184
- exp
185
- end
186
- expect(inherited_engine.chain.size).to eq(10)
187
- expect(TestEngine.chain.size).to eq(9)
188
- end
189
- end
data/spec/erb_spec.rb DELETED
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
- require 'tilt/erubi'
3
-
4
- describe Temple::ERB::Engine do
5
- it 'should compile erb' do
6
- src = %q{
7
- %% hi
8
- = hello
9
- <% 3.times do |n| %>
10
- * <%= n %>
11
- <% end %>
12
- }
13
-
14
- expect(erb(src)).to eq(erubi(src))
15
- end
16
-
17
- it 'should recognize comments' do
18
- src = %q{
19
- hello
20
- <%# comment -- ignored -- useful in testing %>
21
- world}
22
-
23
- expect(erb(src)).to eq(erubi(src))
24
- end
25
-
26
- it 'should recognize <%% and %%>' do
27
- src = %q{
28
- <%%
29
- <% if true %>
30
- %%>
31
- <% end %>
32
- }
33
-
34
- expect(erb(src)).to eq("\n<%\n %>\n")
35
- end
36
-
37
- it 'should escape automatically' do
38
- src = '<%== "<" %>'
39
- ans = '&lt;'
40
- expect(erb(src)).to eq(ans)
41
- end
42
-
43
- it 'should support = to disable automatic escape' do
44
- src = '<%= "<" %>'
45
- ans = '<'
46
- expect(erb(src)).to eq(ans)
47
- end
48
-
49
- it 'should support trim mode' do
50
- src = %q{
51
- %% hi
52
- = hello
53
- <% 3.times do |n| %>
54
- * <%= n %>
55
- <% end %>
56
- }
57
-
58
- expect(erb(src, trim: true)).to eq(erubi(src, trim: true))
59
- expect(erb(src, trim: false)).to eq(erubi(src, trim: false))
60
- end
61
- end
data/spec/filter_spec.rb DELETED
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class SimpleFilter < Temple::Filter
4
- define_options :key
5
-
6
- def on_test(arg)
7
- [:on_test, arg]
8
- end
9
- end
10
-
11
- describe Temple::Filter do
12
- it 'should support options' do
13
- expect(Temple::Filter).to respond_to(:default_options)
14
- expect(Temple::Filter).to respond_to(:set_default_options)
15
- expect(Temple::Filter).to respond_to(:define_options)
16
- expect(Temple::Filter.new.options).to be_a(Temple::ImmutableMap)
17
- expect(SimpleFilter.new(key: 3).options[:key]).to eq(3)
18
- end
19
-
20
- it 'should implement call' do
21
- expect(Temple::Filter.new.call([:exp])).to eq([:exp])
22
- end
23
-
24
- it 'should process expressions' do
25
- filter = SimpleFilter.new
26
- expect(filter.call([:unhandled])).to eq([:unhandled])
27
- expect(filter.call([:test, 42])).to eq([:on_test, 42])
28
- end
29
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Temple::Filters::CodeMerger do
4
- before do
5
- @filter = Temple::Filters::CodeMerger.new
6
- end
7
-
8
- it 'should merge serveral codes' do
9
- expect(@filter.call([:multi,
10
- [:code, "a"],
11
- [:code, "b"],
12
- [:code, "c"]
13
- ])).to eq [:code, "a; b; c"]
14
- end
15
-
16
- it 'should merge serveral codes around static' do
17
- expect(@filter.call([:multi,
18
- [:code, "a"],
19
- [:code, "b"],
20
- [:static, "123"],
21
- [:code, "a"],
22
- [:code, "b"]
23
- ])).to eq [:multi,
24
- [:code, "a; b"],
25
- [:static, "123"],
26
- [:code, "a; b"]
27
- ]
28
- end
29
-
30
- it 'should merge serveral codes with newlines' do
31
- expect(@filter.call([:multi,
32
- [:code, "a"],
33
- [:code, "b"],
34
- [:newline],
35
- [:code, "c"]
36
- ])).to eq [:code, "a; b\nc"]
37
- end
38
- end
@@ -1,90 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Temple::Filters::ControlFlow do
4
- before do
5
- @filter = Temple::Filters::ControlFlow.new
6
- end
7
-
8
- it 'should process blocks' do
9
- expect(@filter.call([:block, 'loop do',
10
- [:static, 'Hello']
11
- ])).to eq [:multi,
12
- [:code, 'loop do'],
13
- [:static, 'Hello'],
14
- [:code, 'end']]
15
- end
16
-
17
- it 'should process if' do
18
- expect(@filter.call([:if, 'condition',
19
- [:static, 'Hello']
20
- ])).to eq [:multi,
21
- [:code, 'if condition'],
22
- [:static, 'Hello'],
23
- [:code, 'end']
24
- ]
25
- end
26
-
27
- it 'should process if with else' do
28
- expect(@filter.call([:if, 'condition',
29
- [:static, 'True'],
30
- [:static, 'False']
31
- ])).to eq [:multi,
32
- [:code, 'if condition'],
33
- [:static, 'True'],
34
- [:code, 'else'],
35
- [:static, 'False'],
36
- [:code, 'end']
37
- ]
38
- end
39
-
40
- it 'should create elsif' do
41
- expect(@filter.call([:if, 'condition1',
42
- [:static, '1'],
43
- [:if, 'condition2',
44
- [:static, '2'],
45
- [:static, '3']]
46
- ])).to eq [:multi,
47
- [:code, 'if condition1'],
48
- [:static, '1'],
49
- [:code, 'elsif condition2'],
50
- [:static, '2'],
51
- [:code, 'else'],
52
- [:static, '3'],
53
- [:code, 'end']
54
- ]
55
- end
56
-
57
- it 'should process cond' do
58
- expect(@filter.call([:cond,
59
- ['cond1', [:exp1]],
60
- ['cond2', [:exp2]],
61
- [:else, [:exp3]],
62
- ])).to eq [:multi,
63
- [:code, 'case'],
64
- [:code, 'when cond1'],
65
- [:exp1],
66
- [:code, 'when cond2'],
67
- [:exp2],
68
- [:code, 'else'],
69
- [:exp3],
70
- [:code, 'end']
71
- ]
72
- end
73
-
74
- it 'should process case' do
75
- expect(@filter.call([:case, 'var',
76
- ['Array', [:exp1]],
77
- ['String', [:exp2]],
78
- [:else, [:exp3]],
79
- ])).to eq [:multi,
80
- [:code, 'case (var)'],
81
- [:code, 'when Array'],
82
- [:exp1],
83
- [:code, 'when String'],
84
- [:exp2],
85
- [:code, 'else'],
86
- [:exp3],
87
- [:code, 'end']
88
- ]
89
- end
90
- end