erubis 1.1.0 → 2.0.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 (116) hide show
  1. data/ChangeLog +45 -18
  2. data/README.txt +80 -0
  3. data/benchmark/erubybench-lib.rb +189 -0
  4. data/benchmark/erubybench.rb +364 -0
  5. data/benchmark/erubybench.rhtml +61 -0
  6. data/benchmark/erubybench.yaml +61 -0
  7. data/bin/erubis +4 -180
  8. data/contrib/erubis +2297 -0
  9. data/contrib/inline-require +151 -0
  10. data/doc-api/classes/Erubis.html +236 -0
  11. data/doc-api/classes/Erubis/ArrayBufferEnhancer.html +175 -0
  12. data/doc-api/classes/Erubis/ArrayBufferEruby.html +120 -0
  13. data/doc-api/classes/Erubis/ArrayEnhancer.html +174 -0
  14. data/doc-api/classes/Erubis/ArrayEruby.html +120 -0
  15. data/doc-api/classes/Erubis/BiPatternEnhancer.html +212 -0
  16. data/doc-api/classes/Erubis/BiPatternEruby.html +120 -0
  17. data/doc-api/classes/Erubis/CommandOptionError.html +113 -0
  18. data/doc-api/classes/Erubis/Context.html +249 -0
  19. data/doc-api/classes/Erubis/Ec.html +399 -0
  20. data/doc-api/classes/Erubis/Ejava.html +366 -0
  21. data/doc-api/classes/Erubis/Ejavascript.html +390 -0
  22. data/doc-api/classes/Erubis/Engine.html +711 -0
  23. data/doc-api/classes/Erubis/Eperl.html +350 -0
  24. data/doc-api/classes/Erubis/Ephp.html +308 -0
  25. data/doc-api/classes/Erubis/ErubisError.html +117 -0
  26. data/doc-api/classes/Erubis/Eruby.html +310 -0
  27. data/doc-api/classes/Erubis/EscapeEnhancer.html +167 -0
  28. data/doc-api/classes/Erubis/EscapedEc.html +120 -0
  29. data/doc-api/classes/Erubis/EscapedEjava.html +120 -0
  30. data/doc-api/classes/Erubis/EscapedEjavascript.html +120 -0
  31. data/doc-api/classes/Erubis/EscapedEperl.html +120 -0
  32. data/doc-api/classes/Erubis/EscapedEphp.html +120 -0
  33. data/doc-api/classes/Erubis/EscapedEruby.html +127 -0
  34. data/doc-api/classes/Erubis/EscapedEscheme.html +120 -0
  35. data/doc-api/classes/Erubis/Escheme.html +389 -0
  36. data/doc-api/classes/Erubis/HeaderFooterEnhancer.html +264 -0
  37. data/doc-api/classes/Erubis/HeaderFooterEruby.html +120 -0
  38. data/doc-api/classes/Erubis/Main.html +318 -0
  39. data/doc-api/classes/Erubis/NoTextEnhancer.html +159 -0
  40. data/doc-api/classes/Erubis/NoTextEruby.html +120 -0
  41. data/doc-api/classes/Erubis/OptimizedEruby.html +445 -0
  42. data/doc-api/classes/Erubis/OptimizedXmlEruby.html +163 -0
  43. data/doc-api/classes/Erubis/PercentLineEnhancer.html +174 -0
  44. data/doc-api/classes/Erubis/PercentLineEruby.html +120 -0
  45. data/doc-api/classes/Erubis/PrintEnabledEnhancer.html +212 -0
  46. data/doc-api/classes/Erubis/PrintEnabledEruby.html +120 -0
  47. data/doc-api/classes/Erubis/PrintOutEnhancer.html +244 -0
  48. data/doc-api/classes/Erubis/PrintOutEruby.html +120 -0
  49. data/doc-api/classes/Erubis/PrintOutSimplifiedEruby.html +121 -0
  50. data/doc-api/classes/Erubis/SimplifiedEruby.html +120 -0
  51. data/doc-api/classes/Erubis/SimplifyEnhancer.html +185 -0
  52. data/doc-api/classes/Erubis/StdoutEnhancer.html +173 -0
  53. data/doc-api/classes/Erubis/StdoutEruby.html +120 -0
  54. data/doc-api/classes/Erubis/StdoutSimplifiedEruby.html +121 -0
  55. data/doc-api/classes/Erubis/StringBufferEnhancer.html +174 -0
  56. data/doc-api/classes/Erubis/StringBufferEruby.html +120 -0
  57. data/doc-api/classes/Erubis/StringIOEruby.html +120 -0
  58. data/doc-api/classes/Erubis/TinyEruby.html +305 -0
  59. data/doc-api/classes/Erubis/XmlEruby.html +130 -0
  60. data/doc-api/classes/Erubis/XmlHelper.html +193 -0
  61. data/doc-api/created.rid +1 -0
  62. data/doc-api/files/__/README_txt.html +214 -0
  63. data/doc-api/files/erubis/engine/ec_rb.html +115 -0
  64. data/doc-api/files/erubis/engine/ejava_rb.html +115 -0
  65. data/doc-api/files/erubis/engine/ejavascript_rb.html +115 -0
  66. data/doc-api/files/erubis/engine/enhanced_rb.html +115 -0
  67. data/doc-api/files/erubis/engine/eperl_rb.html +115 -0
  68. data/doc-api/files/erubis/engine/ephp_rb.html +115 -0
  69. data/doc-api/files/erubis/engine/eruby_rb.html +115 -0
  70. data/doc-api/files/erubis/engine/escheme_rb.html +115 -0
  71. data/doc-api/files/erubis/engine/optimized_rb.html +114 -0
  72. data/doc-api/files/erubis/engine_rb.html +114 -0
  73. data/doc-api/files/erubis/enhancer_rb.html +114 -0
  74. data/doc-api/files/erubis/helper_rb.html +107 -0
  75. data/doc-api/files/erubis/local-setting_rb.html +107 -0
  76. data/doc-api/files/erubis/main_rb.html +125 -0
  77. data/doc-api/files/erubis/tiny_rb.html +107 -0
  78. data/doc-api/files/erubis_rb.html +118 -0
  79. data/doc-api/fr_class_index.html +77 -0
  80. data/doc-api/fr_file_index.html +43 -0
  81. data/doc-api/fr_method_index.html +157 -0
  82. data/doc-api/index.html +24 -0
  83. data/doc-api/rdoc-style.css +208 -0
  84. data/doc/users-guide.html +1507 -375
  85. data/examples/Makefile +53 -0
  86. data/examples/example.ec +24 -0
  87. data/examples/example.ejava +41 -0
  88. data/examples/example.ejavascript +16 -0
  89. data/examples/example.eperl +16 -0
  90. data/examples/example.ephp +17 -0
  91. data/examples/example.eruby +15 -0
  92. data/examples/example.escheme +26 -0
  93. data/lib/erubis.rb +37 -269
  94. data/lib/erubis/engine.rb +260 -0
  95. data/lib/erubis/engine/ec.rb +106 -0
  96. data/lib/erubis/engine/ejava.rb +101 -0
  97. data/lib/erubis/engine/ejavascript.rb +104 -0
  98. data/lib/erubis/engine/enhanced.rb +102 -0
  99. data/lib/erubis/engine/eperl.rb +83 -0
  100. data/lib/erubis/engine/ephp.rb +84 -0
  101. data/lib/erubis/engine/eruby.rb +91 -0
  102. data/lib/erubis/engine/escheme.rb +96 -0
  103. data/lib/erubis/engine/optimized.rb +114 -0
  104. data/lib/erubis/enhancer.rb +487 -0
  105. data/lib/erubis/helper.rb +53 -0
  106. data/lib/erubis/local-setting.rb +10 -0
  107. data/lib/erubis/main.rb +368 -0
  108. data/lib/erubis/tiny.rb +65 -0
  109. data/test/assert-text-equal.rb +45 -0
  110. data/test/test-bin.rb +222 -45
  111. data/test/test-engines.rb +343 -0
  112. data/test/test-erubis.rb +836 -501
  113. data/test/test.rb +27 -0
  114. data/test/testutil.rb +86 -0
  115. metadata +131 -8
  116. data/README +0 -50
@@ -14,7 +14,7 @@
14
14
 
15
15
  <div align="left"><h1>Erubis Users' Guide</h1></div>
16
16
  <div align="left">
17
- last update: $Date: 2006-02-01 19:54:24 +0900 (Wed, 01 Feb 2006) $<br>
17
+ last update: $Date: 2006-05-20 08:57:39 +0900 (Sat, 20 May 2006) $<br>
18
18
  </div>
19
19
 
20
20
  <a name="preface"></a>
@@ -23,17 +23,21 @@
23
23
  It has the following features.
24
24
  </p>
25
25
  <ul type="disc">
26
- <li>Auto sanitizing support
26
+ <li>Very fast, almost three times faster than ERB and even as fast as eruby (implemented in C)
27
+ </li>
28
+ <li>Auto escaping support
27
29
  </li>
28
30
  <li>Auto trimming spaces around '&lt;% %&gt;'
29
31
  </li>
30
32
  <li>Embedded pattern changeable (default '&lt;% %&gt;')
31
33
  </li>
32
- <li>Context object available
34
+ <li>Support multi-language (Ruby/PHP/C/Java/Scheme/Perl/Javascript)
35
+ </li>
36
+ <li>Context object available and easy to combine eRuby template with YAML datafile
33
37
  </li>
34
38
  <li>Print statement available
35
39
  </li>
36
- <li>Easy to expand in subclass
40
+ <li>Easy to extend in subclass
37
41
  </li>
38
42
  </ul>
39
43
  <p>Erubis is implemented in pure Ruby. It requires Ruby 1.8 or higher.
@@ -55,17 +59,69 @@ It has the following features.
55
59
  </li>
56
60
  <li><a href="#tut-trim">Trimming Spaces</a>
57
61
  </li>
58
- <li><a href="#tut-xml">Auto Sanitizing</a>
62
+ <li><a href="#tut-escape">Escape</a>
59
63
  </li>
60
64
  <li><a href="#tut-pattern">Embedded Pattern</a>
61
65
  </li>
62
66
  <li><a href="#tut-context">Context Object</a>
63
67
  </li>
64
- <li><a href="#tut-fast">Faster Eruby</a>
68
+ <li><a href="#tut-datafile">Context Data File</a>
69
+ </li>
70
+ <li><a href="#tut-preamble">Preamble and Postamble</a>
71
+ </li>
72
+ </ul>
73
+ </li>
74
+ <li><a href="#enhancer">Enhancer</a>
75
+ <ul>
76
+ <li><a href="#escape-enhancer">EscapeEnhancer</a>
77
+ </li>
78
+ <li><a href="#stdout-enhancer">StdoutEnhancer</a>
79
+ </li>
80
+ <li><a href="#printout-enhancer">PrintOutEnhancer</a>
81
+ </li>
82
+ <li><a href="#printenabled-enhancer">PrintEnabledEnhancer</a>
83
+ </li>
84
+ <li><a href="#array-enhancer">ArrayEnhancer</a>
85
+ </li>
86
+ <li><a href="#arraybuffer-enhancer">ArrayBufferEnhancer</a>
87
+ </li>
88
+ <li><a href="#stringbuffer-enhancer">StringBufferEnhancer</a>
89
+ </li>
90
+ <li><a href="#notext-enhancer">NoTextEnhancer</a>
91
+ </li>
92
+ <li><a href="#simplify-enhancer">SimplifyEnhancer</a>
65
93
  </li>
66
- <li><a href="#tut-stdout">Stdout Eruby</a>
94
+ <li><a href="#bipattern-enhancer">BiPatternEnhancer</a>
67
95
  </li>
68
- <li><a href="#tut-print">Print Avairable Eruby</a>
96
+ <li><a href="#percentline-enhancer">PercentLineEnhancer</a>
97
+ </li>
98
+ <li><a href="#headerfooter-enhancer">HeaderFooterEnhancer</a>
99
+ </li>
100
+ </ul>
101
+ </li>
102
+ <li><a href="#lang">Multi-Language</a>
103
+ <ul>
104
+ <li><a href="#lang-php">PHP</a>
105
+ </li>
106
+ <li><a href="#lang-c">C</a>
107
+ </li>
108
+ <li><a href="#lang-java">Java</a>
109
+ </li>
110
+ <li><a href="#lang-scheme">Scheme</a>
111
+ </li>
112
+ <li><a href="#lang-perl">Perl</a>
113
+ </li>
114
+ <li><a href="#lang-javascript">JavaScript</a>
115
+ </li>
116
+ </ul>
117
+ </li>
118
+ <li><a href="#topics">Other Topics</a>
119
+ <ul>
120
+ <li><a href="#topics-tinyeruby">TinyEruby class</a>
121
+ </li>
122
+ <li><a href="#topics-php">NoTextEnhancer in PHP</a>
123
+ </li>
124
+ <li><a href="#topics-benchmark">Benchmark</a>
69
125
  </li>
70
126
  </ul>
71
127
  </li>
@@ -75,6 +131,8 @@ It has the following features.
75
131
  </li>
76
132
  <li><a href="#command-options">Options</a>
77
133
  </li>
134
+ <li><a href="#command-props">Properties</a>
135
+ </li>
78
136
  </ul>
79
137
  </li>
80
138
  </ul>
@@ -93,25 +151,21 @@ It has the following features.
93
151
  </li>
94
152
  </ul>
95
153
  <ul type="disc">
96
- <li>Or if you can be root user, download erubis-X.X.X.tar.bz2 and install by setup.rb.
97
- <pre class="terminal">$ tar xjf erubis-X.X.X.tar.bz2
98
- $ cd erubis_X.X.X/
99
- $ ruby setup.rb
100
- </pre>
101
- </li>
102
- </ul>
103
- <ul type="disc">
104
- <li>Else you should copy 'lib/erubis.rb' and 'bin/erubis' into proper directory manually.
105
- <pre class="terminal">$ tar xjf erubis-X.X.X.tar.bz2
154
+ <li>Else install <a href="http://rubyforge.org/projects/erubis/">abstract</a> at first,
155
+ and download erubis_X.X.X.tar.bz2 and install it by setup.rb.
156
+ <pre class="terminal">$ tar xjf abstract_X.X.X.tar.bz2
157
+ $ cd abstract_X.X.X/
158
+ $ sudo ruby setup.rb
159
+ $ cd ..
160
+ $ tar xjf erubis_X.X.X.tar.bz2
106
161
  $ cd erubis_X.X.X/
107
- $ cp lib/erubis.rb /usr/local/lib/ruby/site_ruby/1.8
108
- $ cp bin/erubis /usr/local/bin
162
+ $ sudo ruby setup.rb
109
163
  </pre>
