bigfleet-builder 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ = Builder 1.2.4 Released.
2
+
3
+ Added a "CDATA" method to the XML Markup builder (from Josh Knowles).
4
+
5
+ == What is Builder?
6
+
7
+ Builder::XmlMarkup allows easy programmatic creation of XML markup.
8
+ For example:
9
+
10
+ builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
11
+ builder.person { |b| b.name("Jim"); b.phone("555-1234") }
12
+ puts builder.target!
13
+
14
+ will generate:
15
+
16
+ <person>
17
+ <name>Jim</name>
18
+ <phone>555-1234</phone>
19
+ </person>
20
+
21
+ == Availability
22
+
23
+ The easiest way to get and install builder is via RubyGems ...
24
+
25
+ gem install builder (you may need root/admin privileges)
26
+
27
+ == Thanks
28
+
29
+ * Josh Knowles for the cdata! patch.
30
+
31
+ -- Jim Weirich
@@ -0,0 +1,46 @@
1
+ = Builder 2.0.0 Released.
2
+
3
+ == Changes in 2.0.0
4
+
5
+ * UTF-8 characters in data are now correctly translated to their XML
6
+ equivalents. (Thanks to Sam Ruby)
7
+
8
+ * Attribute values are now escaped by default. See the README
9
+ file for details.
10
+
11
+ <b>NOTE:</b> The escaping attribute values by default is different
12
+ than in previous releases of Builder. This makes version 2.0.0
13
+ somewhat incompatible with the 1.x series of Builder. If you use "&",
14
+ "<", or ">" in attributes values, you may have to change your
15
+ code. (Essentially you remove the manual escaping. The new way is
16
+ easier, believe me).
17
+
18
+ == What is Builder?
19
+
20
+ Builder::XmlMarkup is a library that allows easy programmatic creation
21
+ of XML markup. For example:
22
+
23
+ builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
24
+ builder.person { |b| b.name("Jim"); b.phone("555-1234") }
25
+
26
+ will generate:
27
+
28
+ <person>
29
+ <name>Jim</name>
30
+ <phone>555-1234</phone>
31
+ </person>
32
+
33
+ == Availability
34
+
35
+ The easiest way to get and install builder is via RubyGems ...
36
+
37
+ gem install builder (you may need root/admin privileges)
38
+
39
+ == Thanks
40
+
41
+ * Sam Ruby for the XChar module and the related UTF-8 translation
42
+ tools.
43
+ * Also to Sam Ruby for gently persuading me to start quoting attribute
44
+ values.
45
+
46
+ -- Jim Weirich
@@ -0,0 +1,58 @@
1
+ = Builder 2.1.1 Released.
2
+
3
+ Release 2.1.1 of Builder is mainly a bug fix release.
4
+
5
+ == Changes in 2.1.1
6
+
7
+ * Added <tt>reveal</tt> capability to BlankSlate.
8
+
9
+ * Fixed a bug in BlankSlate where including a module into Object could
10
+ cause methods to leak into BlankSlate.
11
+
12
+ * Fixed typo in XmlMarkup class docs (from Martin Fowler).
13
+
14
+ * Fixed test on private methods to differentiate between targetted and
15
+ untargetted private methods.
16
+
17
+ * Removed legacy capture of @self in XmlBase (@self was used back when
18
+ we used instance eval).
19
+
20
+ * Added additional tests for global functions (both direct and
21
+ included).
22
+
23
+ * Several misc internal cleanups, including rearranging the source
24
+ code tree.
25
+
26
+ <b>NOTE:</b> The escaping attribute values by default is different
27
+ than in previous releases of Builder. This makes version 2.0.x
28
+ somewhat incompatible with the 1.x series of Builder. If you use "&",
29
+ "<", or ">" in attributes values, you may have to change your
30
+ code. (Essentially you remove the manual escaping. The new way is
31
+ easier, believe me).
32
+
33
+ == What is Builder?
34
+
35
+ Builder::XmlMarkup is a library that allows easy programmatic creation
36
+ of XML markup. For example:
37
+
38
+ builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
39
+ builder.person { |b| b.name("Jim"); b.phone("555-1234") }
40
+
41
+ will generate:
42
+
43
+ <person>
44
+ <name>Jim</name>
45
+ <phone>555-1234</phone>
46
+ </person>
47
+
48
+ == Availability
49
+
50
+ The easiest way to get and install builder is via RubyGems ...
51
+
52
+ gem install builder (you may need root/admin privileges)
53
+
54
+ == Thanks
55
+
56
+ * Martin Fowler for spotting some typos in the documentation.
57
+
58
+ -- Jim Weirich
data/lib/blankslate.rb ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+ #++
10
+
11
+ ######################################################################
12
+ # BlankSlate provides an abstract base class with no predefined
13
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
14
+ # BlankSlate is useful as a base class when writing classes that
15
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
16
+ #
17
+ class BlankSlate
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 "__".
22
+ def hide(name)
23
+ if instance_methods.include?(name.to_s) and
24
+ name !~ /^(__|instance_eval)/
25
+ @hidden_methods ||= {}
26
+ @hidden_methods[name.to_sym] = instance_method(name)
27
+ undef_method name
28
+ end
29
+ end
30
+
31
+ def find_hidden_method(name)
32
+ @hidden_methods ||= {}
33
+ @hidden_methods[name] || superclass.find_hidden_method(name)
34
+ end
35
+
36
+ # Redefine a previously hidden method so that it may be called on a blank
37
+ # slate object.
38
+ def reveal(name)
39
+ hidden_method = find_hidden_method(name)
40
+ fail "Don't know how to reveal method '#{name}'" unless hidden_method
41
+ define_method(name, hidden_method)
42
+ end
43
+ end
44
+
45
+ instance_methods.each { |m| hide(m) }
46
+ end
47
+
48
+ ######################################################################
49
+ # Since Ruby is very dynamic, methods added to the ancestors of
50
+ # BlankSlate <em>after BlankSlate is defined</em> will show up in the
51
+ # list of available BlankSlate methods. We handle this by defining a
52
+ # hook in the Object and Kernel classes that will hide any method
53
+ # defined after BlankSlate has been loaded.
54
+ #
55
+ module Kernel
56
+ class << self
57
+ alias_method :blank_slate_method_added, :method_added
58
+
59
+ # Detect method additions to Kernel and remove them in the
60
+ # BlankSlate class.
61
+ def method_added(name)
62
+ result = blank_slate_method_added(name)
63
+ return result if self != Kernel
64
+ BlankSlate.hide(name)
65
+ result
66
+ end
67
+ end
68
+ end
69
+
70
+ ######################################################################
71
+ # Same as above, except in Object.
72
+ #
73
+ class Object
74
+ class << self
75
+ alias_method :blank_slate_method_added, :method_added
76
+
77
+ # Detect method additions to Object and remove them in the
78
+ # BlankSlate class.
79
+ def method_added(name)
80
+ result = blank_slate_method_added(name)
81
+ return result if self != Object
82
+ BlankSlate.hide(name)
83
+ result
84
+ end
85
+
86
+ def find_hidden_method(name)
87
+ nil
88
+ end
89
+ end
90
+ end
91
+
92
+ ######################################################################
93
+ # Also, modules included into Object need to be scanned and have their
94
+ # instance methods removed from blank slate. In theory, modules
95
+ # included into Kernel would have to be removed as well, but a
96
+ # "feature" of Ruby prevents late includes into modules from being
97
+ # exposed in the first place.
98
+ #
99
+ class Module
100
+ alias blankslate_original_append_features append_features
101
+ def append_features(mod)
102
+ result = blankslate_original_append_features(mod)
103
+ return result if mod != Object
104
+ instance_methods.each do |name|
105
+ BlankSlate.hide(name)
106
+ end
107
+ result
108
+ end
109
+ end
data/lib/builder.rb ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #++
11
+
12
+ require 'builder/xmlmarkup'
13
+ require 'builder/xmlevents'
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+ #++
10
+
11
+ require 'blankslate'
12
+
13
+ ######################################################################
14
+ # BlankSlate has been promoted to a top level name and is now
15
+ # available as a standalone gem. We make the name available in the
16
+ # Builder namespace for compatibility.
17
+ #
18
+ module Builder
19
+ BlankSlate = ::BlankSlate
20
+ end
@@ -0,0 +1,119 @@
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.to_s)
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
90
+ XChar = Builder::XChar if ! defined?(XChar)
91
+
92
+ # XML escaped version of chr. When <tt>escape</tt> is set to false
93
+ # the CP1252 fix is still applied but utf-8 characters are not
94
+ # converted to character entities.
95
+ def xchr(escape=true)
96
+ n = XChar::CP1252[self] || self
97
+ case n when *XChar::VALID
98
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : (escape ? "&##{n};" : [n].pack('U*')))
99
+ else
100
+ '*'
101
+ end
102
+ end
103
+ end
104
+
105
+
106
+ ######################################################################
107
+ # Enhance the String class with a XML escaped character version of
108
+ # to_s.
109
+ #
110
+ class String
111
+ # XML escaped version of to_s. When <tt>escape</tt> is set to false
112
+ # the CP1252 fix is still applied but utf-8 characters are not
113
+ # converted to character entities.
114
+ def to_xs(escape=true)
115
+ unpack('U*').map {|n| n.xchr(escape)}.join # ASCII, UTF-8
116
+ rescue
117
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
118
+ end
119
+ end
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'builder/blankslate'
4
+
5
+ module Builder
6
+
7
+ # Generic error for builder
8
+ class IllegalBlockError < RuntimeError; end
9
+
10
+ # XmlBase is a base class for building XML builders. See
11
+ # Builder::XmlMarkup and Builder::XmlEvents for examples.
12
+ class XmlBase < BlankSlate
13
+
14
+ # Create an XML markup builder.
15
+ #
16
+ # out:: Object receiving the markup. +out+ must respond to
17
+ # <tt><<</tt>.
18
+ # indent:: Number of spaces used for indentation (0 implies no
19
+ # indentation and no line breaks).
20
+ # initial:: Level of initial indentation.
21
+ # encoding:: When <tt>encoding</tt> and $KCODE are set to 'utf-8'
22
+ # characters aren't converted to character entities in
23
+ # the output stream.
24
+ def initialize(indent=0, initial=0, encoding='utf-8')
25
+ @indent = indent
26
+ @level = initial
27
+ @encoding = encoding.downcase
28
+ end
29
+
30
+ # Create a tag named +sym+. Other than the first argument which
31
+ # is the tag name, the arguments are the same as the tags
32
+ # implemented via <tt>method_missing</tt>.
33
+ def tag!(sym, *args, &block)
34
+ method_missing(sym.to_sym, *args, &block)
35
+ end
36
+
37
+ # Create XML markup based on the name of the method. This method
38
+ # is never invoked directly, but is called for each markup method
39
+ # in the markup block.
40
+ def method_missing(sym, *args, &block)
41
+ text = nil
42
+ attrs = nil
43
+ sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
44
+ args.each do |arg|
45
+ case arg
46
+ when Hash
47
+ attrs ||= {}
48
+ attrs.merge!(arg)
49
+ else
50
+ text ||= ''
51
+ text << arg.to_s
52
+ end
53
+ end
54
+ if block
55
+ unless text.nil?
56
+ raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
57
+ end
58
+ _indent
59
+ _start_tag(sym, attrs)
60
+ _newline
61
+ _nested_structures(block)
62
+ _indent
63
+ _end_tag(sym)
64
+ _newline
65
+ elsif text.nil?
66
+ _indent
67
+ _start_tag(sym, attrs, true)
68
+ _newline
69
+ else
70
+ _indent
71
+ _start_tag(sym, attrs)
72
+ text! text
73
+ _end_tag(sym)
74
+ _newline
75
+ end
76
+ @target
77
+ end
78
+
79
+ # Append text to the output target. Escape any markup. May be
80
+ # used within the markup brackets as:
81
+ #
82
+ # builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
83
+ def text!(text)
84
+ _text(_escape(text))
85
+ end
86
+
87
+ # Append text to the output target without escaping any markup.
88
+ # May be used within the markup brackets as:
89
+ #
90
+ # builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
91
+ #
92
+ # This is useful when using non-builder enabled software that
93
+ # generates strings. Just insert the string directly into the
94
+ # builder without changing the inserted markup.
95
+ #
96
+ # It is also useful for stacking builder objects. Builders only
97
+ # use <tt><<</tt> to append to the target, so by supporting this
98
+ # method/operation builders can use other builders as their
99
+ # targets.
100
+ def <<(text)
101
+ _text(text)
102
+ end
103
+
104
+ # For some reason, nil? is sent to the XmlMarkup object. If nil?
105
+ # is not defined and method_missing is invoked, some strange kind
106
+ # of recursion happens. Since nil? won't ever be an XML tag, it
107
+ # is pretty safe to define it here. (Note: this is an example of
108
+ # cargo cult programming,
109
+ # cf. http://fishbowl.pastiche.org/2004/10/13/cargo_cult_programming).
110
+ def nil?
111
+ false
112
+ end
113
+
114
+ private
115
+
116
+ require 'builder/xchar'
117
+ def _escape(text)
118
+ text.to_xs((@encoding != 'utf-8' or $KCODE != 'UTF8'))
119
+ end
120
+
121
+ def _escape_quote(text)
122
+ _escape(text).gsub(%r{"}, '&quot;') # " WART
123
+ end
124
+
125
+ def _newline
126
+ return if @indent == 0
127
+ text! "\n"
128
+ end
129
+
130
+ def _indent
131
+ return if @indent == 0 || @level == 0
132
+ text!(" " * (@level * @indent))
133
+ end
134
+
135
+ def _nested_structures(block)
136
+ @level += 1
137
+ block.call(self)
138
+ ensure
139
+ @level -= 1
140
+ end
141
+ end
142
+ end