microformats2 2.1.0 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/lib/microformats2/collection.rb +32 -10
- data/lib/microformats2/format.rb +48 -8
- data/lib/microformats2/format_parser.rb +19 -11
- data/lib/microformats2/property/date_time.rb +2 -2
- data/lib/microformats2/property/foundation.rb +61 -5
- data/lib/microformats2/property_parser.rb +2 -0
- data/lib/microformats2/version.rb +1 -1
- data/microformats2.gemspec +31 -0
- metadata +15 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cd6cf3a5932b16cf908e76912361c306a1c9191
|
4
|
+
data.tar.gz: 59a40a924d3a3ee9222f344459a445bd5925aefd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af7fd7f90d0031996b8164b934877f3168d8b6c6f348055332defd395313a332392ae5a626166911335443b78f8ded3ae4fbd40f5c1ec914d79b95d288337286
|
7
|
+
data.tar.gz: 12bf5d0b7122ef5d551b16ff0ee4aca635d94f92958bc65565283d2de3689ceecedfe8ad9d82c923032b4216dbaa907fd8273010e13b9d2e6df28ab913ea2934
|
data/README.md
CHANGED
@@ -38,9 +38,9 @@ Not Implemented:
|
|
38
38
|
|
39
39
|
## Current Version
|
40
40
|
|
41
|
-
2.
|
41
|
+
2.9.0
|
42
42
|
|
43
|
-
![Version 2.
|
43
|
+
![Version 2.9.0](https://img.shields.io/badge/VERSION-2.9.0-green.svg)
|
44
44
|
|
45
45
|
|
46
46
|
## Requirements
|
@@ -80,8 +80,8 @@ source = "<div class='h-card'><p class='p-name'>Jessica Lynn Suttles</p></div>"
|
|
80
80
|
collection = Microformats2.parse(source)
|
81
81
|
# using singular accessors
|
82
82
|
collection.card.name.to_s #=> "Jessica Lynn Suttles"
|
83
|
-
# using
|
84
|
-
collection.
|
83
|
+
# using :all returns an array
|
84
|
+
collection.card(:all)[0].name(:all).first.to_s #=> "Jessica Lynn Suttles"
|
85
85
|
|
86
86
|
source = "<article class='h-entry'>
|
87
87
|
<h1 class='p-name'>Microformats 2</h1>
|
@@ -90,7 +90,7 @@ source = "<article class='h-entry'>
|
|
90
90
|
collection = Microformats2.parse(source)
|
91
91
|
collection.entry.name.to_s #=> "Microformats 2"
|
92
92
|
# accessing nested microformats
|
93
|
-
collection.entry.author.
|
93
|
+
collection.entry.author.name.to_s #=> "Jessica Lynn Suttles"
|
94
94
|
|
95
95
|
# getting a copy of the canonical microformats2 hash structure
|
96
96
|
collection.to_hash
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Microformats2
|
2
2
|
class Collection
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :items
|
4
4
|
|
5
5
|
def initialize(element, url = nil)
|
6
6
|
@element = element
|
@@ -19,30 +19,37 @@ module Microformats2
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def parse
|
22
|
-
|
22
|
+
items
|
23
23
|
parse_rels
|
24
24
|
self
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
@
|
27
|
+
def items
|
28
|
+
@items ||= FormatParser.parse(@element, @base).each do |format|
|
29
29
|
save_format_name(format.method_name)
|
30
30
|
define_method(format.method_name)
|
31
31
|
set_value(format.method_name, format)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
def all
|
36
|
+
warn "[DEPRECATION] `all` is deprecated and will be removed in the next release. Please use `items` instead."
|
37
|
+
items
|
38
|
+
end
|
39
|
+
|
35
40
|
def first
|
36
|
-
|
41
|
+
warn "[DEPRECATION] `first` is deprecated and will be removed in the next release. Please use `items.first` instead."
|
42
|
+
items.first
|
37
43
|
end
|
38
44
|
|
39
45
|
def last
|
40
|
-
|
46
|
+
warn "[DEPRECATION] `last` is deprecated and will be removed in the next release. Please use `items.last` instead."
|
47
|
+
items.last
|
41
48
|
end
|
42
49
|
|
43
50
|
def to_hash
|
44
51
|
hash = { items: [], rels: @rels }
|
45
|
-
|
52
|
+
items.each do |format|
|
46
53
|
hash[:items] << format.to_hash
|
47
54
|
end
|
48
55
|
hash[:alternates] = @alternates unless @alternates.nil? || @alternates.empty?
|
@@ -64,10 +71,24 @@ module Microformats2
|
|
64
71
|
|
65
72
|
def define_method(mn)
|
66
73
|
unless respond_to?(mn)
|
67
|
-
self.class.class_eval { attr_accessor mn }
|
74
|
+
#self.class.class_eval { attr_accessor mn }
|
75
|
+
self.class.class_eval("
|
76
|
+
def #{mn}(arg = nil);
|
77
|
+
if arg == :all
|
78
|
+
@#{mn}_array
|
79
|
+
else
|
80
|
+
@#{mn}
|
81
|
+
end
|
82
|
+
end")
|
83
|
+
self.class.class_eval("def #{mn}=(x); @#{mn} = x; end")
|
68
84
|
end
|
69
85
|
unless respond_to?(mn.pluralize)
|
70
|
-
self.class.class_eval { attr_accessor mn.pluralize }
|
86
|
+
#self.class.class_eval { attr_accessor mn.pluralize }
|
87
|
+
self.class.class_eval("def #{mn.pluralize};
|
88
|
+
warn \"[DEPRECATION] pluralized accessors are deprecated and will be removed in the next release. Please use `#{mn}(:all)` instead.\"
|
89
|
+
return @#{mn}_array; end")
|
90
|
+
self.class.class_eval("def #{mn.pluralize}=(x); @#{mn}_array = x; end")
|
91
|
+
|
71
92
|
end
|
72
93
|
end
|
73
94
|
|
@@ -75,7 +96,8 @@ module Microformats2
|
|
75
96
|
unless current = send(mn)
|
76
97
|
send("#{mn}=", value)
|
77
98
|
end
|
78
|
-
if current = send(mn
|
99
|
+
if current = send(mn, :all)
|
100
|
+
current = [current] if mn == mn.pluralize #otherwise h-news fails completely
|
79
101
|
current << value
|
80
102
|
else
|
81
103
|
send("#{mn.pluralize}=", [value])
|
data/lib/microformats2/format.rb
CHANGED
@@ -7,18 +7,33 @@ module Microformats2
|
|
7
7
|
def initialize(element, base)
|
8
8
|
@element = element
|
9
9
|
@base = base
|
10
|
-
@method_name = to_method_name(
|
10
|
+
@method_name = to_method_name(type.first)
|
11
11
|
@property_names = []
|
12
|
+
@child_formats = []
|
13
|
+
@child_formats_parsed = false
|
12
14
|
end
|
13
15
|
|
14
16
|
def parse
|
15
|
-
|
17
|
+
type
|
16
18
|
properties
|
17
19
|
self
|
18
20
|
end
|
19
21
|
|
22
|
+
def children
|
23
|
+
unless @child_formats_parsed
|
24
|
+
parse_child_formats
|
25
|
+
@child_formats_parsed = true
|
26
|
+
end
|
27
|
+
@child_formats
|
28
|
+
end
|
29
|
+
|
20
30
|
def format_types
|
21
|
-
|
31
|
+
warn "[DEPRECATION] `format_types` is deprecated and will be removed in the next release. Please use `type` instead."
|
32
|
+
type
|
33
|
+
end
|
34
|
+
|
35
|
+
def type
|
36
|
+
@type ||= @element.attribute("class").to_s.split.select do |html_class|
|
22
37
|
html_class =~ Format::CLASS_REG_EXP
|
23
38
|
end
|
24
39
|
end
|
@@ -33,6 +48,12 @@ module Microformats2
|
|
33
48
|
end
|
34
49
|
end
|
35
50
|
|
51
|
+
def parse_child_formats
|
52
|
+
FormatParser.parse(@element.children, @base, true).each do |child_format|
|
53
|
+
@child_formats.push(child_format)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
36
57
|
def add_property(property_class, value)
|
37
58
|
property = Property.new(nil, property_class, value, @base)
|
38
59
|
assign_property(property)
|
@@ -55,9 +76,15 @@ module Microformats2
|
|
55
76
|
end
|
56
77
|
|
57
78
|
def to_hash
|
58
|
-
hash = { type:
|
79
|
+
hash = { type: type, properties: {} }
|
59
80
|
@property_names.each do |method_name|
|
60
|
-
hash[:properties][method_name.to_sym] = send(method_name
|
81
|
+
hash[:properties][method_name.to_sym] = send(method_name, :all).map(&:to_hash)
|
82
|
+
end
|
83
|
+
unless children.empty?
|
84
|
+
hash[:children] = []
|
85
|
+
children.each do |child_format|
|
86
|
+
hash[:children].push(child_format.to_hash)
|
87
|
+
end
|
61
88
|
end
|
62
89
|
hash
|
63
90
|
end
|
@@ -90,10 +117,23 @@ module Microformats2
|
|
90
117
|
|
91
118
|
def define_method(mn)
|
92
119
|
unless respond_to?(mn)
|
93
|
-
self.singleton_class.class_eval { attr_accessor mn }
|
120
|
+
#self.singleton_class.class_eval { attr_accessor mn }
|
121
|
+
self.singleton_class.class_eval("
|
122
|
+
def #{mn}(arg = nil);
|
123
|
+
if arg == :all
|
124
|
+
@#{mn}_array
|
125
|
+
else
|
126
|
+
@#{mn}
|
127
|
+
end
|
128
|
+
end")
|
129
|
+
self.singleton_class.class_eval("def #{mn}=(x); @#{mn} = x; end")
|
94
130
|
end
|
95
131
|
unless respond_to?(mn.pluralize)
|
96
|
-
self.singleton_class.class_eval { attr_accessor mn.pluralize }
|
132
|
+
#self.singleton_class.class_eval { attr_accessor mn.pluralize }
|
133
|
+
self.singleton_class.class_eval("def #{mn.pluralize};
|
134
|
+
warn \"[DEPRECATION] pluralized accessors are deprecated and will be removed in the next release. Please use `#{mn}(:all)` instead.\"
|
135
|
+
return @#{mn}_array; end")
|
136
|
+
self.singleton_class.class_eval("def #{mn.pluralize}=(x); @#{mn}_array = x; end")
|
97
137
|
end
|
98
138
|
end
|
99
139
|
|
@@ -101,7 +141,7 @@ module Microformats2
|
|
101
141
|
unless current = send(mn)
|
102
142
|
send("#{mn}=", value)
|
103
143
|
end
|
104
|
-
if current = send(mn
|
144
|
+
if current = send(mn,:all)
|
105
145
|
current << value if current.respond_to? :<<
|
106
146
|
else
|
107
147
|
send("#{mn.pluralize}=", [value])
|
@@ -1,28 +1,30 @@
|
|
1
1
|
module Microformats2
|
2
2
|
class FormatParser
|
3
3
|
class << self
|
4
|
-
def parse(element, base=nil)
|
4
|
+
def parse(element, base=nil, parsing_children = false)
|
5
5
|
@@base = base
|
6
|
-
parse_node(element).flatten.compact
|
6
|
+
parse_node(element, parsing_children).flatten.compact
|
7
7
|
end
|
8
8
|
|
9
|
-
def parse_node(node)
|
9
|
+
def parse_node(node, parsing_children=false)
|
10
10
|
case
|
11
|
-
when node.is_a?(Nokogiri::HTML::Document) then parse_node(node.children)
|
12
|
-
when node.is_a?(Nokogiri::XML::NodeSet) then parse_nodeset(node)
|
13
|
-
when node.is_a?(Nokogiri::XML::Element) then [parse_for_microformats(node)]
|
11
|
+
when node.is_a?(Nokogiri::HTML::Document) then parse_node(node.children, parsing_children)
|
12
|
+
when node.is_a?(Nokogiri::XML::NodeSet) then parse_nodeset(node, parsing_children)
|
13
|
+
when node.is_a?(Nokogiri::XML::Element) then [parse_for_microformats(node, parsing_children)]
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def parse_nodeset(nodeset)
|
18
|
-
nodeset.map { |node| parse_node(node) }
|
17
|
+
def parse_nodeset(nodeset, parsing_children=false)
|
18
|
+
nodeset.map { |node| parse_node(node, parsing_children) }
|
19
19
|
end
|
20
20
|
|
21
|
-
def parse_for_microformats(element)
|
22
|
-
if
|
21
|
+
def parse_for_microformats(element, parsing_children=false)
|
22
|
+
if property_classes(element).length >= 1 and parsing_children
|
23
|
+
#do nothing because we don't want properties obj in children
|
24
|
+
elsif format_classes(element).length >= 1
|
23
25
|
parse_microformat(element)
|
24
26
|
else
|
25
|
-
parse_nodeset(element.children)
|
27
|
+
parse_nodeset(element.children, parsing_children)
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
@@ -35,6 +37,12 @@ module Microformats2
|
|
35
37
|
klass.new(element, @@base).parse
|
36
38
|
end
|
37
39
|
|
40
|
+
def property_classes(element)
|
41
|
+
element.attribute("class").to_s.split.select do |html_class|
|
42
|
+
html_class =~ Property::CLASS_REG_EXP
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
38
46
|
def format_classes(element)
|
39
47
|
element.attribute("class").to_s.split.select do |html_class|
|
40
48
|
html_class =~ Format::CLASS_REG_EXP
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module Microformats2
|
2
2
|
module Property
|
3
3
|
class Foundation
|
4
|
+
|
5
|
+
VALUE_CLASS_REG_EXP = /^(value)/
|
6
|
+
VALUE_TITLE_CLASS_REG_EXP = /^(value-title)/
|
7
|
+
|
4
8
|
attr_reader :method_name
|
5
9
|
|
6
10
|
def initialize(element, html_class, string_value=nil, base=nil)
|
@@ -12,7 +16,7 @@ module Microformats2
|
|
12
16
|
|
13
17
|
def parse
|
14
18
|
to_s
|
15
|
-
|
19
|
+
items
|
16
20
|
self
|
17
21
|
end
|
18
22
|
|
@@ -21,18 +25,24 @@ module Microformats2
|
|
21
25
|
end
|
22
26
|
|
23
27
|
def format
|
24
|
-
|
28
|
+
warn "[DEPRECATION] `format` is deprecated and will be removed in the next release. Try just leaving this function out completely (example author.format.name.to_s => author.name.to_s). You can also call `items.first` instead."
|
29
|
+
items.first
|
25
30
|
end
|
26
31
|
|
27
32
|
def formats
|
33
|
+
warn "[DEPRECATION] `formats` is deprecated and will be removed in the next release. Please use `items` instead."
|
34
|
+
items
|
35
|
+
end
|
36
|
+
|
37
|
+
def items
|
28
38
|
@formats ||= format_classes.length >=1 ? FormatParser.parse(@element, @base) : []
|
29
39
|
end
|
30
40
|
|
31
41
|
def to_hash
|
32
|
-
if
|
42
|
+
if items.empty?
|
33
43
|
to_s
|
34
44
|
else
|
35
|
-
{ value: to_s }.merge(
|
45
|
+
{ value: to_s }.merge(items.first.to_hash)
|
36
46
|
end
|
37
47
|
end
|
38
48
|
|
@@ -40,10 +50,45 @@ module Microformats2
|
|
40
50
|
to_hash.to_json
|
41
51
|
end
|
42
52
|
|
53
|
+
def method_missing(name, *arg, &block)
|
54
|
+
fmt = items.first
|
55
|
+
if fmt.respond_to?(name)
|
56
|
+
fmt.send(name)
|
57
|
+
else
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
43
63
|
protected
|
44
64
|
|
45
65
|
def value_class_pattern
|
46
|
-
|
66
|
+
result = value_parse(@element)
|
67
|
+
result = nil if result.empty?
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def value_parse(element)
|
72
|
+
value_parse_node(element).flatten.compact
|
73
|
+
end
|
74
|
+
|
75
|
+
def value_parse_node(node)
|
76
|
+
case
|
77
|
+
when node.is_a?(Nokogiri::XML::NodeSet) then value_parse_nodeset(node)
|
78
|
+
when node.is_a?(Nokogiri::XML::Element) then [parse_for_value_class_pattern(node)]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def value_parse_nodeset(nodeset)
|
83
|
+
nodeset.map { |node| value_parse_node(node) }
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_for_value_class_pattern(element)
|
87
|
+
if value_title_classes(element).length >= 1
|
88
|
+
element.attribute("title").to_s.gsub(/\n+/, " ").gsub(/\s+/, " ").strip
|
89
|
+
elsif value_classes(element).length >= 1
|
90
|
+
element.inner_text.gsub(/\n+/, " ").gsub(/\s+/, " ").strip
|
91
|
+
end
|
47
92
|
end
|
48
93
|
|
49
94
|
def element_value
|
@@ -82,6 +127,17 @@ module Microformats2
|
|
82
127
|
html_class =~ Format::CLASS_REG_EXP
|
83
128
|
end
|
84
129
|
end
|
130
|
+
|
131
|
+
def value_classes(element)
|
132
|
+
element.attribute("class").to_s.split.select do |html_class|
|
133
|
+
html_class =~ VALUE_CLASS_REG_EXP
|
134
|
+
end
|
135
|
+
end
|
136
|
+
def value_title_classes(element)
|
137
|
+
element.attribute("class").to_s.split.select do |html_class|
|
138
|
+
html_class =~ VALUE_TITLE_CLASS_REG_EXP
|
139
|
+
end
|
140
|
+
end
|
85
141
|
end
|
86
142
|
end
|
87
143
|
end
|
@@ -20,6 +20,8 @@ module Microformats2
|
|
20
20
|
def parse_for_properties(element)
|
21
21
|
if property_classes(element).length >= 1
|
22
22
|
parse_property(element)
|
23
|
+
elsif format_classes(element).length >= 1
|
24
|
+
#do nothing because we don't want child elements ending up with their properties here
|
23
25
|
else
|
24
26
|
parse_nodeset(element.children)
|
25
27
|
end
|
data/microformats2.gemspec
CHANGED
@@ -27,4 +27,35 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_development_dependency "rb-fsevent"
|
28
28
|
gem.add_development_dependency "simplecov"
|
29
29
|
gem.add_development_dependency "webmock"
|
30
|
+
|
31
|
+
gem.post_install_message = %q{
|
32
|
+
|
33
|
+
"Calling all. This is our last cry before our eternal silence."
|
34
|
+
- The 2.X version.
|
35
|
+
|
36
|
+
Coming VERY SOON: The 3.0 Version!
|
37
|
+
|
38
|
+
3.0 is a nearly complete re-write of the Microformats Ruby parser.
|
39
|
+
3.0 will fix almost all outstanding issues on the GitHub repo,
|
40
|
+
add classical Microformats support and more! But unfortunately,
|
41
|
+
the cost of doing this is that there will be some breaking changes
|
42
|
+
and changing API.
|
43
|
+
|
44
|
+
The 2.9 release is a transitional release. Really, we want you using 3.0,
|
45
|
+
but 2.9 gives you an opportunity to run your tests, fix any deprecation warnings,
|
46
|
+
and be able to migrate to 3.0 with greater confidence.
|
47
|
+
|
48
|
+
In addition to deprecation warnings on changing methods,
|
49
|
+
there are two changes that will not throw a warning:
|
50
|
+
|
51
|
+
- no more exposed Nokogiri objects
|
52
|
+
- the class names are changing
|
53
|
+
|
54
|
+
If you depend on either of those directly, you'll want to do additional
|
55
|
+
manual acceptance testing in this transition to 2.9 and 3.0.
|
56
|
+
|
57
|
+
<3
|
58
|
+
|
59
|
+
}
|
60
|
+
|
30
61
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: microformats2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shane Becker
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-
|
13
|
+
date: 2017-05-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|
@@ -359,7 +359,19 @@ files:
|
|
359
359
|
homepage: https://github.com/indieweb/microformats2-ruby
|
360
360
|
licenses: []
|
361
361
|
metadata: {}
|
362
|
-
post_install_message:
|
362
|
+
post_install_message: "\n\n \"Calling all. This is our last cry before our eternal
|
363
|
+
silence.\"\n - The 2.X version.\n\n Coming VERY SOON: The 3.0 Version!\n\n 3.0
|
364
|
+
is a nearly complete re-write of the Microformats Ruby parser.\n 3.0 will fix almost
|
365
|
+
all outstanding issues on the GitHub repo,\n add classical Microformats support
|
366
|
+
and more! But unfortunately,\n the cost of doing this is that there will be some
|
367
|
+
breaking changes\n and changing API.\n\n The 2.9 release is a transitional release.
|
368
|
+
Really, we want you using 3.0,\n but 2.9 gives you an opportunity to run your tests,
|
369
|
+
fix any deprecation warnings,\n and be able to migrate to 3.0 with greater confidence.
|
370
|
+
\n\n In addition to deprecation warnings on changing methods,\n there are two
|
371
|
+
changes that will not throw a warning:\n\n - no more exposed Nokogiri objects\n
|
372
|
+
\ - the class names are changing\n\n If you depend on either of those directly,
|
373
|
+
you'll want to do additional\n manual acceptance testing in this transition to
|
374
|
+
2.9 and 3.0.\n\n <3 \n\n "
|
363
375
|
rdoc_options: []
|
364
376
|
require_paths:
|
365
377
|
- lib
|