110
164
  </li>
111
165
  </ul>
112
166
  <ul type="disc">
113
- <li>(Optional) 'contrib/inline-require' enables you to merge 'lib/erubis.rb' into 'bin/erubis'.
114
- <pre class="terminal">$ tar xjf erubis-X.X.X.tar.bz2
167
+ <li>(Optional) 'contrib/inline-require' enables you to merge 'lib/**/*.rb' into 'bin/erubis'.
168
+ <pre class="terminal">$ tar xjf erubis_X.X.X.tar.bz2
115
169
  $ cd erubis_X.X.X/
116
170
  $ unset RUBYLIB
117
171
  $ contrib/inline-require -I lib bin/erubis &gt; contrib/erubis
@@ -125,16 +179,14 @@ $ contrib/inline-require -I lib bin/erubis &gt; contrib/erubis
125
179
  <h2 class="section1">Tutorial</h2>
126
180
  <a name="tut-basic"></a>
127
181
  <h3 class="section2">Basic Example</h3>
128
- <p>Here is a most basic example of Erubis.
182
+ <p>Here is a basic example of Erubis.
129
183
  </p>
130
184
  <a name="example1.eruby"></a>
131
185
  <div class="program_caption">
132
186
  example1.eruby</div>
133
187
  <pre class="program">&lt;ul&gt;
134
188
  <b>&lt;% for item in list %&gt;</b>
135
- &lt;li&gt;
136
- <b>&lt;%= item %&gt;</b>
137
- &lt;/li&gt;
189
+ &lt;li&gt;<b>&lt;%= item %&gt;</b>&lt;/li&gt;
138
190
  <b>&lt;% end %&gt;</b>
139
191
  <b>&lt;%# here is ignored because starting with '#' %&gt;</b>
140
192
  &lt;/ul&gt;
@@ -142,95 +194,126 @@ example1.eruby</div>
142
194
  <a name="example1.rb"></a>
143
195
  <div class="program_caption">
144
196
  example1.rb</div>
145
- <pre class="program">## create Eruby object
146
- require 'erubis'
197
+ <pre class="program">require 'erubis'
147
198
  input = File.read('example1.eruby')
148
- eruby = <b>Erubis::Eruby.new(input)</b>
199
+ eruby = <b>Erubis::Eruby.new(input)</b> # create Eruby object
149
200
 
150
- ## print script source
151
- puts "--- script source ---"
152
- puts <b>eruby.src</b>
201
+ puts "---------- script source ---"
202
+ puts <b>eruby.src</b> # print script source
153
203
 
154
- ## get result
155
- puts "--- result ---"
204
+ puts "---------- result ----------"
156
205
  list = ['aaa', 'bbb', 'ccc']
157
- puts <b>eruby.result(binding())</b>
206
+ puts <b>eruby.result(binding())</b> # get result
158
207
  </pre>
159
208
  <div class="terminal_caption">
160
209
  output</div>
161
210
  <pre class="terminal">$ ruby example1.rb
162
- --- script source ---
163
- _out = ''; _out &lt;&lt; "&lt;ul&gt;\n"
164
- for item in list
165
- _out &lt;&lt; " &lt;li&gt;\n"
166
- _out &lt;&lt; " "; _out &lt;&lt; ( item ).to_s; _out &lt;&lt; "\n"
167
- _out &lt;&lt; " &lt;/li&gt;\n"
168
- end
169
-
170
- _out &lt;&lt; "&lt;/ul&gt;\n"
171
- _out
172
- --- result ---
211
+ ---------- script source ---
212
+ _buf = []; _buf &lt;&lt; '&lt;ul&gt;
213
+ '; for item in list
214
+ _buf &lt;&lt; ' &lt;li&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/li&gt;
215
+ '; end
216
+
217
+ _buf &lt;&lt; '&lt;/ul&gt;
218
+ ';
219
+ _buf.join
220
+ ---------- result ----------
173
221
  &lt;ul&gt;
174
- &lt;li&gt;
175
- aaa
176
- &lt;/li&gt;
177
- &lt;li&gt;
178
- bbb
179
- &lt;/li&gt;
180
- &lt;li&gt;
181
- ccc
182
- &lt;/li&gt;
222
+ &lt;li&gt;aaa&lt;/li&gt;
223
+ &lt;li&gt;bbb&lt;/li&gt;
224
+ &lt;li&gt;ccc&lt;/li&gt;
183
225
  &lt;/ul&gt;
184
226
  </pre>
227
+ <p>Erubis has command 'erubis'. Command-line option '-x' shows the compiled source code of eRuby script.
228
+ </p>
229
+ <div class="terminal_caption">
230
+ example of command-line option '-x'</div>
231
+ <pre class="terminal">$ erubis <b>-x</b> example1.eruby
232
+ _buf = []; _buf &lt;&lt; '&lt;ul&gt;
233
+ '; for item in list
234
+ _buf &lt;&lt; ' &lt;li&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/li&gt;
235
+ '; end
236
+
237
+ _buf &lt;&lt; '&lt;/ul&gt;
238
+ ';
239
+ _buf.join
240
+ </pre>
185
241
  <br>
186
242
 
187
243
 
188
244
  <a name="tut-trim"></a>
189
245
  <h3 class="section2">Trimming Spaces</h3>
190
246
  <p>Erubis deletes spaces around '&lt;% %&gt;' automatically, while it leaves spaces around '&lt;%= %&gt;'.
191
- If you want leave spaces around '&lt;% %&gt;', add <code>:trim=&gt;false</code> option to Erubis::Eruby.new().
192
247
  </p>
193
248
  <a name="example2.eruby"></a>
194
249
  <div class="program_caption">
195
250
  example2.eruby</div>
196
251
  <pre class="program">&lt;ul&gt;
197
- &lt;% for item in list %&gt;
252
+ &lt;% for item in list %&gt; # trimmed
198
253
  &lt;li&gt;
199
- &lt;%= item %&gt;
254
+ &lt;%= item %&gt; # not trimmed
200
255
  &lt;/li&gt;
201
- &lt;% end %&gt;
256
+ &lt;% end %&gt; # trimmed
202
257
  &lt;/ul&gt;
203
258
  </pre>
259
+ <div class="terminal_caption">
260
+ compiled source code</div>
261
+ <pre class="terminal">$ erubis -x example2.eruby
262
+ _buf = []; _buf &lt;&lt; '&lt;ul&gt;
263
+ '; for item in list
264
+ _buf &lt;&lt; ' &lt;li&gt;
265
+ '; _buf &lt;&lt; ' '; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '
266
+ '; _buf &lt;&lt; ' &lt;/li&gt;
267
+ '; end
268
+ _buf &lt;&lt; '&lt;/ul&gt;
269
+ ';
270
+ _buf.join
271
+ </pre>
272
+ <p>If you want leave spaces around '&lt;% %&gt;', add command-line option '-T'.
273
+ </p>
274
+ <div class="terminal_caption">
275
+ compiled source code with command-line option '-T'</div>
276
+ <pre class="terminal">$ erubis -x <b>-T</b> example2.eruby
277
+ _buf = []; _buf &lt;&lt; '&lt;ul&gt;
278
+ '; _buf &lt;&lt; ' '; for item in list ; _buf &lt;&lt; '
279
+ '; _buf &lt;&lt; ' &lt;li&gt;
280
+ '; _buf &lt;&lt; ' '; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '
281
+ '; _buf &lt;&lt; ' &lt;/li&gt;
282
+ '; _buf &lt;&lt; ' '; end ; _buf &lt;&lt; '
283
+ '; _buf &lt;&lt; '&lt;/ul&gt;
284
+ ';
285
+ _buf.join
286
+ </pre>
287
+ <p>Or add option <code>:trim=&gt;false</code> to Erubis::Eruby.new().
288
+ </p>
204
289
  <a name="example2.rb"></a>
205
290
  <div class="program_caption">
206
291
  example2.rb</div>
207
- <pre class="program">## create Eruby object
208
- require 'erubis'
292
+ <pre class="program">require 'erubis'
209
293
  input = File.read('example2.eruby')
210
294
  eruby = Erubis::Eruby.new(input<b>, :trim=&gt;false</b>)
211
295
 
212
- ## print script source
213
- puts "--- script source ---"
214
- puts eruby.src
296
+ puts "---------- script source ---"
297
+ puts eruby.src # print script source
215
298
 
216
- ## get result
217
- puts "--- result ---"
299
+ puts "---------- result ----------"
218
300
  list = ['aaa', 'bbb', 'ccc']
219
- puts eruby.result(binding())
301
+ puts eruby.result(binding()) # get result
220
302
  </pre>
221
303
  <div class="terminal_caption">
222
304
  output</div>
223
305
  <pre class="terminal">$ ruby example2.rb
224
- --- script source ---
225
- _out = ''; _out &lt;&lt; "&lt;ul&gt;\n"
226
- <b>_out &lt;&lt; " ";</b> for item in list <b>; _out &lt;&lt; "\n"</b>
227
- _out &lt;&lt; " &lt;li&gt;\n"
228
- _out &lt;&lt; " "; _out &lt;&lt; ( item ).to_s; _out &lt;&lt; "\n"
229
- _out &lt;&lt; " &lt;/li&gt;\n"
230
- <b>_out &lt;&lt; " ";</b> end <b>; _out &lt;&lt; "\n"</b>
231
- _out &lt;&lt; "&lt;/ul&gt;\n"
232
- _out
233
- --- result ---
306
+ ---------- script source ---
307
+ _buf = []; _buf &lt;&lt; '&lt;ul&gt;
308
+ '; _buf &lt;&lt; ' '; for item in list ; _buf &lt;&lt; '
309
+ '; _buf &lt;&lt; ' &lt;li&gt;
310
+ '; _buf &lt;&lt; ' '; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '
311
+ '; _buf &lt;&lt; ' &lt;/li&gt;
312
+ '; _buf &lt;&lt; ' '; end ; _buf &lt;&lt; '
313
+ '; _buf &lt;&lt; '&lt;/ul&gt;
314
+ ';
315
+ _buf.join
316
+ ---------- result ----------
234
317
  &lt;ul&gt;
235
318
 
236
319
  &lt;li&gt;
@@ -250,134 +333,164 @@ _out
250
333
  <br>
251
334
 
252
335
 
253
- <a name="tut-xml"></a>
254
- <h3 class="section2">Auto Sanitizing</h3>
255
- <p>If you use Erubis::XmlEruby instead of Erubis::Eruby, output is sanitized automatically.
256
- </p>
257
- <p>Erubis::XmlEruby acts the following:
336
+ <a name="tut-escape"></a>
337
+ <h3 class="section2">Escape</h3>
338
+ <p>Erubis have ability to escape (sanitize) expression.
339
+ Erubis::Eruby class act as the following:
258
340
  </p>
259
341
  <ul type="disc">
260
- <li><code>&lt;%= <i>expr</i> %&gt;</code> will be sanitized.
342
+ <li><code>&lt;%= <i>expr</i> %&gt;</code> - not escaped.
261
343
  </li>
262
- <li><code>&lt;%== <i>expr</i> %&gt;</code> will be out as it is.
344
+ <li><code>&lt;%== <i>expr</i> %&gt;</code> - escaped.
263
345
  </li>
264
- <li><code>&lt;%=== <i>expr</i> %&gt;</code> will be out to $stderr.
346
+ <li><code>&lt;%=== <i>expr</i> %&gt;</code> - out to $stderr.
265
347
  </li>
266
- <li><code>&lt;%==== <i>expr</i> %&gt;</code> will be ignored.
348
+ <li><code>&lt;%==== <i>expr</i> %&gt;</code> - ignored.
267
349
  </li>
268
350
  </ul>
351
+ <p>Erubis::EscapedEruby<sup>(<a href="#fnref:1" name="fnlink:1">*1</a>)</sup> class handle '&lt;%= %&gt;' as escaped and '&lt;%== %&gt;' as not escaped.
352
+ It means that using Erubis::EscapedEruby you can escape expression by default.
353
+ Also Erubis::XmlEruby class (which is equivalent to Erubis::EscapedEruby) is provided for compatibility with Erubis 1.1.
354
+ </p>
269
355
  <a name="example3.eruby"></a>
270
356
  <div class="program_caption">
271
357
  example3.eruby</div>
272
- <pre class="program">&lt;ul&gt;
273
- &lt;% for item in list %&gt;
274
- &lt;li&gt;<b>&lt;%=</b> item <b>%&gt;</b>&lt;/li&gt;
275
- &lt;li&gt;<b>&lt;%==</b> item <b>%&gt;</b>&lt;/li&gt;
276
- &lt;li&gt;<b>&lt;%===</b> item <b>%&gt;</b>&lt;/li&gt;
358
+ <pre class="program">&lt;% for item in list %&gt;
359
+ &lt;p&gt;<b>&lt;%=</b> item <b>%&gt;</b>&lt;/p&gt;
360
+ &lt;p&gt;<b>&lt;%==</b> item <b>%&gt;</b>&lt;/p&gt;
361
+ &lt;p&gt;<b>&lt;%===</b> item <b>%&gt;</b>&lt;/p&gt;
277
362
 
278
- &lt;% end %&gt;
279
- &lt;/ul&gt;
363
+ &lt;% end %&gt;
280
364
  </pre>
281
365
  <a name="example3.rb"></a>
282
366
  <div class="program_caption">
283
367
  example3.rb</div>
284
- <pre class="program">## create Eruby object
285
- require 'erubis'
368
+ <pre class="program">require 'erubis'
286
369
  input = File.read('example3.eruby')
287
- eruby = Erubis::<b>XmlEruby</b>.new(input)
370
+ eruby = Erubis::<b>EscapedEruby</b>.new(input) # or Erubis::XmlEruby
288
371
 
289
- ## print script source
290
- puts "--- script source ---"
291
- puts eruby.src
372
+ puts "---------- script source ---"
373
+ puts eruby.src # print script source
292
374
 
293
- ## get result
294
- puts "--- result ---"
375
+ puts "---------- result ----------"
295
376
  <b>list = ['&lt;aaa&gt;', 'b&amp;b', '"ccc"']</b>
296
- puts eruby.result(binding())
377
+ puts eruby.result(binding()) # get result
297
378
  </pre>
298
379
  <div class="terminal_caption">
299
380
  output</div>
300
381
  <pre class="terminal">$ ruby example3.rb 2&gt; stderr.log
