moves common parser methods to Parser class
This commit is contained in:
parent
7937403982
commit
e02e1b3689
4 changed files with 106 additions and 136 deletions
|
@ -2,6 +2,7 @@ require "nokogiri"
|
||||||
require "open-uri"
|
require "open-uri"
|
||||||
require "json"
|
require "json"
|
||||||
require "microformats2/version"
|
require "microformats2/version"
|
||||||
|
require "microformats2/parser"
|
||||||
require "microformats2/collection"
|
require "microformats2/collection"
|
||||||
require "microformats2/format"
|
require "microformats2/format"
|
||||||
require "microformats2/property"
|
require "microformats2/property"
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
class Collection
|
class Collection < Parser
|
||||||
attr_accessor :added_methods, :formats
|
attr_accessor :formats
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@added_methods = []
|
|
||||||
@formats = []
|
@formats = []
|
||||||
end
|
super
|
||||||
|
|
||||||
def parse(document)
|
|
||||||
parse_nodeset(document.children)
|
|
||||||
self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
|
@ -24,34 +19,12 @@ module Microformats2
|
||||||
to_hash.to_json
|
to_hash.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def html_class_regex
|
||||||
|
/^h-/
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse_nodeset(nodeset)
|
|
||||||
nodeset.map { |node| parse_node(node) }
|
|
||||||
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_element(node)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_element(element)
|
|
||||||
# look for root microformat class
|
|
||||||
html_classes = element.attribute("class").to_s.split
|
|
||||||
html_classes.keep_if { |html_class| html_class =~ /^h-/ }
|
|
||||||
|
|
||||||
# if found root microformat, yay parse it
|
|
||||||
if html_classes.length >= 1
|
|
||||||
parse_microformat(element, html_classes)
|
|
||||||
|
|
||||||
# if no root microformat found, look at children
|
|
||||||
else
|
|
||||||
parse_nodeset(element.children)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_microformat(microformat, html_classes)
|
def parse_microformat(microformat, html_classes)
|
||||||
# only worry about the first format for now
|
# only worry about the first format for now
|
||||||
html_class = html_classes.first
|
html_class = html_classes.first
|
||||||
|
@ -69,38 +42,14 @@ module Microformats2
|
||||||
Object.const_set constant_name, klass
|
Object.const_set constant_name, klass
|
||||||
end
|
end
|
||||||
|
|
||||||
# get a new instance of the ruby class
|
# parse microformat
|
||||||
format = klass.new.parse(microformat)
|
value = klass.new.parse(microformat)
|
||||||
|
|
||||||
@formats << format
|
# save microformat in array in order
|
||||||
|
@formats << value
|
||||||
|
|
||||||
save_method_name(method_name)
|
# save microformat under custom method
|
||||||
add_method(method_name)
|
define_method_and_set_value(method_name, value)
|
||||||
populate_method(method_name, format)
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_method_name(method_name)
|
|
||||||
unless @added_methods.include?(method_name)
|
|
||||||
@added_methods << method_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_method(method_name)
|
|
||||||
unless respond_to?(method_name)
|
|
||||||
self.class.class_eval { attr_accessor method_name }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def populate_method(method_name, value)
|
|
||||||
if current = send(method_name)
|
|
||||||
if current.kind_of? Array
|
|
||||||
current << value
|
|
||||||
else
|
|
||||||
send("#{method_name}=", [current, value])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
send("#{method_name}=", value)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
class Format
|
class Format < Parser
|
||||||
attr_accessor :added_method_names
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@added_method_names = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse(element)
|
|
||||||
parse_nodeset(element.children)
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def type
|
def type
|
||||||
# ClassName -> className -> class-name
|
# ClassName -> className -> class-name
|
||||||
self.class.name.gsub(/^([A-Z])/){$1.downcase}.gsub(/([A-Z])/){"-" + $1.downcase}
|
self.class.name.gsub(/^([A-Z])/){$1.downcase}.gsub(/([A-Z])/){"-" + $1.downcase}
|
||||||
|
@ -18,7 +7,7 @@ module Microformats2
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
hash = { type: [type], properties: {} }
|
hash = { type: [type], properties: {} }
|
||||||
@added_method_names.each do |method_name|
|
@added_methods.each do |method_name|
|
||||||
hash[:properties][method_name.to_sym] = send(method_name)
|
hash[:properties][method_name.to_sym] = send(method_name)
|
||||||
end
|
end
|
||||||
hash
|
hash
|
||||||
|
@ -28,74 +17,26 @@ module Microformats2
|
||||||
to_hash.to_json
|
to_hash.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def html_class_regex
|
||||||
|
Microformats2::PropertyPrefixesRegEx
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse_nodeset(nodeset)
|
def parse_microformat(element, html_classes)
|
||||||
nodeset.map { |node| parse_node(node) }
|
|
||||||
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_element(node)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_element(element)
|
|
||||||
# look for microformat property class
|
|
||||||
html_classes = element.attribute("class").to_s.split
|
|
||||||
html_classes.keep_if { |html_class| html_class =~ Microformats2::PropertyPrefixesRegEx }
|
|
||||||
|
|
||||||
# if found microformat property, yay parse it
|
|
||||||
if html_classes.length >= 1
|
|
||||||
parse_property(element, html_classes)
|
|
||||||
|
|
||||||
# if no microformat property found, look at children
|
|
||||||
else
|
|
||||||
parse_nodeset(element.children)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_property(element, html_classes)
|
|
||||||
html_classes.each do |html_class|
|
html_classes.each do |html_class|
|
||||||
# p-class-name -> p
|
# p-class-name -> p
|
||||||
prefix = html_class.split("-").first
|
prefix = html_class.split("-").first
|
||||||
# p-class-name -> class_name
|
# p-class-name -> class_name
|
||||||
method_name = html_class.split("-")[1..-1].join("_")
|
method_name = html_class.split("-")[1..-1].join("_")
|
||||||
|
# avoid overriding Object#class
|
||||||
|
method_name = "klass" if method_name == "class"
|
||||||
|
|
||||||
|
# parse property
|
||||||
value = Microformats2::PropertyPrefixes[prefix].parse(element)
|
value = Microformats2::PropertyPrefixes[prefix].parse(element)
|
||||||
|
|
||||||
# avoid overriding Object#class
|
# save property under custom method
|
||||||
if method_name == "class"
|
define_method_and_set_value(method_name, value)
|
||||||
method_name = "klass"
|
|
||||||
end
|
|
||||||
|
|
||||||
save_method_name(method_name)
|
|
||||||
add_method(method_name)
|
|
||||||
populate_method(method_name, value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_method_name(method_name)
|
|
||||||
unless @added_method_names.include?(method_name)
|
|
||||||
@added_method_names << method_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_method(method_name)
|
|
||||||
unless respond_to?(method_name)
|
|
||||||
self.class.class_eval { attr_accessor method_name }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def populate_method(method_name, value)
|
|
||||||
if current = send(method_name)
|
|
||||||
if current.kind_of? Array
|
|
||||||
current << value
|
|
||||||
else
|
|
||||||
send("#{method_name}=", [current, value])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
send("#{method_name}=", value)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
79
lib/microformats2/parser.rb
Normal file
79
lib/microformats2/parser.rb
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
module Microformats2
|
||||||
|
class Parser
|
||||||
|
attr_accessor :added_methods
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@added_methods = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(element)
|
||||||
|
parse_nodeset(element.children)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# override with regex to match before parsing microformat
|
||||||
|
def html_class_regex
|
||||||
|
//
|
||||||
|
end
|
||||||
|
|
||||||
|
# override and do interesting things here
|
||||||
|
def parse_microformat(element, html_classes)
|
||||||
|
element
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def parse_nodeset(nodeset)
|
||||||
|
nodeset.map { |node| parse_node(node) }
|
||||||
|
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_element(node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_element(element)
|
||||||
|
html_classes = element.attribute("class").to_s.split
|
||||||
|
html_classes.keep_if { |html_class| html_class =~ html_class_regex }
|
||||||
|
|
||||||
|
if html_classes.length >= 1
|
||||||
|
parse_microformat(element, html_classes)
|
||||||
|
else
|
||||||
|
parse_nodeset(element.children)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def define_method_and_set_value(method_name, value)
|
||||||
|
save_method_name(method_name)
|
||||||
|
define_method(method_name)
|
||||||
|
set_value(method_name, value)
|
||||||
|
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)
|
||||||
|
if current.kind_of? Array
|
||||||
|
current << value
|
||||||
|
else
|
||||||
|
send("#{method_name}=", [current, value])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
send("#{method_name}=", value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue