wlang 0.8.5 → 0.9.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.
Files changed (151) hide show
  1. data/CHANGELOG.rdoc +65 -0
  2. data/README.rdoc +85 -31
  3. data/bin/wlang +5 -0
  4. data/doc/specification/dialect.wtpl +14 -0
  5. data/doc/specification/dialects.wtpl +3 -0
  6. data/doc/specification/glossary.wtpl +4 -4
  7. data/doc/specification/rulesets.wtpl +9 -9
  8. data/doc/specification/specification.css +1 -0
  9. data/doc/specification/specification.html +68 -5
  10. data/doc/specification/specification.wtpl +12 -12
  11. data/doc/specification/specification.yml +9 -9
  12. data/doc/specification/symbols.wtpl +8 -8
  13. data/lib/wlang.rb +297 -75
  14. data/lib/wlang/dialect.rb +7 -3
  15. data/lib/wlang/dialects/coderay_dialect.rb +4 -4
  16. data/lib/wlang/dialects/plain_text_dialect.rb +13 -19
  17. data/lib/wlang/dialects/redcloth_dialect.rb +16 -0
  18. data/lib/wlang/dialects/ruby_dialect.rb +16 -2
  19. data/lib/wlang/dialects/standard_dialects.rb +20 -0
  20. data/lib/wlang/dialects/xhtml_dialect.rb +24 -1
  21. data/lib/wlang/encoder.rb +1 -1
  22. data/lib/wlang/encoder_set.rb +5 -0
  23. data/lib/wlang/errors.rb +70 -6
  24. data/lib/wlang/ext/hash_methodize.rb +13 -0
  25. data/lib/wlang/{ruby_extensions.rb → ext/string.rb} +9 -5
  26. data/lib/wlang/hash_scope.rb +89 -0
  27. data/lib/wlang/hosted_language.rb +146 -0
  28. data/lib/wlang/parser.rb +189 -126
  29. data/lib/wlang/parser_state.rb +94 -0
  30. data/lib/wlang/rule_set.rb +16 -3
  31. data/lib/wlang/rulesets/basic_ruleset.rb +14 -6
  32. data/lib/wlang/rulesets/buffering_ruleset.rb +20 -29
  33. data/lib/wlang/rulesets/context_ruleset.rb +16 -20
  34. data/lib/wlang/rulesets/imperative_ruleset.rb +4 -4
  35. data/lib/wlang/rulesets/ruleset_utils.rb +26 -5
  36. data/lib/wlang/template.rb +16 -34
  37. data/lib/wlang/wlang_command.rb +4 -7
  38. data/lib/wlang/wlang_command_options.rb +5 -0
  39. data/test/blackbox/basic/execution_1.exp +1 -0
  40. data/test/blackbox/basic/execution_1.tpl +1 -0
  41. data/test/blackbox/basic/execution_2.exp +1 -0
  42. data/test/blackbox/basic/execution_2.tpl +1 -0
  43. data/test/blackbox/basic/execution_3.exp +1 -0
  44. data/test/blackbox/basic/execution_3.tpl +1 -0
  45. data/test/blackbox/basic/execution_4.exp +1 -0
  46. data/test/blackbox/basic/execution_4.tpl +1 -0
  47. data/test/blackbox/basic/inclusion_1.exp +1 -0
  48. data/test/blackbox/basic/inclusion_1.tpl +1 -0
  49. data/test/blackbox/basic/inclusion_2.exp +1 -0
  50. data/test/blackbox/basic/inclusion_2.tpl +1 -0
  51. data/test/blackbox/basic/injection_1.exp +1 -0
  52. data/test/blackbox/basic/injection_1.tpl +1 -0
  53. data/test/blackbox/basic/injection_2.exp +1 -0
  54. data/test/blackbox/basic/injection_2.tpl +1 -0
  55. data/test/blackbox/basic/modulation_1.exp +1 -0
  56. data/test/blackbox/basic/modulation_1.tpl +1 -0
  57. data/test/blackbox/basic/modulation_2.exp +1 -0
  58. data/test/blackbox/basic/modulation_2.tpl +1 -0
  59. data/test/blackbox/basic/recursive_app_1.exp +1 -0
  60. data/test/blackbox/basic/recursive_app_1.tpl +1 -0
  61. data/test/blackbox/basic/recursive_app_2.exp +1 -0
  62. data/test/blackbox/basic/recursive_app_2.tpl +1 -0
  63. data/test/blackbox/buffering/data_1.rb +1 -0
  64. data/test/blackbox/buffering/data_assignment_1.exp +1 -0
  65. data/test/blackbox/buffering/data_assignment_1.tpl +1 -0
  66. data/test/blackbox/buffering/data_assignment_2.exp +1 -0
  67. data/test/blackbox/buffering/data_assignment_2.tpl +1 -0
  68. data/test/blackbox/buffering/data_assignment_3.exp +1 -0
  69. data/test/blackbox/buffering/data_assignment_3.tpl +1 -0
  70. data/test/blackbox/buffering/data_assignment_4.exp +1 -0
  71. data/test/blackbox/buffering/data_assignment_4.tpl +1 -0
  72. data/test/blackbox/buffering/input_1.exp +1 -0
  73. data/test/blackbox/buffering/input_1.tpl +1 -0
  74. data/test/blackbox/buffering/input_2.exp +1 -0
  75. data/test/blackbox/buffering/input_2.tpl +1 -0
  76. data/test/blackbox/buffering/input_3.exp +1 -0
  77. data/test/blackbox/buffering/input_3.tpl +1 -0
  78. data/test/blackbox/buffering/input_inclusion.exp +1 -0
  79. data/test/blackbox/buffering/input_inclusion.tpl +1 -0
  80. data/test/blackbox/buffering/input_inclusion_1.exp +0 -0
  81. data/test/blackbox/buffering/input_inclusion_1.tpl +1 -0
  82. data/test/blackbox/buffering/input_inclusion_2.exp +1 -0
  83. data/test/blackbox/buffering/input_inclusion_2.tpl +1 -0
  84. data/test/blackbox/buffering/input_inclusion_3.exp +1 -0
  85. data/test/blackbox/buffering/input_inclusion_3.tpl +1 -0
  86. data/test/blackbox/buffering/input_inclusion_4.exp +0 -0
  87. data/test/blackbox/buffering/input_inclusion_4.tpl +1 -0
  88. data/test/blackbox/buffering/input_inclusion_5.exp +1 -0
  89. data/test/blackbox/buffering/input_inclusion_5.tpl +1 -0
  90. data/test/blackbox/buffering/input_inclusion_6.exp +1 -0
  91. data/test/blackbox/buffering/input_inclusion_6.tpl +1 -0
  92. data/test/blackbox/buffering/input_inclusion_7.exp +0 -0
  93. data/test/blackbox/buffering/input_inclusion_7.tpl +1 -0
  94. data/test/blackbox/buffering/text_1.txt +1 -0
  95. data/test/blackbox/buffering/wlang.txt +1 -0
  96. data/test/blackbox/context/assignment_1.exp +1 -0
  97. data/test/blackbox/context/assignment_1.tpl +1 -0
  98. data/test/blackbox/context/assignment_2.exp +1 -0
  99. data/test/blackbox/context/assignment_2.tpl +1 -0
  100. data/test/blackbox/context/assignment_3.exp +2 -0
  101. data/test/blackbox/context/assignment_3.tpl +2 -0
  102. data/test/blackbox/context/assignment_4.exp +1 -0
  103. data/test/blackbox/context/assignment_4.tpl +1 -0
  104. data/test/blackbox/context/block_assignment_1.exp +1 -0
  105. data/test/blackbox/context/block_assignment_1.tpl +1 -0
  106. data/test/blackbox/context/block_assignment_2.exp +1 -0
  107. data/test/blackbox/context/block_assignment_2.tpl +1 -0
  108. data/test/blackbox/context/modulo_assignment_1.exp +1 -0
  109. data/test/blackbox/context/modulo_assignment_1.tpl +1 -0
  110. data/test/blackbox/context/modulo_assignment_2.exp +1 -0
  111. data/test/blackbox/context/modulo_assignment_2.tpl +1 -0
  112. data/test/blackbox/data_1.rb +1 -0
  113. data/test/blackbox/test_all.rb +59 -0
  114. data/test/spec/basic_object.spec +40 -0
  115. data/test/spec/global_extensions.rb +2 -0
  116. data/test/spec/hash_scope.spec +76 -0
  117. data/test/spec/redcloth_dialect.spec +24 -0
  118. data/test/spec/test_all.rb +8 -0
  119. data/test/spec/wlang.spec +53 -0
  120. data/test/spec/xhtml_dialect.spec +23 -0
  121. data/test/{test_all.rb → unit/test_all.rb} +1 -1
  122. data/test/{wlang → unit/wlang}/anagram_bugs_test.rb +2 -2
  123. data/test/{wlang → unit/wlang}/basic_ruleset_test.rb +1 -1
  124. data/test/{wlang → unit/wlang}/buffering_ruleset_test.rb +4 -4
  125. data/test/{wlang → unit/wlang}/buffering_template1.wtpl +0 -0
  126. data/test/{wlang → unit/wlang}/buffering_template2.wtpl +0 -0
  127. data/test/{wlang → unit/wlang}/buffering_template3.wtpl +0 -0
  128. data/test/unit/wlang/buffering_template4.wtpl +1 -0
  129. data/test/unit/wlang/buffering_template5.wtpl +1 -0
  130. data/test/{wlang → unit/wlang}/context_ruleset_test.rb +0 -0
  131. data/test/{wlang → unit/wlang}/data.rb +0 -0
  132. data/test/{wlang → unit/wlang}/encoder_set_test.rb +0 -0
  133. data/test/{wlang → unit/wlang}/imperative_ruleset_test.rb +0 -0
  134. data/test/{wlang → unit/wlang}/intelligent_buffer_test.rb +0 -0
  135. data/test/{wlang → unit/wlang}/othersymbols_test.rb +0 -0
  136. data/test/{wlang → unit/wlang}/parser_test.rb +10 -11
  137. data/test/{wlang → unit/wlang}/plain_text_dialect_test.rb +0 -0
  138. data/test/{wlang → unit/wlang}/ruby_dialect_test.rb +0 -0
  139. data/test/{wlang → unit/wlang}/ruby_expected.rb +0 -0
  140. data/test/{wlang → unit/wlang}/ruby_template.wrb +0 -0
  141. data/test/{wlang → unit/wlang}/ruleset_utils_test.rb +0 -0
  142. data/test/{wlang → unit/wlang}/specification_examples_test.rb +2 -2
  143. data/test/{wlang → unit/wlang}/test_utils.rb +1 -1
  144. data/test/{wlang → unit/wlang}/wlang_test.rb +0 -0
  145. metadata +135 -42
  146. data/lib/wlang/basic_object.rb +0 -19
  147. data/lib/wlang/parser_context.rb +0 -139
  148. data/test/sandbox.rb +0 -1
  149. data/test/wlang/buffering_template4.wtpl +0 -1
  150. data/test/wlang/buffering_template5.wtpl +0 -1
  151. data/test/wlang/parser_context_test.rb +0 -29