301
- --- script source ---
302
- _out = ''; _out &lt;&lt; "&lt;ul&gt;\n"
303
- for item in list
304
- _out &lt;&lt; " &lt;li&gt;"; <b>_out &lt;&lt; Erubis::XmlEruby.escape( item )</b>; _out &lt;&lt; "&lt;/li&gt;\n"
305
- _out &lt;&lt; " &lt;li&gt;"; _out &lt;&lt; ( item ).to_s; _out &lt;&lt; "&lt;/li&gt;\n"
306
- _out &lt;&lt; " &lt;li&gt;"; <b>$stderr.puts("** erubis: item = #{(item).inspect}")</b>; _out &lt;&lt; "&lt;/li&gt;\n"
307
- _out &lt;&lt; "\n"
308
- end
309
- _out &lt;&lt; "&lt;/ul&gt;\n"
310
- _out
311
- --- result ---
312
- &lt;ul&gt;
313
- &lt;li&gt;<b>&amp;lt;aaa&amp;gt;</b>&lt;/li&gt;
314
- &lt;li&gt;&lt;aaa&gt;&lt;/li&gt;
315
- &lt;li&gt;&lt;/li&gt;
382
+ ---------- script source ---
383
+ _buf = []; for item in list
384
+ _buf &lt;&lt; ' &lt;p&gt;'; <b>_buf &lt;&lt; Erubis::XmlHelper.escape_xml( item );</b> _buf &lt;&lt; '&lt;/p&gt;
385
+ &lt;p&gt;'; <b>_buf &lt;&lt; ( item ).to_s;</b> _buf &lt;&lt; '&lt;/p&gt;
386
+ &lt;p&gt;'; <b>$stderr.puts("*** debug: item=#{(item).inspect}");</b> _buf &lt;&lt; '&lt;/p&gt;
316
387
 
317
- &lt;li&gt;<b>b&amp;amp;b</b>&lt;/li&gt;
318
- &lt;li&gt;b&amp;b&lt;/li&gt;
319
- &lt;li&gt;&lt;/li&gt;
388
+ '; end
389
+ _buf.join
390
+ ---------- result ----------
391
+ &lt;p&gt;&amp;lt;aaa&amp;gt;&lt;/p&gt;
392
+ &lt;p&gt;&lt;aaa&gt;&lt;/p&gt;
393
+ &lt;p&gt;&lt;/p&gt;
320
394
 
321
- &lt;li&gt;<b>&amp;quot;ccc&amp;quot;</b>&lt;/li&gt;
322
- &lt;li&gt;"ccc"&lt;/li&gt;
323
- &lt;li&gt;&lt;/li&gt;
395
+ &lt;p&gt;b&amp;amp;b&lt;/p&gt;
396
+ &lt;p&gt;b&amp;b&lt;/p&gt;
397
+ &lt;p&gt;&lt;/p&gt;
398
+
399
+ &lt;p&gt;&amp;quot;ccc&amp;quot;&lt;/p&gt;
400
+ &lt;p&gt;"ccc"&lt;/p&gt;
401
+ &lt;p&gt;&lt;/p&gt;
324
402
 
325
- &lt;/ul&gt;
326
403
  $ cat stderr.log
327
- ** erubis: item = "&lt;aaa&gt;"
328
- ** erubis: item = "b&amp;b"
329
- ** erubis: item = "\"ccc\""
404
+ *** debug: item="&lt;aaa&gt;"
405
+ *** debug: item="b&amp;b"
406
+ *** debug: item="\"ccc\""
407
+ </pre>
408
+ <p>The command-line option '-e'<sup>(<a href="#fnref:2" name="fnlink:2">*2</a>)</sup> will do the same action as Erubis::EscapedEruby.
409
+ This option is available for any language.
410
+ </p>
411
+ <pre class="terminal">$ erubis -l ruby <b>-e</b> example3.eruby
412
+ _buf = []; for item in list
413
+ _buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; Erubis::XmlHelper.escape_xml( item ); _buf &lt;&lt; '&lt;/p&gt;
414
+ &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
415
+ &lt;p&gt;'; $stderr.puts("*** debug: item=#{(item).inspect}"); _buf &lt;&lt; '&lt;/p&gt;
416
+
417
+ '; end
418
+ _buf.join
330
419
  </pre>
420
+ <p>Escaping function (default 'Erubis::XmlHelper.escape_xml()') can be changed by command-line property '--escape=xxx' or by overriding Erubis::Eruby#escaped_expr() in subclass.
421
+ </p>
422
+ <div class="program_caption">
423
+ example to override Erubis::Eruby#escaped_expr()</div>
424
+ <pre class="program">class CGIEruby &lt; Erubis::Eruby
425
+ def <b>escaped_expr(code)</b>
426
+ return "CGI.escapeHTML((#{code.strip}).to_s)"
427
+ #return "h(#{code.strip})"
428
+ end
429
+ end
430
+
431
+ class LatexEruby &lt; Erubi::Eruby
432
+ def <b>escaped_expr(code)</b>
433
+ return "(#{code}).gsub(/[%\\]/,'\\\\\&amp;')"
434
+ end
435
+ end
436
+ </pre>
437
+ <div class="footnote">
438
+ <dl compact>
439
+ <dt>(<a name="fnref:1" href="#fnlink:1">*1</a>)</dt>
440
+ <dd>Erubis::EscapedEruby class includes Erubis::EscapeEnhancer which swtches the action of '&lt;%= %&gt;' and '&lt;%== %&gt;'.</dd>
441
+ <dt>(<a name="fnref:2" href="#fnlink:2">*2</a>)</dt>
442
+ <dd>Command-line option '-e' is equivarent to '-E Escape'.</dd>
443
+ </dl>
444
+ </div>
331
445
  <br>
332
446
 
333
447
 
334
448
  <a name="tut-pattern"></a>
335
449
  <h3 class="section2">Embedded Pattern</h3>
336
- <p>You can change embedded pattern '<code>&lt;% %&gt;</code>' to another.
450
+ <p>You can change embedded pattern '<code>&lt;% %&gt;</code>' to another with command-line option '-p' or option '<code>:pattern=&gt;...</code>' of Erubis::Eruby.new().
337
451
  </p>
338
452
  <a name="example4.eruby"></a>
339
453
  <div class="program_caption">
340
454
  example4.eruby</div>
341
- <pre class="program">&lt;ul&gt;
342
- <b>&lt;!--%</b> for item in list <b>%--&gt;</b>
343
- &lt;li&gt;<b>&lt;!--%=</b> item <b>%--&gt;</b>&lt;/li&gt;
344
- <b>&lt;!--%</b> end <b>%--&gt;</b>
345
- &lt;/ul&gt;
455
+ <pre class="program"><b>&lt;!--%</b> for item in list <b>%--&gt;</b>
456
+ &lt;p&gt;<b>&lt;!--%=</b> item <b>%--&gt;</b>&lt;/p&gt;
457
+ <b>&lt;!--%</b> end <b>%--&gt;</b>
458
+ </pre>
459
+ <div class="terminal_caption">
460
+ compiled source code with command-line option '-p'</div>
461
+ <pre class="terminal">$ erubis -x <b>-p '&lt;!--% %--&gt;'</b> example4.eruby
462
+ _buf = []; for item in list
463
+ _buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
464
+ '; end
465
+ _buf.join
346
466
  </pre>
347
467
  <a name="example4.rb"></a>
348
468
  <div class="program_caption">
349
469
  example4.rb</div>
350
- <pre class="program">## create Eruby object
351
- require 'erubis'
470
+ <pre class="program">require 'erubis'
352
471
  input = File.read('example4.eruby')
353
472
  eruby = Erubis::Eruby.new(input<b>, :pattern=&gt;'&lt;!--% %--&gt;'</b>)
354
473
  # or '&lt;(?:!--)?% %(?:--)?&gt;'
355
474
 
356
- ## print script source
357
- puts "--- script source ---"
358
- puts eruby.src
475
+ puts "---------- script source ---"
476
+ puts eruby.src # print script source
359
477
 
360
- ## get result
361
- puts "--- result ---"
478
+ puts "---------- result ----------"
362
479
  list = ['aaa', 'bbb', 'ccc']
363
- puts eruby.result(binding())
480
+ puts eruby.result(binding()) # get result
364
481
  </pre>
365
482
  <div class="terminal_caption">
366
483
  output</div>
367
484
  <pre class="terminal">$ ruby example4.rb
368
- --- script source ---
369
- _out = ''; _out &lt;&lt; "&lt;ul&gt;\n"
370
- for item in list
371
- _out &lt;&lt; " &lt;li&gt;"; _out &lt;&lt; ( item ).to_s; _out &lt;&lt; "&lt;/li&gt;\n"
372
- end
373
- _out &lt;&lt; "&lt;/ul&gt;\n"
374
- _out
375
- --- result ---
376
- &lt;ul&gt;
377
- &lt;li&gt;aaa&lt;/li&gt;
378
- &lt;li&gt;bbb&lt;/li&gt;
379
- &lt;li&gt;ccc&lt;/li&gt;
380
- &lt;/ul&gt;
485
+ ---------- script source ---
486
+ _buf = []; for item in list
487
+ _buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
488
+ '; end
489
+ _buf.join
490
+ ---------- result ----------
491
+ &lt;p&gt;aaa&lt;/p&gt;
492
+ &lt;p&gt;bbb&lt;/p&gt;
493
+ &lt;p&gt;ccc&lt;/p&gt;
381
494
  </pre>
382
495
  <p>It is able to specify regular expression with :pattern option.
383
496
  Notice that you must use '<code>(?: )</code>' instead of '<code>( )</code>' for grouping.
@@ -390,16 +503,16 @@ For example, '<code>&lt;(!--)?% %(--)?&gt;</code>' will not work while '<code>&l
390
503
  <h3 class="section2">Context Object</h3>
391
504
  <p>Context object is a set of data which are used in eRuby script.
392
505
  Using context object makes clear which data to be used.
506
+ In Erubis, Hash object and Erubis::Context object are available as context object.
393
507
  </p>
394
- <p>In Erubis, Hash object is used as context object.
395
- Hash key means variable name and it can be string or symbol.
508
+ <p>Context data can be accessible via isntance variables in eRuby script.
396
509
  </p>
397
510
  <a name="example5.eruby"></a>
398
511
  <div class="program_caption">
399
512
  example5.eruby</div>
400
- <pre class="program">&lt;span&gt;&lt;%= val %&gt;&lt;/span&gt;
513
+ <pre class="program">&lt;span&gt;&lt;%= <b>@val</b> %&gt;&lt;/span&gt;
401
514
  &lt;ul&gt;
402
- &lt;% for item in list %&gt;
515
+ &lt;% for item in <b>@list</b> %&gt;
403
516
  &lt;li&gt;&lt;%= item %&gt;&lt;/li&gt;
404
517
  &lt;% end %&gt;
405
518
  &lt;/ul&gt;
@@ -407,25 +520,26 @@ example5.eruby</div>
407
520
  <a name="example5.rb"></a>
408
521
  <div class="program_caption">
409
522
  example5.rb</div>
410
- <pre class="program">## create Eruby object
411
- require 'erubis'
523
+ <pre class="program">require 'erubis'
412
524
  input = File.read('example5.eruby')
413
- eruby = Erubis::Eruby.new(input)
525
+ eruby = Erubis::Eruby.new(input) # create Eruby object
414
526
 
415
527
  ## create context object
416
528
  ## (key means var name, which may be string or symbol.)
417
- <b>context = {}</b>
418
- <b>context[:val] = 'Erubis Example'</b>
419
- <b>context['list'] = ['aaa', 'bbb', 'ccc']</b>
529
+ <b>context = {
530
+ :val =&gt; 'Erubis Example',
531
+ 'list' =&gt; ['aaa', 'bbb', 'ccc'],
532
+ }</b>
533
+ # or
534
+ # context = Erubis::Context.new()
535
+ # context['val'] = 'Erubis Example'
536
+ # context[:list] = ['aaa', 'bbb', 'ccc'],
420
537
 
421
- ## get result
422
- puts "--- result ---"
423
- puts <b>eruby.evaluate(context)</b>
538
+ puts <b>eruby.evaluate(context)</b> # get result
424
539
  </pre>
425
540
  <div class="terminal_caption">
426
541
  output</div>
427
542
  <pre class="terminal">$ ruby example5.rb
428
- --- result ---
429
543
  &lt;span&gt;Erubis Example&lt;/span&gt;
430
544
  &lt;ul&gt;
431
545
  &lt;li&gt;aaa&lt;/li&gt;
@@ -433,13 +547,73 @@ output</div>
433
547
  &lt;li&gt;ccc&lt;/li&gt;
434
548
  &lt;/ul&gt;
435
549
  </pre>
436
- <p>It is very useful to import YAML document data into context object.
550
+ <p>The difference between Erubis#result(binding) and Erubis#evaluate(context) is that the former invokes 'eval @src, binding' and the latter invokes 'context.instance_eval @src'.
551
+ This means that data is passed into eRuby script via local variable when Eruby::binding() is called, or instance variable when Eruby::evaluate() is called.
552
+ </p>
553
+ <p>Here is the definition of Erubis#result() and Erubis#evaluate().
437
554
  </p>
438
- <a name="example6.yaml"></a>
439
555
  <div class="program_caption">
440
- example6.yaml</div>
441
- <pre class="program">title: Users List
442
- users:
556
+ definition of result(binding) and evaluate(context)</div>
557
+ <pre class="program">def result(_binding)
558
+ if _binding.is_a?(Hash)
559
+ # load hash data as local variable
560
+ _h = _binding
561
+ eval _h.keys.inject("") {|s,k| s &lt;&lt; "#{k} = _h[#{k.inspect}];"}
562
+ _binding = binding()
563
+ end
564
+ return <b>eval(@src, _binding)</b>
565
+ end
566
+
567
+ def evaluate(context)
568
+ if context.is_a?(Hash)
569
+ # convert hash object to Context object
570
+ hash = context
571
+ context = Erubis::Context.new
572
+ hash.each { |key, val| context[key] = val }
573
+ end
574
+ return <b>context.instance_eval(@src)</b>
575
+ end
576
+ </pre>
577
+ <p>instance_eval() is defined at Object class so it is able to use any object as a context object as well as Hash or Erubis::Context.
578
+ </p>
579
+ <a name="example6.rb"></a>
580
+ <div class="program_caption">
581
+ example6.rb</div>
582
+ <pre class="program">class MyData
583
+ attr_accessor :val, :list
584
+ end
585
+
586
+ ## any object can be a context object
587
+ <b>mydata = MyData.new</b>
588
+ <b>mydata.val = 'Erubis Example'</b>
589
+ <b>mydata.list = ['aaa', 'bbb', 'ccc']</b>
590
+
591
+ require 'erubis'
592
+ eruby = Erubis::Eruby.new(File.read('example5.eruby'))
593
+ puts eruby.evaluate(<b>mydata</b>)
594
+ </pre>
595
+ <div class="terminal_caption">
596
+ output</div>
597
+ <pre class="terminal">$ ruby example6.rb
598
+ &lt;span&gt;Erubis Example&lt;/span&gt;
599
+ &lt;ul&gt;
600
+ &lt;li&gt;aaa&lt;/li&gt;
601
+ &lt;li&gt;bbb&lt;/li&gt;
602
+ &lt;li&gt;ccc&lt;/li&gt;
603
+ &lt;/ul&gt;
604
+ </pre>
605
+ <br>
606
+
607
+
608
+ <a name="tut-datafile"></a>
609
+ <h3 class="section2">Context Data File</h3>
610
+ <p>It is very useful to import YAML document data into Hash context object.
611
+ </p>
612
+ <a name="example7.yaml"></a>
613
+ <div class="program_caption">
614
+ example7.yaml</div>
615
+ <pre class="program"><b>title:</b> Users List
616
+ <b>users:</b>
443
617
  - name: foo
