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,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