ltdtemplate 0.1.5 → 0.2.1

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.
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