erbse 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,4 @@
1
+ </table>
2
+
3
+ </body>
4
+ </html>
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <title>Stock Prices</title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
8
+ <meta http-equiv="Content-Style-Type" content="text/css" />
9
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
10
+ <link rel="shortcut icon" href="/images/favicon.ico" />
11
+ <link rel="stylesheet" type="text/css" href="/css/style.css" media="all" />
12
+ <script type="text/javascript" src="/js/util.js"></script>
13
+ <style type="text/css">
14
+ /*<![CDATA[*/
15
+
16
+ body {
17
+ color: #333333;
18
+ line-height: 150%;
19
+ }
20
+
21
+ thead {
22
+ font-weight: bold;
23
+ background-color: #CCCCCC;
24
+ }
25
+
26
+ .odd {
27
+ background-color: #FFCCCC;
28
+ }
29
+
30
+ .even {
31
+ background-color: #CCCCFF;
32
+ }
33
+
34
+ .minus {
35
+ color: #FF0000;
36
+ }
37
+
38
+ /*]]>*/
39
+ </style>
40
+
41
+ </head>
42
+
43
+ <body>
44
+
45
+ <h1>Stock Prices</h1>
46
+
47
+ <table>
48
+ <thead>
49
+ <tr>
50
+ <th>#</th><th>symbol</th><th>name</th><th>price</th><th>change</th><th>ratio</th>
51
+ </tr>
52
+ </thead>
@@ -0,0 +1,29 @@
1
+ <tbody>
2
+ <%
3
+ n = 0
4
+ for item in list
5
+ n += 1
6
+ %>
7
+ <tr class="<%= n % 2 == 0 ? 'even' : 'odd' %>">
8
+ <td style="text-align: center"><%= n %></td>
9
+ <td>
10
+ <a href="/stocks/<%= item['symbol'] %>"><%= item['symbol'] %></a>
11
+ </td>
12
+ <td>
13
+ <a href="<%= item['url'] %>"><%= item['name'] %></a>
14
+ </td>
15
+ <td>
16
+ <strong><%= item['price'] %></strong>
17
+ </td>
18
+ <% if item['change'] < 0.0 %>
19
+ <td class="minus"><%= item['change'] %></td>
20
+ <td class="minus"><%= item['ratio'] %></td>
21
+ <% else %>
22
+ <td><%= item['change'] %></td>
23
+ <td><%= item['ratio'] %></td>
24
+ <% end %>
25
+ </tr>
26
+ <%
27
+ end
28
+ %>
29
+ </tbody>
@@ -0,0 +1,29 @@
1
+ <tbody>
2
+ <%
3
+ n = 0
4
+ for item in list
5
+ n += 1
6
+ %>
7
+ <tr class="<%= n % 2 == 0 ? 'even' : 'odd' %>">
8
+ <td style="text-align: center"><%= n %></td>
9
+ <td>
10
+ <a href="/stocks/<%= item['symbol'] %>"><%= item['symbol'] %></a>
11
+ </td>
12
+ <td>
13
+ <a href="<%= item['url'] %>"><%= item['name'] %></a>
14
+ </td>
15
+ <td>
16
+ <strong><%= item['price'] %></strong>
17
+ </td>
18
+ <% if item['change'] < 0.0 %>
19
+ <td class="minus"><%= item['change'] %></td>
20
+ <td class="minus"><%= item['ratio'] %></td>
21
+ <% else %>
22
+ <td><%= item['change'] %></td>
23
+ <td><%= item['ratio'] %></td>
24
+ <% end %>
25
+ </tr>
26
+ <%
27
+ end
28
+ %>
29
+ </tbody>
@@ -0,0 +1,29 @@
1
+ <tbody>
2
+ <%
3
+ n = 0
4
+ for item in list
5
+ n += 1
6
+ %>
7
+ <tr class="<%= n % 2 == 0 ? 'even' : 'odd' %>">
8
+ <td style="text-align: center"><%= n %></td>
9
+ <td>
10
+ <a href="/stocks/<%= item['symbol'] %>"><%= item['symbol'] %></a>
11
+ </td>
12
+ <td>
13
+ <a href="<%= item['url'] %>"><%= item['name'] %></a>
14
+ </td>
15
+ <td>
16
+ <strong><%= item['price'] %></strong>
17
+ </td>
18
+ <% if item['change'] < 0.0 %>
19
+ <td class="minus"><%= item['change'] %></td>
20
+ <td class="minus"><%= item['ratio'] %></td>
21
+ <% else %>
22
+ <td><%= item['change'] %></td>
23
+ <td><%= item['ratio'] %></td>
24
+ <% end %>
25
+ </tr>
26
+ <%
27
+ end
28
+ %>
29
+ </tbody>
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ###
4
+ ### $Release: 2.7.0 $
5
+ ### copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
6
+ ###
7
+
8
+ require 'erubis/main'
9
+
10
+ Erubis::Main.main(ARGV)
@@ -0,0 +1,24 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require 'erbse/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "erbse"
8
+ spec.version = Erbse::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["Nick Sutterer"]
11
+ spec.email = ["apotonick@gmail.com"]
12
+ spec.homepage = "https://github.com/apotonick/erbse"
13
+ spec.summary = %q{Updated Erubis.}
14
+ spec.description = %q{An updated Erubis with block support. Block inheritance soon to come.}
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files`.split("\n")
18
+ spec.test_files = `git ls-files -- {test}/*`.split("\n")
19
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "minitest"
24
+ end
@@ -0,0 +1,52 @@
1
+ ##
2
+ ## an implementation of eRuby
3
+ ##
4
+ ## ex.
5
+ ## input = <<'END'
6
+ ## <ul>
7
+ ## <% for item in @list %>
8
+ ## <li><%= item %>
9
+ ## <%== item %></li>
10
+ ## <% end %>
11
+ ## </ul>
12
+ ## END
13
+ ## list = ['<aaa>', 'b&b', '"ccc"']
14
+ ## eruby = Erubis::Eruby.new(input)
15
+ ## puts "--- code ---"
16
+ ## puts eruby.src
17
+ ## puts "--- result ---"
18
+ ## context = Erubis::Context.new() # or new(:list=>list)
19
+ ## context[:list] = list
20
+ ## puts eruby.evaluate(context)
21
+ ##
22
+ ## result:
23
+ ## --- source ---
24
+ ## _buf = ''; _buf << '<ul>
25
+ ## '; for item in @list
26
+ ## _buf << ' <li>'; _buf << ( item ).to_s; _buf << '
27
+ ## '; _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</li>
28
+ ## '; end
29
+ ## _buf << '</ul>
30
+ ## ';
31
+ ## _buf.to_s
32
+ ## --- result ---
33
+ ## <ul>
34
+ ## <li><aaa>
35
+ ## &lt;aaa&gt;</li>
36
+ ## <li>b&b
37
+ ## b&amp;b</li>
38
+ ## <li>"ccc"
39
+ ## &quot;ccc&quot;</li>
40
+ ## </ul>
41
+ ##
42
+
43
+
44
+ module Erbse
45
+ end
46
+
47
+ require 'erbse/engine'
48
+ # require 'erbse/helper'
49
+ # require 'erbse/enhancer'
50
+ require 'erbse/engine/eruby'
51
+
52
+ # require 'erbse/local-setting'
@@ -0,0 +1,83 @@
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
+ ## context object for Engine#evaluate
12
+ ##
13
+ ## ex.
14
+ ## template = <<'END'
15
+ ## Hello <%= @user %>!
16
+ ## <% for item in @list %>
17
+ ## - <%= item %>
18
+ ## <% end %>
19
+ ## END
20
+ ##
21
+ ## context = Erubis::Context.new(:user=>'World', :list=>['a','b','c'])
22
+ ## # or
23
+ ## # context = Erubis::Context.new
24
+ ## # context[:user] = 'World'
25
+ ## # context[:list] = ['a', 'b', 'c']
26
+ ##
27
+ ## eruby = Erubis::Eruby.new(template)
28
+ ## print eruby.evaluate(context)
29
+ ##
30
+ class Context
31
+ include Enumerable
32
+
33
+ def initialize(hash=nil)
34
+ hash.each do |name, value|
35
+ self[name] = value
36
+ end if hash
37
+ end
38
+
39
+ def [](key)
40
+ return instance_variable_get("@#{key}")
41
+ end
42
+
43
+ def []=(key, value)
44
+ return instance_variable_set("@#{key}", value)
45
+ end
46
+
47
+ def keys
48
+ return instance_variables.collect { |name| name[1..-1] }
49
+ end
50
+
51
+ def each
52
+ instance_variables.each do |name|
53
+ key = name[1..-1]
54
+ value = instance_variable_get(name)
55
+ yield(key, value)
56
+ end
57
+ end
58
+
59
+ def to_hash
60
+ hash = {}
61
+ self.keys.each { |key| hash[key] = self[key] }
62
+ return hash
63
+ end
64
+
65
+ def update(context_or_hash)
66
+ arg = context_or_hash
67
+ if arg.is_a?(Hash)
68
+ arg.each do |key, val|
69
+ self[key] = val
70
+ end
71
+ else
72
+ arg.instance_variables.each do |varname|
73
+ key = varname[1..-1]
74
+ val = arg.instance_variable_get(varname)
75
+ self[key] = val
76
+ end
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+
83
+ end
@@ -0,0 +1,357 @@
1
+ ##
2
+ ## $Release: 2.7.0 $
3
+ ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
4
+ ##
5
+
6
+ require 'erubis/util'
7
+
8
+ module Erubis
9
+
10
+
11
+ ##
12
+ ## convert
13
+ ##
14
+ module Converter
15
+
16
+ attr_accessor :preamble, :postamble, :escape
17
+
18
+ def self.supported_properties # :nodoc:
19
+ return [
20
+ [:preamble, nil, "preamble (no preamble when false)"],
21
+ [:postamble, nil, "postamble (no postamble when false)"],
22
+ [:escape, nil, "escape expression or not in default"],
23
+ ]
24
+ end
25
+
26
+ def init_converter(properties={})
27
+ @preamble = properties[:preamble]
28
+ @postamble = properties[:postamble]
29
+ @escape = properties[:escape]
30
+ end
31
+
32
+ ## convert input string into target language
33
+ def convert(input)
34
+ codebuf = "" # or []
35
+ @preamble.nil? ? add_preamble(codebuf) : (@preamble && (codebuf << @preamble))
36
+ convert_input(codebuf, input)
37
+ @postamble.nil? ? add_postamble(codebuf) : (@postamble && (codebuf << @postamble))
38
+ @_proc = nil # clear cached proc object
39
+ return codebuf # or codebuf.join()
40
+ end
41
+
42
+ protected
43
+
44
+ ##
45
+ ## detect spaces at beginning of line
46
+ ##
47
+ def detect_spaces_at_bol(text, is_bol)
48
+ lspace = nil
49
+ if text.empty?
50
+ lspace = "" if is_bol
51
+ elsif text[-1] == ?\n
52
+ lspace = ""
53
+ else
54
+ rindex = text.rindex(?\n)
55
+ if rindex
56
+ s = text[rindex+1..-1]
57
+ if s =~ /\A[ \t]*\z/
58
+ lspace = s
59
+ #text = text[0..rindex]
60
+ text[rindex+1..-1] = ''
61
+ end
62
+ else
63
+ if is_bol && text =~ /\A[ \t]*\z/
64
+ #lspace = text
65
+ #text = nil
66
+ lspace = text.dup
67
+ text[0..-1] = ''
68
+ end
69
+ end
70
+ end
71
+ return lspace
72
+ end
73
+
74
+ ##
75
+ ## (abstract) convert input to code
76
+ ##
77
+ def convert_input(codebuf, input)
78
+ not_implemented
79
+ end
80
+
81
+ end
82
+
83
+
84
+ module Basic
85
+ end
86
+
87
+
88
+ ##
89
+ ## basic converter which supports '<% ... %>' notation.
90
+ ##
91
+ module Basic::Converter
92
+ include Erubis::Converter
93
+
94
+ def self.supported_properties # :nodoc:
95
+ return [
96
+ [:pattern, '<% %>', "embed pattern"],
97
+ [:trim, true, "trim spaces around <% ... %>"],
98
+ ]
99
+ end
100
+
101
+ attr_accessor :pattern, :trim
102
+
103
+ def init_converter(properties={})
104
+ super(properties)
105
+ @pattern = properties[:pattern]
106
+ @trim = properties[:trim] != false
107
+ end
108
+
109
+ protected
110
+
111
+ ## return regexp of pattern to parse eRuby script
112
+ def pattern_regexp(pattern)
113
+ @prefix, @postfix = pattern.split() # '<% %>' => '<%', '%>'
114
+ #return /(.*?)(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m
115
+ #return /(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m
116
+ return /#{@prefix}(=+|-|\#|%)?(.*?)([-=])?#{@postfix}([ \t]*\r?\n)?/m
117
+ end
118
+ module_function :pattern_regexp
119
+
120
+ #DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
121
+ #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
122
+ #DEFAULT_REGEXP = /<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
123
+ DEFAULT_REGEXP = pattern_regexp('<% %>')
124
+
125
+ public
126
+
127
+ def convert_input(src, input)
128
+ pat = @pattern
129
+ regexp = pat.nil? || pat == '<% %>' ? DEFAULT_REGEXP : pattern_regexp(pat)
130
+ pos = 0
131
+ is_bol = true # is beginning of line
132
+ input.scan(regexp) do |indicator, code, tailch, rspace|
133
+ match = Regexp.last_match()
134
+ len = match.begin(0) - pos
135
+ text = input[pos, len]
136
+ pos = match.end(0)
137
+ ch = indicator ? indicator[0] : nil
138
+ lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
139
+ is_bol = rspace ? true : false
140
+ add_text(src, text) if text && !text.empty?
141
+ ## * when '<%= %>', do nothing
142
+ ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
143
+ if ch == ?= # <%= %>
144
+ rspace = nil if tailch && !tailch.empty?
145
+ add_text(src, lspace) if lspace
146
+ add_expr(src, code, indicator)
147
+ add_text(src, rspace) if rspace
148
+ elsif ch == ?\# # <%# %>
149
+ n = code.count("\n") + (rspace ? 1 : 0)
150
+ if @trim && lspace && rspace
151
+ add_stmt(src, "\n" * n)
152
+ else
153
+ add_text(src, lspace) if lspace
154
+ add_stmt(src, "\n" * n)
155
+ add_text(src, rspace) if rspace
156
+ end
157
+ elsif ch == ?% # <%% %>
158
+ s = "#{lspace}#{@prefix||='<%'}#{code}#{tailch}#{@postfix||='%>'}#{rspace}"
159
+ add_text(src, s)
160
+ else # <% %>
161
+ if @trim && lspace && rspace
162
+ add_stmt(src, "#{lspace}#{code}#{rspace}")
163
+ else
164
+ add_text(src, lspace) if lspace
165
+ add_stmt(src, code)
166
+ add_text(src, rspace) if rspace
167
+ end
168
+ end
169
+ end
170
+ #rest = $' || input # ruby1.8
171
+ rest = pos == 0 ? input : input[pos..-1] # ruby1.9
172
+ add_text(src, rest)
173
+ end
174
+
175
+ ## add expression code to src
176
+ def add_expr(src, code, indicator)
177
+ case indicator
178
+ when '='
179
+ @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
180
+ when '=='
181
+ @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
182
+ when '==='
183
+ add_expr_debug(src, code)
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+
190
+ module PI
191
+ end
192
+
193
+ ##
194
+ ## Processing Instructions (PI) converter for XML.
195
+ ## this class converts '<?rb ... ?>' and '${...}' notation.
196
+ ##
197
+ module PI::Converter
198
+ include Erubis::Converter
199
+
200
+ def self.desc # :nodoc:
201
+ "use processing instructions (PI) instead of '<% %>'"
202
+ end
203
+
204
+ def self.supported_properties # :nodoc:
205
+ return [
206
+ [:trim, true, "trim spaces around <% ... %>"],
207
+ [:pi, 'rb', "PI (Processing Instrunctions) name"],
208
+ [:embchar, '@', "char for embedded expression pattern('@{...}@')"],
209
+ [:pattern, '<% %>', "embed pattern"],
210
+ ]
211
+ end
212
+
213
+ attr_accessor :pi, :prefix
214
+
215
+ def init_converter(properties={})
216
+ super(properties)
217
+ @trim = properties.fetch(:trim, true)
218
+ @pi = properties[:pi] if properties[:pi]
219
+ @embchar = properties[:embchar] || '@'
220
+ @pattern = properties[:pattern]
221
+ @pattern = '<% %>' if @pattern.nil? #|| @pattern == true
222
+ end
223
+
224
+ def convert(input)
225
+ code = super(input)
226
+ return @header || @footer ? "#{@header}#{code}#{@footer}" : code
227
+ end
228
+
229
+ protected
230
+
231
+ def convert_input(codebuf, input)
232
+ unless @regexp
233
+ @pi ||= 'e'
234
+ ch = Regexp.escape(@embchar)
235
+ if @pattern
236
+ left, right = @pattern.split(' ')
237
+ @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/m
238
+ else
239
+ @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}/m
240
+ end
241
+ end
242
+ #
243
+ is_bol = true
244
+ pos = 0
245
+ input.scan(@regexp) do |pi_arg, stmt, rspace,
246
+ indicator1, expr1, indicator2, expr2|
247
+ match = Regexp.last_match
248
+ len = match.begin(0) - pos
249
+ text = input[pos, len]
250
+ pos = match.end(0)
251
+ lspace = stmt ? detect_spaces_at_bol(text, is_bol) : nil
252
+ is_bol = stmt && rspace ? true : false
253
+ add_text(codebuf, text) # unless text.empty?
254
+ #
255
+ if stmt
256
+ if @trim && lspace && rspace
257
+ add_pi_stmt(codebuf, "#{lspace}#{stmt}#{rspace}", pi_arg)
258
+ else
259
+ add_text(codebuf, lspace) if lspace
260
+ add_pi_stmt(codebuf, stmt, pi_arg)
261
+ add_text(codebuf, rspace) if rspace
262
+ end
263
+ else
264
+ add_pi_expr(codebuf, expr1 || expr2, indicator1 || indicator2)
265
+ end
266
+ end
267
+ #rest = $' || input # ruby1.8
268
+ rest = pos == 0 ? input : input[pos..-1] # ruby1.9
269
+ add_text(codebuf, rest)
270
+ end
271
+
272
+ #--
273
+ #def convert_input(codebuf, input)
274
+ # parse_stmts(codebuf, input)
275
+ # #parse_stmts2(codebuf, input)
276
+ #end
277
+ #
278
+ #def parse_stmts(codebuf, input)
279
+ # #regexp = pattern_regexp(@pattern)
280
+ # @pi ||= 'e'
281
+ # @stmt_pattern ||= /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?/m
282
+ # is_bol = true
283
+ # pos = 0
284
+ # input.scan(@stmt_pattern) do |pi_arg, code, rspace|
285
+ # match = Regexp.last_match
286
+ # len = match.begin(0) - pos
287
+ # text = input[pos, len]
288
+ # pos = match.end(0)
289
+ # lspace = detect_spaces_at_bol(text, is_bol)
290
+ # is_bol = rspace ? true : false
291
+ # parse_exprs(codebuf, text) # unless text.empty?
292
+ # if @trim && lspace && rspace
293
+ # add_pi_stmt(codebuf, "#{lspace}#{code}#{rspace}", pi_arg)
294
+ # else
295
+ # add_text(codebuf, lspace)
296
+ # add_pi_stmt(codebuf, code, pi_arg)
297
+ # add_text(codebuf, rspace)
298
+ # end
299
+ # end
300
+ # rest = $' || input
301
+ # parse_exprs(codebuf, rest)
302
+ #end
303
+ #
304
+ #def parse_exprs(codebuf, input)
305
+ # unless @expr_pattern
306
+ # ch = Regexp.escape(@embchar)
307
+ # if @pattern
308
+ # left, right = @pattern.split(' ')
309
+ # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/
310
+ # else
311
+ # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}/
312
+ # end
313
+ # end
314
+ # pos = 0
315
+ # input.scan(@expr_pattern) do |indicator1, code1, indicator2, code2|
316
+ # indicator = indicator1 || indicator2
317
+ # code = code1 || code2
318
+ # match = Regexp.last_match
319
+ # len = match.begin(0) - pos
320
+ # text = input[pos, len]
321
+ # pos = match.end(0)
322
+ # add_text(codebuf, text) # unless text.empty?
323
+ # add_pi_expr(codebuf, code, indicator)
324
+ # end
325
+ # rest = $' || input
326
+ # add_text(codebuf, rest)
327
+ #end
328
+ #++
329
+
330
+ def add_pi_stmt(codebuf, code, pi_arg) # :nodoc:
331
+ case pi_arg
332
+ when nil ; add_stmt(codebuf, code)
333
+ when 'header' ; @header = code
334
+ when 'footer' ; @footer = code
335
+ when 'comment'; add_stmt(codebuf, "\n" * code.count("\n"))
336
+ when 'value' ; add_expr_literal(codebuf, code)
337
+ else ; add_stmt(codebuf, code)
338
+ end
339
+ end
340
+
341
+ def add_pi_expr(codebuf, code, indicator) # :nodoc:
342
+ case indicator
343
+ when nil, '', '==' # @{...}@ or <%== ... %>
344
+ @escape == false ? add_expr_literal(codebuf, code) : add_expr_escaped(codebuf, code)
345
+ when '!', '=' # @!{...}@ or <%= ... %>
346
+ @escape == false ? add_expr_escaped(codebuf, code) : add_expr_literal(codebuf, code)
347
+ when '!!', '===' # @!!{...}@ or <%=== ... %>
348
+ add_expr_debug(codebuf, code)
349
+ else
350
+ # ignore
351
+ end
352
+ end
353
+
354
+ end
355
+
356
+
357
+ end