builder 1.2.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of builder might be problematic. Click here for more details.
- data/CHANGES +9 -1
- data/README +73 -11
- data/Rakefile +130 -11
- data/doc/releases/builder-1.2.4.rdoc +31 -0
- data/doc/releases/builder-2.0.0.rdoc +46 -0
- data/lib/builder/blankslate.rb +11 -1
- data/lib/builder/xchar.rb +112 -0
- data/lib/builder/xmlbase.rb +7 -5
- data/lib/builder/xmlmarkup.rb +21 -2
- data/test/performance.rb +30 -0
- data/test/test_xchar.rb +37 -0
- data/test/testeventbuilder.rb +133 -0
- data/test/testmarkupbuilder.rb +79 -6
- metadata +46 -35
data/CHANGES
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
= Change Log
|
2
2
|
|
3
|
+
== Version 2.0.0
|
4
|
+
|
5
|
+
* Added doc directory
|
6
|
+
* Added unit tests for XmlEvents.
|
7
|
+
* Added XChar module and used it in the _escape method.
|
8
|
+
* Attributes are now quoted by default when strings. Use Symbol
|
9
|
+
attribute values for unquoted behavior.
|
10
|
+
|
3
11
|
== Version 1.2.4
|
4
12
|
|
5
|
-
* Added a cdata! command to an XML Builder.
|
13
|
+
* Added a cdata! command to an XML Builder (from Josh Knowles).
|
6
14
|
|
7
15
|
== Version 1.2.3
|
8
16
|
|
data/README
CHANGED
@@ -37,10 +37,41 @@ or
|
|
37
37
|
# <person>
|
38
38
|
# <name>Jim</name>
|
39
39
|
# <phone>555-1234</phone>
|
40
|
-
# </person
|
40
|
+
# </person>
|
41
41
|
|
42
42
|
== Compatibility
|
43
43
|
|
44
|
+
=== Version 2.0.0 Compatibility Changes
|
45
|
+
|
46
|
+
Version 2.0.0 introduces automatically escaped attribute values for
|
47
|
+
the first time. Versions prior to 2.0.0 did not insert escape
|
48
|
+
characters into attribute values in the XML markup. This allowed
|
49
|
+
attribute values to explicitly reference entities, which was
|
50
|
+
occasionally used by a small number of developers. Since strings
|
51
|
+
could always be explicitly escaped by hand, this was not a major
|
52
|
+
restriction in functionality.
|
53
|
+
|
54
|
+
However, it did suprise most users of builder. Since the body text is
|
55
|
+
normally escaped, everybody expected the attribute values to be
|
56
|
+
escaped as well. Escaped attribute values were the number one support
|
57
|
+
request on the 1.x Builder series.
|
58
|
+
|
59
|
+
Starting with Builder version 2.0.0, all attribute values expressed as
|
60
|
+
strings will be processed and the appropriate characters will be
|
61
|
+
escaped (e.g. "&" will be tranlated to "&"). Attribute values
|
62
|
+
that are expressed as Symbol values will not be processed for escaped
|
63
|
+
characters and will be unchanged in output. (Yes, this probably counts
|
64
|
+
as Symbol abuse, but the convention is convenient and flexible).
|
65
|
+
|
66
|
+
Example:
|
67
|
+
|
68
|
+
xml = Builder::XmlMarkup.new
|
69
|
+
xml.sample(:escaped=>"This&That", :unescaped=>:"Here&There")
|
70
|
+
xml.target! =>
|
71
|
+
<sample escaped="This&That" unescaped="Here&There"/>
|
72
|
+
|
73
|
+
=== Version 1.0.0 Compatibility Changes
|
74
|
+
|
44
75
|
Version 1.0.0 introduces some changes that are not backwards
|
45
76
|
compatible with earlier releases of builder. The main areas of
|
46
77
|
incompatibility are:
|
@@ -76,14 +107,14 @@ incompatibility are:
|
|
76
107
|
require_gem 'builder', "~> 0.0" # Gets the old version
|
77
108
|
require_gem 'builder', "~> 1.0" # Gets the new version
|
78
109
|
|
79
|
-
==
|
110
|
+
== Features
|
80
111
|
|
81
|
-
* XML Comments are
|
112
|
+
* XML Comments are supported ...
|
82
113
|
|
83
114
|
xml_markup.comment! "This is a comment"
|
84
115
|
#=> <!-- This is a comment -->
|
85
116
|
|
86
|
-
* XML processing instructions are
|
117
|
+
* XML processing instructions are supported ...
|
87
118
|
|
88
119
|
xml_markup.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
|
89
120
|
#=> <?xml version="1.0" encoding="UTF-8"?>
|
@@ -107,18 +138,19 @@ incompatibility are:
|
|
107
138
|
|
108
139
|
If you need to have an argument to declare! be inserted without
|
109
140
|
quotes, but the arguement does not conform to the typical Ruby
|
110
|
-
syntax for symbols, then use the
|
111
|
-
convert it to a symbol.
|
141
|
+
syntax for symbols, then use the :"string" form to specify a symbol.
|
112
142
|
|
113
|
-
|
143
|
+
For example:
|
144
|
+
|
145
|
+
xml_markup.declare! :ELEMENT, :chapter, :"(title,para+)"
|
114
146
|
#=> <!ELEMENT chapter (title,para+)>
|
115
147
|
|
116
148
|
Nested entity declarations are allowed. For example:
|
117
149
|
|
118
150
|
@xml_markup.declare! :DOCTYPE, :chapter do |x|
|
119
|
-
x.declare! :ELEMENT, :chapter, "(title,para+)"
|
120
|
-
x.declare! :ELEMENT, :title, "(#PCDATA)"
|
121
|
-
x.declare! :ELEMENT, :para, "(#PCDATA)"
|
151
|
+
x.declare! :ELEMENT, :chapter, :"(title,para+)"
|
152
|
+
x.declare! :ELEMENT, :title, :"(#PCDATA)"
|
153
|
+
x.declare! :ELEMENT, :para, :"(#PCDATA)"
|
122
154
|
end
|
123
155
|
|
124
156
|
#=>
|
@@ -129,7 +161,7 @@ incompatibility are:
|
|
129
161
|
<!ELEMENT para (#PCDATA)>
|
130
162
|
]>
|
131
163
|
|
132
|
-
*
|
164
|
+
* Some support for XML namespaces is now available. If the first
|
133
165
|
argument to a tag call is a symbol, it will be joined to the tag to
|
134
166
|
produce a namespace:tag combination. It is easier to show this than
|
135
167
|
describe it.
|
@@ -140,6 +172,36 @@ incompatibility are:
|
|
140
172
|
right form for builder (e.g. "<tt>SOAP:Envelope</tt>" =>
|
141
173
|
"<tt>xml.SOAP :Envelope</tt>")
|
142
174
|
|
175
|
+
* String attribute values are <em>now</em> escaped by default by
|
176
|
+
Builder (<b>NOTE:</b> this is _new_ behavior as of version 2.0).
|
177
|
+
|
178
|
+
However, occasionally you need to use entities in attribute values.
|
179
|
+
Using a symbols (rather than a string) for an attribute value will
|
180
|
+
cause Builder to not run its quoting/escaping algorithm on that
|
181
|
+
particular value.
|
182
|
+
|
183
|
+
(<b>Note:</b> The +escape_attrs+ option for builder is now
|
184
|
+
obsolete).
|
185
|
+
|
186
|
+
Example:
|
187
|
+
|
188
|
+
xml = Builder::XmlMarkup.new
|
189
|
+
xml.sample(:escaped=>"This&That", :unescaped=>:"Here&There")
|
190
|
+
xml.target! =>
|
191
|
+
<sample escaped="This&That" unescaped="Here&There"/>
|
192
|
+
|
193
|
+
* UTF-8 Support
|
194
|
+
|
195
|
+
Builder correctly translates UTF-8 characters into valid XML. (New
|
196
|
+
in version 2.0.0). Thanks to Sam Ruby for the translation code.
|
197
|
+
|
198
|
+
Example:
|
199
|
+
|
200
|
+
xml = Builder::Markup.new
|
201
|
+
xml.sample("I�t�rn�ti�n�l")
|
202
|
+
xml.target! =>
|
203
|
+
"<sample>Iñtërnâtiônàl</sample>"
|
204
|
+
|
143
205
|
== Contact
|
144
206
|
|
145
207
|
Author:: Jim Weirich
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Rakefile for rake -*- ruby -*-
|
2
2
|
|
3
|
-
# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
3
|
+
# Copyright 2004, 2005, 2006 by Jim Weirich (jim@weirichhouse.org).
|
4
4
|
# All rights reserved.
|
5
5
|
|
6
6
|
# Permission is granted for use, copying, modification, distribution,
|
@@ -17,20 +17,29 @@ rescue Exception
|
|
17
17
|
nil
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
# Determine the current version of the software
|
21
|
+
|
22
|
+
CURRENT_VERSION = '2.0.0'
|
23
|
+
PKG_VERSION = ENV['REL'] ? ENV['REL'] : CURRENT_VERSION
|
21
24
|
|
22
25
|
SRC_RB = FileList['lib/**/*.rb']
|
23
26
|
|
24
27
|
# The default task is run if rake is given no explicit arguments.
|
25
28
|
|
26
29
|
desc "Default Task"
|
27
|
-
task :default => :
|
30
|
+
task :default => :test_all
|
28
31
|
|
29
32
|
# Test Tasks ---------------------------------------------------------
|
30
33
|
|
31
|
-
|
34
|
+
desc "Run all tests"
|
35
|
+
task :test_all => [:test_units]
|
36
|
+
task :ta => [:test_all]
|
37
|
+
|
38
|
+
task :tu => [:test_units]
|
39
|
+
|
40
|
+
Rake::TestTask.new("test_units") do |t|
|
32
41
|
t.test_files = FileList['test/test*.rb']
|
33
|
-
t.verbose =
|
42
|
+
t.verbose = false
|
34
43
|
end
|
35
44
|
|
36
45
|
# Create a task to build the RDOC documentation tree.
|
@@ -39,8 +48,8 @@ rd = Rake::RDocTask.new("rdoc") { |rdoc|
|
|
39
48
|
rdoc.rdoc_dir = 'html'
|
40
49
|
rdoc.title = "Builder for Markup"
|
41
50
|
rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
|
42
|
-
rdoc.rdoc_files.include('lib/**/*.rb', '[A-Z]*')
|
43
|
-
rdoc.template = 'jamis'
|
51
|
+
rdoc.rdoc_files.include('lib/**/*.rb', '[A-Z]*', 'doc/**/*.rdoc')
|
52
|
+
rdoc.template = 'doc/jamis.rb'
|
44
53
|
}
|
45
54
|
|
46
55
|
# ====================================================================
|
@@ -52,6 +61,8 @@ PKG_FILES = FileList[
|
|
52
61
|
'test/**/*.rb',
|
53
62
|
'scripts/**/*.rb'
|
54
63
|
]
|
64
|
+
PKG_FILES.exclude('test/testcssbuilder.rb')
|
65
|
+
PKG_FILES.exclude('lib/builder/css.rb')
|
55
66
|
|
56
67
|
if ! defined?(Gem)
|
57
68
|
puts "Package Target requires RubyGEMs"
|
@@ -68,15 +79,14 @@ Builder provides a number of builder objects that make creating structured data
|
|
68
79
|
simple to do. Currently the following builder objects are supported:
|
69
80
|
|
70
81
|
* XML Markup
|
71
|
-
* XML Events
|
82
|
+
* XML Events
|
72
83
|
EOS
|
73
84
|
|
74
85
|
s.files = PKG_FILES.to_a
|
75
|
-
|
76
86
|
s.require_path = 'lib'
|
77
87
|
s.autorequire = 'builder'
|
78
88
|
|
79
|
-
s.test_files =
|
89
|
+
s.test_files = PKG_FILES.select { |fn| fn =~ /^test\/test/ }
|
80
90
|
|
81
91
|
s.has_rdoc = true
|
82
92
|
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
|
@@ -90,7 +100,116 @@ EOS
|
|
90
100
|
s.homepage = "http://onestepback.org"
|
91
101
|
end
|
92
102
|
|
93
|
-
|
103
|
+
Rake::GemPackageTask.new(spec) do |t|
|
104
|
+
t.need_tar = true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
desc "Look for Debugging print lines"
|
109
|
+
task :dbg do
|
110
|
+
FileList['**/*.rb'].egrep /\bDBG|\bbreakpoint\b/
|
111
|
+
end
|
112
|
+
|
113
|
+
# --------------------------------------------------------------------
|
114
|
+
# Creating a release
|
115
|
+
|
116
|
+
def announce(msg='')
|
117
|
+
STDERR.puts msg
|
118
|
+
end
|
119
|
+
|
120
|
+
desc "Make a new release"
|
121
|
+
task :release => [
|
122
|
+
:prerelease,
|
123
|
+
:clobber,
|
124
|
+
:test_all,
|
125
|
+
:update_version,
|
126
|
+
:package,
|
127
|
+
:tag] do
|
128
|
+
|
129
|
+
announce
|
130
|
+
announce "**************************************************************"
|
131
|
+
announce "* Release #{PKG_VERSION} Complete."
|
132
|
+
announce "* Packages ready to upload."
|
133
|
+
announce "**************************************************************"
|
134
|
+
announce
|
135
|
+
end
|
136
|
+
|
137
|
+
# Validate that everything is ready to go for a release.
|
138
|
+
task :prerelease do
|
139
|
+
announce
|
140
|
+
announce "**************************************************************"
|
141
|
+
announce "* Making RubyGem Release #{PKG_VERSION}"
|
142
|
+
announce "* (current version #{CURRENT_VERSION})"
|
143
|
+
announce "**************************************************************"
|
144
|
+
announce
|
145
|
+
|
146
|
+
# Is a release number supplied?
|
147
|
+
unless ENV['REL']
|
148
|
+
fail "Usage: rake release REL=x.y.z [REUSE=tag_suffix]"
|
149
|
+
end
|
150
|
+
|
151
|
+
# Is the release different than the current release.
|
152
|
+
# (or is REUSE set?)
|
153
|
+
if PKG_VERSION == CURRENT_VERSION && ! ENV['REUSE']
|
154
|
+
fail "Current version is #{PKG_VERSION}, must specify REUSE=tag_suffix to reuse version"
|
155
|
+
end
|
156
|
+
|
157
|
+
# Are all source files checked in?
|
158
|
+
if ENV['RELTEST']
|
159
|
+
announce "Release Task Testing, skipping checked-in file test"
|
160
|
+
else
|
161
|
+
announce "Checking for unchecked-in files..."
|
162
|
+
data = `cvs -q update`
|
163
|
+
unless data =~ /^$/
|
164
|
+
fail "CVS update is not clean ... do you have unchecked-in files?"
|
165
|
+
end
|
166
|
+
announce "No outstanding checkins found ... OK"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
task :update_version => [:prerelease] do
|
171
|
+
if PKG_VERSION == CURRENT_VERSION
|
172
|
+
announce "No version change ... skipping version update"
|
173
|
+
else
|
174
|
+
announce "Updating Builder version to #{PKG_VERSION}"
|
175
|
+
open("Rakefile") do |rakein|
|
176
|
+
open("Rakefile.new", "w") do |rakeout|
|
177
|
+
rakein.each do |line|
|
178
|
+
if line =~ /^CURRENT_VERSION\s*=\s*/
|
179
|
+
rakeout.puts "CURRENT_VERSION = '#{PKG_VERSION}'"
|
180
|
+
else
|
181
|
+
rakeout.puts line
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
mv "Rakefile.new", "Rakefile"
|
187
|
+
if ENV['RELTEST']
|
188
|
+
announce "Release Task Testing, skipping commiting of new version"
|
189
|
+
else
|
190
|
+
sh %{cvs commit -m "Updated to version #{PKG_VERSION}" Rakefile}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
desc "Tag all the CVS files with the latest release number (REL=x.y.z)"
|
196
|
+
task :tag => [:prerelease] do
|
197
|
+
reltag = "REL_#{PKG_VERSION.gsub(/\./, '_')}"
|
198
|
+
reltag << ENV['REUSE'].gsub(/\./, '_') if ENV['REUSE']
|
199
|
+
announce "Tagging CVS with [#{reltag}]"
|
200
|
+
if ENV['RELTEST']
|
201
|
+
announce "Release Task Testing, skipping CVS tagging"
|
202
|
+
else
|
203
|
+
sh %{cvs tag #{reltag}}
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
desc "Install the jamis RDoc template"
|
208
|
+
task :install_jamis_template do
|
209
|
+
require 'rbconfig'
|
210
|
+
dest_dir = File.join(Config::CONFIG['rubylibdir'], "rdoc/generators/template/html")
|
211
|
+
fail "Unabled to write to #{dest_dir}" unless File.writable?(dest_dir)
|
212
|
+
install "doc/jamis.rb", dest_dir, :verbose => true
|
94
213
|
end
|
95
214
|
|
96
215
|
require 'scripts/publish'
|
@@ -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
|
data/lib/builder/blankslate.rb
CHANGED
@@ -16,6 +16,9 @@ module Builder
|
|
16
16
|
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
|
17
17
|
class BlankSlate
|
18
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 "__".
|
19
22
|
def hide(name)
|
20
23
|
undef_method name if
|
21
24
|
instance_methods.include?(name.to_s) and
|
@@ -29,10 +32,14 @@ end
|
|
29
32
|
|
30
33
|
# Since Ruby is very dynamic, methods added to the ancestors of
|
31
34
|
# BlankSlate <em>after BlankSlate is defined</em> will show up in the
|
32
|
-
# list of available BlankSlate methods. We handle this by defining a
|
35
|
+
# list of available BlankSlate methods. We handle this by defining a
|
36
|
+
# hook in the Object and Kernel classes that will hide any defined
|
33
37
|
module Kernel
|
34
38
|
class << self
|
35
39
|
alias_method :blank_slate_method_added, :method_added
|
40
|
+
|
41
|
+
# Detect method additions to Kernel and remove them in the
|
42
|
+
# BlankSlate class.
|
36
43
|
def method_added(name)
|
37
44
|
blank_slate_method_added(name)
|
38
45
|
return if self != Kernel
|
@@ -44,6 +51,9 @@ end
|
|
44
51
|
class Object
|
45
52
|
class << self
|
46
53
|
alias_method :blank_slate_method_added, :method_added
|
54
|
+
|
55
|
+
# Detect method additions to Object and remove them in the
|
56
|
+
# BlankSlate class.
|
47
57
|
def method_added(name)
|
48
58
|
blank_slate_method_added(name)
|
49
59
|
return if self != Object
|
@@ -0,0 +1,112 @@
|
|
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)
|
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 => '&', # ampersand
|
70
|
+
60 => '<', # left angle bracket
|
71
|
+
62 => '>', # 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
|
93
|
+
def xchr
|
94
|
+
n = XChar::CP1252[self] || self
|
95
|
+
n = 42 unless XChar::VALID.find {|range| range.include? n}
|
96
|
+
XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
######################################################################
|
102
|
+
# Enhance the String class with a XML escaped character version of
|
103
|
+
# to_s.
|
104
|
+
#
|
105
|
+
class String
|
106
|
+
# XML escaped version of to_s
|
107
|
+
def to_xs
|
108
|
+
unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
|
109
|
+
rescue
|
110
|
+
unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
|
111
|
+
end
|
112
|
+
end
|
data/lib/builder/xmlbase.rb
CHANGED
@@ -13,7 +13,7 @@ module Builder
|
|
13
13
|
|
14
14
|
# Create an XML markup builder.
|
15
15
|
#
|
16
|
-
# out:: Object receiving the markup.
|
16
|
+
# out:: Object receiving the markup. +out+ must respond to
|
17
17
|
# <tt><<</tt>.
|
18
18
|
# indent:: Number of spaces used for indentation (0 implies no
|
19
19
|
# indentation and no line breaks).
|
@@ -111,11 +111,13 @@ module Builder
|
|
111
111
|
|
112
112
|
private
|
113
113
|
|
114
|
+
require 'builder/xchar'
|
114
115
|
def _escape(text)
|
115
|
-
text.
|
116
|
-
|
117
|
-
|
118
|
-
|
116
|
+
text.to_xs
|
117
|
+
end
|
118
|
+
|
119
|
+
def _escape_quote(text)
|
120
|
+
_escape(text).gsub(%r{"}, '"') # " WART
|
119
121
|
end
|
120
122
|
|
121
123
|
def _capture_outer_self(block)
|
data/lib/builder/xmlmarkup.rb
CHANGED
@@ -165,13 +165,23 @@ module Builder
|
|
165
165
|
# :target=><em>target_object</em>::
|
166
166
|
# Object receiving the markup. +out+ must respond to the
|
167
167
|
# <tt><<</tt> operator. The default is a plain string target.
|
168
|
+
#
|
168
169
|
# :indent=><em>indentation</em>::
|
169
170
|
# Number of spaces used for indentation. The default is no
|
170
171
|
# indentation and no line breaks.
|
172
|
+
#
|
171
173
|
# :margin=><em>initial_indentation_level</em>::
|
172
174
|
# Amount of initial indentation (specified in levels, not
|
173
175
|
# spaces).
|
174
176
|
#
|
177
|
+
# :escape_attrs=><b>OBSOLETE</em>::
|
178
|
+
# The :escape_attrs option is no longer supported by builder
|
179
|
+
# (and will be quietly ignored). String attribute values are
|
180
|
+
# now automatically escaped. If you need unescaped attribute
|
181
|
+
# values (perhaps you are using entities in the attribute
|
182
|
+
# values), then give the value as a Symbol. This allows much
|
183
|
+
# finer control over escaping attribute values.
|
184
|
+
#
|
175
185
|
def initialize(options={})
|
176
186
|
indent = options[:indent] || 0
|
177
187
|
margin = options[:margin] || 0
|
@@ -290,10 +300,19 @@ module Builder
|
|
290
300
|
return if attrs.nil?
|
291
301
|
order.each do |k|
|
292
302
|
v = attrs[k]
|
293
|
-
@target << %{ #{k}="#{v}"} if v
|
303
|
+
@target << %{ #{k}="#{_attr_value(v)}"} if v
|
294
304
|
end
|
295
305
|
attrs.each do |k, v|
|
296
|
-
@target << %{ #{k}="#{v}"} unless order.member?(k)
|
306
|
+
@target << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def _attr_value(value)
|
311
|
+
case value
|
312
|
+
when Symbol
|
313
|
+
value.to_s
|
314
|
+
else
|
315
|
+
_escape_quote(value.to_s)
|
297
316
|
end
|
298
317
|
end
|
299
318
|
|
data/test/performance.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'builder/xmlmarkup'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
text = "This is a test of the new xml markup. I�t�rn�ti�n�liz�ti�n\n" * 10000
|
7
|
+
|
8
|
+
include Benchmark # we need the CAPTION and FMTSTR constants
|
9
|
+
include Builder
|
10
|
+
n = 50
|
11
|
+
Benchmark.benchmark do |bm|
|
12
|
+
tf = bm.report("base") {
|
13
|
+
n.times do
|
14
|
+
x = XmlMarkup.new
|
15
|
+
x.text(text)
|
16
|
+
x.target!
|
17
|
+
end
|
18
|
+
}
|
19
|
+
def XmlMarkup._escape(text)
|
20
|
+
text.to_xs
|
21
|
+
end
|
22
|
+
tf = bm.report("to_xs") {
|
23
|
+
n.times do
|
24
|
+
x = XmlMarkup.new
|
25
|
+
x.text(text)
|
26
|
+
x.target!
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
data/test/test_xchar.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'builder/xchar'
|
5
|
+
|
6
|
+
class TestXmlEscaping < Test::Unit::TestCase
|
7
|
+
def test_ascii
|
8
|
+
assert_equal 'abc', 'abc'.to_xs
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_predefined
|
12
|
+
assert_equal '&', '&'.to_xs # ampersand
|
13
|
+
assert_equal '<', '<'.to_xs # left angle bracket
|
14
|
+
assert_equal '>', '>'.to_xs # right angle bracket
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_invalid
|
18
|
+
assert_equal '*', "\x00".to_xs # null
|
19
|
+
assert_equal '*', "\x0C".to_xs # form feed
|
20
|
+
assert_equal '*', "\xEF\xBF\xBF".to_xs # U+FFFF
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_iso_8859_1
|
24
|
+
assert_equal 'ç', "\xE7".to_xs # small c cedilla
|
25
|
+
assert_equal '©', "\xA9".to_xs # copyright symbol
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_win_1252
|
29
|
+
assert_equal '’', "\x92".to_xs # smart quote
|
30
|
+
assert_equal '€', "\x80".to_xs # euro
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_utf8
|
34
|
+
assert_equal '’', "\xE2\x80\x99".to_xs # right single quote
|
35
|
+
assert_equal '©', "\xC2\xA9".to_xs # copy
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
class TestEvents < Test::Unit::TestCase
|
2
|
+
|
3
|
+
class Target
|
4
|
+
attr_reader :events
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@events = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_tag(tag, attrs)
|
11
|
+
@events << [:start_tag, tag, attrs]
|
12
|
+
end
|
13
|
+
|
14
|
+
def end_tag(tag)
|
15
|
+
@events << [:end_tag, tag]
|
16
|
+
end
|
17
|
+
|
18
|
+
def text(string)
|
19
|
+
@events << [:text, string]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def setup
|
26
|
+
@target = Target.new
|
27
|
+
@xml = Builder::XmlEvents.new(:target=>@target)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_simple
|
31
|
+
@xml.one
|
32
|
+
expect [:start_tag, :one, nil]
|
33
|
+
expect [:end_tag, :one]
|
34
|
+
expect_done
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_nested
|
38
|
+
@xml.one { @xml.two }
|
39
|
+
expect [:start_tag, :one, nil]
|
40
|
+
expect [:start_tag, :two, nil]
|
41
|
+
expect [:end_tag, :two]
|
42
|
+
expect [:end_tag, :one]
|
43
|
+
expect_done
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_text
|
47
|
+
@xml.one("a")
|
48
|
+
expect [:start_tag, :one, nil]
|
49
|
+
expect [:text, "a"]
|
50
|
+
expect [:end_tag, :one]
|
51
|
+
expect_done
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_special_text
|
55
|
+
@xml.one("H&R")
|
56
|
+
expect [:start_tag, :one, nil]
|
57
|
+
expect [:text, "H&R"]
|
58
|
+
expect [:end_tag, :one]
|
59
|
+
expect_done
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_text_with_entity
|
63
|
+
@xml.one("H&R")
|
64
|
+
expect [:start_tag, :one, nil]
|
65
|
+
expect [:text, "H&R"]
|
66
|
+
expect [:end_tag, :one]
|
67
|
+
expect_done
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_attributes
|
71
|
+
@xml.a(:b=>"c", :x=>"y")
|
72
|
+
expect [:start_tag, :a, {:x => "y", :b => "c"}]
|
73
|
+
expect [:end_tag, :a]
|
74
|
+
expect_done
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_moderately_complex
|
78
|
+
@xml.tag! "address-book" do |x|
|
79
|
+
x.entry :id=>"1" do
|
80
|
+
x.name {
|
81
|
+
x.first "Bill"
|
82
|
+
x.last "Smith"
|
83
|
+
}
|
84
|
+
x.address "Cincinnati"
|
85
|
+
end
|
86
|
+
x.entry :id=>"2" do
|
87
|
+
x.name {
|
88
|
+
x.first "John"
|
89
|
+
x.last "Doe"
|
90
|
+
}
|
91
|
+
x.address "Columbus"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
expect [:start_tag, "address-book".intern, nil]
|
95
|
+
expect [:start_tag, :entry, {:id => "1"}]
|
96
|
+
expect [:start_tag, :name, nil]
|
97
|
+
expect [:start_tag, :first, nil]
|
98
|
+
expect [:text, "Bill"]
|
99
|
+
expect [:end_tag, :first]
|
100
|
+
expect [:start_tag, :last, nil]
|
101
|
+
expect [:text, "Smith"]
|
102
|
+
expect [:end_tag, :last]
|
103
|
+
expect [:end_tag, :name]
|
104
|
+
expect [:start_tag, :address, nil]
|
105
|
+
expect [:text, "Cincinnati"]
|
106
|
+
expect [:end_tag, :address]
|
107
|
+
expect [:end_tag, :entry]
|
108
|
+
expect [:start_tag, :entry, {:id => "2"}]
|
109
|
+
expect [:start_tag, :name, nil]
|
110
|
+
expect [:start_tag, :first, nil]
|
111
|
+
expect [:text, "John"]
|
112
|
+
expect [:end_tag, :first]
|
113
|
+
expect [:start_tag, :last, nil]
|
114
|
+
expect [:text, "Doe"]
|
115
|
+
expect [:end_tag, :last]
|
116
|
+
expect [:end_tag, :name]
|
117
|
+
expect [:start_tag, :address, nil]
|
118
|
+
expect [:text, "Columbus"]
|
119
|
+
expect [:end_tag, :address]
|
120
|
+
expect [:end_tag, :entry]
|
121
|
+
expect [:end_tag, "address-book".intern]
|
122
|
+
expect_done
|
123
|
+
end
|
124
|
+
|
125
|
+
def expect(value)
|
126
|
+
assert_equal value, @target.events.shift
|
127
|
+
end
|
128
|
+
|
129
|
+
def expect_done
|
130
|
+
assert_nil @target.events.shift
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
data/test/testmarkupbuilder.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
#--
|
4
|
+
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Permission is granted for use, copying, modification, distribution,
|
9
|
+
# and distribution of modified versions of this work as long as the
|
10
|
+
# above copyright notice is included.
|
11
|
+
#++
|
12
|
+
|
3
13
|
require 'test/unit'
|
4
14
|
require 'test/preload'
|
5
15
|
require 'builder'
|
@@ -34,6 +44,31 @@ class TestMarkup < Test::Unit::TestCase
|
|
34
44
|
assert_equal %{<ref id="12"/>}, @xml.target!
|
35
45
|
end
|
36
46
|
|
47
|
+
def test_string_attributes_are_quoted_by_default
|
48
|
+
@xml.ref(:id => "H&R")
|
49
|
+
assert_equal %{<ref id="H&R"/>}, @xml.target!
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_symbol_attributes_are_unquoted_by_default
|
53
|
+
@xml.ref(:id => :"H&R")
|
54
|
+
assert_equal %{<ref id="H&R"/>}, @xml.target!
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_attributes_quoted_can_be_turned_on
|
58
|
+
@xml = Builder::XmlMarkup.new
|
59
|
+
@xml.ref(:id => "<H&R \"block\">")
|
60
|
+
assert_equal %{<ref id="<H&R "block">"/>}, @xml.target!
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_mixed_attribute_quoting_with_nested_builders
|
64
|
+
x = Builder::XmlMarkup.new(:target=>@xml)
|
65
|
+
@xml.ref(:id=>:"H&R") {
|
66
|
+
x.element(:tag=>"Long&Short")
|
67
|
+
}
|
68
|
+
assert_equal "<ref id=\"H&R\"><element tag=\"Long&Short\"/></ref>",
|
69
|
+
@xml.target!
|
70
|
+
end
|
71
|
+
|
37
72
|
def test_multiple_attributes
|
38
73
|
@xml.ref(:id => 12, :name => "bill")
|
39
74
|
assert_match %r{^<ref( id="12"| name="bill"){2}/>$}, @xml.target!
|
@@ -96,7 +131,7 @@ class TestMarkup < Test::Unit::TestCase
|
|
96
131
|
end
|
97
132
|
|
98
133
|
def test_non_escaping
|
99
|
-
@xml.div("ns:xml"
|
134
|
+
@xml.div("ns:xml"=>:"&xml;") { |x| x << "<h&i>"; x.em("H&R Block") }
|
100
135
|
assert_equal %{<div ns:xml="&xml;"><h&i><em>H&R Block</em></div>}, @xml.target!
|
101
136
|
end
|
102
137
|
|
@@ -116,6 +151,44 @@ class TestMarkup < Test::Unit::TestCase
|
|
116
151
|
end
|
117
152
|
end
|
118
153
|
|
154
|
+
class TestAttributeEscaping < Test::Unit::TestCase
|
155
|
+
|
156
|
+
def setup
|
157
|
+
@xml = Builder::XmlMarkup.new
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_element_gt
|
161
|
+
@xml.title('1<2')
|
162
|
+
assert_equal '<title>1<2</title>', @xml.target!
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_element_amp
|
166
|
+
@xml.title('AT&T')
|
167
|
+
assert_equal '<title>AT&T</title>', @xml.target!
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_element_amp2
|
171
|
+
@xml.title('&')
|
172
|
+
assert_equal '<title>&amp;</title>', @xml.target!
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_attr_less
|
176
|
+
@xml.a(:title => '2>1')
|
177
|
+
assert_equal '<a title="2>1"/>', @xml.target!
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_attr_amp
|
181
|
+
@xml.a(:title => 'AT&T')
|
182
|
+
assert_equal '<a title="AT&T"/>', @xml.target!
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_attr_quot
|
186
|
+
@xml.a(:title => '"x"')
|
187
|
+
assert_equal '<a title=""x""/>', @xml.target!
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
119
192
|
class TestNameSpaces < Test::Unit::TestCase
|
120
193
|
def setup
|
121
194
|
@xml = Builder::XmlMarkup.new(:indent=>2)
|
@@ -130,11 +203,11 @@ class TestNameSpaces < Test::Unit::TestCase
|
|
130
203
|
xml = Builder::XmlMarkup.new(:indent=>2)
|
131
204
|
xml.instruct!
|
132
205
|
xml.rdf :RDF,
|
133
|
-
"xmlns:rdf" => "&rdf;",
|
134
|
-
"xmlns:rdfs" => "&rdfs;",
|
135
|
-
"xmlns:xsd" => "&xsd;",
|
136
|
-
"xmlns:owl" => "&owl;" do
|
137
|
-
xml.owl :Class, 'rdf:ID'=>'Bird' do
|
206
|
+
"xmlns:rdf" => :"&rdf;",
|
207
|
+
"xmlns:rdfs" => :"&rdfs;",
|
208
|
+
"xmlns:xsd" => :"&xsd;",
|
209
|
+
"xmlns:owl" => :"&owl;" do
|
210
|
+
xml.owl :Class, :'rdf:ID'=>'Bird' do
|
138
211
|
xml.rdfs :label, 'bird'
|
139
212
|
xml.rdfs :subClassOf do
|
140
213
|
xml.owl :Restriction do
|
metadata
CHANGED
@@ -1,62 +1,73 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11.6
|
3
3
|
specification_version: 1
|
4
4
|
name: builder
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version:
|
7
|
-
date:
|
6
|
+
version: 2.0.0
|
7
|
+
date: 2006-02-05 00:00:00 -05:00
|
8
8
|
summary: Builders for MarkUp.
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email: jim@weirichhouse.org
|
12
12
|
homepage: http://onestepback.org
|
13
13
|
rubyforge_project:
|
14
|
-
description: "Builder provides a number of builder objects that make creating structured data
|
15
|
-
simple to do. Currently the following builder objects are supported: * XML
|
16
|
-
Markup * XML Events"
|
14
|
+
description: "Builder provides a number of builder objects that make creating structured data simple to do. Currently the following builder objects are supported: * XML Markup * XML Events"
|
17
15
|
autorequire: builder
|
18
16
|
default_executable:
|
19
17
|
bindir: bin
|
20
18
|
has_rdoc: true
|
21
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
20
|
requirements:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
27
24
|
version:
|
28
25
|
platform: ruby
|
29
26
|
signing_key:
|
30
27
|
cert_chain:
|
31
28
|
authors:
|
32
|
-
|
29
|
+
- Jim Weirich
|
33
30
|
files:
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
31
|
+
- lib/builder.rb
|
32
|
+
- lib/builder/xmlmarkup.rb
|
33
|
+
- lib/builder/xmlbase.rb
|
34
|
+
- lib/builder/blankslate.rb
|
35
|
+
- lib/builder/xmlevents.rb
|
36
|
+
- lib/builder/xchar.rb
|
37
|
+
- test/testmarkupbuilder.rb
|
38
|
+
- test/testblankslate.rb
|
39
|
+
- test/preload.rb
|
40
|
+
- test/test_xchar.rb
|
41
|
+
- test/testeventbuilder.rb
|
42
|
+
- test/performance.rb
|
43
|
+
- scripts/publish.rb
|
44
|
+
- README
|
45
|
+
- Rakefile
|
46
|
+
- CHANGES
|
47
|
+
- doc/releases/builder-1.2.4.rdoc
|
48
|
+
- doc/releases/builder-2.0.0.rdoc
|
46
49
|
test_files:
|
47
|
-
|
48
|
-
|
50
|
+
- test/testmarkupbuilder.rb
|
51
|
+
- test/testblankslate.rb
|
52
|
+
- test/test_xchar.rb
|
53
|
+
- test/testeventbuilder.rb
|
49
54
|
rdoc_options:
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
+
- --title
|
56
|
+
- Builder -- Easy XML Building
|
57
|
+
- --main
|
58
|
+
- README
|
59
|
+
- --line-numbers
|
55
60
|
extra_rdoc_files:
|
56
|
-
|
57
|
-
|
58
|
-
|
61
|
+
- README
|
62
|
+
- Rakefile
|
63
|
+
- CHANGES
|
64
|
+
- doc/releases/builder-1.2.4.rdoc
|
65
|
+
- doc/releases/builder-2.0.0.rdoc
|
59
66
|
executables: []
|
67
|
+
|
60
68
|
extensions: []
|
69
|
+
|
61
70
|
requirements: []
|
62
|
-
|
71
|
+
|
72
|
+
dependencies: []
|
73
|
+
|