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
@@ -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