erubis 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (220) hide show
  1. data/CHANGES +120 -3
  2. data/README.txt +1 -1
  3. data/benchmark/Makefile +6 -0
  4. data/benchmark/bench.rb +306 -0
  5. data/benchmark/{erubybench.yaml → bench_context.yaml} +20 -20
  6. data/benchmark/templates/_footer.html +4 -0
  7. data/benchmark/{erubybench.rhtml → templates/_header.html} +1 -34
  8. data/benchmark/templates/bench_erb.rhtml +29 -0
  9. data/benchmark/templates/bench_erubis.rhtml +29 -0
  10. data/benchmark/templates/bench_eruby.rhtml +29 -0
  11. data/bin/erubis +2 -2
  12. data/contrib/erubis +3 -3114
  13. data/contrib/erubis-run.rb +132 -0
  14. data/contrib/inline-require +1 -1
  15. data/doc-api/classes/{ERB.html → ActionView/Base/ERB.html} +3 -3
  16. data/doc-api/classes/Erubis.html +8 -1
  17. data/doc-api/classes/Erubis/ArrayEnhancer.html +12 -12
  18. data/doc-api/classes/Erubis/Basic/Converter.html +24 -24
  19. data/doc-api/classes/Erubis/BiPatternEnhancer.html +14 -14
  20. data/doc-api/classes/Erubis/CGenerator.html +60 -60
  21. data/doc-api/classes/Erubis/Context.html +42 -42
  22. data/doc-api/classes/Erubis/Converter.html +27 -27
  23. data/doc-api/classes/Erubis/DeleteIndentEnhancer.html +150 -0
  24. data/doc-api/classes/Erubis/DeleteIndentEruby.html +120 -0
  25. data/doc-api/classes/Erubis/Engine.html +31 -31
  26. data/doc-api/classes/Erubis/ErboutEnhancer.html +175 -0
  27. data/doc-api/classes/Erubis/ErboutEruby.html +120 -0
  28. data/doc-api/classes/Erubis/Eruby.html +5 -0
  29. data/doc-api/classes/Erubis/EscapeEnhancer.html +6 -6
  30. data/doc-api/classes/Erubis/Evaluator.html +19 -19
  31. data/doc-api/classes/Erubis/FastEruby.html +131 -0
  32. data/doc-api/classes/Erubis/HeaderFooterEnhancer.html +14 -14
  33. data/doc-api/classes/Erubis/Helpers/RailsHelper.html +49 -45
  34. data/doc-api/classes/Erubis/InterpolationEnhancer.html +304 -0
  35. data/doc-api/classes/Erubis/InterpolationEruby.html +120 -0
  36. data/doc-api/classes/Erubis/JavaGenerator.html +54 -54
  37. data/doc-api/classes/Erubis/JavascriptGenerator.html +60 -60
  38. data/doc-api/classes/Erubis/Main.html +35 -27
  39. data/doc-api/classes/Erubis/NoCodeEnhancer.html +5 -5
  40. data/doc-api/classes/Erubis/NoTextEnhancer.html +7 -7
  41. data/doc-api/classes/Erubis/OptimizedEruby.html +6 -6
  42. data/doc-api/classes/Erubis/OptimizedGenerator.html +72 -72
  43. data/doc-api/classes/Erubis/OptimizedXmlEruby.html +6 -6
  44. data/doc-api/classes/Erubis/PI/Converter.html +18 -18
  45. data/doc-api/classes/Erubis/PI/Ec.html +6 -6
  46. data/doc-api/classes/Erubis/PI/Ejava.html +6 -6
  47. data/doc-api/classes/Erubis/PI/Ejavascript.html +6 -6
  48. data/doc-api/classes/Erubis/PI/Eperl.html +6 -6
  49. data/doc-api/classes/Erubis/PI/Ephp.html +6 -6
  50. data/doc-api/classes/Erubis/PI/Eruby.html +7 -7
  51. data/doc-api/classes/Erubis/PI/Escheme.html +6 -6
  52. data/doc-api/classes/Erubis/PI/TinyEruby.html +24 -24
  53. data/doc-api/classes/Erubis/PercentLineEnhancer.html +8 -8
  54. data/doc-api/classes/Erubis/PerlGenerator.html +54 -54
  55. data/doc-api/classes/Erubis/PhpGenerator.html +54 -54
  56. data/doc-api/classes/Erubis/PrintEnabledEnhancer.html +20 -20
  57. data/doc-api/classes/Erubis/PrintOutEnhancer.html +30 -30
  58. data/doc-api/classes/Erubis/RubyEvaluator.html +12 -12
  59. data/doc-api/classes/Erubis/RubyGenerator.html +48 -48
  60. data/doc-api/classes/Erubis/SchemeGenerator.html +60 -60
  61. data/doc-api/classes/Erubis/SimplifyEnhancer.html +8 -8
  62. data/doc-api/classes/Erubis/StdoutEnhancer.html +12 -12
  63. data/doc-api/classes/Erubis/StringBufferEnhancer.html +12 -12
  64. data/doc-api/classes/Erubis/TinyEruby.html +24 -24
  65. data/doc-api/classes/Erubis/XmlHelper.html +14 -14
  66. data/doc-api/created.rid +1 -1
  67. data/doc-api/files/README_txt.html +4 -4
  68. data/doc-api/files/erubis/context_rb.html +2 -2
  69. data/doc-api/files/erubis/converter_rb.html +2 -2
  70. data/doc-api/files/erubis/engine/ec_rb.html +2 -2
  71. data/doc-api/files/erubis/engine/ejava_rb.html +2 -2
  72. data/doc-api/files/erubis/engine/ejavascript_rb.html +2 -2
  73. data/doc-api/files/erubis/engine/enhanced_rb.html +2 -2
  74. data/doc-api/files/erubis/engine/eperl_rb.html +2 -2
  75. data/doc-api/files/erubis/engine/ephp_rb.html +2 -2
  76. data/doc-api/files/erubis/engine/eruby_rb.html +2 -2
  77. data/doc-api/files/erubis/engine/escheme_rb.html +2 -2
  78. data/doc-api/files/erubis/engine/optimized_rb.html +2 -2
  79. data/doc-api/files/erubis/engine_rb.html +2 -2
  80. data/doc-api/files/erubis/enhancer_rb.html +2 -2
  81. data/doc-api/files/erubis/error_rb.html +2 -2
  82. data/doc-api/files/erubis/evaluator_rb.html +2 -2
  83. data/doc-api/files/erubis/generator_rb.html +2 -2
  84. data/doc-api/files/erubis/helper_rb.html +2 -2
  85. data/doc-api/files/erubis/helpers/rails_helper_rb.html +2 -2
  86. data/doc-api/files/erubis/local-setting_rb.html +2 -2
  87. data/doc-api/files/erubis/main_rb.html +2 -2
  88. data/doc-api/files/erubis/tiny_rb.html +2 -2
  89. data/doc-api/files/erubis_rb.html +1 -1
  90. data/doc-api/fr_class_index.html +8 -1
  91. data/doc-api/fr_method_index.html +166 -158
  92. data/doc/users-guide.html +623 -215
  93. data/lib/erubis.rb +2 -2
  94. data/lib/erubis/context.rb +2 -2
  95. data/lib/erubis/converter.rb +2 -2
  96. data/lib/erubis/engine.rb +3 -3
  97. data/lib/erubis/engine/ec.rb +2 -2
  98. data/lib/erubis/engine/ejava.rb +2 -2
  99. data/lib/erubis/engine/ejavascript.rb +2 -2
  100. data/lib/erubis/engine/enhanced.rb +17 -2
  101. data/lib/erubis/engine/eperl.rb +2 -2
  102. data/lib/erubis/engine/ephp.rb +2 -2
  103. data/lib/erubis/engine/eruby.rb +10 -2
  104. data/lib/erubis/engine/escheme.rb +2 -2
  105. data/lib/erubis/engine/optimized.rb +2 -2
  106. data/lib/erubis/enhancer.rb +134 -25
  107. data/lib/erubis/error.rb +2 -2
  108. data/lib/erubis/evaluator.rb +2 -2
  109. data/lib/erubis/generator.rb +2 -2
  110. data/lib/erubis/helper.rb +2 -2
  111. data/lib/erubis/helpers/rails_helper.rb +19 -75
  112. data/lib/erubis/local-setting.rb +2 -2
  113. data/lib/erubis/main.rb +63 -36
  114. data/lib/erubis/tiny.rb +2 -2
  115. data/test/assert-text-equal.rb +2 -2
  116. data/test/data/users-guide/Example.ejava +55 -0
  117. data/test/data/users-guide/array_example.result +9 -0
  118. data/test/data/users-guide/arraybuffer_example.result +9 -0
  119. data/test/data/users-guide/bipattern-example.rhtml +4 -0
  120. data/test/data/users-guide/bipattern_example.result +6 -0
  121. data/test/data/users-guide/context.rb +6 -0
  122. data/test/data/users-guide/context.yaml +8 -0
  123. data/test/data/users-guide/escape_example.result +9 -0
  124. data/test/data/users-guide/example.ec +27 -0
  125. data/test/data/users-guide/example.ejs +20 -0
  126. data/test/data/users-guide/example.eperl +18 -0
  127. data/test/data/users-guide/example.ephp +18 -0
  128. data/test/data/users-guide/example.eruby +6 -0
  129. data/test/data/users-guide/example.escheme +28 -0
  130. data/test/data/users-guide/example1.eruby +6 -0
  131. data/test/data/users-guide/example1.rb +16 -0
  132. data/test/data/users-guide/example1.result +16 -0
  133. data/test/data/users-guide/example10.rb +4 -0
  134. data/test/data/users-guide/example10.result +17 -0
  135. data/test/data/users-guide/example10.xhtml +14 -0
  136. data/test/data/users-guide/example10_x.result +17 -0
  137. data/test/data/users-guide/example11.php +20 -0
  138. data/test/data/users-guide/example11.result +23 -0
  139. data/test/data/users-guide/example11.rhtml +21 -0
  140. data/test/data/users-guide/example11_C.result +10 -0
  141. data/test/data/users-guide/example11_N.result +16 -0
  142. data/test/data/users-guide/example11_U.result +16 -0
  143. data/test/data/users-guide/example11_php.result +15 -0
  144. data/test/data/users-guide/example1_x.result +9 -0
  145. data/test/data/users-guide/example2.eruby +7 -0
  146. data/test/data/users-guide/example2.rb +10 -0
  147. data/test/data/users-guide/example2.result +27 -0
  148. data/test/data/users-guide/example2_trim.result +10 -0
  149. data/test/data/users-guide/example2_x.result +10 -0
  150. data/test/data/users-guide/example3.eruby +6 -0
  151. data/test/data/users-guide/example3.rb +10 -0
  152. data/test/data/users-guide/example31.result +22 -0
  153. data/test/data/users-guide/example32.result +4 -0
  154. data/test/data/users-guide/example3_e.result +8 -0
  155. data/test/data/users-guide/example4.eruby +3 -0
  156. data/test/data/users-guide/example4.rb +11 -0
  157. data/test/data/users-guide/example4.result +10 -0
  158. data/test/data/users-guide/example4_x.result +5 -0
  159. data/test/data/users-guide/example5.eruby +6 -0
  160. data/test/data/users-guide/example5.rb +16 -0
  161. data/test/data/users-guide/example5.result +7 -0
  162. data/test/data/users-guide/example6.rb +12 -0
  163. data/test/data/users-guide/example6.result +7 -0
  164. data/test/data/users-guide/example7.eruby +8 -0
  165. data/test/data/users-guide/example71.result +13 -0
  166. data/test/data/users-guide/example72.result +13 -0
  167. data/test/data/users-guide/example8.eruby +6 -0
  168. data/test/data/users-guide/example8_ruby.result +7 -0
  169. data/test/data/users-guide/example8_yaml.result +7 -0
  170. data/test/data/users-guide/example9.eruby +3 -0
  171. data/test/data/users-guide/example9.rb +8 -0
  172. data/test/data/users-guide/example9.result +9 -0
  173. data/test/data/users-guide/example91.result +5 -0
  174. data/test/data/users-guide/example92.result +4 -0
  175. data/test/data/users-guide/example_c.result +29 -0
  176. data/test/data/users-guide/example_java.result +56 -0
  177. data/test/data/users-guide/example_js.result +22 -0
  178. data/test/data/users-guide/example_perl.result +20 -0
  179. data/test/data/users-guide/example_php.result +19 -0
  180. data/test/data/users-guide/example_scheme.result +30 -0
  181. data/test/data/users-guide/example_scheme_display.result +29 -0
  182. data/test/data/users-guide/fasteruby.rb +11 -0
  183. data/test/data/users-guide/fasteruby.result +38 -0
  184. data/test/data/users-guide/fasteruby.rhtml +15 -0
  185. data/test/data/users-guide/headerfooter-example.eruby +9 -0
  186. data/test/data/users-guide/headerfooter-example2.rb +8 -0
  187. data/test/data/users-guide/headerfooter-example2.rhtml +10 -0
  188. data/test/data/users-guide/headerfooter_example.result +11 -0
  189. data/test/data/users-guide/headerfooter_example2.result +13 -0
  190. data/test/data/users-guide/interpolation_example.result +9 -0
  191. data/test/data/users-guide/nocode-example.eruby +14 -0
  192. data/test/data/users-guide/nocode-php.result +20 -0
  193. data/test/data/users-guide/nocode_example.result +15 -0
  194. data/test/data/users-guide/normal-eruby-test.eruby +9 -0
  195. data/test/data/users-guide/normal_eruby_test.result +11 -0
  196. data/test/data/users-guide/notext-example.eruby +14 -0
  197. data/test/data/users-guide/notext-example.php +19 -0
  198. data/test/data/users-guide/notext-php.result +20 -0
  199. data/test/data/users-guide/notext_example.result +16 -0
  200. data/test/data/users-guide/percentline-example.rhtml +4 -0
  201. data/test/data/users-guide/percentline_example.result +7 -0
  202. data/test/data/users-guide/printenable_example.result +4 -0
  203. data/test/data/users-guide/printenabled-example.eruby +3 -0
  204. data/test/data/users-guide/printenabled-example.rb +8 -0
  205. data/test/data/users-guide/printstatement_example.result +8 -0
  206. data/test/data/users-guide/simplify_example.result +9 -0
  207. data/test/data/users-guide/stdout_exmple.result +9 -0
  208. data/test/data/users-guide/stringbuffer_example.result +9 -0
  209. data/test/test-engines.rb +2 -2
  210. data/test/test-enhancers.rb +569 -0
  211. data/test/test-erubis.rb +3 -380
  212. data/test/test-main.rb +39 -15
  213. data/test/test-users-guide.rb +56 -0
  214. data/test/test.rb +4 -3
  215. data/test/testutil.rb +2 -2
  216. metadata +166 -57
  217. data/benchmark/erubybench-lib.rb +0 -189
  218. data/benchmark/erubybench.rb +0 -600
  219. data/bin/notext +0 -154
  220. data/test/test-notext.rb +0 -27
