PageRenderTime 64ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/ruby/1.9.1/gems/erubis-2.7.0/contrib/erubis

https://github.com/KaylaStuebbe/uwsp-virtual-tour-server
Ruby | 3468 lines | 2042 code | 646 blank | 780 comment | 295 complexity | b6ee1e8b2f6e4b4a85b4afb630b90810 MD5 | raw file
Possible License(s): Apache-2.0, MIT, GPL-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. #!/usr/bin/env ruby
  2. ###
  3. ### $Release: 2.7.0 $
  4. ### copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  5. ###
  6. #--begin of require 'erubis/main'
  7. ###
  8. ### $Release: 2.7.0 $
  9. ### copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  10. ###
  11. require 'yaml'
  12. #--begin of require 'erubis'
  13. ##
  14. ## $Release: 2.7.0 $
  15. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  16. ##
  17. ##
  18. ## an implementation of eRuby
  19. ##
  20. ## ex.
  21. ## input = <<'END'
  22. ## <ul>
  23. ## <% for item in @list %>
  24. ## <li><%= item %>
  25. ## <%== item %></li>
  26. ## <% end %>
  27. ## </ul>
  28. ## END
  29. ## list = ['<aaa>', 'b&b', '"ccc"']
  30. ## eruby = Erubis::Eruby.new(input)
  31. ## puts "--- code ---"
  32. ## puts eruby.src
  33. ## puts "--- result ---"
  34. ## context = Erubis::Context.new() # or new(:list=>list)
  35. ## context[:list] = list
  36. ## puts eruby.evaluate(context)
  37. ##
  38. ## result:
  39. ## --- source ---
  40. ## _buf = ''; _buf << '<ul>
  41. ## '; for item in @list
  42. ## _buf << ' <li>'; _buf << ( item ).to_s; _buf << '
  43. ## '; _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</li>
  44. ## '; end
  45. ## _buf << '</ul>
  46. ## ';
  47. ## _buf.to_s
  48. ## --- result ---
  49. ## <ul>
  50. ## <li><aaa>
  51. ## &lt;aaa&gt;</li>
  52. ## <li>b&b
  53. ## b&amp;b</li>
  54. ## <li>"ccc"
  55. ## &quot;ccc&quot;</li>
  56. ## </ul>
  57. ##
  58. module Erubis
  59. VERSION = ('$Release: 2.7.0 $' =~ /([.\d]+)/) && $1
  60. end
  61. #--begin of require 'erubis/engine'
  62. ##
  63. ## $Release: 2.7.0 $
  64. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  65. ##
  66. #--begin of require 'erubis/generator'
  67. ##
  68. ## $Release: 2.7.0 $
  69. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  70. ##
  71. #--begin of require 'erubis/util'
  72. ##
  73. ## $Release: 2.7.0 $
  74. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  75. ##
  76. module Kernel
  77. ##
  78. ## raise NotImplementedError
  79. ##
  80. def not_implemented #:doc:
  81. backtrace = caller()
  82. method_name = (backtrace.shift =~ /`(\w+)'$/) && $1
  83. mesg = "class #{self.class.name} must implement abstract method '#{method_name}()'."
  84. #mesg = "#{self.class.name}##{method_name}() is not implemented."
  85. err = NotImplementedError.new mesg
  86. err.set_backtrace backtrace
  87. raise err
  88. end
  89. private :not_implemented
  90. end
  91. #--end of require 'erubis/util'
  92. module Erubis
  93. ##
  94. ## code generator, called by Converter module
  95. ##
  96. module Generator
  97. def self.supported_properties() # :nodoc:
  98. return [
  99. [:escapefunc, nil, "escape function name"],
  100. ]
  101. end
  102. attr_accessor :escapefunc
  103. def init_generator(properties={})
  104. @escapefunc = properties[:escapefunc]
  105. end
  106. ## (abstract) escape text string
  107. ##
  108. ## ex.
  109. ## def escape_text(text)
  110. ## return text.dump
  111. ## # or return "'" + text.gsub(/['\\]/, '\\\\\&') + "'"
  112. ## end
  113. def escape_text(text)
  114. not_implemented
  115. end
  116. ## return escaped expression code (ex. 'h(...)' or 'htmlspecialchars(...)')
  117. def escaped_expr(code)
  118. code.strip!
  119. return "#{@escapefunc}(#{code})"
  120. end
  121. ## (abstract) add @preamble to src
  122. def add_preamble(src)
  123. not_implemented
  124. end
  125. ## (abstract) add text string to src
  126. def add_text(src, text)
  127. not_implemented
  128. end
  129. ## (abstract) add statement code to src
  130. def add_stmt(src, code)
  131. not_implemented
  132. end
  133. ## (abstract) add expression literal code to src. this is called by add_expr().
  134. def add_expr_literal(src, code)
  135. not_implemented
  136. end
  137. ## (abstract) add escaped expression code to src. this is called by add_expr().
  138. def add_expr_escaped(src, code)
  139. not_implemented
  140. end
  141. ## (abstract) add expression code to src for debug. this is called by add_expr().
  142. def add_expr_debug(src, code)
  143. not_implemented
  144. end
  145. ## (abstract) add @postamble to src
  146. def add_postamble(src)
  147. not_implemented
  148. end
  149. end
  150. end
  151. #--end of require 'erubis/generator'
  152. #--begin of require 'erubis/converter'
  153. ##
  154. ## $Release: 2.7.0 $
  155. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  156. ##
  157. #--already included require 'erubis/util'
  158. module Erubis
  159. ##
  160. ## convert
  161. ##
  162. module Converter
  163. attr_accessor :preamble, :postamble, :escape
  164. def self.supported_properties # :nodoc:
  165. return [
  166. [:preamble, nil, "preamble (no preamble when false)"],
  167. [:postamble, nil, "postamble (no postamble when false)"],
  168. [:escape, nil, "escape expression or not in default"],
  169. ]
  170. end
  171. def init_converter(properties={})
  172. @preamble = properties[:preamble]
  173. @postamble = properties[:postamble]
  174. @escape = properties[:escape]
  175. end
  176. ## convert input string into target language
  177. def convert(input)
  178. codebuf = "" # or []
  179. @preamble.nil? ? add_preamble(codebuf) : (@preamble && (codebuf << @preamble))
  180. convert_input(codebuf, input)
  181. @postamble.nil? ? add_postamble(codebuf) : (@postamble && (codebuf << @postamble))
  182. @_proc = nil # clear cached proc object
  183. return codebuf # or codebuf.join()
  184. end
  185. protected
  186. ##
  187. ## detect spaces at beginning of line
  188. ##
  189. def detect_spaces_at_bol(text, is_bol)
  190. lspace = nil
  191. if text.empty?
  192. lspace = "" if is_bol
  193. elsif text[-1] == ?\n
  194. lspace = ""
  195. else
  196. rindex = text.rindex(?\n)
  197. if rindex
  198. s = text[rindex+1..-1]
  199. if s =~ /\A[ \t]*\z/
  200. lspace = s
  201. #text = text[0..rindex]
  202. text[rindex+1..-1] = ''
  203. end
  204. else
  205. if is_bol && text =~ /\A[ \t]*\z/
  206. #lspace = text
  207. #text = nil
  208. lspace = text.dup
  209. text[0..-1] = ''
  210. end
  211. end
  212. end
  213. return lspace
  214. end
  215. ##
  216. ## (abstract) convert input to code
  217. ##
  218. def convert_input(codebuf, input)
  219. not_implemented
  220. end
  221. end
  222. module Basic
  223. end
  224. ##
  225. ## basic converter which supports '<% ... %>' notation.
  226. ##
  227. module Basic::Converter
  228. include Erubis::Converter
  229. def self.supported_properties # :nodoc:
  230. return [
  231. [:pattern, '<% %>', "embed pattern"],
  232. [:trim, true, "trim spaces around <% ... %>"],
  233. ]
  234. end
  235. attr_accessor :pattern, :trim
  236. def init_converter(properties={})
  237. super(properties)
  238. @pattern = properties[:pattern]
  239. @trim = properties[:trim] != false
  240. end
  241. protected
  242. ## return regexp of pattern to parse eRuby script
  243. def pattern_regexp(pattern)
  244. @prefix, @postfix = pattern.split() # '<% %>' => '<%', '%>'
  245. #return /(.*?)(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m
  246. #return /(^[ \t]*)?#{@prefix}(=+|\#)?(.*?)-?#{@postfix}([ \t]*\r?\n)?/m
  247. return /#{@prefix}(=+|-|\#|%)?(.*?)([-=])?#{@postfix}([ \t]*\r?\n)?/m
  248. end
  249. module_function :pattern_regexp
  250. #DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
  251. #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
  252. #DEFAULT_REGEXP = /<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
  253. DEFAULT_REGEXP = pattern_regexp('<% %>')
  254. public
  255. def convert_input(src, input)
  256. pat = @pattern
  257. regexp = pat.nil? || pat == '<% %>' ? DEFAULT_REGEXP : pattern_regexp(pat)
  258. pos = 0
  259. is_bol = true # is beginning of line
  260. input.scan(regexp) do |indicator, code, tailch, rspace|
  261. match = Regexp.last_match()
  262. len = match.begin(0) - pos
  263. text = input[pos, len]
  264. pos = match.end(0)
  265. ch = indicator ? indicator[0] : nil
  266. lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
  267. is_bol = rspace ? true : false
  268. add_text(src, text) if text && !text.empty?
  269. ## * when '<%= %>', do nothing
  270. ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
  271. if ch == ?= # <%= %>
  272. rspace = nil if tailch && !tailch.empty?
  273. add_text(src, lspace) if lspace
  274. add_expr(src, code, indicator)
  275. add_text(src, rspace) if rspace
  276. elsif ch == ?\# # <%# %>
  277. n = code.count("\n") + (rspace ? 1 : 0)
  278. if @trim && lspace && rspace
  279. add_stmt(src, "\n" * n)
  280. else
  281. add_text(src, lspace) if lspace
  282. add_stmt(src, "\n" * n)
  283. add_text(src, rspace) if rspace
  284. end
  285. elsif ch == ?% # <%% %>
  286. s = "#{lspace}#{@prefix||='<%'}#{code}#{tailch}#{@postfix||='%>'}#{rspace}"
  287. add_text(src, s)
  288. else # <% %>
  289. if @trim && lspace && rspace
  290. add_stmt(src, "#{lspace}#{code}#{rspace}")
  291. else
  292. add_text(src, lspace) if lspace
  293. add_stmt(src, code)
  294. add_text(src, rspace) if rspace
  295. end
  296. end
  297. end
  298. #rest = $' || input # ruby1.8
  299. rest = pos == 0 ? input : input[pos..-1] # ruby1.9
  300. add_text(src, rest)
  301. end
  302. ## add expression code to src
  303. def add_expr(src, code, indicator)
  304. case indicator
  305. when '='
  306. @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
  307. when '=='
  308. @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
  309. when '==='
  310. add_expr_debug(src, code)
  311. end
  312. end
  313. end
  314. module PI
  315. end
  316. ##
  317. ## Processing Instructions (PI) converter for XML.
  318. ## this class converts '<?rb ... ?>' and '${...}' notation.
  319. ##
  320. module PI::Converter
  321. include Erubis::Converter
  322. def self.desc # :nodoc:
  323. "use processing instructions (PI) instead of '<% %>'"
  324. end
  325. def self.supported_properties # :nodoc:
  326. return [
  327. [:trim, true, "trim spaces around <% ... %>"],
  328. [:pi, 'rb', "PI (Processing Instrunctions) name"],
  329. [:embchar, '@', "char for embedded expression pattern('@{...}@')"],
  330. [:pattern, '<% %>', "embed pattern"],
  331. ]
  332. end
  333. attr_accessor :pi, :prefix
  334. def init_converter(properties={})
  335. super(properties)
  336. @trim = properties.fetch(:trim, true)
  337. @pi = properties[:pi] if properties[:pi]
  338. @embchar = properties[:embchar] || '@'
  339. @pattern = properties[:pattern]
  340. @pattern = '<% %>' if @pattern.nil? #|| @pattern == true
  341. end
  342. def convert(input)
  343. code = super(input)
  344. return @header || @footer ? "#{@header}#{code}#{@footer}" : code
  345. end
  346. protected
  347. def convert_input(codebuf, input)
  348. unless @regexp
  349. @pi ||= 'e'
  350. ch = Regexp.escape(@embchar)
  351. if @pattern
  352. left, right = @pattern.split(' ')
  353. @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/m
  354. else
  355. @regexp = /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?|#{ch}(!*)?\{(.*?)\}#{ch}/m
  356. end
  357. end
  358. #
  359. is_bol = true
  360. pos = 0
  361. input.scan(@regexp) do |pi_arg, stmt, rspace,
  362. indicator1, expr1, indicator2, expr2|
  363. match = Regexp.last_match
  364. len = match.begin(0) - pos
  365. text = input[pos, len]
  366. pos = match.end(0)
  367. lspace = stmt ? detect_spaces_at_bol(text, is_bol) : nil
  368. is_bol = stmt && rspace ? true : false
  369. add_text(codebuf, text) # unless text.empty?
  370. #
  371. if stmt
  372. if @trim && lspace && rspace
  373. add_pi_stmt(codebuf, "#{lspace}#{stmt}#{rspace}", pi_arg)
  374. else
  375. add_text(codebuf, lspace) if lspace
  376. add_pi_stmt(codebuf, stmt, pi_arg)
  377. add_text(codebuf, rspace) if rspace
  378. end
  379. else
  380. add_pi_expr(codebuf, expr1 || expr2, indicator1 || indicator2)
  381. end
  382. end
  383. #rest = $' || input # ruby1.8
  384. rest = pos == 0 ? input : input[pos..-1] # ruby1.9
  385. add_text(codebuf, rest)
  386. end
  387. #--
  388. #def convert_input(codebuf, input)
  389. # parse_stmts(codebuf, input)
  390. # #parse_stmts2(codebuf, input)
  391. #end
  392. #
  393. #def parse_stmts(codebuf, input)
  394. # #regexp = pattern_regexp(@pattern)
  395. # @pi ||= 'e'
  396. # @stmt_pattern ||= /<\?#{@pi}(?:-(\w+))?(\s.*?)\?>([ \t]*\r?\n)?/m
  397. # is_bol = true
  398. # pos = 0
  399. # input.scan(@stmt_pattern) do |pi_arg, code, rspace|
  400. # match = Regexp.last_match
  401. # len = match.begin(0) - pos
  402. # text = input[pos, len]
  403. # pos = match.end(0)
  404. # lspace = detect_spaces_at_bol(text, is_bol)
  405. # is_bol = rspace ? true : false
  406. # parse_exprs(codebuf, text) # unless text.empty?
  407. # if @trim && lspace && rspace
  408. # add_pi_stmt(codebuf, "#{lspace}#{code}#{rspace}", pi_arg)
  409. # else
  410. # add_text(codebuf, lspace)
  411. # add_pi_stmt(codebuf, code, pi_arg)
  412. # add_text(codebuf, rspace)
  413. # end
  414. # end
  415. # rest = $' || input
  416. # parse_exprs(codebuf, rest)
  417. #end
  418. #
  419. #def parse_exprs(codebuf, input)
  420. # unless @expr_pattern
  421. # ch = Regexp.escape(@embchar)
  422. # if @pattern
  423. # left, right = @pattern.split(' ')
  424. # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}|#{left}(=+)(.*?)#{right}/
  425. # else
  426. # @expr_pattern = /#{ch}(!*)?\{(.*?)\}#{ch}/
  427. # end
  428. # end
  429. # pos = 0
  430. # input.scan(@expr_pattern) do |indicator1, code1, indicator2, code2|
  431. # indicator = indicator1 || indicator2
  432. # code = code1 || code2
  433. # match = Regexp.last_match
  434. # len = match.begin(0) - pos
  435. # text = input[pos, len]
  436. # pos = match.end(0)
  437. # add_text(codebuf, text) # unless text.empty?
  438. # add_pi_expr(codebuf, code, indicator)
  439. # end
  440. # rest = $' || input
  441. # add_text(codebuf, rest)
  442. #end
  443. #++
  444. def add_pi_stmt(codebuf, code, pi_arg) # :nodoc:
  445. case pi_arg
  446. when nil ; add_stmt(codebuf, code)
  447. when 'header' ; @header = code
  448. when 'footer' ; @footer = code
  449. when 'comment'; add_stmt(codebuf, "\n" * code.count("\n"))
  450. when 'value' ; add_expr_literal(codebuf, code)
  451. else ; add_stmt(codebuf, code)
  452. end
  453. end
  454. def add_pi_expr(codebuf, code, indicator) # :nodoc:
  455. case indicator
  456. when nil, '', '==' # @{...}@ or <%== ... %>
  457. @escape == false ? add_expr_literal(codebuf, code) : add_expr_escaped(codebuf, code)
  458. when '!', '=' # @!{...}@ or <%= ... %>
  459. @escape == false ? add_expr_escaped(codebuf, code) : add_expr_literal(codebuf, code)
  460. when '!!', '===' # @!!{...}@ or <%=== ... %>
  461. add_expr_debug(codebuf, code)
  462. else
  463. # ignore
  464. end
  465. end
  466. end
  467. end
  468. #--end of require 'erubis/converter'
  469. #--begin of require 'erubis/evaluator'
  470. ##
  471. ## $Release: 2.7.0 $
  472. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  473. ##
  474. #--begin of require 'erubis/error'
  475. ##
  476. ## $Release: 2.7.0 $
  477. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  478. ##
  479. module Erubis
  480. ##
  481. ## base error class
  482. ##
  483. class ErubisError < StandardError
  484. end
  485. ##
  486. ## raised when method or function is not supported
  487. ##
  488. class NotSupportedError < ErubisError
  489. end
  490. end
  491. #--end of require 'erubis/error'
  492. #--begin of require 'erubis/context'
  493. ##
  494. ## $Release: 2.7.0 $
  495. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  496. ##
  497. module Erubis
  498. ##
  499. ## context object for Engine#evaluate
  500. ##
  501. ## ex.
  502. ## template = <<'END'
  503. ## Hello <%= @user %>!
  504. ## <% for item in @list %>
  505. ## - <%= item %>
  506. ## <% end %>
  507. ## END
  508. ##
  509. ## context = Erubis::Context.new(:user=>'World', :list=>['a','b','c'])
  510. ## # or
  511. ## # context = Erubis::Context.new
  512. ## # context[:user] = 'World'
  513. ## # context[:list] = ['a', 'b', 'c']
  514. ##
  515. ## eruby = Erubis::Eruby.new(template)
  516. ## print eruby.evaluate(context)
  517. ##
  518. class Context
  519. include Enumerable
  520. def initialize(hash=nil)
  521. hash.each do |name, value|
  522. self[name] = value
  523. end if hash
  524. end
  525. def [](key)
  526. return instance_variable_get("@#{key}")
  527. end
  528. def []=(key, value)
  529. return instance_variable_set("@#{key}", value)
  530. end
  531. def keys
  532. return instance_variables.collect { |name| name[1..-1] }
  533. end
  534. def each
  535. instance_variables.each do |name|
  536. key = name[1..-1]
  537. value = instance_variable_get(name)
  538. yield(key, value)
  539. end
  540. end
  541. def to_hash
  542. hash = {}
  543. self.keys.each { |key| hash[key] = self[key] }
  544. return hash
  545. end
  546. def update(context_or_hash)
  547. arg = context_or_hash
  548. if arg.is_a?(Hash)
  549. arg.each do |key, val|
  550. self[key] = val
  551. end
  552. else
  553. arg.instance_variables.each do |varname|
  554. key = varname[1..-1]
  555. val = arg.instance_variable_get(varname)
  556. self[key] = val
  557. end
  558. end
  559. end
  560. end
  561. end
  562. #--end of require 'erubis/context'
  563. module Erubis
  564. EMPTY_BINDING = binding()
  565. ##
  566. ## evaluate code
  567. ##
  568. module Evaluator
  569. def self.supported_properties # :nodoc:
  570. return []
  571. end
  572. attr_accessor :src, :filename
  573. def init_evaluator(properties)
  574. @filename = properties[:filename]
  575. end
  576. def result(*args)
  577. raise NotSupportedError.new("evaluation of code except Ruby is not supported.")
  578. end
  579. def evaluate(*args)
  580. raise NotSupportedError.new("evaluation of code except Ruby is not supported.")
  581. end
  582. end
  583. ##
  584. ## evaluator for Ruby
  585. ##
  586. module RubyEvaluator
  587. include Evaluator
  588. def self.supported_properties # :nodoc:
  589. list = Evaluator.supported_properties
  590. return list
  591. end
  592. ## eval(@src) with binding object
  593. def result(_binding_or_hash=TOPLEVEL_BINDING)
  594. _arg = _binding_or_hash
  595. if _arg.is_a?(Hash)
  596. _b = binding()
  597. eval _arg.collect{|k,v| "#{k} = _arg[#{k.inspect}]; "}.join, _b
  598. elsif _arg.is_a?(Binding)
  599. _b = _arg
  600. elsif _arg.nil?
  601. _b = binding()
  602. else
  603. raise ArgumentError.new("#{self.class.name}#result(): argument should be Binding or Hash but passed #{_arg.class.name} object.")
  604. end
  605. return eval(@src, _b, (@filename || '(erubis'))
  606. end
  607. ## invoke context.instance_eval(@src)
  608. def evaluate(_context=Context.new)
  609. _context = Context.new(_context) if _context.is_a?(Hash)
  610. #return _context.instance_eval(@src, @filename || '(erubis)')
  611. #@_proc ||= eval("proc { #{@src} }", Erubis::EMPTY_BINDING, @filename || '(erubis)')
  612. @_proc ||= eval("proc { #{@src} }", binding(), @filename || '(erubis)')
  613. return _context.instance_eval(&@_proc)
  614. end
  615. ## if object is an Class or Module then define instance method to it,
  616. ## else define singleton method to it.
  617. def def_method(object, method_name, filename=nil)
  618. m = object.is_a?(Module) ? :module_eval : :instance_eval
  619. object.__send__(m, "def #{method_name}; #{@src}; end", filename || @filename || '(erubis)')
  620. end
  621. end
  622. end
  623. #--end of require 'erubis/evaluator'
  624. #--already included require 'erubis/context'
  625. module Erubis
  626. ##
  627. ## (abstract) abstract engine class.
  628. ## subclass must include evaluator and converter module.
  629. ##
  630. class Engine
  631. #include Evaluator
  632. #include Converter
  633. #include Generator
  634. def initialize(input=nil, properties={})
  635. #@input = input
  636. init_generator(properties)
  637. init_converter(properties)
  638. init_evaluator(properties)
  639. @src = convert(input) if input
  640. end
  641. ##
  642. ## convert input string and set it to @src
  643. ##
  644. def convert!(input)
  645. @src = convert(input)
  646. end
  647. ##
  648. ## load file, write cache file, and return engine object.
  649. ## this method create code cache file automatically.
  650. ## cachefile name can be specified with properties[:cachename],
  651. ## or filname + 'cache' is used as default.
  652. ##
  653. def self.load_file(filename, properties={})
  654. cachename = properties[:cachename] || (filename + '.cache')
  655. properties[:filename] = filename
  656. timestamp = File.mtime(filename)
  657. if test(?f, cachename) && timestamp == File.mtime(cachename)
  658. engine = self.new(nil, properties)
  659. engine.src = File.read(cachename)
  660. else
  661. input = File.open(filename, 'rb') {|f| f.read }
  662. engine = self.new(input, properties)
  663. tmpname = cachename + rand().to_s[1,8]
  664. File.open(tmpname, 'wb') {|f| f.write(engine.src) }
  665. File.rename(tmpname, cachename)
  666. File.utime(timestamp, timestamp, cachename)
  667. end
  668. engine.src.untaint # ok?
  669. return engine
  670. end
  671. ##
  672. ## helper method to convert and evaluate input text with context object.
  673. ## context may be Binding, Hash, or Object.
  674. ##
  675. def process(input, context=nil, filename=nil)
  676. code = convert(input)
  677. filename ||= '(erubis)'
  678. if context.is_a?(Binding)
  679. return eval(code, context, filename)
  680. else
  681. context = Context.new(context) if context.is_a?(Hash)
  682. return context.instance_eval(code, filename)
  683. end
  684. end
  685. ##
  686. ## helper method evaluate Proc object with contect object.
  687. ## context may be Binding, Hash, or Object.
  688. ##
  689. def process_proc(proc_obj, context=nil, filename=nil)
  690. if context.is_a?(Binding)
  691. filename ||= '(erubis)'
  692. return eval(proc_obj, context, filename)
  693. else
  694. context = Context.new(context) if context.is_a?(Hash)
  695. return context.instance_eval(&proc_obj)
  696. end
  697. end
  698. end # end of class Engine
  699. ##
  700. ## (abstract) base engine class for Eruby, Eperl, Ejava, and so on.
  701. ## subclass must include generator.
  702. ##
  703. class Basic::Engine < Engine
  704. include Evaluator
  705. include Basic::Converter
  706. include Generator
  707. end
  708. class PI::Engine < Engine
  709. include Evaluator
  710. include PI::Converter
  711. include Generator
  712. end
  713. end
  714. #--end of require 'erubis/engine'
  715. #require 'erubis/generator'
  716. #require 'erubis/converter'
  717. #require 'erubis/evaluator'
  718. #require 'erubis/error'
  719. #require 'erubis/context'
  720. #requier 'erubis/util'
  721. #--begin of require 'erubis/helper'
  722. ##
  723. ## $Release: 2.7.0 $
  724. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  725. ##
  726. module Erubis
  727. ##
  728. ## helper for xml
  729. ##
  730. module XmlHelper
  731. module_function
  732. ESCAPE_TABLE = {
  733. '&' => '&amp;',
  734. '<' => '&lt;',
  735. '>' => '&gt;',
  736. '"' => '&quot;',
  737. "'" => '&#039;',
  738. }
  739. def escape_xml(value)
  740. value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] } # or /[&<>"']/
  741. #value.to_s.gsub(/[&<>"]/) { ESCAPE_TABLE[$&] }
  742. end
  743. def escape_xml2(value)
  744. return value.to_s.gsub(/\&/,'&amp;').gsub(/</,'&lt;').gsub(/>/,'&gt;').gsub(/"/,'&quot;')
  745. end
  746. alias h escape_xml
  747. alias html_escape escape_xml
  748. def url_encode(str)
  749. return str.gsub(/[^-_.a-zA-Z0-9]+/) { |s|
  750. s.unpack('C*').collect { |i| "%%%02X" % i }.join
  751. }
  752. end
  753. alias u url_encode
  754. end
  755. end
  756. #--end of require 'erubis/helper'
  757. #--begin of require 'erubis/enhancer'
  758. ##
  759. ## $Release: 2.7.0 $
  760. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  761. ##
  762. module Erubis
  763. ##
  764. ## switch '<%= ... %>' to escaped and '<%== ... %>' to unescaped
  765. ##
  766. ## ex.
  767. ## class XmlEruby < Eruby
  768. ## include EscapeEnhancer
  769. ## end
  770. ##
  771. ## this is language-indenedent.
  772. ##
  773. module EscapeEnhancer
  774. def self.desc # :nodoc:
  775. "switch '<%= %>' to escaped and '<%== %>' to unescaped"
  776. end
  777. #--
  778. #def self.included(klass)
  779. # klass.class_eval <<-END
  780. # alias _add_expr_literal add_expr_literal
  781. # alias _add_expr_escaped add_expr_escaped
  782. # alias add_expr_literal _add_expr_escaped
  783. # alias add_expr_escaped _add_expr_literal
  784. # END
  785. #end
  786. #++
  787. def add_expr(src, code, indicator)
  788. case indicator
  789. when '='
  790. @escape ? add_expr_literal(src, code) : add_expr_escaped(src, code)
  791. when '=='
  792. @escape ? add_expr_escaped(src, code) : add_expr_literal(src, code)
  793. when '==='
  794. add_expr_debug(src, code)
  795. end
  796. end
  797. end
  798. #--
  799. ## (obsolete)
  800. #module FastEnhancer
  801. #end
  802. #++
  803. ##
  804. ## use $stdout instead of string
  805. ##
  806. ## this is only for Eruby.
  807. ##
  808. module StdoutEnhancer
  809. def self.desc # :nodoc:
  810. "use $stdout instead of array buffer or string buffer"
  811. end
  812. def add_preamble(src)
  813. src << "#{@bufvar} = $stdout;"
  814. end
  815. def add_postamble(src)
  816. src << "\n''\n"
  817. end
  818. end
  819. ##
  820. ## use print statement instead of '_buf << ...'
  821. ##
  822. ## this is only for Eruby.
  823. ##
  824. module PrintOutEnhancer
  825. def self.desc # :nodoc:
  826. "use print statement instead of '_buf << ...'"
  827. end
  828. def add_preamble(src)
  829. end
  830. def add_text(src, text)
  831. src << " print '#{escape_text(text)}';" unless text.empty?
  832. end
  833. def add_expr_literal(src, code)
  834. src << " print((#{code}).to_s);"
  835. end
  836. def add_expr_escaped(src, code)
  837. src << " print #{escaped_expr(code)};"
  838. end
  839. def add_postamble(src)
  840. src << "\n" unless src[-1] == ?\n
  841. end
  842. end
  843. ##
  844. ## enable print function
  845. ##
  846. ## Notice: use Eruby#evaluate() and don't use Eruby#result()
  847. ## to be enable print function.
  848. ##
  849. ## this is only for Eruby.
  850. ##
  851. module PrintEnabledEnhancer
  852. def self.desc # :nodoc:
  853. "enable to use print function in '<% %>'"
  854. end
  855. def add_preamble(src)
  856. src << "@_buf = "
  857. super
  858. end
  859. def print(*args)
  860. args.each do |arg|
  861. @_buf << arg.to_s
  862. end
  863. end
  864. def evaluate(context=nil)
  865. _src = @src
  866. if context.is_a?(Hash)
  867. context.each do |key, val| instance_variable_set("@#{key}", val) end
  868. elsif context
  869. context.instance_variables.each do |name|
  870. instance_variable_set(name, context.instance_variable_get(name))
  871. end
  872. end
  873. return instance_eval(_src, (@filename || '(erubis)'))
  874. end
  875. end
  876. ##
  877. ## return array instead of string
  878. ##
  879. ## this is only for Eruby.
  880. ##
  881. module ArrayEnhancer
  882. def self.desc # :nodoc:
  883. "return array instead of string"
  884. end
  885. def add_preamble(src)
  886. src << "#{@bufvar} = [];"
  887. end
  888. def add_postamble(src)
  889. src << "\n" unless src[-1] == ?\n
  890. src << "#{@bufvar}\n"
  891. end
  892. end
  893. ##
  894. ## use an Array object as buffer (included in Eruby by default)
  895. ##
  896. ## this is only for Eruby.
  897. ##
  898. module ArrayBufferEnhancer
  899. def self.desc # :nodoc:
  900. "use an Array object for buffering (included in Eruby class)"
  901. end
  902. def add_preamble(src)
  903. src << "_buf = [];"
  904. end
  905. def add_postamble(src)
  906. src << "\n" unless src[-1] == ?\n
  907. src << "_buf.join\n"
  908. end
  909. end
  910. ##
  911. ## use String class for buffering
  912. ##
  913. ## this is only for Eruby.
  914. ##
  915. module StringBufferEnhancer
  916. def self.desc # :nodoc:
  917. "use a String object for buffering"
  918. end
  919. def add_preamble(src)
  920. src << "#{@bufvar} = '';"
  921. end
  922. def add_postamble(src)
  923. src << "\n" unless src[-1] == ?\n
  924. src << "#{@bufvar}.to_s\n"
  925. end
  926. end
  927. ##
  928. ## use StringIO class for buffering
  929. ##
  930. ## this is only for Eruby.
  931. ##
  932. module StringIOEnhancer # :nodoc:
  933. def self.desc # :nodoc:
  934. "use a StringIO object for buffering"
  935. end
  936. def add_preamble(src)
  937. src << "#{@bufvar} = StringIO.new;"
  938. end
  939. def add_postamble(src)
  940. src << "\n" unless src[-1] == ?\n
  941. src << "#{@bufvar}.string\n"
  942. end
  943. end
  944. ##
  945. ## set buffer variable name to '_erbout' as well as '_buf'
  946. ##
  947. ## this is only for Eruby.
  948. ##
  949. module ErboutEnhancer
  950. def self.desc # :nodoc:
  951. "set '_erbout = _buf = \"\";' to be compatible with ERB."
  952. end
  953. def add_preamble(src)
  954. src << "_erbout = #{@bufvar} = '';"
  955. end
  956. def add_postamble(src)
  957. src << "\n" unless src[-1] == ?\n
  958. src << "#{@bufvar}.to_s\n"
  959. end
  960. end
  961. ##
  962. ## remove text and leave code, especially useful when debugging.
  963. ##
  964. ## ex.
  965. ## $ erubis -s -E NoText file.eruby | more
  966. ##
  967. ## this is language independent.
  968. ##
  969. module NoTextEnhancer
  970. def self.desc # :nodoc:
  971. "remove text and leave code (useful when debugging)"
  972. end
  973. def add_text(src, text)
  974. src << ("\n" * text.count("\n"))
  975. if text[-1] != ?\n
  976. text =~ /^(.*?)\z/
  977. src << (' ' * $1.length)
  978. end
  979. end
  980. end
  981. ##
  982. ## remove code and leave text, especially useful when validating HTML tags.
  983. ##
  984. ## ex.
  985. ## $ erubis -s -E NoCode file.eruby | tidy -errors
  986. ##
  987. ## this is language independent.
  988. ##
  989. module NoCodeEnhancer
  990. def self.desc # :nodoc:
  991. "remove code and leave text (useful when validating HTML)"
  992. end
  993. def add_preamble(src)
  994. end
  995. def add_postamble(src)
  996. end
  997. def add_text(src, text)
  998. src << text
  999. end
  1000. def add_expr(src, code, indicator)
  1001. src << "\n" * code.count("\n")
  1002. end
  1003. def add_stmt(src, code)
  1004. src << "\n" * code.count("\n")
  1005. end
  1006. end
  1007. ##
  1008. ## get convert faster, but spaces around '<%...%>' are not trimmed.
  1009. ##
  1010. ## this is language-independent.
  1011. ##
  1012. module SimplifyEnhancer
  1013. def self.desc # :nodoc:
  1014. "get convert faster but leave spaces around '<% %>'"
  1015. end
  1016. #DEFAULT_REGEXP = /(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
  1017. SIMPLE_REGEXP = /<%(=+|\#)?(.*?)-?%>/m
  1018. def convert(input)
  1019. src = ""
  1020. add_preamble(src)
  1021. #regexp = pattern_regexp(@pattern)
  1022. pos = 0
  1023. input.scan(SIMPLE_REGEXP) do |indicator, code|
  1024. match = Regexp.last_match
  1025. index = match.begin(0)
  1026. text = input[pos, index - pos]
  1027. pos = match.end(0)
  1028. add_text(src, text)
  1029. if !indicator # <% %>
  1030. add_stmt(src, code)
  1031. elsif indicator[0] == ?\# # <%# %>
  1032. n = code.count("\n")
  1033. add_stmt(src, "\n" * n)
  1034. else # <%= %>
  1035. add_expr(src, code, indicator)
  1036. end
  1037. end
  1038. #rest = $' || input # ruby1.8
  1039. rest = pos == 0 ? input : input[pos..-1] # ruby1.9
  1040. add_text(src, rest)
  1041. add_postamble(src)
  1042. return src
  1043. end
  1044. end
  1045. ##
  1046. ## enable to use other embedded expression pattern (default is '\[= =\]').
  1047. ##
  1048. ## notice! this is an experimental. spec may change in the future.
  1049. ##
  1050. ## ex.
  1051. ## input = <<END
  1052. ## <% for item in list %>
  1053. ## <%= item %> : <%== item %>
  1054. ## [= item =] : [== item =]
  1055. ## <% end %>
  1056. ## END
  1057. ##
  1058. ## class BiPatternEruby
  1059. ## include BiPatternEnhancer
  1060. ## end
  1061. ## eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]')
  1062. ## list = ['<a>', 'b&b', '"c"']
  1063. ## print eruby.result(binding())
  1064. ##
  1065. ## ## output
  1066. ## <a> : &lt;a&gt;
  1067. ## <a> : &lt;a&gt;
  1068. ## b&b : b&amp;b
  1069. ## b&b : b&amp;b
  1070. ## "c" : &quot;c&quot;
  1071. ## "c" : &quot;c&quot;
  1072. ##
  1073. ## this is language independent.
  1074. ##
  1075. module BiPatternEnhancer
  1076. def self.desc # :nodoc:
  1077. "another embedded expression pattern (default '\[= =\]')."
  1078. end
  1079. def initialize(input, properties={})
  1080. self.bipattern = properties[:bipattern] # or '\$\{ \}'
  1081. super
  1082. end
  1083. ## when pat is nil then '\[= =\]' is used
  1084. def bipattern=(pat) # :nodoc:
  1085. @bipattern = pat || '\[= =\]'
  1086. pre, post = @bipattern.split()
  1087. @bipattern_regexp = /(.*?)#{pre}(=*)(.*?)#{post}/m
  1088. end
  1089. def add_text(src, text)
  1090. return unless text
  1091. m = nil
  1092. text.scan(@bipattern_regexp) do |txt, indicator, code|
  1093. m = Regexp.last_match
  1094. super(src, txt)
  1095. add_expr(src, code, '=' + indicator)
  1096. end
  1097. #rest = $' || text # ruby1.8
  1098. rest = m ? text[m.end(0)..-1] : text # ruby1.9
  1099. super(src, rest)
  1100. end
  1101. end
  1102. ##
  1103. ## regards lines starting with '^[ \t]*%' as program code
  1104. ##
  1105. ## in addition you can specify prefix character (default '%')
  1106. ##
  1107. ## this is language-independent.
  1108. ##
  1109. module PrefixedLineEnhancer
  1110. def self.desc # :nodoc:
  1111. "regard lines matched to '^[ \t]*%' as program code"
  1112. end
  1113. def init_generator(properties={})
  1114. super
  1115. @prefixchar = properties[:prefixchar]
  1116. end
  1117. def add_text(src, text)
  1118. unless @prefixrexp
  1119. @prefixchar ||= '%'
  1120. @prefixrexp = Regexp.compile("^([ \\t]*)\\#{@prefixchar}(.*?\\r?\\n)")
  1121. end
  1122. pos = 0
  1123. text2 = ''
  1124. text.scan(@prefixrexp) do
  1125. space = $1
  1126. line = $2
  1127. space, line = '', $1 unless $2
  1128. match = Regexp.last_match
  1129. len = match.begin(0) - pos
  1130. str = text[pos, len]
  1131. pos = match.end(0)
  1132. if text2.empty?
  1133. text2 = str
  1134. else
  1135. text2 << str
  1136. end
  1137. if line[0, 1] == @prefixchar
  1138. text2 << space << line
  1139. else
  1140. super(src, text2)
  1141. text2 = ''
  1142. add_stmt(src, space + line)
  1143. end
  1144. end
  1145. #rest = pos == 0 ? text : $' # ruby1.8
  1146. rest = pos == 0 ? text : text[pos..-1] # ruby1.9
  1147. unless text2.empty?
  1148. text2 << rest if rest
  1149. rest = text2
  1150. end
  1151. super(src, rest)
  1152. end
  1153. end
  1154. ##
  1155. ## regards lines starting with '%' as program code
  1156. ##
  1157. ## this is for compatibility to eruby and ERB.
  1158. ##
  1159. ## this is language-independent.
  1160. ##
  1161. module PercentLineEnhancer
  1162. include PrefixedLineEnhancer
  1163. def self.desc # :nodoc:
  1164. "regard lines starting with '%' as program code"
  1165. end
  1166. #--
  1167. #def init_generator(properties={})
  1168. # super
  1169. # @prefixchar = '%'
  1170. # @prefixrexp = /^\%(.*?\r?\n)/
  1171. #end
  1172. #++
  1173. def add_text(src, text)
  1174. unless @prefixrexp
  1175. @prefixchar = '%'
  1176. @prefixrexp = /^\%(.*?\r?\n)/
  1177. end
  1178. super(src, text)
  1179. end
  1180. end
  1181. ##
  1182. ## [experimental] allow header and footer in eRuby script
  1183. ##
  1184. ## ex.
  1185. ## ====================
  1186. ## ## without header and footer
  1187. ## $ cat ex1.eruby
  1188. ## <% def list_items(list) %>
  1189. ## <% for item in list %>
  1190. ## <li><%= item %></li>
  1191. ## <% end %>
  1192. ## <% end %>
  1193. ##
  1194. ## $ erubis -s ex1.eruby
  1195. ## _buf = []; def list_items(list)
  1196. ## ; for item in list
  1197. ## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
  1198. ## '; end
  1199. ## ; end
  1200. ## ;
  1201. ## _buf.join
  1202. ##
  1203. ## ## with header and footer
  1204. ## $ cat ex2.eruby
  1205. ## <!--#header:
  1206. ## def list_items(list)
  1207. ## #-->
  1208. ## <% for item in list %>
  1209. ## <li><%= item %></li>
  1210. ## <% end %>
  1211. ## <!--#footer:
  1212. ## end
  1213. ## #-->
  1214. ##
  1215. ## $ erubis -s -c HeaderFooterEruby ex4.eruby
  1216. ##
  1217. ## def list_items(list)
  1218. ## _buf = []; _buf << '
  1219. ## '; for item in list
  1220. ## ; _buf << '<li>'; _buf << ( item ).to_s; _buf << '</li>
  1221. ## '; end
  1222. ## ; _buf << '
  1223. ## ';
  1224. ## _buf.join
  1225. ## end
  1226. ##
  1227. ## ====================
  1228. ##
  1229. ## this is language-independent.
  1230. ##
  1231. module HeaderFooterEnhancer
  1232. def self.desc # :nodoc:
  1233. "allow header/footer in document (ex. '<!--#header: #-->')"
  1234. end
  1235. HEADER_FOOTER_PATTERN = /(.*?)(^[ \t]*)?<!--\#(\w+):(.*?)\#-->([ \t]*\r?\n)?/m
  1236. def add_text(src, text)
  1237. m = nil
  1238. text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace|
  1239. m = Regexp.last_match
  1240. flag_trim = @trim && lspace && rspace
  1241. super(src, txt)
  1242. content = "#{lspace}#{content}#{rspace}" if flag_trim
  1243. super(src, lspace) if !flag_trim && lspace
  1244. instance_variable_set("@#{word}", content)
  1245. super(src, rspace) if !flag_trim && rspace
  1246. end
  1247. #rest = $' || text # ruby1.8
  1248. rest = m ? text[m.end(0)..-1] : text # ruby1.9
  1249. super(src, rest)
  1250. end
  1251. attr_accessor :header, :footer
  1252. def convert(input)
  1253. source = super
  1254. return @src = "#{@header}#{source}#{@footer}"
  1255. end
  1256. end
  1257. ##
  1258. ## delete indentation of HTML.
  1259. ##
  1260. ## this is language-independent.
  1261. ##
  1262. module DeleteIndentEnhancer
  1263. def self.desc # :nodoc:
  1264. "delete indentation of HTML."
  1265. end
  1266. def convert_input(src, input)
  1267. input = input.gsub(/^[ \t]+</, '<')
  1268. super(src, input)
  1269. end
  1270. end
  1271. ##
  1272. ## convert "<h1><%=title%></h1>" into "_buf << %Q`<h1>#{title}</h1>`"
  1273. ##
  1274. ## this is only for Eruby.
  1275. ##
  1276. module InterpolationEnhancer
  1277. def self.desc # :nodoc:
  1278. "convert '<p><%=text%></p>' into '_buf << %Q`<p>\#{text}</p>`'"
  1279. end
  1280. def convert_input(src, input)
  1281. pat = @pattern
  1282. regexp = pat.nil? || pat == '<% %>' ? Basic::Converter::DEFAULT_REGEXP : pattern_regexp(pat)
  1283. pos = 0
  1284. is_bol = true # is beginning of line
  1285. str = ''
  1286. input.scan(regexp) do |indicator, code, tailch, rspace|
  1287. match = Regexp.last_match()
  1288. len = match.begin(0) - pos
  1289. text = input[pos, len]
  1290. pos = match.end(0)
  1291. ch = indicator ? indicator[0] : nil
  1292. lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
  1293. is_bol = rspace ? true : false
  1294. _add_text_to_str(str, text)
  1295. ## * when '<%= %>', do nothing
  1296. ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
  1297. if ch == ?= # <%= %>
  1298. rspace = nil if tailch && !tailch.empty?
  1299. str << lspace if lspace
  1300. add_expr(str, code, indicator)
  1301. str << rspace if rspace
  1302. elsif ch == ?\# # <%# %>
  1303. n = code.count("\n") + (rspace ? 1 : 0)
  1304. if @trim && lspace && rspace
  1305. add_text(src, str)
  1306. str = ''
  1307. add_stmt(src, "\n" * n)
  1308. else
  1309. str << lspace if lspace
  1310. add_text(src, str)
  1311. str = ''
  1312. add_stmt(src, "\n" * n)
  1313. str << rspace if rspace
  1314. end
  1315. else # <% %>
  1316. if @trim && lspace && rspace
  1317. add_text(src, str)
  1318. str = ''
  1319. add_stmt(src, "#{lspace}#{code}#{rspace}")
  1320. else
  1321. str << lspace if lspace
  1322. add_text(src, str)
  1323. str = ''
  1324. add_stmt(src, code)
  1325. str << rspace if rspace
  1326. end
  1327. end
  1328. end
  1329. #rest = $' || input # ruby1.8
  1330. rest = pos == 0 ? input : input[pos..-1] # ruby1.9
  1331. _add_text_to_str(str, rest)
  1332. add_text(src, str)
  1333. end
  1334. def add_text(src, text)
  1335. return if !text || text.empty?
  1336. #src << " _buf << %Q`" << text << "`;"
  1337. if text[-1] == ?\n
  1338. text[-1] = "\\n"
  1339. src << " #{@bufvar} << %Q`#{text}`\n"
  1340. else
  1341. src << " #{@bufvar} << %Q`#{text}`;"
  1342. end
  1343. end
  1344. def _add_text_to_str(str, text)
  1345. return if !text || text.empty?
  1346. str << text.gsub(/[`\#\\]/, '\\\\\&')
  1347. end
  1348. def add_expr_escaped(str, code)
  1349. str << "\#{#{escaped_expr(code)}}"
  1350. end
  1351. def add_expr_literal(str, code)
  1352. str << "\#{#{code}}"
  1353. end
  1354. end
  1355. end
  1356. #--end of require 'erubis/enhancer'
  1357. #require 'erubis/tiny'
  1358. #--begin of require 'erubis/engine/eruby'
  1359. ##
  1360. ## $Release: 2.7.0 $
  1361. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  1362. ##
  1363. #--already included require 'erubis/engine'
  1364. #--already included require 'erubis/enhancer'
  1365. module Erubis
  1366. ##
  1367. ## code generator for Ruby
  1368. ##
  1369. module RubyGenerator
  1370. include Generator
  1371. #include ArrayBufferEnhancer
  1372. include StringBufferEnhancer
  1373. def init_generator(properties={})
  1374. super
  1375. @escapefunc ||= "Erubis::XmlHelper.escape_xml"
  1376. @bufvar = properties[:bufvar] || "_buf"
  1377. end
  1378. def self.supported_properties() # :nodoc:
  1379. return []
  1380. end
  1381. def escape_text(text)
  1382. text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
  1383. end
  1384. def escaped_expr(code)
  1385. return "#{@escapefunc}(#{code})"
  1386. end
  1387. #--
  1388. #def add_preamble(src)
  1389. # src << "#{@bufvar} = [];"
  1390. #end
  1391. #++
  1392. def add_text(src, text)
  1393. src << " #{@bufvar} << '" << escape_text(text) << "';" unless text.empty?
  1394. end
  1395. def add_stmt(src, code)
  1396. #src << code << ';'
  1397. src << code
  1398. src << ';' unless code[-1] == ?\n
  1399. end
  1400. def add_expr_literal(src, code)
  1401. src << " #{@bufvar} << (" << code << ').to_s;'
  1402. end
  1403. def add_expr_escaped(src, code)
  1404. src << " #{@bufvar} << " << escaped_expr(code) << ';'
  1405. end
  1406. def add_expr_debug(src, code)
  1407. code.strip!
  1408. s = (code.dump =~ /\A"(.*)"\z/) && $1
  1409. src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
  1410. end
  1411. #--
  1412. #def add_postamble(src)
  1413. # src << "\n#{@bufvar}.join\n"
  1414. #end
  1415. #++
  1416. end
  1417. ##
  1418. ## engine for Ruby
  1419. ##
  1420. class Eruby < Basic::Engine
  1421. include RubyEvaluator
  1422. include RubyGenerator
  1423. end
  1424. ##
  1425. ## fast engine for Ruby
  1426. ##
  1427. class FastEruby < Eruby
  1428. include InterpolationEnhancer
  1429. end
  1430. ##
  1431. ## swtich '<%= %>' to escaped and '<%== %>' to not escaped
  1432. ##
  1433. class EscapedEruby < Eruby
  1434. include EscapeEnhancer
  1435. end
  1436. ##
  1437. ## sanitize expression (<%= ... %>) by default
  1438. ##
  1439. ## this is equivalent to EscapedEruby and is prepared only for compatibility.
  1440. ##
  1441. class XmlEruby < Eruby
  1442. include EscapeEnhancer
  1443. end
  1444. class PI::Eruby < PI::Engine
  1445. include RubyEvaluator
  1446. include RubyGenerator
  1447. def init_converter(properties={})
  1448. @pi = 'rb'
  1449. super(properties)
  1450. end
  1451. end
  1452. end
  1453. #--end of require 'erubis/engine/eruby'
  1454. #require 'erubis/engine/enhanced' # enhanced eruby engines
  1455. #require 'erubis/engine/optimized' # generates optimized ruby code
  1456. #require 'erubis/engine/ephp'
  1457. #require 'erubis/engine/ec'
  1458. #require 'erubis/engine/ejava'
  1459. #require 'erubis/engine/escheme'
  1460. #require 'erubis/engine/eperl'
  1461. #require 'erubis/engine/ejavascript'
  1462. #--begin of require 'erubis/local-setting'
  1463. ##
  1464. ## $Release: 2.7.0 $
  1465. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  1466. ##
  1467. ##
  1468. ## you can add site-local settings here.
  1469. ## this files is required by erubis.rb
  1470. ##
  1471. #--end of require 'erubis/local-setting'
  1472. #--end of require 'erubis'
  1473. #--begin of require 'erubis/tiny'
  1474. ##
  1475. ## $Release: 2.7.0 $
  1476. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  1477. ##
  1478. module Erubis
  1479. ##
  1480. ## tiny and the simplest implementation of eRuby
  1481. ##
  1482. ## ex.
  1483. ## eruby = TinyEruby.new(File.read('example.rhtml'))
  1484. ## print eruby.src # print ruby code
  1485. ## print eruby.result(binding()) # eval ruby code with Binding object
  1486. ## print eruby.evalute(context) # eval ruby code with context object
  1487. ##
  1488. class TinyEruby
  1489. def initialize(input=nil)
  1490. @src = convert(input) if input
  1491. end
  1492. attr_reader :src
  1493. EMBEDDED_PATTERN = /<%(=+|\#)?(.*?)-?%>/m
  1494. def convert(input)
  1495. src = "_buf = '';" # preamble
  1496. pos = 0
  1497. input.scan(EMBEDDED_PATTERN) do |indicator, code|
  1498. m = Regexp.last_match
  1499. text = input[pos...m.begin(0)]
  1500. pos = m.end(0)
  1501. #src << " _buf << '" << escape_text(text) << "';"
  1502. text.gsub!(/['\\]/, '\\\\\&')
  1503. src << " _buf << '" << text << "';" unless text.empty?
  1504. if !indicator # <% %>
  1505. src << code << ";"
  1506. elsif indicator == '#' # <%# %>
  1507. src << ("\n" * code.count("\n"))
  1508. else # <%= %>
  1509. src << " _buf << (" << code << ").to_s;"
  1510. end
  1511. end
  1512. #rest = $' || input # ruby1.8
  1513. rest = pos == 0 ? input : input[pos..-1] # ruby1.9
  1514. #src << " _buf << '" << escape_text(rest) << "';"
  1515. rest.gsub!(/['\\]/, '\\\\\&')
  1516. src << " _buf << '" << rest << "';" unless rest.empty?
  1517. src << "\n_buf.to_s\n" # postamble
  1518. return src
  1519. end
  1520. #def escape_text(text)
  1521. # return text.gsub!(/['\\]/, '\\\\\&') || text
  1522. #end
  1523. def result(_binding=TOPLEVEL_BINDING)
  1524. eval @src, _binding
  1525. end
  1526. def evaluate(_context=Object.new)
  1527. if _context.is_a?(Hash)
  1528. _obj = Object.new
  1529. _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end
  1530. _context = _obj
  1531. end
  1532. _context.instance_eval @src
  1533. end
  1534. end
  1535. module PI
  1536. end
  1537. class PI::TinyEruby
  1538. def initialize(input=nil, options={})
  1539. @escape = options[:escape] || 'Erubis::XmlHelper.escape_xml'
  1540. @src = convert(input) if input
  1541. end
  1542. attr_reader :src
  1543. EMBEDDED_PATTERN = /(^[ \t]*)?<\?rb(\s.*?)\?>([ \t]*\r?\n)?|@(!+)?\{(.*?)\}@/m
  1544. def convert(input)
  1545. src = "_buf = '';" # preamble
  1546. pos = 0
  1547. input.scan(EMBEDDED_PATTERN) do |lspace, stmt, rspace, indicator, expr|
  1548. match = Regexp.last_match
  1549. len = match.begin(0) - pos
  1550. text = input[pos, len]
  1551. pos = match.end(0)
  1552. #src << " _buf << '" << escape_text(text) << "';"
  1553. text.gsub!(/['\\]/, '\\\\\&')
  1554. src << " _buf << '" << text << "';" unless text.empty?
  1555. if stmt # <?rb ... ?>
  1556. if lspace && rspace
  1557. src << "#{lspace}#{stmt}#{rspace}"
  1558. else
  1559. src << " _buf << '" << lspace << "';" if lspace
  1560. src << stmt << ";"
  1561. src << " _buf << '" << rspace << "';" if rspace
  1562. end
  1563. else # ${...}, $!{...}
  1564. if !indicator
  1565. src << " _buf << " << @escape << "(" << expr << ");"
  1566. elsif indicator == '!'
  1567. src << " _buf << (" << expr << ").to_s;"
  1568. end
  1569. end
  1570. end
  1571. #rest = $' || input # ruby1.8
  1572. rest = pos == 0 ? input : input[pos..-1] # ruby1.9
  1573. #src << " _buf << '" << escape_text(rest) << "';"
  1574. rest.gsub!(/['\\]/, '\\\\\&')
  1575. src << " _buf << '" << rest << "';" unless rest.empty?
  1576. src << "\n_buf.to_s\n" # postamble
  1577. return src
  1578. end
  1579. #def escape_text(text)
  1580. # return text.gsub!(/['\\]/, '\\\\\&') || text
  1581. #end
  1582. def result(_binding=TOPLEVEL_BINDING)
  1583. eval @src, _binding
  1584. end
  1585. def evaluate(_context=Object.new)
  1586. if _context.is_a?(Hash)
  1587. _obj = Object.new
  1588. _context.each do |k, v| _obj.instance_variable_set("@#{k}", v) end
  1589. _context = _obj
  1590. end
  1591. _context.instance_eval @src
  1592. end
  1593. end
  1594. end
  1595. #--end of require 'erubis/tiny'
  1596. #--begin of require 'erubis/engine/enhanced'
  1597. ##
  1598. ## $Release: 2.7.0 $
  1599. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  1600. ##
  1601. #--already included require 'erubis/enhancer'
  1602. #--already included require 'erubis/engine/eruby'
  1603. module Erubis
  1604. #--
  1605. ## moved to engine/ruby.rb
  1606. #class EscapedEruby < Eruby
  1607. # include EscapeEnhancer
  1608. #end
  1609. #++
  1610. #--
  1611. ### (obsolete)
  1612. #class FastEruby < Eruby
  1613. # include FastEnhancer
  1614. #end
  1615. #++
  1616. class StdoutEruby < Eruby
  1617. include StdoutEnhancer
  1618. end
  1619. class PrintOutEruby < Eruby
  1620. include PrintOutEnhancer
  1621. end
  1622. class PrintEnabledEruby < Eruby
  1623. include PrintEnabledEnhancer
  1624. end
  1625. class ArrayEruby < Eruby
  1626. include ArrayEnhancer
  1627. end
  1628. class ArrayBufferEruby < Eruby
  1629. include ArrayBufferEnhancer
  1630. end
  1631. class StringBufferEruby < Eruby
  1632. include StringBufferEnhancer
  1633. end
  1634. class StringIOEruby < Eruby
  1635. include StringIOEnhancer
  1636. end
  1637. class ErboutEruby < Eruby
  1638. include ErboutEnhancer
  1639. end
  1640. class NoTextEruby < Eruby
  1641. include NoTextEnhancer
  1642. end
  1643. class NoCodeEruby < Eruby
  1644. include NoCodeEnhancer
  1645. end
  1646. class SimplifiedEruby < Eruby
  1647. include SimplifyEnhancer
  1648. end
  1649. class StdoutSimplifiedEruby < Eruby
  1650. include StdoutEnhancer
  1651. include SimplifyEnhancer
  1652. end
  1653. class PrintOutSimplifiedEruby < Eruby
  1654. include PrintOutEnhancer
  1655. include SimplifyEnhancer
  1656. end
  1657. class BiPatternEruby < Eruby
  1658. include BiPatternEnhancer
  1659. end
  1660. class PercentLineEruby < Eruby
  1661. include PercentLineEnhancer
  1662. end
  1663. class PrefixedLineEruby < Eruby
  1664. include PrefixedLineEnhancer
  1665. end
  1666. class HeaderFooterEruby < Eruby
  1667. include HeaderFooterEnhancer
  1668. end
  1669. class DeleteIndentEruby < Eruby
  1670. include DeleteIndentEnhancer
  1671. end
  1672. class InterpolationEruby < Eruby
  1673. include InterpolationEnhancer
  1674. end
  1675. end
  1676. #--end of require 'erubis/engine/enhanced'
  1677. #--begin of require 'erubis/engine/optimized'
  1678. ##
  1679. ## $Release: 2.7.0 $
  1680. ## copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
  1681. ##
  1682. #--already included require 'erubis/engine/eruby'
  1683. module Erubis
  1684. module OptimizedGenerator
  1685. include Generator
  1686. def self.supported_properties() # :nodoc:
  1687. return []
  1688. end
  1689. def init_generator(properties={})
  1690. super
  1691. @escapefunc ||= "Erubis::XmlHelper.escape_xml"
  1692. @initialized = false
  1693. @prev_is_expr = false
  1694. end
  1695. protected
  1696. def escape_text(text)
  1697. text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
  1698. end
  1699. def escaped_expr(code)
  1700. @escapefunc ||= 'Erubis::XmlHelper.escape_xml'
  1701. return "#{@escapefunc}(#{code})"
  1702. end
  1703. def switch_to_expr(src)
  1704. return if @prev_is_expr
  1705. @prev_is_expr = true
  1706. src << ' _buf'
  1707. end
  1708. def switch_to_stmt(src)
  1709. return unless @prev_is_expr
  1710. @prev_is_expr = false
  1711. src << ';'
  1712. end
  1713. def add_preamble(src)
  1714. #@initialized = false
  1715. #@prev_is_expr = false
  1716. end
  1717. def add_text(src, text)
  1718. return if text.empty?
  1719. if @initialized
  1720. switch_to_expr(src)
  1721. src << " << '" << escape_text(text) << "'"
  1722. else
  1723. src << "_buf = '" << escape_text(text) << "';"
  1724. @initialized = true
  1725. end
  1726. end
  1727. def add_stmt(src, code)
  1728. switch_to_stmt(src) if @initialized
  1729. #super
  1730. src << code
  1731. src << ';' unless code[-1] == ?\n
  1732. end
  1733. def add_expr_literal(src, code)
  1734. unless @initialized; src << "_buf = ''"; @initialized = true; end
  1735. switch_to_expr(src)
  1736. src << " << (" << code << ").to_s"
  1737. end
  1738. def add_expr_escaped(src, code)
  1739. unless @initialized; src << "_buf = ''"; @ini

Large files files are truncated, but you can click here to view the full file