yay the world is fixed
This commit is contained in:
parent
40fcdf22d9
commit
b4084d5325
10 changed files with 164 additions and 95 deletions
|
@ -18,7 +18,7 @@ module Microformats2
|
||||||
def parse(html)
|
def parse(html)
|
||||||
html = read_html(html)
|
html = read_html(html)
|
||||||
document = Nokogiri::HTML(html)
|
document = Nokogiri::HTML(html)
|
||||||
Collection.new.parse(document)
|
Collection.new(document).parse
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_html(html)
|
def read_html(html)
|
||||||
|
|
|
@ -1,15 +1,36 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
class Collection
|
class Collection
|
||||||
attr_accessor :formats
|
attr_reader :all
|
||||||
|
|
||||||
def parse(document)
|
def initialize(element)
|
||||||
@formats = FormatParser.parse(document)
|
@element = element
|
||||||
|
@format_names = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse
|
||||||
|
all
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def all
|
||||||
|
@all ||= FormatParser.parse(@element).each do |format|
|
||||||
|
save_format_name(format.method_name)
|
||||||
|
define_method(format.method_name)
|
||||||
|
set_value(format.method_name, format)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def first
|
||||||
|
all.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def last
|
||||||
|
all.last
|
||||||
|
end
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
hash = { items: [] }
|
hash = { items: [] }
|
||||||
formats.each do |format|
|
all.each do |format|
|
||||||
hash[:items] << format.to_hash
|
hash[:items] << format.to_hash
|
||||||
end
|
end
|
||||||
hash
|
hash
|
||||||
|
@ -18,5 +39,27 @@ module Microformats2
|
||||||
def to_json
|
def to_json
|
||||||
to_hash.to_json
|
to_hash.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def save_format_name(format_name)
|
||||||
|
unless @format_names.include?(format_name)
|
||||||
|
@format_names << format_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def define_method(mn)
|
||||||
|
unless respond_to?(mn)
|
||||||
|
self.class.class_eval { attr_accessor mn }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_value(mn, value)
|
||||||
|
if current = send(mn)
|
||||||
|
current << value
|
||||||
|
else
|
||||||
|
send("#{mn}=", [value])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,62 +2,38 @@ module Microformats2
|
||||||
class Format
|
class Format
|
||||||
CLASS_REG_EXP = /^(h-)/
|
CLASS_REG_EXP = /^(h-)/
|
||||||
|
|
||||||
attr_reader :element
|
attr_reader :method_name
|
||||||
|
|
||||||
def initialize(element)
|
def initialize(element)
|
||||||
@element = element
|
@element = element
|
||||||
@added_methods = []
|
@method_name = to_method_name(format_types.first)
|
||||||
|
@property_names = []
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse
|
def parse
|
||||||
properties
|
|
||||||
format_types
|
format_types
|
||||||
|
properties
|
||||||
self
|
self
|
||||||
end
|
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
|
def format_types
|
||||||
@format_types ||= element.attribute("class").to_s.split.select do |html_class|
|
@format_types ||= @element.attribute("class").to_s.split.select do |html_class|
|
||||||
html_class =~ Format::CLASS_REG_EXP
|
html_class =~ Format::CLASS_REG_EXP
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def properties
|
||||||
|
@properties ||= PropertyParser.parse(@element.children).each do |property|
|
||||||
|
save_property_name(property.method_name)
|
||||||
|
define_method(property.method_name)
|
||||||
|
set_value(property.method_name, property)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
hash = { type: format_types, properties: {} }
|
hash = { type: format_types, properties: {} }
|
||||||
@added_methods.each do |method_name|
|
@property_names.each do |method_name|
|
||||||
value = send(method_name)
|
hash[:properties][method_name.to_sym] = send(method_name).map(&:to_hash)
|
||||||
value = value.is_a?(Array) ? value : [value]
|
|
||||||
hash[:properties][method_name.to_sym] = value.map(&:to_hash)
|
|
||||||
end
|
end
|
||||||
hash
|
hash
|
||||||
end
|
end
|
||||||
|
@ -65,5 +41,35 @@ module Microformats2
|
||||||
def to_json
|
def to_json
|
||||||
to_hash.to_json
|
to_hash.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def to_method_name(html_class)
|
||||||
|
# p-class-name -> class_name
|
||||||
|
mn = html_class.downcase.split("-")[1..-1].join("_")
|
||||||
|
# avoid overriding Object#class
|
||||||
|
mn = "klass" if mn == "class"
|
||||||
|
mn
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_property_name(property_name)
|
||||||
|
unless @property_names.include?(property_name)
|
||||||
|
@property_names << property_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def define_method(mn)
|
||||||
|
unless respond_to?(mn)
|
||||||
|
self.class.class_eval { attr_accessor mn }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_value(mn, value)
|
||||||
|
if current = send(mn)
|
||||||
|
current << value
|
||||||
|
else
|
||||||
|
send("#{mn}=", [value])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -54,6 +54,6 @@ module Microformats2
|
||||||
end
|
end
|
||||||
klass
|
klass
|
||||||
end
|
end
|
||||||
end
|
end # class << self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,8 @@ module Microformats2
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
def attr_map
|
def attr_map
|
||||||
@attr_map ||= {
|
@attr_map ||= {
|
||||||
"time" => "datetime",
|
"time" => "datetime",
|
||||||
|
|
|
@ -1,60 +1,26 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
module Property
|
module Property
|
||||||
class Foundation
|
class Foundation
|
||||||
attr_accessor :element, :name, :value, :formats
|
attr_reader :method_name
|
||||||
|
|
||||||
def initialize(element, html_class)
|
def initialize(element, html_class)
|
||||||
@element = element
|
@element = element
|
||||||
@name = to_method_name(html_class)
|
@method_name = to_method_name(html_class)
|
||||||
end
|
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
|
def parse
|
||||||
formats
|
|
||||||
value
|
value
|
||||||
|
formats
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def formats
|
|
||||||
@formats ||= format_classes.length >=1 ? FormatParser.parse(element) : []
|
|
||||||
end
|
|
||||||
|
|
||||||
def format_classes
|
|
||||||
@format_classes = element.attribute("class").to_s.split.select do |html_class|
|
|
||||||
html_class =~ Format::CLASS_REG_EXP
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def value
|
def value
|
||||||
@value ||= value_class_pattern || element_value || text_value
|
@value ||= value_class_pattern || element_value || text_value
|
||||||
end
|
end
|
||||||
|
|
||||||
def value_class_pattern
|
def formats
|
||||||
# TODO
|
@formats ||= format_classes.length >=1 ? FormatParser.parse(@element) : []
|
||||||
end
|
end
|
||||||
|
|
||||||
def element_value
|
|
||||||
element.attribute(attribute).to_s if attribute
|
|
||||||
end
|
|
||||||
|
|
||||||
def text_value
|
|
||||||
element.inner_text.gsub(/\n+/, " ").gsub(/\s+/, " ").strip
|
|
||||||
end
|
|
||||||
|
|
||||||
def attribute
|
|
||||||
attr_map[element.name]
|
|
||||||
end
|
|
||||||
|
|
||||||
def attr_map
|
|
||||||
{}
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
if formats.empty?
|
if formats.empty?
|
||||||
|
@ -63,6 +29,48 @@ module Microformats2
|
||||||
{ value: value.to_s }.merge(formats.first.to_hash)
|
{ value: value.to_s }.merge(formats.first.to_hash)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_json
|
||||||
|
to_hash.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def value_class_pattern
|
||||||
|
# TODO
|
||||||
|
end
|
||||||
|
|
||||||
|
def element_value
|
||||||
|
@element.attribute(attribute).to_s if attribute
|
||||||
|
end
|
||||||
|
|
||||||
|
def text_value
|
||||||
|
@element.inner_text.gsub(/\n+/, " ").gsub(/\s+/, " ").strip
|
||||||
|
end
|
||||||
|
|
||||||
|
def attribute
|
||||||
|
attr_map[@element.name]
|
||||||
|
end
|
||||||
|
|
||||||
|
def attr_map
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def to_method_name(html_class)
|
||||||
|
# p-class-name -> class_name
|
||||||
|
mn = html_class.downcase.split("-")[1..-1].join("_")
|
||||||
|
# avoid overriding Object#class
|
||||||
|
mn = "klass" if mn == "class"
|
||||||
|
mn
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_classes
|
||||||
|
@format_classes = @element.attribute("class").to_s.split.select do |html_class|
|
||||||
|
html_class =~ Format::CLASS_REG_EXP
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
module Property
|
module Property
|
||||||
class Text < Foundation
|
class Text < Foundation
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
def attr_map
|
def attr_map
|
||||||
@attr_map = {
|
@attr_map = {
|
||||||
"abbr" => "title",
|
"abbr" => "title",
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
module Property
|
module Property
|
||||||
class Url < Foundation
|
class Url < Foundation
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
def attr_map
|
def attr_map
|
||||||
@attr_map = {
|
@attr_map = {
|
||||||
"a" => "href",
|
"a" => "href",
|
||||||
|
|
|
@ -8,7 +8,7 @@ module Microformats2
|
||||||
def parse_node(node)
|
def parse_node(node)
|
||||||
case
|
case
|
||||||
when node.is_a?(Nokogiri::XML::NodeSet) then parse_nodeset(node)
|
when node.is_a?(Nokogiri::XML::NodeSet) then parse_nodeset(node)
|
||||||
when node.is_a?(Nokogiri::XML::Element) then parse_for_properties(node)
|
when node.is_a?(Nokogiri::XML::Element) then [parse_for_properties(node)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,6 +40,6 @@ module Microformats2
|
||||||
html_class =~ Property::CLASS_REG_EXP
|
html_class =~ Property::CLASS_REG_EXP
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end # class << self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,21 +25,23 @@ describe Microformats2::Collection do
|
||||||
|
|
||||||
describe "#parse" do
|
describe "#parse" do
|
||||||
it "creates ruby class HCard" do
|
it "creates ruby class HCard" do
|
||||||
@collection.formats.first.should be_kind_of HCard
|
@collection.all.first.should be_kind_of HCard
|
||||||
|
@collection.first.should be_kind_of HCard
|
||||||
|
@collection.card.first.should be_kind_of HCard
|
||||||
end
|
end
|
||||||
it "assigns .h-card .p-name to HCard#name" do
|
it "assigns .h-card .p-name to HCard#name" do
|
||||||
@collection.formats.first.name.first.value.should == "Jessica Lynn Suttles"
|
@collection.first.name.first.value.should == "Jessica Lynn Suttles"
|
||||||
end
|
end
|
||||||
it "assigns both .h-card .u-url to HCard#url" do
|
it "assigns both .h-card .u-url to HCard#url" do
|
||||||
urls = ["http://flickr.com/jlsuttles", "http://twitter.com/jlsuttles"]
|
urls = ["http://flickr.com/jlsuttles", "http://twitter.com/jlsuttles"]
|
||||||
@collection.formats.first.url.map(&:value).should == urls
|
@collection.first.url.map(&:value).should == urls
|
||||||
end
|
end
|
||||||
it "assings .h-card .dt-bday to HCard#bday" do
|
it "assings .h-card .dt-bday to HCard#bday" do
|
||||||
@collection.formats.first.bday.first.value.should be_kind_of DateTime
|
@collection.first.bday.first.value.should be_kind_of DateTime
|
||||||
@collection.formats.first.bday.first.value.to_s.should == "1990-10-15T20:45:33-08:00"
|
@collection.first.bday.first.value.to_s.should == "1990-10-15T20:45:33-08:00"
|
||||||
end
|
end
|
||||||
it "assigns .h-card .e-content to HCard#content" do
|
it "assigns .h-card .e-content to HCard#content" do
|
||||||
@collection.formats.first.content.first.value.should == "Vegan. Cat lover. Coder."
|
@collection.first.content.first.value.should == "Vegan. Cat lover. Coder."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,10 +71,12 @@ describe Microformats2::Collection do
|
||||||
|
|
||||||
describe "#parse" do
|
describe "#parse" do
|
||||||
it "creates ruby class HEntry" do
|
it "creates ruby class HEntry" do
|
||||||
@collection.formats.first.should be_kind_of HEntry
|
@collection.all.first.should be_kind_of HEntry
|
||||||
|
@collection.first.should be_kind_of HEntry
|
||||||
|
@collection.entry.first.should be_kind_of HEntry
|
||||||
end
|
end
|
||||||
it "assigns .h-entry .p-author to HEntry#author" do
|
it "assigns .h-entry .p-author to HEntry#author" do
|
||||||
@collection.formats.first.author.value.should == "Jessica Lynn Suttles"
|
@collection.first.author.first.value.should == "Jessica Lynn Suttles"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue