Updated to Builder 2.0 [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4260 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
a9e02fd99f
commit
71a570ffd7
|
@ -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)
|
||||
|
|
|
@ -14,8 +14,11 @@ 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
|
||||
|
@ -29,10 +32,14 @@ end
|
|||
|
||||
# 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,6 +51,9 @@ end
|
|||
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
|
||||
|
|
|
@ -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 => '&', # ampersand
|
||||
60 => '<', # left angle bracket
|
||||
62 => '>', # 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
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'builder/blankslate'
|
||||
|
||||
module Builder #:nodoc:
|
||||
module Builder
|
||||
|
||||
# Generic error for builder
|
||||
class IllegalBlockError < RuntimeError #:nodoc:
|
||||
|
@ -14,7 +14,7 @@ module Builder #: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 @@ module Builder #:nodoc:
|
|||
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 @@ module Builder #:nodoc:
|
|||
|
||||
private
|
||||
|
||||
require 'builder/xchar'
|
||||
def _escape(text)
|
||||
text.
|
||||
gsub(%r{&}, '&').
|
||||
gsub(%r{<}, '<').
|
||||
gsub(%r{>}, '>')
|
||||
text.to_xs
|
||||
end
|
||||
|
||||
def _escape_quote(text)
|
||||
_escape(text).gsub(%r{"}, '"') # " WART
|
||||
end
|
||||
|
||||
def _capture_outer_self(block)
|
||||
|
|
|
@ -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 @@ module Builder
|
|||
# :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 @@ module Builder
|
|||
[: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 @@ module Builder
|
|||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue