Permalink
Browse files

Applied Sam Ruby's 1.9 patch.

  • Loading branch information...
1 parent 7d9bd24 commit b7c99a9d13c717996ad82ffaaf18fbed320db627 @jimweirich jimweirich committed Nov 17, 2010
Showing with 283 additions and 113 deletions.
  1. +26 −25 Rakefile
  2. +6 −3 lib/builder/blankslate.rb
  3. +3 −3 lib/builder/css.rb
  4. +108 −30 lib/builder/xchar.rb
  5. +27 −9 lib/builder/xmlbase.rb
  6. +10 −9 lib/builder/xmlmarkup.rb
  7. +7 −0 test/test_blankslate.rb
  8. +72 −31 test/test_markupbuilder.rb
  9. +24 −3 test/test_xchar.rb
View
@@ -41,6 +41,7 @@ task :tu => [:test_units]
Rake::TestTask.new("test_units") do |t|
t.test_files = FileList['test/test*.rb']
+ t.libs << "."
t.verbose = false
end
@@ -59,7 +60,7 @@ rd = Rake::RDocTask.new("rdoc") { |rdoc|
# gem files.
PKG_FILES = FileList[
- 'lib/**/*.rb',
+ 'lib/**/*.rb',
'test/**/*.rb',
'scripts/**/*.rb'
]
@@ -68,14 +69,14 @@ PKG_FILES.exclude('lib/builder/css.rb')
BLANKSLATE_FILES = FileList[
'lib/blankslate.rb',
- 'test/testblankslate.rb'
+ 'test/test_blankslate.rb'
]
if ! defined?(Gem)
puts "Package Target requires RubyGEMs"
else
spec = Gem::Specification.new do |s|
-
+
#### Basic information.
s.name = 'builder'
@@ -92,58 +93,58 @@ simple to do. Currently the following builder objects are supported:
s.files = PKG_FILES.to_a
s.require_path = 'lib'
s.autorequire = 'builder'
-
+
s.test_files = PKG_FILES.select { |fn| fn =~ /^test\/test/ }
-
+
s.has_rdoc = true
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
s.rdoc_options <<
'--title' << 'Builder -- Easy XML Building' <<
'--main' << 'README.rdoc' <<
'--line-numbers'
-
+
s.author = "Jim Weirich"
s.email = "jim@weirichhouse.org"
s.homepage = "http://onestepback.org"
end
-
+
blankslate_spec = Gem::Specification.new do |s|
-
+
#### Basic information.
-
+
s.name = 'blankslate'
s.version = PKG_VERSION
s.summary = "Blank Slate base class."
s.description = %{\
BlankSlate provides a base class where almost all of the methods from Object and
Kernel have been removed. This is useful when providing proxy object and other
-classes that make heavy use of method_missing.
+classes that make heavy use of method_missing.
}
-
+
s.files = BLANKSLATE_FILES.to_a
s.require_path = 'lib'
s.autorequire = 'builder'
-
+
s.test_files = PKG_FILES.select { |fn| fn =~ /^test\/test/ }
-
+
s.has_rdoc = true
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
s.rdoc_options <<
'--title' << 'BlankSlate -- Base Class for building proxies.' <<
'--main' << 'README.rdoc' <<
'--line-numbers'
-
+
s.author = "Jim Weirich"
s.email = "jim@weirichhouse.org"
s.homepage = "http://onestepback.org"
end
-
+
namespace 'builder' do
Rake::GemPackageTask.new(spec) do |t|
t.need_tar = true
end
end
-
+
namespace 'blankslate' do
Rake::GemPackageTask.new(blankslate_spec) do |t|
t.need_tar = true
@@ -157,7 +158,7 @@ desc "Look for Debugging print lines"
task :dbg do
FileList['**/*.rb'].egrep /\bDBG|\bbreakpoint\b/
end
-
+
# RCov ---------------------------------------------------------------
begin
@@ -183,15 +184,15 @@ end
namespace "tags" do
desc "Create a TAGS file"
task :emacs => "TAGS"
-
+
TAGS = 'xctags -e'
-
+
file "TAGS" => SRC_RB do
puts "Makings TAGS"
sh "#{TAGS} #{SRC_RB}", :verbose => false
end
end
-
+
# --------------------------------------------------------------------
# Creating a release
@@ -207,23 +208,23 @@ task :release => [
:update_version,
:package,
:tag] do
-
- announce
+
+ announce
announce "**************************************************************"
announce "* Release #{PKG_VERSION} Complete."
announce "* Packages ready to upload."
announce "**************************************************************"
- announce
+ announce
end
# Validate that everything is ready to go for a release.
task :prerelease do
- announce
+ announce
announce "**************************************************************"
announce "* Making RubyGem Release #{PKG_VERSION}"
announce "* (current version #{CURRENT_VERSION})"
announce "**************************************************************"
- announce
+ announce
# Is a release number supplied?
unless ENV['REL']
@@ -8,13 +8,16 @@
# above copyright notice is included.
#++
-require 'blankslate'
-
######################################################################
# BlankSlate has been promoted to a top level name and is now
# available as a standalone gem. We make the name available in the
# Builder namespace for compatibility.
#
module Builder
- BlankSlate = ::BlankSlate
+ if Object::const_defined?(:BasicObject)
+ BlankSlate = ::BasicObject
+ else
+ require 'blankslate'
+ BlankSlate = ::BlankSlate
+ end
end
View
@@ -136,14 +136,14 @@ def comment!(comment_text)
end
def id!(arg, &block)
- _start_container('#'+arg.to_s, nil, block_given?)
+ _start_container('#'+arg.to_s, nil, ::Kernel.block_given?)
_css_block(block) if block
_unify_block
self
end
def class!(arg, &block)
- _start_container('.'+arg.to_s, nil, block_given?)
+ _start_container('.'+arg.to_s, nil, ::Kernel.block_given?)
_css_block(block) if block
_unify_block
self
@@ -169,7 +169,7 @@ def group!(*args, &block)
end
def method_missing(sym, *args, &block)
- sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
+ sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
if block
_start_container(sym, args.first)
_css_block(block)
View
@@ -10,14 +10,14 @@
module Builder
def self.check_for_name_collision(klass, method_name, defined_constant=nil)
- if klass.instance_methods.include?(method_name.to_s)
+ if klass.method_defined?(method_name.to_s)
fail RuntimeError,
"Name Collision: Method '#{method_name}' is already defined in #{klass}"
end
end
end
-if ! defined?(Builder::XChar)
+if ! defined?(Builder::XChar) and ! String.method_defined?(:encode)
Builder.check_for_name_collision(String, "to_xs")
Builder.check_for_name_collision(Fixnum, "xchr")
end
@@ -78,42 +78,120 @@ module XChar # :nodoc:
(0xE000..0xFFFD),
(0x10000..0x10FFFF)
]
+
+ # http://www.fileformat.info/info/unicode/char/fffd/index.htm
+ REPLACEMENT_CHAR =
+ if String.method_defined?(:encode)
+ "\uFFFD"
+ elsif $KCODE == 'UTF8'
+ "\xEF\xBF\xBD"
+ else
+ '*'
+ end
end
end
-######################################################################
-# Enhance the Fixnum class with a XML escaped character conversion.
-#
-class Fixnum
- XChar = Builder::XChar if ! defined?(XChar)
-
- # XML escaped version of chr. When <tt>escape</tt> is set to false
- # the CP1252 fix is still applied but utf-8 characters are not
- # converted to character entities.
- def xchr(escape=true)
- n = XChar::CP1252[self] || self
- case n when *XChar::VALID
- XChar::PREDEFINED[n] or (n<128 ? n.chr : (escape ? "&##{n};" : [n].pack('U*')))
- else
- '*'
+if String.method_defined?(:encode)
+ module Builder
+ module XChar # :nodoc:
+ CP1252_DIFFERENCES, UNICODE_EQUIVALENT = Builder::XChar::CP1252.each.
+ inject([[],[]]) {|(domain,range),(key,value)|
+ [domain << key,range << value]
+ }.map {|seq| seq.pack('U*').force_encoding('utf-8')}
+
+ XML_PREDEFINED = Regexp.new('[' +
+ Builder::XChar::PREDEFINED.keys.pack('U*').force_encoding('utf-8') +
+ ']')
+
+ INVALID_XML_CHAR = Regexp.new('[^'+
+ Builder::XChar::VALID.map { |item|
+ case item
+ when Fixnum
+ [item].pack('U').force_encoding('utf-8')
+ when Range
+ [item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8')
+ end
+ }.join +
+ ']')
+
+ ENCODING_BINARY = Encoding.find('BINARY')
+ ENCODING_UTF8 = Encoding.find('UTF-8')
+ ENCODING_ISO1 = Encoding.find('ISO-8859-1')
+
+ # convert a string to valid UTF-8, compensating for a number of
+ # common errors.
+ def XChar.unicode(string)
+ if string.encoding == ENCODING_BINARY
+ if string.ascii_only?
+ string
+ else
+ string = string.clone.force_encoding(ENCODING_UTF8)
+ if string.valid_encoding?
+ string
+ else
+ string.encode(ENCODING_UTF8, ENCODING_ISO1)
+ end
+ end
+
+ elsif string.encoding == ENCODING_UTF8
+ if string.valid_encoding?
+ string
+ else
+ string.encode(ENCODING_UTF8, ENCODING_ISO1)
+ end
+
+ else
+ string.encode(ENCODING_UTF8)
+ end
+ end
+
+ # encode a string per XML rules
+ def XChar.encode(string)
+ unicode(string).
+ tr(CP1252_DIFFERENCES, UNICODE_EQUIVALENT).
+ gsub(INVALID_XML_CHAR, REPLACEMENT_CHAR).
+ gsub(XML_PREDEFINED) {|c| PREDEFINED[c.ord]}
+ end
end
end
-end
+else
-######################################################################
-# Enhance the String class with a XML escaped character version of
-# to_s.
-#
-class String
- # XML escaped version of to_s. When <tt>escape</tt> is set to false
- # the CP1252 fix is still applied but utf-8 characters are not
- # converted to character entities.
- def to_xs(escape=true)
- unpack('U*').map {|n| n.xchr(escape)}.join # ASCII, UTF-8
- rescue
- unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
+ ######################################################################
+ # Enhance the Fixnum class with a XML escaped character conversion.
+ #
+ class Fixnum
+ XChar = Builder::XChar if ! defined?(XChar)
+
+ # XML escaped version of chr. When <tt>escape</tt> is set to false
+ # the CP1252 fix is still applied but utf-8 characters are not
+ # converted to character entities.
+ def xchr(escape=true)
+ n = XChar::CP1252[self] || self
+ case n when *XChar::VALID
+ XChar::PREDEFINED[n] or
+ (n<128 ? n.chr : (escape ? "&##{n};" : [n].pack('U*')))
+ else
+ Builder::XChar::REPLACEMENT_CHAR
+ end
+ end
+ end
+
+
+ ######################################################################
+ # Enhance the String class with a XML escaped character version of
+ # to_s.
+ #
+ class String
+ # XML escaped version of to_s. When <tt>escape</tt> is set to false
+ # the CP1252 fix is still applied but utf-8 characters are not
+ # converted to character entities.
+ def to_xs(escape=true)
+ unpack('U*').map {|n| n.xchr(escape)}.join # ASCII, UTF-8
+ rescue
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
+ end
end
end
Oops, something went wrong.

0 comments on commit b7c99a9

Please sign in to comment.