@@ -27,20 +27,17 @@ module WLang
27
27
  dialect = options.template_dialect
28
28
  braces = options.template_brace
29
29
  context = options.context_object
30
- unless options.context_name.nil?
31
- context = {options.context_name => context}
32
- end
33
- template = WLang::Template.new(source, dialect, context, braces)
34
- template.source_file = options.template_file
30
+ context = {options.context_name => context} unless options.context_name.nil?
31
+ template = WLang::file_template(options.template_file, options.template_dialect, braces)
35
32
 
36
33
  if options.verbosity>1
37
34
  puts "Instantiating #{options.template_file}"
38
- puts "Using dialect #{dialect} : #{dialect.class}"
35
+ puts "Using dialect #{dialect}"
39
36
  puts "Block delimiters are " << Template::BLOCK_SYMBOLS[braces].inspect
40
37
  puts "Context is " << context.inspect
41
38
  end
42
39
 
43
- buffer << template.instantiate
40
+ buffer << template.instantiate(context || {})
44
41
 
45
42
  # Flush and close if needed
46
43
  if File===buffer
@@ -65,6 +65,11 @@ module WLang
65
65
  @template_dialect = value
66
66
  end
67
67
 
68
+ opt.on("-m", "--methodize",
69
+ "Use methodization of hashes?") do |value|
70
+ Kernel.load('wlang/ext/hash_methodize.rb')
71
+ end
72
+
68
73
  opt.on("-o", "--output=OUTPUT",
69
74
  "Flush instantiation result in output file") do |value|
