summaryrefslogtreecommitdiff
path: root/lib/erb.rb
diff options
context:
space:
mode:
authorseki <seki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-07-31 03:42:17 +0000
committerseki <seki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-07-31 03:42:17 +0000
commitf8817c7262afd77028e7cb704e440b67a1104cb7 (patch)
treee0973aeaec70eb3140b7e4fe982beb840da9cbaa /lib/erb.rb
parent1358ec597ba04489834c8265b554aede2ebd6c76 (diff)
add explicit trim mode
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4238 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/erb.rb')
-rw-r--r--lib/erb.rb160
1 files changed, 144 insertions, 16 deletions
diff --git a/lib/erb.rb b/lib/erb.rb
index f8c1c98..9c98ee1 100644
--- a/lib/erb.rb
+++ b/lib/erb.rb
@@ -24,7 +24,21 @@ class ERB
class Scanner
SplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>)|(\n)/
- def initialize(src)
+ @scanner_map = {}
+ def self.regist_scanner(klass, trim_mode, percent)
+ @scanner_map[[trim_mode, percent]] = klass
+ end
+
+ def self.default_scanner=(klass)
+ @default_scanner = klass
+ end
+
+ def self.make_scanner(src, trim_mode, percent)
+ klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
+ klass.new(src, trim_mode, percent)
+ end
+
+ def initialize(src, trim_mode, percent)
@src = src
@stag = nil
end
@@ -37,11 +51,15 @@ class ERB
TrimSplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>\n)|(%>)|(\n)/
def initialize(src, trim_mode, percent)
- super(src)
+ super
@trim_mode = trim_mode
@percent = percent
- if @trim_mode
- @scan_line = self.method(:trim_line)
+ if @trim_mode == '>'
+ @scan_line = self.method(:trim_line1)
+ elsif @trim_mode == '<>'
+ @scan_line = self.method(:trim_line2)
+ elsif @trim_mode == '-'
+ @scan_line = self.method(:explicit_trim_line)
else
@scan_line = self.method(:scan_line)
end
@@ -56,7 +74,7 @@ class ERB
end
else
@src.each do |line|
- trim_line(line, &block)
+ @scan_line.call(line, &block)
end
end
nil
@@ -82,17 +100,26 @@ class ERB
end
end
- def trim_line(line)
+ def trim_line1(line)
+ line.split(TrimSplitRegexp).each do |token|
+ next if token.empty?
+ if token == "%>\n"
+ yield('%>')
+ yield(:cr)
+ break
+ end
+ yield(token)
+ end
+ end
+
+ def trim_line2(line)
head = nil
- last = nil
line.split(TrimSplitRegexp).each do |token|
next if token.empty?
head = token unless head
if token == "%>\n"
yield('%>')
- if @trim_mode == '>'
- yield(:cr)
- elsif @trim_mode == '<>' && is_erb_stag?(head)
+ if is_erb_stag?(head)
yield(:cr)
else
yield("\n")
@@ -103,12 +130,31 @@ class ERB
end
end
+ ExplicitTrimRegexp = /(^[ \t]*<%-)|(-%>\n?$)|(<%-)|(-%>)|(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>)|(\n)/
+ def explicit_trim_line(line)
+ line.split(ExplicitTrimRegexp).each do |token|
+ next if token.empty?
+ if @stag.nil? && /[ \t]*<%-/ =~ token
+ yield('<%')
+ elsif @stag && /-%>\n/ =~ token
+ yield('%>')
+ yield(:cr)
+ elsif @stag && token == '-%>'
+ yield('%>')
+ else
+ yield(token)
+ end
+ end
+ end
+
ERB_STAG = %w(<%= <%# <%)
def is_erb_stag?(s)
ERB_STAG.member?(s)
end
end
+ Scanner.default_scanner = TrimScanner
+
class SimpleScanner < Scanner
def scan
@src.each do |line|
@@ -119,6 +165,90 @@ class ERB
end
end
end
+
+ Scanner.regist_scanner(SimpleScanner, nil, false)
+
+ begin
+ require 'strscan'
+ class SimpleScanner2 < Scanner
+ def scan
+ stag_reg = /(.*?)(<%%|<%=|<%#|<%|\n|$)/
+ etag_reg = /(.*?)(%%>|%>|\n|$)/
+ scanner = StringScanner.new(@src)
+ while ! scanner.eos?
+ scanner.scan(@stag ? etag_reg : stag_reg)
+ text = scanner[1]
+ elem = scanner[2]
+ yield(text) unless text.empty?
+ yield(elem) unless elem.empty?
+ end
+ end
+ end
+ Scanner.regist_scanner(SimpleScanner2, nil, false)
+
+ class PercentScanner < Scanner
+ def scan
+ new_line = true
+ stag_reg = /(.*?)(<%%|<%=|<%#|<%|\n|$)/
+ etag_reg = /(.*?)(%%>|%>|\n|$)/
+ scanner = StringScanner.new(@src)
+ while ! scanner.eos?
+ if new_line && @stag.nil?
+ if scanner.scan(/%%/)
+ yield('%')
+ new_line = false
+ next
+ elsif scanner.scan(/%/)
+ yield(PercentLine.new(scanner.scan(/.*?(\n|$)/).chomp))
+ next
+ end
+ end
+ scanner.scan(@stag ? etag_reg : stag_reg)
+ text = scanner[1]
+ elem = scanner[2]
+ yield(text) unless text.empty?
+ yield(elem) unless elem.empty?
+ new_line = (elem == "\n")
+ end
+ end
+ end
+ Scanner.regist_scanner(PercentScanner, nil, true)
+
+ class ExplicitScanner < Scanner
+ def scan
+ new_line = true
+ stag_reg = /(.*?)(<%%|<%=|<%#|<%-|<%|\n|$)/
+ etag_reg = /(.*?)(%%>|-%>|%>|\n|$)/
+ scanner = StringScanner.new(@src)
+ while ! scanner.eos?
+ if new_line && @stag.nil? && scanner.scan(/[ \t]*<%-/)
+ yield('<%')
+ new_line = false
+ next
+ end
+ scanner.scan(@stag ? etag_reg : stag_reg)
+ text = scanner[1]
+ elem = scanner[2]
+ new_line = (elem == "\n")
+ yield(text) unless text.empty?
+ if elem == '-%>'
+ yield('%>')
+ if scanner.scan(/(\n|$)/)
+ yield(:cr)
+ new_line = true
+ end
+ elsif elem == '<%-'
+ yield('<%')
+ else
+ yield(elem) unless elem.empty?
+ end
+ end
+ end
+ end
+ Scanner.regist_scanner(ExplicitScanner, '-', false)
+
+ rescue LoadError
+ end
class Buffer
def initialize(compiler)
@@ -221,7 +351,9 @@ class ERB
return [false, nil]
when String
perc = mode.include?('%')
- if mode.include?('<>')
+ if mode.include?('-')
+ return [perc, '-']
+ elsif mode.include?('<>')
return [perc, '<>']
elsif mode.include?('>')
return [perc, '>']
@@ -234,11 +366,7 @@ class ERB
end
def make_scanner(src)
- if @percent || @trim_mode
- TrimScanner.new(src, @trim_mode, @percent)
- else
- SimpleScanner.new(src)
- end
+ Scanner.make_scanner(src, @trim_mode, @percent)
end
def initialize(trim_mode)