444
618
  mail: foo@mail.com
445
619
  - name: bar
@@ -447,36 +621,34 @@ users:
447
621
  - name: baz
448
622
  mail: baz@mail.org
449
623
  </pre>
450
- <a name="example6.eruby"></a>
624
+ <a name="example7.eruby"></a>
451
625
  <div class="program_caption">
452
- example6.eruby</div>
453
- <pre class="program">&lt;h1&gt;&lt;%= title %&gt;&lt;/h1&gt;
626
+ example7.eruby</div>
627
+ <pre class="program">&lt;h1&gt;&lt;%= <b>@title</b> %&gt;&lt;/h1&gt;
454
628
  &lt;ul&gt;
455
- &lt;% for user in users %&gt;
629
+ &lt;% for user in <b>@users</b> %&gt;
456
630
  &lt;li&gt;
457
631
  &lt;a href="mailto:&lt;%= user['mail']%&gt;"&gt;&lt;%= user['name'] %&gt;&lt;/a&gt;
458
632
  &lt;/li&gt;
459
633
  &lt;% end %&gt;
460
634
  &lt;/ul&gt;
461
635
  </pre>
462
- <a name="example6.rb"></a>
636
+ <a name="example7.rb"></a>
463
637
  <div class="program_caption">
464
- example6.rb</div>
465
- <pre class="program">## create Eruby object
466
- require 'erubis'
467
- input = File.read('example6.eruby')
468
- eruby = Erubis::Eruby.new(input)
638
+ example7.rb</div>
639
+ <pre class="program">require 'erubis'
640
+ input = File.read('example7.eruby')
641
+ eruby = Erubis::Eruby.new(input) # create Eruby object
469
642
 
470
643
  ## load YAML document as context object
471
644
  <b>require 'yaml'</b>
472
- <b>context = YAML.load_file('example6.yaml')</b>
645
+ <b>context = YAML.load_file('example7.yaml')</b>
473
646
 
474
- ## get result
475
- puts <b>eruby.evaluate(context)</b>
647
+ puts <b>eruby.evaluate(context)</b> # get result
476
648
  </pre>
477
649
  <div class="terminal_caption">
478
650
  output</div>
479
- <pre class="terminal">$ ruby example6.rb
651
+ <pre class="terminal">$ ruby example7.rb
480
652
  &lt;h1&gt;Users List&lt;/h1&gt;
481
653
  &lt;ul&gt;
482
654
  &lt;li&gt;
@@ -490,233 +662,1151 @@ output</div>
490
662
  &lt;/li&gt;
491
663
  &lt;/ul&gt;
492
664
  </pre>
665
+ <p>It is able to specify YAML data file with the command-line option '-f'.
666
+ You don't have to write ruby script such as 'example7.rb'.
667
+ </p>
668
+ <div class="terminal_caption">
669
+ example of command-line option '-f'</div>
670
+ <pre class="terminal">$ erubis <b>-f example7.yaml</b> example7.eruby
671
+ &lt;h1&gt;Users List&lt;/h1&gt;
672
+ &lt;ul&gt;
673
+ &lt;li&gt;
674
+ &lt;a href="mailto:foo@mail.com"&gt;foo&lt;/a&gt;
675
+ &lt;/li&gt;
676
+ &lt;li&gt;
677
+ &lt;a href="mailto:bar@mail.net"&gt;bar&lt;/a&gt;
678
+ &lt;/li&gt;
679
+ &lt;li&gt;
680
+ &lt;a href="mailto:baz@mail.org"&gt;baz&lt;/a&gt;
681
+ &lt;/li&gt;
682
+ &lt;/ul&gt;
683
+ </pre>
684
+ <p>Command-line option '-S' converts keys of mapping in YAML data file from string into symbol.
685
+ Command-line option '-B' invokes 'Erubis::Eruby#result(binding())' instead of 'Erubis::Eruby#evaluate(context)'.
686
+ </p>
493
687
  <br>
494
688
 
495
689
 
496
- <a name="tut-fast"></a>
497
- <h3 class="section2">Faster Eruby</h3>
498
- <p>Erubis::FastEruby and Erubis::FastXmlEruby make faster Erubis::Eruby and Erubis::XmlEruby
499
- to combine several strings into a string.
690
+ <a name="tut-preamble"></a>
691
+ <h3 class="section2">Preamble and Postamble</h3>
692
+ <p>The first line ('_buf = [];') in the compiled source code is called preamble
693
+ and the last line ('_buf.join') is called postamble.
500
694
  </p>
501
- <a name="example7.eruby"></a>
695
+ <p>Command-line option '-b' skips the output of preamble and postamble.
696
+ </p>
697
+ <a name="example8.eruby"></a>
502
698
  <div class="program_caption">
503
- example7.eruby</div>
504
- <pre class="program">&lt;table&gt;
505
- &lt;tbody&gt;
506
- &lt;% for item in list %&gt;
507
- &lt;tr&gt;
508
- &lt;td&gt;&lt;%= item %&gt;&lt;/td&gt;
509
- &lt;/tr&gt;
510
- &lt;% end %&gt;
511
- &lt;/tbody&gt;
512
- &lt;/table&gt;
699
+ example8.eruby</div>
700
+ <pre class="program">&lt;% for item in @list %&gt;
701
+ &lt;b&gt;&lt;%= item %&gt;&lt;/b&gt;
702
+ &lt;% end %&gt;
513
703
  </pre>
514
- <a name="example7.rb"></a>
704
+ <p>compiled source code with and without command-line option '-b'
705
+ </p>
706
+ <pre class="terminal">## without '-b'
707
+ $ erubis -x example8.eruby
708
+ <b>_buf = [];</b> for item in @list
709
+ _buf &lt;&lt; ' &lt;b&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/b&gt;
710
+ '; end
711
+ <b>_buf.join</b>
712
+
713
+ ## with '-b'
714
+ $ erubis -x <b>-b</b> example8.eruby
715
+ for item in @list
716
+ _buf &lt;&lt; ' &lt;b&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/b&gt;
717
+ '; end
718
+ </pre>
719
+ <p>Erubis::Eruby.new option '<code>:preamble=&gt;false</code>' and '<code>:postamble=&gt;false</code>' also suppress output of preamble or postamle.
720
+ </p>
721
+ <a name="example8.rb"></a>
515
722
  <div class="program_caption">
516
- example7.rb</div>
517
- <pre class="program">## print script source with Eruby
518
- require 'erubis'
519
- input = File.read('example7.eruby')
520
- eruby = Erubis::Eruby.new(input)
521
- puts "--- script source (Eruby) ---"
522
- puts eruby.src
723
+ example8.rb</div>
724
+ <pre class="program">require 'erubis'
725
+ input = File.read('example8.eruby')
726
+ eruby1 = Erubis::Eruby.new(input)
727
+ eruby2 = Erubis::Eruby.new(input, <b>:preamble=&gt;false, :postamble=&gt;false</b>)
523
728
 
524
- ## print script source with FastEruby
525
- eruby = Erubis::<b>FastEruby</b>.new(input)
526
- puts "--- script source (FastEruby) ---"
527
- puts eruby.src
729
+ puts eruby1.src # print preamble and postamble
730
+ puts "--------------"
731
+ puts eruby2.src # don't print preamble and postamble
528
732
  </pre>
529
733
  <div class="terminal_caption">
530
734
  output</div>
531
- <pre class="terminal">$ ruby example7.rb
532
- --- script source (Eruby) ---
533
- _out = ''; _out &lt;&lt; "&lt;table&gt;\n"
534
- _out &lt;&lt; " &lt;tbody&gt;\n"
535
- for item in list
536
- _out &lt;&lt; " &lt;tr&gt;\n"
537
- _out &lt;&lt; " &lt;td&gt;"; _out &lt;&lt; ( item ).to_s; _out &lt;&lt; "&lt;/td&gt;\n"
538
- _out &lt;&lt; " &lt;/tr&gt;\n"
539
- end
540
- _out &lt;&lt; " &lt;/tbody&gt;\n"
541
- _out &lt;&lt; "&lt;/table&gt;\n"
542
- _out
543
- --- script source (FastEruby) ---
544
- _out = ''; _out &lt;&lt; "&lt;table&gt;\n &lt;tbody&gt;\n"
545
-
546
- for item in list
547
- _out &lt;&lt; " &lt;tr&gt;\n &lt;td&gt;"
548
- _out &lt;&lt; ( item ).to_s; _out &lt;&lt; "&lt;/td&gt;\n &lt;/tr&gt;\n"
549
-
550
- end
551
- _out &lt;&lt; " &lt;/tbody&gt;\n&lt;/table&gt;\n"
552
-
553
- _out
554
- </pre>
555
- <p>Here is the definition of FastEruby or FastXmlEruby.
556
- They are subclass of Eruby and XmlEruby respectively and only include FastEnhancer module.
557
- It shows that Erubis is extensible.
558
- </p>
559
- <div class="program_caption">
560
- definition of FastEruby and FastXmlEruby</div>
561
- <pre class="program">module Erubis
562
- class FastEruby &lt; Eruby
563
- <b>include FastEnhancer</b>
564
- end
565
- class FastXmlEruby &lt; XmlEruby
566
- <b>include FastEnhancer</b>
567
- end
735
+ <pre class="terminal">$ ruby example8.rb
736
+ _buf = []; for item in @list
737
+ _buf &lt;&lt; ' &lt;b&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/b&gt;
738
+ '; end
739
+ _buf.join
740
+ --------------
741
+ for item in @list
742
+ _buf &lt;&lt; ' &lt;b&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/b&gt;
743
+ '; end
744
+ </pre>
745
+ <br>
746
+
747
+
748
+ <br>
749
+
750
+
751
+ <a name="enhancer"></a>
752
+ <h2 class="section1">Enhancer</h2>
753
+ <p>Enhancer is a module to add a certain feature into Erubis::Eruby class.
754
+ Enhancer may be language-independent or only for Erubis::Eruby class.
755
+ </p>
756
+ <p>To use enhancers, define subclass and include them.
757
+ The folloing is an example to use <a href="#escape-enhancer">EscapeEnhancer</a>, <a href="#percentline-enhancer">PercentLineEnhancer</a>, and <a href="#bipattern-enhancer">BiPatternEnhancer</a>.
758
+ </p>
759
+ <pre class="program">class MyEruby &lt; Erubis::Eruby
760
+ include EscapeEnhancer
761
+ include PercentLineEnhancer
762
+ include BiPatternEnhancer
568
763
  end
569
764
  </pre>
765
+ <p>You can specify enhancers in command-line with option '-E'.
766
+ The following is an example to use some enhancers in command-line.
767
+ </p>
768
+ <pre class="terminal">$ erubis -xE Escape,PercentLine,BiPattern example.eruby
769
+ </pre>
770
+ <p>The following is the list of enhancers.
771
+ </p>
772
+ <dl class="dl1">
773
+ <dt class="dt1">
774
+ <a href="#escape-enhancer">EscapeEnhander</a> (language-independent)</dt>
775
+ <dd class="dd1">
776
+ Switch '&lt;%= %&gt;' to escaped and '&lt;%== %&gt;' to unescaped.
777
+ </dd>
778
+ <dt class="dt1">
779
+ <a href="#stdout-enhancer">StdoutEnhancer</a> (only for Eruby)</dt>
780
+ <dd class="dd1">
781
+ Use $stdout instead of array buffer.
782
+ </dd>
783
+ <dt class="dt1">
784
+ <a href="#printout-enhancer">PrintOutEnhancer</a> (only for Eruby)</dt>
785
+ <dd class="dd1">
786
+ Use "print(...)" statement insead of "_buf &lt;&lt; ...".
787
+ </dd>
788
+ <dt class="dt1">
789
+ <a href="#printenabled-enhancer">PrintEnabledEnhancer</a> (only for Eruby)</dt>
790
+ <dd class="dd1">
791
+ Enable to use print() in '&lt;% ... %&gt;'.
792
+ </dd>
793
+ <dt class="dt1">
794
+ <a href="#array-enhancer">ArrayEnhancer</a> (only for Eruby)</dt>
795
+ <dd class="dd1">
796
+ Return array of string instead of returning string.
797
+ </dd>
798
+ <dt class="dt1">
799
+ <a href="#arraybuffer-enhancer">ArrayBufferEnhancer</a> (only for Eruby)</dt>
800
+ <dd class="dd1">
801
+ Use array buffer. This is included in Erubis::Eruby by default.
802
+ </dd>
803
+ <dt class="dt1">
804
+ <a href="#stringbuffer-enhancer">StringBufferEnhancer</a> (only for Eruby)</dt>
805
+ <dd class="dd1">
806
+ Use string buffer. It is a little slower than ArrayBufferEnhancer.
807
+ </dd>
808
+ <dt class="dt1">
809
+ <a href="#notext-enhancer">NoTextEnhancer</a> (language-independent)</dt>
810
+ <dd class="dd1">
811
+ Print embedded code only and ignore normal text.
812
+ </dd>
813
+ <dt class="dt1">
814
+ <a href="#simplify-enhancer">SimplifyEnhancer</a> (language-independent)</dt>
815
+ <dd class="dd1">
816
+ Make compile faster but don't trim spaces around '&lt;% %&gt;'.
817
+ </dd>
818
+ <dt class="dt1">
819
+ <a href="#bipattern-enhancer">BiPatternEnhancer</a> (language-independent)</dt>
820
+ <dd class="dd1">
821
+ [experimental] Enable to use another embedded pattern with '&lt;% %&gt;'.
822
+ </dd>
823
+ <dt class="dt1">
824
+ <a href="#percentline-enhancer">PercentLineEnhancer</a> (language-independent)</dt>
825
+ <dd class="dd1">
826
+ Regard lines starting with '%' as Ruby code. This is for compatibility with eruby and ERB.
827
+ </dd>
828
+ <dt class="dt1">
829
+ <a href="#headerfooter-enhancer">HeaderFooterEnhancer</a> (language-independent)</dt>
830
+ <dd class="dd1">
831
+ [experimental] Enable you to add header and footer in eRuby script.
832
+ </dd>
833
+ </dl>
834
+ <p>If you required 'erubis/engine/enhanced', Eruby subclasses which include each enhancers are defined.
835
+ For example, class BiPatternEruby includes BiPatternEnhancer.
836
+ </p>
837
+ <a name="escape-enhancer"></a>
838
+ <h3 class="section2">EscapeEnhancer</h3>
839
+ <p>EscapeEnhancer switches '&lt;%= ... %&gt;' to escaped and '&lt;%== ... %&gt;' to unescaped.
840
+ </p>
841
+ <a name="example.eruby"></a>
842
+ <div class="program_caption">
843
+ example.eruby</div>
844
+ <pre class="program">&lt;div&gt;
845
+ &lt;% for item in list %&gt;
846
+ &lt;p&gt;&lt;%= item %&gt;&lt;/p&gt;
847
+ &lt;p&gt;&lt;%== item %&gt;&lt;/p&gt;
848
+ &lt;% end %&gt;
849
+ &lt;/div&gt;
850
+ </pre>
851
+ <div class="terminal_caption">
852
+ compiled source code</div>
853
+ <pre class="terminal">$ erubis -xE Escape example.eruby
854
+ _buf = []; _buf &lt;&lt; '&lt;div&gt;
855
+ '; for item in list
856
+ _buf &lt;&lt; ' &lt;p&gt;'; <b>_buf &lt;&lt; Erubis::XmlHelper.escape_xml( item );</b> _buf &lt;&lt; '&lt;/p&gt;
857
+ &lt;p&gt;'; <b>_buf &lt;&lt; ( item ).to_s;</b> _buf &lt;&lt; '&lt;/p&gt;
858
+ '; end
859
+ _buf &lt;&lt; '&lt;/div&gt;
860
+ ';
861
+ _buf.join
862
+ </pre>
863
+ <p>EscapeEnhancer is language-independent.
864
+ </p>
570
865
  <br>
