erubis 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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