Skip to content
This repository
Browse code

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
... ... @@ -1,5 +1,7 @@
1 1 *SVN*
2 2
  3 +* Updated to Builder 2.0 [DHH]
  4 +
3 5 * Add Array#split for dividing arrays into one or more subarrays by value or block. [Sam Stephenson]
4 6
5 7 *1.3.1* (April 6th, 2006)
22 activesupport/lib/active_support/vendor/builder/blankslate.rb
@@ -14,12 +14,15 @@ module Builder #:nodoc:
14 14 # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
15 15 # BlankSlate is useful as a base class when writing classes that
16 16 # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
17   - class BlankSlate #:nodoc:
  17 + class BlankSlate
18 18 class << self
  19 +
  20 + # Hide the method named +name+ in the BlankSlate class. Don't
  21 + # hide +instance_eval+ or any method beginning with "__".
19 22 def hide(name)
20   - undef_method name if
21   - instance_methods.include?(name.to_s) and
22   - name !~ /^(__|instance_eval)/
  23 + undef_method name if
  24 + instance_methods.include?(name.to_s) and
  25 + name !~ /^(__|instance_eval)/
23 26 end
24 27 end
25 28
@@ -29,10 +32,14 @@ def hide(name)
29 32
30 33 # Since Ruby is very dynamic, methods added to the ancestors of
31 34 # BlankSlate <em>after BlankSlate is defined</em> will show up in the
32   -# list of available BlankSlate methods. We handle this by defining a hook in the Object and Kernel classes that will hide any defined
  35 +# list of available BlankSlate methods. We handle this by defining a
  36 +# hook in the Object and Kernel classes that will hide any defined
33 37 module Kernel #:nodoc:
34 38 class << self
35 39 alias_method :blank_slate_method_added, :method_added
  40 +
  41 + # Detect method additions to Kernel and remove them in the
  42 + # BlankSlate class.
36 43 def method_added(name)
37 44 blank_slate_method_added(name)
38 45 return if self != Kernel
@@ -44,9 +51,12 @@ def method_added(name)
44 51 class Object #:nodoc:
45 52 class << self
46 53 alias_method :blank_slate_method_added, :method_added
  54 +
  55 + # Detect method additions to Object and remove them in the
  56 + # BlankSlate class.
47 57 def method_added(name)
48 58 blank_slate_method_added(name)
49   - return if self != Object
  59 + return if self != Object
