erbse 0.0.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 (162) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.txt +828 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +51 -0
  5. data/benchmark/Makefile +6 -0
  6. data/benchmark/bench.rb +313 -0
  7. data/benchmark/bench_context.yaml +141 -0
  8. data/benchmark/templates/_footer.html +4 -0
  9. data/benchmark/templates/_header.html +52 -0
  10. data/benchmark/templates/bench_erb.rhtml +29 -0
  11. data/benchmark/templates/bench_erubis.rhtml +29 -0
  12. data/benchmark/templates/bench_eruby.rhtml +29 -0
  13. data/bin/erubis +10 -0
  14. data/erbse.gemspec +24 -0
  15. data/lib/erbse.rb +52 -0
  16. data/lib/erbse/context.rb +83 -0
  17. data/lib/erbse/converter.rb +357 -0
  18. data/lib/erbse/engine.rb +114 -0
  19. data/lib/erbse/engine/ec.rb +117 -0
  20. data/lib/erbse/engine/ecpp.rb +113 -0
  21. data/lib/erbse/engine/ejava.rb +110 -0
  22. data/lib/erbse/engine/ejavascript.rb +119 -0
  23. data/lib/erbse/engine/enhanced.rb +126 -0
  24. data/lib/erbse/engine/eperl.rb +95 -0
  25. data/lib/erbse/engine/ephp.rb +99 -0
  26. data/lib/erbse/engine/eruby.rb +119 -0
  27. data/lib/erbse/engine/escheme.rb +114 -0
  28. data/lib/erbse/engine/optimized.rb +127 -0
  29. data/lib/erbse/enhancer.rb +723 -0
  30. data/lib/erbse/error.rb +23 -0
  31. data/lib/erbse/evaluator.rb +88 -0
  32. data/lib/erbse/generator.rb +85 -0
  33. data/lib/erbse/helper.rb +47 -0
  34. data/lib/erbse/helpers/rails_form_helper.rb +197 -0
  35. data/lib/erbse/helpers/rails_helper.rb +353 -0
  36. data/lib/erbse/main.rb +516 -0
  37. data/lib/erbse/preprocessing.rb +58 -0
  38. data/lib/erbse/tiny.rb +144 -0
  39. data/lib/erbse/util.rb +22 -0
  40. data/lib/erbse/version.rb +3 -0
  41. data/test/assert-text-equal.rb +44 -0
  42. data/test/data/users-guide/Example.ejava +55 -0
  43. data/test/data/users-guide/array_example.result +9 -0
  44. data/test/data/users-guide/arraybuffer_example.result +9 -0
  45. data/test/data/users-guide/bipattern-example.rhtml +4 -0
  46. data/test/data/users-guide/bipattern_example.result +6 -0
  47. data/test/data/users-guide/bufvar-example.rb +10 -0
  48. data/test/data/users-guide/bufvar-example.result +17 -0
  49. data/test/data/users-guide/context.rb +6 -0
  50. data/test/data/users-guide/context.yaml +8 -0
  51. data/test/data/users-guide/def_method.rb +14 -0
  52. data/test/data/users-guide/def_method.result +3 -0
  53. data/test/data/users-guide/escape_example.result +9 -0
  54. data/test/data/users-guide/example.ec +27 -0
  55. data/test/data/users-guide/example.ecpp +30 -0
  56. data/test/data/users-guide/example.ejs +20 -0
  57. data/test/data/users-guide/example.eperl +18 -0
  58. data/test/data/users-guide/example.ephp +18 -0
  59. data/test/data/users-guide/example.eruby +6 -0
  60. data/test/data/users-guide/example.escheme +28 -0
  61. data/test/data/users-guide/example1.eruby +6 -0
  62. data/test/data/users-guide/example1.rb +17 -0
  63. data/test/data/users-guide/example1.result +16 -0
  64. data/test/data/users-guide/example10.rb +4 -0
  65. data/test/data/users-guide/example10.result +17 -0
  66. data/test/data/users-guide/example10.xhtml +14 -0
  67. data/test/data/users-guide/example10_x.result +17 -0
  68. data/test/data/users-guide/example11.php +20 -0
  69. data/test/data/users-guide/example11.result +23 -0
  70. data/test/data/users-guide/example11.rhtml +21 -0
  71. data/test/data/users-guide/example11_C.result +10 -0
  72. data/test/data/users-guide/example11_N.result +16 -0
  73. data/test/data/users-guide/example11_U.result +16 -0
  74. data/test/data/users-guide/example11_php.result +15 -0
  75. data/test/data/users-guide/example1_x.result +9 -0
  76. data/test/data/users-guide/example2.eruby +7 -0
  77. data/test/data/users-guide/example2.rb +10 -0
  78. data/test/data/users-guide/example2.result +27 -0
  79. data/test/data/users-guide/example2_trim.result +10 -0
  80. data/test/data/users-guide/example2_x.result +10 -0
  81. data/test/data/users-guide/example3.eruby +6 -0
  82. data/test/data/users-guide/example3.rb +10 -0
  83. data/test/data/users-guide/example31.result +22 -0
  84. data/test/data/users-guide/example32.result +4 -0
  85. data/test/data/users-guide/example3_e.result +8 -0
  86. data/test/data/users-guide/example4.eruby +3 -0
  87. data/test/data/users-guide/example4.rb +11 -0
  88. data/test/data/users-guide/example4.result +10 -0
  89. data/test/data/users-guide/example4_x.result +5 -0
  90. data/test/data/users-guide/example5.eruby +6 -0
  91. data/test/data/users-guide/example5.rb +16 -0
  92. data/test/data/users-guide/example5.result +7 -0
  93. data/test/data/users-guide/example6.rb +12 -0
  94. data/test/data/users-guide/example6.result +7 -0
  95. data/test/data/users-guide/example7.eruby +8 -0
  96. data/test/data/users-guide/example71.result +13 -0
  97. data/test/data/users-guide/example72.result +13 -0
  98. data/test/data/users-guide/example8.eruby +6 -0
  99. data/test/data/users-guide/example8_ruby.result +7 -0
  100. data/test/data/users-guide/example8_yaml.result +7 -0
  101. data/test/data/users-guide/example9.eruby +3 -0
  102. data/test/data/users-guide/example9.rb +8 -0
  103. data/test/data/users-guide/example9.result +9 -0
  104. data/test/data/users-guide/example91.result +5 -0
  105. data/test/data/users-guide/example92.result +4 -0
  106. data/test/data/users-guide/example_c.result +32 -0
  107. data/test/data/users-guide/example_java.result +56 -0
  108. data/test/data/users-guide/example_js.result +22 -0
  109. data/test/data/users-guide/example_perl.result +20 -0
  110. data/test/data/users-guide/example_php.result +19 -0
  111. data/test/data/users-guide/example_scheme.result +30 -0
  112. data/test/data/users-guide/example_scheme_display.result +29 -0
  113. data/test/data/users-guide/fasteruby-example.rb +8 -0
  114. data/test/data/users-guide/fasteruby-example.result +18 -0
  115. data/test/data/users-guide/fasteruby.rb +11 -0
  116. data/test/data/users-guide/fasteruby.result +38 -0
  117. data/test/data/users-guide/fasteruby.rhtml +15 -0
  118. data/test/data/users-guide/headerfooter-example.eruby +9 -0
  119. data/test/data/users-guide/headerfooter-example2.rb +8 -0
  120. data/test/data/users-guide/headerfooter-example2.rhtml +10 -0
  121. data/test/data/users-guide/headerfooter_example.result +11 -0
  122. data/test/data/users-guide/headerfooter_example2.result +13 -0
  123. data/test/data/users-guide/interpolation_example.result +9 -0
  124. data/test/data/users-guide/main_program1.rb +8 -0
  125. data/test/data/users-guide/main_program1.result +6 -0
  126. data/test/data/users-guide/main_program2.rb +8 -0
  127. data/test/data/users-guide/main_program2.result +6 -0
  128. data/test/data/users-guide/nocode-example.eruby +14 -0
  129. data/test/data/users-guide/nocode-php.result +20 -0
  130. data/test/data/users-guide/nocode_example.result +15 -0
  131. data/test/data/users-guide/normal-eruby-test.eruby +9 -0
  132. data/test/data/users-guide/normal_eruby_test.result +11 -0
  133. data/test/data/users-guide/notext-example.eruby +14 -0
  134. data/test/data/users-guide/notext-example.php +19 -0
  135. data/test/data/users-guide/notext-php.result +20 -0
  136. data/test/data/users-guide/notext_example.result +16 -0
  137. data/test/data/users-guide/percentline-example.rhtml +6 -0
  138. data/test/data/users-guide/percentline_example.result +9 -0
  139. data/test/data/users-guide/prefixedline-example.rb +9 -0
  140. data/test/data/users-guide/prefixedline-example.rhtml +6 -0
  141. data/test/data/users-guide/prefixedline_example.result +9 -0
  142. data/test/data/users-guide/printenable_example.result +4 -0
  143. data/test/data/users-guide/printenabled-example.eruby +3 -0
  144. data/test/data/users-guide/printenabled-example.rb +8 -0
  145. data/test/data/users-guide/printstatement_example.result +8 -0
  146. data/test/data/users-guide/simplify_example.result +9 -0
  147. data/test/data/users-guide/stderr.log +3 -0
  148. data/test/data/users-guide/stdout_exmple.result +9 -0
  149. data/test/data/users-guide/stringbuffer_example.result +9 -0
  150. data/test/data/users-guide/tail_260.result +4 -0
  151. data/test/data/users-guide/tailnewline.rhtml +3 -0
  152. data/test/data/users-guide/template1.rhtml +4 -0
  153. data/test/data/users-guide/template2.rhtml +4 -0
  154. data/test/test-engines.rb +425 -0
  155. data/test/test-enhancers.rb +646 -0
  156. data/test/test-erubis.rb +887 -0
  157. data/test/test-index-cgi.rb +191 -0
  158. data/test/test-main.rb +752 -0
  159. data/test/test-users-guide.rb +73 -0
  160. data/test/test.rb +45 -0
  161. data/test/testutil.rb +111 -0
  162. metadata +233 -0
