erubis 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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)