ltdtemplate 0.1.5 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.txt CHANGED
@@ -1,3 +1,14 @@
1
+ 2013-07-28 Version 0.2.1
2
+ Added array.{each,each_rnd,each_seq} methods (executing the code
3
+ block supplied as the first parameter with parameters key and
4
+ value).
5
+
6
+ Added array/ and array% methods for parameter interpolation with
7
+ supporting changes to ::Code::Parameters.
8
+
9
+ Namespace and array to_native methods now dynamically return
10
+ an array, hash, or Sarah as required for the data.
11
+
1
12
  2013-07-24 Version 0.1.5
2
13
  Added RESOURCES.txt to .yardopts. OOPS!
3
14
 
data/TEMPLATE_MANUAL.html CHANGED
@@ -431,17 +431,35 @@ matrix[0, 0] /* => 1 */ matrix['type] /* => identity */</code></blockquote>
431
431
 
432
432
  <tr><td><code>class</code></td><td>Returns the string "Array"</td></tr>
433
433
 
434
+ <tr><td><code>each(</code><i>code_block</i><code>)</code></td>
435
+ <td>Executes <i>code_block</i><code>.each_seq(</code><i>index</i>,
436
+ <i>value</i><code>)</code> for each sequential index then
437
+ <i>code_block</i><code>.each_rnd(</code><i>key</i>,
438
+ <i>value</i><code>)</code> for each random-access key
439
+ and returns an array of results (since 0.2.1)</td></tr>
440
+
441
+ <tr><td><code>each_rnd(</code><i>code_block</i><code>)</code></td>
442
+ <td>Executes <i>code_block</i><code>.each_rnd(</code><i>key</i>,
443
+ <i>value</i><code>)</code> for each random-access key
444
+ and returns an array of results (since 0.2.1)</td></tr>
445
+
446
+ <tr><td><code>each_seq(</code><i>code_block</i><code>)</code></td>
447
+ <td>Executes <i>code_block</i><code>.each_seq(</code><i>index</i>,
448
+ <i>value</i><code>)</code> for each sequential index
449
+ and returns an array of results (since 0.2.1)</td></tr>
450
+
434
451
  <tr><td><code>join</code></td><td>Joins sequential (positional)
435
452
  elements</td></tr>
436
453
 
437
454
  <tr><td><code>join(</code><i>separator</i><code>)</code></td><td>Join with
438
- <i>separator</i> between elements</td></tr>
455
+ <i>separator</i> between sequential (positional) elements</td></tr>
439
456
 
440
457
  <tr><td><code>join(</code><i>two</i><code>, </code><i>first</i><code>,
441
458
  </code><i>middle</i><code>, </code><i>last</i><code>)</code></td>
442
- <td>Joins two elements with <i>two</i> as the separator or more than two
443
- elements with <i>first</i> as the first separator, <i>last</i> as the
444
- last separator, and <i>middle</i> for all other separators</td></tr>
459
+ <td>Joins two sequential elements with <i>two</i> as the separator or
460
+ more than two sequential elements with <i>first</i> as the first
461
+ separator, <i>last</i> as the last separator, and <i>middle</i> for
462
+ all other separators</td></tr>
445
463
 
446
464
  <tr><td><code>pop</code>, <code>-&gt;</code></td><td>Pop the last sequential
447
465
  element</td></tr>
@@ -470,6 +488,14 @@ matrix[0, 0] /* => 1 */ matrix['type] /* => identity */</code></blockquote>
470
488
  <td>Adds zero or more elements in the <i>list</i> to the beginning of
471
489
  the array</td></tr>
472
490
 
491
+ <tr><td><code>/</code></td><td>Interpolate the sequential and random-access
492
+ values of the array into the positional and named parameters of another
493
+ method call (since 0.2.1)</td></tr>
494
+
495
+ <tr><td><code>%</code></td>
496
+ <td>Interpolate pairs of sequential values in the array as named
497
+ parameters of another method call (since 0.2.1)</td></tr>
498
+
473
499
  </table>
474
500
 
475
501
  <p><a href='#codeblock_syntax'>Code blocks</a> may be bound as methods for
@@ -8,6 +8,8 @@ require 'ltdtemplate/code'
8
8
 
9
9
  class LtdTemplate::Code::Parameters < LtdTemplate::Code
10
10
 
11
+ attr_reader :positional, :named
12
+
11
13
  #
12
14
  # Create a parameter list builder with code to generate positional
13
15
  # values and possibly code to generate named values.
@@ -24,17 +26,43 @@ class LtdTemplate::Code::Parameters < LtdTemplate::Code
24
26
  # and return a corresponding array t-value.
25
27
  #
26
28
  def get_value (opts = {})
27
- positional = @positional.map { |val| val.get_value }
28
29
  named = {}
30
+
31
+ # Process the positional parameters (pos1, ..., posN)
32
+ positional = @positional.map do |code|
33
+ val = code.get_value
34
+ if val.is_a? LtdTemplate::Code::Parameters
35
+ if val.named.is_a? Hash
36
+ # Named parameters from array/
37
+ val.named.each { |key, val| named[key] = val }
38
+ elsif val.named.is_a? Array
39
+ # Named parameters from array%
40
+ val.named.each_slice(2) do |key, val|
41
+ named[key.get_value.to_native] = val if val
42
+ end
43
+ end
44
+ val.positional # Positional parameters from array/
45
+ else val
46
+ end
47
+ end.flatten
48
+
49
+ # Process the named parameters (.. key1, val1, ..., keyN, valN)
29
50
  if @named
30
- @named.each_slice(2) do |key, val|
31
- named[key.get_value.to_native] = val.get_value
51
+ if @named.is_a? Hash then named.merge! @named
52
+ else
53
+ @named.each_slice(2) do |key, val|
54
+ named[key.get_value.to_native] = val.get_value if val
55
+ end
32
56
  end
33
57
  scalar = false
34
58
  else
35
- scalar = positional.size == 1
59
+ scalar = positional.size == 1 and !named.empty?
36
60
  end
37
- @template.factory(:array).set_value(positional, named, scalar)
61
+
62
+ array = @template.factory(:array).set_value(positional, named, scalar)
63
+
64
+ # Parameters may get called if chained, e.g. array/.type
65
+ opts[:method] ? array.get_value(opts) : array
38
66
  end
39
67
 
40
68
  end
@@ -45,13 +45,21 @@ class LtdTemplate::Value::Array < LtdTemplate::Code
45
45
  end
46
46
 
47
47
  def to_boolean; true; end
48
- def to_native; @sarah.seq.map { |val| val.to_native }; end
48
+ def to_native
49
+ if @sarah.rnd_size == 0 then native = []
50
+ elsif @sarah.seq_size == 0 then native = {}
51
+ else native = Sarah.new
52
+ end
53
+ @sarah.each { |key, val| native[key] = val.to_native }
54
+ native
55
+ end
49
56
  def to_text; @sarah.seq.map { |val| val.to_text }.join ''; end
50
57
 
51
58
  def get_value (opts = {})
52
59
  case opts[:method]
53
60
  when nil, 'call' then self
54
61
  when 'class' then @template.factory :string, 'Array'
62
+ when 'each', 'each_rnd', 'each_seq' then do_each opts
55
63
  when 'join' then do_join opts
56
64
  when 'pop', '->' then do_pop opts
57
65
  when 'push', '+>' then do_push opts
@@ -61,6 +69,8 @@ class LtdTemplate::Value::Array < LtdTemplate::Code
61
69
  when 'size' then @template.factory :number, @sarah.size
62
70
  when 'type' then @template.factory :string, 'array'
63
71
  when 'unshift', '<+' then do_unshift opts
72
+ when '/' then @template.factory :parameters, @sarah.seq, @sarah.rnd
73
+ when '%' then @template.factory :parameters, [], @sarah.seq
64
74
  else do_method opts, 'Array'
65
75
  end
66
76
  end
@@ -110,6 +120,35 @@ class LtdTemplate::Value::Array < LtdTemplate::Code
110
120
  self
111
121
  end
112
122
 
123
+ #
124
+ # Loop over each key, value
125
+ #
126
+ def do_each (opts)
127
+ results = @template.factory :array
128
+ if params = opts[:parameters] and params.positional.size > 0
129
+ body = params.positional[0]
130
+ if opts[:method] != 'each_rnd'
131
+ @sarah.seq.each_index do |idx|
132
+ @template.use :iterations
133
+ body_params = @template.factory :parameters,
134
+ [@template.factory(:number, idx), @sarah.seq[idx]]
135
+ results.sarah.push body.get_value(:method => 'each_seq',
136
+ :parameters => body_params)
137
+ end
138
+ end
139
+ if opts[:method] != 'each_seq'
140
+ @sarah.rnd.each do |key, val|
141
+ @template.use :iterations
142
+ body_params = @template.factory :parameters,
143
+ [map_native_value(key), val]
144
+ results.sarah.push body.get_value(:method => 'each_rnd',
145
+ :parameters => body_params)
146
+ end
147
+ end
148
+ end
149
+ results
150
+ end
151
+
113
152
  #
114
153
  # Combine array element values into a string
115
154
  #
@@ -20,6 +20,18 @@ class LtdTemplate::Value::Namespace < LtdTemplate::Value::Array
20
20
  clear
21
21
  end
22
22
 
23
+ def to_native
24
+ if @sarah.rnd_size == 3 then native = []
25
+ elsif @sarah.seq_size == 0 then native = {}
26
+ else native = Sarah.new
27
+ end
28
+ @sarah.each do |key, value|
29
+ # Exclude some permanent namespace attributes
30
+ native[key] = value.to_native unless key =~ /^[_@$]$/
31
+ end
32
+ native
33
+ end
34
+
23
35
  #
24
36
  # Clear values except for permanent namespace attributes.
25
37
  #
@@ -103,7 +115,7 @@ class LtdTemplate::Value::Namespace < LtdTemplate::Value::Array
103
115
  end
104
116
 
105
117
  def do_loop (opts)
106
- results = @template.factory(:array)
118
+ results = @template.factory :array
107
119
  if params = opts[:parameters] and params.positional.size > 1
108
120
  params = params.positional
109
121
  while params[0].get_value(:method => 'call').to_boolean
data/ltdtemplate.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "ltdtemplate"
3
- s.version = "0.1.5"
4
- s.date = "2013-07-24"
3
+ s.version = "0.2.1"
4
+ s.date = "2013-07-28"
5
5
  s.authors = ["Brian Katzung"]
6
6
  s.email = ["briank@kappacs.com"]
7
7
  s.homepage = "http://rubygems.org/gems/ltdtemplate"
data/test/07each.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'minitest/autorun'
2
+ require 'ltdtemplate'
3
+
4
+ class TestLtdTemplate_07 < MiniTest::Unit::TestCase
5
+
6
+ def setup
7
+ @tpl = LtdTemplate.new
8
+ end
9
+
10
+ def test_each
11
+ @tpl.parse <<'TPL'
12
+ <<a=(1,2,3..'four,4,'five,5,'six,6,7,7)
13
+ a.each({ $.*($.method,$_[0].type,$_[0],$_[1]).join(",") }).join(";")
14
+ .>>
15
+ TPL
16
+ expected = {}
17
+ %w(
18
+ each_seq,number,0,1
19
+ each_seq,number,1,2
20
+ each_seq,number,2,3
21
+ each_rnd,string,four,4
22
+ each_rnd,string,five,5
23
+ each_rnd,string,six,6
24
+ each_rnd,number,7,7
25
+ ).each { |exp| expected[exp] = nil }
26
+ actual = {}
27
+ @tpl.render.split(?;).each { |res| actual[res] = nil }
28
+ assert_equal(expected, actual, "array.each")
29
+ end
30
+
31
+ def test_each_rnd
32
+ @tpl.parse <<'TPL'
33
+ <<a=(1,2,3..'four,4,'five,5,'six,6,7,7)
34
+ a.each_rnd({ $.*($.method,$_[0].type,$_[0],$_[1]).join(",") }).join(";")
35
+ .>>
36
+ TPL
37
+ expected = {}
38
+ %w(
39
+ each_rnd,string,four,4
40
+ each_rnd,string,five,5
41
+ each_rnd,string,six,6
42
+ each_rnd,number,7,7
43
+ ).each { |exp| expected[exp] = nil }
44
+ actual = {}
45
+ @tpl.render.split(?;).each { |res| actual[res] = nil }
46
+ assert_equal(expected, actual, "array.each_rnd")
47
+ end
48
+
49
+ def test_each_seq
50
+ @tpl.parse <<'TPL'
51
+ <<a=(1,2,3..'four,4,'five,5,'six,6,7,7)
52
+ a.each_seq({ $.*($.method,$_[0].type,$_[0],$_[1]).join(",") }).join(";")
53
+ .>>
54
+ TPL
55
+ expected = {}
56
+ %w(
57
+ each_seq,number,0,1
58
+ each_seq,number,1,2
59
+ each_seq,number,2,3
60
+ ).each { |exp| expected[exp] = nil }
61
+ actual = {}
62
+ @tpl.render.split(?;).each { |res| actual[res] = nil }
63
+ assert_equal(expected, actual, "array.each_seq")
64
+ end
65
+
66
+ end
67
+
68
+ # END
@@ -0,0 +1,38 @@
1
+ require 'minitest/autorun'
2
+ require 'ltdtemplate'
3
+
4
+ class TestLtdTemplate_08 < MiniTest::Unit::TestCase
5
+
6
+ def setup
7
+ @tpl = LtdTemplate.new
8
+ end
9
+
10
+ def test_interpolate1_slash
11
+ @tpl.parse '<<a=(1,2)b=(a/)b.join(",">>'
12
+ assert_equal '1,2', @tpl.render, "a=(1,2)b=(a/)b.join(,)"
13
+ @tpl.parse '<<a=(1,2) $.*(a/,a/).join(",")>>'
14
+ assert_equal "1,2,1,2", @tpl.render, "a=(1,2)$.*(a/,a/).join"
15
+ @tpl.parse '<<a=(1,2) $.*(a).join(",") " " $.*(a/).join(",")>>'
16
+ assert_equal "12 1,2", @tpl.render, "$.*(a).join $.*(a/).join"
17
+ end
18
+
19
+ def test_interpolate2_percent
20
+ @tpl.parse '<<a=("key","value")b=(a%)b.each_rnd({_.join(";")})>>'
21
+ assert_equal 'key;value', @tpl.render, 'a=(key,value) b=(a%)'
22
+ end
23
+
24
+ def test_interpolate3
25
+ @tpl.parse <<'TPL'
26
+ << a=(2, 3 .. 'a, 'a, 'x, 'a, 'y, 'a) b=(5, 6 .. 'b, 'b, 'x, 'b, 'y, 'b)
27
+ c=('c, 'c, 'x, 'c, 'y, 'c) d=(1, a/, 4, b/, 7, c%, 8 .. 'd, 'd, 'y, 'd) >>
28
+ TPL
29
+ @tpl.render
30
+ d = @tpl.namespace.get_item(?d).to_native
31
+ assert_equal [1, 2, 3, 4, 5, 6, 7, 8], d.seq, "d (sequential)"
32
+ assert_equal({ ?a => ?a, ?b => ?b, ?c => ?c, ?d => ?d,
33
+ ?x => ?c, ?y => ?d }, d.rnd, "d (random-access)")
34
+ end
35
+
36
+ end
37
+
38
+ # END
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 2
7
8
  - 1
8
- - 5
9
- version: 0.1.5
9
+ version: 0.2.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Brian Katzung
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2013-07-24 00:00:00 -05:00
17
+ date: 2013-07-28 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -52,7 +52,9 @@ files:
52
52
  - test/04number.rb
53
53
  - test/05string.rb
54
54
  - test/06array.rb
55
+ - test/07each.rb
55
56
  - test/03tpl_singletons.rb
57
+ - test/08interpolate.rb
56
58
  - test/01instance.rb
57
59
  - test/02tpl_literal.rb
58
60
  has_rdoc: true
@@ -92,6 +94,8 @@ test_files:
92
94
  - test/04number.rb
93
95
  - test/05string.rb
94
96
  - test/06array.rb
97
+ - test/07each.rb
95
98
  - test/03tpl_singletons.rb
99
+ - test/08interpolate.rb
96
100
  - test/01instance.rb
97
101
  - test/02tpl_literal.rb