50 60 Builder::BlankSlate.hide(name)
51 61 end
52 62 end
112 activesupport/lib/active_support/vendor/builder/xchar.rb
... ... @@ -0,0 +1,112 @@
  1 +#!/usr/bin/env ruby
  2 +
  3 +# The XChar library is provided courtesy of Sam Ruby (See
  4 +# http://intertwingly.net/stories/2005/09/28/xchar.rb)
  5 +
  6 +# --------------------------------------------------------------------
  7 +
  8 +# If the Builder::XChar module is not currently defined, fail on any
  9 +# name clashes in standard library classes.
  10 +
  11 +module Builder
  12 + def self.check_for_name_collision(klass, method_name, defined_constant=nil)
  13 + if klass.instance_methods.include?(method_name)
  14 + fail RuntimeError,
  15 + "Name Collision: Method '#{method_name}' is already defined in #{klass}"
  16 + end
  17 + end
  18 +end
  19 +
  20 +if ! defined?(Builder::XChar)
  21 + Builder.check_for_name_collision(String, "to_xs")
  22 + Builder.check_for_name_collision(Fixnum, "xchr")
  23 +end
  24 +
  25 +######################################################################
  26 +module Builder
  27 +
  28 + ####################################################################
  29 + # XML Character converter, from Sam Ruby:
  30 + # (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
  31 + #
  32 + module XChar # :nodoc:
  33 +
  34 + # See
  35 + # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
  36 + # for details.
  37 + CP1252 = { # :nodoc:
  38 + 128 => 8364, # euro sign
  39 + 130 => 8218, # single low-9 quotation mark
  40 + 131 => 402, # latin small letter f with hook
  41 + 132 => 8222, # double low-9 quotation mark
  42 + 133 => 8230, # horizontal ellipsis
  43 + 134 => 8224, # dagger
  44 + 135 => 8225, # double dagger
  45 + 136 => 710, # modifier letter circumflex accent
  46 + 137 => 8240, # per mille sign
  47 + 138 => 352, # latin capital letter s with caron
  48 + 139 => 8249, # single left-pointing angle quotation mark
  49 + 140 => 338, # latin capital ligature oe
  50 + 142 => 381, # latin capital letter z with caron
  51 + 145 => 8216, # left single quotation mark
  52 + 146 => 8217, # right single quotation mark
  53 + 147 => 8220, # left double quotation mark
  54 + 148 => 8221, # right double quotation mark
  55 + 149 => 8226, # bullet
  56 + 150 => 8211, # en dash
  57 + 151 => 8212, # em dash
  58 + 152 => 732, # small tilde
  59 + 153 => 8482, # trade mark sign
  60 + 154 => 353, # latin small letter s with caron
  61 + 155 => 8250, # single right-pointing angle quotation mark
  62 + 156 => 339, # latin small ligature oe
  63 + 158 => 382, # latin small letter z with caron
  64 + 159 => 376, # latin capital letter y with diaeresis
  65 + }
  66 +
  67 + # See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
  68 + PREDEFINED = {
  69 + 38 => '&amp;', # ampersand
  70 + 60 => '&lt;', # left angle bracket
  71 + 62 => '&gt;', # right angle bracket
  72 + }
  73 +
  74 + # See http://www.w3.org/TR/REC-xml/#charsets for details.
  75 + VALID = [
  76 + [0x9, 0xA, 0xD],
  77 + (0x20..0xD7FF),
  78 + (0xE000..0xFFFD),
  79 + (0x10000..0x10FFFF)
  80 + ]
  81 + end
  82 +
  83 +end
  84 +
  85 +
  86 +######################################################################
  87 +# Enhance the Fixnum class with a XML escaped character conversion.
  88 +#
  89 +class Fixnum #:nodoc:
  90 + XChar = Builder::XChar if ! defined?(XChar)
  91 +
  92 + # XML escaped version of chr
  93 + def xchr
  94 + n = XChar::CP1252[self] || self
  95 + n = 42 unless XChar::VALID.find {|range| range.include? n}
  96 + XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
  97 + end
  98 +end
  99 +
  100 +
  101 +######################################################################
  102 +# Enhance the String class with a XML escaped character version of
  103 +# to_s.
  104 +#
  105 +class String #:nodoc:
  106 + # XML escaped version of to_s
  107 + def to_xs
  108 + unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
  109 + rescue
  110 + unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
  111 + end
  112 +end
20 activesupport/lib/active_support/vendor/builder/xmlbase.rb
@@ -2,7 +2,7 @@
2 2
3 3 require 'builder/blankslate'
4 4
5   -module Builder #:nodoc:
  5 +module Builder
6 6
7 7 # Generic error for builder
8 8 class IllegalBlockError < RuntimeError #:nodoc:
@@ -14,7 +14,7 @@ class XmlBase < BlankSlate #:nodoc:
14 14
15 15 # Create an XML markup builder.
16 16 #
17   - # out:: Object receiving the markup.1 +out+ must respond to
  17 + # out:: Object receiving the markup. +out+ must respond to
18 18 # <tt><<</tt>.
19 19 # indent:: Number of spaces used for indentation (0 implies no
20 20 # indentation and no line breaks).
@@ -76,15 +76,15 @@ def method_missing(sym, *args, &block)
76 76 end
77 77
78 78 # Append text to the output target. Escape any markup. May be
79   - # used within the markup brackets as:
  79 + # used within the markup brakets as:
