", @xml.target!
end
def name
"bob"
end
end
class TestAttributeEscaping < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new
end
def test_element_gt
@xml.title('1<2')
assert_equal '1<2', @xml.target!
end
def test_element_amp
@xml.title('AT&T')
assert_equal 'AT&T', @xml.target!
end
def test_element_amp2
@xml.title('&')
assert_equal '&', @xml.target!
end
def test_attr_less
@xml.a(:title => '2>1')
assert_equal '', @xml.target!
end
def test_attr_amp
@xml.a(:title => 'AT&T')
assert_equal '', @xml.target!
end
def test_attr_quot
@xml.a(:title => '"x"')
assert_equal '', @xml.target!
end
end
class TestNameSpaces < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_simple_name_spaces
@xml.rdf :RDF
assert_equal "\n", @xml.target!
end
def test_long
xml = Builder::XmlMarkup.new(:indent=>2)
xml.instruct!
xml.rdf :RDF,
"xmlns:rdf" => :"&rdf;",
"xmlns:rdfs" => :"&rdfs;",
"xmlns:xsd" => :"&xsd;",
"xmlns:owl" => :"&owl;" do
xml.owl :Class, :'rdf:ID'=>'Bird' do
xml.rdfs :label, 'bird'
xml.rdfs :subClassOf do
xml.owl :Restriction do
xml.owl :onProperty, 'rdf:resource'=>'#wingspan'
xml.owl :maxCardinality,1,'rdf:datatype'=>'&xsd;nonNegativeInteger'
end
end
end
end
assert_match(/^<\?xml/, xml.target!)
assert_match(/\n/m, xml.target!)
end
def test_ensure
xml = Builder::XmlMarkup.new
xml.html do
xml.body do
begin
xml.p do
raise Exception.new('boom')
end
rescue Exception => e
xml.pre e
end
end
end
assert_match %r{
}, xml.target!
assert_match %r{
}, xml.target!
end
end
class TestDeclarations < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_declare
@xml.declare! :element
assert_equal "\n", @xml.target!
end
def test_bare_arg
@xml.declare! :element, :arg
assert_equal"\n", @xml.target!
end
def test_string_arg
@xml.declare! :element, "string"
assert_equal"\n", @xml.target!
end
def test_mixed_args
@xml.declare! :element, :x, "y", :z, "-//OASIS//DTD DocBook XML//EN"
assert_equal "\n", @xml.target!
end
def test_nested_declarations
@xml = Builder::XmlMarkup.new
@xml.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, "(title,para+)".intern
end
assert_equal "]>", @xml.target!
end
def test_nested_indented_declarations
@xml.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, "(title,para+)".intern
end
assert_equal "\n]>\n", @xml.target!
end
def test_complex_declaration
@xml.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, "(title,para+)".intern
x.declare! :ELEMENT, :title, "(#PCDATA)".intern
x.declare! :ELEMENT, :para, "(#PCDATA)".intern
end
expected = %{
]>
}
assert_equal expected, @xml.target!
end
end
class TestSpecialMarkup < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_comment
@xml.comment!("COMMENT")
assert_equal "\n", @xml.target!
end
def test_indented_comment
@xml.p { @xml.comment! "OK" }
assert_equal "
\n", @xml.target!
end
def test_initial_level
@xml = Builder::XmlMarkup.new(:indent=>2, :margin=>4)
@xml.name { |x| x.first("Jim") }
assert_equal " \n Jim\n \n", @xml.target!
end
class TestUtfMarkup < Test::Unit::TestCase
if ! String.method_defined?(:encode)
def setup
@old_kcode = $KCODE
end
def teardown
$KCODE = @old_kcode
end
def test_use_entities_if_no_encoding_is_given_and_kcode_is_none
$KCODE = 'NONE'
xml = Builder::XmlMarkup.new
xml.p("\xE2\x80\x99")
assert_match(%r(
’
), xml.target!) #
end
def test_use_entities_if_encoding_is_utf_but_kcode_is_not
$KCODE = 'NONE'
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-8')
xml.p("\xE2\x80\x99")
assert_match(%r(
’
), xml.target!) #
end
else
# change in behavior. As there is no $KCODE anymore, the default
# moves from "does not understand utf-8" to "supports utf-8".
def test_use_entities_if_no_encoding_is_given_and_kcode_is_none
xml = Builder::XmlMarkup.new
xml.p("\xE2\x80\x99")
assert_match("
\u2019
", xml.target!) #
end
def test_use_entities_if_encoding_is_utf_but_kcode_is_not
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-8')
xml.p("\xE2\x80\x99")
assert_match("
\u2019
", xml.target!) #
end
end
def encode string, encoding
if !String.method_defined?(:encode)
$KCODE = encoding
string
elsif encoding == 'UTF8'
string.force_encoding('UTF-8')
else
string
end
end
def test_use_entities_if_kcode_is_utf_but_encoding_is_dummy_encoding
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-16')
xml.p(encode("\xE2\x80\x99", 'UTF8'))
assert_match(%r(
’
), xml.target!) #
end
def test_use_entities_if_kcode_is_utf_but_encoding_is_unsupported_encoding
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UCS-2')
xml.p(encode("\xE2\x80\x99", 'UTF8'))
assert_match(%r(
’
), xml.target!) #
end
def test_use_utf8_if_encoding_defaults_and_kcode_is_utf8
xml = Builder::XmlMarkup.new
xml.p(encode("\xE2\x80\x99",'UTF8'))
assert_equal encode("
\xE2\x80\x99
",'UTF8'), xml.target!
end
def test_use_utf8_if_both_encoding_and_kcode_are_utf8
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-8')
xml.p(encode("\xE2\x80\x99",'UTF8'))
assert_match encode("
\xE2\x80\x99
",'UTF8'), xml.target!
end
def test_use_utf8_if_both_encoding_and_kcode_are_utf8_with_lowercase
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'utf-8')
xml.p(encode("\xE2\x80\x99",'UTF8'))
assert_match encode("
\xE2\x80\x99
",'UTF8'), xml.target!
end
end
class TestXmlEvents < Test::Unit::TestCase
def setup
@handler = EventHandler.new
@xe = Builder::XmlEvents.new(:target=>@handler)
end
def test_simple
@xe.p
assert_equal [:start, :p, nil], @handler.events.shift
assert_equal [:end, :p], @handler.events.shift
end
def test_text
@xe.p("HI")
assert_equal [:start, :p, nil], @handler.events.shift
assert_equal [:text, "HI"], @handler.events.shift
assert_equal [:end, :p], @handler.events.shift
end
def test_attributes
@xe.p("id"=>"2")
ev = @handler.events.shift
assert_equal [:start, :p], ev[0,2]
assert_equal "2", ev[2]['id']
assert_equal [:end, :p], @handler.events.shift
end
def test_indented
@xml = Builder::XmlEvents.new(:indent=>2, :target=>@handler)
@xml.p { |x| x.b("HI") }
assert_equal [:start, :p, nil], @handler.events.shift
assert_equal "\n ", pop_text
assert_equal [:start, :b, nil], @handler.events.shift
assert_equal "HI", pop_text
assert_equal [:end, :b], @handler.events.shift
assert_equal "\n", pop_text
assert_equal [:end, :p], @handler.events.shift
end
def pop_text
result = ''
while ! @handler.events.empty? && @handler.events[0][0] == :text
result << @handler.events[0][1]
@handler.events.shift
end
result
end
class EventHandler
attr_reader :events
def initialize
@events = []
end
def start_tag(sym, attrs)
@events << [:start, sym, attrs]
end
def end_tag(sym)
@events << [:end, sym]
end
def text(txt)
@events << [:text, txt]
end
end
end
end
builder-3.2.2/test/test_method_caching.rb 0000644 0000041 0000041 00000003112 12202216152 020461 0 ustar www-data www-data #!/usr/bin/env ruby
#--
# Portions copyright 2011 by Bart ten Brinke (info@retrosync.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'test/unit'
require 'test/preload'
require 'builder'
class TestMethodCaching < Test::Unit::TestCase
# We can directly ask if xml object responds to the cache_me or
# do_not_cache_me methods because xml is derived from BasicObject
# (and repond_to? is not defined in BasicObject).
#
# Instead we are going to stub out method_missing so that it throws
# an error, and then make sure that error is either thrown or not
# thrown as appropriate.
def teardown
super
Builder::XmlBase.cache_method_calls = true
end
def test_caching_does_not_break_weird_symbols
xml = Builder::XmlMarkup.new
xml.__send__("work-order", 1)
assert_equal "1", xml.target!
end
def test_method_call_caching
xml = Builder::XmlMarkup.new
xml.cache_me
def xml.method_missing(*args)
::Kernel.fail StandardError, "SHOULD NOT BE CALLED"
end
assert_nothing_raised do
xml.cache_me
end
end
def test_method_call_caching_disabled
Builder::XmlBase.cache_method_calls = false
xml = Builder::XmlMarkup.new
xml.do_not_cache_me
def xml.method_missing(*args)
::Kernel.fail StandardError, "SHOULD BE CALLED"
end
assert_raise(StandardError, "SHOULD BE CALLED") do
xml.do_not_cache_me
end
end
end
builder-3.2.2/test/performance.rb 0000644 0000041 0000041 00000001644 12202216152 016777 0 ustar www-data www-data #!/usr/bin/env ruby
# encoding: iso-8859-1
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'builder/xmlmarkup'
require 'benchmark'
text = "This is a test of the new xml markup. I�t�rn�ti�n�liz�ti�n\n" * 10000
include Benchmark # we need the CAPTION and FMTSTR constants
include Builder
n = 50
Benchmark.benchmark do |bm|
tf = bm.report("base") {
n.times do
x = XmlMarkup.new
x.text(text)
x.target!
end
}
def XmlMarkup._escape(text)
text.to_xs
end
tf = bm.report("to_xs") {
n.times do
x = XmlMarkup.new
x.text(text)
x.target!
end
}
end
builder-3.2.2/doc/ 0000755 0000041 0000041 00000000000 12202216152 013732 5 ustar www-data www-data builder-3.2.2/doc/releases/ 0000755 0000041 0000041 00000000000 12202216152 015535 5 ustar www-data www-data builder-3.2.2/doc/releases/builder-2.1.1.rdoc 0000755 0000041 0000041 00000003110 12202216152 020467 0 ustar www-data www-data = Builder 2.1.1 Released.
Release 2.1.1 of Builder is mainly a bug fix release.
== Changes in 2.1.1
* Added reveal capability to BlankSlate.
* Fixed a bug in BlankSlate where including a module into Object could
cause methods to leak into BlankSlate.
* Fixed typo in XmlMarkup class docs (from Martin Fowler).
* Fixed test on private methods to differentiate between targetted and
untargetted private methods.
* Removed legacy capture of @self in XmlBase (@self was used back when
we used instance eval).
* Added additional tests for global functions (both direct and
included).
* Several misc internal cleanups, including rearranging the source
code tree.
NOTE: The escaping attribute values by default is different
than in previous releases of Builder. This makes version 2.0.x
somewhat incompatible with the 1.x series of Builder. If you use "&",
"<", or ">" in attributes values, you may have to change your
code. (Essentially you remove the manual escaping. The new way is
easier, believe me).
== What is Builder?
Builder::XmlMarkup is a library that allows easy programmatic creation
of XML markup. For example:
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
will generate:
Jim555-1234
== Availability
The easiest way to get and install builder is via RubyGems ...
gem install builder (you may need root/admin privileges)
== Thanks
* Martin Fowler for spotting some typos in the documentation.
-- Jim Weirich
builder-3.2.2/doc/releases/builder-1.2.4.rdoc 0000644 0000041 0000041 00000001206 12202216152 020473 0 ustar www-data www-data = Builder 1.2.4 Released.
Added a "CDATA" method to the XML Markup builder (from Josh Knowles).
== What is Builder?
Builder::XmlMarkup allows easy programmatic creation of XML markup.
For example:
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
puts builder.target!
will generate:
Jim555-1234
== Availability
The easiest way to get and install builder is via RubyGems ...
gem install builder (you may need root/admin privileges)
== Thanks
* Josh Knowles for the cdata! patch.
-- Jim Weirich
builder-3.2.2/doc/releases/builder-2.0.0.rdoc 0000644 0000041 0000041 00000002346 12202216152 020474 0 ustar www-data www-data = Builder 2.0.0 Released.
== Changes in 2.0.0
* UTF-8 characters in data are now correctly translated to their XML
equivalents. (Thanks to Sam Ruby)
* Attribute values are now escaped by default. See the README
file for details.
NOTE: The escaping attribute values by default is different
than in previous releases of Builder. This makes version 2.0.0
somewhat incompatible with the 1.x series of Builder. If you use "&",
"<", or ">" in attributes values, you may have to change your
code. (Essentially you remove the manual escaping. The new way is
easier, believe me).
== What is Builder?
Builder::XmlMarkup is a library that allows easy programmatic creation
of XML markup. For example:
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
will generate:
Jim555-1234
== Availability
The easiest way to get and install builder is via RubyGems ...
gem install builder (you may need root/admin privileges)
== Thanks
* Sam Ruby for the XChar module and the related UTF-8 translation
tools.
* Also to Sam Ruby for gently persuading me to start quoting attribute
values.
-- Jim Weirich
builder-3.2.2/doc/jamis.rb 0000644 0000041 0000041 00000026117 12202216152 015371 0 ustar www-data www-data module RDoc
module Page
FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif"
STYLE = < pre {
padding: 0.5em;
border: 1px dotted black;
background: #FFE;
}
CSS
XHTML_PREAMBLE = %{
}
HEADER = XHTML_PREAMBLE + <%title%
ENDHEADER
FILE_PAGE = <
HTML
CLASS_INDEX = FILE_INDEX
METHOD_INDEX = FILE_INDEX
INDEX = XHTML_PREAMBLE + <
%title%
HTML
end
end
builder-3.2.2/README.md 0000644 0000041 0000041 00000017037 12202216152 014454 0 ustar www-data www-data # Project: Builder
## Goal
Provide a simple way to create XML markup and data structures.
## Classes
Builder::XmlMarkup:: Generate XML markup notation
Builder::XmlEvents:: Generate XML events (i.e. SAX-like)
**Notes:**
* An Builder::XmlTree class to generate XML tree
(i.e. DOM-like) structures is also planned, but not yet implemented.
Also, the events builder is currently lagging the markup builder in
features.
## Usage
```ruby
require 'rubygems'
require_gem 'builder', '~> 2.0'
builder = Builder::XmlMarkup.new
` xml = builder.person { |b| b.name("Jim"); b.phone("555-1234") }
xml #=> Jim555-1234
```
or
```ruby
require 'rubygems'
require_gem 'builder'
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
#
# Prints:
#
# Jim
# 555-1234
#
```
## Compatibility
### Version 2.0.0 Compatibility Changes
Version 2.0.0 introduces automatically escaped attribute values for
the first time. Versions prior to 2.0.0 did not insert escape
characters into attribute values in the XML markup. This allowed
attribute values to explicitly reference entities, which was
occasionally used by a small number of developers. Since strings
could always be explicitly escaped by hand, this was not a major
restriction in functionality.
However, it did surprise most users of builder. Since the body text is
normally escaped, everybody expected the attribute values to be
escaped as well. Escaped attribute values were the number one support
request on the 1.x Builder series.
Starting with Builder version 2.0.0, all attribute values expressed as
strings will be processed and the appropriate characters will be
escaped (e.g. "&" will be translated to "&"). Attribute values
that are expressed as Symbol values will not be processed for escaped
characters and will be unchanged in output. (Yes, this probably counts
as Symbol abuse, but the convention is convenient and flexible).
Example:
```ruby
xml = Builder::XmlMarkup.new
xml.sample(:escaped=>"This&That", :unescaped=>:"Here&There")
xml.target! =>
```
### Version 1.0.0 Compatibility Changes
Version 1.0.0 introduces some changes that are not backwards
compatible with earlier releases of builder. The main areas of
incompatibility are:
* Keyword based arguments to +new+ (rather than positional based). It
was found that a developer would often like to specify indentation
without providing an explicit target, or specify a target without
indentation. Keyword based arguments handle this situation nicely.
* Builder must now be an explicit target for markup tags. Instead of
writing
```ruby
xml_markup = Builder::XmlMarkup.new
xml_markup.div { strong("text") }
```
you need to write
```ruby
xml_markup = Builder::XmlMarkup.new
xml_markup.div { xml_markup.strong("text") }
```
* The builder object is passed as a parameter to all nested markup
blocks. This allows you to create a short alias for the builder
object that can be used within the block. For example, the previous
example can be written as:
```ruby
xml_markup = Builder::XmlMarkup.new
xml_markup.div { |xml| xml.strong("text") }
```
* If you have both a pre-1.0 and a post-1.0 gem of builder installed,
you can choose which version to use through the RubyGems
+require_gem+ facility.
```ruby
require_gem 'builder', "~> 0.0" # Gets the old version
require_gem 'builder', "~> 1.0" # Gets the new version
```
## Features
* XML Comments are supported ...
```ruby
xml_markup.comment! "This is a comment"
#=>
```
* XML processing instructions are supported ...
```ruby
xml_markup.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
#=>
```
If the processing instruction is omitted, it defaults to "xml".
When the processing instruction is "xml", the defaults attributes
are:
version: 1.0
encoding: "UTF-8"
(NOTE: if the encoding is set to "UTF-8" and $KCODE is set to
"UTF8", then Builder will emit UTF-8 encoded strings rather than
encoding non-ASCII characters as entities.)
* XML entity declarations are now supported to a small degree.
```ruby
xml_markup.declare! :DOCTYPE, :chapter, :SYSTEM, "../dtds/chapter.dtd"
#=>
```
The parameters to a declare! method must be either symbols or
strings. Symbols are inserted without quotes, and strings are
inserted with double quotes. Attribute-like arguments in hashes are
not allowed.
If you need to have an argument to declare! be inserted without
quotes, but the argument does not conform to the typical Ruby
syntax for symbols, then use the :"string" form to specify a symbol.
For example:
```ruby
xml_markup.declare! :ELEMENT, :chapter, :"(title,para+)"
#=>
```
Nested entity declarations are allowed. For example:
```ruby
@xml_markup.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, :"(title,para+)"
x.declare! :ELEMENT, :title, :"(#PCDATA)"
x.declare! :ELEMENT, :para, :"(#PCDATA)"
end
#=>
]>
```
* Some support for XML namespaces is now available. If the first
argument to a tag call is a symbol, it will be joined to the tag to
produce a namespace:tag combination. It is easier to show this than
describe it.
```ruby
xml.SOAP :Envelope do ... end
```
Just put a space before the colon in a namespace to produce the
right form for builder (e.g. "SOAP:Envelope" =>
"xml.SOAP :Envelope")
* String attribute values are now escaped by default by
Builder (NOTE: this is _new_ behavior as of version 2.0).
However, occasionally you need to use entities in attribute values.
Using a symbol (rather than a string) for an attribute value will
cause Builder to not run its quoting/escaping algorithm on that
particular value.
(Note: The +escape_attrs+ option for builder is now
obsolete).
Example:
```ruby
xml = Builder::XmlMarkup.new
xml.sample(:escaped=>"This&That", :unescaped=>:"Here&There")
xml.target! =>
```
* UTF-8 Support
Builder correctly translates UTF-8 characters into valid XML. (New
in version 2.0.0). Thanks to Sam Ruby for the translation code.
You can get UTF-8 encoded output by making sure that the XML
encoding is set to "UTF-8" and that the $KCODE variable is set to
"UTF8".
```ruby
$KCODE = 'UTF8'
xml = Builder::Markup.new
xml.instruct!(:xml, :encoding => "UTF-8")
xml.sample("Iñtërnâtiônàl")
xml.target! =>
"Iñtërnâtiônàl"
```
## Links
| Description | Link |
| :----: | :----: |
| Documents | http://builder.rubyforge.org/ |
| Github Clone | git://github.com/jimweirich/builder.git |
| Issue / Bug Reports | https://github.com/jimweirich/builder/issues?state=open |
## Contact
| Description | Value |
| :----: | :----: |
| Author | Jim Weirich |
| Email | jim.weirich@gmail.com |
| Home Page | http://onestepback.org |
| License | MIT Licence (http://www.opensource.org/licenses/mit-license.html) |
builder-3.2.2/Rakefile 0000644 0000041 0000041 00000011463 12202216152 014637 0 ustar www-data www-data # Rakefile for rake -*- ruby -*-
# Copyright 2004, 2005, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
require 'rake/clean'
require 'rake/testtask'
begin
require 'rubygems'
require 'rubygems/package_task'
require 'rdoc/task'
rescue Exception
nil
end
require './lib/builder/version'
# Determine the current version of the software
CLOBBER.include('pkg', 'html')
CLEAN.include('pkg/builder-*').include('pkg/blankslate-*').exclude('pkg/*.gem')
PKG_VERSION = Builder::VERSION
SRC_RB = FileList['lib/**/*.rb']
# The default task is run if rake is given no explicit arguments.
desc "Default Task"
task :default => :test_all
# Test Tasks ---------------------------------------------------------
desc "Run all tests"
task :test_all => [:test_units]
task :ta => [:test_all]
task :tu => [:test_units]
Rake::TestTask.new("test_units") do |t|
t.test_files = FileList['test/test*.rb']
t.libs << "."
t.verbose = false
end
# Create a task to build the RDOC documentation tree.
if defined?(RDoc)
rd = RDoc::Task.new("rdoc") { |rdoc|
rdoc.rdoc_dir = 'html'
rdoc.title = "Builder for Markup"
rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README.rdoc'
rdoc.rdoc_files.include('lib/**/*.rb', '[A-Z]*', 'doc/**/*.rdoc').exclude("TAGS")
rdoc.template = 'doc/jamis.rb'
}
else
rd = Struct.new(:rdoc_files).new([])
end
# ====================================================================
# Create a task that will package the Rake software into distributable
# gem files.
PKG_FILES = FileList[
'[A-Z]*',
'doc/**/*',
'lib/**/*.rb',
'test/**/*.rb',
'rakelib/**/*'
]
PKG_FILES.exclude('test/test_cssbuilder.rb')
PKG_FILES.exclude('lib/builder/css.rb')
PKG_FILES.exclude('TAGS')
BLANKSLATE_FILES = FileList[
'lib/blankslate.rb',
'test/test_blankslate.rb'
]
if ! defined?(Gem)
puts "Package Target requires RubyGEMs"
else
spec = Gem::Specification.new do |s|
#### Basic information.
s.name = 'builder'
s.version = PKG_VERSION
s.summary = "Builders for MarkUp."
s.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
}
s.files = PKG_FILES.to_a
s.require_path = 'lib'
s.test_files = PKG_FILES.select { |fn| fn =~ /^test\/test/ }
s.has_rdoc = true
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
s.rdoc_options <<
'--title' << 'Builder -- Easy XML Building' <<
'--main' << 'README.rdoc' <<
'--line-numbers'
s.author = "Jim Weirich"
s.email = "jim.weirich@gmail.com"
s.homepage = "http://onestepback.org"
s.license = 'MIT'
end
blankslate_spec = Gem::Specification.new do |s|
#### Basic information.
s.name = 'blankslate'
s.version = PKG_VERSION
s.summary = "Blank Slate base class."
s.description = %{\
BlankSlate provides a base class where almost all of the methods from Object and
Kernel have been removed. This is useful when providing proxy object and other
classes that make heavy use of method_missing.
}
s.files = BLANKSLATE_FILES.to_a
s.require_path = 'lib'
s.test_files = PKG_FILES.select { |fn| fn =~ /^test\/test/ }
s.has_rdoc = true
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
s.rdoc_options <<
'--title' << 'BlankSlate -- Base Class for building proxies.' <<
'--main' << 'README.rdoc' <<
'--line-numbers'
s.author = "Jim Weirich"
s.email = "jim.weirich@gmail.com"
s.homepage = "http://onestepback.org"
s.license = 'MIT'
end
namespace 'builder' do
Gem::PackageTask.new(spec) do |t|
t.need_tar = false
end
end
namespace 'blankslate' do
Gem::PackageTask.new(blankslate_spec) do |t|
t.need_tar = false
end
end
task :package => [:remove_tags, 'builder:package', 'blankslate:package']
end
task :remove_tags do
rm "TAGS" rescue nil
end
# RCov ---------------------------------------------------------------
begin
require 'rcov/rcovtask'
Rcov::RcovTask.new do |t|
t.libs << "test"
t.rcov_opts = [
'-xRakefile', '--text-report'
]
t.test_files = FileList[
'test/test*.rb'
]
t.output_dir = 'coverage'
t.verbose = true
end
rescue LoadError
# No rcov available
end
desc "Install the jamis RDoc template"
task :install_jamis_template do
require 'rbconfig'
dest_dir = File.join(Config::CONFIG['rubylibdir'], "rdoc/generators/template/html")
fail "Unabled to write to #{dest_dir}" unless File.writable?(dest_dir)
install "doc/jamis.rb", dest_dir, :verbose => true
end
builder-3.2.2/checksums.yaml.gz 0000444 0000041 0000041 00000000414 12202216152 016452 0 ustar www-data www-data ;Qe;R@"B:;{O ,X8<K*`w.ox\_ebs[i-#TX&ni~5qh/m,U]*1*8C;)%
rQjra$A
eX,TúR:G;Yq\k46!/iyעajIh9@鷅LGd.6֍Hi
ix-s9Ɯ{D彞tɀJ4f䉗٢ builder-3.2.2/metadata.yml 0000644 0000041 0000041 00000003774 12202216152 015503 0 ustar www-data www-data --- !ruby/object:Gem::Specification
name: builder
version: !ruby/object:Gem::Version
version: 3.2.2
platform: ruby
authors:
- Jim Weirich
autorequire:
bindir: bin
cert_chain: []
date: 2013-06-01 00:00:00.000000000 Z
dependencies: []
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
email: jim.weirich@gmail.com
executables: []
extensions: []
extra_rdoc_files:
- CHANGES
- MIT-LICENSE
- README.md
- Rakefile
- doc/releases/builder-1.2.4.rdoc
- doc/releases/builder-2.0.0.rdoc
- doc/releases/builder-2.1.1.rdoc
files:
- CHANGES
- MIT-LICENSE
- README.md
- Rakefile
- doc/jamis.rb
- doc/releases/builder-1.2.4.rdoc
- doc/releases/builder-2.0.0.rdoc
- doc/releases/builder-2.1.1.rdoc
- lib/blankslate.rb
- lib/builder.rb
- lib/builder/blankslate.rb
- lib/builder/version.rb
- lib/builder/xchar.rb
- lib/builder/xmlbase.rb
- lib/builder/xmlevents.rb
- lib/builder/xmlmarkup.rb
- test/performance.rb
- test/preload.rb
- test/test_blankslate.rb
- test/test_eventbuilder.rb
- test/test_markupbuilder.rb
- test/test_method_caching.rb
- test/test_namecollision.rb
- test/test_xchar.rb
- rakelib/publish.rake
- rakelib/tags.rake
homepage: http://onestepback.org
licenses:
- MIT
metadata: {}
post_install_message:
rdoc_options:
- --title
- Builder -- Easy XML Building
- --main
- README.rdoc
- --line-numbers
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - '>='
- !ruby/object:Gem::Version
version: '0'
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - '>='
- !ruby/object:Gem::Version
version: '0'
requirements: []
rubyforge_project:
rubygems_version: 2.0.3
signing_key:
specification_version: 4
summary: Builders for MarkUp.
test_files:
- test/test_blankslate.rb
- test/test_eventbuilder.rb
- test/test_markupbuilder.rb
- test/test_method_caching.rb
- test/test_namecollision.rb
- test/test_xchar.rb
builder-3.2.2/CHANGES 0000644 0000041 0000041 00000005445 12202216152 014170 0 ustar www-data www-data = Change Log
== Version 3.2.0
* Ruby 2.0 compatibility changes.
* Allow single quoted attributes.
== Version 3.1.0
* Included the to_xs arity patch needed for weird Rails compatibility
issue.
* Escaping newlines in attributes now.
* Allow method caching
== Version 3.0.0
* Ruby 1.9 compatiblity issues.
== Version 2.2.0
* Applied patch from Thijs van der Vossen to allow UTF-8 encoded
output when the encoding is UTF-8 and $KCODE is UTF8.
== Version 2.1.2
* Fixed bug where private methods in kernel could leak through using
tag!(). Thanks to Hagen Overdick for finding and diagnosing this
bug.
== Version 2.1.1
* Fixed typo in XmlMarkup class docs (ident => indent). (from Martin
Fowler).
* Removed extra directory indirection from legacy CVS to SVN move.
* Removed some extraneous tabs from source.
* Fixed test on private methods in blankslate to differentiate between
targetted and untargetted private methods.
* Removed legacy capture of @self in XmlBase (@self was used back when
we used instance eval).
* Added additional tests for global functions (both direct and included).
== Version 2.1.0
* Fixed bug in BlankSlate where including a module into Object could
cause methods to leak into BlankSlate.
* Made BlankSlate available as its own gem. Currently the builder gem
still directly includes the BlankSlate code.
* Added reveal capability to BlankSlate.
== Version 2.0.0
* Added doc directory
* Added unit tests for XmlEvents.
* Added XChar module and used it in the _escape method.
* Attributes are now quoted by default when strings. Use Symbol
attribute values for unquoted behavior.
== Version 1.2.4
* Added a cdata! command to an XML Builder (from Josh Knowles).
== Version 1.2.3
The attributes in the instruction will be ordered:
version, encoding, standalone.
== Version 1.2.2
Another fix for BlankSlate. The Kernal/Object traps added in 1.2.1
failed when a method was defined late more than once. Since the
method was already marked as removed, another attempt to undefine it
raised an error. The fix was to check the list of instance methods
before attempting the undef operation. Thanks to Florian Gross and
David Heinemeier Hansson for the patch.
== Version 1.2.1
BlankSlate now traps method definitions in Kernel and Object to avoid
late method definitions inadvertently becoming part of the definition
of BlankSlate as well.
== Version 1.2.0
Improved support for entity declarations by allowing nested
declarations and removal of the attribute processing.
Added namespace support.
== Version 1.1.0
Added support for comments, entity declarations and processing instructions.
== Version 1.0.0
Removed use of instace_eval making the use of XmlMarkup much
less prone to error.
== Version 0.1.1
Bug fix.
== Version 0.1.0
Initial version release.
builder-3.2.2/lib/ 0000755 0000041 0000041 00000000000 12202216152 013733 5 ustar www-data www-data builder-3.2.2/lib/builder/ 0000755 0000041 0000041 00000000000 12202216152 015361 5 ustar www-data www-data builder-3.2.2/lib/builder/version.rb 0000644 0000041 0000041 00000000230 12202216152 017366 0 ustar www-data www-data module Builder
VERSION_NUMBERS = [
VERSION_MAJOR = 3,
VERSION_MINOR = 2,
VERSION_BUILD = 2,
]
VERSION = VERSION_NUMBERS.join(".")
end
builder-3.2.2/lib/builder/xchar.rb 0000644 0000041 0000041 00000014071 12202216152 017016 0 ustar www-data www-data #!/usr/bin/env ruby
# The XChar library is provided courtesy of Sam Ruby (See
# http://intertwingly.net/stories/2005/09/28/xchar.rb)
# --------------------------------------------------------------------
# If the Builder::XChar module is not currently defined, fail on any
# name clashes in standard library classes.
module Builder
def self.check_for_name_collision(klass, method_name, defined_constant=nil)
if klass.method_defined?(method_name.to_s)
fail RuntimeError,
"Name Collision: Method '#{method_name}' is already defined in #{klass}"
end
end
end
if ! defined?(Builder::XChar) and ! String.method_defined?(:encode)
Builder.check_for_name_collision(String, "to_xs")
Builder.check_for_name_collision(Fixnum, "xchr")
end
######################################################################
module Builder
####################################################################
# XML Character converter, from Sam Ruby:
# (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
#
module XChar # :nodoc:
# See
# http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
# for details.
CP1252 = { # :nodoc:
128 => 8364, # euro sign
130 => 8218, # single low-9 quotation mark
131 => 402, # latin small letter f with hook
132 => 8222, # double low-9 quotation mark
133 => 8230, # horizontal ellipsis
134 => 8224, # dagger
135 => 8225, # double dagger
136 => 710, # modifier letter circumflex accent
137 => 8240, # per mille sign
138 => 352, # latin capital letter s with caron
139 => 8249, # single left-pointing angle quotation mark
140 => 338, # latin capital ligature oe
142 => 381, # latin capital letter z with caron
145 => 8216, # left single quotation mark
146 => 8217, # right single quotation mark
147 => 8220, # left double quotation mark
148 => 8221, # right double quotation mark
149 => 8226, # bullet
150 => 8211, # en dash
151 => 8212, # em dash
152 => 732, # small tilde
153 => 8482, # trade mark sign
154 => 353, # latin small letter s with caron
155 => 8250, # single right-pointing angle quotation mark
156 => 339, # latin small ligature oe
158 => 382, # latin small letter z with caron
159 => 376, # latin capital letter y with diaeresis
}
# See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
PREDEFINED = {
38 => '&', # ampersand
60 => '<', # left angle bracket
62 => '>', # right angle bracket
}
# See http://www.w3.org/TR/REC-xml/#charsets for details.
VALID = [
0x9, 0xA, 0xD,
(0x20..0xD7FF),
(0xE000..0xFFFD),
(0x10000..0x10FFFF)
]
# http://www.fileformat.info/info/unicode/char/fffd/index.htm
REPLACEMENT_CHAR =
if String.method_defined?(:encode)
"\uFFFD"
elsif $KCODE == 'UTF8'
"\xEF\xBF\xBD"
else
'*'
end
end
end
if String.method_defined?(:encode)
module Builder
module XChar # :nodoc:
CP1252_DIFFERENCES, UNICODE_EQUIVALENT = Builder::XChar::CP1252.each.
inject([[],[]]) {|(domain,range),(key,value)|
[domain << key,range << value]
}.map {|seq| seq.pack('U*').force_encoding('utf-8')}
XML_PREDEFINED = Regexp.new('[' +
Builder::XChar::PREDEFINED.keys.pack('U*').force_encoding('utf-8') +
']')
INVALID_XML_CHAR = Regexp.new('[^'+
Builder::XChar::VALID.map { |item|
case item
when Fixnum
[item].pack('U').force_encoding('utf-8')
when Range
[item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8')
end
}.join +
']')
ENCODING_BINARY = Encoding.find('BINARY')
ENCODING_UTF8 = Encoding.find('UTF-8')
ENCODING_ISO1 = Encoding.find('ISO-8859-1')
# convert a string to valid UTF-8, compensating for a number of
# common errors.
def XChar.unicode(string)
if string.encoding == ENCODING_BINARY
if string.ascii_only?
string
else
string = string.clone.force_encoding(ENCODING_UTF8)
if string.valid_encoding?
string
else
string.encode(ENCODING_UTF8, ENCODING_ISO1)
end
end
elsif string.encoding == ENCODING_UTF8
if string.valid_encoding?
string
else
string.encode(ENCODING_UTF8, ENCODING_ISO1)
end
else
string.encode(ENCODING_UTF8)
end
end
# encode a string per XML rules
def XChar.encode(string)
unicode(string).
tr(CP1252_DIFFERENCES, UNICODE_EQUIVALENT).
gsub(INVALID_XML_CHAR, REPLACEMENT_CHAR).
gsub(XML_PREDEFINED) {|c| PREDEFINED[c.ord]}
end
end
end
else
######################################################################
# Enhance the Fixnum class with a XML escaped character conversion.
#
class Fixnum
XChar = Builder::XChar if ! defined?(XChar)
# XML escaped version of chr. When escape is set to false
# the CP1252 fix is still applied but utf-8 characters are not
# converted to character entities.
def xchr(escape=true)
n = XChar::CP1252[self] || self
case n when *XChar::VALID
XChar::PREDEFINED[n] or
(n<128 ? n.chr : (escape ? "#{n};" : [n].pack('U*')))
else
Builder::XChar::REPLACEMENT_CHAR
end
end
end
######################################################################
# Enhance the String class with a XML escaped character version of
# to_s.
#
class String
# XML escaped version of to_s. When escape is set to false
# the CP1252 fix is still applied but utf-8 characters are not
# converted to character entities.
def to_xs(escape=true)
unpack('U*').map {|n| n.xchr(escape)}.join # ASCII, UTF-8
rescue
unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
end
end
end
builder-3.2.2/lib/builder/xmlmarkup.rb 0000644 0000041 0000041 00000025524 12202216152 017736 0 ustar www-data www-data #!/usr/bin/env ruby
#--
# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
# Provide a flexible and easy to use Builder for creating XML markup.
# See XmlBuilder for usage details.
require 'builder/xmlbase'
module Builder
# Create XML markup easily. All (well, almost all) methods sent to
# an XmlMarkup object will be translated to the equivalent XML
# markup. Any method with a block will be treated as an XML markup
# tag with nested markup in the block.
#
# Examples will demonstrate this easier than words. In the
# following, +xm+ is an +XmlMarkup+ object.
#
# xm.em("emphasized") # => emphasized
# xm.em { xm.b("emp & bold") } # => emph & bold
# xm.a("A Link", "href"=>"http://onestepback.org")
# # => A Link
# xm.div { xm.br } # =>
# xm.target("name"=>"compile", "option"=>"fast")
# # =>
# # NOTE: order of attributes is not specified.
#
# xm.instruct! #
# xm.html { #
# xm.head { #
# xm.title("History") # History
# } #
# xm.body { #
# xm.comment! "HI" #
# xm.h1("Header") #
Header
# xm.p("paragraph") #
paragraph
# } #
# } #
#
# == Notes:
#
# * The order that attributes are inserted in markup tags is
# undefined.
#
# * Sometimes you wish to insert text without enclosing tags. Use
# the text! method to accomplish this.
#
# Example:
#
# xm.div { #
# xm.text! "line"; xm.br # line
# xm.text! "another line"; xmbr # another line
# } #
#
# * The special XML characters <, >, and & are converted to <,
# > and & automatically. Use the << operation to
# insert text without modification.
#
# * Sometimes tags use special characters not allowed in ruby
# identifiers. Use the tag! method to handle these
# cases.
#
# Example:
#
# xml.tag!("SOAP:Envelope") { ... }
#
# will produce ...
#
# ... "
#
# tag! will also take text and attribute arguments (after
# the tag name) like normal markup methods. (But see the next
# bullet item for a better way to handle XML namespaces).
#
# * Direct support for XML namespaces is now available. If the
# first argument to a tag call is a symbol, it will be joined to
# the tag to produce a namespace:tag combination. It is easier to
# show this than describe it.
#
# xml.SOAP :Envelope do ... end
#
# Just put a space before the colon in a namespace to produce the
# right form for builder (e.g. "SOAP:Envelope" =>
# "xml.SOAP :Envelope")
#
# * XmlMarkup builds the markup in any object (called a _target_)
# that accepts the << method. If no target is given,
# then XmlMarkup defaults to a string target.
#
# Examples:
#
# xm = Builder::XmlMarkup.new
# result = xm.title("yada")
# # result is a string containing the markup.
#
# buffer = ""
# xm = Builder::XmlMarkup.new(buffer)
# # The markup is appended to buffer (using <<)
#
# xm = Builder::XmlMarkup.new(STDOUT)
# # The markup is written to STDOUT (using <<)
#
# xm = Builder::XmlMarkup.new
# x2 = Builder::XmlMarkup.new(:target=>xm)
# # Markup written to +x2+ will be send to +xm+.
#
# * Indentation is enabled by providing the number of spaces to
# indent for each level as a second argument to XmlBuilder.new.
# Initial indentation may be specified using a third parameter.
#
# Example:
#
# xm = Builder.new(:indent=>2)
# # xm will produce nicely formatted and indented XML.
#
# xm = Builder.new(:indent=>2, :margin=>4)
# # xm will produce nicely formatted and indented XML with 2
# # spaces per indent and an over all indentation level of 4.
#
# builder = Builder::XmlMarkup.new(:target=>$stdout, :indent=>2)
# builder.name { |b| b.first("Jim"); b.last("Weirich) }
# # prints:
# #
# # Jim
# # Weirich
# #
#
# * The instance_eval implementation which forces self to refer to
# the message receiver as self is now obsolete. We now use normal
# block calls to execute the markup block. This means that all
# markup methods must now be explicitly send to the xml builder.
# For instance, instead of
#
# xml.div { strong("text") }
#
# you need to write:
#
# xml.div { xml.strong("text") }
#
# Although more verbose, the subtle change in semantics within the
# block was found to be prone to error. To make this change a
# little less cumbersome, the markup block now gets the markup
# object sent as an argument, allowing you to use a shorter alias
# within the block.
#
# For example:
#
# xml_builder = Builder::XmlMarkup.new
# xml_builder.div { |xml|
# xml.stong("text")
# }
#
class XmlMarkup < XmlBase
# Create an XML markup builder. Parameters are specified by an
# option hash.
#
# :target => target_object::
# Object receiving the markup. +target_object+ must respond to
# the <<(a_string) operator and return
# itself. The default target is a plain string target.
#
# :indent => indentation::
# Number of spaces used for indentation. The default is no
# indentation and no line breaks.
#
# :margin => initial_indentation_level::
# Amount of initial indentation (specified in levels, not
# spaces).
#
# :quote => :single::
# Use single quotes for attributes rather than double quotes.
#
# :escape_attrs => OBSOLETE::
# The :escape_attrs option is no longer supported by builder
# (and will be quietly ignored). String attribute values are
# now automatically escaped. If you need unescaped attribute
# values (perhaps you are using entities in the attribute
# values), then give the value as a Symbol. This allows much
# finer control over escaping attribute values.
#
def initialize(options={})
indent = options[:indent] || 0
margin = options[:margin] || 0
@quote = (options[:quote] == :single) ? "'" : '"'
@explicit_nil_handling = options[:explicit_nil_handling]
super(indent, margin)
@target = options[:target] || ""
end
# Return the target of the builder.
def target!
@target
end
def comment!(comment_text)
_ensure_no_block ::Kernel::block_given?
_special("", comment_text, nil)
end
# Insert an XML declaration into the XML markup.
#
# For example:
#
# xml.declare! :ELEMENT, :blah, "yada"
# # =>
def declare!(inst, *args, &block)
_indent
@target << ""
_newline
end
# Insert a processing instruction into the XML markup. E.g.
#
# For example:
#
# xml.instruct!
# #=>
# xml.instruct! :aaa, :bbb=>"ccc"
# #=>
#
# Note: If the encoding is setup to "UTF-8" and the value of
# $KCODE is "UTF8", then builder will emit UTF-8 encoded strings
# rather than the entity encoding normally used.
def instruct!(directive_tag=:xml, attrs={})
_ensure_no_block ::Kernel::block_given?
if directive_tag == :xml
a = { :version=>"1.0", :encoding=>"UTF-8" }
attrs = a.merge attrs
@encoding = attrs[:encoding].downcase
end
_special(
"#{directive_tag}",
"?>",
nil,
attrs,
[:version, :encoding, :standalone])
end
# Insert a CDATA section into the XML markup.
#
# For example:
#
# xml.cdata!("text to be included in cdata")
# #=>
#
def cdata!(text)
_ensure_no_block ::Kernel::block_given?
_special("", text.gsub(']]>', ']]]]>'), nil)
end
private
# NOTE: All private methods of a builder object are prefixed when
# a "_" character to avoid possible conflict with XML tag names.
# Insert text directly in to the builder's target.
def _text(text)
@target << text
end
# Insert special instruction.
def _special(open, close, data=nil, attrs=nil, order=[])
_indent
@target << open
@target << data if data
_insert_attributes(attrs, order) if attrs
@target << close
_newline
end
# Start an XML tag. If end_too is true, then the start
# tag is also the end tag (e.g.
def _start_tag(sym, attrs, end_too=false)
@target << "<#{sym}"
_insert_attributes(attrs)
@target << "/" if end_too
@target << ">"
end
# Insert an ending tag.
def _end_tag(sym)
@target << "#{sym}>"
end
# Insert the attributes (given in the hash).
def _insert_attributes(attrs, order=[])
return if attrs.nil?
order.each do |k|
v = attrs[k]
@target << %{ #{k}=#{@quote}#{_attr_value(v)}#{@quote}} if v
end
attrs.each do |k, v|
@target << %{ #{k}=#{@quote}#{_attr_value(v)}#{@quote}} unless order.member?(k) # " WART
end
end
def _attr_value(value)
case value
when ::Symbol
value.to_s
else
_escape_attribute(value.to_s)
end
end
def _ensure_no_block(got_block)
if got_block
::Kernel::raise IllegalBlockError.new(
"Blocks are not allowed on XML instructions"
)
end
end
end
end
builder-3.2.2/lib/builder/xmlevents.rb 0000644 0000041 0000041 00000003520 12202216152 017733 0 ustar www-data www-data #!/usr/bin/env ruby
#--
# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'builder/xmlmarkup'
module Builder
# Create a series of SAX-like XML events (e.g. start_tag, end_tag)
# from the markup code. XmlEvent objects are used in a way similar
# to XmlMarkup objects, except that a series of events are generated
# and passed to a handler rather than generating character-based
# markup.
#
# Usage:
# xe = Builder::XmlEvents.new(hander)
# xe.title("HI") # Sends start_tag/end_tag/text messages to the handler.
#
# Indentation may also be selected by providing value for the
# indentation size and initial indentation level.
#
# xe = Builder::XmlEvents.new(handler, indent_size, initial_indent_level)
#
# == XML Event Handler
#
# The handler object must expect the following events.
#
# [start_tag(tag, attrs)]
# Announces that a new tag has been found. +tag+ is the name of
# the tag and +attrs+ is a hash of attributes for the tag.
#
# [end_tag(tag)]
# Announces that an end tag for +tag+ has been found.
#
# [text(text)]
# Announces that a string of characters (+text+) has been found.
# A series of characters may be broken up into more than one
# +text+ call, so the client cannot assume that a single
# callback contains all the text data.
#
class XmlEvents < XmlMarkup
def text!(text)
@target.text(text)
end
def _start_tag(sym, attrs, end_too=false)
@target.start_tag(sym, attrs)
_end_tag(sym) if end_too
end
def _end_tag(sym)
@target.end_tag(sym)
end
end
end
builder-3.2.2/lib/builder/blankslate.rb 0000644 0000041 0000041 00000001265 12202216152 020032 0 ustar www-data www-data #!/usr/bin/env ruby
#--
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
######################################################################
# BlankSlate has been promoted to a top level name and is now
# available as a standalone gem. We make the name available in the
# Builder namespace for compatibility.
#
module Builder
if Object::const_defined?(:BasicObject)
BlankSlate = ::BasicObject
else
require 'blankslate'
BlankSlate = ::BlankSlate
end
end
builder-3.2.2/lib/builder/xmlbase.rb 0000644 0000041 0000041 00000013245 12202216152 017346 0 ustar www-data www-data #!/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
class << self
attr_accessor :cache_method_calls
end
# Create an XML markup builder.
#
# out :: Object receiving the markup. +out+ must respond to
# <<.
# indent :: Number of spaces used for indentation (0 implies no
# indentation and no line breaks).
# initial :: Level of initial indentation.
# encoding :: When encoding and $KCODE are set to 'utf-8'
# characters aren't converted to character entities in
# the output stream.
def initialize(indent=0, initial=0, encoding='utf-8')
@indent = indent
@level = initial
@encoding = encoding.downcase
end
def explicit_nil_handling?
@explicit_nil_handling
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 method_missing.
def tag!(sym, *args, &block)
text = nil
attrs = nil
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
sym = sym.to_sym unless sym.class == ::Symbol
args.each do |arg|
case arg
when ::Hash
attrs ||= {}
attrs.merge!(arg)
when nil
attrs ||= {}
attrs.merge!({:nil => true}) if explicit_nil_handling?
else
text ||= ''
text << arg.to_s
end
end
if block
unless text.nil?
::Kernel::raise ::ArgumentError,
"XmlMarkup cannot mix a text argument with a block"
end
_indent
_start_tag(sym, attrs)
_newline
begin
_nested_structures(block)
ensure
_indent
_end_tag(sym)
_newline
end
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
# 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 that isn't cached.
def method_missing(sym, *args, &block)
cache_method_call(sym) if ::Builder::XmlBase.cache_method_calls
tag!(sym, *args, &block)
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" } #=>
HI
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 << " HI" } #=>
HI
#
# 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 << 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'
if ::String.method_defined?(:encode)
def _escape(text)
result = XChar.encode(text)
begin
encoding = ::Encoding::find(@encoding)
raise Exception if encoding.dummy?
result.encode(encoding)
rescue
# if the encoding can't be supported, use numeric character references
result.
gsub(/[^\u0000-\u007F]/) {|c| "#{c.ord};"}.
force_encoding('ascii')
end
end
else
def _escape(text)
if (text.method(:to_xs).arity == 0)
text.to_xs
else
text.to_xs((@encoding != 'utf-8' or $KCODE != 'UTF8'))
end
end
end
def _escape_attribute(text)
_escape(text).gsub("\n", "
").gsub("\r", "
").
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
# If XmlBase.cache_method_calls = true, we dynamicly create the method
# missed as an instance method on the XMLBase object. Because XML
# documents are usually very repetative in nature, the next node will
# be handled by the new method instead of method_missing. As
# method_missing is very slow, this speeds up document generation
# significantly.
def cache_method_call(sym)
class << self; self; end.class_eval do
unless method_defined?(sym)
define_method(sym) do |*args, &block|
tag!(sym, *args, &block)
end
end
end
end
end
XmlBase.cache_method_calls = true
end
builder-3.2.2/lib/builder.rb 0000644 0000041 0000041 00000000526 12202216152 015711 0 ustar www-data www-data #!/usr/bin/env ruby
#--
# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'builder/xmlmarkup'
require 'builder/xmlevents'
builder-3.2.2/lib/blankslate.rb 0000644 0000041 0000041 00000007401 12202216152 016402 0 ustar www-data www-data #!/usr/bin/env ruby
#--
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
class String
if instance_methods.first.is_a?(Symbol)
def _blankslate_as_name
to_sym
end
else
def _blankslate_as_name
self
end
end
end
class Symbol
if instance_methods.first.is_a?(Symbol)
def _blankslate_as_name
self
end
else
def _blankslate_as_name
to_s
end
end
end
######################################################################
# BlankSlate provides an abstract base class with no predefined
# methods (except for \_\_send__ and \_\_id__).
# BlankSlate is useful as a base class when writing classes that
# depend upon method_missing (e.g. dynamic proxies).
#
class BlankSlate
class << self
# Hide the method named +name+ in the BlankSlate class. Don't
# hide +instance_eval+ or any method beginning with "__".
def hide(name)
warn_level = $VERBOSE
$VERBOSE = nil
if instance_methods.include?(name._blankslate_as_name) &&
name !~ /^(__|instance_eval$)/
@hidden_methods ||= {}
@hidden_methods[name.to_sym] = instance_method(name)
undef_method name
end
ensure
$VERBOSE = warn_level
end
def find_hidden_method(name)
@hidden_methods ||= {}
@hidden_methods[name] || superclass.find_hidden_method(name)
end
# Redefine a previously hidden method so that it may be called on a blank
# slate object.
def reveal(name)
hidden_method = find_hidden_method(name)
fail "Don't know how to reveal method '#{name}'" unless hidden_method
define_method(name, hidden_method)
end
end
instance_methods.each { |m| hide(m) }
end
######################################################################
# Since Ruby is very dynamic, methods added to the ancestors of
# BlankSlate after BlankSlate is defined will show up in the
# list of available BlankSlate methods. We handle this by defining a
# hook in the Object and Kernel classes that will hide any method
# defined after BlankSlate has been loaded.
#
module Kernel
class << self
alias_method :blank_slate_method_added, :method_added
# Detect method additions to Kernel and remove them in the
# BlankSlate class.
def method_added(name)
result = blank_slate_method_added(name)
return result if self != Kernel
BlankSlate.hide(name)
result
end
end
end
######################################################################
# Same as above, except in Object.
#
class Object
class << self
alias_method :blank_slate_method_added, :method_added
# Detect method additions to Object and remove them in the
# BlankSlate class.
def method_added(name)
result = blank_slate_method_added(name)
return result if self != Object
BlankSlate.hide(name)
result
end
def find_hidden_method(name)
nil
end
end
end
######################################################################
# Also, modules included into Object need to be scanned and have their
# instance methods removed from blank slate. In theory, modules
# included into Kernel would have to be removed as well, but a
# "feature" of Ruby prevents late includes into modules from being
# exposed in the first place.
#
class Module
alias blankslate_original_append_features append_features
def append_features(mod)
result = blankslate_original_append_features(mod)
return result if mod != Object
instance_methods.each do |name|
BlankSlate.hide(name)
end
result
end
end