temple 0.8.2 → 0.10.4
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 +5 -5
- data/.github/workflows/test.yml +37 -0
- data/.gitignore +1 -0
- data/CHANGES +43 -1
- data/Gemfile +0 -1
- data/README.md +1 -1
- data/Rakefile +4 -24
- data/lib/temple/engine.rb +1 -0
- data/lib/temple/erb/engine.rb +3 -0
- data/lib/temple/erb/parser.rb +2 -1
- data/lib/temple/erb/template.rb +1 -0
- data/lib/temple/erb/trimming.rb +1 -0
- data/lib/temple/exceptions.rb +1 -0
- data/lib/temple/filter.rb +1 -0
- data/lib/temple/filters/ambles.rb +22 -0
- data/lib/temple/filters/code_merger.rb +1 -0
- data/lib/temple/filters/control_flow.rb +1 -0
- data/lib/temple/filters/dynamic_inliner.rb +2 -1
- data/lib/temple/filters/dynamic_merger.rb +69 -0
- data/lib/temple/filters/encoding.rb +2 -1
- data/lib/temple/filters/eraser.rb +1 -0
- data/lib/temple/filters/escapable.rb +1 -0
- data/lib/temple/filters/multi_flattener.rb +1 -0
- data/lib/temple/filters/remove_bom.rb +1 -0
- data/lib/temple/filters/static_analyzer.rb +1 -0
- data/lib/temple/filters/static_merger.rb +1 -0
- data/lib/temple/filters/string_splitter.rb +13 -1
- data/lib/temple/filters/validator.rb +1 -0
- data/lib/temple/generator.rb +5 -2
- data/lib/temple/generators/array.rb +1 -0
- data/lib/temple/generators/array_buffer.rb +1 -0
- data/lib/temple/generators/erb.rb +1 -0
- data/lib/temple/generators/rails_output_buffer.rb +4 -4
- data/lib/temple/generators/string_buffer.rb +2 -1
- data/lib/temple/grammar.rb +1 -0
- data/lib/temple/html/attribute_merger.rb +1 -0
- data/lib/temple/html/attribute_remover.rb +1 -0
- data/lib/temple/html/attribute_sorter.rb +1 -0
- data/lib/temple/html/dispatcher.rb +1 -0
- data/lib/temple/html/fast.rb +1 -0
- data/lib/temple/html/filter.rb +1 -0
- data/lib/temple/html/pretty.rb +1 -0
- data/lib/temple/html/safe.rb +1 -0
- data/lib/temple/map.rb +1 -0
- data/lib/temple/mixins/dispatcher.rb +1 -0
- data/lib/temple/mixins/engine_dsl.rb +1 -0
- data/lib/temple/mixins/grammar_dsl.rb +4 -2
- data/lib/temple/mixins/options.rb +1 -0
- data/lib/temple/mixins/template.rb +1 -0
- data/lib/temple/parser.rb +1 -0
- data/lib/temple/static_analyzer.rb +1 -0
- data/lib/temple/templates/rails.rb +7 -2
- data/lib/temple/templates/tilt.rb +2 -9
- data/lib/temple/templates.rb +1 -0
- data/lib/temple/utils.rb +5 -15
- data/lib/temple/version.rb +2 -1
- data/lib/temple.rb +3 -0
- data/temple.gemspec +4 -6
- metadata +10 -63
- data/.travis.yml +0 -30
- data/test/filters/test_code_merger.rb +0 -38
- data/test/filters/test_control_flow.rb +0 -90
- data/test/filters/test_dynamic_inliner.rb +0 -95
- data/test/filters/test_eraser.rb +0 -55
- data/test/filters/test_escapable.rb +0 -49
- data/test/filters/test_multi_flattener.rb +0 -33
- data/test/filters/test_static_analyzer.rb +0 -37
- data/test/filters/test_static_merger.rb +0 -41
- data/test/filters/test_string_splitter.rb +0 -25
- data/test/helper.rb +0 -30
- data/test/html/test_attribute_merger.rb +0 -76
- data/test/html/test_attribute_remover.rb +0 -43
- data/test/html/test_attribute_sorter.rb +0 -48
- data/test/html/test_fast.rb +0 -97
- data/test/html/test_pretty.rb +0 -55
- data/test/mixins/test_dispatcher.rb +0 -70
- data/test/mixins/test_grammar_dsl.rb +0 -86
- data/test/test_engine.rb +0 -189
- data/test/test_erb.rb +0 -61
- data/test/test_filter.rb +0 -29
- data/test/test_generator.rb +0 -158
- data/test/test_grammar.rb +0 -47
- data/test/test_map.rb +0 -39
- data/test/test_static_analyzer.rb +0 -39
- data/test/test_utils.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3eedd92f18dc086c241e1163c104e1929477068901992a5b56a36783ddbe2b71
|
4
|
+
data.tar.gz: 87ad60cdfa2a9fbca8c2e499e3dd0ca4b54143cc4e04bbfc07f810bc085a2fdb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 169be5abf462523cc50b21b8b1f5ad16e32dd24d8864a7a0d7c69599224d7f62f5ac939cb3da4db733b173653ac0ee227dfc2dbf8d5d236cc8b507af56dce8bd
|
7
|
+
data.tar.gz: d34651062a8d38fbfeaa22a6f92df88b9cddaf821b7fecb506a4e7f9cbee9ce5fa06c42e5f8d1dee56e5987a2d390583a1188c7577ad90354737f49d4e435404
|
@@ -0,0 +1,37 @@
|
|
1
|
+
name: test
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
branches:
|
5
|
+
- master
|
6
|
+
pull_request:
|
7
|
+
types:
|
8
|
+
- opened
|
9
|
+
- synchronize
|
10
|
+
- reopened
|
11
|
+
schedule:
|
12
|
+
- cron: "00 15 * * *"
|
13
|
+
jobs:
|
14
|
+
test:
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
strategy:
|
17
|
+
fail-fast: false
|
18
|
+
matrix:
|
19
|
+
ruby:
|
20
|
+
- '2.5'
|
21
|
+
- '2.6'
|
22
|
+
- '2.7'
|
23
|
+
- '3.0'
|
24
|
+
- '3.1'
|
25
|
+
- '3.2'
|
26
|
+
- '3.3'
|
27
|
+
- '3.4'
|
28
|
+
- jruby
|
29
|
+
- truffleruby-head
|
30
|
+
steps:
|
31
|
+
- uses: actions/checkout@v4
|
32
|
+
- name: Set up Ruby
|
33
|
+
uses: ruby/setup-ruby@v1
|
34
|
+
with:
|
35
|
+
ruby-version: ${{ matrix.ruby }}
|
36
|
+
bundler-cache: true
|
37
|
+
- run: bundle exec rake spec
|
data/.gitignore
CHANGED
data/CHANGES
CHANGED
@@ -1,3 +1,45 @@
|
|
1
|
+
0.10.4
|
2
|
+
|
3
|
+
* Fix Ruby 3.4 compatibility (#152)
|
4
|
+
|
5
|
+
0.10.3
|
6
|
+
|
7
|
+
* Remove test files from the gem package (#146)
|
8
|
+
* Add DynamicMerger filter (#147)
|
9
|
+
|
10
|
+
0.10.2
|
11
|
+
|
12
|
+
* Fix Sinatra capture_generator problem (#145)
|
13
|
+
|
14
|
+
0.10.1
|
15
|
+
|
16
|
+
* Use specified :capture_generator for nested captures (#112, #144)
|
17
|
+
* Compatibility with frozen string literals
|
18
|
+
|
19
|
+
0.10.0
|
20
|
+
|
21
|
+
* Regression: Revert changes to :capture_generator since 0.8.2 (#112, #113, #137)
|
22
|
+
* Regression: Ensure that output buffer is not reused for capturing in Rails (#135)
|
23
|
+
* Drop support for Rails 4.x
|
24
|
+
|
25
|
+
0.9.1
|
26
|
+
|
27
|
+
* Fix Slim's error in AttributeMerger due to 0.9.0's :capture_generator (#137)
|
28
|
+
* Use specified :capture_generator for nested captures (#112)
|
29
|
+
* Fix Temple::ERB::Engine's <%= to not escape and <%== to escape expressions
|
30
|
+
|
31
|
+
0.9.0
|
32
|
+
|
33
|
+
* Require Ruby 2.5+ (#131)
|
34
|
+
* Change default :capture_generator to self (#113)
|
35
|
+
* Improve compatibility with Rails 7.1 (#135)
|
36
|
+
* Support Rails 6.1's annotate_rendered_view_with_filenames
|
37
|
+
with Temple::Filters::Ambles (#134)
|
38
|
+
* Fix a crash in StringSplitter filter (#138)
|
39
|
+
* Fix a warning by Object#=~ since Ruby 2.6 (#129)
|
40
|
+
* Fix deprecated Tilt template mime type (#108)
|
41
|
+
* Stop using deprecated EscapeUtils from Temple::Utils (#136)
|
42
|
+
|
1
43
|
0.8.2
|
2
44
|
|
3
45
|
* Support TruffleRuby in Temple::Filters::StaticAnalyzer (#127)
|
@@ -16,7 +58,7 @@
|
|
16
58
|
|
17
59
|
0.7.8
|
18
60
|
|
19
|
-
* Fix
|
61
|
+
* Fix a warning in StaticAnalyzer
|
20
62
|
|
21
63
|
0.7.7
|
22
64
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Temple
|
2
2
|
======
|
3
3
|
|
4
|
-
[](https://github.com/judofyr/temple/actions/workflows/test.yml) [](https://codeclimate.com/github/judofyr/temple) [](https://rubygems.org/gems/temple) [](http://rubydoc.info/gems/temple/frames)
|
5
5
|
|
6
6
|
Temple is an abstraction and a framework for compiling templates to pure Ruby.
|
7
7
|
It's all about making it easier to experiment, implement and optimize template
|
data/Rakefile
CHANGED
@@ -1,25 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
2
3
|
|
3
|
-
|
4
|
-
task :
|
5
|
-
sh "bacon -Ilib -Itest --automatic --quiet"
|
6
|
-
end
|
7
|
-
|
8
|
-
#Rake::TestTask.new(:test) do |t|
|
9
|
-
# t.libs << 'lib' << 'test'
|
10
|
-
# t.pattern = 'test/**/test_*.rb'
|
11
|
-
# t.verbose = false
|
12
|
-
#end
|
13
|
-
|
14
|
-
begin
|
15
|
-
require 'rcov/rcovtask'
|
16
|
-
Rcov::RcovTask.new do |t|
|
17
|
-
t.libs << 'lib' << 'test'
|
18
|
-
t.pattern = 'test/**/test_*.rb'
|
19
|
-
t.verbose = false
|
20
|
-
end
|
21
|
-
rescue LoadError
|
22
|
-
task :rcov do
|
23
|
-
abort "RCov is not available. In order to run rcov, you must: gem install rcov"
|
24
|
-
end
|
25
|
-
end
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
task default: :spec
|
data/lib/temple/engine.rb
CHANGED
data/lib/temple/erb/engine.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
module ERB
|
3
4
|
# Example ERB engine implementation
|
@@ -7,6 +8,8 @@ module Temple
|
|
7
8
|
use Temple::ERB::Parser
|
8
9
|
use Temple::ERB::Trimming
|
9
10
|
filter :Escapable
|
11
|
+
filter :StringSplitter
|
12
|
+
filter :StaticAnalyzer
|
10
13
|
filter :MultiFlattener
|
11
14
|
filter :StaticMerger
|
12
15
|
generator :ArrayBuffer
|
data/lib/temple/erb/parser.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
module ERB
|
3
4
|
# Example ERB parser
|
@@ -27,7 +28,7 @@ module Temple
|
|
27
28
|
when '#'
|
28
29
|
result << [:code, "\n" * code.count("\n")]
|
29
30
|
when /=/
|
30
|
-
result << [:escape, indicator.size
|
31
|
+
result << [:escape, indicator.size == 2, [:dynamic, code]]
|
31
32
|
else
|
32
33
|
result << [:code, code]
|
33
34
|
end
|
data/lib/temple/erb/template.rb
CHANGED
data/lib/temple/erb/trimming.rb
CHANGED
data/lib/temple/exceptions.rb
CHANGED
data/lib/temple/filter.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Temple
|
3
|
+
module Filters
|
4
|
+
class Ambles < Filter
|
5
|
+
define_options :preamble, :postamble
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
@preamble = options[:preamble]
|
10
|
+
@postamble = options[:postamble]
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(ast)
|
14
|
+
ret = [:multi]
|
15
|
+
ret << [:static, @preamble] if @preamble
|
16
|
+
ret << ast
|
17
|
+
ret << [:static, @postamble] if @postamble
|
18
|
+
ret
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
module Filters
|
3
4
|
# Inlines several static/dynamic into a single dynamic.
|
@@ -36,7 +37,7 @@ module Temple
|
|
36
37
|
# another one, we add both then.
|
37
38
|
state = :single
|
38
39
|
prev = [exp]
|
39
|
-
curr = [:dynamic, '"']
|
40
|
+
curr = [:dynamic, '"'.dup]
|
40
41
|
when :single
|
41
42
|
# Yes! We found another one. Add the current dynamic to the result.
|
42
43
|
state = :several
|
@@ -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,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
module Filters
|
3
4
|
# Try to encode input string
|
@@ -9,7 +10,7 @@ module Temple
|
|
9
10
|
def call(s)
|
10
11
|
if options[:encoding] && s.respond_to?(:encoding)
|
11
12
|
old_enc = s.encoding
|
12
|
-
s = s
|
13
|
+
s = +s
|
13
14
|
s.force_encoding(options[:encoding])
|
14
15
|
# Fall back to old encoding if new encoding is invalid
|
15
16
|
unless s.valid_encoding?
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
begin
|
2
3
|
require 'ripper'
|
3
4
|
rescue LoadError
|
@@ -7,7 +8,7 @@ module Temple
|
|
7
8
|
module Filters
|
8
9
|
# Compile [:dynamic, "foo#{bar}"] to [:multi, [:static, 'foo'], [:dynamic, 'bar']]
|
9
10
|
class StringSplitter < Filter
|
10
|
-
if defined?(Ripper) &&
|
11
|
+
if defined?(Ripper) && Ripper.respond_to?(:lex)
|
11
12
|
class << self
|
12
13
|
# `code` param must be valid string literal
|
13
14
|
def compile(code)
|
@@ -46,6 +47,7 @@ module Temple
|
|
46
47
|
|
47
48
|
case type
|
48
49
|
when :on_tstring_content
|
50
|
+
beg_str, end_str = escape_quotes(beg_str, end_str)
|
49
51
|
exps << [:static, eval("#{beg_str}#{str}#{end_str}").to_s]
|
50
52
|
when :on_embexpr_beg
|
51
53
|
embedded = shift_balanced_embexpr(tokens)
|
@@ -54,6 +56,16 @@ module Temple
|
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
59
|
+
# Some quotes are split-unsafe. Replace such quotes with null characters.
|
60
|
+
def escape_quotes(beg_str, end_str)
|
61
|
+
case [beg_str[-1], end_str]
|
62
|
+
when ['(', ')'], ['[', ']'], ['{', '}']
|
63
|
+
[beg_str.sub(/.\z/) { "\0" }, "\0"]
|
64
|
+
else
|
65
|
+
[beg_str, end_str]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
57
69
|
def shift_balanced_embexpr(tokens)
|
58
70
|
String.new.tap do |embedded|
|
59
71
|
embexpr_open = 1
|
data/lib/temple/generator.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
# Abstract generator base class
|
3
4
|
# Generators should inherit this class and
|
@@ -12,7 +13,7 @@ module Temple
|
|
12
13
|
define_options :save_buffer,
|
13
14
|
capture_generator: 'StringBuffer',
|
14
15
|
buffer: '_buf',
|
15
|
-
freeze_static:
|
16
|
+
freeze_static: true
|
16
17
|
|
17
18
|
def call(exp)
|
18
19
|
[preamble, compile(exp), postamble].flatten.compact.join('; ')
|
@@ -54,7 +55,9 @@ module Temple
|
|
54
55
|
end
|
55
56
|
|
56
57
|
def on_capture(name, exp)
|
57
|
-
capture_generator.new(
|
58
|
+
capture_generator.new(capture_generator: options[:capture_generator],
|
59
|
+
freeze_static: options[:freeze_static],
|
60
|
+
buffer: name).call(exp)
|
58
61
|
end
|
59
62
|
|
60
63
|
def on_static(text)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
module Generators
|
3
4
|
# Implements a rails output buffer.
|
@@ -9,10 +10,9 @@ module Temple
|
|
9
10
|
#
|
10
11
|
# @api public
|
11
12
|
class RailsOutputBuffer < StringBuffer
|
12
|
-
define_options :streaming,
|
13
|
-
buffer_class: '
|
13
|
+
define_options :streaming, # ignored
|
14
|
+
buffer_class: 'ActionView::OutputBuffer',
|
14
15
|
buffer: '@output_buffer',
|
15
|
-
# output_buffer is needed for Rails 3.1 Streaming support
|
16
16
|
capture_generator: RailsOutputBuffer
|
17
17
|
|
18
18
|
def call(exp)
|
@@ -20,7 +20,7 @@ module Temple
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def create_buffer
|
23
|
-
if
|
23
|
+
if buffer == '@output_buffer'
|
24
24
|
"#{buffer} = output_buffer || #{options[:buffer_class]}.new"
|
25
25
|
else
|
26
26
|
"#{buffer} = #{options[:buffer_class]}.new"
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
module Generators
|
3
4
|
# Implements a string buffer.
|
@@ -10,7 +11,7 @@ module Temple
|
|
10
11
|
# @api public
|
11
12
|
class StringBuffer < ArrayBuffer
|
12
13
|
def create_buffer
|
13
|
-
"#{buffer} = ''"
|
14
|
+
"#{buffer} = ''.dup"
|
14
15
|
end
|
15
16
|
|
16
17
|
def return_buffer
|
data/lib/temple/grammar.rb
CHANGED
data/lib/temple/html/fast.rb
CHANGED
data/lib/temple/html/filter.rb
CHANGED
data/lib/temple/html/pretty.rb
CHANGED
data/lib/temple/html/safe.rb
CHANGED
data/lib/temple/map.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Temple
|
2
3
|
module Mixins
|
3
4
|
# @api private
|
@@ -67,7 +68,7 @@ module Temple
|
|
67
68
|
unmatched.reverse_each do |u|
|
68
69
|
entry = u if u.flatten.size < entry.flatten.size
|
69
70
|
end
|
70
|
-
raise(InvalidExpression, PP.pp(entry.last, "#{@grammar}::#{entry.first} did not match\n"))
|
71
|
+
raise(InvalidExpression, PP.pp(entry.last, "#{@grammar}::#{entry.first} did not match\n".dup))
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -143,7 +144,8 @@ module Temple
|
|
143
144
|
start = Or.new(self)
|
144
145
|
curr = [start]
|
145
146
|
rule.each do |elem|
|
146
|
-
|
147
|
+
case elem
|
148
|
+
when /^(.*)(\*|\?|\+)$/
|
147
149
|
elem = Element.new(self, const_get($1))
|
148
150
|
curr.each {|c| c << elem }
|
149
151
|
elem << elem if $2 != '?'
|
data/lib/temple/parser.rb
CHANGED