3
require 'builder/blankslate'
7
# Generic error for builder
8
class IllegalBlockError < RuntimeError; end
10
# XmlBase is a base class for building XML builders. See
11
# Builder::XmlMarkup and Builder::XmlEvents for examples.
12
class XmlBase < BlankSlate
14
# Create an XML markup builder.
16
# out:: Object receiving the markup. +out+ must respond to
18
# indent:: Number of spaces used for indentation (0 implies no
19
# indentation and no line breaks).
20
# initial:: Level of initial indentation.
22
def initialize(indent=0, initial=0)
27
# Create a tag named +sym+. Other than the first argument which
28
# is the tag name, the arguments are the same as the tags
29
# implemented via <tt>method_missing</tt>.
30
def tag!(sym, *args, &block)
31
method_missing(sym.to_sym, *args, &block)
34
# Create XML markup based on the name of the method. This method
35
# is never invoked directly, but is called for each markup method
36
# in the markup block.
37
def method_missing(sym, *args, &block)
40
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
53
raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
56
_start_tag(sym, attrs)
58
_nested_structures(block)
64
_start_tag(sym, attrs, true)
68
_start_tag(sym, attrs)
76
# Append text to the output target. Escape any markup. May be
77
# used within the markup brackets as:
79
# builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
84
# Append text to the output target without escaping any markup.
85
# May be used within the markup brackets as:
87
# builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
89
# This is useful when using non-builder enabled software that
90
# generates strings. Just insert the string directly into the
91
# builder without changing the inserted markup.
93
# It is also useful for stacking builder objects. Builders only
94
# use <tt><<</tt> to append to the target, so by supporting this
95
# method/operation builders can use other builders as their
101
# For some reason, nil? is sent to the XmlMarkup object. If nil?
102
# is not defined and method_missing is invoked, some strange kind
103
# of recursion happens. Since nil? won't ever be an XML tag, it
104
# is pretty safe to define it here. (Note: this is an example of
105
# cargo cult programming,
106
# cf. http://fishbowl.pastiche.org/2004/10/13/cargo_cult_programming).
113
require 'builder/xchar'
118
def _escape_quote(text)
119
_escape(text).gsub(%r{"}, '"') # " WART
123
return if @indent == 0
128
return if @indent == 0 || @level == 0
129
text!(" " * (@level * @indent))
132
def _nested_structures(block)