From 9f22034ae016b6091063ca99309c20aa46077a18 Mon Sep 17 00:00:00 2001 From: seki Date: Mon, 20 Jan 2003 11:32:19 +0000 Subject: [PATCH] fix: % in <%..%> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3372 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/erb.rb | 118 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 44 deletions(-) diff --git a/lib/erb.rb b/lib/erb.rb index f7925db697..b2897d4960 100644 --- a/lib/erb.rb +++ b/lib/erb.rb @@ -1,24 +1,56 @@ # Tiny eRuby --- ERB2 -# Copyright (c) 1999-2000,2002 Masatoshi SEKI +# Copyright (c) 1999-2000,2002,2003 Masatoshi SEKI # You can redistribute it and/or modify it under the same terms as Ruby. class ERB Revision = '$Date$' #' def self.version - "erb.rb [2.0.1 #{ERB::Revision.split[1]}]" + "erb.rb [2.0.2 #{ERB::Revision.split[1]}]" end end # ERB::Compiler class ERB class Compiler - ERbTag = "<%% %%> <%= <%# <% %>".split private + + class ParcentLine + def initialize(compiler, str) + @compiler = compiler + @line = str + end + + def expand(list) + str = @line.dup + str[0] = '' + if /^%%/ === @line + list.unshift("\n") + list.unshift(str) + else + list.unshift('%>') + list.unshift(str) + list.unshift('<%') + end + list + end + + def expand_in_script(list) + ary = [] + @compiler.push_line(ary, @line) + ary.reverse_each do |x| + list.unshift(x) + end + end + end + + ERbTag = "<%% %%> <%= <%# <% %>".split def is_erb_tag?(s) ERbTag.member?(s) end + SplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>)|(\n)/ + def prepare_trim_mode(mode) case mode when 1 @@ -41,47 +73,41 @@ class ERB end end - SplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>)|(\n)/ - - public - def pre_compile(s, trim_mode) - perc, trim_mode = prepare_trim_mode(trim_mode) + def pre_compile(s) re = SplitRegexp - if trim_mode.nil? && !perc + if @trim_mode.nil? && !@perc list = s.split(re) else list = [] has_cr = (s[-1] == ?\n) s.each do |line| line = line.chomp - if perc && (/^(%{1,2})/ =~ line) - line[0] = '' - if $1 == '%%' - list.push(line) - list.push("\n") - else - list.push('<%') - list.push(line) - list.push('%>') - end + if @perc && (/^%/ =~ line) + list.push(ParcentLine.new(self, line)) else - line = line.split(re) - line.shift if line[0]=='' - list += line - unless ((trim_mode == '>' && line[-1] == '%>') || - (trim_mode == '<>' && (is_erb_tag?(line[0])) && - line[-1] == '%>')) - list.push("\n") - end + push_line(list, line) end end - list.pop unless has_cr + list.pop if list[-1] == "\n" && !has_cr end list end + public + def push_line(list, line) + re = SplitRegexp + line = line.split(re) + line.shift if line[0]=='' + list.concat(line) + unless ((@trim_mode == '>' && line[-1] == '%>') || + (@trim_mode == '<>' && (is_erb_tag?(line[0])) && + line[-1] == '%>')) + list.push("\n") + end + end + def compile(s) - list = pre_compile(s, @trim_mode) + list = pre_compile(s) cmd = [] cmd.concat(@pre_cmd) @@ -98,16 +124,19 @@ class ERB if stag.nil? if ['<%', '<%=', '<%#'].include?(token) stag = token - str = content.join + str = content.join('') if str.size > 0 cmd.push("#{@put_cmd} #{str.dump}") end content = [] elsif token == "\n" content.push("\n") - cmd.push("#{@put_cmd} #{content.join.dump}") + cmd.push("#{@put_cmd} #{content.join('').dump}") cmd.push(:cr) content = [] + elsif ParcentLine === token + token.expand(list) + next else content.push(token) end @@ -115,7 +144,7 @@ class ERB if token == '%>' case stag when '<%' - str = content.join + str = content.join('') if str[-1] == ?\n str.chop! cmd.push(str) @@ -124,19 +153,22 @@ class ERB cmd.push(str) end when '<%=' - cmd.push("#{@put_cmd}((#{content.join}).to_s)") + cmd.push("#{@put_cmd}((#{content.join('')}).to_s)") when '<%#' # cmd.push("# #{content.dump}") end stag = nil content = [] + elsif ParcentLine === token + token.expand_in_script(list) + next else content.push(token) end end end if content.size > 0 - cmd.push("#{@put_cmd} #{content.join.dump}") + cmd.push("#{@put_cmd} #{content.join('').dump}") end cmd.push(:cr) cmd.concat(@post_cmd) @@ -151,19 +183,19 @@ class ERB ary.push('; ') end end - ary.join + ary.join('') end - def initialize - @trim_mode = nil + def initialize(trim_mode) + @perc, @trim_mode = prepare_trim_mode(trim_mode) @put_cmd = 'print' @pre_cmd = [] @post_cmd = [] end - attr :trim_mode, true - attr :put_cmd, true - attr :pre_cmd, true - attr :post_cmd, true + + attr_accessor(:put_cmd) + attr_accessor(:pre_cmd) + attr_accessor(:post_cmd) end end @@ -171,8 +203,7 @@ end class ERB def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout') @safe_level = safe_level - compiler = ERB::Compiler.new - compiler.trim_mode = trim_mode + compiler = ERB::Compiler.new(trim_mode) set_eoutvar(compiler, eoutvar) @src = compiler.compile(str) end @@ -255,4 +286,3 @@ class ERB module_function :def_erb_method end end -