70
75
  @output_file = value
@@ -0,0 +1 @@
1
+ world
@@ -0,0 +1 @@
1
+ !{"world"}
@@ -0,0 +1 @@
1
+ WLang
@@ -0,0 +1 @@
1
+ !{WLang.name}
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ !{who}
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ !{!{whowho}}
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ +{who}
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ +{+{whowho}}
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ ${who}
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ ${${whowho}}
@@ -0,0 +1 @@
1
+ %{blackbox/basic}{!{who}}
@@ -0,0 +1 @@
1
+ !{who}
@@ -0,0 +1 @@
1
+ %{wlang/dummy}{!{who}}
@@ -0,0 +1 @@
1
+ %!{blackbox/basic}{!{who}}
@@ -0,0 +1 @@
1
+ blambeau
@@ -0,0 +1 @@
1
+ %!{blackbox/basic with who: 'blambeau'}{\!{!{whowho}\}}
@@ -0,0 +1 @@
1
+ "blambeau"
@@ -0,0 +1 @@
1
+ <<={data_1.rb as x}{+{x}}
@@ -0,0 +1 @@
1
+ blambeau wlang
@@ -0,0 +1 @@
1
+ <<={data_1.rb as who}{+{who}} +{who}
@@ -0,0 +1 @@
1
+ blambeau wlang
@@ -0,0 +1 @@
1
+ <<={+{data_file_1} as who}{+{who}} +{who}
@@ -0,0 +1 @@
1
+ blambeau wlang
@@ -0,0 +1 @@
1
+ <<={../+{data_file_1} as who}{+{who}} +{who}
@@ -0,0 +1 @@
1
+ text_1
@@ -0,0 +1 @@
1
+ <<{text_1.txt}
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ <<{+{who}.txt}
@@ -0,0 +1 @@
1
+ text_1
@@ -0,0 +1 @@
1
+ <<{+{input_file}}
@@ -0,0 +1 @@
1
+ <<+{input_inclusion.tpl share none}
@@ -0,0 +1 @@
1
+ <<+{input_inclusion.tpl share root}
@@ -0,0 +1 @@
1
+ <<+{input_inclusion.tpl share all}
@@ -0,0 +1 @@
1
+ <<+{input_inclusion_1.tpl with who: 'blambeau'}
@@ -0,0 +1 @@
1
+ <<+{input_inclusion_2.tpl with who: 'blambeau'}
@@ -0,0 +1 @@
1
+ <<+{input_inclusion_3.tpl with who: 'blambeau'}
@@ -0,0 +1 @@
1
+ <<+{input_inclusion.tpl}
@@ -0,0 +1 @@
1
+ text_1
@@ -0,0 +1 @@
1
+ wlang
@@ -0,0 +1 @@
1
+ blambeau
@@ -0,0 +1 @@
1
+ ={'blambeau' as who}{!{who}}
@@ -0,0 +1 @@
1
+ blambeau wlang
@@ -0,0 +1 @@
1
+ ={'blambeau' as who}{!{who}} !{who}
@@ -0,0 +1,2 @@
1
+
2
+ blambeau
@@ -0,0 +1,2 @@
1
+ ={'blambeau' as who}
2
+ !{who}
@@ -0,0 +1 @@
1
+ Hello wlang!
@@ -0,0 +1 @@
1
+ Hello ={'wlang' as result}{${result}}!
@@ -0,0 +1 @@
1
+ #={x}{who}{!{x}}
@@ -0,0 +1 @@
1
+ #={x}{!{who}}{!{x}}
@@ -0,0 +1 @@
1
+ %={wlang/dummy as x}{!{who}}{!{x}}
@@ -0,0 +1 @@
1
+ %={blackbox/context as x}{!{who}}{!{x}}
@@ -0,0 +1 @@
1
+ "blambeau"
@@ -0,0 +1,59 @@
1
+ here = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(File.join(here, '..', '..', 'lib'))
3
+ require 'wlang'
4
+ require 'test/unit'
5
+ module WLang
6
+ class BackBoxTest < Test::Unit::TestCase
7
+
8
+ def test_on_examples
9
+ # Dialect used here
10
+ dialect = WLang::dialect("blackbox") do
11
+ dialect("basic") {
12
+ ruby_require "wlang/rulesets/basic_ruleset"
13
+ rules WLang::RuleSet::Basic
14
+ }
15
+ dialect("context") {
16
+ ruby_require "wlang/rulesets/basic_ruleset"
17
+ ruby_require "wlang/rulesets/context_ruleset"
18
+ rules WLang::RuleSet::Basic
19
+ rules WLang::RuleSet::Context
20
+ }
21
+ dialect("buffering") {
22
+ ruby_require "wlang/rulesets/basic_ruleset"
23
+ ruby_require "wlang/rulesets/buffering_ruleset"
24
+ rules WLang::RuleSet::Basic
25
+ rules WLang::RuleSet::Buffering
26
+ }
27
+ end
28
+ hosted = ::WLang::HostedLanguage.new
29
+ def hosted.variable_missing(name)
30
+ ""
31
+ end
32
+ WLang::file_extension_map('.tpl', 'blackbox/buffering')
33
+
34
+ # Context used here
35
+ context = {
36
+ 'who' => 'wlang',
37
+ 'whowho' => 'who',
38
+ 'input_file' => 'text_1.txt',
39
+ 'data_file_1' => 'data_1.rb'
40
+ }
41
+
42
+ Dir["#{File.dirname(__FILE__)}/*"].each do |folder|
43
+ dialect_name = File.basename(folder)
44
+ Dir["#{folder}/*.tpl"].each do |template_file|
45
+ begin
46
+ basename = File.basename(template_file, ".tpl")
47
+ expected = File.read(File.join(folder, "#{basename}.exp"))
48
+ template = WLang::file_template(template_file, "blackbox/#{dialect_name}")
49
+ assert_equal(expected, template.instantiate(context.dup, hosted), "Blackbox test failed #{basename}")
50
+ rescue Exception => ex
51
+ puts "Blackbox test failed: #{template_file}\n#{ex.message}"
52
+ puts ex.backtrace.join("\n")
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ end # class BackBoxTest
59
+ end # module WLang
@@ -0,0 +1,40 @@
1
+ require "wlang"
2
+ describe "WLang's version of BasicObject" do
3
+
4
+ class A
5
+ # Methods that we keep
6
+ KEPT_METHODS = ["__send__", "__id__", "instance_eval", "initialize",
7
+ "object_id", "nil?", "singleton_method_added", "__clean_scope__",
8
+ "singleton_method_undefined"]
9
+
10
+ def self.__clean_scope__
11
+ # Removes all methods that are not needed to the class
12
+ (instance_methods + private_instance_methods).each do |m|
13
+ undef_method(m.to_s.to_sym) unless KEPT_METHODS.include?(m.to_s)
14
+ end
15
+ end
16
+ __clean_scope__
17
+ end
18
+
19
+ it "should not have kernel methods except certain" do
20
+ [:puts, :to_s, :hash].each do |sym|
21
+ begin
22
+ A.new.instance_eval{ __send__(sym, []) }
23
+ "Not pass here".should == ""
24
+ rescue NoMethodError
25
+ true.should == true
26
+ end
27
+ end
28
+ end
29
+
30
+ it "should not gain methods when requiring gems" do
31
+ Kernel.load(File.join(File.dirname(__FILE__),"global_extensions.rb"))
32
+ begin
33
+ A.new.__clean_scope__.instance_eval{ hello_world }
34
+ "Not pass here".should == ""
35
+ rescue NoMethodError
36
+ true.should == true
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,2 @@
1
+ def hello_world
2
+ end
@@ -0,0 +1,76 @@
1
+ require 'wlang'
2
+ require 'wlang/hash_scope'
3
+
4
+ describe ::WLang::HashScope do
5
+
6
+ # Builds a new scope instance, with an optional parent and
7
+ # initial hash
8
+ def newscope(pairing = nil, parent = nil)
9
+ ::WLang::HashScope.new(pairing, parent)
10
+ end
11
+
12
+ it "should act as a basic hash at first glance" do
13
+ scope = newscope
14
+ scope.has_key?(:hello).should be_false
15
+ scope[:hello] = "world"
16
+ scope.has_key?(:hello).should be_true
17
+ scope[:hello].should == "world"
18
+ end
19
+
20
+ it "should support a parent" do
21
+ parent = newscope(:hello => "world", :mine => false)
22
+ child = newscope({:mine => true}, parent)
23
+
24
+ child.has_key?(:mine).should be_true
25
+ child.has_key?(:hello).should be_true
26
+ child[:mine].should be_true
27
+ child[:hello].should == "world"
28
+ end
29
+
30
+ it "should never touch its parent" do
31
+ parent = newscope(:hello => "world")
32
+ child = newscope(nil, parent)
33
+ child[:hello].should == "world"
34
+ child[:hello] = "none"
35
+ child[:hello].should == "none"
36
+ parent[:hello].should == "world"
37
+ end
38
+
39
+ it "should support branching easily" do
40
+ parent = newscope(:hello => "world")
41
+ parent.branch do |scope|
42
+ scope[:who] = "blambeau"
43
+ scope[:who].should == "blambeau"
44
+ scope[:hello].should == "world"
45
+ scope[:hello] = "none"
46
+ end
47
+ parent.has_key?(:who).should be_false
48
+ parent[:hello].should == "world"
49
+ end
50
+
51
+ it "should allow push/pop kind of branching" do
52
+ scope = newscope(:hello => "world")
53
+ scope = scope.branch
54
+ scope[:hello].should == "world"
55
+ scope[:hello] = "none"
56
+ scope[:hello].should == "none"
57
+ scope = scope.parent
58
+ scope[:hello].should == "world"
59
+ end
60
+
61
+ it "should respect scoping hierarchy" do
62
+ scope = newscope(:hello => "world")
63
+ child = newscope({}, scope)
64
+ child2 = newscope({}, child)
65
+
66
+ scope.parent.should be_nil
67
+ scope.root.should == scope
68
+
69
+ child.parent.should == scope
70
+ child.root.should == scope
71
+
72
+ child2.parent.should == child
73
+ child2.root.should == scope
74
+ end
75
+
76
+ end
@@ -0,0 +1,24 @@
1
+ require "wlang"
2
+ describe("WLang should support redcloth encoder") do
3
+
4
+ it("should support basic redcloth encoding") {
5
+ expected = "<h1>This is a title</h1>"
6
+ WLang::encode("h1. This is a title", "redcloth/xhtml").should == expected
7
+ }
8
+
9
+ it("should not perturbate template variables with global variables") {
10
+ # RedCloth installs a t global method (which becomes a private method
11
+ # of Object) which was perturbating the HostedLanguage::DSL class.
12
+ # This test acts as a non-regression one.
13
+ require 'rubygems'
14
+ require 'RedCloth'
15
+ "${t}".wlang(:t => 'wlang').should == 'wlang'
16
+ begin
17
+ "${t}".wlang()
18
+ true.should == false
19
+ rescue ::WLang::UndefinedVariableError
20
+ true.should == true
21
+ end
22
+ }
23
+
24
+ end