80 80 #
81   - # builder.p { br; text! "HI" } #=> <p><br/>HI</p>
  81 + # builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
82 82 def text!(text)
83 83 _text(_escape(text))
84 84 end
85 85
86 86 # Append text to the output target without escaping any markup.
87   - # May be used within the markup brackets as:
  87 + # May be used within the markup brakets as:
88 88 #
89 89 # builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
90 90 #
@@ -112,11 +112,13 @@ def nil?
112 112
113 113 private
114 114
  115 + require 'builder/xchar'
115 116 def _escape(text)
116   - text.
117   - gsub(%r{&}, '&amp;').
118   - gsub(%r{<}, '&lt;').
119   - gsub(%r{>}, '&gt;')
  117 + text.to_xs
  118 + end
  119 +
  120 + def _escape_quote(text)
  121 + _escape(text).gsub(%r{"}, '&quot;') # " WART
120 122 end
121 123
122 124 def _capture_outer_self(block)
32 activesupport/lib/active_support/vendor/builder/xmlmarkup.rb
... ... @@ -1,6 +1,6 @@
1 1 #!/usr/bin/env ruby
2 2 #--
3   -# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
  3 +# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
4 4 # All rights reserved.
5 5
6 6 # Permission is granted for use, copying, modification, distribution,
@@ -165,13 +165,23 @@ class XmlMarkup < XmlBase
165 165 # :target=><em>target_object</em>::
166 166 # Object receiving the markup. +out+ must respond to the
167 167 # <tt><<</tt> operator. The default is a plain string target.
  168 + #
168 169 # :indent=><em>indentation</em>::
169 170 # Number of spaces used for indentation. The default is no
170 171 # indentation and no line breaks.
  172 + #
171 173 # :margin=><em>initial_indentation_level</em>::
172 174 # Amount of initial indentation (specified in levels, not
173 175 # spaces).
174 176 #
  177 + # :escape_attrs=><b>OBSOLETE</em>::
  178 + # The :escape_attrs option is no longer supported by builder
  179 + # (and will be quietly ignored). String attribute values are
  180 + # now automatically escaped. If you need unescaped attribute
  181 + # values (perhaps you are using entities in the attribute
  182 + # values), then give the value as a Symbol. This allows much
  183 + # finer control over escaping attribute values.
  184 + #
175 185 def initialize(options={})
176 186 indent = options[:indent] || 0
177 187 margin = options[:margin] || 0
@@ -239,12 +249,13 @@ def instruct!(directive_tag=:xml, attrs={})
239 249 [:version, :encoding, :standalone])
240 250 end
241 251
242   - # Surrounds the given text with a CDATA tag
  252 + # Insert a CDATA section into the XML markup.
243 253 #
244 254 # For example:
245 255 #
246   - # xml.cdata! "blah blah blah"
247   - # # => <![CDATA[blah blah blah]]>
  256 + # xml.cdata!("text to be included in cdata")
  257 + # #=> <![CDATA[text to be included in cdata]]>
  258 + #
248 259 def cdata!(text)
249 260 _ensure_no_block block_given?
250 261 _special("<![CDATA[", "]]>", text, nil)
@@ -289,10 +300,19 @@ def _insert_attributes(attrs, order=[])
289 300 return if attrs.nil?
290 301 order.each do |k|
291 302 v = attrs[k]
292   - @target << %{ #{k}="#{v}"} if v
  303 + @target << %{ #{k}="#{_attr_value(v)}"} if v
293 304 end
294 305 attrs.each do |k, v|
295   - @target << %{ #{k}="#{v}"} unless order.member?(k)
  306 + @target << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k)
  307 + end
  308 + end
  309 +
  310 + def _attr_value(value)
  311 + case value
  312 + when Symbol
  313 + value.to_s
  314 + else
  315 + _escape_quote(value.to_s)
296 316 end
297 317 end
298 318

0 comments on commit 71a570f

Please sign in to comment.
Something went wrong with that request. Please try again.