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
@@ -0,0 +1,96 @@
1
+ ##
2
+ ## $Rev: 21 $
3
+ ## $Release: 2.0.0 $
4
+ ## copyright(c) 2006 kuwata-lab all rights reserved.
5
+ ##
6
+
7
+ require 'erubis/engine'
8
+ require 'erubis/enhancer'
9
+
10
+
11
+ module Erubis
12
+
13
+
14
+ ##
15
+ ## engine for Scheme
16
+ ##
17
+ class Escheme < Engine
18
+
19
+ def self.supported_properties() # :nodoc:
20
+ list = super
21
+ list << [:func, '_add', "function name (ex. 'display')"]
22
+ return list
23
+ end
24
+
25
+ def initialize(input, properties={})
26
+ @func = properties[:func] || '_add' # or 'display'
27
+ super
28
+ end
29
+
30
+ def add_preamble(src)
31
+ return unless @func == '_add'
32
+ src << "(let ((_buf '())) " + \
33
+ "(define (_add x) (set! _buf (cons x _buf))) "
34
+ #src << "(let* ((_buf '())" + \
35
+ # " (_add (lambda (x) (set! _buf (cons x _buf))))) "
36
+ end
37
+
38
+ def escape_text(text)
39
+ @table_ ||= { '"'=>'\\"', '\\'=>'\\\\' }
40
+ text.gsub!(/["\\]/) { |m| @table_[m] }
41
+ return text
42
+ end
43
+
44
+ def escaped_expr(code)
45
+ @escape ||= 'escape'
46
+ return "(#{@escape} #{code.strip})"
47
+ end
48
+
49
+ def add_text(src, text)
50
+ return if text.empty?
51
+ t = escape_text(text)
52
+ if t[-1] == ?\n
53
+ t[-1, 1] = ''
54
+ src << "(#{@func} \"" << t << "\\n\")\n"
55
+ else
56
+ src << "(#{@func} \"" << t << '")'
57
+ end
58
+ end
59
+
60
+ def add_stmt(src, code)
61
+ src << code
62
+ end
63
+
64
+ def add_expr_literal(src, code)
65
+ src << "(#{@func} " << code.strip << ')'
66
+ end
67
+
68
+ def add_expr_escaped(src, code)
69
+ src << "(#{@func} " << escaped_expr(code) << ')'
70
+ end
71
+
72
+ def add_expr_debug(src, code)
73
+ s = (code.strip! || code).gsub(/\"/, '\\"')
74
+ src << "(display \"*** debug: #{s}=\")(display #{code.strip})(display \"\\n\")"
75
+ end
76
+
77
+ def add_postamble(src)
78
+ return unless @func == '_add'
79
+ src << "\n" unless src[-1] == ?\n
80
+ src << " (reverse _buf))\n"
81
+ end
82
+
83
+ end
84
+
85
+
86
+ class EscapedEscheme < Escheme
87
+ include EscapeEnhancer
88
+ end
89
+
90
+
91
+ #class XmlEscheme < Escheme
92
+ # include EscapeEnhancer
93
+ #end
94
+
95
+
96
+ end
@@ -0,0 +1,114 @@
1
+ ##
2
+ ## $Rev: 21 $
3
+ ## $Release: 2.0.0 $
4
+ ## copyright(c) 2006 kuwata-lab all rights reserved.
5
+ ##
6
+
7
+
8
+ require 'erubis/engine/eruby'
9
+
10
+
11
+ module Erubis
12
+
13
+
14
+ ##
15
+ ## Eruby class which generates optimized ruby code
16
+ ##
17
+ class OptimizedEruby < Engine # Eruby
18
+
19
+ def self.supported_properties() # :nodoc:
20
+ return super
21
+ end
22
+
23
+ def initialize(input, properties={})
24
+ @initialized = false
25
+ @prev_is_expr = false
26
+ super
27
+ end
28
+
29
+ protected
30
+
31
+ def escape_text(text)
32
+ text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
33
+ end
34
+
35
+ def escaped_expr(code)
36
+ @escape ||= 'Erubis::XmlHelper.escape_xml'
37
+ return "#{@escape}(#{code})"
38
+ end
39
+
40
+ def switch_to_expr(src)
41
+ return if @prev_is_expr
42
+ @prev_is_expr = true
43
+ src << ' _buf'
44
+ end
45
+
46
+ def switch_to_stmt(src)
47
+ return unless @prev_is_expr
48
+ @prev_is_expr = false
49
+ src << ';'
50
+ end
51
+
52
+ def add_preamble(src)
53
+ #@initialized = false
54
+ #@prev_is_expr = false
55
+ end
56
+
57
+ def add_text(src, text)
58
+ return if text.empty?
59
+ if @initialized
60
+ switch_to_expr(src)
61
+ src << " << '" << escape_text(text) << "'"
62
+ else
63
+ src << "_buf = '" << escape_text(text) << "';"
64
+ @initialized = true
65
+ end
66
+ end
67
+
68
+ def add_stmt(src, code)
69
+ switch_to_stmt(src) if @initialized
70
+ #super
71
+ src << code
72
+ src << ';' unless code[-1] == ?\n
73
+ end
74
+
75
+ def add_expr_literal(src, code)
76
+ unless @initialized; src << "_buf = ''"; @initialized = true; end
77
+ switch_to_expr(src)
78
+ src << " << (" << code << ").to_s"
79
+ end
80
+
81
+ def add_expr_escaped(src, code)
82
+ unless @initialized; src << "_buf = ''"; @initialized = true; end
83
+ switch_to_expr(src)
84
+ src << " << " << escaped_expr(code)
85
+ end
86
+
87
+ def add_expr_debug(src, code)
88
+ code.strip!
89
+ s = (code.dump =~ /\A"(.*)"\z/) && $1
90
+ src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
91
+ end
92
+
93
+ def add_postamble(src)
94
+ #super if @initialized
95
+ src << "\n_buf\n" if @initialized
96
+ end
97
+
98
+ end # end of class OptimizedEruby
99
+
100
+
101
+ ##
102
+ ## XmlEruby class which generates optimized ruby code
103
+ ##
104
+ class OptimizedXmlEruby < OptimizedEruby
105
+ include EscapeEnhancer
106
+
107
+ def add_expr_debug(src, code)
108
+ switch_to_stmt(src) if indicator == '===' && !@initialized
109
+ super
110
+ end
111
+
112
+ end # end of class OptimizedXmlEruby
113
+
114
+ end
@@ -0,0 +1,487 @@
1
+ ##
2
+ ## $Rev: 21 $
3
+ ## $Release: 2.0.0 $
4
+ ## copyright(c) 2006 kuwata-lab all rights reserved.
5
+ ##
6
+
7
+
8
+ require 'erubis/engine'
9
+
10
+
11
+ module Erubis
12
+
13
+
14
+ ##
15
+ ## switch '<%= ... %>' to escaped and '<%== ... %>' to unescaped
16
+ ##
17
+ ## ex.
18
+ ## class XmlEruby < Eruby
19
+ ## include EscapeEnhancer
20
+ ## end
21
+ ##
22
+ ## this is language-indenedent.
23
+ ##
24
+ module EscapeEnhancer
25
+
26
+ def self.desc # :nodoc:
27
+ "switch '<%= %>' to escaped and '<%== %>' to unescaped"
28
+ end
29
+
30
+ #--
31
+ #def self.included(klass)
32
+ # klass.class_eval <<-END
33
+ # alias _add_expr_literal add_expr_literal
34
+ # alias _add_expr_escaped add_expr_escaped
35
+ # alias add_expr_literal _add_expr_escaped
36
+ # alias add_expr_escaped _add_expr_literal
37
+ # END
38
+ #end
39
+ #++
40
+
41
+ def add_expr(src, code, indicator)
42
+ case indicator
43
+ when '='
44
+ add_expr_escaped(src, code)
45
+ #add_expr_literal(src, code)
46
+ when '=='
47
+ add_expr_literal(src, code)
48
+ #add_expr_escaped(src, code)
49
+ when '==='
50
+ add_expr_debug(src, code)
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+
57
+ #--
58
+ ## (obsolete)
59
+ #module FastEnhancer
60
+ #end
61
+ #++
62
+
63
+
64
+ ##
65
+ ## use $stdout instead of string
66
+ ##
67
+ ## this is only for Eruby.
68
+ ##
69
+ module StdoutEnhancer
70
+
71
+ def self.desc # :nodoc:
72
+ "use $stdout instead of array buffer or string buffer"
73
+ end
74
+
75
+ def add_preamble(src)
76
+ src << "_buf = $stdout;"
77
+ end
78
+
79
+ def add_postamble(src)
80
+ src << "\n''\n"
81
+ end
82
+
83
+ end
84
+
85
+
86
+ ##
87
+ ## use print statement instead of '_buf << ...'
88
+ ##
89
+ ## this is only for Eruby.
90
+ ##
91
+ module PrintOutEnhancer
92
+
93
+ def self.desc # :nodoc:
94
+ "use print statement instead of '_buf << ...'"
95
+ end
96
+
97
+ def add_preamble(src)
98
+ end
99
+
100
+ def add_text(src, text)
101
+ src << " print '" << escape_text(text) << "';" unless text.empty?
102
+ end
103
+
104
+ def add_expr_literal(src, code)
105
+ src << ' print((' << code << ').to_s);'
106
+ end
107
+
108
+ def add_expr_escaped(src, code)
109
+ src << ' print ' << escaped_expr(code) << ';'
110
+ end
111
+
112
+ def add_postamble(src)
113
+ src << "\n" unless src[-1] == ?\n
114
+ end
115
+
116
+ end
117
+
118
+
119
+ ##
120
+ ## enable print function
121
+ ##
122
+ ## Notice: use Eruby#evaluate() and don't use Eruby#result()
123
+ ## to be enable print function.
124
+ ##
125
+ ## this is only for Eruby.
126
+ ##
127
+ module PrintEnabledEnhancer
128
+
129
+ def self.desc # :nodoc:
130
+ "enable to use print function in '<% %>'"
131
+ end
132
+
133
+ def add_preamble(src)
134
+ src << "@_buf = "
135
+ super
136
+ end
137
+
138
+ def print(*args)
139
+ args.each do |arg|
140
+ @_buf << arg.to_s
141
+ end
142
+ end
143
+
144
+ def evaluate(context=Context.new)
145
+ _src = @src
146
+ if context.is_a?(Hash)
147
+ context.each do |key, val| instance_variable_set("@#{key}", val) end
148
+ else
149
+ context.instance_variables.each do |name|
150
+ instance_variable_set(name, context.instance_variable_get(name))
151
+ end
152
+ end
153
+ return instance_eval(_src, (@filename || '(erubis)'))
154
+ end
155
+
156
+ end
157
+
158
+
159
+ ##
160
+ ## return array instead of string
161
+ ##
162
+ ## this is only for Eruby.
163
+ ##
164
+ module ArrayEnhancer
165
+
166
+ def self.desc # :nodoc:
167
+ "return array instead of string"
168
+ end
169
+
170
+ def add_preamble(src)
171
+ src << "_buf = [];"
172
+ end
173
+
174
+ def add_postamble(src)
175
+ src << "\n" unless src[-1] == ?\n
176
+ src << "_buf\n"
177
+ end
178
+
179
+ end
180
+
181
+
182
+ ##
183
+ ## use an Array object as buffer (included in Eruby by default)
184
+ ##
185
+ ## this is only for Eruby.
186
+ ##
187
+ module ArrayBufferEnhancer
188
+
189
+ def self.desc # :nodoc:
190
+ "use an Array object for buffering (included in Eruby class)"
191
+ end
192
+
193
+ def add_preamble(src)
194
+ src << "_buf = [];"
195
+ end
196
+
197
+ def add_postamble(src)
198
+ src << "\n" unless src[-1] == ?\n
199
+ src << "_buf.join\n"
200
+ end
201
+
202
+ end
203
+
204
+
205
+ ##
206
+ ## use String class for buffering
207
+ ##
208
+ ## this is only for Eruby.
209
+ ##
210
+ module StringBufferEnhancer
211
+
212
+ def self.desc # :nodoc:
213
+ "use a String object for buffering"
214
+ end
215
+
216
+ def add_preamble(src)
217
+ src << "_buf = '';"
218
+ end
219
+
220
+ def add_postamble(src)
221
+ src << "\n" unless src[-1] == ?\n
222
+ src << "_buf\n"
223
+ end
224
+
225
+ end
226
+
227
+
228
+ ##
229
+ ## use StringIO class for buffering
230
+ ##
231
+ ## this is only for Eruby.
232
+ ##
233
+ module StringIOEnhancer # :nodoc:
234
+
235
+ def self.desc # :nodoc:
236
+ "use a StringIO object for buffering"
237
+ end
238
+
239
+ def add_preamble(src)
240
+ src << "_buf = StringIO.new;"
241
+ end
242
+
243
+ def add_postamble(src)
244
+ src << "\n" unless src[-1] == ?\n
245
+ src << "_buf.string\n"
246
+ end
247
+
248
+ end
249
+
250
+
251
+ ##
252
+ ## remove text and leave code, especially useful when debugging.
253
+ ##
254
+ ## ex.
255
+ ## $ erubis -s -e NoText file.eruby | more
256
+ ##
257
+ ## this is language independent.
258
+ ##
259
+ module NoTextEnhancer
260
+
261
+ def self.desc # :nodoc:
262
+ "remove text and leave code (useful when debugging)"
263
+ end
264
+
265
+ def add_text(src, text)
266
+ src << ("\n" * text.count("\n"))
267
+ if text[-1] != ?\n
268
+ text =~ /^(.*?)\z/
269
+ src << (' ' * $1.length)
270
+ end
271
+ end
272
+
273
+ end
274
+
275
+
276
+ ##
277
+ ## get compile faster, but spaces around '<%...%>' are not trimmed.
278
+ ##
279
+ ## this is language-independent.
280
+ ##
281
+ module SimplifyEnhancer
282
+
283
+ def self.desc # :nodoc:
284
+ "get compile faster but leave spaces around '<% %>'"
285
+ end
286
+
287
+ #DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
288
+ SIMPLE_REGEXP = /(.*?)<%(=+|\#)?(.*?)-?%>/m
289
+
290
+ def compile(input)
291
+ src = ""
292
+ add_preamble(src)
293
+ #regexp = pattern_regexp(@pattern)
294
+ input.scan(SIMPLE_REGEXP) do |text, indicator, code|
295
+ add_text(src, text)
296
+ if !indicator # <% %>
297
+ add_stmt(src, code)
298
+ elsif indicator[0] == ?\# # <%# %>
299
+ n = code.count("\n")
300
+ add_stmt(src, "\n" * n)
301
+ else # <%= %>
302
+ add_expr(src, code, indicator)
303
+ end
304
+ end
305
+ rest = $' || input
306
+ add_text(src, rest)
307
+ add_postamble(src)
308
+ return src
309
+ end
310
+
311
+ end
312
+
313
+
314
+ ##
315
+ ## enable to use other embedded expression pattern (default is '\[= =\]').
316
+ ##
317
+ ## notice! this is an experimental. spec may change in the future.
318
+ ##
319
+ ## ex.
320
+ ## input = <<END
321
+ ## <% for item in list %>
322
+ ## <%= item %> : <%== item %>
323
+ ## [= item =] : [== item =]
324
+ ## <% end %>
325
+ ## END
326
+ ##
327
+ ## class BiPatternEruby
328
+ ## include BiPatternEnhancer
329
+ ## end
330
+ ## eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]')
331
+ ## list = ['<a>', 'b&b', '"c"']
332
+ ## print eruby.result(binding())
333
+ ##
334
+ ## ## output
335
+ ## <a> : &lt;a&gt;
336
+ ## <a> : &lt;a&gt;
337
+ ## b&b : b&amp;b
338
+ ## b&b : b&amp;b
339
+ ## "c" : &quot;c&quot;
340
+ ## "c" : &quot;c&quot;
341
+ ##
342
+ ## this is language independent.
343
+ ##
344
+ module BiPatternEnhancer
345
+
346
+ def self.desc # :nodoc:
347
+ "another embedded expression pattern (default '\[= =\]')."
348
+ end
349
+
350
+ def initialize(input, properties={})
351
+ self.bipattern = properties[:bipattern] # or '\$\{ \}'
352
+ super
353
+ end
354
+
355
+ ## when pat is nil then '\[= =\]' is used
356
+ def bipattern=(pat) # :nodoc:
357
+ @bipattern = pat || '\[= =\]'
358
+ pre, post = @bipattern.split()
359
+ @bipattern_regexp = /(.*?)#{pre}(=*)(.*?)#{post}/m
360
+ end
361
+
362
+ def add_text(src, text)
363
+ return unless text
364
+ text.scan(@bipattern_regexp) do |txt, indicator, code|
365
+ super(src, txt)
366
+ add_expr(src, code, '=' + indicator)
367
+ end
368
+ rest = $' || text
369
+ super(src, rest)
370
+ end
371
+
372
+ end
373
+
374
+
375
+ ##
376
+ ## regards lines starting with '%' as program code
377
+ ##
378
+ ## this is for compatibility to eruby and ERB.
379
+ ##
380
+ ## this is language-independent.
381
+ ##
382
+ module PercentLineEnhancer
383
+
384
+ def self.desc # :nodoc:
385
+ "regard lines starting with '%' as program code"
386
+ end
387
+
388
+ PERCENT_LINE_PATTERN = /(.*?)^\%(.*?\r?\n)/m
389
+
390
+ def add_text(src, text)
391
+ text.scan(PERCENT_LINE_PATTERN) do |txt, line|
392
+ super(src, txt)
393
+ if line[0] == ?%
394
+ super(src, line)
395
+ else
396
+ add_stmt(src, line)
397
+ end
398
+ end
399
+ rest = $' || text
400
+ super(src, rest)
401
+ end
402
+
403
+ end
404
+
405
+
406
+ ##
407
+ ## [experimental] allow header and footer in eRuby script
408
+ ##
409
+ ## ex.
410
+ ## ====================
411
+ ## ## without header and footer
412
+ ## $ cat ex1.eruby
413
+ ## <% def list_items(list) %>
414
+ ## <% for item in list %>
415
+ ## <li><%= item %></li>
416
+ ## <% end %>
417
+ ## <% end %>
418
+ ##
419
+ ## $ erubis -s ex1.eruby
420
+ ## _buf = []; def list_items(list)
421
+ ## ; for item in list
422
+ ## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
423
+ ## '; end
424
+ ## ; end
425
+ ## ;
426
+ ## _buf.join
427
+ ##
428
+ ## ## with header and footer
429
+ ## $ cat ex2.eruby
430
+ ## <!--#header:
431
+ ## def list_items(list)
432
+ ## #-->
433
+ ## <% for item in list %>
434
+ ## <li><%= item %></li>
435
+ ## <% end %>
436
+ ## <!--#footer:
437
+ ## end
438
+ ## #-->
439
+ ##
440
+ ## $ erubis -s -c HeaderFooterEruby ex4.eruby
441
+ ##
442
+ ## def list_items(list)
443
+ ## _buf = []; _buf << '
444
+ ## '; for item in list
445
+ ## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
446
+ ## '; end
447
+ ## ; _buf << '
448
+ ## ';
449
+ ## _buf.join
450
+ ## end
451
+ ##
452
+ ## ====================
453
+ ##
454
+ ## this is language-independent.
455
+ ##
456
+ module HeaderFooterEnhancer
457
+
458
+ def self.desc # :nodoc:
459
+ "allow header/footer in document (ex. '<!--#header: #-->')"
460
+ end
461
+
462
+ HEADER_FOOTER_PATTERN = /(.*?)(^[ \t]*)?<!--\#(\w+):(.*?)\#-->([ \t]*\r?\n)?/m
463
+
464
+ def add_text(src, text)
465
+ text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace|
466
+ flag_trim = @trim && lspace && rspace
467
+ super(src, txt)
468
+ content = "#{lspace}#{content}#{rspace}" if flag_trim
469
+ super(src, lspace) if !flag_trim && lspace
470
+ instance_variable_set("@#{word}", content)
471
+ super(src, rspace) if !flag_trim && rspace
472
+ end
473
+ rest = $' || text
474
+ super(src, rest)
475
+ end
476
+
477
+ attr_accessor :header, :footer
478
+
479
+ def compile(input)
480
+ source = super
481
+ return @src = "#{@header}#{source}#{@footer}"
482
+ end
483
+
484
+ end
485
+
486
+
487
+ end