rtpl 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ # rcov generated
2
+ coverage
3
+ coverage.data
4
+
5
+ # rdoc generated
6
+ rdoc
7
+
8
+ # yard generated
9
+ doc
10
+ .yardoc
11
+
12
+ # bundler
13
+ .bundle
14
+
15
+ # jeweler generated
16
+ pkg
17
+
18
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
19
+ #
20
+ # * Create a file at ~/.gitignore
21
+ # * Include files you want ignored
22
+ # * Run: git config --global core.excludesfile ~/.gitignore
23
+ #
24
+ # After doing this, these files will be ignored in all your git projects,
25
+ # saving you from having to 'pollute' every project you touch with them
26
+ #
27
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
28
+ #
29
+ # For MacOS:
30
+ #
31
+ #.DS_Store
32
+
33
+ # For TextMate
34
+ #*.tmproj
35
+ #tmtags
36
+
37
+ # For emacs:
38
+ #*~
39
+ #\#*
40
+ #.\#*
41
+
42
+ # For vim:
43
+ #*.swp
44
+
45
+ # For redcar:
46
+ #.redcar
47
+
48
+ # For rubinius:
49
+ #*.rbc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rtpl.gemspec
4
+ gemspec
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rtpl (0.0.0)
5
+ parslet (= 1.2.3)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ blankslate (2.1.2.4)
11
+ diff-lcs (1.1.3)
12
+ ffi (1.0.11)
13
+ guard (1.0.1)
14
+ ffi (>= 0.5.0)
15
+ thor (~> 0.14.6)
16
+ guard-rspec (0.6.0)
17
+ guard (>= 0.10.0)
18
+ parslet (1.2.3)
19
+ blankslate (~> 2.0)
20
+ rspec (2.8.0)
21
+ rspec-core (~> 2.8.0)
22
+ rspec-expectations (~> 2.8.0)
23
+ rspec-mocks (~> 2.8.0)
24
+ rspec-core (2.8.0)
25
+ rspec-expectations (2.8.0)
26
+ diff-lcs (~> 1.1.2)
27
+ rspec-mocks (2.8.0)
28
+ thor (0.14.6)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ guard-rspec (= 0.6.0)
35
+ rspec (~> 2.8.0)
36
+ rtpl!
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Eric Himmelreich
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ ____ __ ___
2
+ /\ _`\ /\ \__ /\_ \
3
+ \ \ \L\ \\ \ ,_\ _____\//\ \
4
+ \ \ , / \ \ \/ /\ '__`\\ \ \
5
+ \ \ \\ \ \ \ \_\ \ \L\ \\_\ \_
6
+ \ \_\ \_\\ \__\\ \ ,__//\____\
7
+ \/_/\/ / \/__/ \ \ \/ \/____/
8
+ \ \_\
9
+ \/_/
10
+
11
+ A Ruby port of [jtpl](http://jtpl.sourceforge.net/) using [Parslet](https://github.com/kschiess/parslet) instead of regexes all the way down.
12
+
13
+ Rspec tests are included. Tested against ruby-1.9.2-p290.
14
+
15
+ However this library is new, if you have a particularly complex jtpl
16
+ template. I suggest you add it to the rspec tests.
17
+
18
+ ## Contributing to rtpl
19
+
20
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
21
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
22
+ * Fork the project.
23
+ * Start a feature/bugfix branch.
24
+ * Commit and push until you are happy with your contribution.
25
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
26
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
27
+
28
+ ## Copyright
29
+
30
+ Copyright (c) 2012 Eric Himmelreich. See LICENSE.txt for
31
+ further details.
32
+
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new
5
+ task :default => :spec
@@ -0,0 +1,118 @@
1
+ begin
2
+ require 'parslet'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'parslet'
6
+ end
7
+
8
+ class Rtpl
9
+ attr_reader :vars, :ast, :parsed_blocks
10
+
11
+ def initialize(template)
12
+ @ast = Rtpl::Parser.new.parse(template)
13
+ @vars = {}
14
+ @parsed_blocks = {}
15
+ @parsed_blocks.default = ""
16
+ @transform = Rtpl::Transform.new
17
+ @sub_blocks = false
18
+ end
19
+
20
+ def assign(key, value)
21
+ @vars[key] = value
22
+ end
23
+
24
+ def parse(block_name)
25
+ if block_name =~ /\./
26
+ @sub_blocks = true
27
+ @parsed_blocks[block_name] +=
28
+ nested_output(@transform.apply(sub_block(block_name), :vars => @vars),
29
+ block_name)
30
+ else
31
+ @parsed_blocks[block_name] +=
32
+ block_output(@transform.apply(@ast, :vars => @vars).
33
+ detect{|b| b[:open][:name] == block_name })
34
+ end
35
+ end
36
+
37
+ def out(key = "main")
38
+ @parsed_blocks[key].to_s
39
+ end
40
+
41
+ private
42
+
43
+ def block_output(block)
44
+ raise ArgumentError if (block.nil? || block.empty?)
45
+ return block[:content].join unless @sub_blocks
46
+
47
+ before = block[:content].detect {|h| h.has_key?(:before) }
48
+ after = block[:content].detect {|h| h.has_key?(:after) }
49
+ inner_block = block[:content].detect {|h| h.has_key?(:open) }
50
+ before = before ? before[:before].join : ""
51
+ after = after ? after[:after].join : ""
52
+ key = block[:open][:name].to_s + "." + inner_block[:open][:name]
53
+ inner_block = @parsed_blocks[key]
54
+
55
+ #clear the inner block when parsing a parent block
56
+ @parsed_blocks[key] = ""
57
+ before.to_s + inner_block + after.to_s
58
+ end
59
+
60
+ def nested_output(block, block_name)
61
+ nested_block =
62
+ block[:content].
63
+ detect {|b| !b.instance_of?(String) && b.has_key?(:open)}
64
+ if nested_block.nil?
65
+ output = block[:content].join if block[:content]
66
+ else
67
+ before = block[:content].detect {|h| h.has_key?(:before) }
68
+ after = block[:content].detect {|h| h.has_key?(:after) }
69
+ before = before ? before[:before].join : ""
70
+ after = after ? after[:after].join : ""
71
+ output =
72
+ before +
73
+ @parsed_blocks["#{block_name}.#{nested_block[:open][:name]}"] +
74
+ after
75
+
76
+ # clear the key when parsing a parent block
77
+ @parsed_blocks["#{block_name}.#{nested_block[:open][:name]}"] = ""
78
+ end
79
+
80
+ output
81
+ end
82
+
83
+ def sub_block(block_name)
84
+ name_parts = block_name.split(".")
85
+ block = nil
86
+ tree = @transform.apply(@ast, :vars => @vars)
87
+
88
+ name_parts.each do |n|
89
+ if block
90
+ before = block.detect {|b| b.has_key?(:before) }
91
+ after = block.detect {|b| b.has_key?(:after) }
92
+ old_block = block
93
+ block =
94
+ if n == name_parts.last
95
+ block.detect {|b| b.has_key?(:open) && b[:open][:name] == n }
96
+ else
97
+ block.
98
+ detect {|b| b.has_key?(:open) && b[:open][:name] == n }[:content]
99
+ end
100
+
101
+ raise ArgumentError, "Could not find #{block_name}" if block.nil?
102
+
103
+ unless block.instance_of?(Array)
104
+ block.merge!(before) if before
105
+ block.merge!(after) if after
106
+ end
107
+ else
108
+ block =
109
+ tree.detect {|b| (b[:open] != "" && b[:open][:name]) == n }[:content]
110
+ end
111
+ end
112
+
113
+ block
114
+ end
115
+ end
116
+
117
+ require 'rtpl/parser'
118
+ require 'rtpl/transform'
@@ -0,0 +1,29 @@
1
+ class Rtpl::Parser < Parslet::Parser
2
+ root(:block)
3
+
4
+ rule(:block) { (open_block.as(:open) >> (nested_block | not_block).repeat.as(:content) >> close_block.as(:close) >> spc?).repeat(1) }
5
+
6
+ rule(:block?) { block.maybe }
7
+
8
+ rule(:open_block) { comment >> open_sym >> name.as(:name) >> end_comment }
9
+ rule(:close_block) { comment >> close_sym >> name.as(:name) >> end_comment }
10
+
11
+ rule(:nested_block) { not_block.repeat.as(:before) >> block >> not_block.repeat.as(:after) }
12
+
13
+ rule(:not_block?) { not_block.maybe }
14
+ rule(:not_block) { (open_block | close_block).absent? >> (var | text) }
15
+ rule(:not_blocks) { not_block.repeat }
16
+
17
+ rule(:comment) { str('<!--') >> spc? }
18
+ rule(:end_comment) { spc? >> str('-->') >> spc? }
19
+
20
+ rule(:close_sym) { spc? >> str('END:') >> spc? }
21
+ rule(:open_sym) { spc? >> str('BEGIN:') >> spc?}
22
+
23
+ rule(:var) { str('{') >> name.as(:var_name) >> str('}') }
24
+ rule(:text) { any.as(:text) }
25
+ rule(:name) { match('\w').repeat(1) }
26
+
27
+ rule(:space) { match('\s').repeat(1) }
28
+ rule(:spc?) { space.maybe }
29
+ end
@@ -0,0 +1,7 @@
1
+ class Rtpl::Transform < Parslet::Transform
2
+ attr_accessor :vars
3
+
4
+ rule(:var_name => simple(:x)) { vars[x.to_s] }
5
+ rule(:text => simple(:x)) { x.to_s }
6
+ rule(:text => sequence(:texts)) { texts.join }
7
+ end
@@ -0,0 +1,3 @@
1
+ class Rtpl
2
+ VERSION = '0.0.0'
3
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rtpl/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'rtpl'
7
+ s.version = Rtpl::VERSION
8
+ s.author = 'Eric Himmelreich'
9
+ s.email = 'eric@rawsyntax.com'
10
+ s.description = 'http://jtpl.sourceforge.net/ ported to ruby'
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.homepage = 'http://github.com/rawsyntax/rtpl'
14
+ s.licenses = ['MIT']
15
+ s.require_paths = ['lib']
16
+ s.summary = 'jtpl templates in ruby'
17
+
18
+ s.add_dependency('parslet', ['= 1.2.3'])
19
+
20
+ s.add_development_dependency('rspec', ['~> 2.8.0'])
21
+ s.add_development_dependency('guard-rspec', ['= 0.6.0'])
22
+ end
@@ -0,0 +1,11 @@
1
+ <!-- BEGIN: block_name-->
2
+ before_text
3
+ <!-- BEGIN: nested-->
4
+ before_text
5
+ <!-- BEGIN: nested2-->
6
+ the content of the block
7
+ <!-- END: nested2 -->
8
+ after_text
9
+ <!-- END: nested -->
10
+ after_text
11
+ <!-- END: block_name -->
@@ -0,0 +1,15 @@
1
+ <!-- BEGIN: block_name-->
2
+ before_text
3
+ <!-- BEGIN: nested-->
4
+ before_text
5
+ <!-- BEGIN: nested2-->
6
+ the content of the block
7
+ <!-- END: nested2 -->
8
+ after_text
9
+ <!-- BEGIN: nested2a-->
10
+ the content of the block
11
+ <!-- END: nested2a -->
12
+ after_text
13
+ <!-- END: nested -->
14
+ after_text
15
+ <!-- END: block_name -->
@@ -0,0 +1,3 @@
1
+ <!-- BEGIN: block_name-->
2
+ <!-- the content of the block-->
3
+ <!-- END: block_name -->
@@ -0,0 +1,7 @@
1
+ <!-- BEGIN: block_name-->
2
+ before_text
3
+ <!-- BEGIN: nested-->
4
+ the content of the block
5
+ <!-- END: nested -->
6
+ after_text
7
+ <!-- END: block_name -->
@@ -0,0 +1,10 @@
1
+ <!-- BEGIN: block_name-->
2
+ before_text
3
+ <!-- BEGIN: nested-->
4
+ the content of the block
5
+ <!-- END: nested -->
6
+ after_text
7
+ <!-- BEGIN: nested2-->
8
+ the content of the block
9
+ <!-- END: nested2 -->
10
+ <!-- END: block_name -->
@@ -0,0 +1,11 @@
1
+ <!-- BEGIN: block_name-->
2
+ before_text
3
+ <!-- BEGIN: nested-->
4
+ before_text
5
+ <!-- BEGIN: nested2-->
6
+ the content of the block
7
+ <!-- END: nested2 -->
8
+ after_text
9
+ <!-- END: nested -->
10
+ after_text
11
+ <!-- END: block_name -->
@@ -0,0 +1,3 @@
1
+ <!-- BEGIN: block_name-->
2
+ the content of the block
3
+ <!-- END: block_name -->
@@ -0,0 +1,3 @@
1
+ <!-- BEGIN: block_name-->
2
+ the {content} of the block
3
+ <!-- END: block_name -->
@@ -0,0 +1,3 @@
1
+ <!-- BEGIN: block_name-->
2
+ the {content} of the {var2} block
3
+ <!-- END: block_name -->
@@ -0,0 +1 @@
1
+ <!-- BEGIN: block_name--><!-- END: block_name -->
@@ -0,0 +1 @@
1
+ the content of the block<!-- END: block_name-->
@@ -0,0 +1,79 @@
1
+ <html>
2
+ <head>
3
+ <title>Sample 2</title>
4
+ </head>
5
+ <body>
6
+ <table>
7
+ <tr>
8
+ <td bgcolor="#75D2FF">line:1 col:1</td>
9
+ <td bgcolor="#CCEEFF">line:1 col:2</td>
10
+ <td bgcolor="#75D2FF">line:1 col:3</td>
11
+ <td bgcolor="#CCEEFF">line:1 col:4</td>
12
+ <td bgcolor="#75D2FF">line:1 col:5</td>
13
+ </tr>
14
+ <tr>
15
+ <td bgcolor="#75D2FF">line:2 col:1</td>
16
+ <td bgcolor="#CCEEFF">line:2 col:2</td>
17
+ <td bgcolor="#75D2FF">line:2 col:3</td>
18
+ <td bgcolor="#CCEEFF">line:2 col:4</td>
19
+ <td bgcolor="#75D2FF">line:2 col:5</td>
20
+ </tr>
21
+ <tr>
22
+ <td bgcolor="#75D2FF">line:3 col:1</td>
23
+ <td bgcolor="#CCEEFF">line:3 col:2</td>
24
+ <td bgcolor="#75D2FF">line:3 col:3</td>
25
+ <td bgcolor="#CCEEFF">line:3 col:4</td>
26
+ <td bgcolor="#75D2FF">line:3 col:5</td>
27
+ </tr>
28
+ <tr>
29
+ <td bgcolor="#75D2FF">line:4 col:1</td>
30
+ <td bgcolor="#CCEEFF">line:4 col:2</td>
31
+ <td bgcolor="#75D2FF">line:4 col:3</td>
32
+ <td bgcolor="#CCEEFF">line:4 col:4</td>
33
+ <td bgcolor="#75D2FF">line:4 col:5</td>
34
+ </tr>
35
+ <tr>
36
+ <td bgcolor="#75D2FF">line:5 col:1</td>
37
+ <td bgcolor="#CCEEFF">line:5 col:2</td>
38
+ <td bgcolor="#75D2FF">line:5 col:3</td>
39
+ <td bgcolor="#CCEEFF">line:5 col:4</td>
40
+ <td bgcolor="#75D2FF">line:5 col:5</td>
41
+ </tr>
42
+ <tr>
43
+ <td bgcolor="#75D2FF">line:6 col:1</td>
44
+ <td bgcolor="#CCEEFF">line:6 col:2</td>
45
+ <td bgcolor="#75D2FF">line:6 col:3</td>
46
+ <td bgcolor="#CCEEFF">line:6 col:4</td>
47
+ <td bgcolor="#75D2FF">line:6 col:5</td>
48
+ </tr>
49
+ <tr>
50
+ <td bgcolor="#75D2FF">line:7 col:1</td>
51
+ <td bgcolor="#CCEEFF">line:7 col:2</td>
52
+ <td bgcolor="#75D2FF">line:7 col:3</td>
53
+ <td bgcolor="#CCEEFF">line:7 col:4</td>
54
+ <td bgcolor="#75D2FF">line:7 col:5</td>
55
+ </tr>
56
+ <tr>
57
+ <td bgcolor="#75D2FF">line:8 col:1</td>
58
+ <td bgcolor="#CCEEFF">line:8 col:2</td>
59
+ <td bgcolor="#75D2FF">line:8 col:3</td>
60
+ <td bgcolor="#CCEEFF">line:8 col:4</td>
61
+ <td bgcolor="#75D2FF">line:8 col:5</td>
62
+ </tr>
63
+ <tr>
64
+ <td bgcolor="#75D2FF">line:9 col:1</td>
65
+ <td bgcolor="#CCEEFF">line:9 col:2</td>
66
+ <td bgcolor="#75D2FF">line:9 col:3</td>
67
+ <td bgcolor="#CCEEFF">line:9 col:4</td>
68
+ <td bgcolor="#75D2FF">line:9 col:5</td>
69
+ </tr>
70
+ <tr>
71
+ <td bgcolor="#75D2FF">line:10 col:1</td>
72
+ <td bgcolor="#CCEEFF">line:10 col:2</td>
73
+ <td bgcolor="#75D2FF">line:10 col:3</td>
74
+ <td bgcolor="#CCEEFF">line:10 col:4</td>
75
+ <td bgcolor="#75D2FF">line:10 col:5</td>
76
+ </tr>
77
+ </table>
78
+ </body>
79
+ </html>
@@ -0,0 +1,18 @@
1
+ <!-- BEGIN: main -->
2
+ <html>
3
+ <head>
4
+ <title>{TITLE}</title>
5
+ </head>
6
+ <body>
7
+ <table>
8
+ <!-- BEGIN: line -->
9
+ <tr>
10
+ <!-- BEGIN: row -->
11
+ <td bgcolor="{BGCOLOR}">{VARIABLE}</td>
12
+ <!-- END: row -->
13
+ </tr>
14
+ <!-- END: line -->
15
+ </table>
16
+ </body>
17
+ </html>
18
+ <!-- END: main -->
@@ -0,0 +1,5 @@
1
+ before_text
2
+ <!-- BEGIN: block_name-->
3
+ the content of the block
4
+ <!-- END: block_name -->
5
+ after_text
@@ -0,0 +1 @@
1
+ <!-- BEGIN: block_name-->the content of the block
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rtpl::Parser do
4
+ let(:parser) { Rtpl::Parser.new }
5
+ let(:f) { fixtures }
6
+
7
+ describe 'spaces' do
8
+ it 'should parse one' do
9
+ parser.space.should parse(' ')
10
+ end
11
+
12
+ it 'should parse multiple' do
13
+ parser.space.should parse(' ')
14
+ end
15
+ end
16
+
17
+ describe 'spc?' do
18
+ it 'should parse empty string' do
19
+ parser.spc?.should parse('')
20
+ end
21
+
22
+ it 'should parse one space' do
23
+ parser.spc?.should parse(' ')
24
+ end
25
+
26
+ it 'should parse multiple spaces' do
27
+ parser.spc?.should parse(' ')
28
+ end
29
+ end
30
+
31
+ describe 'name' do
32
+ it 'should parse a block_name' do
33
+ parser.name.should parse('main')
34
+ end
35
+
36
+ it 'should parse a longer block_name' do
37
+ parser.name.should parse('block_name')
38
+ end
39
+
40
+ it 'should not accept whitespace' do
41
+ parser.name.should_not parse('name ')
42
+ end
43
+ end
44
+
45
+ describe 'open_sym' do
46
+ it 'should parse an open_sym string with whitespace' do
47
+ parser.open_sym.should parse(' BEGIN: ')
48
+ end
49
+
50
+ it 'should parse an open_sym string without whitespace' do
51
+ parser.open_sym.should parse('BEGIN:')
52
+ end
53
+
54
+ it 'should require a colon' do
55
+ parser.open_sym.should_not parse('BEGIN')
56
+ end
57
+ end
58
+
59
+ describe 'close_sym' do
60
+ it 'should parse a close_sym string with whitespace' do
61
+ parser.close_sym.should parse(' END: ')
62
+ end
63
+
64
+ it 'should parse a close_sym string without whitespace' do
65
+ parser.close_sym.should parse('END:')
66
+ end
67
+
68
+ it 'should require a colon' do
69
+ parser.close_sym.should_not parse('END')
70
+ end
71
+ end
72
+
73
+ describe 'comment' do
74
+ it 'should parse a comment' do
75
+ parser.comment.should parse('<!--')
76
+ end
77
+
78
+ it 'should parse a comment followed by whitespace' do
79
+ parser.comment.should parse('<!-- ')
80
+ end
81
+ end
82
+
83
+ describe 'end_comment' do
84
+ it 'should parse an end_comment' do
85
+ parser.end_comment.should parse('-->')
86
+ end
87
+
88
+ it 'should parse an end_comment preceded by whitespace' do
89
+ parser.end_comment.should parse(' -->')
90
+ end
91
+ end
92
+
93
+ describe 'open_block' do
94
+ it 'should parse an open_block' do
95
+ parser.open_block.should parse('<!-- BEGIN: block_name-->')
96
+ end
97
+ end
98
+
99
+ describe 'close_block' do
100
+ it 'should parse an close_block' do
101
+ parser.close_block.should parse('<!-- END: block_name-->')
102
+ end
103
+ end
104
+
105
+ describe 'block' do
106
+ subject { Rtpl::Parser.new.block }
107
+
108
+ it { should parse(f.empty_block) }
109
+ it { should parse(f.block_with_plaintext) }
110
+ it { should parse(f.block_with_variable) }
111
+ it { should parse(f.block_with_variables) }
112
+ it { should parse(f.block_with_html_comment) }
113
+ it { should parse(f.block_with_nested_block) }
114
+ it { should parse(f.block_with_nested_blocks) }
115
+ it { should parse(f.block_with_deep_nested_block) }
116
+ it { should parse(f.block_with_deep_nested_blocks) }
117
+
118
+ it { should_not parse(f.open_block_without_end) }
119
+ it { should_not parse(f.end_block_without_open) }
120
+ end
121
+
122
+ describe 'nested_block' do
123
+ it 'should parse a nested_block' do
124
+ parser.nested_block.should parse(f.nested_block)
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rtpl::Transform do
4
+ let(:f) { fixtures }
5
+ let(:transform) { Rtpl::Transform.new }
6
+ let(:parser) { Rtpl::Parser.new }
7
+
8
+ it 'should substitue variable values' do
9
+ vars = {'two' => 'exactly', 'cool' => '0'}
10
+ tree = parser.not_blocks.parse("string with {two} {cool} vars")
11
+
12
+ transform.apply(tree, :vars => vars).join.should ==
13
+ "string with exactly 0 vars"
14
+ end
15
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rtpl do
4
+ let(:f) { fixtures }
5
+ let(:rtpl) { Rtpl.new(f.block_with_plaintext) }
6
+ let(:rtpl_nested) { Rtpl.new(f.block_with_nested_block) }
7
+ let(:rtpl_nested_nested) { Rtpl.new(f.block_with_nested_nested_block) }
8
+ let(:sample2) { Rtpl.new(f.jtpl_sample2)}
9
+
10
+ describe 'assign' do
11
+
12
+ it 'should alter the vars hash' do
13
+ rtpl.assign("k","v")
14
+
15
+ rtpl.vars.should == {"k" => "v"}
16
+ end
17
+ end
18
+
19
+ describe 'parse' do
20
+ it 'should parse a top level block and add it to parsed_blocks' do
21
+ rtpl.parse("block_name")
22
+
23
+ rtpl.parsed_blocks["block_name"].should == "the content of the block\n"
24
+ end
25
+
26
+ it 'should parse a block repeatedly and accumulate parsed_blocks' do
27
+ 2.times { rtpl.parse("block_name") }
28
+
29
+ rtpl.parsed_blocks["block_name"].should ==
30
+ "the content of the block\nthe content of the block\n"
31
+ end
32
+
33
+ it 'should parse a sub_block' do
34
+ rtpl_nested.parse("block_name.nested")
35
+
36
+ rtpl_nested.parsed_blocks["block_name.nested"].should ==
37
+ "the content of the block\n"
38
+ end
39
+
40
+ it 'should parse a sub_block then a top level block pushing text up' do
41
+ rtpl_nested.parse("block_name.nested")
42
+ rtpl_nested.parse("block_name")
43
+
44
+ rtpl_nested.parsed_blocks["block_name"].should ==
45
+ "before_text\nthe content of the block\nafter_text\n"
46
+ end
47
+
48
+ it 'should parse a nested nested_block' do
49
+ rtpl_nested_nested.parse("block_name.nested.nested2")
50
+ rtpl_nested_nested.parse("block_name.nested")
51
+ rtpl_nested_nested.parse("block_name").should ==
52
+ "before_text\nbefore_text\nthe content of the block\nafter_text\nafter_text\n"
53
+
54
+ end
55
+
56
+ it 'should error when trying to parse a nonexistent nested_block' do
57
+ lambda { rtpl_nested.parse("block_name.z") }.should raise_error ArgumentError
58
+ end
59
+
60
+ it 'should error when trying to parse a nonexistent block' do
61
+ lambda { rtpl.parse("z") }.should raise_error ArgumentError
62
+ lambda { rtpl.parse("") }.should raise_error ArgumentError
63
+ end
64
+ end
65
+
66
+ describe 'out' do
67
+ it 'should take a key and return a string' do
68
+ rtpl_nested.parse("block_name.nested")
69
+ rtpl_nested.parse("block_name")
70
+
71
+ rtpl_nested.out("block_name").should ==
72
+ "before_text\nthe content of the block\nafter_text\n"
73
+ end
74
+ end
75
+
76
+ describe 'jtpl samples' do
77
+ it 'should match the output from jtpl' do
78
+ output = File.open(File.join(File.dirname(__FILE__), "fixtures", "jtpl_sample2.html"))
79
+ sample2.assign('TITLE', 'Sample 2')
80
+
81
+ 10.times do |i|
82
+ 5.times do |j|
83
+ sample2.assign('BGCOLOR', j % 2 == 0 ? '#75D2FF' : '#CCEEFF')
84
+ sample2.assign('VARIABLE', "line:#{i + 1} col:#{j + 1}")
85
+ sample2.parse("main.line.row")
86
+ end
87
+
88
+ sample2.parse("main.line")
89
+ end
90
+
91
+ sample2.parse("main")
92
+ sample2.out.should == output.read
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,28 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rspec'
5
+ require 'parslet'
6
+ require 'parslet/rig/rspec'
7
+ require 'yaml'
8
+ require 'ostruct'
9
+ require 'rtpl'
10
+
11
+ # Requires supporting files with custom matchers and macros, etc,
12
+ # in ./support/ and its subdirectories.
13
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
14
+
15
+ def fixtures
16
+ return @fixtures if @fixtures
17
+ files = {}
18
+
19
+ Dir[File.join(File.dirname(__FILE__), *%w[fixtures *.jtpl])].each do |path|
20
+ files[File.basename(path, '.jtpl').to_sym] =
21
+ File.open(path) {|f| f.read }
22
+ end
23
+
24
+ OpenStruct.new(files)
25
+ end
26
+
27
+ RSpec.configure do |config|
28
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rtpl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Himmelreich
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-10 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: parslet
16
+ requirement: &70180936501620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - =
20
+ - !ruby/object:Gem::Version
21
+ version: 1.2.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70180936501620
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70180936500600 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.8.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70180936500600
36
+ - !ruby/object:Gem::Dependency
37
+ name: guard-rspec
38
+ requirement: &70180936493640 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - =
42
+ - !ruby/object:Gem::Version
43
+ version: 0.6.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70180936493640
47
+ description: http://jtpl.sourceforge.net/ ported to ruby
48
+ email: eric@rawsyntax.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .rspec
55
+ - Gemfile
56
+ - Gemfile.lock
57
+ - Guardfile
58
+ - LICENSE.txt
59
+ - README.markdown
60
+ - Rakefile
61
+ - lib/rtpl.rb
62
+ - lib/rtpl/parser.rb
63
+ - lib/rtpl/transform.rb
64
+ - lib/rtpl/version.rb
65
+ - rtpl.gemspec
66
+ - spec/fixtures/block_with_deep_nested_block.jtpl
67
+ - spec/fixtures/block_with_deep_nested_blocks.jtpl
68
+ - spec/fixtures/block_with_html_comment.jtpl
69
+ - spec/fixtures/block_with_nested_block.jtpl
70
+ - spec/fixtures/block_with_nested_blocks.jtpl
71
+ - spec/fixtures/block_with_nested_nested_block.jtpl
72
+ - spec/fixtures/block_with_plaintext.jtpl
73
+ - spec/fixtures/block_with_variable.jtpl
74
+ - spec/fixtures/block_with_variables.jtpl
75
+ - spec/fixtures/empty_block.jtpl
76
+ - spec/fixtures/end_block_without_open.jtpl
77
+ - spec/fixtures/jtpl_sample2.html
78
+ - spec/fixtures/jtpl_sample2.jtpl
79
+ - spec/fixtures/nested_block.jtpl
80
+ - spec/fixtures/open_block_without_end.jtpl
81
+ - spec/rtpl/parser_spec.rb
82
+ - spec/rtpl/transform_spec.rb
83
+ - spec/rtpl_spec.rb
84
+ - spec/spec_helper.rb
85
+ homepage: http://github.com/rawsyntax/rtpl
86
+ licenses:
87
+ - MIT
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 1.8.10
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: jtpl templates in ruby
110
+ test_files: []