571
866
 
572
867
 
573
- <a name="tut-stdout"></a>
574
- <h3 class="section2">Stdout Eruby</h3>
575
- <p>Erubis::StdoutEruby and Erubis::StdoutXmlEruby use $stdout instead of string object.
868
+ <a name="stdout-enhancer"></a>
869
+ <h3 class="section2">StdoutEnhancer</h3>
870
+ <p>StdoutEnhancer use $sdtdout instead of array buffer.
576
871
  Therefore, you can use 'print' statement in embedded ruby code.
577
872
  </p>
578
- <a name="example8.eruby"></a>
873
+ <div class="terminal_caption">
874
+ compiled source code</div>
875
+ <pre class="terminal">$ erubis -xE Stdout example.eruby
876
+ <b>_buf = $stdout;</b> _buf &lt;&lt; '&lt;div&gt;
877
+ '; for item in list
878
+ _buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
879
+ &lt;p&gt;'; _buf &lt;&lt; Erubis::XmlHelper.escape_xml( item ); _buf &lt;&lt; '&lt;/p&gt;
880
+ '; end
881
+ _buf &lt;&lt; '&lt;/div&gt;
882
+ ';
883
+ ''
884
+ </pre>
885
+ <p>StdoutEnhancer is only for Eruby.
886
+ </p>
887
+ <br>
888
+
889
+
890
+ <a name="printout-enhancer"></a>
891
+ <h3 class="section2">PrintOutEnhancer</h3>
892
+ <p>PrintOutEnhancer makes compiled source code to use 'print(...)' instead of '_buf &lt;&lt; ...'.
893
+ </p>
894
+ <div class="terminal_caption">
895
+ compiled source code</div>
896
+ <pre class="terminal">$ erubis -xE PrintOut example.eruby
897
+ <b>print</b> '&lt;div&gt;
898
+ '; for item in list
899
+ <b>print</b> ' &lt;p&gt;'; <b>print</b>(( item ).to_s); <b>print</b> '&lt;/p&gt;
900
+ &lt;p&gt;'; <b>print</b> Erubis::XmlHelper.escape_xml( item ); <b>print</b> '&lt;/p&gt;
901
+ '; end
902
+ <b>print</b> '&lt;/div&gt;
903
+ ';
904
+ </pre>
905
+ <p>PrintOutEnhancer is only for Eruby.
906
+ </p>
907
+ <br>
908
+
909
+
910
+ <a name="printenabled-enhancer"></a>
911
+ <h3 class="section2">PrintEnabledEnhancer</h3>
912
+ <p>PrintEnabledEnhancer enables you to use print() method in '&lt;% ... %&gt;'.
913
+ </p>
914
+ <a name="printenabled-example.eruby"></a>
579
915
  <div class="program_caption">
580
- example8.eruby</div>
581
- <pre class="program">&lt;ul&gt;
582
- &lt;% for item in list %&gt;
583
- &lt;li&gt;<b>&lt;% print item %&gt;</b>&lt;/li&gt;
584
- &lt;% end %&gt;
585
- &lt;/ul&gt;
916
+ printenabled-example.eruby</div>
917
+ <pre class="program">&lt;% for item in @list %&gt;
918
+ &lt;b&gt;<b>&lt;% print item %&gt;</b>&lt;/b&gt;
919
+ &lt;% end %&gt;
586
920
  </pre>
587
- <a name="example8.rb"></a>
921
+ <a name="printenabled-example.rb"></a>
588
922
  <div class="program_caption">
589
- example8.rb</div>
590
- <pre class="program">## create Eruby object
591
- require 'erubis'
592
- input = File.read('example8.eruby')
593
- eruby = Erubis::<b>StdoutEruby</b>.new(input)
923
+ printenabled-example.rb</div>
924
+ <pre class="program">require 'erubis'
925
+ class PrintEnabledEruby &lt; Erubis::Eruby
926
+ include Erubis::PrintEnabledEnhancer
927
+ end
928
+ input = File.read('printenabled-example.eruby')
929
+ eruby = PrintEnabledEruby.new(input)
930
+ list = ['aaa', 'bbb', 'ccc']
931
+ print eruby.evaluate(:list=&gt;list)
932
+ </pre>
933
+ <div class="terminal_caption">
934
+ output result</div>
935
+ <pre class="terminal">$ ruby printenabled-example.rb
936
+ &lt;b&gt;aaa&lt;/b&gt;
937
+ &lt;b&gt;bbb&lt;/b&gt;
938
+ &lt;b&gt;ccc&lt;/b&gt;
939
+ </pre>
940
+ <p>Notice to use Eruby#evaluate() and not to use Eruby#result(),
941
+ because print() method in '&lt;% ... %&gt;' invokes not Kernel#print() but PrintEnabledEnhancer#print().
942
+ </p>
943
+ <p>PrintEnabledEnhancer is only for Eruby.
944
+ </p>
945
+ <br>
594
946
 
595
- ## print script source
596
- puts "--- script source ---"
597
- puts eruby.src
598
947
 
599
- ## get result
600
- puts "--- result ---"
601
- list = ['aaa', 'bbb', 'ccc']
602
- #puts eruby.result(binding())
603
- <b>eruby.result(binding())</b> # returns nil
948
+ <a name="array-enhancer"></a>
949
+ <h3 class="section2">ArrayEnhancer</h3>
950
+ <p>ArrayEnhancer makes Eruby to return an array of strings.
951
+ </p>
952
+ <div class="terminal_caption">
953
+ compiled source code</div>
954
+ <pre class="terminal"><b>_buf = [];</b> _buf &lt;&lt; '&lt;div&gt;
955
+ '; for item in list
956
+ _buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
957
+ &lt;p&gt;'; _buf &lt;&lt; Erubis::XmlHelper.escape_xml( item ); _buf &lt;&lt; '&lt;/p&gt;
958
+ '; end
959
+ _buf &lt;&lt; '&lt;/div&gt;
960
+ ';
961
+ <b>_buf</b>
962
+ </pre>
963
+ <p>ArrayEnhancer is only for Eruby.
964
+ </p>
965
+ <br>
966
+
967
+
968
+ <a name="arraybuffer-enhancer"></a>
969
+ <h3 class="section2">ArrayBufferEnhancer</h3>
970
+ <p>Arraybufferenhancer makes Eruby to use array buffer.
971
+ Array buffer is a litte faster than String buffer.
972
+ Erubis::Eruby includes this enhancer by default.
973
+ </p>
974
+ <p>ArrayBufferEnhancer is only for Eruby.
975
+ </p>
976
+ <br>
977
+
978
+
979
+ <a name="stringbuffer-enhancer"></a>
980
+ <h3 class="section2">StringBufferEnhancer</h3>
981
+ <p>StringBufferEnhancer makes Eruby to use string buffer.
982
+ </p>
983
+ <pre class="terminal">$ erubis -xE StringBuffer example.eruby
984
+ <b>_buf = '';</b> _buf &lt;&lt; '&lt;div&gt;
985
+ '; for item in list
986
+ _buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
987
+ &lt;p&gt;'; _buf &lt;&lt; Erubis::XmlHelper.escape_xml( item ); _buf &lt;&lt; '&lt;/p&gt;
988
+ '; end
989
+ _buf &lt;&lt; '&lt;/div&gt;
990
+ ';
991
+ <b>_buf</b>
992
+ </pre>
993
+ <p>StringBufferEnhancer is only for Eruby.
994
+ </p>
995
+ <br>
996
+
997
+
998
+ <a name="notext-enhancer"></a>
999
+ <h3 class="section2">NoTextEnhancer</h3>
1000
+ <p>NoTextEnhancer suppress output of text and prints only embedded code.
1001
+ This is useful especially when debugging a complex eRuby script.
1002
+ </p>
1003
+ <a name="notext-example.eruby"></a>
1004
+ <div class="program_caption">
1005
+ notext-example.eruby</div>
1006
+ <pre class="program">&lt;h3&gt;List&lt;/h3&gt;
1007
+ &lt;% if !@list || @list.empty? %&gt;
1008
+ &lt;p&gt;not found.&lt;/p&gt;
1009
+ &lt;% else %&gt;
1010
+ &lt;table&gt;
1011
+ &lt;tbody&gt;
1012
+ &lt;% @list.each_with_index do |item, i| %&gt;
1013
+ &lt;tr bgcolor="&lt;%= i%2 == 0 ? '#FFCCCC' : '#CCCCFF' %&gt;"&gt;
1014
+ &lt;td&gt;&lt;%= item %&gt;&lt;/td&gt;
1015
+ &lt;/tr&gt;
1016
+ &lt;% end %&gt;
1017
+ &lt;/tbody&gt;
1018
+ &lt;/table&gt;
1019
+ &lt;% end %&gt;
604
1020
  </pre>
605
1021
  <div class="terminal_caption">
606
- output</div>
607
- <pre class="terminal">$ ruby example8.rb
608
- --- script source ---
609
- <b>_out = $stdout</b>; _out &lt;&lt; "&lt;ul&gt;\n"
610
- for item in list
611
- _out &lt;&lt; " &lt;li&gt;"; <b>print item</b> ; _out &lt;&lt; "&lt;/li&gt;\n"
612
- end
613
- _out &lt;&lt; "&lt;/ul&gt;\n"
614
- <b>nil</b>
615
- --- result ---
616
- &lt;ul&gt;
617
- &lt;li&gt;aaa&lt;/li&gt;
618
- &lt;li&gt;bbb&lt;/li&gt;
619
- &lt;li&gt;ccc&lt;/li&gt;
620
- &lt;/ul&gt;
1022
+ output example of NoTextEnhancer</div>
1023
+ <pre class="terminal">$ erubis -TxE NoText notext-example.eruby
1024
+ _buf = [];
1025
+ if !@list || @list.empty? ;
1026
+
1027
+ else ;
1028
+
1029
+
1030
+ @list.each_with_index do |item, i| ;
1031
+ _buf &lt;&lt; ( i%2 == 0 ? '#FFCCCC' : '#CCCCFF' ).to_s;
1032
+ _buf &lt;&lt; ( item ).to_s;
1033
+
1034
+ end ;
1035
+
1036
+
1037
+ end ;
1038
+ _buf.join
621
1039
  </pre>
622
- <p>Here is the definition of StdoutEruby or StdoutXmlEruby.
623
- They are subclass of Eruby and XmlEruby respectively and only include StdoutEnhancer module.
624
- It shows that Erubis is extensible.
1040
+ <p>NoTextEnhancer is language-independent. It is useful even if you are PHP user, see <a href="#topics-php">this section</a>.
625
1041
  </p>
1042
+ <br>
1043
+
1044
+
1045
+ <a name="simplify-enhancer"></a>
1046
+ <h3 class="section2">SimplifyEnhancer</h3>
1047
+ <p>SimplifyEnhancer makes compiling a little faster but don't trim spaces around '&lt;% %&gt;'.
1048
+ </p>
1049
+ <div class="terminal_caption">
1050
+ compiled source code</div>
1051
+ <pre class="terminal">$ erubis -xE Simplify example.euby
1052
+ _buf = []; _buf &lt;&lt; '&lt;div&gt;
1053
+ '; for item in list ; _buf &lt;&lt; '
1054
+ &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
1055
+ &lt;p&gt;'; _buf &lt;&lt; Erubis::XmlHelper.escape_xml( item ); _buf &lt;&lt; '&lt;/p&gt;
1056
+ '; end ; _buf &lt;&lt; '
1057
+ &lt;/div&gt;
1058
+ ';
1059
+ _buf.join
1060
+ </pre>
1061
+ <p>SimplifyEnhancer is language-independent.
1062
+ </p>
1063
+ <br>
1064
+
1065
+
1066
+ <a name="bipattern-enhancer"></a>
1067
+ <h3 class="section2">BiPatternEnhancer</h3>
1068
+ <p>BiPatternEnhancer enables to use another embedded pattern with '&lt;% %&gt;'.
1069
+ By Default, '[= ... =]' is available for expression.
1070
+ You can specify pattern by :bipattern property.
1071
+ </p>
1072
+ <a name="bipattern-example.rhtml"></a>
626
1073
  <div class="program_caption">
