PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/jruby-1.1.6RC1/lib/ruby/1.8/erb.rb

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