@@ -2,140 +2,140 @@ list:
2
2
  - name: Adobe Systems
3
3
  name2: Adobe Systems Inc.
4
4
  url: http://www.adobe.com
5
- code: ADBE
5
+ symbol: ADBE
6
6
  price: 39.26
7
7
  change: 0.13
8
8
  ratio: 0.33
9
9
  - name: Advanced Micro Devices
10
10
  name2: Advanced Micro Devices Inc.
11
11
  url: http://www.amd.com
12
- code: AMD
12
+ symbol: AMD
13
13
  price: 16.22
14
14
  change: 0.17
15
15
  ratio: 1.06
16
16
  - name: Amazon.com
17
17
  name2: Amazon.com Inc
18
18
  url: http://www.amazon.com
19
- code: AMZN
19
+ symbol: AMZN
20
20
  price: 36.85
21
21
  change: -0.23
22
22
  ratio: -0.62
23
23
  - name: Apple
24
24
  name2: Apple Inc.
25
25
  url: http://www.apple.com
26
- code: AAPL
26
+ symbol: AAPL
27
27
  price: 85.38
28
28
  change: -0.87
29
29
  ratio: -1.01
30
30
  - name: BEA Systems
31
31
  name2: BEA Systems Inc.
32
32
  url: http://www.bea.com
33
- code: BEAS
33
+ symbol: BEAS
34
34
  price: 12.46
35
35
  change: 0.09
36
36
  ratio: 0.73
37
37
  - name: CA
38
38
  name2: CA, Inc.
39
39
  url: http://www.ca.com
40
- code: CA
40
+ symbol: CA
41
41
  price: 24.66
42
42
  change: 0.38
43
43
  ratio: 1.57
44
44
  - name: Cisco Systems
45
45
  name2: Cisco Systems Inc.
46
46
  url: http://www.cisco.com
47
- code: CSCO
47
+ symbol: CSCO
48
48
  price: 26.35
49
49
  change: 0.13
50
50
  ratio: 0.5
51
51
  - name: Dell
52
52
  name2: Dell Corp.
53
53
  url: http://www.dell.com/
54
- code: DELL
54
+ symbol: DELL
55
55
  price: 23.73
56
56
  change: -0.42
57
57
  ratio: -1.74
58
58
  - name: eBay
59
59
  name2: eBay Inc.
60
60
  url: http://www.ebay.com
61
- code: EBAY
61
+ symbol: EBAY
62
62
  price: 31.65
63
63
  change: -0.8
64
64
  ratio: -2.47
65
65
  - name: Google
66
66
  name2: Google Inc.
67
67
  url: http://www.google.com
68
- code: GOOG
68
+ symbol: GOOG
69
69
  price: 495.84
70
70
  change: 7.75
71
71
  ratio: 1.59
72
72
  - name: Hewlett-Packard
73
73
  name2: Hewlett-Packard Co.
74
74
  url: http://www.hp.com
75
- code: HPQ
75
+ symbol: HPQ
76
76
  price: 41.69
77
77
  change: -0.02
78
78
  ratio: -0.05
79
79
  - name: IBM
80
80
  name2: International Business Machines Corp.
81
81
  url: http://www.ibm.com
82
- code: IBM
82
+ symbol: IBM
83
83
  price: 97.45
84
84
  change: -0.06
85
85
  ratio: -0.06
86
86
  - name: Intel
87
87
  name2: Intel Corp.
88
88
  url: http://www.intel.com
89
- code: INTC
89
+ symbol: INTC
90
90
  price: 20.53
91
91
  change: -0.07
92
92
  ratio: -0.34
93
93
  - name: Juniper Networks
94
94
  name2: Juniper Networks, Inc
95
95
  url: http://www.juniper.net/
96
- code: JNPR
96
+ symbol: JNPR
97
97
  price: 18.96
98
98
  change: 0.5
99
99
  ratio: 2.71
100
100
  - name: Microsoft
101
101
  name2: Microsoft Corp
102
102
  url: http://www.microsoft.com
103
- code: MSFT
103
+ symbol: MSFT
104
104
  price: 30.6
105
105
  change: 0.15
106
106
  ratio: 0.49
107
107
  - name: Oracle
108
108
  name2: Oracle Corp.
109
109
  url: http://www.oracle.com
110
- code: ORCL
110
+ symbol: ORCL
111
111
  price: 17.15
112
112
  change: 0.17
113
113
  ratio: 1.0
114
114
  - name: SAP
115
115
  name2: SAP AG
116
116
  url: http://www.sap.com
117
- code: SAP
117
+ symbol: SAP
118
118
  price: 46.2
119
119
  change: -0.16
120
120
  ratio: -0.35
121
121
  - name: Seagate Technology
122
122
  name2: Seagate Technology
123
123
  url: http://www.seagate.com/
124
- code: STX
124
+ symbol: STX
125
125
  price: 27.35
126
126
  change: -0.36
127
127
  ratio: -1.3
128
128
  - name: Sun Microsystems
129
129
  name2: Sun Microsystems Inc.
130
130
  url: http://www.sun.com
131
- code: SUNW
131
+ symbol: SUNW
132
132
  price: 6.33
133
133
  change: -0.01
134
134
  ratio: -0.16
135
135
  - name: Yahoo
136
136
  name2: Yahoo! Inc.
137
137
  url: http://www.yahoo.com
138
- code: YHOO
138
+ symbol: YHOO
139
139
  price: 28.04
140
140
  change: -0.17
141
141
  ratio: -0.6
@@ -0,0 +1,4 @@
1
+ </table>
2
+
3
+ </body>
4
+ </html>
@@ -47,39 +47,6 @@ thead {
47
47
  <table>
48
48
  <thead>
49
49
  <tr>
50
- <th>#</th><th>code</th><th>name</th><th>price</th><th>change</th><th>ratio</th>
50
+ <th>#</th><th>symbol</th><th>name</th><th>price</th><th>change</th><th>ratio</th>
51
51
  </tr>
52
52
  </thead>
53
- <tbody>
54
- <%
55
- n = 0
56
- for item in list
57
- n += 1
58
- %>
59
- <tr class="<%= n % 2 == 0 ? 'even' : 'odd' %>">
60
- <td style="text-align: center"><%= n %></td>
61
- <td>
62
- <a href="/stocks/<%= item['code'] %>"><%= item['code'] %></a>
63
- </td>
64
- <td>
65
- <a href="<%= item['url'] %>"><%= item['name'] %></a>
66
- </td>
67
- <td>
68
- <strong><%= item['price'] %></strong>
69
- </td>
70
- <% if item['change'] < 0.0 %>
71
- <td class="minus"><%= item['change'] %></td>
72
- <td class="minus"><%= item['ratio'] %></td>
73
- <% else %>
74
- <td><%= item['change'] %></td>
75
- <td><%= item['ratio'] %></td>
76
- <% end %>
77
- </tr>
78
- <%
79
- end
80
- %>
81
- </tbody>
82
- </table>
83
-
84
- </body>
85
- </html>
@@ -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>
data/bin/erubis CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  ###
4
- ### $Rev: 10 $
5
- ### $Release: 2.2.0 $
4
+ ### $Rev: 77 $
5
+ ### $Release: 2.3.0 $
6
6
  ### copyright(c) 2006-2007 kuwata-lab all rights reserved.
7
7
  ###
8
8
 
@@ -1,3122 +1,11 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  ###
4
- ### $Rev: 10 $
5
- ### $Release: 2.2.0 $
4
+ ### $Rev: 77 $
5
+ ### $Release: 2.3.0 $
6
6
  ### copyright(c) 2006-2007 kuwata-lab all rights reserved.
7
7
  ###
8
8
 
9
- #--begin of require 'erubis/main'
10
- ###
11
- ### $Rev: 65 $
12
- ### $Release: 2.2.0 $
13
- ### copyright(c) 2006-2007 kuwata-lab all rights reserved.
14
- ###
15
-
16
- require 'yaml'
17
- #--begin of require 'erubis'
18
- ##
19
- ## $Rev: 59 $
20
- ## $Release: 2.2.0 $
21
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
22
- ##
23
-
24
- ##
25
- ## an implementation of eRuby
26
- ##
27
- ## ex.
28
- ## input = <<'END'
29
- ## <ul>
30
- ## <% for item in @list %>
31
- ## <li><%= item %>
32
- ## <%== item %></li>
33
- ## <% end %>
34
- ## </ul>
35
- ## END
36
- ## list = ['<aaa>', 'b&b', '"ccc"']
37
- ## eruby = Erubis::Eruby.new(input)
38
- ## puts "--- code ---"
39
- ## puts eruby.src
40
- ## puts "--- result ---"
41
- ## context = Erubis::Context.new() # or new(:list=>list)
42
- ## context[:list] = list
43
- ## puts eruby.evaluate(context)
44
- ##
45
- ## result:
46
- ## --- source ---
47
- ## _buf = ''; _buf << '<ul>
48
- ## '; for item in @list
49
- ## _buf << ' <li>'; _buf << ( item ).to_s; _buf << '
50
- ## '; _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</li>
51
- ## '; end
52
- ## _buf << '</ul>
53
- ## ';
54
- ## _buf.to_s
55
- ## --- result ---
56
- ## <ul>
57
- ## <li><aaa>
58
- ## &lt;aaa&gt;</li>
59
- ## <li>b&b
60
- ## b&amp;b</li>
61
- ## <li>"ccc"
62
- ## &quot;ccc&quot;</li>
63
- ## </ul>
64
- ##
65
-
66
-
67
- module Erubis
68
- VERSION = ('$Release: 2.2.0 $' =~ /([.\d]+)/) && $1
69
- end
70
-
71
- #--begin of require 'erubis/engine'
72
- ##
73
- ## $Rev: 55 $
74
- ## $Release: 2.2.0 $
75
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
76
- ##
77
-
78
-
79
- #--begin of require 'erubis/generator'
80
- ##
81
- ## $Rev: 42 $
82
- ## $Release: 2.2.0 $
83
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
84
- ##
85
-
86
- #--begin of require 'abstract'
87
- ##
88
- ## $Rev: 1 $
89
- ## $Release: 0.1.0 $
90
- ## copyright(c) 2006 kuwata-lab.com all rights reserved.
91
- ##
92
- ##
93
- ## helper to define abstract method in Ruby.
94
- ##
95
- ##
96
- ## example1. (shorter notation)
97
- ##
98
- ## require 'abstract'
99
- ## class Foo
100
- ## abstract_method 'arg1, arg2=""', :method1, :method2, :method3
101
- ## end
102
- ##
103
- ##
104
- ## example2. (RDoc friendly notation)
105
- ##
106
- ## require 'abstract'
107
- ## class Bar
108
- ## # ... method1 description ...
109
- ## def method1(arg1, arg2="")
110
- ## not_implemented
111
- ## end
112
- ##
113
- ## # ... method2 description ...
114
- ## def method2(arg1, arg2="")
115
- ## not_implemented
116
- ## end
117
- ## end
118
- ##
119
-
120
-
121
- ##
122
- class Module
123
-
124
- ##
125
- ## define abstract methods
126
- ##
127
- def abstract_method args_str, *method_names
128
- method_names.each do |name|
129
- module_eval <<-END
130
- def #{name}(#{args_str})
131
- mesg = "class \#{self.class.name} must implement abstract method `#{self.name}##{name}()'."
132
- #mesg = "\#{self.class.name}##{name}() is not implemented."
133
- err = NotImplementedError.new mesg
134
- err.set_backtrace caller()
135
- raise err
136
- end
137
- END
138
- end
139
- end
140
-
141
- end
142
-
143
-
144
- ##
145
- module Kernel
146
-
147
- ##
148
- ## raise NotImplementedError
149
- ##
150
- def not_implemented #:doc:
151
- backtrace = caller()
152
- method_name = (backtrace.shift =~ /`(\w+)'$/) && $1
153
- mesg = "class #{self.class.name} must implement abstract method '#{method_name}()'."
154
- #mesg = "#{self.class.name}##{method_name}() is not implemented."
155
- err = NotImplementedError.new mesg
156
- err.set_backtrace backtrace
157
- raise err
158
- end
159
- private :not_implemented
160
-
161
- end
162
- #--end of require 'abstract'
163
-
164
- module Erubis
165
-
166
-
167
- ##
168
- ## code generator, called by Converter module
169
- ##
170
- module Generator
171
-
172
- def self.supported_properties() # :nodoc:
173
- return [
174
- [:escapefunc, nil, "escape function name"],
175
- ]
176
- end
177
-
178
- attr_accessor :escapefunc
179
-
180
- def init_generator(properties={})
181
- @escapefunc = properties[:escapefunc]
182
- end
183
-
184
-
185
- ## (abstract) escape text string
186
- ##
187
- ## ex.
188
- ## def escape_text(text)
189
- ## return text.dump
190
- ## # or return "'" + text.gsub(/['\\]/, '\\\\\&') + "'"
191
- ## end
192
- def escape_text(text)
193
- not_implemented
194
- end
195
-
196
- ## return escaped expression code (ex. 'h(...)' or 'htmlspecialchars(...)')
197
- def escaped_expr(code)
198
- code.strip!
199
- return "#{@escapefunc}(#{code})"
200
- end
201
-
202
- ## (abstract) add @preamble to src
203
- def add_preamble(src)
204
- not_implemented
205
- end
206
-
207
- ## (abstract) add text string to src
208
- def add_text(src, text)
209
- not_implemented
210
- end
211
-
212
- ## (abstract) add statement code to src
213
- def add_stmt(src, code)
214
- not_implemented
215
- end
216
-
217
- ## (abstract) add expression literal code to src. this is called by add_expr().
218
- def add_expr_literal(src, code)
219
- not_implemented
220
- end
221
-
222
- ## (abstract) add escaped expression code to src. this is called by add_expr().
223
- def add_expr_escaped(src, code)
224
- not_implemented
225
- end
226
-
227
- ## (abstract) add expression code to src for debug. this is called by add_expr().
228
- def add_expr_debug(src, code)
229
- not_implemented
230
- end
231
-
232
- ## (abstract) add @postamble to src
233
- def add_postamble(src)
234
- not_implemented
235
- end
236
-
237
-
238
- end
239
-
240
-
241
- end
242
- #--end of require 'erubis/generator'
243
- #--begin of require 'erubis/converter'
244
- ##
245
- ## $Rev: 60 $
246
- ## $Release: 2.2.0 $
247
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
248
- ##
249
-
250
- #--already included require 'abstract'
251
-
252
- module Erubis
253
-
254
-
255
- ##
256
- ## convert
257
- ##
258
- module Converter
259
-
260
- attr_accessor :preamble, :postamble, :escape
261
-
262
- def self.supported_properties # :nodoc:
263
- return [
264
- [:preamble, nil, "preamble (no preamble when false)"],
265
- [:postamble, nil, "postamble (no postamble when false)"],
266
- [:escape, nil, "escape expression or not in default"],
267
- ]
268
- end
269
-
270
- def init_converter(properties={})
271
- @preamble = properties[:preamble]
272
- @postamble = properties[:postamble]
273
- @escape = properties[:escape]
274
- end
275
-
276
- ## convert input string into target language
277
- def convert(input)
278
- codebuf = "" # or []
279
- @preamble.nil? ? add_preamble(codebuf) : (@preamble && (codebuf << @preamble))
280
- convert_input(codebuf, input)
281
- @postamble.nil? ? add_postamble(codebuf) : (@postamble && (codebuf << @postamble))
282
- return codebuf # or codebuf.join()
283
- end
284
-
285
- protected
286
-
287
- ##
288
- ## detect spaces at beginning of line
289
- ##
290
- def detect_spaces_at_bol(text, is_bol)
291
- lspace = nil
292
- if text.empty?
293
- lspace = "" if is_bol
294
- elsif text[-1] == ?\n
295
- lspace = ""
296
- else
297
- rindex = text.rindex(?\n)
298
- if rindex
299
- s = text[rindex+1..-1]
300
- if s =~ /\A[ \t]*\z/
301
- lspace = s
302
- #text = text[0..rindex]
303
- text[rindex+1..-1] = ''
304
- end
305
- else
306
- if is_bol && text =~ /\A[ \t]*\z/
307
- #lspace = text
308
- #text = nil
309
- lspace = text.dup
310
- text[0..-1] = ''
311
- end
312
- end
313
- end
314
- return lspace
315
- end
316
-
317
- ##
318
- ## (abstract) convert input to code
319
- ##
320
- def convert_input(codebuf, input)
321
- not_implemented
322
- end
323
-
324
- end
325
-
326
-
327
- module Basic
328
- end
329
-
330
-
331
- ##
332
- ## basic converter which supports '<% ... %>' notation.
333
- ##
334
- module Basic::Converter
335
- include Erubis::Converter
336
-
337
- def self.supported_properties # :nodoc:
338
- return [
339
- [:pattern, '<% %>', "embed pattern"],
340
- [:trim, true, "trim spaces around <% ... %>"],
341
- ]
342
- end
343
-
344
- attr_accessor :pattern, :trim
345
-
346
- def init_converter(properties={})
347
- super(properties)
348
- @pattern = properties[:pattern]
349
- @trim = properties[:trim] != false
350
- end
351
-
352
- protected
353
-
354
- ## return regexp of pattern to parse eRuby script
355
- def pattern_regexp(pattern)
356
- prefix, postfix = pattern.split() # '<% %>' => '<%', '%>'
357
- #return /(.*?)(^[ \t]*)?#{prefix}(=+|\#)?(.*?)-?#{postfix}([ \t]*\r?\n)?/m
358
- #return /(^[ \t]*)?#{prefix}(=+|\#)?(.*?)-?#{postfix}([ \t]*\r?\n)?/m
359
- return /#{prefix}(=+|-|\#)?(.*?)-?#{postfix}([ \t]*\r?\n)?/m
360
- end
361
- module_function :pattern_regexp
362
-
363
- #DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
364
- #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
365
- #DEFAULT_REGEXP = /<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
366
- DEFAULT_REGEXP = pattern_regexp('<% %>')
367
-
368
- public
369
-
370
- def convert_input(src, input)
371
- pat = @pattern
372
- regexp = pat.nil? || pat == '<% %>' ? DEFAULT_REGEXP : pattern_regexp(pat)
373
- pos = 0
374
- is_bol = true # is beginning of line
375
- input.scan(regexp) do |indicator, code, rspace|
376
- match = Regexp.last_match()
377
- len = match.begin(0) - pos
378
- text = input[pos, len]
379
- pos = match.end(0)
380
- ch = indicator ? indicator[0] : nil
381
- lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
382
- is_bol = rspace ? true : false
383
- add_text(src, text) if text && !text.empty?
384
- ## * when '<%= %>', do nothing
385
- ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
386
- if ch == ?= # <%= %>
387
- add_text(src, lspace) if lspace
388
- add_expr(src, code, indicator)
389
- add_text(src, rspace) if rspace
390
- elsif ch == ?\# # <%# %>
391
- n = code.count("\n") + (rspace ? 1 : 0)
392
- if @trim && lspace && rspace
393
- add_stmt(src, "\n" * n)
394
- else
395
- add_text(src, lspace) if lspace
396
- add_stmt(src, "\n" * n)
397
- add_text(src, rspace) if rspace
398
- end
399
- else # <% %>
400
- if @trim && lspace && rspace
401
- add_stmt(src, "#{lspace}#{code}#{rspace}")
402
- else
403
- add_text(src, lspace) if lspace
404
- add_stmt(src, code)
405
- add_text(src, rspace) if rspace
406
- end
407
- end
408
- end
409
- rest = $' || input # add input when no matched
410
- add_text(src, rest)
411
- end
412
-
413
- ## add expression code to src
414
- def add_expr(src, code, indicator)
415
- case indicator
416
- when '='
417
- @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
418
- when '=='
419
- @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
420
- when '==='
421
- add_expr_debug(src, code)
422
- end
423
- end
424
-
425
- end
426
-
427
-
428
- module PI
429
- end
430
-
431
- ##
432
- ## Processing Instructions (PI) converter for XML.
433
- ## this class converts '<?rb ... ?>' and '${...}' notation.
434
- ##
435
- module PI::Converter
436
- include Erubis::Converter
437
-
438
- def self.desc # :nodoc:
439
- "use processing instructions (PI) instead of '<% %>'"
440
- end
441
-
442
- def self.supported_properties # :nodoc:
443
- return [
444
- [:trim, true, "trim spaces around <% ... %>"],
445
- [:pi, 'rb', "PI (Processing Instrunctions) name"],
446
- [:embchar, '@', "char for embedded expression pattern('@{...}@')"],
447
- [:pattern, '<% %>', "embed pattern"],
448
- ]
449
- end
450
-
451
- attr_accessor :pi, :prefix
452
-
453
- def init_converter(properties={})
454
- super(properties)
455
- @trim = properties.fetch(:trim, true)
456
- @pi = properties[:pi] if properties[:pi]
457
- @embchar = properties[:embchar] || '@'
458
- @pattern = properties[:pattern]
459
- @pattern = '<% %>' if @pattern.nil? #|| @pattern == true
460
- end
461
-
462
- def convert(input)
463
- code = super(input)
464
- return @header || @footer ? "#{@header}#{code}#{@footer}" : code
465
- end
466
-
467
- protected
468
-
469
- def convert_input(codebuf, input)
470
- unless @regexp
471
- @pi ||= 'e'
472
- ch = Regexp.escape(@embchar)
473
- if @pattern
474
- left, right = @pattern.split(' ')
475
- @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/m
476
- else
477
- @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}/m
478
- end
479
- end
480
- #
481
- is_bol = true
482
- pos = 0
483
- input.scan(@regexp) do |pi_arg, stmt, rspace,
484
- indicator1, expr1, indicator2, expr2|
485
- match = Regexp.last_match
486
- len = match.begin(0) - pos
487
- text = input[pos, len]
488
- pos = match.end(0)
489
- lspace = stmt ? detect_spaces_at_bol(text, is_bol) : nil
490
- is_bol = stmt && rspace ? true : false
491
- add_text(codebuf, text) # unless text.empty?
492
- #
493
- if stmt
494
- if @trim && lspace && rspace
495
- add_pi_stmt(codebuf, "#{lspace}#{stmt}#{rspace}", pi_arg)
496
- else
497
- add_text(codebuf, lspace) if lspace
498
- add_pi_stmt(codebuf, stmt, pi_arg)
499
- add_text(codebuf, rspace) if rspace
500
- end
501
- else
502
- add_pi_expr(codebuf, expr1 || expr2, indicator1 || indicator2)
503
- end
504
- end
505
- rest = $' || input
506
- add_text(codebuf, rest)
507
- end
508
-
509
- #--
510
- #def convert_input(codebuf, input)
511
- # parse_stmts(codebuf, input)
512
- # #parse_stmts2(codebuf, input)
513
- #end
514
- #
515
- #def parse_stmts(codebuf, input)
516
- # #regexp = pattern_regexp(@pattern)
517
- # @pi ||= 'e'
518
- # @stmt_pattern ||= /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?/m
519
- # is_bol = true
520
- # pos = 0
521
- # input.scan(@stmt_pattern) do |pi_arg, code, rspace|
522
- # match = Regexp.last_match
523
- # len = match.begin(0) - pos
524
- # text = input[pos, len]
525
- # pos = match.end(0)
526
- # lspace = detect_spaces_at_bol(text, is_bol)
527
- # is_bol = rspace ? true : false
528
- # parse_exprs(codebuf, text) # unless text.empty?
529
- # if @trim && lspace && rspace
530
- # add_pi_stmt(codebuf, "#{lspace}#{code}#{rspace}", pi_arg)
531
- # else
532
- # add_text(codebuf, lspace)
533
- # add_pi_stmt(codebuf, code, pi_arg)
534
- # add_text(codebuf, rspace)
535
- # end
536
- # end
537
- # rest = $' || input
538
- # parse_exprs(codebuf, rest)
539
- #end
540
- #
541
- #def parse_exprs(codebuf, input)
542
- # unless @expr_pattern
543
- # ch = Regexp.escape(@embchar)
544
- # if @pattern
545
- # left, right = @pattern.split(' ')
546
- # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/
547
- # else
548
- # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}/
549
- # end
550
- # end
551
- # pos = 0
552
- # input.scan(@expr_pattern) do |indicator1, code1, indicator2, code2|
553
- # indicator = indicator1 || indicator2
554
- # code = code1 || code2
555
- # match = Regexp.last_match
556
- # len = match.begin(0) - pos
557
- # text = input[pos, len]
558
- # pos = match.end(0)
559
- # add_text(codebuf, text) # unless text.empty?
560
- # add_pi_expr(codebuf, code, indicator)
561
- # end
562
- # rest = $' || input
563
- # add_text(codebuf, rest)
564
- #end
565
- #++
566
-
567
- def add_pi_stmt(codebuf, code, pi_arg) # :nodoc:
568
- case pi_arg
569
- when nil ; add_stmt(codebuf, code)
570
- when 'header' ; @header = code
571
- when 'footer' ; @footer = code
572
- when 'comment'; add_stmt(codebuf, "\n" * code.count("\n"))
573
- when 'value' ; add_expr_literal(codebuf, code)
574
- else ; add_stmt(codebuf, code)
575
- end
576
- end
577
-
578
- def add_pi_expr(codebuf, code, indicator) # :nodoc:
579
- case indicator
580
- when nil, '', '==' # @{...}@ or <%== ... %>
581
- @escape == false ? add_expr_literal(codebuf, code) : add_expr_escaped(codebuf, code)
582
- when '!', '=' # @!{...}@ or <%= ... %>
583
- @escape == false ? add_expr_escaped(codebuf, code) : add_expr_literal(codebuf, code)
584
- when '!!', '===' # @!!{...}@ or <%=== ... %>
585
- add_expr_debug(codebuf, code)
586
- else
587
- # ignore
588
- end
589
- end
590
-
591
- end
592
-
593
-
594
- end
595
- #--end of require 'erubis/converter'
596
- #--begin of require 'erubis/evaluator'
597
- ##
598
- ## $Rev: 32 $
599
- ## $Release: 2.2.0 $
600
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
601
- ##
602
-
603
- #--begin of require 'erubis/error'
604
- ##
605
- ## $Rev: 32 $
606
- ## $Release: 2.2.0 $
607
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
608
- ##
609
-
610
- module Erubis
611
-
612
-
613
- ##
614
- ## base error class
615
- ##
616
- class ErubisError < StandardError
617
- end
618
-
619
-
620
- ##
621
- ## raised when method or function is not supported
622
- ##
623
- class NotSupportedError < ErubisError
624
- end
625
-
626
-
627
- end
628
- #--end of require 'erubis/error'
629
- #--begin of require 'erubis/context'
630
- ##
631
- ## $Rev: 59 $
632
- ## $Release: 2.2.0 $
633
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
634
- ##
635
-
636
-
637
- module Erubis
638
-
639
-
640
- ##
641
- ## context object for Engine#evaluate
642
- ##
643
- ## ex.
644
- ## template = <<'END'
645
- ## Hello <%= @user %>!
646
- ## <% for item in @list %>
647
- ## - <%= item %>
648
- ## <% end %>
649
- ## END
650
- ##
651
- ## context = Erubis::Context.new(:user=>'World', :list=>['a','b','c'])
652
- ## # or
653
- ## # context = Erubis::Context.new
654
- ## # context[:user] = 'World'
655
- ## # context[:list] = ['a', 'b', 'c']
656
- ##
657
- ## eruby = Erubis::Eruby.new(template)
658
- ## print eruby.evaluate(context)
659
- ##
660
- class Context
661
- include Enumerable
662
-
663
- def initialize(hash=nil)
664
- hash.each do |name, value|
665
- self[name] = value
666
- end if hash
667
- end
668
-
669
- def [](key)
670
- return instance_variable_get("@#{key}")
671
- end
672
-
673
- def []=(key, value)
674
- return instance_variable_set("@#{key}", value)
675
- end
676
-
677
- def keys
678
- return instance_variables.collect { |name| name[1..-1] }
679
- end
680
-
681
- def each
682
- instance_variables.each do |name|
683
- key = name[1..-1]
684
- value = instance_variable_get(name)
685
- yield(key, value)
686
- end
687
- end
688
-
689
- def to_hash
690
- hash = {}
691
- self.keys.each { |key| hash[key] = self[key] }
692
- return hash
693
- end
694
-
695
- def update(context_or_hash)
696
- arg = context_or_hash
697
- if arg.is_a?(Hash)
698
- arg.each do |key, val|
699
- self[key] = val
700
- end
701
- else
702
- arg.instance_variables.each do |varname|
703
- key = varname[1..-1]
704
- val = arg.instance_variable_get(varname)
705
- self[key] = val
706
- end
707
- end
708
- end
709
-
710
- end
711
-
712
-
713
- end
714
- #--end of require 'erubis/context'
715
-
716
-
717
- module Erubis
718
-
719
-
720
- ##
721
- ## evaluate code
722
- ##
723
- module Evaluator
724
-
725
- def self.supported_properties # :nodoc:
726
- return []
727
- end
728
-
729
- attr_accessor :src, :filename
730
-
731
- def init_evaluator(properties)
732
- @filename = properties[:filename]
733
- end
734
-
735
- def result(*args)
736
- raise NotSupportedError.new("evaluation of code except Ruby is not supported.")
737
- end
738
-
739
- def evaluate(*args)
740
- raise NotSupportedError.new("evaluation of code except Ruby is not supported.")
741
- end
742
-
743
- end
744
-
745
-
746
- ##
747
- ## evaluator for Ruby
748
- ##
749
- module RubyEvaluator
750
- include Evaluator
751
-
752
- def self.supported_properties # :nodoc:
753
- list = Evaluator.supported_properties
754
- return list
755
- end
756
-
757
- ## eval(@src) with binding object
758
- def result(_binding_or_hash=TOPLEVEL_BINDING)
759
- _arg = _binding_or_hash
760
- if _arg.is_a?(Hash)
761
- ## load _context data as local variables by eval
762
- eval _arg.keys.inject("") { |s, k| s << "#{k.to_s} = _arg[#{k.inspect}];" }
763
- _arg = binding()
764
- end
765
- return eval(@src, _arg, (@filename || '(erubis)'))
766
- end
767
-
768
- ## invoke context.instance_eval(@src)
769
- def evaluate(context=Context.new)
770
- context = Context.new(context) if context.is_a?(Hash)
771
- return context.instance_eval(@src, (@filename || '(erubis)'))
772
- end
773
-
774
- end
775
-
776
-
777
- end
778
- #--end of require 'erubis/evaluator'
779
- #--already included require 'erubis/context'
780
-
781
-
782
- module Erubis
783
-
784
-
785
- ##
786
- ## (abstract) abstract engine class.
787
- ## subclass must include evaluator and converter module.
788
- ##
789
- class Engine
790
- #include Evaluator
791
- #include Converter
792
- #include Generator
793
-
794
- def initialize(input=nil, properties={})
795
- #@input = input
796
- init_generator(properties)
797
- init_converter(properties)
798
- init_evaluator(properties)
799
- @src = convert(input) if input
800
- end
801
-
802
-
803
- ##
804
- ## convert input string and set it to @src
805
- ##
806
- def convert!(input)
807
- @src = convert(input)
808
- end
809
-
810
-
811
- ##
812
- ## load file, write cache file, and return engine object.
813
- ## this method create cache file (filename + '.cache') automatically.
814
- ##
815
- def self.load_file(filename, properties={})
816
- cachename = filename + '.cache'
817
- properties[:filename] = filename
818
- if test(?f, cachename) && File.mtime(filename) <= File.mtime(cachename)
819
- engine = self.new(nil, properties)
820
- engine.src = File.read(cachename)
821
- else
822
- input = File.open(filename, 'rb') { |f| f.read }
823
- engine = self.new(input, properties)
824
- File.open(cachename, 'w') do |f|
825
- f.flock(File::LOCK_EX)
826
- f.write(engine.src)
827
- end
828
- end
829
- engine.src.untaint # ok?
830
- return engine
831
- end
832
-
833
-
834
- ##
835
- ## helper method to convert and evaluate input text with context object.
836
- ## context may be Binding, Hash, or Object.
837
- ##
838
- def process(input, context=nil, filename=nil)
839
- code = convert(input)
840
- filename ||= '(erubis)'
841
- if context.is_a?(Binding)
842
- return eval(code, context, filename)
843
- else
844
- context = Context.new(context) if context.is_a?(Hash)
845
- return context.instance_eval(code, filename)
846
- end
847
- end
848
-
849
-
850
- ##
851
- ## helper method evaluate Proc object iwth contect object.
852
- ## context may be Binding, Hash, or Object.
853
- ##
854
- def process_proc(proc_obj, context=nil, filename=nil)
855
- if context.is_a?(Binding)
856
- filename ||= '(erubis)'
857
- return eval(proc_obj, context, filename)
858
- else
859
- context = Context.new(context) if context.is_a?(Hash)
860
- return context.instance_eval(&proc_obj)
861
- end
862
- end
863
-
864
-
865
- end # end of class Engine
866
-
867
-
868
- ##
869
- ## (abstract) base engine class for Eruby, Eperl, Ejava, and so on.
870
- ## subclass must include generator.
871
- ##
872
- class Basic::Engine < Engine
873
- include Evaluator
874
- include Basic::Converter
875
- include Generator
876
- end
877
-
878
-
879
- class PI::Engine < Engine
880
- include Evaluator
881
- include PI::Converter
882
- include Generator
883
- end
884
-
885
-
886
- end
887
- #--end of require 'erubis/engine'
888
- #require 'erubis/generator'
889
- #require 'erubis/converter'
890
- #require 'erubis/evaluator'
891
- #require 'erubis/error'
892
- #require 'erubis/context'
893
- #--begin of require 'erubis/helper'
894
- ##
895
- ## $Rev: 64 $
896
- ## $Release: 2.2.0 $
897
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
898
- ##
899
-
900
-
901
- module Erubis
902
-
903
- ##
904
- ## helper for xml
905
- ##
906
- module XmlHelper
907
-
908
- module_function
909
-
910
- ESCAPE_TABLE = {
911
- '&' => '&amp;',
912
- '<' => '&lt;',
913
- '>' => '&gt;',
914
- '"' => '&quot;',
915
- "'" => '&#039;',
916
- }
917
-
918
- def escape_xml(value)
919
- value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] } # or /[&<>"']/
920
- #value.to_s.gsub(/[&<>"]/) { ESCAPE_TABLE[$&] }
921
- end
922
-
923
- alias h escape_xml
924
- alias html_escape escape_xml
925
-
926
- end
927
-
928
-
929
- end
930
- #--end of require 'erubis/helper'
931
- #--begin of require 'erubis/enhancer'
932
- ##
933
- ## $Rev: 60 $
934
- ## $Release: 2.2.0 $
935
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
936
- ##
937
-
938
-
939
- module Erubis
940
-
941
-
942
- ##
943
- ## switch '<%= ... %>' to escaped and '<%== ... %>' to unescaped
944
- ##
945
- ## ex.
946
- ## class XmlEruby < Eruby
947
- ## include EscapeEnhancer
948
- ## end
949
- ##
950
- ## this is language-indenedent.
951
- ##
952
- module EscapeEnhancer
953
-
954
- def self.desc # :nodoc:
955
- "switch '<%= %>' to escaped and '<%== %>' to unescaped"
956
- end
957
-
958
- #--
959
- #def self.included(klass)
960
- # klass.class_eval <<-END
961
- # alias _add_expr_literal add_expr_literal
962
- # alias _add_expr_escaped add_expr_escaped
963
- # alias add_expr_literal _add_expr_escaped
964
- # alias add_expr_escaped _add_expr_literal
965
- # END
966
- #end
967
- #++
968
-
969
- def add_expr(src, code, indicator)
970
- case indicator
971
- when '='
972
- @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
973
- when '=='
974
- @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
975
- when '==='
976
- add_expr_debug(src, code)
977
- end
978
- end
979
-
980
- end
981
-
982
-
983
- #--
984
- ## (obsolete)
985
- #module FastEnhancer
986
- #end
987
- #++
988
-
989
-
990
- ##
991
- ## use $stdout instead of string
992
- ##
993
- ## this is only for Eruby.
994
- ##
995
- module StdoutEnhancer
996
-
997
- def self.desc # :nodoc:
998
- "use $stdout instead of array buffer or string buffer"
999
- end
1000
-
1001
- def add_preamble(src)
1002
- src << "_buf = $stdout;"
1003
- end
1004
-
1005
- def add_postamble(src)
1006
- src << "\n''\n"
1007
- end
1008
-
1009
- end
1010
-
1011
-
1012
- ##
1013
- ## use print statement instead of '_buf << ...'
1014
- ##
1015
- ## this is only for Eruby.
1016
- ##
1017
- module PrintOutEnhancer
1018
-
1019
- def self.desc # :nodoc:
1020
- "use print statement instead of '_buf << ...'"
1021
- end
1022
-
1023
- def add_preamble(src)
1024
- end
1025
-
1026
- def add_text(src, text)
1027
- src << " print '" << escape_text(text) << "';" unless text.empty?
1028
- end
1029
-
1030
- def add_expr_literal(src, code)
1031
- src << ' print((' << code << ').to_s);'
1032
- end
1033
-
1034
- def add_expr_escaped(src, code)
1035
- src << ' print ' << escaped_expr(code) << ';'
1036
- end
1037
-
1038
- def add_postamble(src)
1039
- src << "\n" unless src[-1] == ?\n
1040
- end
1041
-
1042
- end
1043
-
1044
-
1045
- ##
1046
- ## enable print function
1047
- ##
1048
- ## Notice: use Eruby#evaluate() and don't use Eruby#result()
1049
- ## to be enable print function.
1050
- ##
1051
- ## this is only for Eruby.
1052
- ##
1053
- module PrintEnabledEnhancer
1054
-
1055
- def self.desc # :nodoc:
1056
- "enable to use print function in '<% %>'"
1057
- end
1058
-
1059
- def add_preamble(src)
1060
- src << "@_buf = "
1061
- super
1062
- end
1063
-
1064
- def print(*args)
1065
- args.each do |arg|
1066
- @_buf << arg.to_s
1067
- end
1068
- end
1069
-
1070
- def evaluate(context=nil)
1071
- _src = @src
1072
- if context.is_a?(Hash)
1073
- context.each do |key, val| instance_variable_set("@#{key}", val) end
1074
- elsif context
1075
- context.instance_variables.each do |name|
1076
- instance_variable_set(name, context.instance_variable_get(name))
1077
- end
1078
- end
1079
- return instance_eval(_src, (@filename || '(erubis)'))
1080
- end
1081
-
1082
- end
1083
-
1084
-
1085
- ##
1086
- ## return array instead of string
1087
- ##
1088
- ## this is only for Eruby.
1089
- ##
1090
- module ArrayEnhancer
1091
-
1092
- def self.desc # :nodoc:
1093
- "return array instead of string"
1094
- end
1095
-
1096
- def add_preamble(src)
1097
- src << "_buf = [];"
1098
- end
1099
-
1100
- def add_postamble(src)
1101
- src << "\n" unless src[-1] == ?\n
1102
- src << "_buf\n"
1103
- end
1104
-
1105
- end
1106
-
1107
-
1108
- ##
1109
- ## use an Array object as buffer (included in Eruby by default)
1110
- ##
1111
- ## this is only for Eruby.
1112
- ##
1113
- module ArrayBufferEnhancer
1114
-
1115
- def self.desc # :nodoc:
1116
- "use an Array object for buffering (included in Eruby class)"
1117
- end
1118
-
1119
- def add_preamble(src)
1120
- src << "_buf = [];"
1121
- end
1122
-
1123
- def add_postamble(src)
1124
- src << "\n" unless src[-1] == ?\n
1125
- src << "_buf.join\n"
1126
- end
1127
-
1128
- end
1129
-
1130
-
1131
- ##
1132
- ## use String class for buffering
1133
- ##
1134
- ## this is only for Eruby.
1135
- ##
1136
- module StringBufferEnhancer
1137
-
1138
- def self.desc # :nodoc:
1139
- "use a String object for buffering"
1140
- end
1141
-
1142
- def add_preamble(src)
1143
- src << "_buf = '';"
1144
- end
1145
-
1146
- def add_postamble(src)
1147
- src << "\n" unless src[-1] == ?\n
1148
- src << "_buf.to_s\n"
1149
- end
1150
-
1151
- end
1152
-
1153
-
1154
- ##
1155
- ## use StringIO class for buffering
1156
- ##
1157
- ## this is only for Eruby.
1158
- ##
1159
- module StringIOEnhancer # :nodoc:
1160
-
1161
- def self.desc # :nodoc:
1162
- "use a StringIO object for buffering"
1163
- end
1164
-
1165
- def add_preamble(src)
1166
- src << "_buf = StringIO.new;"
1167
- end
1168
-
1169
- def add_postamble(src)
1170
- src << "\n" unless src[-1] == ?\n
1171
- src << "_buf.string\n"
1172
- end
1173
-
1174
- end
1175
-
1176
-
1177
- #--
1178
- ###
1179
- ### set buffer variable name to '_erbout' as well as '_buf'
1180
- ###
1181
- ### this is only for Eruby.
1182
- ###
1183
- #module ErboutEnhancer
1184
- #
1185
- # def self.desc # :nodoc:
1186
- # "set buffer name '_erbout' as well as '_buf'"
1187
- # end
1188
- #
1189
- # def add_preamble(src)
1190
- # src << "_erbout = _buf = '';"
1191
- # end
1192
- #
1193
- # def add_postamble(src)
1194
- # src << "\n" unless src[-1] == ?\n
1195
- # src << "_buf.to_s\n"
1196
- # end
1197
- #
1198
- #end
1199
- #++
1200
-
1201
-
1202
- ##
1203
- ## remove text and leave code, especially useful when debugging.
1204
- ##
1205
- ## ex.
1206
- ## $ erubis -s -E NoText file.eruby | more
1207
- ##
1208
- ## this is language independent.
1209
- ##
1210
- module NoTextEnhancer
1211
-
1212
- def self.desc # :nodoc:
1213
- "remove text and leave code (useful when debugging)"
1214
- end
1215
-
1216
- def add_text(src, text)
1217
- src << ("\n" * text.count("\n"))
1218
- if text[-1] != ?\n
1219
- text =~ /^(.*?)\z/
1220
- src << (' ' * $1.length)
1221
- end
1222
- end
1223
-
1224
- end
1225
-
1226
-
1227
- ##
1228
- ## remove code and leave text, especially useful when validating HTML tags.
1229
- ##
1230
- ## ex.
1231
- ## $ erubis -s -E NoCode file.eruby | tidy -errors
1232
- ##
1233
- ## this is language independent.
1234
- ##
1235
- module NoCodeEnhancer
1236
-
1237
- def self.desc # :nodoc:
1238
- "remove code and leave text (useful when validating HTML)"
1239
- end
1240
-
1241
- def add_preamble(src)
1242
- end
1243
-
1244
- def add_postamble(src)
1245
- end
1246
-
1247
- def add_text(src, text)
1248
- src << text
1249
- end
1250
-
1251
- def add_expr(src, code, indicator)
1252
- src << "\n" * code.count("\n")
1253
- end
1254
-
1255
- def add_stmt(src, code)
1256
- src << "\n" * code.count("\n")
1257
- end
1258
-
1259
- end
1260
-
1261
-
1262
- ##
1263
- ## get convert faster, but spaces around '<%...%>' are not trimmed.
1264
- ##
1265
- ## this is language-independent.
1266
- ##
1267
- module SimplifyEnhancer
1268
-
1269
- def self.desc # :nodoc:
1270
- "get convert faster but leave spaces around '<% %>'"
1271
- end
1272
-
1273
- #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
1274
- SIMPLE_REGEXP = /<%(=+|\#)?(.*?)-?%>/m
1275
-
1276
- def convert(input)
1277
- src = ""
1278
- add_preamble(src)
1279
- #regexp = pattern_regexp(@pattern)
1280
- pos = 0
1281
- input.scan(SIMPLE_REGEXP) do |indicator, code|
1282
- match = Regexp.last_match
1283
- index = match.begin(0)
1284
- text = input[pos, index - pos]
1285
- pos = match.end(0)
1286
- add_text(src, text)
1287
- if !indicator # <% %>
1288
- add_stmt(src, code)
1289
- elsif indicator[0] == ?\# # <%# %>
1290
- n = code.count("\n")
1291
- add_stmt(src, "\n" * n)
1292
- else # <%= %>
1293
- add_expr(src, code, indicator)
1294
- end
1295
- end
1296
- rest = $' || input
1297
- add_text(src, rest)
1298
- add_postamble(src)
1299
- return src
1300
- end
1301
-
1302
- end
1303
-
1304
-
1305
- ##
1306
- ## enable to use other embedded expression pattern (default is '\[= =\]').
1307
- ##
1308
- ## notice! this is an experimental. spec may change in the future.
1309
- ##
1310
- ## ex.
1311
- ## input = <<END
1312
- ## <% for item in list %>
1313
- ## <%= item %> : <%== item %>
1314
- ## [= item =] : [== item =]
1315
- ## <% end %>
1316
- ## END
1317
- ##
1318
- ## class BiPatternEruby
1319
- ## include BiPatternEnhancer
1320
- ## end
1321
- ## eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]')
1322
- ## list = ['<a>', 'b&b', '"c"']
1323
- ## print eruby.result(binding())
1324
- ##
1325
- ## ## output
1326
- ## <a> : &lt;a&gt;
1327
- ## <a> : &lt;a&gt;
1328
- ## b&b : b&amp;b
1329
- ## b&b : b&amp;b
1330
- ## "c" : &quot;c&quot;
1331
- ## "c" : &quot;c&quot;
1332
- ##
1333
- ## this is language independent.
1334
- ##
1335
- module BiPatternEnhancer
1336
-
1337
- def self.desc # :nodoc:
1338
- "another embedded expression pattern (default '\[= =\]')."
1339
- end
1340
-
1341
- def initialize(input, properties={})
1342
- self.bipattern = properties[:bipattern] # or '\$\{ \}'
1343
- super
1344
- end
1345
-
1346
- ## when pat is nil then '\[= =\]' is used
1347
- def bipattern=(pat) # :nodoc:
1348
- @bipattern = pat || '\[= =\]'
1349
- pre, post = @bipattern.split()
1350
- @bipattern_regexp = /(.*?)#{pre}(=*)(.*?)#{post}/m
1351
- end
1352
-
1353
- def add_text(src, text)
1354
- return unless text
1355
- text.scan(@bipattern_regexp) do |txt, indicator, code|
1356
- super(src, txt)
1357
- add_expr(src, code, '=' + indicator)
1358
- end
1359
- rest = $' || text
1360
- super(src, rest)
1361
- end
1362
-
1363
- end
1364
-
1365
-
1366
- ##
1367
- ## regards lines starting with '%' as program code
1368
- ##
1369
- ## this is for compatibility to eruby and ERB.
1370
- ##
1371
- ## this is language-independent.
1372
- ##
1373
- module PercentLineEnhancer
1374
-
1375
- def self.desc # :nodoc:
1376
- "regard lines starting with '%' as program code"
1377
- end
1378
-
1379
- PERCENT_LINE_PATTERN = /(.*?)^\%(.*?\r?\n)/m
1380
-
1381
- def add_text(src, text)
1382
- text.scan(PERCENT_LINE_PATTERN) do |txt, line|
1383
- super(src, txt)
1384
- if line[0] == ?%
1385
- super(src, line)
1386
- else
1387
- add_stmt(src, line)
1388
- end
1389
- end
1390
- rest = $' || text
1391
- super(src, rest)
1392
- end
1393
-
1394
- end
1395
-
1396
-
1397
- ##
1398
- ## [experimental] allow header and footer in eRuby script
1399
- ##
1400
- ## ex.
1401
- ## ====================
1402
- ## ## without header and footer
1403
- ## $ cat ex1.eruby
1404
- ## <% def list_items(list) %>
1405
- ## <% for item in list %>
1406
- ## <li><%= item %></li>
1407
- ## <% end %>
1408
- ## <% end %>
1409
- ##
1410
- ## $ erubis -s ex1.eruby
1411
- ## _buf = []; def list_items(list)
1412
- ## ; for item in list
1413
- ## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
1414
- ## '; end
1415
- ## ; end
1416
- ## ;
1417
- ## _buf.join
1418
- ##
1419
- ## ## with header and footer
1420
- ## $ cat ex2.eruby
1421
- ## <!--#header:
1422
- ## def list_items(list)
1423
- ## #-->
1424
- ## <% for item in list %>
1425
- ## <li><%= item %></li>
1426
- ## <% end %>
1427
- ## <!--#footer:
1428
- ## end
1429
- ## #-->
1430
- ##
1431
- ## $ erubis -s -c HeaderFooterEruby ex4.eruby
1432
- ##
1433
- ## def list_items(list)
1434
- ## _buf = []; _buf << '
1435
- ## '; for item in list
1436
- ## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
1437
- ## '; end
1438
- ## ; _buf << '
1439
- ## ';
1440
- ## _buf.join
1441
- ## end
1442
- ##
1443
- ## ====================
1444
- ##
1445
- ## this is language-independent.
1446
- ##
1447
- module HeaderFooterEnhancer
1448
-
1449
- def self.desc # :nodoc:
1450
- "allow header/footer in document (ex. '<!--#header: #-->')"
1451
- end
1452
-
1453
- HEADER_FOOTER_PATTERN = /(.*?)(^[ \t]*)?<!--\#(\w+):(.*?)\#-->([ \t]*\r?\n)?/m
1454
-
1455
- def add_text(src, text)
1456
- text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace|
1457
- flag_trim = @trim && lspace && rspace
1458
- super(src, txt)
1459
- content = "#{lspace}#{content}#{rspace}" if flag_trim
1460
- super(src, lspace) if !flag_trim && lspace
1461
- instance_variable_set("@#{word}", content)
1462
- super(src, rspace) if !flag_trim && rspace
1463
- end
1464
- rest = $' || text
1465
- super(src, rest)
1466
- end
1467
-
1468
- attr_accessor :header, :footer
1469
-
1470
- def convert(input)
1471
- source = super
1472
- return @src = "#{@header}#{source}#{@footer}"
1473
- end
1474
-
1475
- end
1476
-
1477
-
1478
- end
1479
- #--end of require 'erubis/enhancer'
1480
- #require 'erubis/tiny'
1481
- #--begin of require 'erubis/engine/eruby'
1482
- ##
1483
- ## $Rev: 54 $
1484
- ## $Release: 2.2.0 $
1485
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
1486
- ##
1487
-
1488
- #--already included require 'erubis/engine'
1489
- #--already included require 'erubis/enhancer'
1490
-
1491
-
1492
- module Erubis
1493
-
1494
-
1495
- ##
1496
- ## code generator for Ruby
1497
- ##
1498
- module RubyGenerator
1499
- include Generator
1500
- #include ArrayBufferEnhancer
1501
- include StringBufferEnhancer
1502
-
1503
- def init_generator(properties={})
1504
- super
1505
- @escapefunc ||= "Erubis::XmlHelper.escape_xml"
1506
- end
1507
-
1508
- def self.supported_properties() # :nodoc:
1509
- return []
1510
- end
1511
-
1512
- def escape_text(text)
1513
- text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
1514
- end
1515
-
1516
- def escaped_expr(code)
1517
- return "#{@escapefunc}(#{code})"
1518
- end
1519
-
1520
- #--
1521
- #def add_preamble(src)
1522
- # src << "_buf = [];"
1523
- #end
1524
- #++
1525
-
1526
- def add_text(src, text)
1527
- src << " _buf << '" << escape_text(text) << "';" unless text.empty?
1528
- end
1529
-
1530
- def add_stmt(src, code)
1531
- #src << code << ';'
1532
- src << code
1533
- src << ';' unless code[-1] == ?\n
1534
- end
1535
-
1536
- def add_expr_literal(src, code)
1537
- src << ' _buf << (' << code << ').to_s;'
1538
- end
1539
-
1540
- def add_expr_escaped(src, code)
1541
- src << ' _buf << ' << escaped_expr(code) << ';'
1542
- end
1543
-
1544
- def add_expr_debug(src, code)
1545
- code.strip!
1546
- s = (code.dump =~ /\A"(.*)"\z/) && $1
1547
- src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
1548
- end
1549
-
1550
- #--
1551
- #def add_postamble(src)
1552
- # src << "\n_buf.join\n"
1553
- #end
1554
- #++
1555
-
1556
- end
1557
-
1558
-
1559
- ##
1560
- ## engine for Ruby
1561
- ##
1562
- class Eruby < Basic::Engine
1563
- include RubyEvaluator
1564
- include RubyGenerator
1565
- end
1566
-
1567
-
1568
- ##
1569
- ## swtich '<%= %>' to escaped and '<%== %>' to not escaped
1570
- ##
1571
- class EscapedEruby < Eruby
1572
- include EscapeEnhancer
1573
- end
1574
-
1575
-
1576
- ##
1577
- ## sanitize expression (<%= ... %>) by default
1578
- ##
1579
- ## this is equivalent to EscapedEruby and is prepared only for compatibility.
1580
- ##
1581
- class XmlEruby < Eruby
1582
- include EscapeEnhancer
1583
- end
1584
-
1585
-
1586
- class PI::Eruby < PI::Engine
1587
- include RubyEvaluator
1588
- include RubyGenerator
1589
-
1590
- def init_converter(properties={})
1591
- @pi = 'rb'
1592
- super(properties)
1593
- end
1594
-
1595
- end
1596
-
1597
-
1598
- end
1599
- #--end of require 'erubis/engine/eruby'
1600
- #require 'erubis/engine/enhanced' # enhanced eruby engines
1601
- #require 'erubis/engine/optimized' # generates optimized ruby code
1602
- #require 'erubis/engine/ephp'
1603
- #require 'erubis/engine/ec'
1604
- #require 'erubis/engine/ejava'
1605
- #require 'erubis/engine/escheme'
1606
- #require 'erubis/engine/eperl'
1607
- #require 'erubis/engine/ejavascript'
1608
-
1609
- #--begin of require 'erubis/local-setting'
1610
- ##
1611
- ## $Rev: 42 $
1612
- ## $Release: 2.2.0 $
1613
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
1614
- ##
1615
-
1616
- ##
1617
- ## you can add site-local settings here.
1618
- ## this files is required by erubis.rb
1619
- ##
1620
- #--end of require 'erubis/local-setting'
1621
- #--end of require 'erubis'
1622
- #--begin of require 'erubis/tiny'
1623
- ##
1624
- ## $Rev: 54 $
1625
- ## $Release: 2.2.0 $
1626
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
1627
- ##
1628
-
1629
- module Erubis
1630
-
1631
- ##
1632
- ## tiny and the simplest implementation of eRuby
1633
- ##
1634
- ## ex.
1635
- ## eruby = TinyEruby.new(File.read('example.rhtml'))
1636
- ## print eruby.src # print ruby code
1637
- ## print eruby.result(binding()) # eval ruby code with Binding object
1638
- ## print eruby.evalute(context) # eval ruby code with context object
1639
- ##
1640
- class TinyEruby
1641
-
1642
- def initialize(input=nil)
1643
- @src = convert(input) if input
1644
- end
1645
- attr_reader :src
1646
-
1647
- EMBEDDED_PATTERN = /<%(=+|\#)?(.*?)-?%>/m
1648
-
1649
- def convert(input)
1650
- src = "_buf = '';" # preamble
1651
- pos = 0
1652
- input.scan(EMBEDDED_PATTERN) do |indicator, code|
1653
- match = Regexp.last_match
1654
- len = match.begin(0) - pos
1655
- text = input[pos, len]
1656
- pos = match.end(0)
1657
- #src << " _buf << '" << escape_text(text) << "';"
1658
- text.gsub!(/['\\]/, '\\\\\&')
1659
- src << " _buf << '" << text << "';" unless text.empty?
1660
- if !indicator # <% %>
1661
- src << code << ";"
1662
- elsif indicator == '#' # <%# %>
1663
- src << ("\n" * code.count("\n"))
1664
- else # <%= %>
1665
- src << " _buf << (" << code << ").to_s;"
1666
- end
1667
- end
1668
- rest = $' || input
1669
- #src << " _buf << '" << escape_text(rest) << "';"
1670
- rest.gsub!(/['\\]/, '\\\\\&')
1671
- src << " _buf << '" << rest << "';" unless rest.empty?
1672
- src << "\n_buf.to_s\n" # postamble
1673
- return src
1674
- end
1675
-
1676
- #def escape_text(text)
1677
- # return text.gsub!(/['\\]/, '\\\\\&') || text
1678
- #end
1679
-
1680
- def result(_binding=TOPLEVEL_BINDING)
1681
- eval @src, _binding
1682
- end
1683
-
1684
- def evaluate(_context=Object.new)
1685
- if _context.is_a?(Hash)
1686
- _obj = Object.new
1687
- _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end
1688
- _context = _obj
1689
- end
1690
- _context.instance_eval @src
1691
- end
1692
-
1693
- end
1694
-
1695
-
1696
-
1697
- module PI
1698
- end
1699
-
1700
- class PI::TinyEruby
1701
-
1702
- def initialize(input=nil, options={})
1703
- @escape = options[:escape] || 'Erubis::XmlHelper.escape_xml'
1704
- @src = convert(input) if input
1705
- end
1706
-
1707
- attr_reader :src
1708
-
1709
- EMBEDDED_PATTERN = /(^[ \t]*)?<\?rb(\s.*?)\?>([ \t]*\r?\n)?|@(!+)?\{(.*?)\}@/m
1710
-
1711
- def convert(input)
1712
- src = "_buf = '';" # preamble
1713
- pos = 0
1714
- input.scan(EMBEDDED_PATTERN) do |lspace, stmt, rspace, indicator, expr|
1715
- match = Regexp.last_match
1716
- len = match.begin(0) - pos
1717
- text = input[pos, len]
1718
- pos = match.end(0)
1719
- #src << " _buf << '" << escape_text(text) << "';"
1720
- text.gsub!(/['\\]/, '\\\\\&')
1721
- src << " _buf << '" << text << "';" unless text.empty?
1722
- if stmt # <?rb ... ?>
1723
- if lspace && rspace
1724
- src << "#{lspace}#{stmt}#{rspace}"
1725
- else
1726
- src << " _buf << '" << lspace << "';" if lspace
1727
- src << stmt << ";"
1728
- src << " _buf << '" << rspace << "';" if rspace
1729
- end
1730
- else # ${...}, $!{...}
1731
- if !indicator
1732
- src << " _buf << " << @escape << "(" << expr << ");"
1733
- elsif indicator == '!'
1734
- src << " _buf << (" << expr << ").to_s;"
1735
- end
1736
- end
1737
- end
1738
- rest = $' || input
1739
- #src << " _buf << '" << escape_text(rest) << "';"
1740
- rest.gsub!(/['\\]/, '\\\\\&')
1741
- src << " _buf << '" << rest << "';" unless rest.empty?
1742
- src << "\n_buf.to_s\n" # postamble
1743
- return src
1744
- end
1745
-
1746
- #def escape_text(text)
1747
- # return text.gsub!(/['\\]/, '\\\\\&') || text
1748
- #end
1749
-
1750
- def result(_binding=TOPLEVEL_BINDING)
1751
- eval @src, _binding
1752
- end
1753
-
1754
- def evaluate(_context=Object.new)
1755
- if _context.is_a?(Hash)
1756
- _obj = Object.new
1757
- _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end
1758
- _context = _obj
1759
- end
1760
- _context.instance_eval @src
1761
- end
1762
-
1763
- end
1764
-
1765
-
1766
- end
1767
- #--end of require 'erubis/tiny'
1768
- #--begin of require 'erubis/engine/enhanced'
1769
- ##
1770
- ## $Rev: 27 $
1771
- ## $Release: 2.2.0 $
1772
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
1773
- ##
1774
-
1775
- #--already included require 'erubis/enhancer'
1776
- #--already included require 'erubis/engine/eruby'
1777
-
1778
-
1779
- module Erubis
1780
-
1781
-
1782
- #--
1783
- ## moved to engine/ruby.rb
1784
- #class EscapedEruby < Eruby
1785
- # include EscapeEnhancer
1786
- #end
1787
- #++
1788
-
1789
-
1790
- #--
1791
- ### (obsolete)
1792
- #class FastEruby < Eruby
1793
- # include FastEnhancer
1794
- #end
1795
- #++
1796
-
1797
-
1798
- class StdoutEruby < Eruby
1799
- include StdoutEnhancer
1800
- end
1801
-
1802
-
1803
- class PrintOutEruby < Eruby
1804
- include PrintOutEnhancer
1805
- end
1806
-
1807
-
1808
- class PrintEnabledEruby < Eruby
1809
- include PrintEnabledEnhancer
1810
- end
1811
-
1812
-
1813
- class ArrayEruby < Eruby
1814
- include ArrayEnhancer
1815
- end
1816
-
1817
-
1818
- class ArrayBufferEruby < Eruby
1819
- include ArrayBufferEnhancer
1820
- end
1821
-
1822
-
1823
- class StringBufferEruby < Eruby
1824
- include StringBufferEnhancer
1825
- end
1826
-
1827
-
1828
- class StringIOEruby < Eruby
1829
- include StringIOEnhancer
1830
- end
1831
-
1832
-
1833
- class NoTextEruby < Eruby
1834
- include NoTextEnhancer
1835
- end
1836
-
1837
-
1838
- class NoCodeEruby < Eruby
1839
- include NoCodeEnhancer
1840
- end
1841
-
1842
-
1843
- class SimplifiedEruby < Eruby
1844
- include SimplifyEnhancer
1845
- end
1846
-
1847
-
1848
- class StdoutSimplifiedEruby < Eruby
1849
- include StdoutEnhancer
1850
- include SimplifyEnhancer
1851
- end
1852
-
1853
-
1854
- class PrintOutSimplifiedEruby < Eruby
1855
- include PrintOutEnhancer
1856
- include SimplifyEnhancer
1857
- end
1858
-
1859
-
1860
- class BiPatternEruby < Eruby
1861
- include BiPatternEnhancer
1862
- end
1863
-
1864
-
1865
- class PercentLineEruby < Eruby
1866
- include PercentLineEnhancer
1867
- end
1868
-
1869
-
1870
- class HeaderFooterEruby < Eruby
1871
- include HeaderFooterEnhancer
1872
- end
1873
-
1874
-
1875
- end
1876
- #--end of require 'erubis/engine/enhanced'
1877
- #--begin of require 'erubis/engine/optimized'
1878
- ##
1879
- ## $Rev: 31 $
1880
- ## $Release: 2.2.0 $
1881
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
1882
- ##
1883
-
1884
-
1885
- #--already included require 'erubis/engine/eruby'
1886
-
1887
-
1888
- module Erubis
1889
-
1890
-
1891
- module OptimizedGenerator
1892
- include Generator
1893
-
1894
- def self.supported_properties() # :nodoc:
1895
- return []
1896
- end
1897
-
1898
- def init_generator(properties={})
1899
- super
1900
- @escapefunc ||= "Erubis::XmlHelper.escape_xml"
1901
- @initialized = false
1902
- @prev_is_expr = false
1903
- end
1904
-
1905
- protected
1906
-
1907
- def escape_text(text)
1908
- text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
1909
- end
1910
-
1911
- def escaped_expr(code)
1912
- @escapefunc ||= 'Erubis::XmlHelper.escape_xml'
1913
- return "#{@escapefunc}(#{code})"
1914
- end
1915
-
1916
- def switch_to_expr(src)
1917
- return if @prev_is_expr
1918
- @prev_is_expr = true
1919
- src << ' _buf'
1920
- end
1921
-
1922
- def switch_to_stmt(src)
1923
- return unless @prev_is_expr
1924
- @prev_is_expr = false
1925
- src << ';'
1926
- end
1927
-
1928
- def add_preamble(src)
1929
- #@initialized = false
1930
- #@prev_is_expr = false
1931
- end
1932
-
1933
- def add_text(src, text)
1934
- return if text.empty?
1935
- if @initialized
1936
- switch_to_expr(src)
1937
- src << " << '" << escape_text(text) << "'"
1938
- else
1939
- src << "_buf = '" << escape_text(text) << "';"
1940
- @initialized = true
1941
- end
1942
- end
1943
-
1944
- def add_stmt(src, code)
1945
- switch_to_stmt(src) if @initialized
1946
- #super
1947
- src << code
1948
- src << ';' unless code[-1] == ?\n
1949
- end
1950
-
1951
- def add_expr_literal(src, code)
1952
- unless @initialized; src << "_buf = ''"; @initialized = true; end
1953
- switch_to_expr(src)
1954
- src << " << (" << code << ").to_s"
1955
- end
1956
-
1957
- def add_expr_escaped(src, code)
1958
- unless @initialized; src << "_buf = ''"; @initialized = true; end
1959
- switch_to_expr(src)
1960
- src << " << " << escaped_expr(code)
1961
- end
1962
-
1963
- def add_expr_debug(src, code)
1964
- code.strip!
1965
- s = (code.dump =~ /\A"(.*)"\z/) && $1
1966
- src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
1967
- end
1968
-
1969
- def add_postamble(src)
1970
- #super if @initialized
1971
- src << "\n_buf\n" if @initialized
1972
- end
1973
-
1974
- end # end of class OptimizedEruby
1975
-
1976
-
1977
- ##
1978
- ## Eruby class which generates optimized ruby code
1979
- ##
1980
- class OptimizedEruby < Basic::Engine # Eruby
1981
- include RubyEvaluator
1982
- include OptimizedGenerator
1983
-
1984
- def init_converter(properties={})
1985
- @pi = 'rb'
1986
- super(properties)
1987
- end
1988
-
1989
- end
1990
-
1991
-
1992
- ##
1993
- ## XmlEruby class which generates optimized ruby code
1994
- ##
1995
- class OptimizedXmlEruby < OptimizedEruby
1996
- include EscapeEnhancer
1997
-
1998
- def add_expr_debug(src, code)
1999
- switch_to_stmt(src) if indicator == '===' && !@initialized
2000
- super
2001
- end
2002
-
2003
- end # end of class OptimizedXmlEruby
2004
-
2005
- end
2006
- #--end of require 'erubis/engine/optimized'
2007
- #--already included require 'erubis/engine/eruby'
2008
- #--begin of require 'erubis/engine/ephp'
2009
- ##
2010
- ## $Rev: 31 $
2011
- ## $Release: 2.2.0 $
2012
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
2013
- ##
2014
-
2015
- #--already included require 'erubis/engine'
2016
- #--already included require 'erubis/enhancer'
2017
-
2018
-
2019
- module Erubis
2020
-
2021
-
2022
- module PhpGenerator
2023
- include Generator
2024
-
2025
- def self.supported_properties() # :nodoc:
2026
- return []
2027
- end
2028
-
2029
- def init_generator(properties={})
2030
- super
2031
- @escapefunc ||= 'htmlspecialchars'
2032
- end
2033
-
2034
- def add_preamble(src)
2035
- # empty
2036
- end
2037
-
2038
- def escape_text(text)
2039
- return text.gsub!(/<\?xml\b/, '<<?php ?>?xml') || text
2040
- end
2041
-
2042
- def add_text(src, text)
2043
- src << escape_text(text)
2044
- end
2045
-
2046
- def add_expr_literal(src, code)
2047
- code.strip!
2048
- src << "<?php echo #{code}; ?>"
2049
- end
2050
-
2051
- def add_expr_escaped(src, code)
2052
- add_expr_literal(src, escaped_expr(code))
2053
- end
2054
-
2055
- def add_expr_debug(src, code)
2056
- code.strip!
2057
- s = code.gsub(/\'/, "\\'")
2058
- src << "<?php error_log('*** debug: #{s}='.(#{code}), 0); ?>"
2059
- end
2060
-
2061
- def add_stmt(src, code)
2062
- src << "<?php"
2063
- src << " " if code[0] != ?\ #
2064
- if code[-1] == ?\n
2065
- code.chomp!
2066
- src << code << "?>\n"
2067
- else
2068
- src << code << "?>"
2069
- end
2070
- end
2071
-
2072
- def add_postamble(src)
2073
- # empty
2074
- end
2075
-
2076
- end
2077
-
2078
-
2079
- ##
2080
- ## engine for PHP
2081
- ##
2082
- class Ephp < Basic::Engine
2083
- include PhpGenerator
2084
- end
2085
-
2086
-
2087
- class EscapedEphp < Ephp
2088
- include EscapeEnhancer
2089
- end
2090
-
2091
-
2092
- #class XmlEphp < Ephp
2093
- # include EscapeEnhancer
2094
- #end
2095
-
2096
-
2097
- class PI::Ephp < PI::Engine
2098
- include PhpGenerator
2099
-
2100
- def init_converter(properties={})
2101
- @pi = 'php'
2102
- super(properties)
2103
- end
2104
-
2105
- end
2106
-
2107
-
2108
- end
2109
- #--end of require 'erubis/engine/ephp'
2110
- #--begin of require 'erubis/engine/ec'
2111
- ##
2112
- ## $Rev: 33 $
2113
- ## $Release: 2.2.0 $
2114
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
2115
- ##
2116
-
2117
- #--already included require 'erubis/engine'
2118
- #--already included require 'erubis/enhancer'
2119
-
2120
-
2121
- module Erubis
2122
-
2123
-
2124
- module CGenerator
2125
- include Generator
2126
-
2127
- def self.supported_properties() # :nodoc:
2128
- return [
2129
- [:indent, '', "indent spaces (ex. ' ')"],
2130
- [:out, 'stdout', "output file pointer name"],
2131
- ]
2132
- end
2133
-
2134
- def init_generator(properties={})
2135
- super
2136
- @escapefunc ||= "escape"
2137
- @indent = properties[:indent] || ''
2138
- @out = properties[:out] || 'stdout'
2139
- end
2140
-
2141
- def add_preamble(src)
2142
- src << "#line 1 \"#{self.filename}\"\n" if self.filename
2143
- end
2144
-
2145
- def escape_text(text)
2146
- @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
2147
- text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] }
2148
- return text
2149
- end
2150
-
2151
- def escaped_expr(code)
2152
- return "#{@escapefunc}(#{code.strip}, #{@out})"
2153
- end
2154
-
2155
- def add_text(src, text)
2156
- return if text.empty?
2157
- src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
2158
- src << "fputs("
2159
- i = 0
2160
- text.each_line do |line|
2161
- src << "\n" << @indent << ' ' if i > 0
2162
- i += 1
2163
- src << '"' << escape_text(line) << '"'
2164
- end
2165
- src << ", #{@out});" #<< (text[-1] == ?\n ? "\n" : "")
2166
- src << "\n" if text[-1] == ?\n
2167
- end
2168
-
2169
- def add_stmt(src, code)
2170
- src << code
2171
- end
2172
-
2173
- def add_expr_literal(src, code)
2174
- src << @indent if src.empty? || src[-1] == ?\n
2175
- src << " fprintf(#{@out}, " << code.strip << ');'
2176
- end
2177
-
2178
- def add_expr_escaped(src, code)
2179
- src << @indent if src.empty? || src[-1] == ?\n
2180
- src << ' ' << escaped_expr(code) << ';'
2181
- end
2182
-
2183
- def add_expr_debug(src, code)
2184
- code.strip!
2185
- s = nil
2186
- if code =~ /\A\".*?\"\s*,\s*(.*)/
2187
- s = $1.gsub(/[%"]/, '\\\1') + '='
2188
- end
2189
- src << @indent if src.empty? || src[-1] == ?\n
2190
- src << " fprintf(stderr, \"*** debug: #{s}\" #{code});"
2191
- end
2192
-
2193
- def add_postamble(src)
2194
- # empty
2195
- end
2196
-
2197
- end
2198
-
2199
-
2200
- ##
2201
- ## engine for C
2202
- ##
2203
- class Ec < Basic::Engine
2204
- include CGenerator
2205
- end
2206
-
2207
-
2208
- class EscapedEc < Ec
2209
- include EscapeEnhancer
2210
- end
2211
-
2212
-
2213
- #class XmlEc < Ec
2214
- # include EscapeEnhancer
2215
- #end
2216
-
2217
- class PI::Ec < PI::Engine
2218
- include CGenerator
2219
-
2220
- def init_converter(properties={})
2221
- @pi = 'c'
2222
- super(properties)
2223
- end
2224
-
2225
- end
2226
-
2227
-
2228
- end
2229
- #--end of require 'erubis/engine/ec'
2230
- #--begin of require 'erubis/engine/ejava'
2231
- ##
2232
- ## $Rev: 31 $
2233
- ## $Release: 2.2.0 $
2234
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
2235
- ##
2236
-
2237
- #--already included require 'erubis/engine'
2238
- #--already included require 'erubis/enhancer'
2239
-
2240
-
2241
- module Erubis
2242
-
2243
-
2244
- module JavaGenerator
2245
- include Generator
2246
-
2247
- def self.supported_properties() # :nodoc:
2248
- return [
2249
- [:indent, '', "indent spaces (ex. ' ')"],
2250
- [:buf, '_buf', "output buffer name"],
2251
- [:bufclass, 'StringBuffer', "output buffer class (ex. 'StringBuilder')"],
2252
- ]
2253
- end
2254
-
2255
- def init_generator(properties={})
2256
- super
2257
- @escapefunc ||= 'escape'
2258
- @indent = properties[:indent] || ''
2259
- @buf = properties[:buf] || '_buf'
2260
- @bufclass = properties[:bufclass] || 'StringBuffer'
2261
- end
2262
-
2263
- def add_preamble(src)
2264
- src << "#{@indent}#{@bufclass} #{@buf} = new #{@bufclass}();"
2265
- end
2266
-
2267
- def escape_text(text)
2268
- @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
2269
- return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text
2270
- end
2271
-
2272
- def add_text(src, text)
2273
- return if text.empty?
2274
- src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
2275
- src << @buf << ".append("
2276
- i = 0
2277
- text.each_line do |line|
2278
- src << "\n" << @indent << ' + ' if i > 0
2279
- i += 1
2280
- src << '"' << escape_text(line) << '"'
2281
- end
2282
- src << ");" << (text[-1] == ?\n ? "\n" : "")
2283
- end
2284
-
2285
- def add_stmt(src, code)
2286
- src << code
2287
- end
2288
-
2289
- def add_expr_literal(src, code)
2290
- src << @indent if src.empty? || src[-1] == ?\n
2291
- code.strip!
2292
- src << " #{@buf}.append(#{code});"
2293
- end
2294
-
2295
- def add_expr_escaped(src, code)
2296
- add_expr_literal(src, escaped_expr(code))
2297
- end
2298
-
2299
- def add_expr_debug(src, code)
2300
- code.strip!
2301
- src << @indent if src.empty? || src[-1] == ?\n
2302
- src << " System.err.println(\"*** debug: #{code}=\"+(#{code}));"
2303
- end
2304
-
2305
- def add_postamble(src)
2306
- src << "\n" if src[-1] == ?;
2307
- src << @indent << "return " << @buf << ".toString();\n"
2308
- #src << @indent << "System.out.print(" << @buf << ".toString());\n"
2309
- end
2310
-
2311
- end
2312
-
2313
-
2314
- ##
2315
- ## engine for Java
2316
- ##
2317
- class Ejava < Basic::Engine
2318
- include JavaGenerator
2319
- end
2320
-
2321
-
2322
- class EscapedEjava < Ejava
2323
- include EscapeEnhancer
2324
- end
2325
-
2326
-
2327
- #class XmlEjava < Ejava
2328
- # include EscapeEnhancer
2329
- #end
2330
-
2331
- class PI::Ejava < PI::Engine
2332
- include JavaGenerator
2333
-
2334
- def init_converter(properties={})
2335
- @pi = 'java'
2336
- super(properties)
2337
- end
2338
-
2339
- end
2340
-
2341
- end
2342
- #--end of require 'erubis/engine/ejava'
2343
- #--begin of require 'erubis/engine/escheme'
2344
- ##
2345
- ## $Rev: 33 $
2346
- ## $Release: 2.2.0 $
2347
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
2348
- ##
2349
-
2350
- #--already included require 'erubis/engine'
2351
- #--already included require 'erubis/enhancer'
2352
-
2353
-
2354
- module Erubis
2355
-
2356
-
2357
- module SchemeGenerator
2358
- include Generator
2359
-
2360
- def self.supported_properties() # :nodoc:
2361
- return [
2362
- [:func, '_add', "function name (ex. 'display')"],
2363
- ]
2364
- end
2365
-
2366
- def init_generator(properties={})
2367
- super
2368
- @escapefunc ||= 'escape'
2369
- @func = properties[:func] || '_add' # or 'display'
2370
- end
2371
-
2372
- def add_preamble(src)
2373
- return unless @func == '_add'
2374
- src << "(let ((_buf '())) " + \
2375
- "(define (_add x) (set! _buf (cons x _buf))) "
2376
- #src << "(let* ((_buf '())" + \
2377
- # " (_add (lambda (x) (set! _buf (cons x _buf))))) "
2378
- end
2379
-
2380
- def escape_text(text)
2381
- @table_ ||= { '"'=>'\\"', '\\'=>'\\\\' }
2382
- text.gsub!(/["\\]/) { |m| @table_[m] }
2383
- return text
2384
- end
2385
-
2386
- def escaped_expr(code)
2387
- code.strip!
2388
- return "(#{@escapefunc} #{code})"
2389
- end
2390
-
2391
- def add_text(src, text)
2392
- return if text.empty?
2393
- t = escape_text(text)
2394
- if t[-1] == ?\n
2395
- t[-1, 1] = ''
2396
- src << "(#{@func} \"" << t << "\\n\")\n"
2397
- else
2398
- src << "(#{@func} \"" << t << '")'
2399
- end
2400
- end
2401
-
2402
- def add_stmt(src, code)
2403
- src << code
2404
- end
2405
-
2406
- def add_expr_literal(src, code)
2407
- code.strip!
2408
- src << "(#{@func} #{code})"
2409
- end
2410
-
2411
- def add_expr_escaped(src, code)
2412
- add_expr_literal(src, escaped_expr(code))
2413
- end
2414
-
2415
- def add_expr_debug(src, code)
2416
- s = (code.strip! || code).gsub(/\"/, '\\"')
2417
- src << "(display \"*** debug: #{s}=\")(display #{code.strip})(display \"\\n\")"
2418
- end
2419
-
2420
- def add_postamble(src)
2421
- return unless @func == '_add'
2422
- src << "\n" unless src[-1] == ?\n
2423
- src << " (reverse _buf))\n"
2424
- end
2425
-
2426
- end
2427
-
2428
-
2429
- ##
2430
- ## engine for Scheme
2431
- ##
2432
- class Escheme < Basic::Engine
2433
- include SchemeGenerator
2434
- end
2435
-
2436
-
2437
- class EscapedEscheme < Escheme
2438
- include EscapeEnhancer
2439
- end
2440
-
2441
-
2442
- #class XmlEscheme < Escheme
2443
- # include EscapeEnhancer
2444
- #end
2445
-
2446
-
2447
- class PI::Escheme < PI::Engine
2448
- include SchemeGenerator
2449
-
2450
- def init_converter(properties={})
2451
- @pi = 'scheme'
2452
- super(properties)
2453
- end
2454
-
2455
- end
2456
-
2457
-
2458
- end
2459
- #--end of require 'erubis/engine/escheme'
2460
- #--begin of require 'erubis/engine/eperl'
2461
- ##
2462
- ## $Rev: 40 $
2463
- ## $Release: 2.2.0 $
2464
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
2465
- ##
2466
-
2467
- #--already included require 'erubis/engine'
2468
- #--already included require 'erubis/enhancer'
2469
-
2470
-
2471
- module Erubis
2472
-
2473
-
2474
- module PerlGenerator
2475
- include Generator
2476
-
2477
- def self.supported_properties() # :nodoc:
2478
- return [
2479
- [:func, 'print', "function name"],
2480
- ]
2481
- end
2482
-
2483
- def init_generator(properties={})
2484
- super
2485
- @escapefunc ||= 'encode_entities'
2486
- @func = properties[:func] || 'print'
2487
- end
2488
-
2489
- def add_preamble(src)
2490
- src << "use HTML::Entities; ";
2491
- end
2492
-
2493
- def escape_text(text)
2494
- return text.gsub!(/['\\]/, '\\\\\&') || text
2495
- end
2496
-
2497
- def add_text(src, text)
2498
- src << @func << "('" << escape_text(text) << "'); " unless text.empty?
2499
- end
2500
-
2501
- def add_expr_literal(src, code)
2502
- code.strip!
2503
- src << @func << "(" << code << "); "
2504
- end
2505
-
2506
- def add_expr_escaped(src, code)
2507
- add_expr_literal(src, escaped_expr(code))
2508
- end
2509
-
2510
- def add_expr_debug(src, code)
2511
- code.strip!
2512
- s = code.gsub(/\'/, "\\'")
2513
- src << @func << "('*** debug: #{code}=', #{code}, \"\\n\");"
2514
- end
2515
-
2516
- def add_stmt(src, code)
2517
- src << code
2518
- end
2519
-
2520
- def add_postamble(src)
2521
- src << "\n" unless src[-1] == ?\n
2522
- end
2523
-
2524
- end
2525
-
2526
-
2527
- ##
2528
- ## engine for Perl
2529
- ##
2530
- class Eperl < Basic::Engine
2531
- include PerlGenerator
2532
- end
2533
-
2534
-
2535
- class EscapedEperl < Eperl
2536
- include EscapeEnhancer
2537
- end
2538
-
2539
-
2540
- #class XmlEperl < Eperl
2541
- # include EscapeEnhancer
2542
- #end
2543
-
2544
-
2545
- class PI::Eperl < PI::Engine
2546
- include PerlGenerator
2547
-
2548
- def init_converter(properties={})
2549
- @pi = 'perl'
2550
- super(properties)
2551
- end
2552
-
2553
- end
2554
-
2555
-
2556
- end
2557
- #--end of require 'erubis/engine/eperl'
2558
- #--begin of require 'erubis/engine/ejavascript'
2559
- ##
2560
- ## $Rev: 31 $
2561
- ## $Release: 2.2.0 $
2562
- ## copyright(c) 2006-2007 kuwata-lab all rights reserved.
2563
- ##
2564
-
2565
- #--already included require 'erubis/engine'
2566
- #--already included require 'erubis/enhancer'
2567
-
2568
-
2569
- module Erubis
2570
-
2571
-
2572
- module JavascriptGenerator
2573
- include Generator
2574
-
2575
- def self.supported_properties() # :nodoc:
2576
- list = []
2577
- #list << [:indent, '', "indent spaces (ex. ' ')"]
2578
- #list << [:buf, '_buf', "output buffer name"]
2579
- return list
2580
- end
2581
-
2582
- def init_generator(properties={})
2583
- super
2584
- @escapefunc ||= 'escape'
2585
- @indent = properties[:indent] || ''
2586
- @buf = properties[:out] || '_buf'
2587
- end
2588
-
2589
- def add_preamble(src)
2590
- src << "#{@indent}var #{@buf} = [];"
2591
- end
2592
-
2593
- def escape_text(text)
2594
- @@table_ ||= { "\r"=>"\\r", "\n"=>"\\n\\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
2595
- return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text
2596
- end
2597
-
2598
- def add_indent(src, indent)
2599
- src << (src.empty? || src[-1] == ?\n ? indent : ' ')
2600
- end
2601
-
2602
- def add_text(src, text)
2603
- return if text.empty?
2604
- add_indent(src, @indent)
2605
- src << @buf << '.push("'
2606
- s = escape_text(text)
2607
- if s[-1] == ?\n
2608
- s[-2, 2] = ''
2609
- src << s << "\");\n"
2610
- else
2611
- src << s << "\");"
2612
- end
2613
- end
2614
-
2615
- def add_stmt(src, code)
2616
- src << code
2617
- end
2618
-
2619
- def add_expr_literal(src, code)
2620
- add_indent(src, @indent)
2621
- code.strip!
2622
- src << "#{@buf}.push(#{code});"
2623
- end
2624
-
2625
- def add_expr_escaped(src, code)
2626
- add_expr_literal(src, escaped_expr(code))
2627
- end
2628
-
2629
- def add_expr_debug(src, code)
2630
- add_indent(src, @indent)
2631
- code.strip!
2632
- src << "alert(\"*** debug: #{code}=\"+(#{code}));"
2633
- end
2634
-
2635
- def add_postamble(src)
2636
- src << "\n" if src[-1] == ?;
2637
- src << @indent << 'document.write(' << @buf << ".join(\"\"));\n"
2638
- end
2639
-
2640
- end
2641
-
2642
-
2643
- ##
2644
- ## engine for JavaScript
2645
- ##
2646
- class Ejavascript < Basic::Engine
2647
- include JavascriptGenerator
2648
- end
2649
-
2650
-
2651
- class EscapedEjavascript < Ejavascript
2652
- include EscapeEnhancer
2653
- end
2654
-
2655
-
2656
- #class XmlEjavascript < Ejavascript
2657
- # include EscapeEnhancer
2658
- #end
2659
-
2660
-
2661
- class PI::Ejavascript < PI::Engine
2662
- include JavascriptGenerator
2663
-
2664
- def init_converter(properties={})
2665
- @pi = 'js'
2666
- super(properties)
2667
- end
2668
-
2669
- end
2670
-
2671
-
2672
- end
2673
- #--end of require 'erubis/engine/ejavascript'
2674
-
2675
-
2676
- module Erubis
2677
-
2678
-
2679
- Ejs = Ejavascript
2680
- EscapedEjs = EscapedEjavascript
2681
-
2682
-
2683
- class CommandOptionError < ErubisError
2684
- end
2685
-
2686
-
2687
- ##
2688
- ## main class of command
2689
- ##
2690
- ## ex.
2691
- ## Main.main(ARGV)
2692
- ##
2693
- class Main
2694
-
2695
- def self.main(argv=ARGV)
2696
- status = 0
2697
- begin
2698
- Main.new.execute(ARGV)
2699
- rescue CommandOptionError => ex
2700
- $stderr.puts ex.message
2701
- status = 1
2702
- end
2703
- exit(status)
2704
- end
2705
-
2706
- def initialize
2707
- @single_options = "hvxztSbeB"
2708
- @arg_options = "pcrfKIlaEC"
2709
- @option_names = {
2710
- ?h => :help,
2711
- ?v => :version,
2712
- ?x => :source,
2713
- ?z => :syntax,
2714
- #?T => :notrim,
2715
- ?t => :untabify,
2716
- ?S => :intern,
2717
- ?b => :bodyonly,
2718
- ?B => :binding,
2719
- ?p => :pattern,
2720
- ?c => :context,
2721
- ?C => :class,
2722
- ?e => :escape,
2723
- ?r => :requires,
2724
- ?f => :datafiles,
2725
- ?K => :kanji,
2726
- ?I => :includes,
2727
- ?l => :lang,
2728
- ?a => :action,
2729
- ?E => :enhancers,
2730
- }
2731
- assert unless @single_options.length + @arg_options.length == @option_names.length
2732
- (@single_options + @arg_options).each_byte do |ch|
2733
- assert unless @option_names.key?(ch)
2734
- end
2735
- end
2736
-
2737
-
2738
- def execute(argv=ARGV)
2739
- ## parse command-line options
2740
- options, properties = parse_argv(argv, @single_options, @arg_options)
2741
- filenames = argv
2742
- options[?h] = true if properties[:help]
2743
- opts = Object.new
2744
- arr = @option_names.collect { |ch, name| "def #{name}; @#{name}; end\n" }
2745
- opts.instance_eval arr.join
2746
- options.each do |ch, val|
2747
- name = @option_names[ch]
2748
- opts.instance_variable_set("@#{name}", val)
2749
- end
2750
-
2751
- ## help, version, enhancer list
2752
- if opts.help || opts.version
2753
- puts version() if opts.version
2754
- puts usage() if opts.help
2755
- puts show_properties() if opts.help
2756
- puts show_enhancers() if opts.help
2757
- return
2758
- end
2759
-
2760
- ## include path
2761
- opts.includes.split(/,/).each do |path|
2762
- $: << path
2763
- end if opts.includes
2764
-
2765
- ## require library
2766
- opts.requires.split(/,/).each do |library|
2767
- require library
2768
- end if opts.requires
2769
-
2770
- ## action
2771
- action = opts.action
2772
- action ||= 'syntax' if opts.syntax
2773
- action ||= 'convert' if opts.source
2774
-
2775
- ## lang
2776
- lang = opts.lang || 'ruby'
2777
- action ||= 'convert' if opts.lang
2778
-
2779
- ## class name of Eruby
2780
- classname = opts.class
2781
- klass = get_classobj(classname, lang, properties[:pi])
2782
-
2783
- ## kanji code
2784
- $KCODE = opts.kanji if opts.kanji
2785
-
2786
- ## read context values from yaml file
2787
- datafiles = opts.datafiles
2788
- context = load_datafiles(datafiles, opts)
2789
-
2790
- ## parse context data
2791
- if opts.context
2792
- context = parse_context_data(opts.context, opts)
2793
- end
2794
-
2795
- ## properties for engine
2796
- properties[:escape] = true if opts.escape && !properties.key?(:escape)
2797
- properties[:pattern] = opts.pattern if opts.pattern
2798
- #properties[:trim] = false if opts.notrim
2799
- properties[:preamble] = properties[:postamble] = false if opts.bodyonly
2800
- properties[:pi] = nil if properties[:pi] == true
2801
-
2802
- ## create engine and extend enhancers
2803
- engine = klass.new(nil, properties)
2804
- enhancers = get_enhancers(opts.enhancers)
2805
- #enhancers.push(Erubis::EscapeEnhancer) if opts.escape
2806
- enhancers.each do |enhancer|
2807
- engine.extend(enhancer)
2808
- engine.bipattern = properties[:bipattern] if enhancer == Erubis::BiPatternEnhancer
2809
- end
2810
-
2811
- ## convert and execute
2812
- val = nil
2813
- msg = "Syntax OK\n"
2814
- if filenames && !filenames.empty?
2815
- filenames.each do |filename|
2816
- test(?f, filename) or raise CommandOptionError.new("#{filename}: file not found.")
2817
- engine.filename = filename
2818
- engine.convert!(File.read(filename))
2819
- val = do_action(action, engine, context, filename, opts)
2820
- msg = nil if val
2821
- end
2822
- else
2823
- engine.filename = '(stdin)'
2824
- engine.convert!($stdin.read())
2825
- val = do_action(action, engine, context, filename, opts)
2826
- msg = nil if val
2827
- end
2828
- print msg if action == 'syntax' && msg
2829
-
2830
- end
2831
-
2832
- private
2833
-
2834
- def do_action(action, engine, context, filename, opts)
2835
- case action
2836
- when 'convert'
2837
- s = engine.src
2838
- when nil, 'exec', 'execute'
2839
- s = opts.binding ? engine.result(context.to_hash) : engine.evaluate(context)
2840
- when 'syntax'
2841
- s = check_syntax(filename, engine.src)
2842
- else
2843
- raise "*** internal error"
2844
- end
2845
- print s if s
2846
- return s
2847
- end
2848
-
2849
- def usage
2850
- command = File.basename($0)
2851
- s = <<END
2852
- erubis - embedded program converter for multi-language
2853
- Usage: #{command} [..options..] [file ...]
2854
- -h, --help : help
2855
- -v : version
2856
- -x : show converted code
2857
- -z : syntax checking
2858
- -b : body only (no preamble nor postamble)
2859
- -e : escape (equal to '--E Escape')
2860
- -p pattern : embedded pattern (default '<% %>')
2861
- -l lang : convert but no execute (ruby/php/c/java/scheme/perl/js)
2862
- -E e1,e2,... : enhancer names (Escape, PercentLine, BiPattern, ...)
2863
- -I path : library include path
2864
- -K kanji : kanji code (euc/sjis/utf8) (default none)
2865
- -c context : context data string (yaml inline style or ruby code)
2866
- -f datafile : context data file ('*.yaml', '*.yml', or '*.rb')
2867
- -t : expand tab character in YAML file
2868
- -S : convert mapping key from string to symbol in YAML file
2869
- -B : invoke 'result(binding)' instead of 'evaluate(context)'
2870
- --pi=name : parse '<?name ... ?>' instead of '<% ... %>'
2871
-
2872
- END
2873
- #'
2874
- # -T : don't trim spaces around '<% %>'
2875
- # -c class : class name (XmlEruby/PercentLineEruby/...) (default Eruby)
2876
- # -r library : require library
2877
- # -a : action (convert/execute)
2878
- return s
2879
- end
2880
-
2881
-
2882
- def collect_supported_properties(erubis_klass)
2883
- list = []
2884
- erubis_klass.ancestors.each do |klass|
2885
- if klass.respond_to?(:supported_properties)
2886
- list.concat(klass.supported_properties)
2887
- end
2888
- end
2889
- return list
2890
- end
2891
-
2892
- def show_properties
2893
- s = "supported properties:\n"
2894
- basic_props = collect_supported_properties(Erubis::Basic::Engine)
2895
- pi_props = collect_supported_properties(Erubis::PI::Engine)
2896
- list = []
2897
- common_props = basic_props & pi_props
2898
- list << ['(common)', common_props]
2899
- list << ['(basic)', basic_props - common_props]
2900
- list << ['(pi)', pi_props - common_props]
2901
- %w[ruby php c java scheme perl javascript].each do |lang|
2902
- klass = Erubis.const_get("E#{lang}")
2903
- list << [lang, collect_supported_properties(klass) - basic_props]
2904
- end
2905
- list.each do |lang, props|
2906
- s << " * #{lang}\n"
2907
- props.each do |name, default_val, desc|
2908
- s << (" --%-23s : %s\n" % ["#{name}=#{default_val.inspect}", desc])
2909
- end
2910
- end
2911
- s << "\n"
2912
- return s
2913
- end
2914
-
2915
- def show_enhancers
2916
- s = "enhancers:\n"
2917
- list = []
2918
- ObjectSpace.each_object(Module) do |m| list << m end
2919
- list.sort_by { |m| m.name }.each do |m|
2920
- next unless m.name =~ /\AErubis::(.*)Enhancer\z/
2921
- name = $1
2922
- desc = m.desc
2923
- s << (" %-13s : %s\n" % [name, desc])
2924
- end
2925
- return s
2926
- end
2927
-
2928
- def version
2929
- return Erubis::VERSION
2930
- end
2931
-
2932
- def parse_argv(argv, arg_none='', arg_required='', arg_optional='')
2933
- options = {}
2934
- context = {}
2935
- while argv[0] && argv[0][0] == ?-
2936
- optstr = argv.shift
2937
- optstr = optstr[1, optstr.length-1]
2938
- #
2939
- if optstr[0] == ?- # context
2940
- unless optstr =~ /\A\-([-\w]+)(?:=(.*))?/
2941
- raise CommandOptionError.new("-#{optstr}: invalid context value.")
2942
- end
2943
- name = $1; value = $2
2944
- name = name.gsub(/-/, '_').intern
2945
- #value = value.nil? ? true : YAML.load(value) # error, why?
2946
- value = value.nil? ? true : YAML.load("---\n#{value}\n")
2947
- context[name] = value
2948
- #
2949
- else # options
2950
- while optstr && !optstr.empty?
2951
- optchar = optstr[0]
2952
- optstr[0,1] = ""
2953
- if arg_none.include?(optchar)
2954
- options[optchar] = true
2955
- elsif arg_required.include?(optchar)
2956
- arg = optstr.empty? ? argv.shift : optstr
2957
- unless arg
2958
- mesg = "-#{optchar.chr}: #{@option_args[optchar]} required."
2959
- raise CommandOptionError.new(mesg)
2960
- end
2961
- options[optchar] = arg
2962
- optstr = nil
2963
- elsif arg_optional.include?(optchar)
2964
- arg = optstr.empty? ? true : optstr
2965
- options[optchar] = arg
2966
- optstr = nil
2967
- else
2968
- raise CommandOptionError.new("-#{optchar.chr}: unknown option.")
2969
- end
2970
- end
2971
- end
2972
- #
2973
- end # end of while
2974
-
2975
- return options, context
2976
- end
2977
-
2978
-
2979
- def untabify(str, width=8)
2980
- list = str.split(/\t/)
2981
- last = list.pop
2982
- sb = ''
2983
- list.each do |s|
2984
- column = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length
2985
- n = width - (column % width)
2986
- sb << s << (' ' * n)
2987
- end
2988
- sb << last
2989
- return sb
2990
- end
2991
- #--
2992
- #def untabify(str, width=8)
2993
- # sb = ''
2994
- # str.scan(/(.*?)\t/m) do |s, |
2995
- # len = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length
2996
- # sb << s << (" " * (width - len % width))
2997
- # end
2998
- # return $' ? (sb << $') : str
2999
- #end
3000
- #++
3001
-
3002
-
3003
- def get_classobj(classname, lang, pi)
3004
- classname ||= "E#{lang}"
3005
- base_module = pi ? Erubis::PI : Erubis
3006
- begin
3007
- klass = base_module.const_get(classname)
3008
- rescue NameError
3009
- klass = nil
3010
- end
3011
- unless klass
3012
- if lang
3013
- msg = "-l #{lang}: invalid language name (class #{base_module.name}::#{classname} not found)."
3014
- else
3015
- msg = "-c #{classname}: invalid class name."
3016
- end
3017
- raise CommandOptionError.new(msg)
3018
- end
3019
- return klass
3020
- end
3021
-
3022
- def get_enhancers(enhancer_names)
3023
- return [] unless enhancer_names
3024
- enhancers = []
3025
- shortname = nil
3026
- begin
3027
- enhancer_names.split(/,/).each do |shortname|
3028
- enhancers << Erubis.const_get("#{shortname}Enhancer")
3029
- end
3030
- rescue NameError
3031
- raise CommandOptionError.new("#{shortname}: no such Enhancer (try '-E' to show all enhancers).")
3032
- end
3033
- return enhancers
3034
- end
3035
-
3036
- def load_datafiles(filenames, opts)
3037
- context = Erubis::Context.new
3038
- return hash unless filenames
3039
- filenames.split(/,/).each do |filename|
3040
- filename.strip!
3041
- test(?f, filename) or raise CommandOptionError.new("#{filename}: file not found.")
3042
- if filename =~ /\.ya?ml$/
3043
- if opts.untabify
3044
- ydoc = YAML.load(untabify(File.read(filename)))
3045
- else
3046
- ydoc = YAML.load_file(filename)
3047
- end
3048
- ydoc.is_a?(Hash) or raise CommandOptionError.new("#{filename}: root object is not a mapping.")
3049
- intern_hash_keys(ydoc) if opts.intern
3050
- context.update(ydoc)
3051
- elsif filename =~ /\.rb$/
3052
- str = File.read(filename)
3053
- context2 = Erubis::Context.new
3054
- _instance_eval(context2, str)
3055
- context.update(context2)
3056
- else
3057
- CommandOptionError.new("#{filename}: '*.yaml', '*.yml', or '*.rb' required.")
3058
- end
3059
- end
3060
- return context
3061
- end
3062
-
3063
- def _instance_eval(_context, _str)
3064
- _context.instance_eval(_str)
3065
- end
3066
-
3067
- def parse_context_data(context_str, opts)
3068
- if context_str[0] == ?{
3069
- require 'yaml'
3070
- ydoc = YAML.load(context_str)
3071
- unless ydoc.is_a?(Hash)
3072
- raise CommandOptionError.new("-c: root object is not a mapping.")
3073
- end
3074
- intern_hash_keys(ydoc) if opts.intern
3075
- return ydoc
3076
- else
3077
- context = Erubis::Context.new
3078
- context.instance_eval(context_str, '-c')
3079
- return context
3080
- end
3081
- end
3082
-
3083
- def intern_hash_keys(obj, done={})
3084
- return if done.key?(obj.__id__)
3085
- case obj
3086
- when Hash
3087
- done[obj.__id__] = obj
3088
- obj.keys.each do |key|
3089
- obj[key.intern] = obj.delete(key) if key.is_a?(String)
3090
- end
3091
- obj.values.each do |val|
3092
- intern_hash_keys(val, done) if val.is_a?(Hash) || val.is_a?(Array)
3093
- end
3094
- when Array
3095
- done[obj.__id__] = obj
3096
- obj.each do |val|
3097
- intern_hash_keys(val, done) if val.is_a?(Hash) || val.is_a?(Array)
3098
- end
3099
- end
3100
- end
3101
-
3102
- def check_syntax(filename, src)
3103
- require 'open3'
3104
- stdin, stdout, stderr = Open3.popen3('ruby -wc')
3105
- stdin.write(src)
3106
- stdin.close
3107
- result = stdout.read()
3108
- stdout.close()
3109
- errmsg = stderr.read()
3110
- stderr.close()
3111
- return nil unless errmsg && !errmsg.empty?
3112
- errmsg =~ /\A-:(\d+): /
3113
- linenum, message = $1, $'
3114
- return "#{filename}:#{linenum}: #{message}"
3115
- end
3116
-
3117
- end
3118
-
3119
- end
3120
- #--end of require 'erubis/main'
9
+ require 'erubis/main'
3121
10
 
3122
11
  Erubis::Main.main(ARGV)