627
- definition of StdoutEruby and StdoutXmlEruby</div>
628
- <pre class="program">module Erubis
629
- class StdoutEruby &lt; Eruby
630
- <b>include StdoutEnhancer</b>
631
- end
632
- class StdoutXmlEruby &lt; XmlEruby
633
- <b>include StdoutEnhancer</b>
634
- end
635
- end
1074
+ bipattern-example.rhtml</div>
1075
+ <pre class="program">&lt;% for item in list %&gt;
1076
+ &lt;b&gt;<b>[= item =]</b>&lt;/b&gt;
1077
+ &lt;b&gt;<b>[== item =]</b>&lt;/b&gt;
1078
+ &lt;% end %&gt;
636
1079
  </pre>
1080
+ <div class="terminal_caption">
1081
+ compiled source code</div>
1082
+ <pre class="terminal">$ erubis -xE BiPattern bipattern-example.rhtml
1083
+ _buf = []; for item in list
1084
+ _buf &lt;&lt; ' &lt;b&gt;'; <b>_buf &lt;&lt; ( item ).to_s;</b> _buf &lt;&lt; '&lt;/b&gt;
1085
+ &lt;b&gt;'; <b>_buf &lt;&lt; Erubis::XmlHelper.escape_xml( item );</b> _buf &lt;&lt; '&lt;/b&gt;
1086
+ '; end
1087
+ _buf.join
1088
+ </pre>
1089
+ <p>BiPatternEnhancer is language-independent.
1090
+ </p>
1091
+ <br>
1092
+
1093
+
1094
+ <a name="percentline-enhancer"></a>
1095
+ <h3 class="section2">PercentLineEnhancer</h3>
1096
+ <p>PercentLineEnhancer regards lines starting with '%' as Ruby code.
1097
+ This is for compatibility with eruby and ERB.
1098
+ </p>
1099
+ <a name="percentline-example.rhtml"></a>
1100
+ <div class="program_caption">
1101
+ percentline-example.rhtml</div>
1102
+ <pre class="program"><b>% for item in list</b>
1103
+ &lt;b&gt;&lt;%= item %&gt;&lt;/b&gt;
1104
+ <b>% end</b>
1105
+ %% lines with '%%'
1106
+ </pre>
1107
+ <div class="terminal_caption">
1108
+ compiled source code</div>
1109
+ <pre class="terminal">$ erubis -xE PercentLine percentline-example.rhtml
1110
+ _buf = []; <b>for item in list</b>
1111
+ _buf &lt;&lt; ' &lt;b&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/b&gt;
1112
+ '; <b>end</b>
1113
+ _buf &lt;&lt; '% lines with \'%%\'
1114
+ ';
1115
+ _buf.join
1116
+ </pre>
1117
+ <p>PercentLineEnhancer is language-independent.
1118
+ </p>
637
1119
  <br>
638
1120
 
639
1121
 
640
- <a name="tut-print"></a>
641
- <h3 class="section2">Print Avairable Eruby</h3>
642
- <p>Erubis::PrintEruby and Erubis::PrintXmlEruby enables you to use print statement.
643
- You can get output as String because Erubis::PrintEruby and Erubis::PrintXmlEruby doesn't use $stdout.
1122
+ <a name="headerfooter-enhancer"></a>
1123
+ <h3 class="section2">HeaderFooterEnhancer</h3>
1124
+ <p>[experimental]
644
1125
  </p>
645
- <p>Notice:
1126
+ <p>HeaderFooterEnhancer enables you to add header and footer in eRuby script.
646
1127
  </p>
647
- <ul type="disc">
648
- <li>Use evaluate() and don't use result().
649
- </li>
650
- <li>Only print() is available, put() or p() are not available.
651
- </li>
652
- <li>PrintEruby and PrintXmlEruby has instance method 'print()'.
653
- It means that print statement invokes PrintEruby#print() or PrintXmlEruby#print(),
654
- and Kernel#print() is not invoked.
655
- </li>
656
- <li>PrintEruby#print() and PrintXmlEruby#print() can take just an argument.
657
- </li>
658
- </ul>
659
- <a name="example9.eruby"></a>
1128
+ <a name="headerfooter-example.eruby"></a>
660
1129
  <div class="program_caption">
661
- example9.eruby</div>
662
- <pre class="program">&lt;ul&gt;
663
- &lt;% for item in list %&gt;
664
- &lt;li&gt;<b>&lt;% print item %&gt;</b>&lt;/li&gt;
665
- &lt;% end %&gt;
666
- &lt;/ul&gt;
1130
+ headerfooter-example.eruby</div>
1131
+ <pre class="program"><b>&lt;!--#header:</b>
1132
+ <b>def list_items(items)</b>
1133
+ <b>#--&gt;</b>
1134
+ &lt;% for item in items %&gt;
1135
+ &lt;b&gt;&lt;%= item %&gt;&lt;/b&gt;
1136
+ &lt;% end %&gt;
1137
+ <b>&lt;!--#footer:</b>
1138
+ <b>end</b>
1139
+ <b>#--&gt;</b>
667
1140
  </pre>
668
- <a name="example9.rb"></a>
1141
+ <div class="terminal_caption">
1142
+ compiled source code</div>
1143
+ <pre class="terminal">$ erubis -xE HeaderFooter headerfooter-example.eruby
1144
+
1145
+ <b>def list_items(items)</b>
1146
+
1147
+ _buf = []; for item in items
1148
+ _buf &lt;&lt; ' &lt;b&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/b&gt;
1149
+ '; end
1150
+ _buf.join
1151
+
1152
+ <b>end</b>
1153
+
1154
+ </pre>
1155
+ <p>Compare to the following:
1156
+ </p>
1157
+ <a name="normal-eruby-test.eruby"></a>
669
1158
  <div class="program_caption">
670
- example9.rb</div>
671
- <pre class="program">## create Eruby object
672
- require 'erubis'
673
- input = File.read('example9.eruby')
674
- eruby = Erubis::<b>PrintEruby</b>.new(input)
1159
+ normal-eruby-test.eruby</div>
1160
+ <pre class="program"><b>&lt;%</b>
1161
+ <b>def list_items(items)</b>
1162
+ <b>%&gt;</b>
1163
+ &lt;% for item in items %&gt;
1164
+ &lt;li&gt;&lt;%= item %&gt;&lt;/li&gt;
1165
+ &lt;% end %&gt;
1166
+ <b>&lt;%</b>
1167
+ <b>end</b>
1168
+ <b>%&gt;</b>
1169
+ </pre>
1170
+ <div class="terminal_caption">
1171
+ compiled source code</div>
1172
+ <pre class="terminal">$ erubis -x normal-eruby-test.eruby
1173
+ _buf = [];
1174
+ <b>def list_items(items)</b>
675
1175
 
676
- ## print script source
677
- puts "--- script source ---"
678
- puts eruby.src
1176
+ for item in items
1177
+ _buf &lt;&lt; '&lt;li&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/li&gt;
1178
+ '; end
679
1179
 
680
- ## get result
681
- puts "--- result ---"
682
- list = ['aaa', 'bbb', 'ccc']
683
- puts <b>eruby.evaluate(:list =&gt; list)</b> # don't use result()!
1180
+ <b>end</b>
1181
+
1182
+ _buf.join
1183
+ </pre>
1184
+ <p>Header and footer can be in any position in eRuby script,
1185
+ that is, header is no need to be in the head of eRuby script.
1186
+ </p>
1187
+ <a name="headerfooter-example2.rhtml"></a>
1188
+ <div class="program_caption">
1189
+ headerfooter-example2.rhtml</div>
1190
+ <pre class="program">&lt;?xml version="1.0"?&gt;
1191
+ &lt;html&gt;
1192
+ <b>&lt;!--#header:</b>
1193
+ <b>def page(list)</b>
1194
+ <b>#--&gt;</b>
1195
+ :
1196
+ <b>&lt;!--#footer:</b>
1197
+ <b>end</b>
1198
+ <b>#--&gt;</b>
1199
+ &lt;/html&gt;
684
1200
  </pre>
685
1201
  <div class="terminal_caption">
686
- output</div>
687
- <pre class="terminal">$ ruby example9.rb
688
- --- script source ---
689
- <b>@_out =</b> _out = ''; _out &lt;&lt; "&lt;ul&gt;\n"
690
- for item in list
691
- _out &lt;&lt; " &lt;li&gt;"; <b>print item</b> ; _out &lt;&lt; "&lt;/li&gt;\n"
692
- end
693
- _out &lt;&lt; "&lt;/ul&gt;\n"
694
- _out
695
- --- result ---
696
- &lt;ul&gt;
697
- &lt;li&gt;aaa&lt;/li&gt;
698
- &lt;li&gt;bbb&lt;/li&gt;
699
- &lt;li&gt;ccc&lt;/li&gt;
700
- &lt;/ul&gt;
1202
+ compiled source code</div>
1203
+ <pre class="terminal">$ erubis -xE HeaderFooter headerfooter-example2.rhtml
1204
+
1205
+ <b>def page(list)</b>
1206
+
1207
+ _buf = []; _buf &lt;&lt; '&lt;?xml version="1.0"?&gt;
1208
+ &lt;html&gt;
1209
+ '; _buf &lt;&lt; ' :
1210
+ '; _buf &lt;&lt; '&lt;/html&gt;
1211
+ ';
1212
+ _buf.join
1213
+
1214
+ <b>end</b>
1215
+
701
1216
  </pre>
702
- <p>Here is the definition of PrintEruby or PrintXmlEruby.
703
- They are subclass of Eruby and XmlEruby respectively and only include PrintEnhancer module.
704
- It shows that Erubis is extensible.
1217
+ <p>HeaderFooterEnhancer is experimental and is language-independent.
705
1218
  </p>
1219
+ <br>
1220
+
1221
+
1222
+ <br>
1223
+
1224
+
1225
+ <a name="lang"></a>
1226
+ <h2 class="section1">Multi-Language</h2>
1227
+ <p>Erubis supports the following language currently:
1228
+ </p>
1229
+ <ul type="disc">
1230
+ <li>Ruby
1231
+ </li>
1232
+ <li>PHP
1233
+ </li>
1234
+ <li>C
1235
+ </li>
1236
+ <li>Java
1237
+ </li>
1238
+ <li>Scheme
1239
+ </li>
1240
+ <li>Perl
1241
+ </li>
1242
+ <li>JavaScript
1243
+ </li>
1244
+ </ul>
1245
+ <a name="lang-php"></a>
1246
+ <h3 class="section2">PHP</h3>
1247
+ <a name="example.ephp"></a>
706
1248
  <div class="program_caption">
707
- definition of PrintEruby and PrintXmlEruby</div>
708
- <pre class="program">module Erubis
709
- class PrintEruby &lt; Eruby
710
- <b>include PrintEnhancer</b>
711
- end
712
- class PrintXmlEruby &lt; XmlEruby
713
- <b>include PrintEnhancer</b>
714
- end
715
- end
1249
+ example.ephp</div>
1250
+ <pre class="program">&lt;?xml version="1.0"?&gt;
1251
+ &lt;html&gt;
1252
+ &lt;body&gt;
1253
+ &lt;p&gt;Hello <b>&lt;%= $user %&gt;</b>!&lt;/p&gt;
1254
+ &lt;table&gt;
1255
+ &lt;tbody&gt;
1256
+ <b>&lt;% $i = 0; %&gt;</b>
1257
+ <b>&lt;% foreach ($list as $item) { %&gt;</b>
1258
+ <b>&lt;% $i++; %&gt;</b>
1259
+ &lt;tr bgcolor=<b>"&lt;%= $i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %&gt;"</b>&gt;
1260
+ &lt;td&gt;<b>&lt;%= $i %&gt;</b>&lt;/td&gt;
1261
+ &lt;td&gt;<b>&lt;%== $item %&gt;</b>&lt;/td&gt;
1262
+ &lt;/tr&gt;
1263
+ &lt;% } %&gt;
1264
+ &lt;/tbody&gt;
1265
+ &lt;/table&gt;
1266
+ &lt;/body&gt;
1267
+ &lt;/html&gt;
1268
+ </pre>
1269
+ <div class="terminal_caption">
1270
+ compiled source code</div>
1271
+ <pre class="terminal">$ erubis -l php example.ephp
1272
+ &lt;&lt;?php ?&gt;?xml version="1.0"?&gt;
1273
+ &lt;html&gt;
1274
+ &lt;body&gt;
1275
+ &lt;p&gt;Hello &lt;?php echo $user; ?&gt;!&lt;/p&gt;
1276
+ &lt;table&gt;
1277
+ &lt;tbody&gt;
1278
+ &lt;?php $i = 0; ?&gt;
1279
+ &lt;?php foreach ($list as $item) { ?&gt;
1280
+ &lt;?php $i++; ?&gt;
1281
+ &lt;tr bgcolor="&lt;?php echo $i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'; ?&gt;"&gt;
1282
+ &lt;td&gt;&lt;?php echo $i; ?&gt;&lt;/td&gt;
1283
+ &lt;td&gt;&lt;?php echo htmlspecialchars($item); ?&gt;&lt;/td&gt;
1284
+ &lt;/tr&gt;
1285
+ &lt;?php } ?&gt;
1286
+ &lt;/tbody&gt;
1287
+ &lt;/table&gt;
1288
+ &lt;/body&gt;
1289
+ &lt;/html&gt;
716
1290
  </pre>
717
1291
  <br>
718
1292
 
719
1293
 
