diff --git a/vendor/htree/.cvsignore b/vendor/htree/.cvsignore
new file mode 100644
index 0000000..f63e5e5
--- /dev/null
+++ b/vendor/htree/.cvsignore
@@ -0,0 +1,3 @@
+index.html
+README.html
+doc
diff --git a/vendor/htree/Makefile b/vendor/htree/Makefile
new file mode 100644
index 0000000..74d858e
--- /dev/null
+++ b/vendor/htree/Makefile
@@ -0,0 +1,21 @@
+RUBY=ruby
+RD2HTML=rd2 -r rd/rd2html-lib.rb
+
+all: README.html doc/index.html
+
+README.html: README.rd
+ $(RD2HTML) --html-title='htree - HTML/XML tree library' -o README README.rd
+
+check test:
+ $(RUBY) -I. test-all.rb
+
+install:
+ $(RUBY) install.rb
+
+.PHONY: check test all install
+
+RB = htree.rb htree/modules.rb $(wildcard htree/[a-l]*.rb) $(wildcard htree/[n-z]*.rb)
+doc/index.html: $(RB)
+ rm -rf doc
+ rdoc $(RB)
+
diff --git a/vendor/htree/README.rd b/vendor/htree/README.rd
new file mode 100644
index 0000000..f868278
--- /dev/null
+++ b/vendor/htree/README.rd
@@ -0,0 +1,48 @@
+= htree - HTML/XML tree library
+
+htree provides a tree data structure which represent HTML and XML data.
+
+== Features
+
+* Permissive unified HTML/XML parser
+* byte-to-byte round-tripping unparser
+* XML namespace support
+* Dedicated class for escaped string. This ease sanitization.
+* HTML/XHTML/XML generator
+* template engine
+* recursive template expansion
+* converter to REXML document
+
+== Home Page
+
+(())
+
+== Download
+
+* (())
+
+== Install
+
+ % ruby install.rb
+
+== Reference Manual
+
+(())
+
+== Usage Example
+
+Following two-line script convert HTML to XHTML.
+
+ require 'htree'
+ HTree(STDIN).display_xml
+
+The conversion method to REXML is provided as to_rexml.
+
+ HTree(...).to_rexml
+
+== License
+
+Ruby's
+
+== Author
+Tanaka Akira
diff --git a/vendor/htree/htree.rb b/vendor/htree/htree.rb
new file mode 100644
index 0000000..a797d54
--- /dev/null
+++ b/vendor/htree/htree.rb
@@ -0,0 +1,97 @@
+#
+# = htree.rb
+#
+# HTML/XML document tree
+#
+# Author:: Tanaka Akira
+#
+# == Features
+#
+# - Permissive unified HTML/XML parser
+# - byte-to-byte round-tripping unparser
+# - XML namespace support
+# - Dedicated class for escaped string. This ease sanitization.
+# - XHTML/XML generator
+# - template engine: link:files/htree/template_rb.html
+# - recursive template expansion
+# - REXML tree generator: link:files/htree/rexml_rb.html
+#
+# == Example
+#
+# The following one-liner prints parsed tree object.
+#
+# % ruby -rhtree -e 'pp HTree(ARGF)' html-file
+#
+# The following two-line script convert HTML to XHTML.
+#
+# require 'htree'
+# HTree(STDIN).display_xml
+#
+# The conversion method to REXML is provided as to_rexml.
+#
+# HTree(...).to_rexml
+#
+# == Module/Class Hierarchy
+#
+# * HTree
+# * HTree::Name
+# * HTree::Context
+# * HTree::Location
+# * HTree::Node
+# * HTree::Doc
+# * HTree::Elem
+# * HTree::Text
+# * HTree::XMLDecl
+# * HTree::DocType
+# * HTree::ProcIns
+# * HTree::Comment
+# * HTree::BogusETag
+# * HTree::Error
+#
+# == Method Summary
+#
+# HTree provides following methods.
+#
+# - Parsing Methods
+# - HTree(html_string) -> HTree::Doc
+# - HTree.parse(input) -> HTree::Doc
+#
+# - Generation Methods
+# - HTree::Node#display_xml -> STDOUT
+# - HTree::Node#display_xml(out) -> out
+# - HTree::Node#display_xml(out, encoding) -> out
+# - HTree::Text#to_s -> String
+#
+# - Template Methods
+# - HTree.expand_template{template_string} -> STDOUT
+# - HTree.expand_template(out){template_string} -> out
+# - HTree.expand_template(out, encoding){template_string} -> out
+# - HTree.compile_template(template_string) -> Module
+# - HTree{template_string} -> HTree::Doc
+#
+# - Traverse Methods
+# - HTree::Elem#attributes -> Hash[HTree::Name -> HTree::Text]
+# - HTree::Elem::Location#attributes -> Hash[HTree::Name -> HTree::Location]
+#
+# - Predicate Methods
+# - HTree::Traverse#doc? -> true or false
+# - HTree::Traverse#elem? -> true or false
+# - HTree::Traverse#text? -> true or false
+# - HTree::Traverse#xmldecl? -> true or false
+# - HTree::Traverse#doctype? -> true or false
+# - HTree::Traverse#procins? -> true or false
+# - HTree::Traverse#comment? -> true or false
+# - HTree::Traverse#bogusetag? -> true or false
+#
+# - REXML Tree Generator
+# - HTree::Node#to_rexml -> REXML::Child
+
+require 'htree/parse'
+require 'htree/extract_text'
+require 'htree/equality'
+require 'htree/inspect'
+require 'htree/display'
+require 'htree/loc'
+require 'htree/traverse'
+require 'htree/template'
+require 'htree/rexml'
diff --git a/vendor/htree/htree/container.rb b/vendor/htree/htree/container.rb
new file mode 100644
index 0000000..da7da8b
--- /dev/null
+++ b/vendor/htree/htree/container.rb
@@ -0,0 +1,8 @@
+require 'htree/modules'
+
+module HTree::Container
+ # +children+ returns children nodes as an array.
+ def children
+ @children.dup
+ end
+end
diff --git a/vendor/htree/htree/context.rb b/vendor/htree/htree/context.rb
new file mode 100644
index 0000000..cf54b82
--- /dev/null
+++ b/vendor/htree/htree/context.rb
@@ -0,0 +1,69 @@
+module HTree
+ class Context
+ # :stopdoc:
+ DefaultNamespaces = {'xml'=>'http://www.w3.org/XML/1998/namespace'}
+ DefaultNamespaces.default = ""
+ DefaultNamespaces.freeze
+ # :startdoc:
+
+ # The optional argument `namespaces' should be a hash or nil.
+ # HTree::DefaultNamespaces is used if nil is specified.
+ #
+ # If it is a hash, its key should be nil or a string.
+ # nil means default namespace.
+ # The string means some prefix which must not be empty.
+ #
+ # The hash value should be a string.
+ # The empty string "" means unbound namespace.
+ def initialize(namespaces=nil)
+ namespaces ||= DefaultNamespaces
+ namespaces.each_pair {|k, v|
+ check_namespace_prefix(k)
+ check_namespace_uri(v)
+ }
+ namespaces = namespaces.dup.freeze unless namespaces.frozen?
+ @namespaces = namespaces
+ end
+ attr_reader :namespaces
+
+ # return a namespace URI corresponding to _prefix_.
+ # It returns nil if _prefix_ is not defined.
+ def namespace_uri(prefix)
+ @namespaces[prefix]
+ end
+
+ # generate a new Context object which namespaces are substituted by
+ # a hash _declared_namespaces_.
+ def subst_namespaces(declared_namespaces)
+ namespaces = @namespaces.dup
+ declared_namespaces.each {|k, v|
+ check_namespace_prefix(k)
+ check_namespace_uri(v)
+ namespaces[k] = v
+ }
+ if namespaces == @namespaces
+ self
+ else
+ Context.new(namespaces)
+ end
+ end
+
+ private
+ def check_namespace_prefix(k)
+ unless (String === k && !k.empty?) || k == nil
+ raise ArgumentError, "invalid namespace prefix: #{k.inspect}"
+ end
+ end
+
+ def check_namespace_uri(v)
+ unless String === v
+ raise ArgumentError, "invalid namespace URI: #{v.inspect}"
+ end
+ end
+ end
+
+ # :stopdoc:
+ DefaultContext = Context.new
+ HTMLContext = DefaultContext.subst_namespaces(nil=>"http://www.w3.org/1999/xhtml")
+ # :startdoc:
+end
diff --git a/vendor/htree/htree/display.rb b/vendor/htree/htree/display.rb
new file mode 100644
index 0000000..61d12e9
--- /dev/null
+++ b/vendor/htree/htree/display.rb
@@ -0,0 +1,46 @@
+require 'htree/output'
+
+module HTree
+ module Node
+ # HTree::Node#display_xml prints the node as XML.
+ #
+ # The first optional argument, out,
+ # specifies output target.
+ # It should respond to <<.
+ # If it is not specified, $stdout is used.
+ #
+ # The second optional argument, encoding,
+ # specifies output MIME charset (character encoding).
+ # If it is not specified, HTree::Encoder.internal_charset is used.
+ #
+ # HTree::Node#display_xml returns out.
+ def display_xml(out=$stdout, encoding=HTree::Encoder.internal_charset)
+ encoder = HTree::Encoder.new(encoding)
+ self.output(encoder, HTree::DefaultContext)
+ # don't call finish_with_xmldecl because self already has a xml decl.
+ out << encoder.finish
+ out
+ end
+
+ # HTree::Node#display_html prints the node as HTML.
+ #
+ # The first optional argument, out,
+ # specifies output target.
+ # It should respond to <<.
+ # If it is not specified, $stdout is used.
+ #
+ # The second optional argument, encoding,
+ # specifies output MIME charset (character encoding).
+ # If it is not specified, HTree::Encoder.internal_charset is used.
+ #
+ # HTree::Node#display_html returns out.
+ def display_html(out=$stdout, encoding=HTree::Encoder.internal_charset)
+ encoder = HTree::Encoder.new(encoding)
+ encoder.html_output = true
+ self.output(encoder, HTree::HTMLContext)
+ out << encoder.finish
+ out
+ end
+
+ end
+end
diff --git a/vendor/htree/htree/doc.rb b/vendor/htree/htree/doc.rb
new file mode 100644
index 0000000..def6e38
--- /dev/null
+++ b/vendor/htree/htree/doc.rb
@@ -0,0 +1,149 @@
+require 'htree/modules'
+require 'htree/container'
+
+module HTree
+ class Doc
+ # :stopdoc:
+ class << self
+ alias new! new
+ end
+ # :startdoc:
+
+ # The arguments should be a sequence of follows.
+ # [String object] specified string is converted to HTree::Text.
+ # [HTree::Node object] used as a child.
+ # [HTree::Doc object]
+ # used as children.
+ # It is expanded except HTree::XMLDecl and HTree::DocType objects.
+ # [Array of String, HTree::Node and HTree::Doc] used as children.
+ #
+ def Doc.new(*args)
+ children = []
+ args.each {|arg|
+ arg = arg.to_node if HTree::Location === arg
+ case arg
+ when Array
+ arg.each {|a|
+ a = a.to_node if HTree::Location === a
+ case a
+ when HTree::Doc
+ children.concat(a.children.reject {|c|
+ HTree::XMLDecl === c || HTree::DocType === c
+ })
+ when HTree::Node
+ children << a
+ when String
+ children << Text.new(a)
+ else
+ raise TypeError, "unexpected argument: #{arg.inspect}"
+ end
+ }
+ when HTree::Doc
+ children.concat(arg.children.reject {|c|
+ HTree::XMLDecl === c || HTree::DocType === c
+ })
+ when HTree::Node
+ children << arg
+ when String
+ children << Text.new(arg)
+ else
+ raise TypeError, "unexpected argument: #{arg.inspect}"
+ end
+ }
+ new!(children)
+ end
+
+ def initialize(children=[]) # :notnew:
+ @children = children.dup.freeze
+ unless @children.all? {|c| c.kind_of?(HTree::Node) and !c.kind_of?(HTree::Doc) }
+ unacceptable = @children.reject {|c| c.kind_of?(HTree::Node) and !c.kind_of?(HTree::Doc) }
+ unacceptable = unacceptable.map {|uc| uc.inspect }.join(', ')
+ raise TypeError, "Unacceptable document child: #{unacceptable}"
+ end
+ end
+
+ def get_subnode_internal(index) # :nodoc:
+ unless Integer === index
+ raise TypeError, "invalid index: #{index.inspect}"
+ end
+ if index < 0 || @children.length <= index
+ nil
+ else
+ @children[index]
+ end
+ end
+
+ # doc.subst_subnode(pairs) -> doc
+ #
+ # The argument _pairs_ should be a hash or an assocs.
+ # Its key should be an integer which means an index for children.
+ #
+ # Its value should be one of follows.
+ # [HTree::Node object] specified object is used as is.
+ # [String object] specified string is converted to HTree::Text
+ # [Array of above] specified HTree::Node and String is used in that order.
+ # [nil] delete corresponding node.
+ #
+ # d = HTree('')
+ # p d.subst_subnode({0=>HTree(''), 2=>HTree('')})
+ # p d.subst_subnode([[0,HTree('')], [2,HTree('')]])
+ # # =>
+ # #} {emptyelem } {emptyelem }>
+ # #} {emptyelem } {emptyelem }>
+ #
+ def subst_subnode(pairs)
+ hash = {}
+ pairs.each {|index, value|
+ unless Integer === index
+ raise TypeError, "invalid index: #{index.inspect}"
+ end
+ value = value.to_node if HTree::Location === value
+ case value
+ when Node
+ value = [value]
+ when String
+ value = [value]
+ when Array
+ value = value.dup
+ when nil
+ value = []
+ else
+ raise TypeError, "invalid value: #{value.inspect}"
+ end
+ value.map! {|v|
+ v = v.to_node if HTree::Location === v
+ case v
+ when Node
+ v
+ when String
+ Text.new(v)
+ else
+ raise TypeError, "invalid value: #{v.inspect}"
+ end
+ }
+ if !hash.include?(index)
+ hash[index] = []
+ end
+ hash[index].concat value
+ }
+
+ children_left = []
+ children = @children.dup
+ children_right = []
+
+ hash.keys.sort.each {|index|
+ value = hash[index]
+ if index < 0
+ children_left << value
+ elsif children.length <= index
+ children_right << value
+ else
+ children[index] = value
+ end
+ }
+
+ children = [children_left, children, children_right].flatten.compact
+ Doc.new(children)
+ end
+ end
+end
diff --git a/vendor/htree/htree/elem.rb b/vendor/htree/htree/elem.rb
new file mode 100644
index 0000000..61afa2f
--- /dev/null
+++ b/vendor/htree/htree/elem.rb
@@ -0,0 +1,262 @@
+require 'htree/modules'
+require 'htree/tag'
+require 'htree/context'
+require 'htree/container'
+
+module HTree
+ class Elem
+ # :stopdoc:
+ class << self
+ alias new! new
+ end
+ # :startdoc:
+
+ # The first argument _name_ should be an instance of String or HTree::Name.
+ #
+ # The rest of arguments should be a sequence of follows.
+ # [Hash object] used as attributes.
+ # [String object] specified string is converted to HTree::Text.
+ # [HTree::Node object] used as a child.
+ # [HTree::Doc object]
+ # used as children.
+ # It is expanded except HTree::XMLDecl and HTree::DocType objects.
+ # [Array of String, HTree::Node, HTree::Doc] used as children.
+ # [HTree::Context object]
+ # used as as context which represents XML namespaces.
+ # This should apper once at most.
+ #
+ # HTree::Location object is accepted just as HTree::Node.
+ #
+ # If the rest arguments consists only
+ # Hash and HTree::Context, empty element is created.
+ #
+ # p HTree::Elem.new("e").empty_element? # => true
+ # p HTree::Elem.new("e", []).empty_element? # => false
+ def Elem.new(name, *args)
+ attrs = []
+ children = []
+ context = nil
+ args.each {|arg|
+ arg = arg.to_node if HTree::Location === arg
+ case arg
+ when Context
+ raise ArgumentError, "multiple context" if context
+ context = arg
+ when Hash
+ arg.each {|k, v| attrs << [k, v] }
+ when Array
+ arg.each {|a|
+ a = a.to_node if HTree::Location === a
+ case a
+ when HTree::Doc
+ children.concat(a.children.reject {|c|
+ HTree::XMLDecl === c || HTree::DocType === c
+ })
+ when HTree::Node
+ children << a
+ when String
+ children << Text.new(a)
+ else
+ raise TypeError, "unexpected argument: #{arg.inspect}"
+ end
+ }
+ when HTree::Doc
+ children.concat(arg.children.reject {|c|
+ HTree::XMLDecl === c || HTree::DocType === c
+ })
+ when HTree::Node
+ children << arg
+ when String
+ children << Text.new(arg)
+
+ else
+ raise TypeError, "unexpected argument: #{arg.inspect}"
+ end
+ }
+ context ||= DefaultContext
+ if children.empty? && args.all? {|arg| Hash === arg || Context === arg }
+ children = nil
+ end
+ new!(STag.new(name, attrs, context), children)
+ end
+
+ def initialize(stag, children=nil, etag=nil) # :notnew:
+ unless stag.class == STag
+ raise TypeError, "HTree::STag expected: #{stag.inspect}"
+ end
+ unless !children || children.all? {|c| c.kind_of?(HTree::Node) and !c.kind_of?(HTree::Doc) }
+ unacceptable = children.reject {|c| c.kind_of?(HTree::Node) and !c.kind_of?(HTree::Doc) }
+ unacceptable = unacceptable.map {|uc| uc.inspect }.join(', ')
+ raise TypeError, "Unacceptable element child: #{unacceptable}"
+ end
+ unless !etag || etag.class == ETag
+ raise TypeError, "HTree::ETag expected: #{etag.inspect}"
+ end
+ @stag = stag
+ @children = (children ? children.dup : []).freeze
+ @empty = children == nil && etag == nil
+ @etag = etag
+ end
+
+ def context; @stag.context end
+
+ # +element_name+ returns the name of the element name as a Name object.
+ def element_name() @stag.element_name end
+
+ def empty_element?
+ @empty
+ end
+
+ def each_attribute(&block) # :yields: attr_name, attr_text
+ @stag.each_attribute(&block)
+ end
+
+ def get_subnode_internal(index) # :nodoc:
+ case index
+ when String
+ name = Name.parse_attribute_name(index, DefaultContext)
+ update_attribute_hash[name.universal_name]
+ when Name
+ update_attribute_hash[index.universal_name]
+ when Integer
+ if index < 0 || @children.length <= index
+ nil
+ else
+ @children[index]
+ end
+ else
+ raise TypeError, "invalid index: #{index.inspect}"
+ end
+ end
+
+ # call-seq:
+ # elem.subst_subnode(pairs) -> elem
+ #
+ # The argument _pairs_ should be a hash or an assocs.
+ #
+ # The key of pairs should be one of following.
+ # [HTree::Name or String object] attribute name.
+ # [Integer object] child index.
+ #
+ # The value of pairs should be one of follows.
+ # [HTree::Node object] specified object is used as is.
+ # [String object] specified string is converted to HTree::Text
+ # [Array of above] specified HTree::Node and String is used in that order.
+ # [nil] delete corresponding node.
+ #
+ # e = HTree('').root
+ # p e.subst_subnode({0=>HTree(''), 2=>HTree('')})
+ # p e.subst_subnode([[0, HTree('')], [2,HTree('')]])
+ # # =>
+ # {elem {emptyelem } {emptyelem } {emptyelem }}
+ # {elem {emptyelem } {emptyelem } {emptyelem }}
+ #
+ def subst_subnode(pairs)
+ hash = {}
+ pairs.each {|index, value|
+ case index
+ when Name, Integer
+ when String
+ index = Name.parse_attribute_name(index, DefaultContext)
+ else
+ raise TypeError, "invalid index: #{index.inspect}"
+ end
+ value = value.to_node if HTree::Location === value
+ case value
+ when Node
+ value = [value]
+ when String
+ value = [value]
+ when Array
+ value = value.dup
+ when nil
+ value = []
+ else
+ raise TypeError, "invalid value: #{value.inspect}"
+ end
+ value.map! {|v|
+ v = v.to_node if HTree::Location === v
+ case v
+ when Node
+ v
+ when String
+ Text.new(v)
+ else
+ raise TypeError, "invalid value: #{v.inspect}"
+ end
+ }
+ if !hash.include?(index)
+ hash[index] = []
+ end
+ hash[index].concat value
+ }
+
+ attrs = []
+ @stag.attributes.each {|k, v|
+ if hash.include? k
+ v = hash[k]
+ if !v.empty?
+ attrs << {k=>Text.concat(*v)}
+ end
+ hash.delete k
+ else
+ attrs << {k=>v}
+ end
+ }
+ hash.keys.each {|k|
+ if Name === k
+ v = hash[k]
+ if !v.empty?
+ attrs << {k=>Text.concat(*v)}
+ end
+ hash.delete k
+ end
+ }
+
+ children_left = []
+ children = @children.dup
+ children_right = []
+
+ hash.keys.sort.each {|index|
+ value = hash[index]
+ if index < 0
+ children_left << value
+ elsif children.length <= index
+ children_right << value
+ else
+ children[index] = value
+ end
+ }
+
+ children = [children_left, children, children_right].flatten
+
+ if children.empty? && @empty
+ Elem.new(
+ @stag.element_name,
+ @stag.context,
+ *attrs)
+ else
+ Elem.new(
+ @stag.element_name,
+ @stag.context,
+ children,
+ *attrs)
+ end
+ end
+ end
+
+ module Elem::Trav
+ private
+ def update_attribute_hash
+ if defined?(@attribute_hash)
+ @attribute_hash
+ else
+ h = {}
+ each_attribute {|name, text|
+ h[name.universal_name] = text
+ }
+ @attribute_hash = h
+ end
+ end
+ end
+end
diff --git a/vendor/htree/htree/encoder.rb b/vendor/htree/htree/encoder.rb
new file mode 100644
index 0000000..7840260
--- /dev/null
+++ b/vendor/htree/htree/encoder.rb
@@ -0,0 +1,212 @@
+require 'iconv'
+
+module HTree
+ class Encoder
+ # HTree::Encoder.internal_charset returns the MIME charset corresponding to $KCODE.
+ #
+ # - 'ISO-8859-1' when $KCODE=='NONE'
+ # - 'UTF-8' when $KCODE=='UTF8'
+ # - 'EUC-JP' when $KCODE=='EUC'
+ # - 'Shift_JIS' when $KCODE=='SJIS'
+ #
+ # This mapping ignores EUC-KR and various single byte charset other than ISO-8859-1 at least.
+ # This should be fixed when Ruby is m17nized.
+ def Encoder.internal_charset
+ KcodeCharset[$KCODE]
+ end
+
+ def initialize(output_encoding, internal_encoding=HTree::Encoder.internal_charset)
+ @buf = ''
+ @internal_encoding = internal_encoding
+ @output_encoding = output_encoding
+ @ic = Iconv.new(output_encoding, @internal_encoding)
+ @charpat = FirstCharPattern[internal_encoding]
+
+ @subcharset_list = SubCharset[output_encoding] || []
+ @subcharset_ic = {}
+ @subcharset_list.each {|subcharset|
+ @subcharset_ic[subcharset] = Iconv.new(subcharset, @internal_encoding)
+ }
+ @html_output = false
+ end
+
+ # :stopdoc:
+ def html_output?
+ @html_output
+ end
+
+ def html_output=(flag)
+ @html_output = flag
+ end
+
+ def output_cdata_content_do(out, pre, body, post)
+ if @html_output
+ pre.call
+ body.call
+ post.call(out)
+ else
+ body.call
+ end
+ return out
+ end
+
+ def output_slash_if_xml
+ if !@html_output
+ output_string('/')
+ end
+ end
+
+ def output_cdata_content(content, context)
+ if @html_output
+ # xxx: should raise an error for non-text node?
+ texts = content.grep(HTree::Text)
+ text = HTree::Text.concat(*texts)
+ text.output_cdata(self)
+ else
+ content.each {|n| n.output(self, context) }
+ end
+ end
+
+ def output_cdata_for_html(*args)
+ str = args.join('')
+ if %r{} =~ str
+ raise ArgumentError, "cdata contains '' : #{str.inspect}"
+ end
+ output_string str
+ end
+
+ def output_string(internal_str, external_str=@ic.iconv(internal_str))
+ @buf << external_str
+ @subcharset_ic.reject! {|subcharset, ic|
+ begin
+ ic.iconv(internal_str) != external_str
+ rescue Iconv::Failure
+ true
+ end
+ }
+ nil
+ end
+
+ def output_text(string)
+ begin
+ output_string string, @ic.iconv(string)
+ rescue Iconv::IllegalSequence, Iconv::InvalidCharacter => e
+ output_string string[0, string.length - e.failed.length], e.success
+ unless @charpat =~ e.failed
+ # xxx: should be configulable?
+ #raise ArgumentError, "cannot extract first character: #{e.failed.dump}"
+ string = e.failed[1, e.failed.length-1]
+ output_string '?'
+ retry
+ end
+ char = $&
+ rest = $'
+ begin
+ ucode = Iconv.conv("UTF-8", @internal_encoding, char).unpack("U")[0]
+ char = "#{ucode};"
+ rescue Iconv::IllegalSequence, Iconv::InvalidCharacter
+ # xxx: should be configulable?
+ char = '?'
+ end
+ output_string char
+ string = rest
+ retry
+ end
+ end
+
+ ChRef = {
+ '&' => '&',
+ '<' => '<',
+ '>' => '>',
+ '"' => '"',
+ }
+
+ def output_dynamic_text(string)
+ if string.respond_to? :rcdata
+ output_text(string.rcdata.gsub(/[<>]/) { ChRef[$&] })
+ else
+ output_text(string.to_s.gsub(/[&<>]/) { ChRef[$&] })
+ end
+ end
+
+ def output_dynamic_attvalue(string)
+ if string.respond_to? :rcdata
+ output_text(string.rcdata.gsub(/[<>"]/) { ChRef[$&] })
+ else
+ output_text(string.to_s.gsub(/[&<>"]/) { ChRef[$&] })
+ end
+ end
+
+ # :startdoc:
+
+ def finish
+ external_str = @ic.close
+ @buf << external_str
+ @subcharset_ic.reject! {|subcharset, ic|
+ begin
+ ic.close != external_str
+ rescue Iconv::Failure
+ true
+ end
+ }
+ @buf
+ end
+
+ def finish_with_xmldecl
+ content = finish
+ xmldecl = Iconv.conv(@output_encoding, 'US-ASCII',
+ "")
+ xmldecl + content
+ end
+
+ def minimal_charset
+ @subcharset_list.each {|subcharset|
+ if @subcharset_ic.include? subcharset
+ return subcharset
+ end
+ }
+ @output_encoding
+ end
+
+ # :stopdoc:
+
+ KcodeCharset = {
+ 'EUC' => 'EUC-JP',
+ 'SJIS' => 'Shift_JIS',
+ 'UTF8' => 'UTF-8',
+ 'NONE' => 'ISO-8859-1',
+ }
+
+ FirstCharPattern = {
+ 'EUC-JP' => /\A(?:
+ [\x00-\x7f]
+ |[\xa1-\xfe][\xa1-\xfe]
+ |\x8e[\xa1-\xfe]
+ |\x8f[\xa1-\xfe][\xa1-\xfe])/nx,
+ 'Shift_JIS' => /\A(?:
+ [\x00-\x7f]
+ |[\x81-\x9f][\x40-\x7e\x80-\xfc]
+ |[\xa1-\xdf]
+ |[\xe0-\xfc][\x40-\x7e\x80-\xfc])/nx,
+ 'UTF-8' => /\A(?:
+ [\x00-\x7f]
+ |[\xc0-\xdf][\x80-\xbf]
+ |[\xe0-\xef][\x80-\xbf][\x80-\xbf]
+ |[\xf0-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]
+ |[\xf8-\xfb][\x80-\xbf][\x80-\xbf][\x80-\xbf][\x80-\xbf]
+ |[\xfc-\xfd][\x80-\xbf][\x80-\xbf][\x80-\xbf][\x80-\xbf][\x80-\xbf])/nx,
+ 'ISO-8859-1' => /\A[\x00-\xff]/n
+ }
+
+ SubCharset = {
+ 'ISO-2022-JP-2' => ['US-ASCII', 'ISO-2022-JP'],
+ 'ISO-2022-JP-3' => ['US-ASCII', 'ISO-2022-JP'],
+ 'UTF-16BE' => [],
+ 'UTF-16LE' => [],
+ 'UTF-16' => [],
+ }
+ SubCharset.default = ['US-ASCII']
+
+ # :startdoc:
+ end
+end
diff --git a/vendor/htree/htree/equality.rb b/vendor/htree/htree/equality.rb
new file mode 100644
index 0000000..4595cca
--- /dev/null
+++ b/vendor/htree/htree/equality.rb
@@ -0,0 +1,219 @@
+require 'htree/doc'
+require 'htree/elem'
+require 'htree/leaf'
+require 'htree/tag'
+require 'htree/raw_string'
+require 'htree/context'
+
+module HTree
+ # compare tree structures.
+ def ==(other)
+ check_equality(self, other, :usual_equal_object)
+ end
+ alias eql? ==
+
+ # hash value for the tree structure.
+ def hash
+ return @hash_code if defined? @hash_code
+ @hash_code = usual_equal_object.hash
+ end
+
+ # :stopdoc:
+
+ def usual_equal_object
+ return @usual_equal_object if defined? @usual_equal_object
+ @usual_equal_object = make_usual_equal_object
+ end
+
+ def make_usual_equal_object
+ raise NotImplementedError
+ end
+
+ def exact_equal_object
+ return @exact_equal_object if defined? @exact_equal_object
+ @exact_equal_object = make_exact_equal_object
+ end
+
+ def make_exact_equal_object
+ raise NotImplementedError
+ end
+
+ def exact_equal?(other)
+ check_equality(self, other, :exact_equal_object)
+ end
+
+ def check_equality(obj1, obj2, equal_object_method)
+ return false unless obj1.class == obj2.class
+ if obj1.class == Array
+ return false unless obj1.length == obj2.length
+ obj1.each_with_index {|c1, i|
+ return false unless c1.class == obj2[i].class
+ }
+ obj1.each_with_index {|c1, i|
+ return false unless check_equality(c1, obj2[i], equal_object_method)
+ }
+ true
+ elsif obj1.respond_to? equal_object_method
+ o1 = obj1.send(equal_object_method)
+ o2 = obj2.send(equal_object_method)
+ check_equality(o1, o2, equal_object_method)
+ else
+ obj1 == obj2
+ end
+ end
+
+ class Doc
+ alias exact_equal_object children
+ alias usual_equal_object children
+ end
+
+ class Elem
+ def make_exact_equal_object
+ [@stag, @children, @empty, @etag]
+ end
+
+ def make_usual_equal_object
+ [@stag, @children]
+ end
+ end
+
+ class Name
+ def make_exact_equal_object
+ [@namespace_prefix, @namespace_uri, @local_name]
+ end
+
+ def make_usual_equal_object
+ xmlns? ? @local_name : [@namespace_uri, @local_name]
+ end
+ end
+
+ module Util
+ module_function
+ def cmp_with_nil(a, b)
+ if a == nil
+ if b == nil
+ 0
+ else
+ -1
+ end
+ else
+ if b == nil
+ 1
+ else
+ a <=> b
+ end
+ end
+ end
+ end
+
+ class Context
+ def make_exact_equal_object
+ @namespaces.keys.sort {|prefix1, prefix2|
+ Util.cmp_with_nil(prefix1, prefix2)
+ }.map {|prefix| [prefix, @namespaces[prefix]] }
+ end
+
+ # make_usual_equal_object is not used through STag#make_usual_equal_object
+ # NotImplementedError is suitable?
+ alias make_usual_equal_object make_exact_equal_object
+ end
+
+ class STag
+ def make_exact_equal_object
+ [@raw_string,
+ @name,
+ @attributes.sort {|(n1,t1), (n2, t2)|
+ Util.cmp_with_nil(n1.namespace_prefix, n2.namespace_prefix).nonzero? ||
+ Util.cmp_with_nil(n1.namespace_uri, n2.namespace_uri).nonzero? ||
+ Util.cmp_with_nil(n1.local_name, n2.local_name)
+ },
+ @inherited_context
+ ]
+ end
+
+ def make_usual_equal_object
+ [@name,
+ @attributes.find_all {|n,t| !n.xmlns? }.sort {|(n1,t1), (n2, t2)|
+ Util.cmp_with_nil(n1.namespace_prefix, n2.namespace_prefix).nonzero? ||
+ Util.cmp_with_nil(n1.namespace_uri, n2.namespace_uri).nonzero? ||
+ Util.cmp_with_nil(n1.local_name, n2.local_name)
+ }
+ ]
+ end
+
+ end
+
+ class ETag
+ def make_exact_equal_object
+ [@raw_string, @qualified_name]
+ end
+
+ alias usual_equal_object qualified_name
+ end
+
+ class Text
+ def make_exact_equal_object
+ [@raw_string, @rcdata]
+ end
+
+ def make_usual_equal_object
+ @normalized_rcdata
+ end
+ end
+
+ class XMLDecl
+ def make_exact_equal_object
+ [@raw_string, @version, @encoding, @standalone]
+ end
+
+ def make_usual_equal_object
+ [@version, @encoding, @standalone]
+ end
+ end
+
+ class DocType
+ def make_exact_equal_object
+ [@raw_string, @root_element_name, @system_identifier, @public_identifier]
+ end
+
+ def make_usual_equal_object
+ [@root_element_name, @system_identifier, @public_identifier]
+ end
+ end
+
+ class ProcIns
+ def make_exact_equal_object
+ [@raw_string, @target, @content]
+ end
+
+ def make_usual_equal_object
+ [@target, @content]
+ end
+ end
+
+ class Comment
+ def make_exact_equal_object
+ [@raw_string, @content]
+ end
+
+ alias usual_equal_object content
+ end
+
+ class BogusETag
+ def make_exact_equal_object
+ [@etag]
+ end
+
+ alias usual_equal_object make_exact_equal_object
+ end
+
+ class Location
+ def make_exact_equal_object
+ [@parent, @index, @node]
+ end
+
+ alias usual_equal_object make_exact_equal_object
+ end
+
+ # :startdoc:
+end
diff --git a/vendor/htree/htree/extract_text.rb b/vendor/htree/htree/extract_text.rb
new file mode 100644
index 0000000..711f9f4
--- /dev/null
+++ b/vendor/htree/htree/extract_text.rb
@@ -0,0 +1,37 @@
+require 'htree/text'
+require 'htree/doc'
+require 'htree/elem'
+
+module HTree
+ module Node
+ def extract_text
+ raise NotImplementedError
+ end
+ end
+
+ class Location
+ def extract_text
+ to_node.extract_text
+ end
+ end
+
+ # :stopdoc:
+ module Container
+ def extract_text
+ Text.concat(*@children.map {|n| n.extract_text })
+ end
+ end
+
+ module Leaf
+ def extract_text
+ Text.new('')
+ end
+ end
+
+ class Text
+ def extract_text
+ self
+ end
+ end
+ # :startdoc:
+end
diff --git a/vendor/htree/htree/fstr.rb b/vendor/htree/htree/fstr.rb
new file mode 100644
index 0000000..a731c3d
--- /dev/null
+++ b/vendor/htree/htree/fstr.rb
@@ -0,0 +1,32 @@
+require 'htree/modules'
+
+module HTree
+ # :stopdoc:
+ def HTree.with_frozen_string_hash
+ if Thread.current[:htree_frozen_string_hash]
+ yield
+ else
+ begin
+ Thread.current[:htree_frozen_string_hash] = {}
+ yield
+ ensure
+ Thread.current[:htree_frozen_string_hash] = nil
+ end
+ end
+ end
+
+ def HTree.frozen_string(str)
+ if h = Thread.current[:htree_frozen_string_hash]
+ if s = h[str]
+ s
+ else
+ str = str.dup.freeze unless str.frozen?
+ h[str] = str
+ end
+ else
+ str = str.dup.freeze unless str.frozen?
+ str
+ end
+ end
+ # :startdoc:
+end
diff --git a/vendor/htree/htree/gencode.rb b/vendor/htree/htree/gencode.rb
new file mode 100644
index 0000000..dde5df3
--- /dev/null
+++ b/vendor/htree/htree/gencode.rb
@@ -0,0 +1,193 @@
+require 'htree/encoder'
+require 'htree/output'
+
+# :stopdoc:
+
+module HTree
+ module Node
+ def generate_xml_output_code(outvar='out', contextvar='top_context')
+ namespaces = HTree::Context::DefaultNamespaces.dup
+ namespaces.default = nil
+ context = Context.new(namespaces)
+ gen = HTree::GenCode.new(outvar, contextvar)
+ output(gen, context)
+ gen.finish
+ end
+ end
+
+ class GenCode
+ def initialize(outvar, contextvar, internal_encoding=Encoder.internal_charset)
+ @outvar = outvar
+ @contextvar = contextvar
+ @state = :none
+ @buffer = ''
+ @internal_encoding = internal_encoding
+ @code = ''
+ @html_output = nil
+ end
+ attr_reader :outvar, :contextvar
+
+ def html_output?
+ @html_output
+ end
+
+ def html_output=(flag)
+ @html_output = flag
+ end
+
+ class CDATABuffer
+ def initialize
+ @buf = ''
+ end
+
+ def html_output?
+ true
+ end
+
+ def not_valid_for_html_cdata(*args)
+ raise ArgumentError, "CDATA content only accept texts."
+ end
+ alias output_slash_if_xml not_valid_for_html_cdata
+ alias output_cdata_content not_valid_for_html_cdata
+ alias output_dynamic_attvalue not_valid_for_html_cdata
+
+ def output_string(string)
+ @buf << string
+ end
+
+ def output_text(string)
+ @buf << string
+ end
+
+ ChRef = {
+ '&' => '&',
+ '<' => '<',
+ '>' => '>',
+ '"' => '"',
+ }
+
+ def output_dynamic_text(string)
+ if string.respond_to? :rcdata
+ @buf << string.rcdata.gsub(/[<>]/) { ChRef[$&] }
+ else
+ @buf << string.to_s.gsub(/[&<>]/) { ChRef[$&] }
+ end
+ end
+
+ def result
+ if %r{[<>]} =~ @buf
+ raise ArgumentError, "cdata contains non-text : #{@buf.inspect}"
+ end
+ str = HTree::Text.parse_pcdata(@buf).to_s
+ if %r{} =~ str
+ raise ArgumentError, "cdata contains '' : #{str.inspect}"
+ end
+ str
+ end
+ end
+
+ def output_cdata_content(content, context)
+ tmp_outvar = @outvar + '_tmp'
+ output_logic_line "#{@outvar} = #{@outvar}.output_cdata_content_do(#{@outvar},"
+ output_logic_line "lambda { #{@outvar} = HTree::GenCode::CDATABuffer.new },"
+ output_logic_line "lambda {"
+ content.each {|n| n.output(self, context) }
+ output_logic_line "},"
+ output_logic_line "lambda {|#{tmp_outvar}| #{tmp_outvar}.output_string(#{@outvar}.result) })"
+ end
+
+ def output_slash_if_xml
+ output_logic_line "#{@outvar}.output_slash_if_xml"
+ end
+
+ def output_dynamic_text(expr)
+ flush_buffer
+ @code << "#{@outvar}.output_dynamic_text((#{expr}))\n"
+ end
+
+ def output_dynamic_tree(expr, context_expr)
+ flush_buffer
+ @code << "(#{expr}).output(#{@outvar}, #{context_expr})\n"
+ end
+
+ def output_dynamic_attvalue(expr)
+ flush_buffer
+ @code << "#{@outvar}.output_dynamic_attvalue((#{expr}))\n"
+ end
+
+ def output_logic_line(line)
+ flush_buffer
+ @code << line << "\n"
+ end
+
+ def output_string(str)
+ return if str.empty?
+ if @state != :string
+ flush_buffer
+ @state = :string
+ end
+ @buffer << str
+ end
+
+ def output_text(str)
+ return if str.empty?
+ if /\A[\s\x21-\x7e]+\z/ =~ str && @state == :string
+ # Assumption: external charset can represent white spaces and
+ # ASCII printable.
+ output_string(str)
+ return
+ end
+ if @state != :text
+ flush_buffer
+ @state = :text
+ end
+ @buffer << str
+ end
+
+ ChRef = {
+ '&' => '&',
+ '>' => '>',
+ '<' => '<',
+ '"' => '"',
+ }
+ def output_xmlns(namespaces)
+ unless namespaces.empty?
+ flush_buffer
+ namespaces.each {|k, v|
+ if k
+ ks = k.dump
+ aname = "xmlns:#{k}"
+ else
+ ks = "nil"
+ aname = "xmlns"
+ end
+ @code << "if #{@contextvar}.namespace_uri(#{ks}) != #{v.dump}\n"
+ output_string " #{aname}=\""
+ output_text v.gsub(/[&<>"]/) {|s| ChRef[s] }
+ output_string '"'
+ flush_buffer
+ @code << "end\n"
+ }
+ end
+ end
+
+ def flush_buffer
+ return if @buffer.empty?
+ case @state
+ when :string
+ @code << "#{@outvar}.output_string #{@buffer.dump}\n"
+ @buffer = ''
+ when :text
+ @code << "#{@outvar}.output_text #{@buffer.dump}\n"
+ @buffer = ''
+ end
+ end
+
+ def finish
+ flush_buffer
+ @code
+ end
+ end
+end
+
+# :startdoc:
diff --git a/vendor/htree/htree/htmlinfo.rb b/vendor/htree/htree/htmlinfo.rb
new file mode 100644
index 0000000..d4206c2
--- /dev/null
+++ b/vendor/htree/htree/htmlinfo.rb
@@ -0,0 +1,672 @@
+module HTree
+# The code below is auto-generated. Don't edit manually.
+ # :stopdoc:
+ NamedCharacters =
+{"AElig"=>198, "Aacute"=>193, "Acirc"=>194, "Agrave"=>192, "Alpha"=>913,
+ "Aring"=>197, "Atilde"=>195, "Auml"=>196, "Beta"=>914, "Ccedil"=>199,
+ "Chi"=>935, "Dagger"=>8225, "Delta"=>916, "ETH"=>208, "Eacute"=>201,
+ "Ecirc"=>202, "Egrave"=>200, "Epsilon"=>917, "Eta"=>919, "Euml"=>203,
+ "Gamma"=>915, "Iacute"=>205, "Icirc"=>206, "Igrave"=>204, "Iota"=>921,
+ "Iuml"=>207, "Kappa"=>922, "Lambda"=>923, "Mu"=>924, "Ntilde"=>209, "Nu"=>925,
+ "OElig"=>338, "Oacute"=>211, "Ocirc"=>212, "Ograve"=>210, "Omega"=>937,
+ "Omicron"=>927, "Oslash"=>216, "Otilde"=>213, "Ouml"=>214, "Phi"=>934,
+ "Pi"=>928, "Prime"=>8243, "Psi"=>936, "Rho"=>929, "Scaron"=>352, "Sigma"=>931,
+ "THORN"=>222, "Tau"=>932, "Theta"=>920, "Uacute"=>218, "Ucirc"=>219,
+ "Ugrave"=>217, "Upsilon"=>933, "Uuml"=>220, "Xi"=>926, "Yacute"=>221,
+ "Yuml"=>376, "Zeta"=>918, "aacute"=>225, "acirc"=>226, "acute"=>180,
+ "aelig"=>230, "agrave"=>224, "alefsym"=>8501, "alpha"=>945, "amp"=>38,
+ "and"=>8743, "ang"=>8736, "apos"=>39, "aring"=>229, "asymp"=>8776,
+ "atilde"=>227, "auml"=>228, "bdquo"=>8222, "beta"=>946, "brvbar"=>166,
+ "bull"=>8226, "cap"=>8745, "ccedil"=>231, "cedil"=>184, "cent"=>162,
+ "chi"=>967, "circ"=>710, "clubs"=>9827, "cong"=>8773, "copy"=>169,
+ "crarr"=>8629, "cup"=>8746, "curren"=>164, "dArr"=>8659, "dagger"=>8224,
+ "darr"=>8595, "deg"=>176, "delta"=>948, "diams"=>9830, "divide"=>247,
+ "eacute"=>233, "ecirc"=>234, "egrave"=>232, "empty"=>8709, "emsp"=>8195,
+ "ensp"=>8194, "epsilon"=>949, "equiv"=>8801, "eta"=>951, "eth"=>240,
+ "euml"=>235, "euro"=>8364, "exist"=>8707, "fnof"=>402, "forall"=>8704,
+ "frac12"=>189, "frac14"=>188, "frac34"=>190, "frasl"=>8260, "gamma"=>947,
+ "ge"=>8805, "gt"=>62, "hArr"=>8660, "harr"=>8596, "hearts"=>9829,
+ "hellip"=>8230, "iacute"=>237, "icirc"=>238, "iexcl"=>161, "igrave"=>236,
+ "image"=>8465, "infin"=>8734, "int"=>8747, "iota"=>953, "iquest"=>191,
+ "isin"=>8712, "iuml"=>239, "kappa"=>954, "lArr"=>8656, "lambda"=>955,
+ "lang"=>9001, "laquo"=>171, "larr"=>8592, "lceil"=>8968, "ldquo"=>8220,
+ "le"=>8804, "lfloor"=>8970, "lowast"=>8727, "loz"=>9674, "lrm"=>8206,
+ "lsaquo"=>8249, "lsquo"=>8216, "lt"=>60, "macr"=>175, "mdash"=>8212,
+ "micro"=>181, "middot"=>183, "minus"=>8722, "mu"=>956, "nabla"=>8711,
+ "nbsp"=>160, "ndash"=>8211, "ne"=>8800, "ni"=>8715, "not"=>172, "notin"=>8713,
+ "nsub"=>8836, "ntilde"=>241, "nu"=>957, "oacute"=>243, "ocirc"=>244,
+ "oelig"=>339, "ograve"=>242, "oline"=>8254, "omega"=>969, "omicron"=>959,
+ "oplus"=>8853, "or"=>8744, "ordf"=>170, "ordm"=>186, "oslash"=>248,
+ "otilde"=>245, "otimes"=>8855, "ouml"=>246, "para"=>182, "part"=>8706,
+ "permil"=>8240, "perp"=>8869, "phi"=>966, "pi"=>960, "piv"=>982,
+ "plusmn"=>177, "pound"=>163, "prime"=>8242, "prod"=>8719, "prop"=>8733,
+ "psi"=>968, "quot"=>34, "rArr"=>8658, "radic"=>8730, "rang"=>9002,
+ "raquo"=>187, "rarr"=>8594, "rceil"=>8969, "rdquo"=>8221, "real"=>8476,
+ "reg"=>174, "rfloor"=>8971, "rho"=>961, "rlm"=>8207, "rsaquo"=>8250,
+ "rsquo"=>8217, "sbquo"=>8218, "scaron"=>353, "sdot"=>8901, "sect"=>167,
+ "shy"=>173, "sigma"=>963, "sigmaf"=>962, "sim"=>8764, "spades"=>9824,
+ "sub"=>8834, "sube"=>8838, "sum"=>8721, "sup"=>8835, "sup1"=>185, "sup2"=>178,
+ "sup3"=>179, "supe"=>8839, "szlig"=>223, "tau"=>964, "there4"=>8756,
+ "theta"=>952, "thetasym"=>977, "thinsp"=>8201, "thorn"=>254, "tilde"=>732,
+ "times"=>215, "trade"=>8482, "uArr"=>8657, "uacute"=>250, "uarr"=>8593,
+ "ucirc"=>251, "ugrave"=>249, "uml"=>168, "upsih"=>978, "upsilon"=>965,
+ "uuml"=>252, "weierp"=>8472, "xi"=>958, "yacute"=>253, "yen"=>165,
+ "yuml"=>255, "zeta"=>950, "zwj"=>8205, "zwnj"=>8204}
+
+
+ NamedCharactersPattern = /\A(?-mix:AElig|Aacute|Acirc|Agrave|Alpha|Aring|Atilde|Auml|Beta|Ccedil|Chi|Dagger|Delta|ETH|Eacute|Ecirc|Egrave|Epsilon|Eta|Euml|Gamma|Iacute|Icirc|Igrave|Iota|Iuml|Kappa|Lambda|Mu|Ntilde|Nu|OElig|Oacute|Ocirc|Ograve|Omega|Omicron|Oslash|Otilde|Ouml|Phi|Pi|Prime|Psi|Rho|Scaron|Sigma|THORN|Tau|Theta|Uacute|Ucirc|Ugrave|Upsilon|Uuml|Xi|Yacute|Yuml|Zeta|aacute|acirc|acute|aelig|agrave|alefsym|alpha|amp|and|ang|apos|aring|asymp|atilde|auml|bdquo|beta|brvbar|bull|cap|ccedil|cedil|cent|chi|circ|clubs|cong|copy|crarr|cup|curren|dArr|dagger|darr|deg|delta|diams|divide|eacute|ecirc|egrave|empty|emsp|ensp|epsilon|equiv|eta|eth|euml|euro|exist|fnof|forall|frac12|frac14|frac34|frasl|gamma|ge|gt|hArr|harr|hearts|hellip|iacute|icirc|iexcl|igrave|image|infin|int|iota|iquest|isin|iuml|kappa|lArr|lambda|lang|laquo|larr|lceil|ldquo|le|lfloor|lowast|loz|lrm|lsaquo|lsquo|lt|macr|mdash|micro|middot|minus|mu|nabla|nbsp|ndash|ne|ni|not|notin|nsub|ntilde|nu|oacute|ocirc|oelig|ograve|oline|omega|omicron|oplus|or|ordf|ordm|oslash|otilde|otimes|ouml|para|part|permil|perp|phi|pi|piv|plusmn|pound|prime|prod|prop|psi|quot|rArr|radic|rang|raquo|rarr|rceil|rdquo|real|reg|rfloor|rho|rlm|rsaquo|rsquo|sbquo|scaron|sdot|sect|shy|sigma|sigmaf|sim|spades|sub|sube|sum|sup|sup1|sup2|sup3|supe|szlig|tau|there4|theta|thetasym|thinsp|thorn|tilde|times|trade|uArr|uacute|uarr|ucirc|ugrave|uml|upsih|upsilon|uuml|weierp|xi|yacute|yen|yuml|zeta|zwj|zwnj)\z/
+
+ ElementContent =
+{"h6"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "object"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "param", "pre", "q",
+ "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "dl"=>["dd", "dt"],
+ "p"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "acronym"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "code"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "ul"=>["li"],
+ "tt"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "label"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "form"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "q"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "thead"=>["tr"],
+ "area"=>:EMPTY,
+ "td"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "title"=>[],
+ "dir"=>["li"],
+ "s"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "ol"=>["li"],
+ "hr"=>:EMPTY,
+ "applet"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "param", "pre", "q",
+ "s", "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "table"=>["caption", "col", "colgroup", "tbody", "tfoot", "thead", "tr"],
+ "legend"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "cite"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "a"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "html"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "base", "basefont", "bdo",
+ "big", "blockquote", "body", "br", "button", "center", "cite", "code",
+ "dfn", "dir", "div", "dl", "em", "fieldset", "font", "form", "h1", "h2",
+ "h3", "h4", "h5", "h6", "head", "hr", "i", "iframe", "img", "input",
+ "isindex", "kbd", "label", "map", "menu", "noframes", "noscript", "object",
+ "ol", "p", "pre", "q", "s", "samp", "script", "select", "small", "span",
+ "strike", "strong", "sub", "sup", "table", "textarea", "title", "tt", "u",
+ "ul", "var"],
+ "u"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "blockquote"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "center"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "b"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "base"=>:EMPTY,
+ "th"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "link"=>:EMPTY,
+ "var"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "samp"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "div"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "textarea"=>[],
+ "pre"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "head"=>["base", "isindex", "title"],
+ "span"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "br"=>:EMPTY,
+ "script"=>:CDATA,
+ "noframes"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "style"=>:CDATA,
+ "meta"=>:EMPTY,
+ "dt"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "option"=>[],
+ "kbd"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "big"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "tfoot"=>["tr"],
+ "sup"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "bdo"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "isindex"=>:EMPTY,
+ "dfn"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "fieldset"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "legend",
+ "map", "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "em"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "font"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "tbody"=>["tr"],
+ "noscript"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "li"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "col"=>:EMPTY,
+ "small"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "dd"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "i"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "menu"=>["li"],
+ "strong"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "basefont"=>:EMPTY,
+ "img"=>:EMPTY,
+ "optgroup"=>["option"],
+ "map"=>
+ ["address", "area", "blockquote", "center", "dir", "div", "dl", "fieldset",
+ "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "isindex", "menu",
+ "noframes", "noscript", "ol", "p", "pre", "table", "ul"],
+ "h1"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "address"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "p", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "sub"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "param"=>:EMPTY,
+ "input"=>:EMPTY,
+ "h2"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "abbr"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "h3"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "strike"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "body"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "ins"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "button"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "h4"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "select"=>["optgroup", "option"],
+ "caption"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "colgroup"=>["col"],
+ "tr"=>["td", "th"],
+ "del"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"],
+ "h5"=>
+ ["a", "abbr", "acronym", "applet", "b", "basefont", "bdo", "big", "br",
+ "button", "cite", "code", "dfn", "em", "font", "i", "iframe", "img",
+ "input", "kbd", "label", "map", "object", "q", "s", "samp", "script",
+ "select", "small", "span", "strike", "strong", "sub", "sup", "textarea",
+ "tt", "u", "var"],
+ "iframe"=>
+ ["a", "abbr", "acronym", "address", "applet", "b", "basefont", "bdo", "big",
+ "blockquote", "br", "button", "center", "cite", "code", "dfn", "dir", "div",
+ "dl", "em", "fieldset", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "i", "iframe", "img", "input", "isindex", "kbd", "label", "map",
+ "menu", "noframes", "noscript", "object", "ol", "p", "pre", "q", "s",
+ "samp", "script", "select", "small", "span", "strike", "strong", "sub",
+ "sup", "table", "textarea", "tt", "u", "ul", "var"]}
+
+ ElementInclusions =
+{"head"=>["link", "meta", "object", "script", "style"], "body"=>["del", "ins"]}
+
+ ElementExclusions =
+{"button"=>
+ ["a", "button", "fieldset", "form", "iframe", "input", "isindex", "label",
+ "select", "textarea"],
+ "a"=>["a"],
+ "dir"=>
+ ["address", "blockquote", "center", "dir", "div", "dl", "fieldset", "form",
+ "h1", "h2", "h3", "h4", "h5", "h6", "hr", "isindex", "menu", "noframes",
+ "noscript", "ol", "p", "pre", "table", "ul"],
+ "title"=>["link", "meta", "object", "script", "style"],
+ "pre"=>
+ ["applet", "basefont", "big", "font", "img", "object", "small", "sub",
+ "sup"],
+ "form"=>["form"],
+ "menu"=>
+ ["address", "blockquote", "center", "dir", "div", "dl", "fieldset", "form",
+ "h1", "h2", "h3", "h4", "h5", "h6", "hr", "isindex", "menu", "noframes",
+ "noscript", "ol", "p", "pre", "table", "ul"],
+ "label"=>["label"]}
+
+ OmittedAttrName =
+{"h6"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "object"=>
+ {"bottom"=>"align", "declare"=>"declare", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"align", "right"=>"align", "rtl"=>"dir", "top"=>"align"},
+ "dl"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"},
+ "p"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "acronym"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "code"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "ul"=>
+ {"circle"=>"type", "compact"=>"compact", "disc"=>"type", "ltr"=>"dir",
+ "rtl"=>"dir", "square"=>"type"},
+ "tt"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "label"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "form"=>{"get"=>"method", "ltr"=>"dir", "post"=>"method", "rtl"=>"dir"},
+ "q"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "thead"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"},
+ "area"=>
+ {"circle"=>"shape", "default"=>"shape", "ltr"=>"dir", "nohref"=>"nohref",
+ "poly"=>"shape", "rect"=>"shape", "rtl"=>"dir"},
+ "td"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "col"=>"scope", "colgroup"=>"scope", "justify"=>"align",
+ "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "nowrap"=>"nowrap",
+ "right"=>"align", "row"=>"scope", "rowgroup"=>"scope", "rtl"=>"dir",
+ "top"=>"valign"},
+ "title"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "dir"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"},
+ "s"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "ol"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"},
+ "hr"=>
+ {"center"=>"align", "left"=>"align", "ltr"=>"dir", "noshade"=>"noshade",
+ "right"=>"align", "rtl"=>"dir"},
+ "applet"=>
+ {"bottom"=>"align", "left"=>"align", "middle"=>"align", "right"=>"align",
+ "top"=>"align"},
+ "table"=>
+ {"above"=>"frame", "all"=>"rules", "below"=>"frame", "border"=>"frame",
+ "box"=>"frame", "center"=>"align", "cols"=>"rules", "groups"=>"rules",
+ "hsides"=>"frame", "left"=>"align", "lhs"=>"frame", "ltr"=>"dir",
+ "none"=>"rules", "rhs"=>"frame", "right"=>"align", "rows"=>"rules",
+ "rtl"=>"dir", "void"=>"frame", "vsides"=>"frame"},
+ "legend"=>
+ {"bottom"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align",
+ "rtl"=>"dir", "top"=>"align"},
+ "cite"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "a"=>
+ {"circle"=>"shape", "default"=>"shape", "ltr"=>"dir", "poly"=>"shape",
+ "rect"=>"shape", "rtl"=>"dir"},
+ "html"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "u"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "blockquote"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "center"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "b"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "th"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "col"=>"scope", "colgroup"=>"scope", "justify"=>"align",
+ "left"=>"align", "ltr"=>"dir", "middle"=>"valign", "nowrap"=>"nowrap",
+ "right"=>"align", "row"=>"scope", "rowgroup"=>"scope", "rtl"=>"dir",
+ "top"=>"valign"},
+ "link"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "var"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "samp"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "div"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "textarea"=>
+ {"disabled"=>"disabled", "ltr"=>"dir", "readonly"=>"readonly", "rtl"=>"dir"},
+ "pre"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "head"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "span"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "br"=>{"all"=>"clear", "left"=>"clear", "none"=>"clear", "right"=>"clear"},
+ "script"=>{"defer"=>"defer"},
+ "noframes"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "style"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "meta"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "dt"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "option"=>
+ {"disabled"=>"disabled", "ltr"=>"dir", "rtl"=>"dir", "selected"=>"selected"},
+ "kbd"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "big"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "tfoot"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"},
+ "sup"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "bdo"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "isindex"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "dfn"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "fieldset"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "em"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "font"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "tbody"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"},
+ "noscript"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "li"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "col"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"},
+ "small"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "dd"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "i"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "menu"=>{"compact"=>"compact", "ltr"=>"dir", "rtl"=>"dir"},
+ "strong"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "img"=>
+ {"bottom"=>"align", "ismap"=>"ismap", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"align", "right"=>"align", "rtl"=>"dir", "top"=>"align"},
+ "optgroup"=>{"disabled"=>"disabled", "ltr"=>"dir", "rtl"=>"dir"},
+ "map"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "address"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "h1"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "sub"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "param"=>{"data"=>"valuetype", "object"=>"valuetype", "ref"=>"valuetype"},
+ "input"=>
+ {"bottom"=>"align", "button"=>"type", "checkbox"=>"type",
+ "checked"=>"checked", "disabled"=>"disabled", "file"=>"type",
+ "hidden"=>"type", "image"=>"type", "ismap"=>"ismap", "left"=>"align",
+ "ltr"=>"dir", "middle"=>"align", "password"=>"type", "radio"=>"type",
+ "readonly"=>"readonly", "reset"=>"type", "right"=>"align", "rtl"=>"dir",
+ "submit"=>"type", "text"=>"type", "top"=>"align"},
+ "h2"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "abbr"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "h3"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "strike"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "body"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "ins"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "button"=>
+ {"button"=>"type", "disabled"=>"disabled", "ltr"=>"dir", "reset"=>"type",
+ "rtl"=>"dir", "submit"=>"type"},
+ "h4"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "select"=>
+ {"disabled"=>"disabled", "ltr"=>"dir", "multiple"=>"multiple", "rtl"=>"dir"},
+ "caption"=>
+ {"bottom"=>"align", "left"=>"align", "ltr"=>"dir", "right"=>"align",
+ "rtl"=>"dir", "top"=>"align"},
+ "colgroup"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"},
+ "tr"=>
+ {"baseline"=>"valign", "bottom"=>"valign", "center"=>"align",
+ "char"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "middle"=>"valign", "right"=>"align", "rtl"=>"dir", "top"=>"valign"},
+ "del"=>{"ltr"=>"dir", "rtl"=>"dir"},
+ "h5"=>
+ {"center"=>"align", "justify"=>"align", "left"=>"align", "ltr"=>"dir",
+ "right"=>"align", "rtl"=>"dir"},
+ "iframe"=>
+ {"0"=>"frameborder", "1"=>"frameborder", "auto"=>"scrolling",
+ "bottom"=>"align", "left"=>"align", "middle"=>"align", "no"=>"scrolling",
+ "right"=>"align", "top"=>"align", "yes"=>"scrolling"}}
+
+ # :startdoc:
+# The code above is auto-generated. Don't edit manually.
+end
diff --git a/vendor/htree/htree/inspect.rb b/vendor/htree/htree/inspect.rb
new file mode 100644
index 0000000..d5362d7
--- /dev/null
+++ b/vendor/htree/htree/inspect.rb
@@ -0,0 +1,108 @@
+require 'pp'
+require 'htree/doc'
+require 'htree/elem'
+require 'htree/leaf'
+require 'htree/tag'
+require 'htree/output'
+require 'htree/raw_string'
+
+module HTree
+ # :stopdoc:
+ class Doc
+ def pretty_print(q)
+ q.object_group(self) { @children.each {|elt| q.breakable; q.pp elt } }
+ end
+ alias inspect pretty_print_inspect
+ end
+
+ class Elem
+ def pretty_print(q)
+ if @empty
+ q.group(1, '{emptyelem', '}') {
+ q.breakable; q.pp @stag
+ }
+ else
+ q.group(1, "{elem", "}") {
+ q.breakable; q.pp @stag
+ @children.each {|elt| q.breakable; q.pp elt }
+ if @etag
+ q.breakable; q.pp @etag
+ end
+ }
+ end
+ end
+ alias inspect pretty_print_inspect
+ end
+
+ module Leaf
+ def pretty_print(q)
+ q.group(1, '{', '}') {
+ q.text self.class.name.sub(/.*::/,'').downcase
+ if rs = @raw_string
+ rs.scan(/[^\r\n]*(?:\r\n?|\n|[^\r\n]\z)/) {|line|
+ q.breakable
+ q.pp line
+ }
+ elsif self.respond_to? :display_xml
+ q.breakable
+ q.text self.display_xml('')
+ end
+ }
+ end
+ alias inspect pretty_print_inspect
+ end
+
+ class Name
+ def inspect
+ if xmlns?
+ @local_name ? "xmlns:#{@local_name}" : "xmlns"
+ elsif !@namespace_uri || @namespace_uri.empty?
+ @local_name
+ elsif @namespace_prefix
+ "#{@namespace_prefix}{#{@namespace_uri}}#{@local_name}"
+ elsif @namespace_prefix == false
+ "-{#{@namespace_uri}}#{@local_name}"
+ else
+ "{#{@namespace_uri}}#{@local_name}"
+ end
+ end
+ end
+
+ class STag
+ def pretty_print(q)
+ q.group(1, '<', '>') {
+ q.text @name.inspect
+
+ @attributes.each {|n, t|
+ q.breakable
+ q.text "#{n.inspect}=\"#{t.to_attvalue_content}\""
+ }
+ }
+ end
+ alias inspect pretty_print_inspect
+ end
+
+ class ETag
+ def pretty_print(q)
+ q.group(1, '', '>') {
+ q.text @qualified_name
+ }
+ end
+ alias inspect pretty_print_inspect
+ end
+
+ class BogusETag
+ def pretty_print(q)
+ q.group(1, '{', '}') {
+ q.text self.class.name.sub(/.*::/,'').downcase
+ if rs = @raw_string
+ q.breakable
+ q.text rs
+ else
+ q.text "#{@qualified_name}>"
+ end
+ }
+ end
+ end
+ # :startdoc:
+end
diff --git a/vendor/htree/htree/leaf.rb b/vendor/htree/htree/leaf.rb
new file mode 100644
index 0000000..243ff30
--- /dev/null
+++ b/vendor/htree/htree/leaf.rb
@@ -0,0 +1,92 @@
+require 'htree/modules'
+require 'htree/raw_string'
+
+module HTree
+ class XMLDecl
+ def initialize(version, encoding=nil, standalone=nil)
+ init_raw_string
+ if /\A[a-zA-Z0-9_.:-]+\z/ !~ version
+ raise HTree::Error, "invalid version in XML declaration: #{version.inspect}"
+ end
+ if encoding && /\A[A-Za-z][A-Za-z0-9._-]*\z/ !~ encoding
+ raise HTree::Error, "invalid encoding in XML declaration: #{encoding.inspect}"
+ end
+ unless standalone == nil || standalone == true || standalone == false
+ raise HTree::Error, "invalid standalone document declaration in XML declaration: #{standalone.inspect}"
+ end
+ @version = version
+ @encoding = encoding
+ @standalone = standalone
+ end
+ attr_reader :version, :encoding, :standalone
+ end
+
+ class DocType
+ def initialize(root_element_name, public_identifier=nil, system_identifier=nil)
+ init_raw_string
+ if public_identifier && /\A[ \x0d\x0aa-zA-Z0-9\-'()+,.\/:=?;!*\#@$_%]*\z/ !~ public_identifier
+ raise HTree::Error, "invalid public identifier in document type declaration: #{public_identifier.inspect}"
+ end
+ if system_identifier && /"/ =~ system_identifier && /'/ =~ system_identifier
+ raise HTree::Error, "invalid system identifier in document type declaration: #{system_identifier.inspect}"
+ end
+
+ @root_element_name = root_element_name
+ @public_identifier = public_identifier
+ @system_identifier = system_identifier
+ end
+ attr_reader :root_element_name, :public_identifier, :system_identifier
+ end
+
+ class ProcIns
+ # :stopdoc:
+ class << self
+ alias new! new
+ end
+ # :startdoc:
+
+ def ProcIns.new(target, content)
+ content = content.gsub(/\?>/, '? >') if content
+ new! target, content
+ end
+
+ def initialize(target, content) # :notnew:
+ init_raw_string
+ if content && /\?>/ =~ content
+ raise HTree::Error, "invalid processing instruction content: #{content.inspect}"
+ end
+ @target = target
+ @content = content
+ end
+ attr_reader :target, :content
+ end
+
+ class Comment
+ # :stopdoc:
+ class << self
+ alias new! new
+ end
+ # :startdoc:
+
+ def Comment.new(content)
+ content = content.gsub(/-(-+)/) { '-' + ' -' * $1.length }.sub(/-\z/, '- ')
+ new! content
+ end
+
+ def initialize(content) # :notnew:
+ init_raw_string
+ if /--/ =~ content || /-\z/ =~ content
+ raise HTree::Error, "invalid comment content: #{content.inspect}"
+ end
+ @content = content
+ end
+ attr_reader :content
+ end
+
+ class BogusETag
+ def initialize(qualified_name)
+ init_raw_string
+ @etag = ETag.new(qualified_name)
+ end
+ end
+end
diff --git a/vendor/htree/htree/loc.rb b/vendor/htree/htree/loc.rb
new file mode 100644
index 0000000..2072f0f
--- /dev/null
+++ b/vendor/htree/htree/loc.rb
@@ -0,0 +1,369 @@
+require 'htree/modules'
+require 'htree/elem'
+require 'htree/inspect'
+
+module HTree
+ module Node
+ # creates a location object which points to self.
+ def make_loc
+ self.class::Loc.new(nil, nil, self)
+ end
+
+ # return self.
+ def to_node
+ self
+ end
+
+ # +subst+ substitutes several subtrees at once.
+ #
+ # t = HTree('')
+ # l = t.make_loc
+ # t2 = t.subst({
+ # l.get_subnode(0, 'k') => 'v',
+ # l.get_subnode(0, -1) => HTree(''),
+ # l.get_subnode(0, 1) => nil,
+ # l.get_subnode(0, 2, 0) => HTree(''),
+ # })
+ # pp t2
+ # # =>
+ # # {emptyelem } {emptyelem } {elem {emptyelem }}}>
+ def subst(pairs)
+ pairs = pairs.map {|key, val|
+ key = key.index_list(self)
+ unless Array === val
+ val = [val]
+ end
+ [key, val]
+ }
+
+ pairs_empty_key, pairs_nonempty_key =
+ pairs.partition {|key, val| key.empty? }
+ if !pairs_empty_key.empty?
+ if !pairs_nonempty_key.empty?
+ raise ArgumentError, "cannot substitute a node under substituting tree."
+ end
+ result = []
+ pairs_empty_key.each {|key, val| result.concat val }
+ result.compact!
+ if result.length == 1
+ return result[0]
+ else
+ raise ArgumentError, "cannot substitute top node by multiple nodes: #{nodes.inspect}"
+ end
+ end
+ if pairs_nonempty_key.empty?
+ return self
+ end
+
+ subst_internal(pairs)
+ end
+
+ def subst_internal(pairs) # :nodoc:
+ subnode_pairs = {}
+ pairs.each {|key, val|
+ k = key.pop
+ (subnode_pairs[k] ||= []) << [key, val]
+ }
+ subnode_pairs = subnode_pairs.map {|k, subpairs|
+ s = get_subnode(k)
+ subpairs_empty_key, subpairs_nonempty_key =
+ subpairs.partition {|key, val| key.empty? }
+ if !subpairs_empty_key.empty?
+ if !subpairs_nonempty_key.empty?
+ raise ArgumentError, "cannot substitute a node under substituting tree."
+ end
+ r = []
+ subpairs_empty_key.each {|key, val| r.concat val }
+ [k, r.compact]
+ elsif subpairs_nonempty_key.empty?
+ [k, s]
+ else
+ [k, s.subst_internal(subpairs)]
+ end
+ }
+ subst_subnode(subnode_pairs)
+ end
+ end
+
+ # :stopdoc:
+ class Doc; def node_test_string() 'doc()' end end
+ class Elem; def node_test_string() @stag.element_name.qualified_name end end
+ class Text; def node_test_string() 'text()' end end
+ class BogusETag; def node_test_string() 'bogus-etag()' end end
+ class XMLDecl; def node_test_string() 'xml-declaration()' end end
+ class DocType; def node_test_string() 'doctype()' end end
+ class ProcIns; def node_test_string() 'processing-instruction()' end end
+ class Comment; def node_test_string() 'comment()' end end
+
+ module Container
+ def find_loc_step(index)
+ if index < 0 || @children.length <= index
+ return "*[#{index}]"
+ end
+
+ return @loc_step_children[index].dup if defined? @loc_step_children
+
+ count = {}
+ count.default = 0
+
+ steps = []
+
+ @children.each {|c|
+ node_test = c.node_test_string
+ count[node_test] += 1
+ steps << [node_test, count[node_test]]
+ }
+
+ @loc_step_children = []
+ steps.each {|node_test, i|
+ if count[node_test] == 1
+ @loc_step_children << node_test
+ else
+ @loc_step_children << "#{node_test}[#{i}]"
+ end
+ }
+
+ return @loc_step_children[index].dup
+ end
+ end
+
+ class Elem
+ def find_loc_step(index)
+ return super if Integer === index
+ if String === index
+ index = Name.parse_attribute_name(index, DefaultContext)
+ end
+ unless Name === index
+ raise TypeError, "invalid index: #{index.inspect}"
+ end
+ "@#{index.qualified_name}"
+ end
+ end
+ # :startdoc:
+end
+
+class HTree::Location
+ def initialize(parent, index, node) # :nodoc:
+ if parent
+ @parent = parent
+ @index = index
+ @node = parent.node.get_subnode(index)
+ if !@node.equal?(node)
+ raise ArgumentError, "unexpected node"
+ end
+ else
+ @parent = nil
+ @index = nil
+ @node = node
+ end
+ if @node && self.class != @node.class::Loc
+ raise ArgumentError, "invalid location class: #{self.class} should be #{node.class::Loc}"
+ end
+ @subloc = {}
+ end
+ attr_reader :parent, :index, :node
+ alias to_node node
+
+ # return self.
+ def make_loc
+ self
+ end
+
+ # +top+ returns the originator location.
+ #
+ # t = HTree('')
+ # l = t.make_loc.get_subnode(0, 0, 0, 0)
+ # p l, l.top
+ # # =>
+ # #
+ # #
+ def top
+ result = self
+ while result.parent
+ result = result.parent
+ end
+ result
+ end
+
+ # +subst_itself+ substitutes the node pointed by the location.
+ # It returns the location of substituted node.
+ #
+ # t1 = HTree('')
+ # p t1
+ # l1 = t1.make_loc.get_subnode(0, 0, 0, 0)
+ # p l1
+ # l2 = l1.subst_itself(HTree(''))
+ # p l2
+ # t2 = l2.top.to_node
+ # p t2
+ # # =>
+ # # {elem {elem {emptyelem }}}}>
+ # #
+ # #
+ # # {elem {elem {emptyelem }}}}>
+ #
+ def subst_itself(node)
+ if @parent
+ new_index = @index
+ if !@node
+ if Integer === @index
+ if @index < 0
+ new_index = 0
+ elsif @parent.to_node.children.length < @index
+ new_index = @parent.to_node.children.length
+ end
+ end
+ end
+ @parent.subst_itself(@parent.to_node.subst_subnode({@index=>node})).get_subnode(new_index)
+ else
+ node.make_loc
+ end
+ end
+
+ # +subst+ substitutes several subtrees at once.
+ #
+ # t = HTree('')
+ # l = t.make_loc
+ # l2 = l.subst({
+ # l.root.get_subnode('k') => 'v',
+ # l.root.get_subnode(-1) => HTree(''),
+ # l.find_element('y') => nil,
+ # l.find_element('z').get_subnode(0) => HTree(''),
+ # })
+ # pp l2, l2.to_node
+ # # =>
+ # #
+ # # {emptyelem } {emptyelem } {elem {emptyelem }}}>
+ def subst(pairs)
+ subst_itself(@node.subst(pairs))
+ end
+
+ # +loc_list+ returns an array containing from location's root to itself.
+ #
+ # t = HTree('')
+ # l = t.make_loc.get_subnode(0, 0, 0)
+ # pp l, l.loc_list
+ # # =>
+ # #
+ # [#,
+ # #,
+ # #,
+ # #]
+ #
+ def loc_list
+ loc = self
+ result = [self]
+ while loc = loc.parent
+ result << loc
+ end
+ result.reverse!
+ result
+ end
+
+ # +path+ returns the path of the location.
+ #
+ # l = HTree.parse("x").make_loc
+ # l = l.get_subnode(0, 0, 0)
+ # p l.path # => "doc()/a/b[1]/text()"
+ def path
+ result = ''
+ loc_list.each {|loc|
+ if parent = loc.parent
+ result << '/' << parent.node.find_loc_step(loc.index)
+ else
+ result << loc.node.node_test_string
+ end
+ }
+ result
+ end
+
+ def index_list(node) # :nodoc:
+ result = []
+ loc = self
+ while parent = loc.parent
+ return result if loc.to_node.equal? node
+ result << loc.index
+ loc = parent
+ end
+ return result if loc.to_node.equal? node
+ raise ArgumentError, "the location is not under the node: #{self.path}"
+ end
+
+ # :stopdoc:
+ def pretty_print(q)
+ q.group(1, "#<#{self.class.name}", '>') {
+ q.text ':'
+ q.breakable
+ loc_list.each {|loc|
+ if parent = loc.parent
+ q.text '/'
+ q.group { q.breakable '' }
+ q.text parent.node.find_loc_step(loc.index)
+ else
+ q.text loc.node.node_test_string
+ end
+ }
+ }
+ end
+ alias inspect pretty_print_inspect
+ # :startdoc:
+end
+
+module HTree::Container::Loc
+ # +get_subnode+ returns a location object which points to a subnode
+ # indexed by _index_.
+ def get_subnode_internal(index) # :nodoc:
+ return @subloc[index] if @subloc.include? index
+ node = @node.get_subnode(index)
+ if node
+ @subloc[index] = node.class::Loc.new(self, index, node)
+ else
+ @subloc[index] = HTree::Location.new(self, index, node)
+ end
+ end
+
+ # +subst_subnode+ returns the location which refers the substituted tree.
+ # loc.subst_subnode(pairs) -> loc
+ #
+ # t = HTree('')
+ # l = t.make_loc.get_subnode(0, 0)
+ # l = l.subst_subnode({0=>HTree('')})
+ # pp t, l.top.to_node
+ # # =>
+ # # {elem {emptyelem }}}>
+ # # {elem {emptyelem }}}>
+ #
+ def subst_subnode(pairs)
+ self.subst_itself(@node.subst_subnode(pairs))
+ end
+
+ # +children+ returns an array of child locations.
+ def children
+ (0...@node.children.length).map {|i| get_subnode(i) }
+ end
+end
+
+class HTree::Elem::Loc
+ def context() @node.context end
+
+ # +element_name+ returns the name of the element name as a Name object.
+ def element_name() @node.element_name end
+
+ def empty_element?() @node.empty_element? end
+
+ # +each_attribute+ iterates over each attributes.
+ def each_attribute
+ @node.each_attribute {|attr_name, attr_text|
+ attr_loc = get_subnode(attr_name)
+ yield attr_name, attr_loc
+ }
+ end
+end
+
+class HTree::Text::Loc
+ def to_s() @node.to_s end
+ def strip() @node.strip end
+ def empty?() @node.empty? end
+end
diff --git a/vendor/htree/htree/modules.rb b/vendor/htree/htree/modules.rb
new file mode 100644
index 0000000..920fb22
--- /dev/null
+++ b/vendor/htree/htree/modules.rb
@@ -0,0 +1,49 @@
+module HTree
+ class Name; include HTree end
+ class Context; include HTree end
+
+ # :stopdoc:
+ module Tag; include HTree end
+ class STag; include Tag end
+ class ETag; include Tag end
+ # :startdoc:
+
+ module Node; include HTree end
+ module Container; include Node end
+ class Doc; include Container end
+ class Elem; include Container end
+ module Leaf; include Node end
+ class Text; include Leaf end
+ class XMLDecl; include Leaf end
+ class DocType; include Leaf end
+ class ProcIns; include Leaf end
+ class Comment; include Leaf end
+ class BogusETag; include Leaf end
+
+ module Traverse end
+ module Container::Trav; include Traverse end
+ module Leaf::Trav; include Traverse end
+ class Doc; module Trav; include Container::Trav end; include Trav end
+ class Elem; module Trav; include Container::Trav end; include Trav end
+ class Text; module Trav; include Leaf::Trav end; include Trav end
+ class XMLDecl; module Trav; include Leaf::Trav end; include Trav end
+ class DocType; module Trav; include Leaf::Trav end; include Trav end
+ class ProcIns; module Trav; include Leaf::Trav end; include Trav end
+ class Comment; module Trav; include Leaf::Trav end; include Trav end
+ class BogusETag; module Trav; include Leaf::Trav end; include Trav end
+
+ class Location; include HTree end
+ module Container::Loc end
+ module Leaf::Loc end
+ class Doc; class Loc < Location; include Trav, Container::Loc end end
+ class Elem; class Loc < Location; include Trav, Container::Loc end end
+ class Text; class Loc < Location; include Trav, Leaf::Loc end end
+ class XMLDecl; class Loc < Location; include Trav, Leaf::Loc end end
+ class DocType; class Loc < Location; include Trav, Leaf::Loc end end
+ class ProcIns; class Loc < Location; include Trav, Leaf::Loc end end
+ class Comment; class Loc < Location; include Trav, Leaf::Loc end end
+ class BogusETag; class Loc < Location; include Trav, Leaf::Loc end end
+
+ class Error < StandardError; end
+end
+
diff --git a/vendor/htree/htree/name.rb b/vendor/htree/htree/name.rb
new file mode 100644
index 0000000..7364bd1
--- /dev/null
+++ b/vendor/htree/htree/name.rb
@@ -0,0 +1,122 @@
+require 'htree/scan' # for Pat::Nmtoken
+require 'htree/context'
+
+module HTree
+ # Name represents a element name and attribute name.
+ # It consists of a namespace prefix, a namespace URI and a local name.
+ class Name
+=begin
+element name prefix uri localname
+{u}n, n with xmlns=u nil 'u' 'n'
+p{u}n, p:n with xmlns:p=u 'p' 'u' 'n'
+n with xmlns='' nil '' 'n'
+
+attribute name
+xmlns= 'xmlns' nil nil
+xmlns:n= 'xmlns' nil 'n'
+p{u}n=, p:n= with xmlns:p=u 'p' 'u' 'n'
+n= nil '' 'n'
+=end
+ def Name.parse_element_name(name, context)
+ if /\{(.*)\}/ =~ name
+ # "{u}n" means "use default namespace",
+ # "p{u}n" means "use the specified prefix p"
+ $` == '' ? Name.new(nil, $1, $') : Name.new($`, $1, $')
+ elsif /:/ =~ name && !context.namespace_uri($`).empty?
+ Name.new($`, context.namespace_uri($`), $')
+ elsif !context.namespace_uri(nil).empty?
+ Name.new(nil, context.namespace_uri(nil), name)
+ else
+ Name.new(nil, '', name)
+ end
+ end
+
+ def Name.parse_attribute_name(name, context)
+ if name == 'xmlns'
+ Name.new('xmlns', nil, nil)
+ elsif /\Axmlns:/ =~ name
+ Name.new('xmlns', nil, $')
+ elsif /\{(.*)\}/ =~ name
+ case $`
+ when ''; Name.new(nil, $1, $')
+ else Name.new($`, $1, $')
+ end
+ elsif /:/ =~ name && !context.namespace_uri($`).empty?
+ Name.new($`, context.namespace_uri($`), $')
+ else
+ Name.new(nil, '', name)
+ end
+ end
+
+ NameCache = {}
+ def Name.new(namespace_prefix, namespace_uri, local_name)
+ key = [namespace_prefix, namespace_uri, local_name, self]
+ NameCache.fetch(key) {
+ 0.upto(2) {|i| key[i] = key[i].dup.freeze if key[i] }
+ NameCache[key] = super(key[0], key[1], key[2])
+ }
+ end
+
+ def initialize(namespace_prefix, namespace_uri, local_name)
+ @namespace_prefix = namespace_prefix
+ @namespace_uri = namespace_uri
+ @local_name = local_name
+ if @namespace_prefix && /\A#{Pat::Nmtoken}\z/o !~ @namespace_prefix
+ raise HTree::Error, "invalid namespace prefix: #{@namespace_prefix.inspect}"
+ end
+ if @local_name && /\A#{Pat::Nmtoken}\z/o !~ @local_name
+ raise HTree::Error, "invalid local name: #{@local_name.inspect}"
+ end
+ if @namespace_prefix == 'xmlns'
+ unless @namespace_uri == nil
+ raise HTree::Error, "Name object for xmlns:* must not have namespace URI: #{@namespace_uri.inspect}"
+ end
+ else
+ unless String === @namespace_uri
+ raise HTree::Error, "invalid namespace URI: #{@namespace_uri.inspect}"
+ end
+ end
+ end
+ attr_reader :namespace_prefix, :namespace_uri, :local_name
+
+ def xmlns?
+ @namespace_prefix == 'xmlns' && @namespace_uri == nil
+ end
+
+ def universal_name
+ if @namespace_uri && !@namespace_uri.empty?
+ "{#{@namespace_uri}}#{@local_name}"
+ else
+ @local_name.dup
+ end
+ end
+
+ def qualified_name
+ if @namespace_uri && !@namespace_uri.empty?
+ if @namespace_prefix
+ "#{@namespace_prefix}:#{@local_name}"
+ else
+ @local_name.dup
+ end
+ elsif @local_name
+ @local_name.dup
+ else
+ "xmlns"
+ end
+ end
+
+ def to_s
+ if @namespace_uri && !@namespace_uri.empty?
+ if @namespace_prefix
+ "#{@namespace_prefix}{#{@namespace_uri}}#{@local_name}"
+ else
+ "{#{@namespace_uri}}#{@local_name}"
+ end
+ elsif @local_name
+ @local_name.dup
+ else
+ "xmlns"
+ end
+ end
+ end
+end
diff --git a/vendor/htree/htree/output.rb b/vendor/htree/htree/output.rb
new file mode 100644
index 0000000..11e81bd
--- /dev/null
+++ b/vendor/htree/htree/output.rb
@@ -0,0 +1,212 @@
+require 'htree/encoder'
+require 'htree/doc'
+require 'htree/elem'
+require 'htree/leaf'
+require 'htree/text'
+
+module HTree
+ # :stopdoc:
+
+ class Text
+ ChRef = {
+ '>' => '>',
+ '<' => '<',
+ '"' => '"',
+ }
+
+ def output(out, context=nil)
+ out.output_text @rcdata.gsub(/[<>]/) {|s| ChRef[s] }
+ end
+
+ def to_attvalue_content
+ @rcdata.gsub(/[<>"]/) {|s| ChRef[s] }
+ end
+
+ def output_attvalue(out, context)
+ out.output_string '"'
+ out.output_text to_attvalue_content
+ out.output_string '"'
+ end
+
+ def output_cdata(out)
+ str = self.to_s
+ if %r{} =~ str
+ raise ArgumentError, "CDATA cannot contain '': #{str.inspect}"
+ end
+ out.output_string(str)
+ end
+ end
+
+ class Name
+ def output(out, context)
+ # xxx: validate namespace prefix
+ if xmlns?
+ if @local_name
+ out.output_string "xmlns:#{@local_name}"
+ else
+ out.output_string "xmlns"
+ end
+ else
+ out.output_string qualified_name
+ end
+ end
+
+ def output_attribute(text, out, context)
+ output(out, context)
+ out.output_string '='
+ text.output_attvalue(out, context)
+ end
+ end
+
+ class Doc
+ def output(out, context)
+ xmldecl = false
+ @children.each {|n|
+ if n.respond_to? :output_prolog_xmldecl
+ n.output_prolog_xmldecl(out, context) unless xmldecl # xxx: encoding?
+ xmldecl = true
+ else
+ n.output(out, context)
+ end
+ }
+ end
+ end
+
+ class Elem
+ def output(out, context)
+ if %r{\A\{http://www.w3.org/1999/xhtml\}(script|style)} =~ @stag.element_name.universal_name
+ children_context = @stag.output_stag(out, context)
+ out.output_cdata_content(@children, children_context)
+ @stag.output_etag(out, context)
+ elsif @empty
+ @stag.output_emptytag(out, context)
+ else
+ children_context = @stag.output_stag(out, context)
+ @children.each {|n| n.output(out, children_context) }
+ @stag.output_etag(out, context)
+ end
+ end
+ end
+
+ class STag
+ def output_attributes(out, context)
+ @attributes.each {|aname, text|
+ next if aname.xmlns?
+ out.output_string ' '
+ aname.output_attribute(text, out, context)
+ }
+ @context.output_namespaces(out, context)
+ end
+
+ def output_emptytag(out, context)
+ out.output_string '<'
+ @name.output(out, context)
+ children_context = output_attributes(out, context)
+ out.output_string "\n"
+ out.output_slash_if_xml
+ out.output_string ">"
+ children_context
+ end
+
+ def output_stag(out, context)
+ out.output_string '<'
+ @name.output(out, context)
+ children_context = output_attributes(out, context)
+ out.output_string "\n>"
+ children_context
+ end
+
+ def output_etag(out, context)
+ out.output_string ''
+ @name.output(out, context)
+ out.output_string "\n>"
+ end
+ end
+
+ class Context
+ def output_namespaces(out, outer_context)
+ unknown_namespaces = {}
+ @namespaces.each {|prefix, uri|
+ outer_uri = outer_context.namespace_uri(prefix)
+ if outer_uri == nil
+ unknown_namespaces[prefix] = uri
+ elsif outer_uri != uri
+ if prefix
+ out.output_string " xmlns:#{prefix}="
+ else
+ out.output_string " xmlns="
+ end
+ Text.new(uri).output_attvalue(out, outer_context)
+ end
+ }
+ unless unknown_namespaces.empty?
+ out.output_xmlns(unknown_namespaces)
+ end
+ outer_context.subst_namespaces(@namespaces)
+ end
+ end
+
+ class BogusETag
+ # don't output anything.
+ def output(out, context)
+ end
+ end
+
+ class XMLDecl
+ # don't output anything.
+ def output(out, context)
+ end
+
+ def output_prolog_xmldecl(out, context)
+ out.output_string ""
+ end
+ end
+
+ class DocType
+ def output(out, context)
+ out.output_string ""
+ end
+
+ def generate_content # :nodoc:
+ result = ''
+ if @public_identifier
+ result << "PUBLIC \"#{@public_identifier}\""
+ else
+ result << "SYSTEM"
+ end
+ # Although a system identifier is not omissible in XML,
+ # we cannot output it if it is not given.
+ if @system_identifier
+ if /"/ !~ @system_identifier
+ result << " \"#{@system_identifier}\""
+ else
+ result << " '#{@system_identifier}'"
+ end
+ end
+ result
+ end
+ end
+
+ class ProcIns
+ def output(out, context)
+ out.output_string "#{@target}"
+ out.output_string " #{@content}" if @content
+ out.output_string "?>"
+ end
+ end
+
+ class Comment
+ def output(out, context)
+ out.output_string ""
+ end
+ end
+
+ # :startdoc:
+end
diff --git a/vendor/htree/htree/parse.rb b/vendor/htree/htree/parse.rb
new file mode 100644
index 0000000..dcbd815
--- /dev/null
+++ b/vendor/htree/htree/parse.rb
@@ -0,0 +1,410 @@
+require 'htree/scan'
+require 'htree/htmlinfo'
+require 'htree/text'
+require 'htree/tag'
+require 'htree/leaf'
+require 'htree/doc'
+require 'htree/elem'
+require 'htree/raw_string'
+require 'htree/context'
+require 'htree/encoder'
+require 'htree/fstr'
+
+module HTree
+ # HTree.parse parses input and return a document tree.
+ # represented by HTree::Doc.
+ #
+ # input should be a String or
+ # an object which respond to read or open method.
+ # For example, IO, StringIO, Pathname, URI::HTTP and URI::FTP are acceptable.
+ # Note that the URIs need open-uri.
+ #
+ # HTree.parse guesses input is HTML or not and XML or not.
+ #
+ # If it is guessed as HTML, the default namespace in the result is set to http://www.w3.org/1999/xhtml
+ # regardless of input has XML namespace declaration or not nor even it is pre-XML HTML.
+ #
+ # If it is guessed as HTML and not XML, all element and attribute names are downcaseed.
+ #
+ # If opened file or read content has charset method,
+ # HTree.parse decode it according to $KCODE before parsing.
+ # Otherwise HTree.parse assumes the character encoding of the content is
+ # compatible to $KCODE.
+ # Note that the charset method is provided by URI::HTTP with open-uri.
+ def HTree.parse(input)
+ HTree.with_frozen_string_hash {
+ parse_as(input, false)
+ }
+ end
+
+ # HTree.parse_xml parses input as XML and
+ # return a document tree represented by HTree::Doc.
+ #
+ # It behaves almost same as HTree.parse but it assumes input is XML
+ # even if no XML declaration.
+ # The assumption causes following differences.
+ # * doesn't downcase element name.
+ # * The content of