fixes the world minus nested formats
This commit is contained in:
parent
081d0e5000
commit
40fcdf22d9
7 changed files with 91 additions and 50 deletions
|
@ -3,7 +3,8 @@ module Microformats2
|
|||
attr_accessor :formats
|
||||
|
||||
def parse(document)
|
||||
formats = FormatParser.parse(document)
|
||||
@formats = FormatParser.parse(document)
|
||||
self
|
||||
end
|
||||
|
||||
def to_hash
|
||||
|
|
|
@ -2,20 +2,50 @@ module Microformats2
|
|||
class Format
|
||||
CLASS_REG_EXP = /^(h-)/
|
||||
|
||||
attr_reader :element, :properties, :format_types
|
||||
attr_reader :element
|
||||
|
||||
def initialize(element)
|
||||
@element = element
|
||||
@format_types = []
|
||||
@properties = []
|
||||
@added_methods = []
|
||||
end
|
||||
|
||||
def parse
|
||||
properties << PropertyParser.parse(element)
|
||||
properties
|
||||
format_types
|
||||
self
|
||||
end
|
||||
|
||||
def properties
|
||||
@properties ||= create_properties
|
||||
end
|
||||
|
||||
def create_properties
|
||||
PropertyParser.parse(element).map do |property|
|
||||
save_method_name(property.name)
|
||||
define_method(property.name)
|
||||
set_value(property.name, property)
|
||||
end
|
||||
end
|
||||
|
||||
def save_method_name(method_name)
|
||||
unless @added_methods.include?(method_name)
|
||||
@added_methods << method_name
|
||||
end
|
||||
end
|
||||
|
||||
def define_method(method_name)
|
||||
unless respond_to?(method_name)
|
||||
self.class.class_eval { attr_accessor method_name }
|
||||
end
|
||||
end
|
||||
|
||||
def set_value(method_name, value)
|
||||
if current = send(method_name)
|
||||
current << value
|
||||
else
|
||||
send("#{method_name}=", [value])
|
||||
end
|
||||
end
|
||||
def format_types
|
||||
@format_types ||= element.attribute("class").to_s.split.select do |html_class|
|
||||
html_class =~ Format::CLASS_REG_EXP
|
||||
|
@ -23,8 +53,8 @@ module Microformats2
|
|||
end
|
||||
|
||||
def to_hash
|
||||
hash = { type: @format_types, properties: {} }
|
||||
properties.each do |method_name|
|
||||
hash = { type: format_types, properties: {} }
|
||||
@added_methods.each do |method_name|
|
||||
value = send(method_name)
|
||||
value = value.is_a?(Array) ? value : [value]
|
||||
hash[:properties][method_name.to_sym] = value.map(&:to_hash)
|
||||
|
|
|
@ -2,13 +2,14 @@ module Microformats2
|
|||
class FormatParser
|
||||
class << self
|
||||
def parse(element)
|
||||
parse_node(element)
|
||||
parse_node(element).flatten.compact
|
||||
end
|
||||
|
||||
def parse_node(node)
|
||||
case
|
||||
when node.is_a?(Nokogiri::XML::NodeSet) then parse_nodeset(node)
|
||||
when node.is_a?(Nokogiri::XML::Element) then parse_for_microformats(node)
|
||||
when node.is_a?(Nokogiri::HTML::Document) then parse_node(node.children)
|
||||
when node.is_a?(Nokogiri::XML::NodeSet) then parse_nodeset(node)
|
||||
when node.is_a?(Nokogiri::XML::Element) then [parse_for_microformats(node)]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -25,22 +26,11 @@ module Microformats2
|
|||
end
|
||||
|
||||
def parse_microformat(element)
|
||||
# only worry about the first format for now
|
||||
# only create ruby object for first format class
|
||||
html_class = format_classes(element).first
|
||||
# class-name -> class_name
|
||||
method_name = html_class.downcase.gsub("-","_")
|
||||
# class_name -> Class_name -> ClassName
|
||||
constant_name = method_name.gsub(/^([a-z])/){$1.upcase}.gsub(/_(.)/){$1.upcase}
|
||||
const_name = constant_name(html_class)
|
||||
klass = find_or_create_ruby_class(const_name)
|
||||
|
||||
# find or create ruby class for microformat
|
||||
if Object.const_defined?(constant_name)
|
||||
klass = Object.const_get(constant_name)
|
||||
else
|
||||
klass = Class.new(Microformats2::Format)
|
||||
Object.const_set constant_name, klass
|
||||
end
|
||||
|
||||
# parse microformat
|
||||
klass.new(element).parse
|
||||
end
|
||||
|
||||
|
@ -49,6 +39,21 @@ module Microformats2
|
|||
html_class =~ Format::CLASS_REG_EXP
|
||||
end
|
||||
end
|
||||
|
||||
def constant_name(html_class)
|
||||
# html-Class -> html-class -> html_class -> Html_class -> HtmlClass
|
||||
html_class.downcase.gsub("-","_").gsub(/^([a-z])/){$1.upcase}.gsub(/_(.)/){$1.upcase}
|
||||
end
|
||||
|
||||
def find_or_create_ruby_class(const_name)
|
||||
if Object.const_defined?(const_name)
|
||||
klass = Object.const_get(const_name)
|
||||
else
|
||||
klass = Class.new(Microformats2::Format)
|
||||
Object.const_set const_name, klass
|
||||
end
|
||||
klass
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,6 @@ module Microformats2
|
|||
"p" => Text,
|
||||
"u" => Url,
|
||||
"dt" => DateTime,
|
||||
"e" => Embedded
|
||||
}
|
||||
"e" => Embedded }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +1,33 @@
|
|||
module Microformats2
|
||||
module Property
|
||||
class Foundation
|
||||
attr_accessor :element, :value, :formats
|
||||
attr_accessor :element, :name, :value, :formats
|
||||
|
||||
def initialize(element)
|
||||
def initialize(element, html_class)
|
||||
@element = element
|
||||
@formats = []
|
||||
@name = to_method_name(html_class)
|
||||
end
|
||||
|
||||
def to_method_name(html_class)
|
||||
# p-class-name -> class_name
|
||||
method_name = html_class.downcase.split("-")[1..-1].join("_")
|
||||
# avoid overriding Object#class
|
||||
method_name = "klass" if method_name == "class"
|
||||
method_name
|
||||
end
|
||||
|
||||
def parse
|
||||
formats << FormatParser.parse(element) if format_classes.length >=1
|
||||
formats
|
||||
value
|
||||
self
|
||||
end
|
||||
|
||||
def formats
|
||||
@formats ||= format_classes.length >=1 ? FormatParser.parse(element) : []
|
||||
end
|
||||
|
||||
def format_classes
|
||||
element.attribute("class").to_s.split.select do |html_class|
|
||||
@format_classes = element.attribute("class").to_s.split.select do |html_class|
|
||||
html_class =~ Format::CLASS_REG_EXP
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ module Microformats2
|
|||
class PropertyParser
|
||||
class << self
|
||||
def parse(element)
|
||||
parse_node(element)
|
||||
parse_node(element).flatten.compact
|
||||
end
|
||||
|
||||
def parse_node(node)
|
||||
|
@ -24,24 +24,18 @@ module Microformats2
|
|||
end
|
||||
end
|
||||
|
||||
def parse_property(element, html_classes)
|
||||
property_classes(element).each do |property_class|
|
||||
def parse_property(element)
|
||||
property_classes(element).map do |property_class|
|
||||
# p-class-name -> p
|
||||
prefix = property_class.split("-").first
|
||||
# p-class-name -> class_name
|
||||
method_name = property_class.split("-")[1..-1].join("_")
|
||||
# avoid overriding Object#class
|
||||
method_name = "klass" if method_name == "class"
|
||||
|
||||
# find ruby class for kind of property
|
||||
klass = Microformats2::Property::PREFIX_CLASS_MAP[prefix]
|
||||
|
||||
# parse property
|
||||
klass.new(element).parse
|
||||
klass.new(element, property_class).parse
|
||||
end
|
||||
end
|
||||
|
||||
def property_classes(element, regexp)
|
||||
def property_classes(element)
|
||||
element.attribute("class").to_s.split.select do |html_class|
|
||||
html_class =~ Property::CLASS_REG_EXP
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue