microformats2 2.1.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-

|
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
|