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.
- checksums.yaml +7 -0
- data/CHANGES.txt +828 -0
- data/MIT-LICENSE +20 -0
- data/README.md +51 -0
- data/benchmark/Makefile +6 -0
- data/benchmark/bench.rb +313 -0
- data/benchmark/bench_context.yaml +141 -0
- data/benchmark/templates/_footer.html +4 -0
- data/benchmark/templates/_header.html +52 -0
- data/benchmark/templates/bench_erb.rhtml +29 -0
- data/benchmark/templates/bench_erubis.rhtml +29 -0
- data/benchmark/templates/bench_eruby.rhtml +29 -0
- data/bin/erubis +10 -0
- data/erbse.gemspec +24 -0
- data/lib/erbse.rb +52 -0
- data/lib/erbse/context.rb +83 -0
- data/lib/erbse/converter.rb +357 -0
- data/lib/erbse/engine.rb +114 -0
- data/lib/erbse/engine/ec.rb +117 -0
- data/lib/erbse/engine/ecpp.rb +113 -0
- data/lib/erbse/engine/ejava.rb +110 -0
- data/lib/erbse/engine/ejavascript.rb +119 -0
- data/lib/erbse/engine/enhanced.rb +126 -0
- data/lib/erbse/engine/eperl.rb +95 -0
- data/lib/erbse/engine/ephp.rb +99 -0
- data/lib/erbse/engine/eruby.rb +119 -0
- data/lib/erbse/engine/escheme.rb +114 -0
- data/lib/erbse/engine/optimized.rb +127 -0
- data/lib/erbse/enhancer.rb +723 -0
- data/lib/erbse/error.rb +23 -0
- data/lib/erbse/evaluator.rb +88 -0
- data/lib/erbse/generator.rb +85 -0
- data/lib/erbse/helper.rb +47 -0
- data/lib/erbse/helpers/rails_form_helper.rb +197 -0
- data/lib/erbse/helpers/rails_helper.rb +353 -0
- data/lib/erbse/main.rb +516 -0
- data/lib/erbse/preprocessing.rb +58 -0
- data/lib/erbse/tiny.rb +144 -0
- data/lib/erbse/util.rb +22 -0
- data/lib/erbse/version.rb +3 -0
- data/test/assert-text-equal.rb +44 -0
- data/test/data/users-guide/Example.ejava +55 -0
- data/test/data/users-guide/array_example.result +9 -0
- data/test/data/users-guide/arraybuffer_example.result +9 -0
- data/test/data/users-guide/bipattern-example.rhtml +4 -0
- data/test/data/users-guide/bipattern_example.result +6 -0
- data/test/data/users-guide/bufvar-example.rb +10 -0
- data/test/data/users-guide/bufvar-example.result +17 -0
- data/test/data/users-guide/context.rb +6 -0
- data/test/data/users-guide/context.yaml +8 -0
- data/test/data/users-guide/def_method.rb +14 -0
- data/test/data/users-guide/def_method.result +3 -0
- data/test/data/users-guide/escape_example.result +9 -0
- data/test/data/users-guide/example.ec +27 -0
- data/test/data/users-guide/example.ecpp +30 -0
- data/test/data/users-guide/example.ejs +20 -0
- data/test/data/users-guide/example.eperl +18 -0
- data/test/data/users-guide/example.ephp +18 -0
- data/test/data/users-guide/example.eruby +6 -0
- data/test/data/users-guide/example.escheme +28 -0
- data/test/data/users-guide/example1.eruby +6 -0
- data/test/data/users-guide/example1.rb +17 -0
- data/test/data/users-guide/example1.result +16 -0
- data/test/data/users-guide/example10.rb +4 -0
- data/test/data/users-guide/example10.result +17 -0
- data/test/data/users-guide/example10.xhtml +14 -0
- data/test/data/users-guide/example10_x.result +17 -0
- data/test/data/users-guide/example11.php +20 -0
- data/test/data/users-guide/example11.result +23 -0
- data/test/data/users-guide/example11.rhtml +21 -0
- data/test/data/users-guide/example11_C.result +10 -0
- data/test/data/users-guide/example11_N.result +16 -0
- data/test/data/users-guide/example11_U.result +16 -0
- data/test/data/users-guide/example11_php.result +15 -0
- data/test/data/users-guide/example1_x.result +9 -0
- data/test/data/users-guide/example2.eruby +7 -0
- data/test/data/users-guide/example2.rb +10 -0
- data/test/data/users-guide/example2.result +27 -0
- data/test/data/users-guide/example2_trim.result +10 -0
- data/test/data/users-guide/example2_x.result +10 -0
- data/test/data/users-guide/example3.eruby +6 -0
- data/test/data/users-guide/example3.rb +10 -0
- data/test/data/users-guide/example31.result +22 -0
- data/test/data/users-guide/example32.result +4 -0
- data/test/data/users-guide/example3_e.result +8 -0
- data/test/data/users-guide/example4.eruby +3 -0
- data/test/data/users-guide/example4.rb +11 -0
- data/test/data/users-guide/example4.result +10 -0
- data/test/data/users-guide/example4_x.result +5 -0
- data/test/data/users-guide/example5.eruby +6 -0
- data/test/data/users-guide/example5.rb +16 -0
- data/test/data/users-guide/example5.result +7 -0
- data/test/data/users-guide/example6.rb +12 -0
- data/test/data/users-guide/example6.result +7 -0
- data/test/data/users-guide/example7.eruby +8 -0
- data/test/data/users-guide/example71.result +13 -0
- data/test/data/users-guide/example72.result +13 -0
- data/test/data/users-guide/example8.eruby +6 -0
- data/test/data/users-guide/example8_ruby.result +7 -0
- data/test/data/users-guide/example8_yaml.result +7 -0
- data/test/data/users-guide/example9.eruby +3 -0
- data/test/data/users-guide/example9.rb +8 -0
- data/test/data/users-guide/example9.result +9 -0
- data/test/data/users-guide/example91.result +5 -0
- data/test/data/users-guide/example92.result +4 -0
- data/test/data/users-guide/example_c.result +32 -0
- data/test/data/users-guide/example_java.result +56 -0
- data/test/data/users-guide/example_js.result +22 -0
- data/test/data/users-guide/example_perl.result +20 -0
- data/test/data/users-guide/example_php.result +19 -0
- data/test/data/users-guide/example_scheme.result +30 -0
- data/test/data/users-guide/example_scheme_display.result +29 -0
- data/test/data/users-guide/fasteruby-example.rb +8 -0
- data/test/data/users-guide/fasteruby-example.result +18 -0
- data/test/data/users-guide/fasteruby.rb +11 -0
- data/test/data/users-guide/fasteruby.result +38 -0
- data/test/data/users-guide/fasteruby.rhtml +15 -0
- data/test/data/users-guide/headerfooter-example.eruby +9 -0
- data/test/data/users-guide/headerfooter-example2.rb +8 -0
- data/test/data/users-guide/headerfooter-example2.rhtml +10 -0
- data/test/data/users-guide/headerfooter_example.result +11 -0
- data/test/data/users-guide/headerfooter_example2.result +13 -0
- data/test/data/users-guide/interpolation_example.result +9 -0
- data/test/data/users-guide/main_program1.rb +8 -0
- data/test/data/users-guide/main_program1.result +6 -0
- data/test/data/users-guide/main_program2.rb +8 -0
- data/test/data/users-guide/main_program2.result +6 -0
- data/test/data/users-guide/nocode-example.eruby +14 -0
- data/test/data/users-guide/nocode-php.result +20 -0
- data/test/data/users-guide/nocode_example.result +15 -0
- data/test/data/users-guide/normal-eruby-test.eruby +9 -0
- data/test/data/users-guide/normal_eruby_test.result +11 -0
- data/test/data/users-guide/notext-example.eruby +14 -0
- data/test/data/users-guide/notext-example.php +19 -0
- data/test/data/users-guide/notext-php.result +20 -0
- data/test/data/users-guide/notext_example.result +16 -0
- data/test/data/users-guide/percentline-example.rhtml +6 -0
- data/test/data/users-guide/percentline_example.result +9 -0
- data/test/data/users-guide/prefixedline-example.rb +9 -0
- data/test/data/users-guide/prefixedline-example.rhtml +6 -0
- data/test/data/users-guide/prefixedline_example.result +9 -0
- data/test/data/users-guide/printenable_example.result +4 -0
- data/test/data/users-guide/printenabled-example.eruby +3 -0
- data/test/data/users-guide/printenabled-example.rb +8 -0
- data/test/data/users-guide/printstatement_example.result +8 -0
- data/test/data/users-guide/simplify_example.result +9 -0
- data/test/data/users-guide/stderr.log +3 -0
- data/test/data/users-guide/stdout_exmple.result +9 -0
- data/test/data/users-guide/stringbuffer_example.result +9 -0
- data/test/data/users-guide/tail_260.result +4 -0
- data/test/data/users-guide/tailnewline.rhtml +3 -0
- data/test/data/users-guide/template1.rhtml +4 -0
- data/test/data/users-guide/template2.rhtml +4 -0
- data/test/test-engines.rb +425 -0
- data/test/test-enhancers.rb +646 -0
- data/test/test-erubis.rb +887 -0
- data/test/test-index-cgi.rb +191 -0
- data/test/test-main.rb +752 -0
- data/test/test-users-guide.rb +73 -0
- data/test/test.rb +45 -0
- data/test/testutil.rb +111 -0
- metadata +233 -0
@@ -0,0 +1,114 @@
|
|
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 SchemeGenerator
|
14
|
+
include Generator
|
15
|
+
|
16
|
+
def self.supported_properties() # :nodoc:
|
17
|
+
return [
|
18
|
+
[:func, '_add', "function name (ex. 'display')"],
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
def init_generator(properties={})
|
23
|
+
super
|
24
|
+
@escapefunc ||= 'escape'
|
25
|
+
@func = properties[:func] || '_add' # or 'display'
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_preamble(src)
|
29
|
+
return unless @func == '_add'
|
30
|
+
src << "(let ((_buf '())) " + \
|
31
|
+
"(define (_add x) (set! _buf (cons x _buf))) "
|
32
|
+
#src << "(let* ((_buf '())" + \
|
33
|
+
# " (_add (lambda (x) (set! _buf (cons x _buf))))) "
|
34
|
+
end
|
35
|
+
|
36
|
+
def escape_text(text)
|
37
|
+
@table_ ||= { '"'=>'\\"', '\\'=>'\\\\' }
|
38
|
+
text.gsub!(/["\\]/) { |m| @table_[m] }
|
39
|
+
return text
|
40
|
+
end
|
41
|
+
|
42
|
+
def escaped_expr(code)
|
43
|
+
code.strip!
|
44
|
+
return "(#{@escapefunc} #{code})"
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_text(src, text)
|
48
|
+
return if text.empty?
|
49
|
+
t = escape_text(text)
|
50
|
+
if t[-1] == ?\n
|
51
|
+
t[-1, 1] = ''
|
52
|
+
src << "(#{@func} \"" << t << "\\n\")\n"
|
53
|
+
else
|
54
|
+
src << "(#{@func} \"" << t << '")'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_stmt(src, code)
|
59
|
+
src << code
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_expr_literal(src, code)
|
63
|
+
code.strip!
|
64
|
+
src << "(#{@func} #{code})"
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_expr_escaped(src, code)
|
68
|
+
add_expr_literal(src, escaped_expr(code))
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_expr_debug(src, code)
|
72
|
+
s = (code.strip! || code).gsub(/\"/, '\\"')
|
73
|
+
src << "(display \"*** debug: #{s}=\")(display #{code.strip})(display \"\\n\")"
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_postamble(src)
|
77
|
+
return unless @func == '_add'
|
78
|
+
src << "\n" unless src[-1] == ?\n
|
79
|
+
src << " (reverse _buf))\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
##
|
86
|
+
## engine for Scheme
|
87
|
+
##
|
88
|
+
class Escheme < Basic::Engine
|
89
|
+
include SchemeGenerator
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
class EscapedEscheme < Escheme
|
94
|
+
include EscapeEnhancer
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
#class XmlEscheme < Escheme
|
99
|
+
# include EscapeEnhancer
|
100
|
+
#end
|
101
|
+
|
102
|
+
|
103
|
+
class PI::Escheme < PI::Engine
|
104
|
+
include SchemeGenerator
|
105
|
+
|
106
|
+
def init_converter(properties={})
|
107
|
+
@pi = 'scheme'
|
108
|
+
super(properties)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
##
|
2
|
+
## $Release: 2.7.0 $
|
3
|
+
## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
|
4
|
+
##
|
5
|
+
|
6
|
+
|
7
|
+
require 'erubis/engine/eruby'
|
8
|
+
|
9
|
+
|
10
|
+
module Erubis
|
11
|
+
|
12
|
+
|
13
|
+
module OptimizedGenerator
|
14
|
+
include Generator
|
15
|
+
|
16
|
+
def self.supported_properties() # :nodoc:
|
17
|
+
return []
|
18
|
+
end
|
19
|
+
|
20
|
+
def init_generator(properties={})
|
21
|
+
super
|
22
|
+
@escapefunc ||= "Erubis::XmlHelper.escape_xml"
|
23
|
+
@initialized = false
|
24
|
+
@prev_is_expr = false
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def escape_text(text)
|
30
|
+
text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
|
31
|
+
end
|
32
|
+
|
33
|
+
def escaped_expr(code)
|
34
|
+
@escapefunc ||= 'Erubis::XmlHelper.escape_xml'
|
35
|
+
return "#{@escapefunc}(#{code})"
|
36
|
+
end
|
37
|
+
|
38
|
+
def switch_to_expr(src)
|
39
|
+
return if @prev_is_expr
|
40
|
+
@prev_is_expr = true
|
41
|
+
src << ' _buf'
|
42
|
+
end
|
43
|
+
|
44
|
+
def switch_to_stmt(src)
|
45
|
+
return unless @prev_is_expr
|
46
|
+
@prev_is_expr = false
|
47
|
+
src << ';'
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_preamble(src)
|
51
|
+
#@initialized = false
|
52
|
+
#@prev_is_expr = false
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_text(src, text)
|
56
|
+
return if text.empty?
|
57
|
+
if @initialized
|
58
|
+
switch_to_expr(src)
|
59
|
+
src << " << '" << escape_text(text) << "'"
|
60
|
+
else
|
61
|
+
src << "_buf = '" << escape_text(text) << "';"
|
62
|
+
@initialized = true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_stmt(src, code)
|
67
|
+
switch_to_stmt(src) if @initialized
|
68
|
+
#super
|
69
|
+
src << code
|
70
|
+
src << ';' unless code[-1] == ?\n
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_expr_literal(src, code)
|
74
|
+
unless @initialized; src << "_buf = ''"; @initialized = true; end
|
75
|
+
switch_to_expr(src)
|
76
|
+
src << " << (" << code << ").to_s"
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_expr_escaped(src, code)
|
80
|
+
unless @initialized; src << "_buf = ''"; @initialized = true; end
|
81
|
+
switch_to_expr(src)
|
82
|
+
src << " << " << escaped_expr(code)
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_expr_debug(src, code)
|
86
|
+
code.strip!
|
87
|
+
s = (code.dump =~ /\A"(.*)"\z/) && $1
|
88
|
+
src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_postamble(src)
|
92
|
+
#super if @initialized
|
93
|
+
src << "\n_buf\n" if @initialized
|
94
|
+
end
|
95
|
+
|
96
|
+
end # end of class OptimizedEruby
|
97
|
+
|
98
|
+
|
99
|
+
##
|
100
|
+
## Eruby class which generates optimized ruby code
|
101
|
+
##
|
102
|
+
class OptimizedEruby < Basic::Engine # Eruby
|
103
|
+
include RubyEvaluator
|
104
|
+
include OptimizedGenerator
|
105
|
+
|
106
|
+
def init_converter(properties={})
|
107
|
+
@pi = 'rb'
|
108
|
+
super(properties)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
##
|
115
|
+
## XmlEruby class which generates optimized ruby code
|
116
|
+
##
|
117
|
+
class OptimizedXmlEruby < OptimizedEruby
|
118
|
+
include EscapeEnhancer
|
119
|
+
|
120
|
+
def add_expr_debug(src, code)
|
121
|
+
switch_to_stmt(src) if indicator == '===' && !@initialized
|
122
|
+
super
|
123
|
+
end
|
124
|
+
|
125
|
+
end # end of class OptimizedXmlEruby
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,723 @@
|
|
1
|
+
##
|
2
|
+
## $Release: 2.7.0 $
|
3
|
+
## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
|
4
|
+
##
|
5
|
+
|
6
|
+
|
7
|
+
module Erubis
|
8
|
+
|
9
|
+
|
10
|
+
##
|
11
|
+
## switch '<%= ... %>' to escaped and '<%== ... %>' to unescaped
|
12
|
+
##
|
13
|
+
## ex.
|
14
|
+
## class XmlEruby < Eruby
|
15
|
+
## include EscapeEnhancer
|
16
|
+
## end
|
17
|
+
##
|
18
|
+
## this is language-indenedent.
|
19
|
+
##
|
20
|
+
module EscapeEnhancer
|
21
|
+
|
22
|
+
def self.desc # :nodoc:
|
23
|
+
"switch '<%= %>' to escaped and '<%== %>' to unescaped"
|
24
|
+
end
|
25
|
+
|
26
|
+
#--
|
27
|
+
#def self.included(klass)
|
28
|
+
# klass.class_eval <<-END
|
29
|
+
# alias _add_expr_literal add_expr_literal
|
30
|
+
# alias _add_expr_escaped add_expr_escaped
|
31
|
+
# alias add_expr_literal _add_expr_escaped
|
32
|
+
# alias add_expr_escaped _add_expr_literal
|
33
|
+
# END
|
34
|
+
#end
|
35
|
+
#++
|
36
|
+
|
37
|
+
def add_expr(src, code, indicator)
|
38
|
+
case indicator
|
39
|
+
when '='
|
40
|
+
@escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
|
41
|
+
when '=='
|
42
|
+
@escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
|
43
|
+
when '==='
|
44
|
+
add_expr_debug(src, code)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
#--
|
52
|
+
## (obsolete)
|
53
|
+
#module FastEnhancer
|
54
|
+
#end
|
55
|
+
#++
|
56
|
+
|
57
|
+
|
58
|
+
##
|
59
|
+
## use $stdout instead of string
|
60
|
+
##
|
61
|
+
## this is only for Eruby.
|
62
|
+
##
|
63
|
+
module StdoutEnhancer
|
64
|
+
|
65
|
+
def self.desc # :nodoc:
|
66
|
+
"use $stdout instead of array buffer or string buffer"
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_preamble(src)
|
70
|
+
src << "#{@bufvar} = $stdout;"
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_postamble(src)
|
74
|
+
src << "\n''\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
##
|
81
|
+
## use print statement instead of '_buf << ...'
|
82
|
+
##
|
83
|
+
## this is only for Eruby.
|
84
|
+
##
|
85
|
+
module PrintOutEnhancer
|
86
|
+
|
87
|
+
def self.desc # :nodoc:
|
88
|
+
"use print statement instead of '_buf << ...'"
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_preamble(src)
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_text(src, text)
|
95
|
+
src << " print '#{escape_text(text)}';" unless text.empty?
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_expr_literal(src, code)
|
99
|
+
src << " print((#{code}).to_s);"
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_expr_escaped(src, code)
|
103
|
+
src << " print #{escaped_expr(code)};"
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_postamble(src)
|
107
|
+
src << "\n" unless src[-1] == ?\n
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
##
|
114
|
+
## enable print function
|
115
|
+
##
|
116
|
+
## Notice: use Eruby#evaluate() and don't use Eruby#result()
|
117
|
+
## to be enable print function.
|
118
|
+
##
|
119
|
+
## this is only for Eruby.
|
120
|
+
##
|
121
|
+
module PrintEnabledEnhancer
|
122
|
+
|
123
|
+
def self.desc # :nodoc:
|
124
|
+
"enable to use print function in '<% %>'"
|
125
|
+
end
|
126
|
+
|
127
|
+
def add_preamble(src)
|
128
|
+
src << "@_buf = "
|
129
|
+
super
|
130
|
+
end
|
131
|
+
|
132
|
+
def print(*args)
|
133
|
+
args.each do |arg|
|
134
|
+
@_buf << arg.to_s
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def evaluate(context=nil)
|
139
|
+
_src = @src
|
140
|
+
if context.is_a?(Hash)
|
141
|
+
context.each do |key, val| instance_variable_set("@#{key}", val) end
|
142
|
+
elsif context
|
143
|
+
context.instance_variables.each do |name|
|
144
|
+
instance_variable_set(name, context.instance_variable_get(name))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
return instance_eval(_src, (@filename || '(erubis)'))
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
##
|
154
|
+
## return array instead of string
|
155
|
+
##
|
156
|
+
## this is only for Eruby.
|
157
|
+
##
|
158
|
+
module ArrayEnhancer
|
159
|
+
|
160
|
+
def self.desc # :nodoc:
|
161
|
+
"return array instead of string"
|
162
|
+
end
|
163
|
+
|
164
|
+
def add_preamble(src)
|
165
|
+
src << "#{@bufvar} = [];"
|
166
|
+
end
|
167
|
+
|
168
|
+
def add_postamble(src)
|
169
|
+
src << "\n" unless src[-1] == ?\n
|
170
|
+
src << "#{@bufvar}\n"
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
##
|
177
|
+
## use an Array object as buffer (included in Eruby by default)
|
178
|
+
##
|
179
|
+
## this is only for Eruby.
|
180
|
+
##
|
181
|
+
module ArrayBufferEnhancer
|
182
|
+
|
183
|
+
def self.desc # :nodoc:
|
184
|
+
"use an Array object for buffering (included in Eruby class)"
|
185
|
+
end
|
186
|
+
|
187
|
+
def add_preamble(src)
|
188
|
+
src << "_buf = [];"
|
189
|
+
end
|
190
|
+
|
191
|
+
def add_postamble(src)
|
192
|
+
src << "\n" unless src[-1] == ?\n
|
193
|
+
src << "_buf.join\n"
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
##
|
200
|
+
## use String class for buffering
|
201
|
+
##
|
202
|
+
## this is only for Eruby.
|
203
|
+
##
|
204
|
+
module StringBufferEnhancer
|
205
|
+
|
206
|
+
def self.desc # :nodoc:
|
207
|
+
"use a String object for buffering"
|
208
|
+
end
|
209
|
+
|
210
|
+
def add_preamble(src)
|
211
|
+
src << "#{@bufvar} = '';"
|
212
|
+
end
|
213
|
+
|
214
|
+
def add_postamble(src)
|
215
|
+
src << "\n" unless src[-1] == ?\n
|
216
|
+
src << "#{@bufvar}.to_s\n"
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
|
222
|
+
##
|
223
|
+
## use StringIO class for buffering
|
224
|
+
##
|
225
|
+
## this is only for Eruby.
|
226
|
+
##
|
227
|
+
module StringIOEnhancer # :nodoc:
|
228
|
+
|
229
|
+
def self.desc # :nodoc:
|
230
|
+
"use a StringIO object for buffering"
|
231
|
+
end
|
232
|
+
|
233
|
+
def add_preamble(src)
|
234
|
+
src << "#{@bufvar} = StringIO.new;"
|
235
|
+
end
|
236
|
+
|
237
|
+
def add_postamble(src)
|
238
|
+
src << "\n" unless src[-1] == ?\n
|
239
|
+
src << "#{@bufvar}.string\n"
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
##
|
246
|
+
## set buffer variable name to '_erbout' as well as '_buf'
|
247
|
+
##
|
248
|
+
## this is only for Eruby.
|
249
|
+
##
|
250
|
+
module ErboutEnhancer
|
251
|
+
|
252
|
+
def self.desc # :nodoc:
|
253
|
+
"set '_erbout = _buf = \"\";' to be compatible with ERB."
|
254
|
+
end
|
255
|
+
|
256
|
+
def add_preamble(src)
|
257
|
+
src << "_erbout = #{@bufvar} = '';"
|
258
|
+
end
|
259
|
+
|
260
|
+
def add_postamble(src)
|
261
|
+
src << "\n" unless src[-1] == ?\n
|
262
|
+
src << "#{@bufvar}.to_s\n"
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
##
|
269
|
+
## remove text and leave code, especially useful when debugging.
|
270
|
+
##
|
271
|
+
## ex.
|
272
|
+
## $ erubis -s -E NoText file.eruby | more
|
273
|
+
##
|
274
|
+
## this is language independent.
|
275
|
+
##
|
276
|
+
module NoTextEnhancer
|
277
|
+
|
278
|
+
def self.desc # :nodoc:
|
279
|
+
"remove text and leave code (useful when debugging)"
|
280
|
+
end
|
281
|
+
|
282
|
+
def add_text(src, text)
|
283
|
+
src << ("\n" * text.count("\n"))
|
284
|
+
if text[-1] != ?\n
|
285
|
+
text =~ /^(.*?)\z/
|
286
|
+
src << (' ' * $1.length)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
|
293
|
+
##
|
294
|
+
## remove code and leave text, especially useful when validating HTML tags.
|
295
|
+
##
|
296
|
+
## ex.
|
297
|
+
## $ erubis -s -E NoCode file.eruby | tidy -errors
|
298
|
+
##
|
299
|
+
## this is language independent.
|
300
|
+
##
|
301
|
+
module NoCodeEnhancer
|
302
|
+
|
303
|
+
def self.desc # :nodoc:
|
304
|
+
"remove code and leave text (useful when validating HTML)"
|
305
|
+
end
|
306
|
+
|
307
|
+
def add_preamble(src)
|
308
|
+
end
|
309
|
+
|
310
|
+
def add_postamble(src)
|
311
|
+
end
|
312
|
+
|
313
|
+
def add_text(src, text)
|
314
|
+
src << text
|
315
|
+
end
|
316
|
+
|
317
|
+
def add_expr(src, code, indicator)
|
318
|
+
src << "\n" * code.count("\n")
|
319
|
+
end
|
320
|
+
|
321
|
+
def add_stmt(src, code)
|
322
|
+
src << "\n" * code.count("\n")
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
##
|
329
|
+
## get convert faster, but spaces around '<%...%>' are not trimmed.
|
330
|
+
##
|
331
|
+
## this is language-independent.
|
332
|
+
##
|
333
|
+
module SimplifyEnhancer
|
334
|
+
|
335
|
+
def self.desc # :nodoc:
|
336
|
+
"get convert faster but leave spaces around '<% %>'"
|
337
|
+
end
|
338
|
+
|
339
|
+
#DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
|
340
|
+
SIMPLE_REGEXP = /<%(=+|\#)?(.*?)-?%>/m
|
341
|
+
|
342
|
+
def convert(input)
|
343
|
+
src = ""
|
344
|
+
add_preamble(src)
|
345
|
+
#regexp = pattern_regexp(@pattern)
|
346
|
+
pos = 0
|
347
|
+
input.scan(SIMPLE_REGEXP) do |indicator, code|
|
348
|
+
match = Regexp.last_match
|
349
|
+
index = match.begin(0)
|
350
|
+
text = input[pos, index - pos]
|
351
|
+
pos = match.end(0)
|
352
|
+
add_text(src, text)
|
353
|
+
if !indicator # <% %>
|
354
|
+
add_stmt(src, code)
|
355
|
+
elsif indicator[0] == ?\# # <%# %>
|
356
|
+
n = code.count("\n")
|
357
|
+
add_stmt(src, "\n" * n)
|
358
|
+
else # <%= %>
|
359
|
+
add_expr(src, code, indicator)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
#rest = $' || input # ruby1.8
|
363
|
+
rest = pos == 0 ? input : input[pos..-1] # ruby1.9
|
364
|
+
add_text(src, rest)
|
365
|
+
add_postamble(src)
|
366
|
+
return src
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
|
371
|
+
|
372
|
+
##
|
373
|
+
## enable to use other embedded expression pattern (default is '\[= =\]').
|
374
|
+
##
|
375
|
+
## notice! this is an experimental. spec may change in the future.
|
376
|
+
##
|
377
|
+
## ex.
|
378
|
+
## input = <<END
|
379
|
+
## <% for item in list %>
|
380
|
+
## <%= item %> : <%== item %>
|
381
|
+
## [= item =] : [== item =]
|
382
|
+
## <% end %>
|
383
|
+
## END
|
384
|
+
##
|
385
|
+
## class BiPatternEruby
|
386
|
+
## include BiPatternEnhancer
|
387
|
+
## end
|
388
|
+
## eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]')
|
389
|
+
## list = ['<a>', 'b&b', '"c"']
|
390
|
+
## print eruby.result(binding())
|
391
|
+
##
|
392
|
+
## ## output
|
393
|
+
## <a> : <a>
|
394
|
+
## <a> : <a>
|
395
|
+
## b&b : b&b
|
396
|
+
## b&b : b&b
|
397
|
+
## "c" : "c"
|
398
|
+
## "c" : "c"
|
399
|
+
##
|
400
|
+
## this is language independent.
|
401
|
+
##
|
402
|
+
module BiPatternEnhancer
|
403
|
+
|
404
|
+
def self.desc # :nodoc:
|
405
|
+
"another embedded expression pattern (default '\[= =\]')."
|
406
|
+
end
|
407
|
+
|
408
|
+
def initialize(input, properties={})
|
409
|
+
self.bipattern = properties[:bipattern] # or '\$\{ \}'
|
410
|
+
super
|
411
|
+
end
|
412
|
+
|
413
|
+
## when pat is nil then '\[= =\]' is used
|
414
|
+
def bipattern=(pat) # :nodoc:
|
415
|
+
@bipattern = pat || '\[= =\]'
|
416
|
+
pre, post = @bipattern.split()
|
417
|
+
@bipattern_regexp = /(.*?)#{pre}(=*)(.*?)#{post}/m
|
418
|
+
end
|
419
|
+
|
420
|
+
def add_text(src, text)
|
421
|
+
return unless text
|
422
|
+
m = nil
|
423
|
+
text.scan(@bipattern_regexp) do |txt, indicator, code|
|
424
|
+
m = Regexp.last_match
|
425
|
+
super(src, txt)
|
426
|
+
add_expr(src, code, '=' + indicator)
|
427
|
+
end
|
428
|
+
#rest = $' || text # ruby1.8
|
429
|
+
rest = m ? text[m.end(0)..-1] : text # ruby1.9
|
430
|
+
super(src, rest)
|
431
|
+
end
|
432
|
+
|
433
|
+
end
|
434
|
+
|
435
|
+
|
436
|
+
##
|
437
|
+
## regards lines starting with '^[ \t]*%' as program code
|
438
|
+
##
|
439
|
+
## in addition you can specify prefix character (default '%')
|
440
|
+
##
|
441
|
+
## this is language-independent.
|
442
|
+
##
|
443
|
+
module PrefixedLineEnhancer
|
444
|
+
|
445
|
+
def self.desc # :nodoc:
|
446
|
+
"regard lines matched to '^[ \t]*%' as program code"
|
447
|
+
end
|
448
|
+
|
449
|
+
def init_generator(properties={})
|
450
|
+
super
|
451
|
+
@prefixchar = properties[:prefixchar]
|
452
|
+
end
|
453
|
+
|
454
|
+
def add_text(src, text)
|
455
|
+
unless @prefixrexp
|
456
|
+
@prefixchar ||= '%'
|
457
|
+
@prefixrexp = Regexp.compile("^([ \\t]*)\\#{@prefixchar}(.*?\\r?\\n)")
|
458
|
+
end
|
459
|
+
pos = 0
|
460
|
+
text2 = ''
|
461
|
+
text.scan(@prefixrexp) do
|
462
|
+
space = $1
|
463
|
+
line = $2
|
464
|
+
space, line = '', $1 unless $2
|
465
|
+
match = Regexp.last_match
|
466
|
+
len = match.begin(0) - pos
|
467
|
+
str = text[pos, len]
|
468
|
+
pos = match.end(0)
|
469
|
+
if text2.empty?
|
470
|
+
text2 = str
|
471
|
+
else
|
472
|
+
text2 << str
|
473
|
+
end
|
474
|
+
if line[0, 1] == @prefixchar
|
475
|
+
text2 << space << line
|
476
|
+
else
|
477
|
+
super(src, text2)
|
478
|
+
text2 = ''
|
479
|
+
add_stmt(src, space + line)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
#rest = pos == 0 ? text : $' # ruby1.8
|
483
|
+
rest = pos == 0 ? text : text[pos..-1] # ruby1.9
|
484
|
+
unless text2.empty?
|
485
|
+
text2 << rest if rest
|
486
|
+
rest = text2
|
487
|
+
end
|
488
|
+
super(src, rest)
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
|
494
|
+
##
|
495
|
+
## regards lines starting with '%' as program code
|
496
|
+
##
|
497
|
+
## this is for compatibility to eruby and ERB.
|
498
|
+
##
|
499
|
+
## this is language-independent.
|
500
|
+
##
|
501
|
+
module PercentLineEnhancer
|
502
|
+
include PrefixedLineEnhancer
|
503
|
+
|
504
|
+
def self.desc # :nodoc:
|
505
|
+
"regard lines starting with '%' as program code"
|
506
|
+
end
|
507
|
+
|
508
|
+
#--
|
509
|
+
#def init_generator(properties={})
|
510
|
+
# super
|
511
|
+
# @prefixchar = '%'
|
512
|
+
# @prefixrexp = /^\%(.*?\r?\n)/
|
513
|
+
#end
|
514
|
+
#++
|
515
|
+
|
516
|
+
def add_text(src, text)
|
517
|
+
unless @prefixrexp
|
518
|
+
@prefixchar = '%'
|
519
|
+
@prefixrexp = /^\%(.*?\r?\n)/
|
520
|
+
end
|
521
|
+
super(src, text)
|
522
|
+
end
|
523
|
+
|
524
|
+
end
|
525
|
+
|
526
|
+
|
527
|
+
##
|
528
|
+
## [experimental] allow header and footer in eRuby script
|
529
|
+
##
|
530
|
+
## ex.
|
531
|
+
## ====================
|
532
|
+
## ## without header and footer
|
533
|
+
## $ cat ex1.eruby
|
534
|
+
## <% def list_items(list) %>
|
535
|
+
## <% for item in list %>
|
536
|
+
## <li><%= item %></li>
|
537
|
+
## <% end %>
|
538
|
+
## <% end %>
|
539
|
+
##
|
540
|
+
## $ erubis -s ex1.eruby
|
541
|
+
## _buf = []; def list_items(list)
|
542
|
+
## ; for item in list
|
543
|
+
## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
|
544
|
+
## '; end
|
545
|
+
## ; end
|
546
|
+
## ;
|
547
|
+
## _buf.join
|
548
|
+
##
|
549
|
+
## ## with header and footer
|
550
|
+
## $ cat ex2.eruby
|
551
|
+
## <!--#header:
|
552
|
+
## def list_items(list)
|
553
|
+
## #-->
|
554
|
+
## <% for item in list %>
|
555
|
+
## <li><%= item %></li>
|
556
|
+
## <% end %>
|
557
|
+
## <!--#footer:
|
558
|
+
## end
|
559
|
+
## #-->
|
560
|
+
##
|
561
|
+
## $ erubis -s -c HeaderFooterEruby ex4.eruby
|
562
|
+
##
|
563
|
+
## def list_items(list)
|
564
|
+
## _buf = []; _buf << '
|
565
|
+
## '; for item in list
|
566
|
+
## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
|
567
|
+
## '; end
|
568
|
+
## ; _buf << '
|
569
|
+
## ';
|
570
|
+
## _buf.join
|
571
|
+
## end
|
572
|
+
##
|
573
|
+
## ====================
|
574
|
+
##
|
575
|
+
## this is language-independent.
|
576
|
+
##
|
577
|
+
module HeaderFooterEnhancer
|
578
|
+
|
579
|
+
def self.desc # :nodoc:
|
580
|
+
"allow header/footer in document (ex. '<!--#header: #-->')"
|
581
|
+
end
|
582
|
+
|
583
|
+
HEADER_FOOTER_PATTERN = /(.*?)(^[ \t]*)?<!--\#(\w+):(.*?)\#-->([ \t]*\r?\n)?/m
|
584
|
+
|
585
|
+
def add_text(src, text)
|
586
|
+
m = nil
|
587
|
+
text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace|
|
588
|
+
m = Regexp.last_match
|
589
|
+
flag_trim = @trim && lspace && rspace
|
590
|
+
super(src, txt)
|
591
|
+
content = "#{lspace}#{content}#{rspace}" if flag_trim
|
592
|
+
super(src, lspace) if !flag_trim && lspace
|
593
|
+
instance_variable_set("@#{word}", content)
|
594
|
+
super(src, rspace) if !flag_trim && rspace
|
595
|
+
end
|
596
|
+
#rest = $' || text # ruby1.8
|
597
|
+
rest = m ? text[m.end(0)..-1] : text # ruby1.9
|
598
|
+
super(src, rest)
|
599
|
+
end
|
600
|
+
|
601
|
+
attr_accessor :header, :footer
|
602
|
+
|
603
|
+
def convert(input)
|
604
|
+
source = super
|
605
|
+
return @src = "#{@header}#{source}#{@footer}"
|
606
|
+
end
|
607
|
+
|
608
|
+
end
|
609
|
+
|
610
|
+
|
611
|
+
##
|
612
|
+
## delete indentation of HTML.
|
613
|
+
##
|
614
|
+
## this is language-independent.
|
615
|
+
##
|
616
|
+
module DeleteIndentEnhancer
|
617
|
+
|
618
|
+
def self.desc # :nodoc:
|
619
|
+
"delete indentation of HTML."
|
620
|
+
end
|
621
|
+
|
622
|
+
def convert_input(src, input)
|
623
|
+
input = input.gsub(/^[ \t]+</, '<')
|
624
|
+
super(src, input)
|
625
|
+
end
|
626
|
+
|
627
|
+
end
|
628
|
+
|
629
|
+
|
630
|
+
##
|
631
|
+
## convert "<h1><%=title%></h1>" into "_buf << %Q`<h1>#{title}</h1>`"
|
632
|
+
##
|
633
|
+
## this is only for Eruby.
|
634
|
+
##
|
635
|
+
module InterpolationEnhancer
|
636
|
+
|
637
|
+
def self.desc # :nodoc:
|
638
|
+
"convert '<p><%=text%></p>' into '_buf << %Q`<p>\#{text}</p>`'"
|
639
|
+
end
|
640
|
+
|
641
|
+
def convert_input(src, input)
|
642
|
+
pat = @pattern
|
643
|
+
regexp = pat.nil? || pat == '<% %>' ? Basic::Converter::DEFAULT_REGEXP : pattern_regexp(pat)
|
644
|
+
pos = 0
|
645
|
+
is_bol = true # is beginning of line
|
646
|
+
str = ''
|
647
|
+
input.scan(regexp) do |indicator, code, tailch, rspace|
|
648
|
+
match = Regexp.last_match()
|
649
|
+
len = match.begin(0) - pos
|
650
|
+
text = input[pos, len]
|
651
|
+
pos = match.end(0)
|
652
|
+
ch = indicator ? indicator[0] : nil
|
653
|
+
lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
|
654
|
+
is_bol = rspace ? true : false
|
655
|
+
_add_text_to_str(str, text)
|
656
|
+
## * when '<%= %>', do nothing
|
657
|
+
## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
|
658
|
+
if ch == ?= # <%= %>
|
659
|
+
rspace = nil if tailch && !tailch.empty?
|
660
|
+
str << lspace if lspace
|
661
|
+
add_expr(str, code, indicator)
|
662
|
+
str << rspace if rspace
|
663
|
+
elsif ch == ?\# # <%# %>
|
664
|
+
n = code.count("\n") + (rspace ? 1 : 0)
|
665
|
+
if @trim && lspace && rspace
|
666
|
+
add_text(src, str)
|
667
|
+
str = ''
|
668
|
+
add_stmt(src, "\n" * n)
|
669
|
+
else
|
670
|
+
str << lspace if lspace
|
671
|
+
add_text(src, str)
|
672
|
+
str = ''
|
673
|
+
add_stmt(src, "\n" * n)
|
674
|
+
str << rspace if rspace
|
675
|
+
end
|
676
|
+
else # <% %>
|
677
|
+
if @trim && lspace && rspace
|
678
|
+
add_text(src, str)
|
679
|
+
str = ''
|
680
|
+
add_stmt(src, "#{lspace}#{code}#{rspace}")
|
681
|
+
else
|
682
|
+
str << lspace if lspace
|
683
|
+
add_text(src, str)
|
684
|
+
str = ''
|
685
|
+
add_stmt(src, code)
|
686
|
+
str << rspace if rspace
|
687
|
+
end
|
688
|
+
end
|
689
|
+
end
|
690
|
+
#rest = $' || input # ruby1.8
|
691
|
+
rest = pos == 0 ? input : input[pos..-1] # ruby1.9
|
692
|
+
_add_text_to_str(str, rest)
|
693
|
+
add_text(src, str)
|
694
|
+
end
|
695
|
+
|
696
|
+
def add_text(src, text)
|
697
|
+
return if !text || text.empty?
|
698
|
+
#src << " _buf << %Q`" << text << "`;"
|
699
|
+
if text[-1] == ?\n
|
700
|
+
text[-1] = "\\n"
|
701
|
+
src << " #{@bufvar} << %Q`#{text}`\n"
|
702
|
+
else
|
703
|
+
src << " #{@bufvar} << %Q`#{text}`;"
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
def _add_text_to_str(str, text)
|
708
|
+
return if !text || text.empty?
|
709
|
+
str << text.gsub(/[`\#\\]/, '\\\\\&')
|
710
|
+
end
|
711
|
+
|
712
|
+
def add_expr_escaped(str, code)
|
713
|
+
str << "\#{#{escaped_expr(code)}}"
|
714
|
+
end
|
715
|
+
|
716
|
+
def add_expr_literal(str, code)
|
717
|
+
str << "\#{#{code}}"
|
718
|
+
end
|
719
|
+
|
720
|
+
end
|
721
|
+
|
722
|
+
|
723
|
+
end
|