1294
+ <a name="lang-c"></a>
1295
+ <h3 class="section2">C</h3>
1296
+ <a name="example.ec"></a>
1297
+ <div class="program_caption">
1298
+ example.ec</div>
1299
+ <pre class="program"><b>&lt;%
1300
+ #include &lt;stdio.h&gt;
1301
+
1302
+ int main(int argc, char *argv[])
1303
+ {
1304
+ int i;
1305
+
1306
+ %&gt;</b>
1307
+ &lt;html&gt;
1308
+ &lt;body&gt;
1309
+ &lt;p&gt;Hello <b>&lt;%= "%s", argv[0] %&gt;</b>!&lt;/p&gt;
1310
+ &lt;table&gt;
1311
+ &lt;tbody&gt;
1312
+ <b>&lt;% for (i = 1; i &lt; argc; i++) { %&gt;</b>
1313
+ &lt;tr bgcolor="<b>&lt;%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %&gt;</b>"&gt;
1314
+ &lt;td&gt;<b>&lt;%= "%d", i %&gt;</b>&lt;/td&gt;
1315
+ &lt;td&gt;<b>&lt;%= "%s", argv[i] %&gt;</b>&lt;/td&gt;
1316
+ &lt;/tr&gt;
1317
+ <b>&lt;% } %&gt;</b>
1318
+ &lt;/tbody&gt;
1319
+ &lt;/table&gt;
1320
+ &lt;/body&gt;
1321
+ &lt;/html&gt;
1322
+ <b>&lt;%
1323
+ return 0;
1324
+ }
1325
+ %&gt;</b>
1326
+ </pre>
1327
+ <div class="terminal_caption">
1328
+ compiled source code</div>
1329
+ <pre class="terminal">$ erubis -l c example.ec
1330
+ #line 1 "example.ec"
1331
+
1332
+ #include &lt;stdio.h&gt;
1333
+
1334
+ int main(int argc, char *argv[])
1335
+ {
1336
+ int i;
1337
+
1338
+
1339
+ fputs("&lt;html&gt;\n"
1340
+ " &lt;body&gt;\n"
1341
+ " &lt;p&gt;Hello ", stdout); fprintf(stdout, "%s", argv[0]); fputs("!&lt;/p&gt;\n"
1342
+ " &lt;table&gt;\n"
1343
+ " &lt;tbody&gt;\n", stdout);
1344
+ for (i = 1; i &lt; argc; i++) {
1345
+ fputs(" &lt;tr bgcolor=\"", stdout); fprintf(stdout, i % 2 == 0 ? "#FFCCCC" : "#CCCCFF"); fputs("\"&gt;\n"
1346
+ " &lt;td&gt;", stdout); fprintf(stdout, "%d", i); fputs("&lt;/td&gt;\n"
1347
+ " &lt;td&gt;", stdout); fprintf(stdout, "%s", argv[i]); fputs("&lt;/td&gt;\n"
1348
+ " &lt;/tr&gt;\n", stdout);
1349
+ }
1350
+ fputs(" &lt;/tbody&gt;\n"
1351
+ " &lt;/table&gt;\n"
1352
+ " &lt;/body&gt;\n"
1353
+ "&lt;/html&gt;\n", stdout);
1354
+
1355
+ return 0;
1356
+ }
1357
+
1358
+ </pre>
1359
+ <br>
1360
+
1361
+
1362
+ <a name="lang-java"></a>
1363
+ <h3 class="section2">Java</h3>
1364
+ <a name="Example.ejava"></a>
1365
+ <div class="program_caption">
1366
+ Example.ejava</div>
1367
+ <pre class="program"><b>&lt;%
1368
+ import java.util.*;
1369
+
1370
+ public class Example {
1371
+ private String user;
1372
+ private String[] list;
1373
+ public example(String user, String[] list) {
1374
+ this.user = user;
1375
+ this.list = list;
1376
+ }
1377
+
1378
+ public String view() {
1379
+ StringBuffer _buf = new StringBuffer();
1380
+ %&gt;</b>
1381
+ &lt;html&gt;
1382
+ &lt;body&gt;
1383
+ &lt;p&gt;Hello <b>&lt;%= user %&gt;</b>!&lt;/p&gt;
1384
+ &lt;table&gt;
1385
+ &lt;tbody&gt;
1386
+ <b>&lt;% for (int i = 0; i &lt; list.length; i++) { %&gt;</b>
1387
+ &lt;tr bgcolor=<b>"&lt;%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %&gt;"</b>&gt;
1388
+ &lt;td&gt;<b>&lt;%= i + 1 %&gt;</b>&lt;/td&gt;
1389
+ &lt;td&gt;<b>&lt;%== list[i] %&gt;</b>&lt;/td&gt;
1390
+ &lt;/tr&gt;
1391
+ <b>&lt;% } %&gt;</b>
1392
+ &lt;/tbody&gt;
1393
+ &lt;/table&gt;
1394
+ &lt;body&gt;
1395
+ &lt;/html&gt;
1396
+ <b>&lt;%
1397
+ return _buf.toString();
1398
+ }
1399
+
1400
+ public static void main(String[] args) {
1401
+ String[] list = { "&lt;aaa&gt;", "b&amp;b", "\"ccc\"" };
1402
+ Example ex = Example.new("Erubis", list);
1403
+ System.out.print(ex.view());
1404
+ }
1405
+
1406
+ public static String escape(String s) {
1407
+ StringBuffer sb = new StringBuffer();
1408
+ for (int i = 0; i &lt; s.length(); i++) {
1409
+ char ch = s.charAt(i);
1410
+ switch (ch) {
1411
+ case '&lt;': sb.append("&amp;lt;"); break;
1412
+ case '&gt;': sb.append("&amp;gt;"); break;
1413
+ case '&amp;': sb.append("&amp;amp;"); break;
1414
+ case '"': sb.append("&amp;quot;"); break;
1415
+ default: sb.append(ch);
1416
+ }
1417
+ }
1418
+ return sb.toString();
1419
+ }
1420
+ }
1421
+ %&gt;</b>
1422
+ </pre>
1423
+ <div class="terminal_caption">
1424
+ compiled source code</div>
1425
+ <pre class="terminal">$ erubis -b -l java example.ejava
1426
+ StringBuffer _buf = new StringBuffer();
1427
+ import java.util.*;
1428
+
1429
+ public class Example {
1430
+ private String user;
1431
+ private String[] list;
1432
+ public example(String user, String[] list) {
1433
+ this.user = user;
1434
+ this.list = list;
1435
+ }
1436
+
1437
+ public String view() {
1438
+ StringBuffer _buf = new StringBuffer();
1439
+
1440
+ _buf.append("&lt;html&gt;\n"
1441
+ + " &lt;body&gt;\n"
1442
+ + " &lt;p&gt;Hello "); _buf.append(user); _buf.append("!&lt;/p&gt;\n"
1443
+ + " &lt;table&gt;\n"
1444
+ + " &lt;tbody&gt;\n");
1445
+ for (int i = 0; i &lt; list.length; i++) {
1446
+ _buf.append(" &lt;tr bgcolor=\""); _buf.append(i % 2 == 0 ? "#FFCCCC" : "#CCCCFF"); _buf.append("\"&gt;\n"
1447
+ + " &lt;td&gt;"); _buf.append(i + 1); _buf.append("&lt;/td&gt;\n"
1448
+ + " &lt;td&gt;"); _buf.append(escape(list[i])); _buf.append("&lt;/td&gt;\n"
1449
+ + " &lt;/tr&gt;\n");
1450
+ }
1451
+ _buf.append(" &lt;/tbody&gt;\n"
1452
+ + " &lt;/table&gt;\n"
1453
+ + " &lt;body&gt;\n"
1454
+ + "&lt;/html&gt;\n");
1455
+
1456
+ return _buf.toString();
1457
+ }
1458
+
1459
+ public static void main(String[] args) {
1460
+ String[] list = { "&lt;aaa&gt;", "b&amp;b", "\"ccc\"" };
1461
+ Example ex = Example.new("Erubis", list);
1462
+ System.out.print(ex.view());
1463
+ }
1464
+
1465
+ public static String escape(String s) {
1466
+ StringBuffer sb = new StringBuffer();
1467
+ for (int i = 0; i &lt; s.length(); i++) {
1468
+ char ch = s.charAt(i);
1469
+ switch (ch) {
1470
+ case '&lt;': sb.append("&amp;lt;"); break;
1471
+ case '&gt;': sb.append("&amp;gt;"); break;
1472
+ case '&amp;': sb.append("&amp;amp;"); break;
1473
+ case '"': sb.append("&amp;quot;"); break;
1474
+ default: sb.append(ch);
1475
+ }
1476
+ }
1477
+ return sb.toString();
1478
+ }
1479
+ }
1480
+
1481
+ return _buf.toString();
1482
+ </pre>
1483
+ <br>
1484
+
1485
+
1486
+ <a name="lang-scheme"></a>
1487
+ <h3 class="section2">Scheme</h3>
1488
+ <a name="example.escheme"></a>
1489
+ <div class="program_caption">
1490
+ example.escheme</div>
1491
+ <pre class="program">&lt;html&gt;
1492
+ &lt;body&gt;
1493
+ <b>&lt;%
1494
+ (let ((user "Erubis")
1495
+ (items '("&lt;aaa&gt;" "b&amp;b" "\"ccc\""))
1496
+ (i 0))
1497
+ %&gt;</b>
1498
+ &lt;p&gt;Hello <b>&lt;%= user %&gt;</b>!&lt;/p&gt;
1499
+ &lt;table&gt;
1500
+ <b>&lt;%
1501
+ (for-each
1502
+ (lambda (item)
1503
+ (set! i (+ i 1))
1504
+ %&gt;</b>
1505
+ &lt;tr bgcolor="<b>&lt;%= (if (= (modulo i 2) 0) "#FFCCCC" "#CCCCFF") %&gt;</b>"&gt;
1506
+ &lt;td&gt;<b>&lt;%= i %&gt;</b>&lt;/td&gt;
1507
+ &lt;td&gt;<b>&lt;%= item %&gt;</b>&lt;/td&gt;
1508
+ &lt;/tr&gt;
1509
+ <b>&lt;%
1510
+ ) ; lambda end
1511
+ items) ; for-each end
1512
+ %&gt;</b>
1513
+ &lt;/table&gt;
1514
+ <b>&lt;%
1515
+ ) ; let end
1516
+ %&gt;</b>
1517
+ &lt;/body&gt;
1518
+ &lt;/html&gt;
1519
+ </pre>
1520
+ <div class="terminal_caption">
1521
+ compiled source code</div>
1522
+ <pre class="terminal">$ erubis -l scheme example.escheme
1523
+ (let ((_buf '())) (define (_add x) (set! _buf (cons x _buf))) (_add "&lt;html&gt;
1524
+ &lt;body&gt;\n")
1525
+
1526
+ (let ((user "Erubis")
1527
+ (items '("&lt;aaa&gt;" "b&amp;b" "\"ccc\""))
1528
+ (i 0))
1529
+
1530
+ (_add " &lt;p&gt;Hello ")(_add user)(_add "!&lt;/p&gt;
1531
+ &lt;table&gt;\n")
1532
+
1533
+ (for-each
1534
+ (lambda (item)
1535
+ (set! i (+ i 1))
1536
+
1537
+ (_add " &lt;tr bgcolor=\"")(_add (if (= (modulo i 2) 0) "#FFCCCC" "#CCCCFF"))(_add "\"&gt;
1538
+ &lt;td&gt;")(_add i)(_add "&lt;/td&gt;
1539
+ &lt;td&gt;")(_add item)(_add "&lt;/td&gt;
1540
+ &lt;/tr&gt;\n")
1541
+
1542
+ ) ; lambda end
1543
+ items) ; for-each end
1544
+
1545
+ (_add " &lt;/table&gt;\n")
1546
+
1547
+ ) ; let end
1548
+
1549
+ (_add " &lt;/body&gt;
1550
+ &lt;/html&gt;\n")
1551
+ (reverse _buf))
1552
+ </pre>
1553
+ <div class="terminal_caption">
1554
+ compiled source code (with --func=display property)</div>
1555
+ <pre class="terminal">$ erubis -l scheme --func=display example.escheme
1556
+ (display "&lt;html&gt;
1557
+ &lt;body&gt;\n")
1558
+
1559
+ (let ((user "Erubis")
1560
+ (items '("&lt;aaa&gt;" "b&amp;b" "\"ccc\""))
1561
+ (i 0))
1562
+
1563
+ (display " &lt;p&gt;Hello ")(display user)(display "!&lt;/p&gt;
1564
+ &lt;table&gt;\n")
1565
+
1566
+ (for-each
1567
+ (lambda (item)
1568
+ (set! i (+ i 1))
1569
+
1570
+ (display " &lt;tr bgcolor=\"")(display (if (= (modulo i 2) 0) "#FFCCCC" "#CCCCFF"))(display "\"&gt;
1571
+ &lt;td&gt;")(display i)(display "&lt;/td&gt;
1572
+ &lt;td&gt;")(display item)(display "&lt;/td&gt;
1573
+ &lt;/tr&gt;\n")
1574
+
1575
+ ) ; lambda end
1576
+ items) ; for-each end
1577
+
1578
+ (display " &lt;/table&gt;\n")
1579
+
1580
+ ) ; let end
1581
+
1582
+ (display " &lt;/body&gt;
1583
+ &lt;/html&gt;\n")
1584
+ </pre>
1585
+ <br>
1586
+
1587
+
1588
+ <a name="lang-perl"></a>
1589
+ <h3 class="section2">Perl</h3>
1590
+ <a name="example.eperl"></a>
1591
+ <div class="program_caption">
1592
+ example.eprl</div>
1593
+ <pre class="program"><b>&lt;%
1594
+ my $user = 'Erubis';
1595
+ my @list = ('&lt;aaa&gt;', 'b&amp;b', '"ccc"');
1596
+ %&gt;</b>
1597
+ &lt;html&gt;
1598
+ &lt;body&gt;
1599
+ &lt;p&gt;Hello <b>&lt;%= $user %&gt;</b>!&lt;/p&gt;
1600
+ &lt;table&gt;
1601
+ <b>&lt;% $i = 0; %&gt;</b>
1602
+ <b>&lt;% for $item (@list) { %&gt;</b>
1603
+ &lt;tr bgcolor=<b>&lt;%= ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %&gt;</b>"&gt;
1604
+ &lt;td&gt;<b>&lt;%= $i %&gt;</b>&lt;/td&gt;
1605
+ &lt;td&gt;<b>&lt;%= $item %&gt;</b>&lt;/td&gt;
1606
+ &lt;/tr&gt;
1607
+ <b>&lt;% } %&gt;</b>
1608
+ &lt;/table&gt;
1609
+ &lt;/body&gt;
1610
+ &lt;/html&gt;
1611
+ </pre>
1612
+ <div class="terminal_caption">
1613
+ compiled source code</div>
1614
+ <pre class="terminal">$ erubis -l perl example.eperl
1615
+
1616
+ my $user = 'Erubis';
1617
+ my @list = ('&lt;aaa&gt;', 'b&amp;b', '"ccc"');
1618
+
1619
+ print('&lt;html&gt;
1620
+ &lt;body&gt;
1621
+ &lt;p&gt;Hello '); print($user); print('!&lt;/p&gt;
1622
+ &lt;table&gt;
1623
+ '); $i = 0;
1624
+ for $item (@list) {
1625
+ print(' &lt;tr bgcolor='); print(++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'); print('"&gt;
1626
+ &lt;td&gt;'); print($i); print('&lt;/td&gt;
1627
+ &lt;td&gt;'); print($item); print('&lt;/td&gt;
1628
+ &lt;/tr&gt;
1629
+ '); }
1630
+ print(' &lt;/table&gt;
1631
+ &lt;/body&gt;
1632
+ &lt;/html&gt;
1633
+ ');
1634
+ </pre>
1635
+ <br>
1636
+
1637
+
1638
+ <a name="lang-javascript"></a>
1639
+ <h3 class="section2">JavaScript</h3>
1640
+ <p>example.ejs
1641
+ </p>
1642
+ <a name="example.ejs"></a>
1643
+ <pre class="program"><b>&lt;%
1644
+ var user = 'Erubis';
1645
+ var list = ['&lt;aaa&gt;', 'b&amp;b', '"ccc"'];
1646
+ %&gt;</b>
1647
+ &lt;html&gt;
1648
+ &lt;body&gt;
1649
+ &lt;p&gt;Hello <b>&lt;%= user %&gt;</b>!&lt;/p&gt;
1650
+ &lt;table&gt;
1651
+ &lt;tbody&gt;
1652
+ <b>&lt;% var i; %&gt;</b>
1653
+ <b>&lt;% for (i = 0; i &lt; list.length; i++) { %&gt;</b>
1654
+ &lt;tr bgcolor="<b>&lt;%= i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %&gt;</b>"&gt;
1655
+ &lt;td&gt;<b>&lt;%= i + 1 %&gt;</b>&lt;/td&gt;
1656
+ &lt;td&gt;<b>&lt;%= list[i] %&gt;</b>&lt;/td&gt;
1657
+ &lt;/tr&gt;
1658
+ <b>&lt;% } %&gt;</b>
1659
+ &lt;/tbody&gt;
1660
+ &lt;/table&gt;
1661
+ &lt;/body&gt;
1662
+ &lt;/html&gt;
1663
+ </pre>
1664
+ <div class="terminal_caption">
1665
+ compiled source code</div>
1666
+ <pre class="terminal">$ erubis -l js example.ejs
1667
+ var _buf = [];
1668
+ var user = 'Erubis';
1669
+ var list = ['&lt;aaa&gt;', 'b&amp;b', '"ccc"'];
1670
+
1671
+ _buf.push("&lt;html&gt;\n\
1672
+ &lt;body&gt;\n\
1673
+ &lt;p&gt;Hello "); _buf.push(user); _buf.push("!&lt;/p&gt;\n\
1674
+ &lt;table&gt;\n\
1675
+ &lt;tbody&gt;\n");
1676
+ var i;
1677
+ for (i = 0; i &lt; list.length; i++) {
1678
+ _buf.push(" &lt;tr bgcolor=\""); _buf.push(i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'); _buf.push("\"&gt;\n\
1679
+ &lt;td&gt;"); _buf.push(i + 1); _buf.push("&lt;/td&gt;\n\
1680
+ &lt;td&gt;"); _buf.push(list[i]); _buf.push("&lt;/td&gt;\n\
1681
+ &lt;/tr&gt;\n");
1682
+ }
1683
+ _buf.push(" &lt;/tbody&gt;\n\
1684
+ &lt;/table&gt;\n\
1685
+ &lt;/body&gt;\n\
1686
+ &lt;/html&gt;\n");
1687
+ document.write(_buf.join(""));
1688
+ </pre>
1689
+ <br>
1690
+
1691
+
1692
+ <br>
1693
+
1694
+
1695
+ <a name="topics"></a>
1696
+ <h2 class="section1">Other Topics</h2>
1697
+ <a name="topics-tinyeruby"></a>
1698
+ <h3 class="section2">TinyEruby class</h3>
1699
+ <p>TinyEruby class in 'erubis/tiny.rb' is the smallest implementation of eRuby.
1700
+ If you don't need any enhancements of Erubis and only require simple eRuby implementation,
1701
+ try TinyEruby class.
1702
+ </p>
1703
+ <br>
1704
+
1705
+
1706
+ <a name="topics-php"></a>
1707
+ <h3 class="section2">NoTextEnhancer in PHP</h3>
1708
+ <p>NoTextEnhancer is quite useful not only for eRuby but also for PHP.
1709
+ It can "drop" HTML text and show up embedded Ruby/PHP code.
1710
+ </p>
1711
+ <p>For example, see the following PHP script.
1712
+ </p>
1713
+ <a name="notext-example.php"></a>
1714
+ <div class="program_caption">
1715
+ notext-example.php</div>
1716
+ <pre class="program">&lt;html&gt;
1717
+ &lt;body&gt;
1718
+ &lt;h3&gt;List&lt;/h3&gt;
1719
+ &lt;?php if (!$list || count($list) == 0) { ?&gt;
1720
+ &lt;p&gt;not found.&lt;/p&gt;
1721
+ &lt;?php } else { ?&gt;
1722
+ &lt;table&gt;
1723
+ &lt;tbody&gt;
1724
+ &lt;?php $i = 0; ?&gt;
1725
+ &lt;?php foreach ($list as $item) { ?&gt;
1726
+ &lt;tr bgcolor="&lt;?php echo ++$i % 2 == 1 ? '#FFCCCC' : '#CCCCFF'; ?&gt;"&gt;
1727
+ &lt;td&gt;&lt;?php echo $item; ?&gt;&lt;/td&gt;
1728
+ &lt;/tr&gt;
1729
+ &lt;?php } ?&gt;
1730
+ &lt;/tbody&gt;
1731
+ &lt;/table&gt;
1732
+ &lt;?php } ?&gt;
1733
+ &lt;/body&gt;
1734
+ &lt;/html&gt;
1735
+ </pre>
1736
+ <p>This is complex because PHP code and HTML document are mixed.
1737
+ NoTextEnhancer can separate PHP code from HTML document.
1738
+ </p>
1739
+ <div class="terminal_caption">
1740
+ example of using NoTextEnhancer with PHP file</div>
1741
+ <pre class="terminal">$ erubis -T -l php -E NoText -p '&lt;\?php \?&gt;' notext-example.php | uniq
1742
+
1743
+ &lt;?php if (!$list || count($list) == 0) { ?&gt;
1744
+
1745
+ &lt;?php } else { ?&gt;
1746
+
1747
+ &lt;?php $i = 0; ?&gt;
1748
+ &lt;?php foreach ($list as $item) { ?&gt;
1749
+ &lt;?php echo ++$i % 2 == 1 ? '#FFCCCC' : '#CCCCFF'; ?&gt;
1750
+ &lt;?php echo $item; ?&gt;
1751
+
1752
+ &lt;?php } ?&gt;
1753
+
1754
+ &lt;?php } ?&gt;
1755
+
1756
+ </pre>
1757
+ <br>
1758
+
1759
+
1760
+ <a name="topics-benchmark"></a>
1761
+ <h3 class="section2">Benchmark</h3>
1762
+ <p>A benchmark script is included in Erubis package at erubis-X.X.X/benchark directory.
1763
+ Here is an example result of benchmark.
1764
+ </p>
1765
+ <div class="output_caption">
1766
+ Env: Linux FedoraCore4, Celeron 667MHz, Mem512MB, Ruby1.8.4</div>
1767
+ <pre class="output"> user system total real
1768
+ ERuby 138.280000 1.900000 140.180000 (141.470426)
1769
+ ERB 402.220000 3.190000 405.410000 (408.886894)
1770
+ Erubis::Eruby 147.080000 2.400000 149.480000 (150.752255)
1771
+ Erubis::StringBufferEruby 186.130000 2.600000 188.730000 (190.374098)
1772
+ Erubis::SimplifiedEruby 130.100000 2.210000 132.310000 (133.426010)
1773
+ Erubis::StdoutEruby 106.010000 2.130000 108.140000 (108.999193)
1774
+ Erubis::StdoutSimplifiedEruby 97.130000 2.180000 99.310000 (100.104433)
1775
+ Erubis::TinyEruby 118.740000 2.360000 121.100000 (122.141380)
1776
+ Erubis::TinyStdoutEruby 86.140000 1.840000 87.980000 ( 88.679196)
1777
+ </pre>
1778
+ <div class="output_caption">
1779
+ Env: MacOS X 10.4, PowerPC 1.42GHz, Mem1.5GB, Ruby1.8.4</div>
1780
+ <pre class="output"> user system total real
1781
+ ERuby 55.040000 2.120000 57.160000 ( 89.311397)
1782
+ ERB 103.960000 3.480000 107.440000 (159.231792)
1783
+ Erubis::Eruby 36.130000 1.570000 37.700000 ( 52.188574)
1784
+ Erubis::StringBufferEruby 47.270000 1.980000 49.250000 ( 73.867537)
1785
+ Erubis::SimplifiedEruby 34.310000 1.600000 35.910000 ( 51.762841)
1786
+ Erubis::StdoutEruby 26.240000 1.490000 27.730000 ( 41.840430)
1787
+ Erubis::StdoutSimplifiedEruby 25.380000 1.340000 26.720000 ( 37.231918)
1788
+ Erubis::TinyEruby 31.690000 1.590000 33.280000 ( 49.862091)
1789
+ Erubis::TinyStdoutEruby 22.550000 1.230000 23.780000 ( 33.316978)
1790
+ </pre>
1791
+ <p>This shows that:
1792
+ </p>
1793
+ <ul type="disc">
1794
+ <li>Erubis::Eruby is about 2.7 or 2.9 times faster than ERB.
1795
+ </li>
1796
+ <li>Erubis::Eruby is about 6% slower in linux or 1.5 times faster than ERuby in Mac.
1797
+ </li>
1798
+ <li>Erubis::SimplifiedEruby (which incudes SimplifiedEnhander) is faster than ERuby.
1799
+ </li>
1800
+ <li>String buffer (StringBufferEnhancer) is slower than array buffer (ArrayBufferEnhancer which Erubis::Eruby includes)
1801
+ </li>
1802
+ <li>Using print statement or $stdout is faster than array buffer and string buffer.
1803
+ </li>
1804
+ <li>Erubis::TinyEruby (at 'erubis/tiny.rb') and it's subclasses are the fastest in all eRuby implementation.
1805
+ </li>
1806
+ </ul>
1807
+ <br>
1808
+
1809
+
720
1810
  <br>
721
1811
 
722
1812
 
@@ -724,7 +1814,7 @@ end
724
1814
  <h2 class="section1">Command Reference</h2>
725
1815
  <a name="command-usage"></a>
726
1816
  <h3 class="section2">Usage</h3>
727
- <p>erubis [-hvsT] [-p <i>pattern</i>] [-c <i>class</i>] [-K <i>kanji</i>] [-f <i>file.yaml</i>] [<i>file</i> ...]
1817
+ <p>erubis [..options..] [<i>file</i> ...]
728
1818
  </p>
729
1819
  <br>
730
1820
 
@@ -743,30 +1833,52 @@ end
743
1833
  Release version.
744
1834
  </dd>
745
1835
  <dt class="dt3"><b>
746
- -s </b></dt>
1836
+ -x </b></dt>
747
1837
  <dd class="dd3">
748
- Show script source.
1838
+ Show compiled source.
749
1839
  </dd>
750
1840
  <dt class="dt3"><b>
751
1841
  -T </b></dt>
752
1842
  <dd class="dd3">
753
1843
  No trimming spaces around '&lt;% %&gt;'.
1844
+ This is equivarent to '--trim=false'.
1845
+ </dd>
1846
+ <dt class="dt3"><b>
1847
+ -b </b></dt>
1848
+ <dd class="dd3">
1849
+ Body only (no preamble nor postamble).
1850
+ This is equivarent to '--preamble=false --postamble=false'.
1851
+ </dd>
1852
+ <dt class="dt3"><b>
1853
+ -e </b></dt>
1854
+ <dd class="dd3">
1855
+ Escape. This is equivarent to '-E Escape'.
754
1856
  </dd>
755
1857
  <dt class="dt3"><b>
756
1858
  -p pattern </b></dt>
757
1859
  <dd class="dd3">
758
1860
  Embedded pattern (default '&lt;% %&gt;').
1861
+ This is equivarent to '--pattern=<i>pattern</i>'.
1862
+ </dd>
1863
+ <dt class="dt3"><b>
1864
+ -l lang </b></dt>
1865
+ <dd class="dd3">
1866
+ Language name.
1867
+ This option makes erubis command to compile script but no execute.
759
1868
  </dd>
760
1869
  <dt class="dt3"><b>
761
- -c class </b></dt>
1870
+ -E enhacers </b></dt>
762
1871
  <dd class="dd3">
763
- Class name (Eruby, XmlEruby, FastEruby, ...) (default Eruby).
1872
+ Enhancer name (Escape, PercentLine, ...).
1873
+ It is able to specify several enhancer name separating with ','
1874
+ (ex. -f Escape,PercentLine,HeaderFooter).
764
1875
  </dd>
765
1876
  <dt class="dt3"><b>
766
1877
  -I path </b></dt>
767
1878
  <dd class="dd3">
768
1879
  Require library path ($:).
769
- It is able to specify several paths separating with ',' (ex. -f path1,path2,path3).
1880
+ It is able to specify several paths separating with ','
1881
+ (ex. -f path1,path2,path3).
770
1882
  </dd>
771
1883
  <dt class="dt3"><b>
772
1884
  -K kanji </b></dt>
@@ -777,17 +1889,37 @@ end
777
1889
  -f file.yaml </b></dt>
778
1890
  <dd class="dd3">
779
1891
  YAML file for context values (read stdin if filename is '-').
780
- It is able to specify several filenames separating with ',' (ex. -f file1,file2,file3).
1892
+ It is able to specify several filenames separating with ','
1893
+ (ex. -f file1,file2,file3).
1894
+ </dd>
1895
+ <dt class="dt3"><b>
1896
+ -t </b></dt>
1897
+ <dd class="dd3">
1898
+ Expand tab characters in YAML file.
781
1899
  </dd>
782
1900
  <dt class="dt3"><b>
783
- --name=value </b></dt>
1901
+ -S </b></dt>
784
1902
  <dd class="dd3">
785
- Variable name and value
1903
+ Convert mapping key from string to symbol in YAML file.
1904
+ </dd>
1905
+ <dt class="dt3"><b>
1906
+ -B </b></dt>
1907
+ <dd class="dd3">
1908
+ invoke Eruby#result() instead of Eruby#evaluate()
786
1909
  </dd>
787
1910
  </dl>
788
1911
  <br>
789
1912
 
790
1913
 
1914
+ <a name="command-props"></a>
1915
+ <h3 class="section2">Properties</h3>
1916
+ <p>Some Eruby classes can take optional properties to change it's compile option.
1917
+ For example, property '--indent=" "' may change indentation of compiled source code.
1918
+ Try 'erubis -h' for details.
1919
+ </p>
1920
+ <br>
1921
+
1922
+
791
1923
  <br>
792
1924
 
793
1925