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