diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2007-10-10 23:01:41 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2007-10-10 23:01:41 +0000 |
commit | e7040b09e8dc381c746a0a3b4dff540eebe7a35d (patch) | |
tree | 842c2cfeb39de4cb23d20f910297d6b6da7be221 /activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb | |
parent | cff25aae90859d5f47d827b162b505f8b316b733 (diff) | |
download | rails-e7040b09e8dc381c746a0a3b4dff540eebe7a35d.tar.gz rails-e7040b09e8dc381c746a0a3b4dff540eebe7a35d.tar.bz2 rails-e7040b09e8dc381c746a0a3b4dff540eebe7a35d.zip |
Rebundle Builder 2.1.2 but prefer a newer RubyGem if available.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7828 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb')
-rw-r--r-- | activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb b/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb new file mode 100644 index 0000000000..ace4b56d59 --- /dev/null +++ b/activesupport/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb @@ -0,0 +1,139 @@ +#!/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{"}, '"') # " 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 |