builder 3.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,137 @@
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
+ class String
12
+ if instance_methods.first.is_a?(Symbol)
13
+ def _blankslate_as_name
14
+ to_sym
15
+ end
16
+ else
17
+ def _blankslate_as_name
18
+ self
19
+ end
20
+ end
21
+ end
22
+
23
+ class Symbol
24
+ if instance_methods.first.is_a?(Symbol)
25
+ def _blankslate_as_name
26
+ self
27
+ end
28
+ else
29
+ def _blankslate_as_name
30
+ to_s
31
+ end
32
+ end
33
+ end
34
+
35
+ ######################################################################
36
+ # BlankSlate provides an abstract base class with no predefined
37
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
38
+ # BlankSlate is useful as a base class when writing classes that
39
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
40
+ #
41
+ class BlankSlate
42
+ class << self
43
+
44
+ # Hide the method named +name+ in the BlankSlate class. Don't
45
+ # hide +instance_eval+ or any method beginning with "__".
46
+ def hide(name)
47
+ warn_level = $VERBOSE
48
+ $VERBOSE = nil
49
+ if instance_methods.include?(name._blankslate_as_name) &&
50
+ name !~ /^(__|instance_eval$)/
51
+ @hidden_methods ||= {}
52
+ @hidden_methods[name.to_sym] = instance_method(name)
53
+ undef_method name
54
+ end
55
+ ensure
56
+ $VERBOSE = warn_level
57
+ end
58
+
59
+ def find_hidden_method(name)
60
+ @hidden_methods ||= {}
61
+ @hidden_methods[name] || superclass.find_hidden_method(name)
62
+ end
63
+
64
+ # Redefine a previously hidden method so that it may be called on a blank
65
+ # slate object.
66
+ def reveal(name)
67
+ hidden_method = find_hidden_method(name)
68
+ fail "Don't know how to reveal method '#{name}'" unless hidden_method
69
+ define_method(name, hidden_method)
70
+ end
71
+ end
72
+
73
+ instance_methods.each { |m| hide(m) }
74
+ end
75
+
76
+ ######################################################################
77
+ # Since Ruby is very dynamic, methods added to the ancestors of
78
+ # BlankSlate <em>after BlankSlate is defined</em> will show up in the
79
+ # list of available BlankSlate methods. We handle this by defining a
80
+ # hook in the Object and Kernel classes that will hide any method
81
+ # defined after BlankSlate has been loaded.
82
+ #
83
+ module Kernel
84
+ class << self
85
+ alias_method :blank_slate_method_added, :method_added
86
+
87
+ # Detect method additions to Kernel and remove them in the
88
+ # BlankSlate class.
89
+ def method_added(name)
90
+ result = blank_slate_method_added(name)
91
+ return result if self != Kernel
92
+ BlankSlate.hide(name)
93
+ result
94
+ end
95
+ end
96
+ end
97
+
98
+ ######################################################################
99
+ # Same as above, except in Object.
100
+ #
101
+ class Object
102
+ class << self
103
+ alias_method :blank_slate_method_added, :method_added
104
+
105
+ # Detect method additions to Object and remove them in the
106
+ # BlankSlate class.
107
+ def method_added(name)
108
+ result = blank_slate_method_added(name)
109
+ return result if self != Object
110
+ BlankSlate.hide(name)
111
+ result
112
+ end
113
+
114
+ def find_hidden_method(name)
115
+ nil
116
+ end
117
+ end
118
+ end
119
+
120
+ ######################################################################
121
+ # Also, modules included into Object need to be scanned and have their
122
+ # instance methods removed from blank slate. In theory, modules
123
+ # included into Kernel would have to be removed as well, but a
124
+ # "feature" of Ruby prevents late includes into modules from being
125
+ # exposed in the first place.
126
+ #
127
+ class Module
128
+ alias blankslate_original_append_features append_features
129
+ def append_features(mod)
130
+ result = blankslate_original_append_features(mod)
131
+ return result if mod != Object
132
+ instance_methods.each do |name|
133
+ BlankSlate.hide(name)
134
+ end
135
+ result
136
+ end
137
+ end
@@ -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,23 @@
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 has been promoted to a top level name and is now
13
+ # available as a standalone gem. We make the name available in the
14
+ # Builder namespace for compatibility.
15
+ #
16
+ module Builder
17
+ if Object::const_defined?(:BasicObject)
18
+ BlankSlate = ::BasicObject
19
+ else
20
+ require 'blankslate'
21
+ BlankSlate = ::BlankSlate
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ module Builder
2
+ VERSION_NUMBERS = [
3
+ VERSION_MAJOR = 3,
4
+ VERSION_MINOR = 2,
5
+ VERSION_BUILD = 3,
6
+ ]
7
+ VERSION = VERSION_NUMBERS.join(".")
8
+ end
@@ -0,0 +1,197 @@
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.method_defined?(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) and ! String.method_defined?(:encode)
21
+ Builder.check_for_name_collision(String, "to_xs")
22
+ Builder.check_for_name_collision(Integer, "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
+
82
+ # http://www.fileformat.info/info/unicode/char/fffd/index.htm
83
+ REPLACEMENT_CHAR =
84
+ if String.method_defined?(:encode)
85
+ "\uFFFD"
86
+ elsif $KCODE == 'UTF8'
87
+ "\xEF\xBF\xBD"
88
+ else
89
+ '*'
90
+ end
91
+ end
92
+
93
+ end
94
+
95
+
96
+ if String.method_defined?(:encode)
97
+ module Builder
98
+ module XChar # :nodoc:
99
+ CP1252_DIFFERENCES, UNICODE_EQUIVALENT = Builder::XChar::CP1252.each.
100
+ inject([[],[]]) {|(domain,range),(key,value)|
101
+ [domain << key,range << value]
102
+ }.map {|seq| seq.pack('U*').force_encoding('utf-8')}
103
+
104
+ XML_PREDEFINED = Regexp.new('[' +
105
+ Builder::XChar::PREDEFINED.keys.pack('U*').force_encoding('utf-8') +
106
+ ']')
107
+
108
+ INVALID_XML_CHAR = Regexp.new('[^'+
109
+ Builder::XChar::VALID.map { |item|
110
+ case item
111
+ when Integer
112
+ [item].pack('U').force_encoding('utf-8')
113
+ when Range
114
+ [item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8')
115
+ end
116
+ }.join +
117
+ ']')
118
+
119
+ ENCODING_BINARY = Encoding.find('BINARY')
120
+ ENCODING_UTF8 = Encoding.find('UTF-8')
121
+ ENCODING_ISO1 = Encoding.find('ISO-8859-1')
122
+
123
+ # convert a string to valid UTF-8, compensating for a number of
124
+ # common errors.
125
+ def XChar.unicode(string)
126
+ if string.encoding == ENCODING_BINARY
127
+ if string.ascii_only?
128
+ string
129
+ else
130
+ string = string.clone.force_encoding(ENCODING_UTF8)
131
+ if string.valid_encoding?
132
+ string
133
+ else
134
+ string.encode(ENCODING_UTF8, ENCODING_ISO1)
135
+ end
136
+ end
137
+
138
+ elsif string.encoding == ENCODING_UTF8
139
+ if string.valid_encoding?
140
+ string
141
+ else
142
+ string.encode(ENCODING_UTF8, ENCODING_ISO1)
143
+ end
144
+
145
+ else
146
+ string.encode(ENCODING_UTF8)
147
+ end
148
+ end
149
+
150
+ # encode a string per XML rules
151
+ def XChar.encode(string)
152
+ unicode(string).
153
+ tr(CP1252_DIFFERENCES, UNICODE_EQUIVALENT).
154
+ gsub(INVALID_XML_CHAR, REPLACEMENT_CHAR).
155
+ gsub(XML_PREDEFINED) {|c| PREDEFINED[c.ord]}
156
+ end
157
+ end
158
+ end
159
+
160
+ else
161
+
162
+ ######################################################################
163
+ # Enhance the Integer class with a XML escaped character conversion.
164
+ #
165
+ class Integer
166
+ XChar = Builder::XChar if ! defined?(XChar)
167
+
168
+ # XML escaped version of chr. When <tt>escape</tt> is set to false
169
+ # the CP1252 fix is still applied but utf-8 characters are not
170
+ # converted to character entities.
171
+ def xchr(escape=true)
172
+ n = XChar::CP1252[self] || self
173
+ case n when *XChar::VALID
174
+ XChar::PREDEFINED[n] or
175
+ (n<128 ? n.chr : (escape ? "&##{n};" : [n].pack('U*')))
176
+ else
177
+ Builder::XChar::REPLACEMENT_CHAR
178
+ end
179
+ end
180
+ end
181
+
182
+
183
+ ######################################################################
184
+ # Enhance the String class with a XML escaped character version of
185
+ # to_s.
186
+ #
187
+ class String
188
+ # XML escaped version of to_s. When <tt>escape</tt> is set to false
189
+ # the CP1252 fix is still applied but utf-8 characters are not
190
+ # converted to character entities.
191
+ def to_xs(escape=true)
192
+ unpack('U*').map {|n| n.xchr(escape)}.join # ASCII, UTF-8
193
+ rescue
194
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
195
+ end
196
+ end
197
+ end