Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 903 lines (850 sloc) 23.014 kB
511dc44 initial import
Laurent Sansonetti authored
1 # = ERB -- Ruby Templating
2 #
3 # Author:: Masatoshi SEKI
4 # Documentation:: James Edward Gray II and Gavin Sinclair
5 #
6 # See ERB for primary documentation and ERB::Util for a couple of utility
7 # routines.
8 #
9 # Copyright (c) 1999-2000,2002,2003 Masatoshi SEKI
10 #
11 # You can redistribute it and/or modify it under the same terms as Ruby.
12
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
13 #
14 # = ERB -- Ruby Templating
15 #
16 # == Introduction
17 #
18 # ERB provides an easy to use but powerful templating system for Ruby. Using
19 # ERB, actual Ruby code can be added to any plain text document for the
20 # purposes of generating document information details and/or flow control.
21 #
22 # A very simple example is this:
23 #
24 # require 'erb'
25 #
26 # x = 42
27 # template = ERB.new <<-EOF
28 # The value of x is: <%= x %>
29 # EOF
30 # puts template.result(binding)
31 #
32 # <em>Prints:</em> The value of x is: 42
33 #
34 # More complex examples are given below.
35 #
36 #
37 # == Recognized Tags
38 #
39 # ERB recognizes certain tags in the provided template and converts them based
40 # on the rules below:
41 #
42 # <% Ruby code -- inline with output %>
43 # <%= Ruby expression -- replace with result %>
44 # <%# comment -- ignored -- useful in testing %>
45 # % a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)
46 # %% replaced with % if first thing on a line and % processing is used
47 # <%% or %%> -- replace with <% or %> respectively
48 #
49 # All other text is passed through ERB filtering unchanged.
50 #
51 #
52 # == Options
53 #
54 # There are several settings you can change when you use ERB:
55 # * the nature of the tags that are recognized;
56 # * the value of <tt>$SAFE</tt> under which the template is run;
57 # * the binding used to resolve local variables in the template.
58 #
59 # See the ERB.new and ERB#result methods for more detail.
60 #
61 # == Character encodings
62 #
63 # ERB (or ruby code generated by ERB) returns a string in the same
64 # character encoding as the input string. When the input string has
65 # a magic comment, however, it returns a string in the encoding specified
66 # by the magic comment.
67 #
68 # # -*- coding: UTF-8 -*-
69 # require 'erb'
70 #
71 # template = ERB.new <<EOF
72 # <%#-*- coding: Big5 -*-%>
73 # \_\_ENCODING\_\_ is <%= \_\_ENCODING\_\_ %>.
74 # EOF
75 # puts template.result
76 #
77 # <em>Prints:</em> \_\_ENCODING\_\_ is Big5.
78 #
79 #
80 # == Examples
81 #
82 # === Plain Text
83 #
84 # ERB is useful for any generic templating situation. Note that in this example, we use the
85 # convenient "% at start of line" tag, and we quote the template literally with
86 # <tt>%q{...}</tt> to avoid trouble with the backslash.
87 #
88 # require "erb"
89 #
90 # # Create template.
91 # template = %q{
92 # From: James Edward Gray II <james@grayproductions.net>
93 # To: <%= to %>
94 # Subject: Addressing Needs
95 #
96 # <%= to[/\w+/] %>:
97 #
98 # Just wanted to send a quick note assuring that your needs are being
99 # addressed.
100 #
101 # I want you to know that my team will keep working on the issues,
102 # especially:
103 #
104 # <%# ignore numerous minor requests -- focus on priorities %>
105 # % priorities.each do |priority|
106 # * <%= priority %>
107 # % end
108 #
109 # Thanks for your patience.
110 #
111 # James Edward Gray II
112 # }.gsub(/^ /, '')
113 #
114 # message = ERB.new(template, 0, "%<>")
115 #
116 # # Set up template data.
117 # to = "Community Spokesman <spokesman@ruby_community.org>"
118 # priorities = [ "Run Ruby Quiz",
119 # "Document Modules",
120 # "Answer Questions on Ruby Talk" ]
121 #
122 # # Produce result.
123 # email = message.result
124 # puts email
125 #
126 # <i>Generates:</i>
127 #
128 # From: James Edward Gray II <james@grayproductions.net>
129 # To: Community Spokesman <spokesman@ruby_community.org>
130 # Subject: Addressing Needs
131 #
132 # Community:
133 #
134 # Just wanted to send a quick note assuring that your needs are being addressed.
135 #
136 # I want you to know that my team will keep working on the issues, especially:
137 #
138 # * Run Ruby Quiz
139 # * Document Modules
140 # * Answer Questions on Ruby Talk
141 #
142 # Thanks for your patience.
143 #
144 # James Edward Gray II
145 #
146 # === Ruby in HTML
147 #
148 # ERB is often used in <tt>.rhtml</tt> files (HTML with embedded Ruby). Notice the need in
149 # this example to provide a special binding when the template is run, so that the instance
150 # variables in the Product object can be resolved.
151 #
152 # require "erb"
153 #
154 # # Build template data class.
155 # class Product
156 # def initialize( code, name, desc, cost )
157 # @code = code
158 # @name = name
159 # @desc = desc
160 # @cost = cost
161 #
162 # @features = [ ]
163 # end
164 #
165 # def add_feature( feature )
166 # @features << feature
167 # end
168 #
169 # # Support templating of member data.
170 # def get_binding
171 # binding
172 # end
173 #
174 # # ...
175 # end
176 #
177 # # Create template.
178 # template = %{
179 # <html>
180 # <head><title>Ruby Toys -- <%= @name %></title></head>
181 # <body>
182 #
183 # <h1><%= @name %> (<%= @code %>)</h1>
184 # <p><%= @desc %></p>
185 #
186 # <ul>
187 # <% @features.each do |f| %>
188 # <li><b><%= f %></b></li>
189 # <% end %>
190 # </ul>
191 #
192 # <p>
193 # <% if @cost < 10 %>
194 # <b>Only <%= @cost %>!!!</b>
195 # <% else %>
196 # Call for a price, today!
197 # <% end %>
198 # </p>
199 #
200 # </body>
201 # </html>
202 # }.gsub(/^ /, '')
203 #
204 # rhtml = ERB.new(template)
205 #
206 # # Set up template data.
207 # toy = Product.new( "TZ-1002",
208 # "Rubysapien",
209 # "Geek's Best Friend! Responds to Ruby commands...",
210 # 999.95 )
211 # toy.add_feature("Listens for verbal commands in the Ruby language!")
212 # toy.add_feature("Ignores Perl, Java, and all C variants.")
213 # toy.add_feature("Karate-Chop Action!!!")
214 # toy.add_feature("Matz signature on left leg.")
215 # toy.add_feature("Gem studded eyes... Rubies, of course!")
216 #
217 # # Produce result.
218 # rhtml.run(toy.get_binding)
219 #
220 # <i>Generates (some blank lines removed):</i>
221 #
222 # <html>
223 # <head><title>Ruby Toys -- Rubysapien</title></head>
224 # <body>
225 #
226 # <h1>Rubysapien (TZ-1002)</h1>
227 # <p>Geek's Best Friend! Responds to Ruby commands...</p>
228 #
229 # <ul>
230 # <li><b>Listens for verbal commands in the Ruby language!</b></li>
231 # <li><b>Ignores Perl, Java, and all C variants.</b></li>
232 # <li><b>Karate-Chop Action!!!</b></li>
233 # <li><b>Matz signature on left leg.</b></li>
234 # <li><b>Gem studded eyes... Rubies, of course!</b></li>
235 # </ul>
236 #
237 # <p>
238 # Call for a price, today!
239 # </p>
240 #
241 # </body>
242 # </html>
243 #
244 #
245 # == Notes
246 #
247 # There are a variety of templating solutions available in various Ruby projects:
248 # * ERB's big brother, eRuby, works the same but is written in C for speed;
249 # * Amrita (smart at producing HTML/XML);
250 # * cs/Template (written in C for speed);
251 # * RDoc, distributed with Ruby, uses its own template engine, which can be reused elsewhere;
252 # * and others; search the RAA.
253 #
254 # Rails, the web application framework, uses ERB to create views.
255 #
511dc44 initial import
Laurent Sansonetti authored
256 class ERB
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
257 Revision = '$Date:: 2009-10-02 05:04:37 -0700#$' #'
511dc44 initial import
Laurent Sansonetti authored
258
259 # Returns revision information for the erb.rb module.
260 def self.version
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
261 "erb.rb [2.1.0 #{ERB::Revision.split[1]}]"
511dc44 initial import
Laurent Sansonetti authored
262 end
263 end
264
265 #--
266 # ERB::Compiler
267 class ERB
268 class Compiler # :nodoc:
269 class PercentLine # :nodoc:
270 def initialize(str)
271 @value = str
272 end
273 attr_reader :value
274 alias :to_s :value
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
275
276 def empty?
277 @value.empty?
278 end
511dc44 initial import
Laurent Sansonetti authored
279 end
280
281 class Scanner # :nodoc:
282 @scanner_map = {}
283 def self.regist_scanner(klass, trim_mode, percent)
284 @scanner_map[[trim_mode, percent]] = klass
285 end
286
287 def self.default_scanner=(klass)
288 @default_scanner = klass
289 end
290
291 def self.make_scanner(src, trim_mode, percent)
292 klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
293 klass.new(src, trim_mode, percent)
294 end
295
296 def initialize(src, trim_mode, percent)
297 @src = src
298 @stag = nil
299 end
300 attr_accessor :stag
301
302 def scan; end
303 end
304
305 class TrimScanner < Scanner # :nodoc:
306 def initialize(src, trim_mode, percent)
307 super
308 @trim_mode = trim_mode
309 @percent = percent
310 if @trim_mode == '>'
311 @scan_line = self.method(:trim_line1)
312 elsif @trim_mode == '<>'
313 @scan_line = self.method(:trim_line2)
314 elsif @trim_mode == '-'
315 @scan_line = self.method(:explicit_trim_line)
316 else
317 @scan_line = self.method(:scan_line)
318 end
319 end
320 attr_accessor :stag
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
321
511dc44 initial import
Laurent Sansonetti authored
322 def scan(&block)
323 @stag = nil
324 if @percent
325 @src.each_line do |line|
326 percent_line(line, &block)
327 end
328 else
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
329 @scan_line.call(@src, &block)
511dc44 initial import
Laurent Sansonetti authored
330 end
331 nil
332 end
333
334 def percent_line(line, &block)
335 if @stag || line[0] != ?%
336 return @scan_line.call(line, &block)
337 end
338
339 line[0] = ''
340 if line[0] == ?%
341 @scan_line.call(line, &block)
342 else
343 yield(PercentLine.new(line.chomp))
344 end
345 end
346
347 def scan_line(line)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
348 line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
349 tokens.each do |token|
350 next if token.empty?
351 yield(token)
352 end
511dc44 initial import
Laurent Sansonetti authored
353 end
354 end
355
356 def trim_line1(line)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
357 line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
358 tokens.each do |token|
359 next if token.empty?
360 if token == "%>\n"
361 yield('%>')
362 yield(:cr)
363 else
364 yield(token)
365 end
366 end
511dc44 initial import
Laurent Sansonetti authored
367 end
368 end
369
370 def trim_line2(line)
371 head = nil
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
372 line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
373 tokens.each do |token|
374 next if token.empty?
375 head = token unless head
376 if token == "%>\n"
377 yield('%>')
378 if is_erb_stag?(head)
379 yield(:cr)
380 else
381 yield("\n")
382 end
383 head = nil
384 else
385 yield(token)
386 head = nil if token == "\n"
387 end
388 end
511dc44 initial import
Laurent Sansonetti authored
389 end
390 end
391
392 def explicit_trim_line(line)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
393 line.scan(/(.*?)(^[ \t]*<%\-|<%\-|<%%|%%>|<%=|<%#|<%|-%>\n|-%>|%>|\z)/m) do |tokens|
394 tokens.each do |token|
395 next if token.empty?
396 if @stag.nil? && /[ \t]*<%-/ =~ token
397 yield('<%')
398 elsif @stag && token == "-%>\n"
399 yield('%>')
400 yield(:cr)
401 elsif @stag && token == '-%>'
402 yield('%>')
403 else
404 yield(token)
405 end
406 end
407 end
511dc44 initial import
Laurent Sansonetti authored
408 end
409
410 ERB_STAG = %w(<%= <%# <%)
411 def is_erb_stag?(s)
412 ERB_STAG.member?(s)
413 end
414 end
415
416 Scanner.default_scanner = TrimScanner
417
418 class SimpleScanner < Scanner # :nodoc:
419 def scan
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
420 @src.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
421 tokens.each do |token|
422 next if token.empty?
423 yield(token)
424 end
511dc44 initial import
Laurent Sansonetti authored
425 end
426 end
427 end
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
428
511dc44 initial import
Laurent Sansonetti authored
429 Scanner.regist_scanner(SimpleScanner, nil, false)
430
431 begin
432 require 'strscan'
433 class SimpleScanner2 < Scanner # :nodoc:
434 def scan
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
435 stag_reg = /(.*?)(<%%|<%=|<%#|<%|\z)/m
436 etag_reg = /(.*?)(%%>|%>|\z)/m
511dc44 initial import
Laurent Sansonetti authored
437 scanner = StringScanner.new(@src)
438 while ! scanner.eos?
439 scanner.scan(@stag ? etag_reg : stag_reg)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
440 yield(scanner[1])
441 yield(scanner[2])
511dc44 initial import
Laurent Sansonetti authored
442 end
443 end
444 end
445 Scanner.regist_scanner(SimpleScanner2, nil, false)
446
447 class ExplicitScanner < Scanner # :nodoc:
448 def scan
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
449 stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%=|<%#|<%-|<%|\z)/m
450 etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
511dc44 initial import
Laurent Sansonetti authored
451 scanner = StringScanner.new(@src)
452 while ! scanner.eos?
453 scanner.scan(@stag ? etag_reg : stag_reg)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
454 yield(scanner[1])
455
511dc44 initial import
Laurent Sansonetti authored
456 elem = scanner[2]
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
457 if /[ \t]*<%-/ =~ elem
458 yield('<%')
459 elsif elem == '-%>'
511dc44 initial import
Laurent Sansonetti authored
460 yield('%>')
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
461 yield(:cr) if scanner.scan(/(\n|\z)/)
511dc44 initial import
Laurent Sansonetti authored
462 else
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
463 yield(elem)
511dc44 initial import
Laurent Sansonetti authored
464 end
465 end
466 end
467 end
468 Scanner.regist_scanner(ExplicitScanner, '-', false)
469
470 rescue LoadError
471 end
472
473 class Buffer # :nodoc:
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
474 def initialize(compiler, enc=nil)
511dc44 initial import
Laurent Sansonetti authored
475 @compiler = compiler
476 @line = []
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
477 @script = enc ? "#coding:#{enc.to_s}\n" : ""
511dc44 initial import
Laurent Sansonetti authored
478 @compiler.pre_cmd.each do |x|
479 push(x)
480 end
481 end
482 attr_reader :script
483
484 def push(cmd)
485 @line << cmd
486 end
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
487
511dc44 initial import
Laurent Sansonetti authored
488 def cr
489 @script << (@line.join('; '))
490 @line = []
491 @script << "\n"
492 end
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
493
511dc44 initial import
Laurent Sansonetti authored
494 def close
495 return unless @line
496 @compiler.post_cmd.each do |x|
497 push(x)
498 end
499 @script << (@line.join('; '))
500 @line = nil
501 end
502 end
503
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
504 def content_dump(s)
505 n = s.count("\n")
506 if n > 0
507 s.dump + "\n" * n
508 else
509 s.dump
510 end
511 end
512
511dc44 initial import
Laurent Sansonetti authored
513 def compile(s)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
514 enc = s.encoding
515 raise ArgumentError, "#{enc} is not ASCII compatible" if enc.dummy?
516 s = s.dup.force_encoding("ASCII-8BIT") # don't use constant Enoding::ASCII_8BIT for miniruby
517 enc = detect_magic_comment(s) || enc
518 out = Buffer.new(self, enc)
511dc44 initial import
Laurent Sansonetti authored
519
520 content = ''
521 scanner = make_scanner(s)
522 scanner.scan do |token|
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
523 next if token.nil?
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
524 next if token == ''
511dc44 initial import
Laurent Sansonetti authored
525 if scanner.stag.nil?
526 case token
527 when PercentLine
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
528 out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
511dc44 initial import
Laurent Sansonetti authored
529 content = ''
530 out.push(token.to_s)
531 out.cr
532 when :cr
533 out.cr
534 when '<%', '<%=', '<%#'
535 scanner.stag = token
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
536 out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
511dc44 initial import
Laurent Sansonetti authored
537 content = ''
538 when "\n"
539 content << "\n"
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
540 out.push("#{@put_cmd} #{content_dump(content)}")
511dc44 initial import
Laurent Sansonetti authored
541 content = ''
542 when '<%%'
543 content << '<%'
544 else
545 content << token
546 end
547 else
548 case token
549 when '%>'
550 case scanner.stag
551 when '<%'
552 if content[-1] == ?\n
553 content.chop!
554 out.push(content)
555 out.cr
556 else
557 out.push(content)
558 end
559 when '<%='
560 out.push("#{@insert_cmd}((#{content}).to_s)")
561 when '<%#'
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
562 # out.push("# #{content_dump(content)}")
511dc44 initial import
Laurent Sansonetti authored
563 end
564 scanner.stag = nil
565 content = ''
566 when '%%>'
567 content << '%>'
568 else
569 content << token
570 end
571 end
572 end
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
573 out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
511dc44 initial import
Laurent Sansonetti authored
574 out.close
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
575 return out.script, enc
511dc44 initial import
Laurent Sansonetti authored
576 end
577
578 def prepare_trim_mode(mode)
579 case mode
580 when 1
581 return [false, '>']
582 when 2
583 return [false, '<>']
584 when 0
585 return [false, nil]
586 when String
587 perc = mode.include?('%')
588 if mode.include?('-')
589 return [perc, '-']
590 elsif mode.include?('<>')
591 return [perc, '<>']
592 elsif mode.include?('>')
593 return [perc, '>']
594 else
595 [perc, nil]
596 end
597 else
598 return [false, nil]
599 end
600 end
601
602 def make_scanner(src)
603 Scanner.make_scanner(src, @trim_mode, @percent)
604 end
605
606 def initialize(trim_mode)
607 @percent, @trim_mode = prepare_trim_mode(trim_mode)
608 @put_cmd = 'print'
609 @insert_cmd = @put_cmd
610 @pre_cmd = []
611 @post_cmd = []
612 end
613 attr_reader :percent, :trim_mode
614 attr_accessor :put_cmd, :insert_cmd, :pre_cmd, :post_cmd
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
615
616 private
617 def detect_magic_comment(s)
618 if /\A<%#(.*)%>/ =~ s or (@percent and /\A%#(.*)/ =~ s)
619 comment = $1
620 comment = $1 if comment[/-\*-\s*(.*?)\s*-*-$/]
621 if %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" =~ comment
622 enc = $1.sub(/-(?:mac|dos|unix)/i, '')
623 enc = Encoding.find(enc)
624 end
625 end
626 end
511dc44 initial import
Laurent Sansonetti authored
627 end
628 end
629
630 #--
631 # ERB
632 class ERB
633 #
634 # Constructs a new ERB object with the template specified in _str_.
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
635 #
511dc44 initial import
Laurent Sansonetti authored
636 # An ERB object works by building a chunk of Ruby code that will output
637 # the completed template when run. If _safe_level_ is set to a non-nil value,
638 # ERB code will be run in a separate thread with <b>$SAFE</b> set to the
639 # provided level.
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
640 #
511dc44 initial import
Laurent Sansonetti authored
641 # If _trim_mode_ is passed a String containing one or more of the following
642 # modifiers, ERB will adjust its code generation as listed:
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
643 #
511dc44 initial import
Laurent Sansonetti authored
644 # % enables Ruby code processing for lines beginning with %
645 # <> omit newline for lines starting with <% and ending in %>
646 # > omit newline for lines ending in %>
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
647 #
511dc44 initial import
Laurent Sansonetti authored
648 # _eoutvar_ can be used to set the name of the variable ERB will build up
649 # its output in. This is useful when you need to run multiple ERB
650 # templates through the same binding and/or when you want to control where
651 # output ends up. Pass the name of the variable to be used inside a String.
652 #
653 # === Example
654 #
655 # require "erb"
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
656 #
511dc44 initial import
Laurent Sansonetti authored
657 # # build data class
658 # class Listings
659 # PRODUCT = { :name => "Chicken Fried Steak",
660 # :desc => "A well messages pattie, breaded and fried.",
661 # :cost => 9.95 }
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
662 #
511dc44 initial import
Laurent Sansonetti authored
663 # attr_reader :product, :price
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
664 #
511dc44 initial import
Laurent Sansonetti authored
665 # def initialize( product = "", price = "" )
666 # @product = product
667 # @price = price
668 # end
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
669 #
511dc44 initial import
Laurent Sansonetti authored
670 # def build
671 # b = binding
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
672 # # create and run templates, filling member data variables
511dc44 initial import
Laurent Sansonetti authored
673 # ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "", "@product").result b
674 # <%= PRODUCT[:name] %>
675 # <%= PRODUCT[:desc] %>
676 # END_PRODUCT
677 # ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b
678 # <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
679 # <%= PRODUCT[:desc] %>
680 # END_PRICE
681 # end
682 # end
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
683 #
511dc44 initial import
Laurent Sansonetti authored
684 # # setup template data
685 # listings = Listings.new
686 # listings.build
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
687 #
511dc44 initial import
Laurent Sansonetti authored
688 # puts listings.product + "\n" + listings.price
689 #
690 # _Generates_
691 #
692 # Chicken Fried Steak
693 # A well messages pattie, breaded and fried.
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
694 #
511dc44 initial import
Laurent Sansonetti authored
695 # Chicken Fried Steak -- 9.95
696 # A well messages pattie, breaded and fried.
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
697 #
511dc44 initial import
Laurent Sansonetti authored
698 def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
699 @safe_level = safe_level
700 compiler = ERB::Compiler.new(trim_mode)
701 set_eoutvar(compiler, eoutvar)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
702 @src, @enc = *compiler.compile(str)
511dc44 initial import
Laurent Sansonetti authored
703 @filename = nil
704 end
705
706 # The Ruby code generated by ERB
707 attr_reader :src
708
709 # The optional _filename_ argument passed to Kernel#eval when the ERB code
710 # is run
711 attr_accessor :filename
712
713 #
714 # Can be used to set _eoutvar_ as described in ERB#new. It's probably easier
715 # to just use the constructor though, since calling this method requires the
716 # setup of an ERB _compiler_ object.
717 #
718 def set_eoutvar(compiler, eoutvar = '_erbout')
719 compiler.put_cmd = "#{eoutvar}.concat"
720 compiler.insert_cmd = "#{eoutvar}.concat"
721
722 cmd = []
723 cmd.push "#{eoutvar} = ''"
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
724
511dc44 initial import
Laurent Sansonetti authored
725 compiler.pre_cmd = cmd
726
727 cmd = []
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
728 cmd.push("#{eoutvar}.force_encoding(__ENCODING__)")
511dc44 initial import
Laurent Sansonetti authored
729
730 compiler.post_cmd = cmd
731 end
732
733 # Generate results and print them. (see ERB#result)
734 def run(b=TOPLEVEL_BINDING)
735 print self.result(b)
736 end
737
738 #
739 # Executes the generated ERB code to produce a completed template, returning
740 # the results of that code. (See ERB#new for details on how this process can
741 # be affected by _safe_level_.)
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
742 #
511dc44 initial import
Laurent Sansonetti authored
743 # _b_ accepts a Binding or Proc object which is used to set the context of
744 # code evaluation.
745 #
746 def result(b=TOPLEVEL_BINDING)
747 if @safe_level
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
748 proc {
511dc44 initial import
Laurent Sansonetti authored
749 $SAFE = @safe_level
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
750 eval(@src, b, (@filename || '(erb)'), 0)
751 }.call
511dc44 initial import
Laurent Sansonetti authored
752 else
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
753 eval(@src, b, (@filename || '(erb)'), 0)
511dc44 initial import
Laurent Sansonetti authored
754 end
755 end
756
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
757 # Define _methodname_ as instance method of _mod_ from compiled ruby source.
758 #
759 # example:
760 # filename = 'example.rhtml' # 'arg1' and 'arg2' are used in example.rhtml
761 # erb = ERB.new(File.read(filename))
762 # erb.def_method(MyClass, 'render(arg1, arg2)', filename)
763 # print MyClass.new.render('foo', 123)
764 def def_method(mod, methodname, fname='(ERB)')
765 src = self.src
766 magic_comment = "#coding:#{@enc}\n"
767 mod.module_eval do
768 eval(magic_comment + "def #{methodname}\n" + src + "\nend\n", binding, fname, -2)
769 end
511dc44 initial import
Laurent Sansonetti authored
770 end
771
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
772 # Create unnamed module, define _methodname_ as instance method of it, and return it.
773 #
774 # example:
775 # filename = 'example.rhtml' # 'arg1' and 'arg2' are used in example.rhtml
776 # erb = ERB.new(File.read(filename))
777 # erb.filename = filename
778 # MyModule = erb.def_module('render(arg1, arg2)')
779 # class MyClass
780 # include MyModule
781 # end
782 def def_module(methodname='erb')
511dc44 initial import
Laurent Sansonetti authored
783 mod = Module.new
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
784 def_method(mod, methodname, @filename || '(ERB)')
511dc44 initial import
Laurent Sansonetti authored
785 mod
786 end
787
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
788 # Define unnamed class which has _methodname_ as instance method, and return it.
789 #
790 # example:
791 # class MyClass_
792 # def initialize(arg1, arg2)
793 # @arg1 = arg1; @arg2 = arg2
794 # end
795 # end
796 # filename = 'example.rhtml' # @arg1 and @arg2 are used in example.rhtml
797 # erb = ERB.new(File.read(filename))
798 # erb.filename = filename
799 # MyClass = erb.def_class(MyClass_, 'render()')
800 # print MyClass.new('foo', 123).render()
801 def def_class(superklass=Object, methodname='result')
511dc44 initial import
Laurent Sansonetti authored
802 cls = Class.new(superklass)
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
803 def_method(cls, methodname, @filename || '(ERB)')
511dc44 initial import
Laurent Sansonetti authored
804 cls
805 end
806 end
807
808 #--
809 # ERB::Util
810 class ERB
811 # A utility module for conversion routines, often handy in HTML generation.
812 module Util
813 public
814 #
815 # A utility method for escaping HTML tag characters in _s_.
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
816 #
511dc44 initial import
Laurent Sansonetti authored
817 # require "erb"
818 # include ERB::Util
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
819 #
511dc44 initial import
Laurent Sansonetti authored
820 # puts html_escape("is a > 0 & a < 10?")
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
821 #
511dc44 initial import
Laurent Sansonetti authored
822 # _Generates_
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
823 #
511dc44 initial import
Laurent Sansonetti authored
824 # is a &gt; 0 &amp; a &lt; 10?
825 #
826 def html_escape(s)
827 s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
828 end
829 alias h html_escape
830 module_function :h
831 module_function :html_escape
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
832
511dc44 initial import
Laurent Sansonetti authored
833 #
834 # A utility method for encoding the String _s_ as a URL.
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
835 #
511dc44 initial import
Laurent Sansonetti authored
836 # require "erb"
837 # include ERB::Util
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
838 #
511dc44 initial import
Laurent Sansonetti authored
839 # puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
840 #
511dc44 initial import
Laurent Sansonetti authored
841 # _Generates_
467bc1b Update library and removing working tags
Thibault Martin-Lagardette authored
842 #
511dc44 initial import
Laurent Sansonetti authored
843 # Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
844 #
845 def url_encode(s)
eee9d7b sync with ruby trunk r15665
Laurent Sansonetti authored
846 s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) {
847 sprintf("%%%02X", $&.unpack("C")[0])
848 }
511dc44 initial import
Laurent Sansonetti authored
849 end
850 alias u url_encode
851 module_function :u
852 module_function :url_encode
853 end
854 end
855
856 #--
857 # ERB::DefMethod
858 class ERB
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
859 # Utility module to define eRuby script as instance method.
860 #
861 # === Example
862 #
863 # example.rhtml:
864 # <% for item in @items %>
865 # <b><%= item %></b>
866 # <% end %>
867 #
868 # example.rb:
869 # require 'erb'
870 # class MyClass
871 # extend ERB::DefMethod
872 # def_erb_method('render()', 'example.rhtml')
873 # def initialize(items)
874 # @items = items
875 # end
876 # end
877 # print MyClass.new([10,20,30]).render()
878 #
879 # result:
880 #
881 # <b>10</b>
882 #
883 # <b>20</b>
884 #
885 # <b>30</b>
886 #
887 module DefMethod
511dc44 initial import
Laurent Sansonetti authored
888 public
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
889 # define _methodname_ as instance method of current module, using ERB object or eRuby file
890 def def_erb_method(methodname, erb_or_fname)
891 if erb_or_fname.kind_of? String
892 fname = erb_or_fname
893 erb = ERB.new(File.read(fname))
894 erb.def_method(self, methodname, fname)
511dc44 initial import
Laurent Sansonetti authored
895 else
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
896 erb = erb_or_fname
897 erb.def_method(self, methodname, erb.filename || '(ERB)')
511dc44 initial import
Laurent Sansonetti authored
898 end
899 end
900 module_function :def_erb_method
901 end
902 end
Something went wrong with that request. Please try again.