@@ -0,0 +1,114 @@
1
+ require 'erbse/generator'
2
+ require 'erbse/converter'
3
+ require 'erbse/evaluator'
4
+ require 'erbse/context'
5
+
6
+
7
+ module Erbse
8
+
9
+
10
+ ##
11
+ ## (abstract) abstract engine class.
12
+ ## subclass must include evaluator and converter module.
13
+ ##
14
+ class Engine
15
+ #include Evaluator
16
+ #include Converter
17
+ #include Generator
18
+
19
+ def initialize(input=nil, properties={})
20
+ #@input = input
21
+ init_generator(properties)
22
+ init_converter(properties)
23
+ init_evaluator(properties)
24
+ @src = convert(input) if input
25
+ end
26
+
27
+
28
+ ##
29
+ ## convert input string and set it to @src
30
+ ##
31
+ def convert!(input)
32
+ @src = convert(input)
33
+ end
34
+
35
+
36
+ ##
37
+ ## load file, write cache file, and return engine object.
38
+ ## this method create code cache file automatically.
39
+ ## cachefile name can be specified with properties[:cachename],
40
+ ## or filname + 'cache' is used as default.
41
+ ##
42
+ def self.load_file(filename, properties={})
43
+ cachename = properties[:cachename] || (filename + '.cache')
44
+ properties[:filename] = filename
45
+ timestamp = File.mtime(filename)
46
+ if test(?f, cachename) && timestamp == File.mtime(cachename)
47
+ engine = self.new(nil, properties)
48
+ engine.src = File.read(cachename)
49
+ else
50
+ input = File.open(filename, 'rb') {|f| f.read }
51
+ engine = self.new(input, properties)
52
+ tmpname = cachename + rand().to_s[1,8]
53
+ File.open(tmpname, 'wb') {|f| f.write(engine.src) }
54
+ File.rename(tmpname, cachename)
55
+ File.utime(timestamp, timestamp, cachename)
56
+ end
57
+ engine.src.untaint # ok?
58
+ return engine
59
+ end
60
+
61
+
62
+ ##
63
+ ## helper method to convert and evaluate input text with context object.
64
+ ## context may be Binding, Hash, or Object.
65
+ ##
66
+ def process(input, context=nil, filename=nil)
67
+ code = convert(input)
68
+ filename ||= '(erubis)'
69
+ if context.is_a?(Binding)
70
+ return eval(code, context, filename)
71
+ else
72
+ context = Context.new(context) if context.is_a?(Hash)
73
+ return context.instance_eval(code, filename)
74
+ end
75
+ end
76
+
77
+
78
+ ##
79
+ ## helper method evaluate Proc object with contect object.
80
+ ## context may be Binding, Hash, or Object.
81
+ ##
82
+ def process_proc(proc_obj, context=nil, filename=nil)
83
+ if context.is_a?(Binding)
84
+ filename ||= '(erubis)'
85
+ return eval(proc_obj, context, filename)
86
+ else
87
+ context = Context.new(context) if context.is_a?(Hash)
88
+ return context.instance_eval(&proc_obj)
89
+ end
90
+ end
91
+
92
+
93
+ end # end of class Engine
94
+
95
+
96
+ ##
97
+ ## (abstract) base engine class for Eruby, Eperl, Ejava, and so on.
98
+ ## subclass must include generator.
99
+ ##
100
+ class Basic::Engine < Engine
101
+ include Evaluator
102
+ include Basic::Converter
103
+ include Generator
104
+ end
105
+
106
+
107
+ class PI::Engine < Engine
108
+ include Evaluator
109
+ include PI::Converter
110
+ include Generator
111
+ end
112
+
113
+
114
+ end
@@ -0,0 +1,117 @@
1
+ ##
2
+ ## $Release: 2.7.0 $
3
+ ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
4
+ ##
5
+
6
+ require 'erubis/engine'
7
+ require 'erubis/enhancer'
8
+
9
+
10
+ module Erubis
11
+
12
+
13
+ module CGenerator
14
+ include Generator
15
+
16
+ def self.supported_properties() # :nodoc:
17
+ return [
18
+ [:indent, '', "indent spaces (ex. ' ')"],
19
+ [:out, 'stdout', "output file pointer name"],
20
+ ]
21
+ end
22
+
23
+ def init_generator(properties={})
24
+ super
25
+ @escapefunc ||= "escape"
26
+ @indent = properties[:indent] || ''
27
+ @out = properties[:out] || 'stdout'
28
+ end
29
+
30
+ def add_preamble(src)
31
+ src << "#line 1 \"#{self.filename}\"\n" if self.filename
32
+ end
33
+
34
+ def escape_text(text)
35
+ @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
36
+ text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] }
37
+ return text
38
+ end
39
+
40
+ def escaped_expr(code)
41
+ return "#{@escapefunc}(#{code.strip}, #{@out})"
42
+ end
43
+
44
+ def add_text(src, text)
45
+ return if text.empty?
46
+ src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
47
+ src << "fputs("
48
+ i = 0
49
+ text.each_line do |line|
50
+ src << "\n" << @indent << ' ' if i > 0
51
+ i += 1
52
+ src << '"' << escape_text(line) << '"'
53
+ end
54
+ src << ", #{@out});" #<< (text[-1] == ?\n ? "\n" : "")
55
+ src << "\n" if text[-1] == ?\n
56
+ end
57
+
58
+ def add_stmt(src, code)
59
+ src << code
60
+ end
61
+
62
+ def add_expr_literal(src, code)
63
+ src << @indent if src.empty? || src[-1] == ?\n
64
+ src << " fprintf(#{@out}, " << code.strip << ');'
65
+ end
66
+
67
+ def add_expr_escaped(src, code)
68
+ src << @indent if src.empty? || src[-1] == ?\n
69
+ src << ' ' << escaped_expr(code) << ';'
70
+ end
71
+
72
+ def add_expr_debug(src, code)
73
+ code.strip!
74
+ s = nil
75
+ if code =~ /\A\".*?\"\s*,\s*(.*)/
76
+ s = $1.gsub(/[%"]/, '\\\1') + '='
77
+ end
78
+ src << @indent if src.empty? || src[-1] == ?\n
79
+ src << " fprintf(stderr, \"*** debug: #{s}\" #{code});"
80
+ end
81
+
82
+ def add_postamble(src)
83
+ # empty
84
+ end
85
+
86
+ end
87
+
88
+
89
+ ##
90
+ ## engine for C
91
+ ##
92
+ class Ec < Basic::Engine
93
+ include CGenerator
94
+ end
95
+
96
+
97
+ class EscapedEc < Ec
98
+ include EscapeEnhancer
99
+ end
100
+
101
+
102
+ #class XmlEc < Ec
103
+ # include EscapeEnhancer
104
+ #end
105
+
106
+ class PI::Ec < PI::Engine
107
+ include CGenerator
108
+
109
+ def init_converter(properties={})
110
+ @pi = 'c'
111
+ super(properties)
112
+ end
113
+
114
+ end
115
+
116
+
117
+ end
@@ -0,0 +1,113 @@
1
+ ##
2
+ ## $Release: 2.7.0 $
3
+ ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
4
+ ##
5
+
6
+ require 'erubis/engine'
7
+ require 'erubis/enhancer'
8
+
9
+
10
+ module Erubis
11
+
12
+
13
+ module CppGenerator
14
+ include Generator
15
+
16
+ def self.supported_properties() # :nodoc:
17
+ return [
18
+ [:indent, '', "indent spaces (ex. ' ')"],
19
+ [:bufvar, '_buf', "buffer variable name"],
20
+ ]
21
+ end
22
+
23
+ def init_generator(properties={})
24
+ super
25
+ @escapefunc ||= "escape"
26
+ @indent = properties[:indent] || ''
27
+ @bufvar = properties[:bufvar] || '_buf'
28
+ end
29
+
30
+ def add_preamble(src)
31
+ src << "#line 1 \"#{self.filename}\"\n" if self.filename
32
+ end
33
+
34
+ def escape_text(text)
35
+ @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
36
+ text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] }
37
+ return text
38
+ end
39
+
40
+ def escaped_expr(code)
41
+ return "#{@escapefunc}(#{code.strip})"
42
+ end
43
+
44
+ def add_text(src, text)
45
+ return if text.empty?
46
+ src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
47
+ src << "_buf << "
48
+ i = 0
49
+ text.each_line do |line|
50
+ src << "\n" << @indent << " " if i > 0
51
+ i += 1
52
+ src << '"' << escape_text(line) << '"'
53
+ end
54
+ src << ";" #<< (text[-1] == ?\n ? "\n" : "")
55
+ src << "\n" if text[-1] == ?\n
56
+ end
57
+
58
+ def add_stmt(src, code)
59
+ src << code
60
+ end
61
+
62
+ def add_expr_literal(src, code)
63
+ src << @indent if src.empty? || src[-1] == ?\n
64
+ src << " _buf << (" << code.strip << ");"
65
+ end
66
+
67
+ def add_expr_escaped(src, code)
68
+ src << @indent if src.empty? || src[-1] == ?\n
69
+ src << ' ' << escaped_expr(code) << ';'
70
+ end
71
+
72
+ def add_expr_debug(src, code)
73
+ code.strip!
74
+ src << @indent if src.empty? || src[-1] == ?\n
75
+ src << " std::cerr << \"*** debug: #{code.gsub(/(")/, '\\\&')}=\" << (#{code});"
76
+ end
77
+
78
+ def add_postamble(src)
79
+ # empty
80
+ end
81
+
82
+ end
83
+
84
+
85
+ ##
86
+ ## engine for C
87
+ ##
88
+ class Ecpp < Basic::Engine
89
+ include CppGenerator
90
+ end
91
+
92
+
93
+ class EscapedEcpp < Ecpp
94
+ include EscapeEnhancer
95
+ end
96
+
97
+
98
+ #class XmlEcpp < Ecpp
99
+ # include EscapeEnhancer
100
+ #end
101
+
102
+ class PI::Ecpp < PI::Engine
103
+ include CppGenerator
104
+
105
+ def init_converter(properties={})
106
+ @pi = 'cpp'
107
+ super(properties)
108
+ end
109
+
110
+ end
111
+
112
+
113
+ end
@@ -0,0 +1,110 @@
1
+ ##
2
+ ## $Release: 2.7.0 $
3
+ ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
4
+ ##
5
+
6
+ require 'erubis/engine'
7
+ require 'erubis/enhancer'
8
+
9
+
10
+ module Erubis
11
+
12
+
13
+ module JavaGenerator
14
+ include Generator
15
+
16
+ def self.supported_properties() # :nodoc:
17
+ return [
18
+ [:indent, '', "indent spaces (ex. ' ')"],
19
+ [:bufvar, '_buf', "output buffer variable name"],
20
+ [:bufclass, 'StringBuffer', "output buffer class (ex. 'StringBuilder')"],
21
+ ]
22
+ end
23
+
24
+ def init_generator(properties={})
25
+ super
26
+ @escapefunc ||= 'escape'
27
+ @indent = properties[:indent] || ''
28
+ @bufvar = properties[:bufvar] || '_buf'
29
+ @bufclass = properties[:bufclass] || 'StringBuffer'
30
+ end
31
+
32
+ def add_preamble(src)
33
+ src << "#{@indent}#{@bufclass} #{@bufvar} = new #{@bufclass}();"
34
+ end
35
+
36
+ def escape_text(text)
37
+ @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
38
+ return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text
39
+ end
40
+
41
+ def add_text(src, text)
42
+ return if text.empty?
43
+ src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
44
+ src << @bufvar << ".append("
45
+ i = 0
46
+ text.each_line do |line|
47
+ src << "\n" << @indent << ' + ' if i > 0
48
+ i += 1
49
+ src << '"' << escape_text(line) << '"'
50
+ end
51
+ src << ");" << (text[-1] == ?\n ? "\n" : "")
52
+ end
53
+
54
+ def add_stmt(src, code)
55
+ src << code
56
+ end
57
+
58
+ def add_expr_literal(src, code)
59
+ src << @indent if src.empty? || src[-1] == ?\n
60
+ code.strip!
61
+ src << " #{@bufvar}.append(#{code});"
62
+ end
63
+
64
+ def add_expr_escaped(src, code)
65
+ add_expr_literal(src, escaped_expr(code))
66
+ end
67
+
68
+ def add_expr_debug(src, code)
69
+ code.strip!
70
+ src << @indent if src.empty? || src[-1] == ?\n
71
+ src << " System.err.println(\"*** debug: #{code}=\"+(#{code}));"
72
+ end
73
+
74
+ def add_postamble(src)
75
+ src << "\n" if src[-1] == ?;
76
+ src << @indent << "return " << @bufvar << ".toString();\n"
77
+ #src << @indent << "System.out.print(" << @bufvar << ".toString());\n"
78
+ end
79
+
80
+ end
81
+
82
+
83
+ ##
84
+ ## engine for Java
85
+ ##
86
+ class Ejava < Basic::Engine
87
+ include JavaGenerator
88
+ end
89
+
90
+
91
+ class EscapedEjava < Ejava
92
+ include EscapeEnhancer
93
+ end
94
+
95
+
96
+ #class XmlEjava < Ejava
97
+ # include EscapeEnhancer
98
+ #end
99
+
100
+ class PI::Ejava < PI::Engine
101
+ include JavaGenerator
102
+
103
+ def init_converter(properties={})
104
+ @pi = 'java'
105
+ super(properties)
106
+ end
107
+
108
+ end
109
+
110
+ end