Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated to Builder 2.0 [DHH]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4260 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 71a570ffd7ecc94b5b474c659a34e36a29989a65 1 parent a9e02fd
David Heinemeier Hansson dhh authored
2  activesupport/CHANGELOG
View
@@ -1,5 +1,7 @@
*SVN*
+* Updated to Builder 2.0 [DHH]
+
* Add Array#split for dividing arrays into one or more subarrays by value or block. [Sam Stephenson]
*1.3.1* (April 6th, 2006)
22 activesupport/lib/active_support/vendor/builder/blankslate.rb
View
@@ -14,12 +14,15 @@ module Builder #:nodoc:
# methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
# BlankSlate is useful as a base class when writing classes that
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
- class BlankSlate #:nodoc:
+ class BlankSlate
class << self
+
+ # Hide the method named +name+ in the BlankSlate class. Don't
+ # hide +instance_eval+ or any method beginning with "__".
def hide(name)
- undef_method name if
- instance_methods.include?(name.to_s) and
- name !~ /^(__|instance_eval)/
+ undef_method name if
+ instance_methods.include?(name.to_s) and
+ name !~ /^(__|instance_eval)/
end
end
@@ -29,10 +32,14 @@ def hide(name)
# Since Ruby is very dynamic, methods added to the ancestors of
# BlankSlate <em>after BlankSlate is defined</em> will show up in the
-# list of available BlankSlate methods. We handle this by defining a hook in the Object and Kernel classes that will hide any defined
+# list of available BlankSlate methods. We handle this by defining a
+# hook in the Object and Kernel classes that will hide any defined
module Kernel #:nodoc:
class << self
alias_method :blank_slate_method_added, :method_added
+
+ # Detect method additions to Kernel and remove them in the
+ # BlankSlate class.
def method_added(name)
blank_slate_method_added(name)
return if self != Kernel
@@ -44,9 +51,12 @@ def method_added(name)
class Object #:nodoc:
class << self
alias_method :blank_slate_method_added, :method_added
+
+ # Detect method additions to Object and remove them in the
+ # BlankSlate class.
def method_added(name)
blank_slate_method_added(name)
- return if self != Object
+ return if self != Object
Builder::BlankSlate.hide(name)
end
end
112 activesupport/lib/active_support/vendor/builder/xchar.rb
View
@@ -0,0 +1,112 @@
+#!/usr/bin/env ruby
+
+# The XChar library is provided courtesy of Sam Ruby (See
+# http://intertwingly.net/stories/2005/09/28/xchar.rb)
+
+# --------------------------------------------------------------------
+
+# If the Builder::XChar module is not currently defined, fail on any
+# name clashes in standard library classes.
+
+module Builder
+ def self.check_for_name_collision(klass, method_name, defined_constant=nil)
+ if klass.instance_methods.include?(method_name)
+ fail RuntimeError,
+ "Name Collision: Method '#{method_name}' is already defined in #{klass}"
+ end
+ end
+end
+
+if ! defined?(Builder::XChar)
+ Builder.check_for_name_collision(String, "to_xs")
+ Builder.check_for_name_collision(Fixnum, "xchr")
+end
+
+######################################################################
+module Builder
+
+ ####################################################################
+ # XML Character converter, from Sam Ruby:
+ # (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
+ #
+ module XChar # :nodoc:
+
+ # See
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
+ # for details.
+ CP1252 = { # :nodoc:
+ 128 => 8364, # euro sign
+ 130 => 8218, # single low-9 quotation mark
+ 131 => 402, # latin small letter f with hook
+ 132 => 8222, # double low-9 quotation mark
+ 133 => 8230, # horizontal ellipsis
+ 134 => 8224, # dagger
+ 135 => 8225, # double dagger
+ 136 => 710, # modifier letter circumflex accent
+ 137 => 8240, # per mille sign
+ 138 => 352, # latin capital letter s with caron
+ 139 => 8249, # single left-pointing angle quotation mark
+ 140 => 338, # latin capital ligature oe
+ 142 => 381, # latin capital letter z with caron
+ 145 => 8216, # left single quotation mark
+ 146 => 8217, # right single quotation mark
+ 147 => 8220, # left double quotation mark
+ 148 => 8221, # right double quotation mark
+ 149 => 8226, # bullet
+ 150 => 8211, # en dash
+ 151 => 8212, # em dash
+ 152 => 732, # small tilde
+ 153 => 8482, # trade mark sign
+ 154 => 353, # latin small letter s with caron
+ 155 => 8250, # single right-pointing angle quotation mark
+ 156 => 339, # latin small ligature oe
+ 158 => 382, # latin small letter z with caron
+ 159 => 376, # latin capital letter y with diaeresis
+ }
+
+ # See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
+ PREDEFINED = {
+ 38 => '&amp;', # ampersand
+ 60 => '&lt;', # left angle bracket
+ 62 => '&gt;', # right angle bracket
+ }
+
+ # See http://www.w3.org/TR/REC-xml/#charsets for details.
+ VALID = [
+ [0x9, 0xA, 0xD],
+ (0x20..0xD7FF),
+ (0xE000..0xFFFD),
+ (0x10000..0x10FFFF)
+ ]
+ end
+
+end
+
+
+######################################################################
+# Enhance the Fixnum class with a XML escaped character conversion.
+#
+class Fixnum #:nodoc:
+ XChar = Builder::XChar if ! defined?(XChar)
+
+ # XML escaped version of chr
+ def xchr
+ n = XChar::CP1252[self] || self
+ n = 42 unless XChar::VALID.find {|range| range.include? n}
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
+ end
+end
+
+
+######################################################################
+# Enhance the String class with a XML escaped character version of
+# to_s.
+#
+class String #:nodoc:
+ # XML escaped version of to_s
+ def to_xs
+ unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
+ rescue
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
+ end
+end
20 activesupport/lib/active_support/vendor/builder/xmlbase.rb
View
@@ -2,7 +2,7 @@
require 'builder/blankslate'
-module Builder #:nodoc:
+module Builder
# Generic error for builder
class IllegalBlockError < RuntimeError #:nodoc:
@@ -14,7 +14,7 @@ class XmlBase < BlankSlate #:nodoc:
# Create an XML markup builder.
#
- # out:: Object receiving the markup.1 +out+ must respond to
+ # out:: Object receiving the markup. +out+ must respond to
# <tt><<</tt>.
# indent:: Number of spaces used for indentation (0 implies no
# indentation and no line breaks).
@@ -76,15 +76,15 @@ def method_missing(sym, *args, &block)
end
# Append text to the output target. Escape any markup. May be
- # used within the markup brackets as:
+ # used within the markup brakets as:
#
- # builder.p { br; text! "HI" } #=> <p><br/>HI</p>
+ # builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
def text!(text)
_text(_escape(text))
end
# Append text to the output target without escaping any markup.
- # May be used within the markup brackets as:
+ # May be used within the markup brakets as:
#
# builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
#
@@ -112,11 +112,13 @@ def nil?
private
+ require 'builder/xchar'
def _escape(text)
- text.
- gsub(%r{&}, '&amp;').
- gsub(%r{<}, '&lt;').
- gsub(%r{>}, '&gt;')
+ text.to_xs
+ end
+
+ def _escape_quote(text)
+ _escape(text).gsub(%r{"}, '&quot;') # " WART
end
def _capture_outer_self(block)
32 activesupport/lib/active_support/vendor/builder/xmlmarkup.rb
View
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
#--
-# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
+# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
@@ -165,13 +165,23 @@ class XmlMarkup < XmlBase
# :target=><em>target_object</em>::
# Object receiving the markup. +out+ must respond to the
# <tt><<</tt> operator. The default is a plain string target.
+ #
# :indent=><em>indentation</em>::
# Number of spaces used for indentation. The default is no
# indentation and no line breaks.
+ #
# :margin=><em>initial_indentation_level</em>::
# Amount of initial indentation (specified in levels, not
# spaces).
#
+ # :escape_attrs=><b>OBSOLETE</em>::
+ # The :escape_attrs option is no longer supported by builder
+ # (and will be quietly ignored). String attribute values are
+ # now automatically escaped. If you need unescaped attribute
+ # values (perhaps you are using entities in the attribute
+ # values), then give the value as a Symbol. This allows much
+ # finer control over escaping attribute values.
+ #
def initialize(options={})
indent = options[:indent] || 0
margin = options[:margin] || 0
@@ -239,12 +249,13 @@ def instruct!(directive_tag=:xml, attrs={})
[:version, :encoding, :standalone])
end
- # Surrounds the given text with a CDATA tag
+ # Insert a CDATA section into the XML markup.
#
# For example:
#
- # xml.cdata! "blah blah blah"
- # # => <![CDATA[blah blah blah]]>
+ # xml.cdata!("text to be included in cdata")
+ # #=> <![CDATA[text to be included in cdata]]>
+ #
def cdata!(text)
_ensure_no_block block_given?
_special("<![CDATA[", "]]>", text, nil)
@@ -289,10 +300,19 @@ def _insert_attributes(attrs, order=[])
return if attrs.nil?
order.each do |k|
v = attrs[k]
- @target << %{ #{k}="#{v}"} if v
+ @target << %{ #{k}="#{_attr_value(v)}"} if v
end
attrs.each do |k, v|
- @target << %{ #{k}="#{v}"} unless order.member?(k)
+ @target << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k)
+ end
+ end
+
+ def _attr_value(value)
+ case value
+ when Symbol
+ value.to_s
+ else
+ _escape_quote(value.to_s)
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.