From 623787d240c601ba5d11ff68b8b6f5bb6bcce3df Mon Sep 17 00:00:00 2001 From: yugui Date: Mon, 29 Dec 2008 09:26:34 +0000 Subject: * lib/erb.rb (ERB): m17n of ERB. adds rdoc. fixes #712. c.f. [ruby-dev:37516]. * lib/erb.rb (ERB::Compiler#compile): recognizes magic comments. returns a pair of compiled script and its script encoding. * lib/erb.rb (ERB#set_eoutvar): make generated scripts return a string in correct encoding. * lib/erb.rb (ERB#def_method): use Kernel#eval for encoding-awareness of the evaluated string. * bin/erb.rb (ERB::Main.run): adds -E and -U options. String is no longer Enumerable. * man/erb.1: new manapage. * test/erb/test_erb_m17n.rb: new test case for m17n features. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@21170 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/erb.rb | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'lib/erb.rb') diff --git a/lib/erb.rb b/lib/erb.rb index c87994128..c5194817b 100644 --- a/lib/erb.rb +++ b/lib/erb.rb @@ -58,6 +58,24 @@ # # See the ERB.new and ERB#result methods for more detail. # +# == Character encodings +# +# ERB (or ruby code generated by ERB) returns a string in the same +# character encoding as the input string. When the input string has +# a magic comment, however, it returns a string in the encoding specified +# by the magic comment. +# +# # -*- coding: UTF-8 -*- +# require 'erb' +# +# template = ERB.new < +# \_\_ENCODING\_\_ is <%= \_\_ENCODING\_\_ %>. +# EOF +# puts template.result +# +# Prints: \_\_ENCODING\_\_ is Big5. +# # # == Examples # @@ -517,10 +535,14 @@ class ERB end def compile(s) - out = Buffer.new(self, s.encoding) + enc = s.encoding + raise ArgumentError, "#{enc} is not ASCII compatible" if enc.dummy? + s = s.dup.force_encoding("ASCII-8BIT") # don't use constant Enoding::ASCII_8BIT for miniruby + enc = detect_magic_comment(s) || enc + out = Buffer.new(self, enc) content = '' - scanner = make_scanner(s.dup.force_encoding("ASCII-8BIT")) + scanner = make_scanner(s) scanner.scan do |token| if scanner.stag.nil? case token @@ -560,6 +582,7 @@ class ERB when '<%=' out.push("#{@insert_cmd}((#{content}).to_s)") when '<%#' + # content = content.force_encoding(@enc) # out.push("# #{content.dump}") end scanner.stag = nil @@ -573,7 +596,7 @@ class ERB end out.push("#{@put_cmd} #{content.dump}") if content.size > 0 out.close - out.script + return out.script, enc end def prepare_trim_mode(mode) @@ -613,6 +636,18 @@ class ERB end attr_reader :percent, :trim_mode attr_accessor :put_cmd, :insert_cmd, :pre_cmd, :post_cmd + + private + def detect_magic_comment(s) + if /\A<%#(.*)%>/ =~ s or (@percent and /\A%#(.*)/ =~ s) + comment = $1 + comment = $1 if comment[/-\*-\s*(.*?)\s*-*-$/] + if %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" =~ comment + enc = $1.sub(/-(?:mac|dos|unix)/i, '') + enc = Encoding.find(enc) + end + end + end end end @@ -688,7 +723,7 @@ class ERB @safe_level = safe_level compiler = ERB::Compiler.new(trim_mode) set_eoutvar(compiler, eoutvar) - @src = compiler.compile(str) + @src, @enc = *compiler.compile(str) @filename = nil end @@ -714,7 +749,7 @@ class ERB compiler.pre_cmd = cmd cmd = [] - cmd.push(eoutvar) + cmd.push("#{eoutvar}.force_encoding(__ENCODING__)") compiler.post_cmd = cmd end @@ -745,7 +780,11 @@ class ERB end def def_method(mod, methodname, fname='(ERB)') # :nodoc: - mod.module_eval("def #{methodname}\n" + self.src + "\nend\n", fname, -1) + src = self.src + magic_comment = "#coding:#{@enc}\n" + mod.module_eval do + eval(magic_comment + "def #{methodname}\n" + src + "\nend\n", binding, fname, -2) + end end def def_module(methodname='erb') # :nodoc: -- cgit