wlang 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/LICENCE.rdoc +25 -0
  2. data/README.rdoc +111 -0
  3. data/bin/wlang +24 -0
  4. data/doc/specification/about.rdoc +61 -0
  5. data/doc/specification/dialects.wtpl +0 -0
  6. data/doc/specification/examples.rb +3 -0
  7. data/doc/specification/glossary.wtpl +14 -0
  8. data/doc/specification/hosting.rdoc +0 -0
  9. data/doc/specification/overview.rdoc +116 -0
  10. data/doc/specification/rulesets.wtpl +87 -0
  11. data/doc/specification/specification.css +52 -0
  12. data/doc/specification/specification.html +1361 -0
  13. data/doc/specification/specification.js +8 -0
  14. data/doc/specification/specification.wtpl +41 -0
  15. data/doc/specification/specification.yml +430 -0
  16. data/doc/specification/symbols.wtpl +16 -0
  17. data/lib/wlang.rb +186 -0
  18. data/lib/wlang/basic_object.rb +19 -0
  19. data/lib/wlang/dialect.rb +230 -0
  20. data/lib/wlang/dialect_dsl.rb +136 -0
  21. data/lib/wlang/dialect_loader.rb +69 -0
  22. data/lib/wlang/dialects/coderay_dialect.rb +35 -0
  23. data/lib/wlang/dialects/plain_text_dialect.rb +75 -0
  24. data/lib/wlang/dialects/rdoc_dialect.rb +33 -0
  25. data/lib/wlang/dialects/ruby_dialect.rb +35 -0
  26. data/lib/wlang/dialects/sql_dialect.rb +38 -0
  27. data/lib/wlang/dialects/standard_dialects.rb +113 -0
  28. data/lib/wlang/dialects/xhtml_dialect.rb +40 -0
  29. data/lib/wlang/encoder.rb +66 -0
  30. data/lib/wlang/encoder_set.rb +117 -0
  31. data/lib/wlang/errors.rb +37 -0
  32. data/lib/wlang/intelligent_buffer.rb +94 -0
  33. data/lib/wlang/parser.rb +251 -0
  34. data/lib/wlang/parser_context.rb +146 -0
  35. data/lib/wlang/ruby_extensions.rb +21 -0
  36. data/lib/wlang/rule.rb +66 -0
  37. data/lib/wlang/rule_set.rb +93 -0
  38. data/lib/wlang/rulesets/basic_ruleset.rb +75 -0
  39. data/lib/wlang/rulesets/buffering_ruleset.rb +103 -0
  40. data/lib/wlang/rulesets/context_ruleset.rb +115 -0
  41. data/lib/wlang/rulesets/encoding_ruleset.rb +73 -0
  42. data/lib/wlang/rulesets/imperative_ruleset.rb +132 -0
  43. data/lib/wlang/rulesets/ruleset_utils.rb +296 -0
  44. data/lib/wlang/template.rb +79 -0
  45. data/lib/wlang/wlang_command.rb +54 -0
  46. data/lib/wlang/wlang_command_options.rb +158 -0
  47. data/test/sandbox.rb +1 -0
  48. data/test/test_all.rb +8 -0
  49. data/test/wlang/anagram_bugs_test.rb +111 -0
  50. data/test/wlang/basic_ruleset_test.rb +52 -0
  51. data/test/wlang/buffering_ruleset_test.rb +102 -0
  52. data/test/wlang/buffering_template1.wtpl +1 -0
  53. data/test/wlang/buffering_template2.wtpl +1 -0
  54. data/test/wlang/buffering_template3.wtpl +1 -0
  55. data/test/wlang/buffering_template4.wtpl +1 -0
  56. data/test/wlang/buffering_template5.wtpl +1 -0
  57. data/test/wlang/context_ruleset_test.rb +32 -0
  58. data/test/wlang/data.rb +3 -0
  59. data/test/wlang/encoder_set_test.rb +42 -0
  60. data/test/wlang/imperative_ruleset_test.rb +107 -0
  61. data/test/wlang/intelligent_buffer_test.rb +194 -0
  62. data/test/wlang/othersymbols_test.rb +16 -0
  63. data/test/wlang/parser_context_test.rb +29 -0
  64. data/test/wlang/parser_test.rb +89 -0
  65. data/test/wlang/plain_text_dialect_test.rb +21 -0
  66. data/test/wlang/ruby_dialect_test.rb +100 -0
  67. data/test/wlang/ruby_expected.rb +3 -0
  68. data/test/wlang/ruby_template.wrb +3 -0
  69. data/test/wlang/ruleset_utils_test.rb +245 -0
  70. data/test/wlang/specification_examples_test.rb +52 -0
  71. data/test/wlang/test_utils.rb +25 -0
  72. data/test/wlang/wlang_test.rb +80 -0
  73. metadata +136 -0
@@ -0,0 +1,102 @@
1
+ require 'test/unit'
2
+ require 'wlang'
3
+ require 'wlang/test_utils.rb'
4
+ require 'wlang/rulesets/buffering_ruleset'
5
+
6
+ # Tests the Scoping ruleset
7
+ class WLang::BufferingRuleSetTest < Test::Unit::TestCase
8
+ include WLang::TestUtils
9
+
10
+ # Installs a dialect on wlang
11
+ def setup
12
+ WLang::dialect "buffering-test" do
13
+ rules WLang::RuleSet::Basic
14
+ rules WLang::RuleSet::Buffering
15
+ rule ';' do |parser, offset|
16
+ text, reached = parser.parse(offset)
17
+ [text.upcase, reached]
18
+ end
19
+ end
20
+ end
21
+
22
+ # Tests input rule
23
+ def test_input
24
+ expected = read_relative_file("ruby_template.wrb", __FILE__)
25
+ template = relative_template("<<{ruby_template.wrb}", "buffering-test", __FILE__)
26
+ result = template.instantiate()
27
+ assert_equal(expected, result)
28
+ end
29
+
30
+ # Tests that input rule allows creating file name in wlang
31
+ def test_input_accepts_injection
32
+ expected = read_relative_file("ruby_template.wrb", __FILE__)
33
+ template = relative_template("<<{ruby_template.wrb}", "buffering-test", __FILE__)
34
+ result = template.instantiate("", "ext" => "wrb")
35
+ assert_equal(expected, result)
36
+ end
37
+
38
+ # Tests output rule
39
+ def test_output
40
+ output = relative_file("buffering_ruleset_test_output.txt", __FILE__)
41
+ File.delete(output) if File.exists?(output)
42
+ template = relative_template(">>{buffering_ruleset_test_output.txt}{an output}", "buffering-test", __FILE__)
43
+ assert_equal("", template.instantiate())
44
+ assert_equal("an output", File.read(output))
45
+ File.delete(output) if File.exists?(output)
46
+ end
47
+
48
+ # Tests output rule allows creating file name in wlang
49
+ def test_output_accepts_injection
50
+ output = relative_file("buffering_ruleset_test_output.txt", __FILE__)
51
+ File.delete(output) if File.exists?(output)
52
+ template = relative_template(">>{buffering_ruleset_test_output.${ext}}{an output}", "buffering-test", __FILE__)
53
+ assert_equal("", template.instantiate("", "ext" => "txt"))
54
+ assert_equal("an output", File.read(output))
55
+ File.delete(output) if File.exists?(output)
56
+ end
57
+
58
+ # Tests output rule parses the second block in same dialect
59
+ def test_output_stays_in_same_dialect
60
+ output = relative_file("buffering_ruleset_test_output.txt", __FILE__)
61
+ File.delete(output) if File.exists?(output)
62
+ template = relative_template(">>{buffering_ruleset_test_output.txt}{;{an output}}", "buffering-test", __FILE__)
63
+ assert_equal("", template.instantiate())
64
+ assert_equal("AN OUTPUT", File.read(output))
65
+ File.delete(output) if File.exists?(output)
66
+ end
67
+
68
+ def test_output_created_dirs
69
+ output = relative_file("buffering_ruleset_output/buffering_ruleset_test_output.txt", __FILE__)
70
+ File.delete(output) if File.exists?(output)
71
+ template = relative_template(">>{buffering_ruleset_output/buffering_ruleset_test_output.txt}{an output}", "buffering-test", __FILE__)
72
+ assert_equal("", template.instantiate())
73
+ assert_equal("an output", File.read(output))
74
+ File.delete(output) if File.exists?(output)
75
+ end
76
+
77
+ def test_output_multiple_created_dirs
78
+ output = relative_file("buffering_ruleset_output/subdir/subdir/buffering_ruleset_test_output.txt", __FILE__)
79
+ File.delete(output) if File.exists?(output)
80
+ template = relative_template(">>{buffering_ruleset_output/subdir/subdir/buffering_ruleset_test_output.txt}{an output}", "buffering-test", __FILE__)
81
+ assert_equal("", template.instantiate())
82
+ assert_equal("an output", File.read(output))
83
+ File.delete(output) if File.exists?(output)
84
+ end
85
+
86
+ # Tests that an included template can include other thinks
87
+ def test_inclusion_in_include_template_works
88
+ expected = "template3"
89
+ file = relative_file("buffering_template1.wtpl", __FILE__)
90
+ result = WLang::file_instantiate(file)
91
+ assert_equal(expected, result)
92
+ end
93
+
94
+ # Tests that an included template can include other thinks
95
+ def test_with_works_in_inclusion
96
+ expected = "blambeau world"
97
+ file = relative_file("buffering_template4.wtpl", __FILE__)
98
+ result = WLang::file_instantiate(file, {"who" => "blambeau"})
99
+ assert_equal(expected, result)
100
+ end
101
+
102
+ end # class WLang::ScopingRuleSetTest
@@ -0,0 +1 @@
1
+ <<+{buffering_template2.wtpl}
@@ -0,0 +1 @@
1
+ <<+{buffering_template3.wtpl}
@@ -0,0 +1 @@
1
+ template3
@@ -0,0 +1 @@
1
+ <<+{buffering_template5.wtpl using self with who2: who, hello: 'world'}
@@ -0,0 +1 @@
1
+ +{who} +{hello}
@@ -0,0 +1,32 @@
1
+ require 'test/unit/testcase'
2
+ require 'wlang'
3
+ require 'wlang/rulesets/basic_ruleset'
4
+ require 'wlang/rulesets/context_ruleset'
5
+
6
+ # Tests the Scoping ruleset
7
+ class WLang::ContextRuleSetTest < Test::Unit::TestCase
8
+
9
+ # Installs a dialect on wlang
10
+ def setup
11
+ WLang::dialect "context-test" do
12
+ rules WLang::RuleSet::Basic
13
+ rules WLang::RuleSet::Context
14
+ end
15
+ end
16
+
17
+ # Tests the define decoder
18
+ def test_block_assignment
19
+ tests = [
20
+ ["#={code}{hello}+{code}", "hello"],
21
+ ["#={code}{hello}{+{code}}", "hello"],
22
+ ["#={code}{%{wlang/dummy}{hello}}{+{code}}", "hello"],
23
+ ["#={code}{%{wlang/dummy}{+{hello}}}{+{code}}", "+{hello}"]
24
+ ]
25
+ tests.each do |test|
26
+ template, expected = test
27
+ result = template.wlang(nil, "context-test")
28
+ assert_equal(expected, result)
29
+ end
30
+ end
31
+
32
+ end # class WLang::ScopingRuleSetTest
@@ -0,0 +1,3 @@
1
+ {"name" => "O'Neil",
2
+ "author" => "blambeau",
3
+ "authors" => ["blambeau", "llambeau", "ancailliau"]}
@@ -0,0 +1,42 @@
1
+ require 'test/unit/testcase'
2
+ require 'wlang'
3
+ module WLang
4
+
5
+ # Tests Dialect class
6
+ class EncoderSetTest < Test::Unit::TestCase
7
+
8
+ # Installs a simple upcase/lowcase plain-text dialect
9
+ def setup
10
+ @plain = WLang::EncoderSet.new
11
+ @plain.add_encoder(:upcase)
12
+ @plain.add_encoder("downcase") {|src,options| src.downcase}
13
+ identity = Proc.new {|src, options| src}
14
+ @plain.add_encoder("identity", identity)
15
+ end
16
+
17
+ # Tests has_encoder? method
18
+ def test_has_encoder
19
+ assert_equal(true, @plain.has_encoder?("upcase"))
20
+ assert_equal(true, @plain.has_encoder?("downcase"))
21
+ assert_equal(true, @plain.has_encoder?("identity"))
22
+ assert_equal(false, @plain.has_encoder?("encoding"))
23
+ end
24
+
25
+ # Tests get_encoder method
26
+ def test_get_encoder
27
+ assert_equal(true, @plain.get_encoder("upcase").is_a?(Encoder))
28
+ assert_equal(true, @plain.get_encoder("downcase").is_a?(Encoder))
29
+ assert_equal(true, @plain.get_encoder("identity").is_a?(Encoder))
30
+ assert_nil(@plain.get_encoder("encoding"))
31
+ end
32
+
33
+ # Tests the encode method
34
+ def test_encode
35
+ assert_equal("IN UPPER CASE", @plain.encode("upcase","in Upper Case"))
36
+ assert_equal("in lower case", @plain.encode("downcase","IN Lower CASE"))
37
+ end
38
+
39
+
40
+ end # class TargetLanguageTest
41
+
42
+ end # module WLang
@@ -0,0 +1,107 @@
1
+ require 'test/unit'
2
+ require "wlang"
3
+ require 'wlang/rulesets/imperative_ruleset'
4
+ module WLang
5
+
6
+ # Tests the Imperative rule set
7
+ class ImperativeRuleSetTest < Test::Unit::TestCase
8
+
9
+ # Installs some dialects on wlang
10
+ def setup
11
+ # wlang dialect, empty by default
12
+ WLang::dialect "imperative-test" do
13
+ rules WLang::RuleSet::Basic
14
+ rules WLang::RuleSet::Imperative
15
+ end
16
+ end
17
+
18
+ # Tests the each regexp
19
+ def test_decode_each
20
+ expr = WLang::RuleSet::Utils.expr(:expr,
21
+ ["using", :var, false],
22
+ ["as", :multi_as, false])
23
+ hash = expr.decode("items")
24
+ assert_equal({:expr => "items", :using => nil, :as => nil}, hash)
25
+ hash = expr.decode("the_items")
26
+ assert_equal({:expr => "the_items", :using => nil, :as => nil}, hash)
27
+ hash = expr.decode("items using each_with_index")
28
+ assert_equal({:expr => "items", :using => "each_with_index", :as => nil}, hash)
29
+ hash = expr.decode("items as x")
30
+ assert_equal({:expr => "items", :using => nil, :as => ["x"]}, hash)
31
+ hash = expr.decode("items using each_with_index as x, i")
32
+ assert_equal({:expr => "items", :using => "each_with_index", :as => ["x", "i"]}, hash)
33
+ hash = expr.decode("names using each_with_index as name, i")
34
+ assert_equal({:expr => "names", :using => "each_with_index", :as => ["name", "i"]}, hash)
35
+ text = "p.items.children using each_with_index as child, i"
36
+ assert_not_nil(expr.decode(text))
37
+ end
38
+
39
+ # Tests merging args
40
+ def test_merge_each_args
41
+ hash = WLang::RuleSet::Imperative.merge_each_args(["item", "index"], [1, 2])
42
+ assert_equal({"item" => 1, "index" => 2}, hash)
43
+ hash = WLang::RuleSet::Imperative.merge_each_args(["item", "index"], [1])
44
+ assert_equal({"item" => 1}, hash)
45
+ hash = WLang::RuleSet::Imperative.merge_each_args(["item"], [1, 2])
46
+ assert_equal({"item" => 1}, hash)
47
+ end
48
+
49
+ # Tests conditional
50
+ def test_conditional
51
+ context = {"name" => "blambeau", "no" => false, "yes" => true}
52
+ tests = [
53
+ ["?{true}{then} after", "then after"],
54
+ ["?{true}{then}{else} after", "then after"],
55
+ ["?{false}{text} after", " after"],
56
+ ["?{false}{text}{else} after", "else after"],
57
+ ["before ?{true}{then} after", "before then after"],
58
+ ["before ?{true}{then}{else} after", "before then after"],
59
+ ["before ?{false}{text} after", "before after"],
60
+ ["before ?{false}{text}{else} after", "before else after"],
61
+ ["?{name}{${name}}", "blambeau"],
62
+ ["?{nil}{${name}}{else}", "else"],
63
+ ["?{no}{${name}}", ""],
64
+ ["?{yes}{${name}}", "blambeau"],
65
+ ]
66
+ tests.each do |test|
67
+ result = test[0].wlang_instantiate(context, "imperative-test")
68
+ assert_equal(test[1], result)
69
+ end
70
+ end
71
+
72
+ # Tests the enumration
73
+ def test_enumeration
74
+ context = {"names" => ["blambeau", "llambeau", "chl"],
75
+ "empty" => [],
76
+ "one" => ["blambeau"],
77
+ "two" => ["blambeau", "llambeau"]}
78
+ tests = [
79
+ ['*{["blambeau","llambeau","chl"] as x}{${x}}{, }', "blambeau, llambeau, chl"],
80
+ ["*{names as name}{${name}}", "blambeaullambeauchl"],
81
+ ["*{names as name}{${name}}{, }", "blambeau, llambeau, chl"],
82
+ ["*{names using each_with_index as name, i}{${i}:${name}}{, }", "0:blambeau, 1:llambeau, 2:chl"],
83
+ ["*{empty as e}{+{e}}", ""],
84
+ ["*{empty as e}{+{e}}{}", ""],
85
+ ["*{empty as e}{+{e}}{ }", ""],
86
+ ["*{one as e}{+{e}}", "blambeau"],
87
+ ["*{one as e}{+{e}}{}", "blambeau"],
88
+ ["*{one as e}{+{e}}{ }", "blambeau"],
89
+ ["*{two as t}{+{t}}", "blambeaullambeau"],
90
+ ["*{two as t}{+{t}}{ }", "blambeau llambeau"]
91
+ ]
92
+ tests.each do |test|
93
+ result = test[0].wlang_instantiate(context, "imperative-test")
94
+ assert_equal(test[1], result)
95
+ end
96
+ end
97
+
98
+ def test_enumeration_bug
99
+ context = {"hello" => "world", "names" => ["blambeau", "llambeau", "chl"]}
100
+ expected = "worldworldworld"
101
+ template = "*{names as n}{+{hello}}"
102
+ assert_equal expected, template.wlang_instantiate(context, "imperative-test")
103
+ end
104
+
105
+ end # class ImperativeRuleSetTest
106
+
107
+ end # module WLang
@@ -0,0 +1,194 @@
1
+ require 'test/unit'
2
+ require 'wlang'
3
+ module WLang
4
+
5
+ # Tests the IntelligentBuffer class
6
+ class IntelligentBufferTest < Test::Unit::TestCase
7
+ include IntelligentBuffer::Methods
8
+
9
+ # Creates a buffer instance
10
+ def buffer(str)
11
+ IntelligentBuffer.new(str)
12
+ end
13
+
14
+ def test_last_column
15
+ assert_equal(4, last_column('abc'))
16
+ assert_equal(4, last_column("\nabc"))
17
+ assert_equal(6, last_column("\nabc\nab cd"))
18
+ assert_equal(1, last_column("\n\n\n\n\n\n"))
19
+ end
20
+
21
+ def test_ismultiline?
22
+ assert is_multiline?("\n")
23
+ assert is_multiline?("\nabc")
24
+ assert is_multiline?("\nabc\n")
25
+ assert_equal false, is_multiline?("abc")
26
+ assert_equal false, is_multiline?("abc\t")
27
+ end
28
+
29
+ def test_tabto
30
+ template = <<-EOF
31
+ def +{d}
32
+ contents of the method here
33
+ and also here
34
+ end
35
+ EOF
36
+ template = tabto(template, 0).strip
37
+ assert_equal("def +{d}\n contents of the method here\n and also here\nend", template)
38
+ # check on normal multiline
39
+ template = %Q{
40
+ def +{d}
41
+ contents of the method here
42
+ and also here
43
+ end
44
+ }
45
+ stripped = strip_block(template)
46
+ expected = " def +{d}\n contents of the method here\n and also here\n end\n"
47
+ assert_equal(expected, tabto(stripped, 4))
48
+ end
49
+
50
+ def test_strip_block
51
+ # check on non multiline
52
+ assert_equal 'abc', strip_block('abc')
53
+
54
+ # check on normal multiline
55
+ template = %Q{
56
+ def +{d}
57
+ contents of the method here
58
+ and also here
59
+ end
60
+ }
61
+ expected = " def +{d}\n contents of the method here\n and also here\n end\n"
62
+ assert_equal(expected, strip_block(template))
63
+
64
+ # check that explicit carriage return are recognized
65
+ template = %Q{
66
+
67
+ def +{d}
68
+ contents of the method here
69
+ and also here
70
+ end
71
+ }
72
+ expected = "\n def +{d}\n contents of the method here\n and also here\n end\n"
73
+ assert_equal(expected, strip_block(template))
74
+
75
+ # check that no first carriage return is recognized as well
76
+ template = %Q{def +{d}
77
+ contents of the method here
78
+ and also here
79
+ end
80
+ }
81
+ expected = "def +{d}\n contents of the method here\n and also here\nend\n"
82
+ assert_equal(expected, strip_block(template))
83
+
84
+ # Check on push failure
85
+ template = %Q{
86
+
87
+ def hello()
88
+ end
89
+ }
90
+ assert_equal("\n def hello()\n end\n", strip_block(template))
91
+
92
+ # Tests on a missing end bug
93
+ mod = "module MyModule\n 10\n 20\n 30\n\nend"
94
+ assert_equal(mod, strip_block(mod))
95
+ end
96
+
97
+ def test_missing_end_bug_reason
98
+ buf = IntelligentBuffer.new
99
+ mod = "module MyModule\n 10\n 20\n 30\n\nend"
100
+ assert_equal(mod, strip_block(mod))
101
+ buf.<<(mod, true)
102
+ assert_equal(mod, buf.to_s)
103
+ end
104
+
105
+ def test_push
106
+ template = <<-EOF
107
+ module +{name}
108
+
109
+ *{defs as d}{
110
+
111
+ def +{d}
112
+ end
113
+ }
114
+
115
+ end
116
+ EOF
117
+ #puts template.gsub(/ {8}/, '').strip
118
+ buf = buffer('')
119
+ buf.<<("module ", false)
120
+ buf.<<("MyModule", true)
121
+ buf.<<("\n\n ", false)
122
+ bufit = buffer('')
123
+ buf2 = buffer('')
124
+ buf2.<<("\n\n def ", false)
125
+ buf3 = buffer('')
126
+ buf3.<<('hello', true)
127
+ buf2.<<(buf3.to_s, true)
128
+ buf2.<<("()\n end\n ", false)
129
+ #puts "\nAppending on bufit, first iteration"
130
+ #puts "|#{buf2.to_s}|"
131
+ bufit.<<(buf2.to_s, true)
132
+ #puts "\nAfter append"
133
+ #puts "|#{bufit.to_s}|"
134
+ #puts "Last column is now #{last_column(bufit)}"
135
+ buf2 = buffer('')
136
+ buf2.<<("\n\n def ", false)
137
+ buf3 = buffer('')
138
+ buf3.<<('strip', true)
139
+ buf2.<<(buf3.to_s, true)
140
+ buf2.<<("()\n end\n ", false)
141
+ #puts "\nAppending on bufit, second iteration"
142
+ #puts "|#{buf2.to_s}|"
143
+ bufit.<<(buf2.to_s, true)
144
+ #puts "\nAfter append"
145
+ #puts "|#{bufit.to_s}|"
146
+ #puts "\nAppending bufit on buf"
147
+ #puts "|#{buf.to_s}|"
148
+ buf.<<(bufit.to_s, true)
149
+ #puts "\nAfter append"
150
+ #puts "|#{buf.to_s}|"
151
+ buf.<<("\n\nend", false)
152
+ #puts "\nNow, we've done"
153
+ #puts buf
154
+ expected = "module MyModule\n\n def hello()\n end\n \n def strip()\n end\n\n\nend"
155
+ assert_equal(expected, buf.to_s)
156
+ end
157
+
158
+ def test_wlang_on_intelligent_buffer
159
+ template = <<-EOF
160
+ module +{name}
161
+
162
+ *{defs as d}{
163
+
164
+ def +{d}
165
+ end
166
+ }
167
+
168
+ end
169
+ EOF
170
+ template = template.gsub(/ {8}/, '').strip
171
+ #puts template
172
+ context = {"name" => "MyModule", "defs" => ["hello", "strip", "toeol"]}
173
+ #puts template.wlang_instantiate(context, "wlang/ruby")
174
+ end
175
+
176
+ def test_wlang_on_web_example
177
+ template = %q{
178
+ <table>
179
+ *{rows as r}{
180
+ <tr>
181
+ *{r as d}{
182
+ <td>+{d}</td>
183
+ }
184
+ </tr>
185
+ }
186
+ </table>
187
+ }.gsub(/^ {8}/, '').strip
188
+ #puts template
189
+ context = {"rows" => [[10, 11, 12], [20, 21, 22], [30, 31, 32]]}
190
+ #puts template.wlang_instantiate(context, "wlang/xhtml")
191
+ end
192
+
193
+ end # class IntelligentBufferTest
194
+ end