aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorMikel Lindsaar <raasdnil@gmail.com>2010-01-28 11:51:37 +1100
committerMikel Lindsaar <raasdnil@gmail.com>2010-01-28 11:51:37 +1100
commitf1fe71d754f589710ce6a4deacca0e2dc4b5b8de (patch)
treecf31ab1cf84abe47d553ae1132c2135304e78476 /activesupport
parent9029efce410ea49de6eb65481fb2ad8143e69c35 (diff)
downloadrails-f1fe71d754f589710ce6a4deacca0e2dc4b5b8de.tar.gz
rails-f1fe71d754f589710ce6a4deacca0e2dc4b5b8de.tar.bz2
rails-f1fe71d754f589710ce6a4deacca0e2dc4b5b8de.zip
Unvendor'd Builder. Now requires the Builder gem as a dependency
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/activesupport.gemspec1
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb113
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder.rb13
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb20
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb250
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb115
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb139
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb63
-rw-r--r--activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb328
10 files changed, 3 insertions, 1041 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 3f008ac6f8..2d80f3ce6b 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*Edge*
+* Unvendor'd Builder. Now requires the Builder gem as a dependency
+
* Unvendor'd TZInfo. Now requires the TZInfo gem as a dependency
* YAML serialization for OrderedHash. #3608 [Gregor Schmidt]
diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec
index e610456a5e..ada5c5c0fe 100644
--- a/activesupport/activesupport.gemspec
+++ b/activesupport/activesupport.gemspec
@@ -8,6 +8,7 @@ Gem::Specification.new do |s|
s.add_dependency('i18n', '~> 0.3.0')
s.add_dependency('tzinfo', '~> 0.3.16')
+ s.add_dependency('builder', '~> 2.1.2')
s.files = Dir['CHANGELOG', 'README', 'lib/**/*']
s.require_path = 'lib'
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb
deleted file mode 100644
index da6034d9c4..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
-# All rights reserved.
-
-# Permission is granted for use, copying, modification, distribution,
-# and distribution of modified versions of this work as long as the
-# above copyright notice is included.
-#++
-
-######################################################################
-# BlankSlate provides an abstract base class with no predefined
-# 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
- class << self
-
- # Hide the method named +name+ in the BlankSlate class. Don't
- # hide +instance_eval+ or any method beginning with "__".
- def hide(name)
- if instance_methods.include?(name.to_s) and
- name !~ /^(__|instance_eval)/
- @hidden_methods ||= {}
- @hidden_methods[name.to_sym] = instance_method(name)
- undef_method name
- end
- end
-
- def find_hidden_method(name)
- @hidden_methods ||= {}
- @hidden_methods[name] || superclass.find_hidden_method(name)
- end
-
- # Redefine a previously hidden method so that it may be called on a blank
- # slate object.
- def reveal(name)
- bound_method = nil
- unbound_method = find_hidden_method(name)
- fail "Don't know how to reveal method '#{name}'" unless unbound_method
- define_method(name) do |*args|
- bound_method ||= unbound_method.bind(self)
- bound_method.call(*args)
- end
- end
- end
-
- instance_methods.each { |m| hide(m) }
-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 method
-# defined after BlankSlate has been loaded.
-#
-module Kernel
- 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)
- result = blank_slate_method_added(name)
- return result if self != Kernel
- BlankSlate.hide(name)
- result
- end
- end
-end
-
-######################################################################
-# Same as above, except in Object.
-#
-class Object
- 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)
- result = blank_slate_method_added(name)
- return result if self != Object
- BlankSlate.hide(name)
- result
- end
-
- def find_hidden_method(name)
- nil
- end
- end
-end
-
-######################################################################
-# Also, modules included into Object need to be scanned and have their
-# instance methods removed from blank slate. In theory, modules
-# included into Kernel would have to be removed as well, but a
-# "feature" of Ruby prevents late includes into modules from being
-# exposed in the first place.
-#
-class Module
- alias blankslate_original_append_features append_features
- def append_features(mod)
- result = blankslate_original_append_features(mod)
- return result if mod != Object
- instance_methods.each do |name|
- BlankSlate.hide(name)
- end
- result
- end
-end \ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder.rb
deleted file mode 100644
index 9719277669..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env ruby
-
-#--
-# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
-# All rights reserved.
-
-# Permission is granted for use, copying, modification, distribution,
-# and distribution of modified versions of this work as long as the
-# above copyright notice is included.
-#++
-
-require 'builder/xmlmarkup'
-require 'builder/xmlevents'
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb
deleted file mode 100644
index 2935b6f1d1..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
-# All rights reserved.
-
-# Permission is granted for use, copying, modification, distribution,
-# and distribution of modified versions of this work as long as the
-# 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
-end
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb
deleted file mode 100644
index e086a1b132..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
-# Copyright 2005 by Scott Barron (scott@elitists.net).
-# All rights reserved.
-#
-# Permission is granted for use, copying, modification, distribution,
-# and distribution of modified versions of this work as long as the
-# above copyright notice is included.
-#
-# Much of this is taken from Jim's work in xmlbase.rb and xmlmarkup.rb.
-# Documentation has also been copied and pasted and modified to reflect
-# that we're building CSS here instead of XML. Jim is conducting the
-# orchestra here and I'm just off in the corner playing a flute.
-#++
-
-# Provide a flexible and easy to use Builder for creating Cascading
-# Style Sheets (CSS).
-
-
-require 'builder/blankslate'
-
-module Builder
-
- # Create a Cascading Style Sheet (CSS) using Ruby.
- #
- # Example usage:
- #
- # css = Builder::CSS.new
- #
- # text_color = '#7F7F7F'
- # preferred_fonts = 'Helvetica, Arial, sans_serif'
- #
- # css.comment! 'This is our stylesheet'
- # css.body {
- # background_color '#FAFAFA'
- # font_size 'small'
- # font_family preferred_fonts
- # color text_color
- # }
- #
- # css.id!('navbar') {
- # width '500px'
- # }
- #
- # css.class!('navitem') {
- # color 'red'
- # }
- #
- # css.a :hover {
- # text_decoration 'underline'
- # }
- #
- # css.div(:id => 'menu') {
- # background 'green'
- # }
- #
- # css.div(:class => 'foo') {
- # background 'red'
- # }
- #
- # This will yield the following stylesheet:
- #
- # /* This is our stylesheet */
- # body {
- # background_color: #FAFAFA;
- # font_size: small;
- # font_family: Helvetica, Arial, sans_serif;
- # color: #7F7F7F;
- # }
- #
- # #navbar {
- # width: 500px;
- # }
- #
- # .navitem {
- # color: red;
- # }
- #
- # a:hover {
- # text_decoration: underline;
- # }
- #
- # div#menu {
- # background: green;
- # }
- #
- # div.foo {
- # background: red;
- # }
- #
- class CSS < BlankSlate
-
- # Create a CSS builder.
- #
- # out:: Object receiving the markup.1 +out+ must respond to
- # <tt><<</tt>.
- # indent:: Number of spaces used for indentation (0 implies no
- # indentation and no line breaks).
- #
- def initialize(indent=2)
- @indent = indent
- @target = []
- @parts = []
- @library = {}
- end
-
- def +(part)
- _join_with_op! '+'
- self
- end
-
- def >>(part)
- _join_with_op! ''
- self
- end
-
- def >(part)
- _join_with_op! '>'
- self
- end
-
- def |(part)
- _join_with_op! ','
- self
- end
-
- # Return the target of the builder
- def target!
- @target * ''
- end
-
- # Create a comment string in the output.
- def comment!(comment_text)
- @target << "/* #{comment_text} */\n"
- end
-
- def id!(arg, &block)
- _start_container('#'+arg.to_s, nil, block_given?)
- _css_block(block) if block
- _unify_block
- self
- end
-
- def class!(arg, &block)
- _start_container('.'+arg.to_s, nil, block_given?)
- _css_block(block) if block
- _unify_block
- self
- end
-
- def store!(sym, &block)
- @library[sym] = block.to_proc
- end
-
- def group!(*args, &block)
- args.each do |arg|
- if arg.is_a?(Symbol)
- instance_eval(&@library[arg])
- else
- instance_eval(&arg)
- end
- _text ', ' unless arg == args.last
- end
- if block
- _css_block(block)
- _unify_block
- end
- end
-
- def method_missing(sym, *args, &block)
- sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
- if block
- _start_container(sym, args.first)
- _css_block(block)
- _unify_block
- elsif @in_block
- _indent
- _css_line(sym, *args)
- _newline
- return self
- else
- _start_container(sym, args.first, false)
- _unify_block
- end
- self
- end
-
- # "Cargo culted" from Jim who also "cargo culted" it. See xmlbase.rb.
- def nil?
- false
- end
-
- private
- def _unify_block
- @target << @parts * ''
- @parts = []
- end
-
- def _join_with_op!(op)
- rhs, lhs = @target.pop, @target.pop
- @target << "#{lhs} #{op} #{rhs}"
- end
-
- def _text(text)
- @parts << text
- end
-
- def _css_block(block)
- _newline
- _nested_structures(block)
- _end_container
- _end_block
- end
-
- def _end_block
- _newline
- _newline
- end
-
- def _newline
- _text "\n"
- end
-
- def _indent
- _text ' ' * @indent
- end
-
- def _nested_structures(block)
- @in_block = true
- self.instance_eval(&block)
- @in_block = false
- end
-
- def _start_container(sym, atts = {}, with_bracket = true)
- selector = sym.to_s
- selector << ".#{atts[:class]}" if atts && atts[:class]
- selector << '#' + "#{atts[:id]}" if atts && atts[:id]
- @parts << "#{selector}#{with_bracket ? ' {' : ''}"
- end
-
- def _end_container
- @parts << "}"
- end
-
- def _css_line(sym, *args)
- _text("#{sym.to_s.gsub('_','-')}: #{args * ' '};")
- end
- end
-end
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb
deleted file mode 100644
index 8bdbd05899..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/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.to_s)
- 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
- XChar = Builder::XChar if ! defined?(XChar)
-
- # XML escaped version of chr
- def xchr
- n = XChar::CP1252[self] || self
- case n when *XChar::VALID
- XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
- else
- '*'
- end
- end
-end
-
-
-######################################################################
-# Enhance the String class with a XML escaped character version of
-# to_s.
-#
-class String
- # 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
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb
deleted file mode 100644
index ace4b56d59..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'builder/blankslate'
-
-module Builder
-
- # Generic error for builder
- class IllegalBlockError < RuntimeError; end
-
- # XmlBase is a base class for building XML builders. See
- # Builder::XmlMarkup and Builder::XmlEvents for examples.
- class XmlBase < BlankSlate
-
- # Create an XML markup builder.
- #
- # 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).
- # initial:: Level of initial indentation.
- #
- def initialize(indent=0, initial=0)
- @indent = indent
- @level = initial
- end
-
- # Create a tag named +sym+. Other than the first argument which
- # is the tag name, the arguments are the same as the tags
- # implemented via <tt>method_missing</tt>.
- def tag!(sym, *args, &block)
- method_missing(sym.to_sym, *args, &block)
- end
-
- # Create XML markup based on the name of the method. This method
- # is never invoked directly, but is called for each markup method
- # in the markup block.
- def method_missing(sym, *args, &block)
- text = nil
- attrs = nil
- sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
- args.each do |arg|
- case arg
- when Hash
- attrs ||= {}
- attrs.merge!(arg)
- else
- text ||= ''
- text << arg.to_s
- end
- end
- if block
- unless text.nil?
- raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
- end
- _indent
- _start_tag(sym, attrs)
- _newline
- _nested_structures(block)
- _indent
- _end_tag(sym)
- _newline
- elsif text.nil?
- _indent
- _start_tag(sym, attrs, true)
- _newline
- else
- _indent
- _start_tag(sym, attrs)
- text! text
- _end_tag(sym)
- _newline
- end
- @target
- end
-
- # Append text to the output target. Escape any markup. May be
- # used within the markup brackets as:
- #
- # 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:
- #
- # builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
- #
- # This is useful when using non-builder enabled software that
- # generates strings. Just insert the string directly into the
- # builder without changing the inserted markup.
- #
- # It is also useful for stacking builder objects. Builders only
- # use <tt><<</tt> to append to the target, so by supporting this
- # method/operation builders can use other builders as their
- # targets.
- def <<(text)
- _text(text)
- end
-
- # For some reason, nil? is sent to the XmlMarkup object. If nil?
- # is not defined and method_missing is invoked, some strange kind
- # of recursion happens. Since nil? won't ever be an XML tag, it
- # is pretty safe to define it here. (Note: this is an example of
- # cargo cult programming,
- # cf. http://fishbowl.pastiche.org/2004/10/13/cargo_cult_programming).
- def nil?
- false
- end
-
- private
-
- require 'builder/xchar'
- def _escape(text)
- text.to_xs
- end
-
- def _escape_quote(text)
- _escape(text).gsub(%r{"}, '&quot;') # " WART
- end
-
- def _newline
- return if @indent == 0
- text! "\n"
- end
-
- def _indent
- return if @indent == 0 || @level == 0
- text!(" " * (@level * @indent))
- end
-
- def _nested_structures(block)
- @level += 1
- block.call(self)
- ensure
- @level -= 1
- end
- end
-end
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb
deleted file mode 100644
index b373e4da3c..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env ruby
-
-#--
-# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
-# All rights reserved.
-
-# Permission is granted for use, copying, modification, distribution,
-# and distribution of modified versions of this work as long as the
-# above copyright notice is included.
-#++
-
-require 'builder/xmlmarkup'
-
-module Builder
-
- # Create a series of SAX-like XML events (e.g. start_tag, end_tag)
- # from the markup code. XmlEvent objects are used in a way similar
- # to XmlMarkup objects, except that a series of events are generated
- # and passed to a handler rather than generating character-based
- # markup.
- #
- # Usage:
- # xe = Builder::XmlEvents.new(handler)
- # xe.title("HI") # Sends start_tag/end_tag/text messages to the handler.
- #
- # Indentation may also be selected by providing value for the
- # indentation size and initial indentation level.
- #
- # xe = Builder::XmlEvents.new(handler, indent_size, initial_indent_level)
- #
- # == XML Event Handler
- #
- # The handler object must expect the following events.
- #
- # [<tt>start_tag(tag, attrs)</tt>]
- # Announces that a new tag has been found. +tag+ is the name of
- # the tag and +attrs+ is a hash of attributes for the tag.
- #
- # [<tt>end_tag(tag)</tt>]
- # Announces that an end tag for +tag+ has been found.
- #
- # [<tt>text(text)</tt>]
- # Announces that a string of characters (+text+) has been found.
- # A series of characters may be broken up into more than one
- # +text+ call, so the client cannot assume that a single
- # callback contains all the text data.
- #
- class XmlEvents < XmlMarkup
- def text!(text)
- @target.text(text)
- end
-
- def _start_tag(sym, attrs, end_too=false)
- @target.start_tag(sym, attrs)
- _end_tag(sym) if end_too
- end
-
- def _end_tag(sym)
- @target.end_tag(sym)
- end
- end
-
-end
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb
deleted file mode 100644
index ec59dddc36..0000000000
--- a/activesupport/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb
+++ /dev/null
@@ -1,328 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
-# All rights reserved.
-
-# Permission is granted for use, copying, modification, distribution,
-# and distribution of modified versions of this work as long as the
-# above copyright notice is included.
-#++
-
-# Provide a flexible and easy to use Builder for creating XML markup.
-# See XmlBuilder for usage details.
-
-require 'builder/xmlbase'
-
-module Builder
-
- # Create XML markup easily. All (well, almost all) methods sent to
- # an XmlMarkup object will be translated to the equivalent XML
- # markup. Any method with a block will be treated as an XML markup
- # tag with nested markup in the block.
- #
- # Examples will demonstrate this easier than words. In the
- # following, +xm+ is an +XmlMarkup+ object.
- #
- # xm.em("emphasized") # => <em>emphasized</em>
- # xm.em { xmm.b("emp & bold") } # => <em><b>emph &amp; bold</b></em>
- # xm.a("A Link", "href"=>"http://onestepback.org")
- # # => <a href="http://onestepback.org">A Link</a>
- # xm.div { br } # => <div><br/></div>
- # xm.target("name"=>"compile", "option"=>"fast")
- # # => <target option="fast" name="compile"\>
- # # NOTE: order of attributes is not specified.
- #
- # xm.instruct! # <?xml version="1.0" encoding="UTF-8"?>
- # xm.html { # <html>
- # xm.head { # <head>
- # xm.title("History") # <title>History</title>
- # } # </head>
- # xm.body { # <body>
- # xm.comment! "HI" # <! -- HI -->
- # xm.h1("Header") # <h1>Header</h1>
- # xm.p("paragraph") # <p>paragraph</p>
- # } # </body>
- # } # </html>
- #
- # == Notes:
- #
- # * The order that attributes are inserted in markup tags is
- # undefined.
- #
- # * Sometimes you wish to insert text without enclosing tags. Use
- # the <tt>text!</tt> method to accomplish this.
- #
- # Example:
- #
- # xm.div { # <div>
- # xm.text! "line"; xm.br # line<br/>
- # xm.text! "another line"; xmbr # another line<br/>
- # } # </div>
- #
- # * The special XML characters <, >, and & are converted to &lt;,
- # &gt; and &amp; automatically. Use the <tt><<</tt> operation to
- # insert text without modification.
- #
- # * Sometimes tags use special characters not allowed in ruby
- # identifiers. Use the <tt>tag!</tt> method to handle these
- # cases.
- #
- # Example:
- #
- # xml.tag!("SOAP:Envelope") { ... }
- #
- # will produce ...
- #
- # <SOAP:Envelope> ... </SOAP:Envelope>"
- #
- # <tt>tag!</tt> will also take text and attribute arguments (after
- # the tag name) like normal markup methods. (But see the next
- # bullet item for a better way to handle XML namespaces).
- #
- # * Direct support for XML namespaces is now available. If the
- # first argument to a tag call is a symbol, it will be joined to
- # the tag to produce a namespace:tag combination. It is easier to
- # show this than describe it.
- #
- # xml.SOAP :Envelope do ... end
- #
- # Just put a space before the colon in a namespace to produce the
- # right form for builder (e.g. "<tt>SOAP:Envelope</tt>" =>
- # "<tt>xml.SOAP :Envelope</tt>")
- #
- # * XmlMarkup builds the markup in any object (called a _target_)
- # that accepts the <tt><<</tt> method. If no target is given,
- # then XmlMarkup defaults to a string target.
- #
- # Examples:
- #
- # xm = Builder::XmlMarkup.new
- # result = xm.title("yada")
- # # result is a string containing the markup.
- #
- # buffer = ""
- # xm = Builder::XmlMarkup.new(buffer)
- # # The markup is appended to buffer (using <<)
- #
- # xm = Builder::XmlMarkup.new(STDOUT)
- # # The markup is written to STDOUT (using <<)
- #
- # xm = Builder::XmlMarkup.new
- # x2 = Builder::XmlMarkup.new(:target=>xm)
- # # Markup written to +x2+ will be send to +xm+.
- #
- # * Indentation is enabled by providing the number of spaces to
- # indent for each level as a second argument to XmlBuilder.new.
- # Initial indentation may be specified using a third parameter.
- #
- # Example:
- #
- # xm = Builder.new(:indent=>2)
- # # xm will produce nicely formatted and indented XML.
- #
- # xm = Builder.new(:indent=>2, :margin=>4)
- # # xm will produce nicely formatted and indented XML with 2
- # # spaces per indent and an over all indentation level of 4.
- #
- # builder = Builder::XmlMarkup.new(:target=>$stdout, :indent=>2)
- # builder.name { |b| b.first("Jim"); b.last("Weirich) }
- # # prints:
- # # <name>
- # # <first>Jim</first>
- # # <last>Weirich</last>
- # # </name>
- #
- # * The instance_eval implementation which forces self to refer to
- # the message receiver as self is now obsolete. We now use normal
- # block calls to execute the markup block. This means that all
- # markup methods must now be explicitly send to the xml builder.
- # For instance, instead of
- #
- # xml.div { strong("text") }
- #
- # you need to write:
- #
- # xml.div { xml.strong("text") }
- #
- # Although more verbose, the subtle change in semantics within the
- # block was found to be prone to error. To make this change a
- # little less cumbersome, the markup block now gets the markup
- # object sent as an argument, allowing you to use a shorter alias
- # within the block.
- #
- # For example:
- #
- # xml_builder = Builder::XmlMarkup.new
- # xml_builder.div { |xml|
- # xml.stong("text")
- # }
- #
- class XmlMarkup < XmlBase
-
- # Create an XML markup builder. Parameters are specified by an
- # option hash.
- #
- # :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
- super(indent, margin)
- @target = options[:target] || ""
- end
-
- # Return the target of the builder.
- def target!
- @target
- end
-
- def comment!(comment_text)
- _ensure_no_block block_given?
- _special("<!-- ", " -->", comment_text, nil)
- end
-
- # Insert an XML declaration into the XML markup.
- #
- # For example:
- #
- # xml.declare! :ELEMENT, :blah, "yada"
- # # => <!ELEMENT blah "yada">
- def declare!(inst, *args, &block)
- _indent
- @target << "<!#{inst}"
- args.each do |arg|
- case arg
- when String
- @target << %{ "#{arg}"} # " WART
- when Symbol
- @target << " #{arg}"
- end
- end
- if block_given?
- @target << " ["
- _newline
- _nested_structures(block)
- @target << "]"
- end
- @target << ">"
- _newline
- end
-
- # Insert a processing instruction into the XML markup. E.g.
- #
- # For example:
- #
- # xml.instruct!
- # #=> <?xml version="1.0" encoding="UTF-8"?>
- # xml.instruct! :aaa, :bbb=>"ccc"
- # #=> <?aaa bbb="ccc"?>
- #
- def instruct!(directive_tag=:xml, attrs={})
- _ensure_no_block block_given?
- if directive_tag == :xml
- a = { :version=>"1.0", :encoding=>"UTF-8" }
- attrs = a.merge attrs
- end
- _special(
- "<?#{directive_tag}",
- "?>",
- nil,
- attrs,
- [:version, :encoding, :standalone])
- end
-
- # Insert a CDATA section into the XML markup.
- #
- # For example:
- #
- # 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)
- end
-
- private
-
- # NOTE: All private methods of a builder object are prefixed when
- # a "_" character to avoid possible conflict with XML tag names.
-
- # Insert text directly in to the builder's target.
- def _text(text)
- @target << text
- end
-
- # Insert special instruction.
- def _special(open, close, data=nil, attrs=nil, order=[])
- _indent
- @target << open
- @target << data if data
- _insert_attributes(attrs, order) if attrs
- @target << close
- _newline
- end
-
- # Start an XML tag. If <tt>end_too</tt> is true, then the start
- # tag is also the end tag (e.g. <br/>
- def _start_tag(sym, attrs, end_too=false)
- @target << "<#{sym}"
- _insert_attributes(attrs)
- @target << "/" if end_too
- @target << ">"
- end
-
- # Insert an ending tag.
- def _end_tag(sym)
- @target << "</#{sym}>"
- end
-
- # Insert the attributes (given in the hash).
- def _insert_attributes(attrs, order=[])
- return if attrs.nil?
- order.each do |k|
- v = attrs[k]
- @target << %{ #{k}="#{_attr_value(v)}"} if v # " WART
- end
- attrs.each do |k, v|
- @target << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k) # " WART
- end
- end
-
- def _attr_value(value)
- case value
- when Symbol
- value.to_s
- else
- _escape_quote(value.to_s)
- end
- end
-
- def _ensure_no_block(got_block)
- if got_block
- fail IllegalBlockError,
- "Blocks are not allowed on XML instructions"
- end
- end
-
- end
-
-end