micromicro 0.1.0 → 2.0.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/CHANGELOG.md +37 -0
- data/CONTRIBUTING.md +2 -2
- data/README.md +65 -29
- data/lib/micro_micro/collectible.rb +15 -0
- data/lib/micro_micro/collections/base_collection.rb +18 -13
- data/lib/micro_micro/collections/items_collection.rb +7 -0
- data/lib/micro_micro/collections/properties_collection.rb +20 -6
- data/lib/micro_micro/collections/relationships_collection.rb +33 -0
- data/lib/micro_micro/document.rb +36 -44
- data/lib/micro_micro/helpers.rb +82 -0
- data/lib/micro_micro/implied_property.rb +2 -0
- data/lib/micro_micro/item.rb +78 -52
- data/lib/micro_micro/parsers/base_implied_property_parser.rb +29 -0
- data/lib/micro_micro/parsers/base_property_parser.rb +9 -14
- data/lib/micro_micro/parsers/date_time_parser.rb +60 -31
- data/lib/micro_micro/parsers/date_time_property_parser.rb +20 -29
- data/lib/micro_micro/parsers/embedded_markup_property_parser.rb +7 -17
- data/lib/micro_micro/parsers/implied_name_property_parser.rb +17 -58
- data/lib/micro_micro/parsers/implied_photo_property_parser.rb +23 -51
- data/lib/micro_micro/parsers/implied_url_property_parser.rb +13 -42
- data/lib/micro_micro/parsers/plain_text_property_parser.rb +11 -18
- data/lib/micro_micro/parsers/url_property_parser.rb +29 -37
- data/lib/micro_micro/parsers/value_class_pattern_parser.rb +29 -55
- data/lib/micro_micro/property.rb +73 -68
- data/lib/micro_micro/{relation.rb → relationship.rb} +19 -16
- data/lib/micro_micro/version.rb +3 -1
- data/lib/micromicro.rb +37 -22
- data/micromicro.gemspec +14 -9
- metadata +23 -31
- data/.editorconfig +0 -14
- data/.gitignore +0 -34
- data/.gitmodules +0 -3
- data/.reek.yml +0 -8
- data/.rspec +0 -2
- data/.rubocop +0 -3
- data/.rubocop.yml +0 -25
- data/.ruby-version +0 -1
- data/.simplecov +0 -11
- data/.travis.yml +0 -19
- data/Gemfile +0 -14
- data/Rakefile +0 -18
- data/lib/micro_micro/collections/relations_collection.rb +0 -23
@@ -1,68 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MicroMicro
|
2
4
|
module Parsers
|
3
|
-
class ImpliedPhotoPropertyParser <
|
4
|
-
|
5
|
-
|
5
|
+
class ImpliedPhotoPropertyParser < BaseImpliedPropertyParser
|
6
|
+
CSS_SELECTORS_ARRAY = ['> img[src]:only-of-type', '> object[data]:only-of-type'].freeze
|
7
|
+
|
6
8
|
HTML_ELEMENTS_MAP = {
|
7
9
|
'img' => 'src',
|
8
10
|
'object' => 'data'
|
9
11
|
}.freeze
|
10
12
|
|
11
|
-
# @
|
13
|
+
# @see https://microformats.org/wiki/microformats2-parsing#parsing_for_implied_properties
|
14
|
+
# @see https://microformats.org/wiki/microformats2-parsing#parse_an_img_element_for_src_and_alt
|
15
|
+
#
|
16
|
+
# @return [String, Hash{Symbol => String}, nil]
|
12
17
|
def value
|
13
|
-
@value ||=
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
@value ||=
|
19
|
+
if attribute_value
|
20
|
+
return attribute_value unless candidate_node.matches?('img[alt]')
|
21
|
+
|
22
|
+
{
|
23
|
+
value: attribute_value,
|
24
|
+
alt: candidate_node['alt'].strip
|
25
|
+
}
|
26
|
+
end
|
22
27
|
end
|
23
28
|
|
24
29
|
private
|
25
30
|
|
26
|
-
# @return [Array
|
27
|
-
def
|
28
|
-
|
29
|
-
HTML_ELEMENTS_MAP.map do |element, attribute|
|
30
|
-
node if node.matches?("#{element}[#{attribute}]")
|
31
|
-
end.compact
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# @return [String, nil]
|
36
|
-
def resolved_value
|
37
|
-
@resolved_value ||= Absolutely.to_abs(base: node.document.url, relative: unresolved_value.strip) if unresolved_value
|
38
|
-
end
|
31
|
+
# @return [Array]
|
32
|
+
def child_nodes
|
33
|
+
nodes = [node.at_css(*CSS_SELECTORS_ARRAY)]
|
39
34
|
|
40
|
-
|
41
|
-
def unresolved_value
|
42
|
-
@unresolved_value ||= value_node[HTML_ELEMENTS_MAP[value_node.name]] if value_node
|
43
|
-
end
|
44
|
-
|
45
|
-
# @return [Nokogiri::XML::Element, nil]
|
46
|
-
def value_node
|
47
|
-
@value_node ||= begin
|
48
|
-
return attribute_values.first if attribute_values.any?
|
49
|
-
|
50
|
-
HTML_ELEMENTS_MAP.each do |element, attribute|
|
51
|
-
child_node = node.at_css("> #{element}[#{attribute}]:only-of-type")
|
52
|
-
|
53
|
-
return child_node if child_node && !Item.item_node?(child_node) && element == child_node.name && child_node[attribute]
|
54
|
-
end
|
55
|
-
|
56
|
-
if node.element_children.one? && !Item.item_node?(node.first_element_child)
|
57
|
-
HTML_ELEMENTS_MAP.each do |element, attribute|
|
58
|
-
child_node = node.first_element_child.at_css("> #{element}[#{attribute}]:only-of-type")
|
59
|
-
|
60
|
-
return child_node if child_node && !Item.item_node?(child_node) && element == child_node.name && child_node[attribute]
|
61
|
-
end
|
62
|
-
end
|
35
|
+
nodes << node.first_element_child.at_css(*CSS_SELECTORS_ARRAY) if node.element_children.one?
|
63
36
|
|
64
|
-
|
65
|
-
end
|
37
|
+
nodes.compact.reject { |child_node| Helpers.item_node?(child_node) }
|
66
38
|
end
|
67
39
|
end
|
68
40
|
end
|
@@ -1,60 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MicroMicro
|
2
4
|
module Parsers
|
3
|
-
class ImpliedUrlPropertyParser <
|
4
|
-
|
5
|
-
|
5
|
+
class ImpliedUrlPropertyParser < BaseImpliedPropertyParser
|
6
|
+
CSS_SELECTORS_ARRAY = ['> a[href]:only-of-type', '> area[href]:only-of-type'].freeze
|
7
|
+
|
6
8
|
HTML_ELEMENTS_MAP = {
|
7
9
|
'a' => 'href',
|
8
10
|
'area' => 'href'
|
9
11
|
}.freeze
|
10
12
|
|
13
|
+
# @see https://microformats.org/wiki/microformats2-parsing#parsing_for_implied_properties
|
14
|
+
#
|
11
15
|
# @return [String, nil]
|
12
16
|
def value
|
13
|
-
@value ||=
|
17
|
+
@value ||= attribute_value
|
14
18
|
end
|
15
19
|
|
16
20
|
private
|
17
21
|
|
18
|
-
# @return [Array
|
19
|
-
def
|
20
|
-
|
21
|
-
HTML_ELEMENTS_MAP.map do |element, attribute|
|
22
|
-
node if node.matches?("#{element}[#{attribute}]")
|
23
|
-
end.compact
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [String, nil]
|
28
|
-
def resolved_value
|
29
|
-
@resolved_value ||= Absolutely.to_abs(base: node.document.url, relative: unresolved_value.strip) if unresolved_value
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [String, nil]
|
33
|
-
def unresolved_value
|
34
|
-
@unresolved_value ||= value_node[HTML_ELEMENTS_MAP[value_node.name]] if value_node
|
35
|
-
end
|
36
|
-
|
37
|
-
# @return [Nokogiri::XML::Element, nil]
|
38
|
-
def value_node
|
39
|
-
@value_node ||= begin
|
40
|
-
return attribute_values.first if attribute_values.any?
|
41
|
-
|
42
|
-
HTML_ELEMENTS_MAP.each do |element, attribute|
|
43
|
-
child_node = node.at_css("> #{element}[#{attribute}]:only-of-type")
|
44
|
-
|
45
|
-
return child_node if child_node && !Item.item_node?(child_node) && element == child_node.name && child_node[attribute]
|
46
|
-
end
|
47
|
-
|
48
|
-
if node.element_children.one? && !Item.item_node?(node.first_element_child)
|
49
|
-
HTML_ELEMENTS_MAP.each do |element, attribute|
|
50
|
-
child_node = node.first_element_child.at_css("> #{element}[#{attribute}]:only-of-type")
|
22
|
+
# @return [Array]
|
23
|
+
def child_nodes
|
24
|
+
nodes = [node.at_css(*CSS_SELECTORS_ARRAY)]
|
51
25
|
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
26
|
+
nodes << node.first_element_child.at_css(*CSS_SELECTORS_ARRAY) if node.element_children.one?
|
55
27
|
|
56
|
-
|
57
|
-
end
|
28
|
+
nodes.compact.reject { |child_node| Helpers.item_node?(child_node) }
|
58
29
|
end
|
59
30
|
end
|
60
31
|
end
|
@@ -1,38 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MicroMicro
|
2
4
|
module Parsers
|
3
5
|
class PlainTextPropertyParser < BasePropertyParser
|
4
|
-
# @see microformats2 Parsing Specification section 1.3.1
|
5
|
-
# @see http://microformats.org/wiki/microformats2-parsing#parsing_a_p-_property
|
6
6
|
HTML_ATTRIBUTES_MAP = {
|
7
7
|
'title' => %w[abbr link],
|
8
8
|
'value' => %w[data input],
|
9
9
|
'alt' => %w[area img]
|
10
10
|
}.freeze
|
11
11
|
|
12
|
+
# @see https://microformats.org/wiki/microformats2-parsing#parsing_a_p-_property
|
13
|
+
#
|
12
14
|
# @return [String]
|
13
15
|
def value
|
14
|
-
@value ||=
|
15
|
-
return value_class_pattern_parser.value if value_class_pattern_parser.value?
|
16
|
-
return attribute_values.first if attribute_values.any?
|
17
|
-
|
18
|
-
super
|
19
|
-
end
|
16
|
+
@value ||= value_class_pattern_value || attribute_value || super
|
20
17
|
end
|
21
18
|
|
22
19
|
private
|
23
20
|
|
24
|
-
# @return [
|
25
|
-
def
|
26
|
-
|
27
|
-
HTML_ATTRIBUTES_MAP.map do |attribute, names|
|
28
|
-
node[attribute] if names.include?(node.name) && node[attribute]
|
29
|
-
end.compact
|
30
|
-
end
|
21
|
+
# @return [String, nil]
|
22
|
+
def attribute_value
|
23
|
+
Helpers.attribute_value_from(node, HTML_ATTRIBUTES_MAP)
|
31
24
|
end
|
32
25
|
|
33
|
-
# @return [
|
34
|
-
def
|
35
|
-
|
26
|
+
# @return [String, nil]
|
27
|
+
def value_class_pattern_value
|
28
|
+
ValueClassPatternParser.new(node).value
|
36
29
|
end
|
37
30
|
end
|
38
31
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MicroMicro
|
2
4
|
module Parsers
|
3
5
|
class UrlPropertyParser < BasePropertyParser
|
4
|
-
# @see microformats2 Parsing Specification section 1.3.2
|
5
|
-
# @see http://microformats.org/wiki/microformats2-parsing#parsing_a_u-_property
|
6
6
|
HTML_ATTRIBUTES_MAP = {
|
7
7
|
'href' => %w[a area link],
|
8
8
|
'src' => %w[audio iframe img source video],
|
@@ -10,65 +10,57 @@ module MicroMicro
|
|
10
10
|
'data' => %w[object]
|
11
11
|
}.freeze
|
12
12
|
|
13
|
-
# @see microformats2 Parsing Specification section 1.3.2
|
14
|
-
# @see http://microformats.org/wiki/microformats2-parsing#parsing_a_u-_property
|
15
13
|
EXTENDED_HTML_ATTRIBUTES_MAP = {
|
16
14
|
'title' => %w[abbr],
|
17
15
|
'value' => %w[data input]
|
18
16
|
}.freeze
|
19
17
|
|
20
|
-
# @see microformats2
|
21
|
-
# @see
|
18
|
+
# @see https://microformats.org/wiki/microformats2-parsing#parsing_a_u-_property
|
19
|
+
# @see https://microformats.org/wiki/microformats2-parsing#parse_an_img_element_for_src_and_alt
|
22
20
|
#
|
23
21
|
# @return [String, Hash{Symbol => String}]
|
24
22
|
def value
|
25
|
-
@value ||=
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
@value ||=
|
24
|
+
if node.matches?('img[alt]')
|
25
|
+
{
|
26
|
+
value: resolved_value,
|
27
|
+
alt: node['alt'].strip
|
28
|
+
}
|
29
|
+
else
|
30
|
+
resolved_value
|
31
|
+
end
|
33
32
|
end
|
34
33
|
|
35
34
|
private
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
node[attribute] if names.include?(node.name) && node[attribute]
|
41
|
-
end.compact
|
42
|
-
end
|
36
|
+
# @return [String, nil]
|
37
|
+
def attribute_value
|
38
|
+
Helpers.attribute_value_from(node, HTML_ATTRIBUTES_MAP)
|
43
39
|
end
|
44
40
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
node[attribute] if names.include?(node.name) && node[attribute]
|
49
|
-
end
|
50
|
-
end.compact
|
41
|
+
# @return [String, nil]
|
42
|
+
def extended_attribute_value
|
43
|
+
Helpers.attribute_value_from(node, EXTENDED_HTML_ATTRIBUTES_MAP)
|
51
44
|
end
|
52
45
|
|
53
46
|
# @return [String]
|
54
47
|
def resolved_value
|
55
|
-
@resolved_value ||=
|
48
|
+
@resolved_value ||= node.document.resolve_relative_url(unresolved_value.strip)
|
56
49
|
end
|
57
50
|
|
58
51
|
# @return [String]
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
return value_class_pattern_parser.value if value_class_pattern_parser.value?
|
63
|
-
return extended_attribute_values.first if extended_attribute_values.any?
|
52
|
+
def text_content
|
53
|
+
Helpers.text_content_from(node)
|
54
|
+
end
|
64
55
|
|
65
|
-
|
66
|
-
|
56
|
+
# @return [String]
|
57
|
+
def unresolved_value
|
58
|
+
attribute_value || value_class_pattern_value || extended_attribute_value || text_content
|
67
59
|
end
|
68
60
|
|
69
|
-
# @return [
|
70
|
-
def
|
71
|
-
|
61
|
+
# @return [String, nil]
|
62
|
+
def value_class_pattern_value
|
63
|
+
ValueClassPatternParser.new(node).value
|
72
64
|
end
|
73
65
|
end
|
74
66
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MicroMicro
|
2
4
|
module Parsers
|
3
5
|
class ValueClassPatternParser
|
4
|
-
# @see
|
5
|
-
# @see
|
6
|
-
# @see http://microformats.org/wiki/value-class-pattern#Date_and_time_values
|
6
|
+
# @see https://microformats.org/wiki/value-class-pattern#Basic_Parsing
|
7
|
+
# @see https://microformats.org/wiki/value-class-pattern#Date_and_time_values
|
7
8
|
HTML_ATTRIBUTES_MAP = {
|
8
9
|
'alt' => %w[area img],
|
9
10
|
'value' => %w[data],
|
@@ -11,82 +12,55 @@ module MicroMicro
|
|
11
12
|
'datetime' => %w[del ins time]
|
12
13
|
}.freeze
|
13
14
|
|
14
|
-
# @param context [Nokogiri::XML::Element]
|
15
|
-
# @param separator [String]
|
16
|
-
def initialize(node, separator = '')
|
17
|
-
@node = node
|
18
|
-
@separator = separator
|
19
|
-
end
|
20
|
-
|
21
|
-
# @return [String, nil]
|
22
|
-
def value
|
23
|
-
@value ||= values.join(separator).strip if values?
|
24
|
-
end
|
25
|
-
|
26
|
-
# @return [Boolean]
|
27
|
-
def value?
|
28
|
-
value.present?
|
29
|
-
end
|
30
|
-
|
31
|
-
# @return [Array<String>]
|
32
|
-
def values
|
33
|
-
@values ||= value_nodes.map { |value_node| self.class.value_from(value_node) }.select(&:present?)
|
34
|
-
end
|
35
|
-
|
36
|
-
# @return [Boolean]
|
37
|
-
def values?
|
38
|
-
values.any?
|
39
|
-
end
|
40
|
-
|
41
15
|
# @param context [Nokogiri::XML::NodeSet, Nokogiri::XML::Element]
|
42
16
|
# @param node_set [Nokogiri::XML::NodeSet]
|
43
17
|
# @return [Nokogiri::XML::NodeSet]
|
44
|
-
def self.
|
45
|
-
context.each { |node|
|
18
|
+
def self.node_set_from(context, node_set = Nokogiri::XML::NodeSet.new(context.document, []))
|
19
|
+
context.each { |node| node_set_from(node, node_set) } if context.is_a?(Nokogiri::XML::NodeSet)
|
46
20
|
|
47
|
-
if context.is_a?(Nokogiri::XML::Element) && !
|
48
|
-
if value_class_node?(context) || value_title_node?(context)
|
21
|
+
if context.is_a?(Nokogiri::XML::Element) && !Helpers.ignore_node?(context)
|
22
|
+
if Helpers.value_class_node?(context) || Helpers.value_title_node?(context)
|
49
23
|
node_set << context
|
50
24
|
else
|
51
|
-
|
25
|
+
node_set_from(context.element_children, node_set)
|
52
26
|
end
|
53
27
|
end
|
54
28
|
|
55
29
|
node_set
|
56
30
|
end
|
57
31
|
|
58
|
-
# @param node [Nokogiri::XML::Element]
|
59
|
-
# @return [Boolean]
|
60
|
-
def self.value_class_node?(node)
|
61
|
-
node.classes.include?('value')
|
62
|
-
end
|
63
|
-
|
64
32
|
# @param node [Nokogiri::XML::Element]
|
65
33
|
# @return [String, nil]
|
66
34
|
def self.value_from(node)
|
67
|
-
return node['title'] if value_title_node?(node)
|
35
|
+
return node['title'] if Helpers.value_title_node?(node)
|
68
36
|
|
69
|
-
|
70
|
-
|
71
|
-
|
37
|
+
Helpers.attribute_value_from(node, HTML_ATTRIBUTES_MAP) || node.text
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param context [Nokogiri::XML::Element]
|
41
|
+
# @param separator [String]
|
42
|
+
def initialize(node, separator = '')
|
43
|
+
@node = node
|
44
|
+
@separator = separator
|
45
|
+
end
|
72
46
|
|
73
|
-
|
47
|
+
# @return [String, nil]
|
48
|
+
def value
|
49
|
+
@value ||= values.join(separator).strip if values.any?
|
74
50
|
end
|
75
51
|
|
76
|
-
# @
|
77
|
-
|
78
|
-
|
79
|
-
|
52
|
+
# @return [Array<String>]
|
53
|
+
def values
|
54
|
+
@values ||=
|
55
|
+
self.class
|
56
|
+
.node_set_from(node)
|
57
|
+
.map { |value_node| self.class.value_from(value_node) }
|
58
|
+
.select(&:present?)
|
80
59
|
end
|
81
60
|
|
82
61
|
private
|
83
62
|
|
84
63
|
attr_reader :node, :separator
|
85
|
-
|
86
|
-
# @return [Nokogiri::XML::NodeSet]
|
87
|
-
def value_nodes
|
88
|
-
@value_nodes ||= self.class.nodes_from(node)
|
89
|
-
end
|
90
64
|
end
|
91
65
|
end
|
92
66
|
end
|
data/lib/micro_micro/property.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MicroMicro
|
2
4
|
class Property
|
5
|
+
include Collectible
|
6
|
+
|
3
7
|
PROPERTY_PARSERS_MAP = {
|
4
8
|
'dt' => Parsers::DateTimePropertyParser,
|
5
9
|
'e' => Parsers::EmbeddedMarkupPropertyParser,
|
@@ -7,16 +11,46 @@ module MicroMicro
|
|
7
11
|
'u' => Parsers::UrlPropertyParser
|
8
12
|
}.freeze
|
9
13
|
|
10
|
-
attr_accessor :collection
|
11
14
|
attr_reader :name, :node, :prefix
|
12
15
|
|
16
|
+
# @param context [Nokogiri::XML::NodeSet, Nokogiri::XML::Element]
|
17
|
+
# @return [Array<MicroMicro::Property>]
|
18
|
+
def self.from_context(context)
|
19
|
+
node_set_from(context).flat_map do |node|
|
20
|
+
Helpers.property_class_names_from(node).map { |token| new(node, token) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param context [Nokogiri::XML::NodeSet, Nokogiri::XML::Element]
|
25
|
+
# @param node_set [Nokogiri::XML::NodeSet]
|
26
|
+
# @return [Nokogiri::XML::NodeSet]
|
27
|
+
def self.node_set_from(context, node_set = Nokogiri::XML::NodeSet.new(context.document, []))
|
28
|
+
context.each { |node| node_set_from(node, node_set) } if context.is_a?(Nokogiri::XML::NodeSet)
|
29
|
+
|
30
|
+
if context.is_a?(Nokogiri::XML::Element) && !Helpers.ignore_node?(context)
|
31
|
+
node_set << context if Helpers.property_node?(context)
|
32
|
+
|
33
|
+
node_set_from(context.element_children, node_set) unless Helpers.item_node?(context)
|
34
|
+
end
|
35
|
+
|
36
|
+
node_set
|
37
|
+
end
|
38
|
+
|
13
39
|
# @param node [Nokogiri::XML::Element]
|
14
|
-
# @param
|
15
|
-
|
16
|
-
def initialize(node, name:, prefix:)
|
40
|
+
# @param token [String]
|
41
|
+
def initialize(node, token)
|
17
42
|
@node = node
|
18
|
-
@name =
|
19
|
-
|
43
|
+
@prefix, @name = token.split(/-/, 2)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Boolean]
|
47
|
+
def date_time_property?
|
48
|
+
prefix == 'dt'
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Boolean]
|
52
|
+
def embedded_markup_property?
|
53
|
+
prefix == 'e'
|
20
54
|
end
|
21
55
|
|
22
56
|
# @return [Boolean]
|
@@ -24,91 +58,62 @@ module MicroMicro
|
|
24
58
|
false
|
25
59
|
end
|
26
60
|
|
61
|
+
# :nocov:
|
27
62
|
# @return [String]
|
28
63
|
def inspect
|
29
|
-
|
64
|
+
"#<#{self.class}:#{format('%#0x', object_id)} " \
|
65
|
+
"name: #{name.inspect}, " \
|
66
|
+
"prefix: #{prefix.inspect}, " \
|
67
|
+
"value: #{value.inspect}>"
|
68
|
+
end
|
69
|
+
# :nocov:
|
70
|
+
|
71
|
+
# @return [MicroMicro::Item, nil]
|
72
|
+
def item
|
73
|
+
@item ||= Item.new(node) if item_node?
|
30
74
|
end
|
31
75
|
|
32
76
|
# @return [Boolean]
|
33
77
|
def item_node?
|
34
|
-
@item_node ||=
|
78
|
+
@item_node ||= Helpers.item_node?(node)
|
35
79
|
end
|
36
80
|
|
37
|
-
# @return [
|
38
|
-
def
|
39
|
-
|
40
|
-
return parser.value unless item_node?
|
41
|
-
|
42
|
-
item.value = item_value
|
43
|
-
|
44
|
-
item
|
45
|
-
end
|
81
|
+
# @return [Boolean]
|
82
|
+
def plain_text_property?
|
83
|
+
prefix == 'p'
|
46
84
|
end
|
47
85
|
|
48
86
|
# @return [Boolean]
|
49
|
-
def
|
50
|
-
|
87
|
+
def url_property?
|
88
|
+
prefix == 'u'
|
51
89
|
end
|
52
90
|
|
53
|
-
# @
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
|
91
|
+
# @return [String, Hash]
|
92
|
+
# rubocop:disable Metrics
|
93
|
+
def value
|
94
|
+
@value ||=
|
95
|
+
if item_node?
|
96
|
+
hash = item.to_h
|
58
97
|
|
59
|
-
|
60
|
-
node_set << context if property_node?(context)
|
98
|
+
return hash.merge(parser.value) if embedded_markup_property?
|
61
99
|
|
62
|
-
|
63
|
-
|
100
|
+
p_property = item.properties.find { |property| property.name == 'name' } if plain_text_property?
|
101
|
+
u_property = item.properties.find { |property| property.name == 'url' } if url_property?
|
64
102
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# @return [Array<MicroMicro::Property>]
|
70
|
-
def self.properties_from(context)
|
71
|
-
nodes_from(context).map do |node|
|
72
|
-
types_from(node).map { |prefix, name| new(node, name: name, prefix: prefix) }
|
73
|
-
end.flatten
|
103
|
+
hash.merge(value: (p_property || u_property || parser).value)
|
104
|
+
else
|
105
|
+
parser.value
|
106
|
+
end
|
74
107
|
end
|
108
|
+
# rubocop:enable Metrics
|
75
109
|
|
76
|
-
# @param node [Nokogiri::XML::Element]
|
77
110
|
# @return [Boolean]
|
78
|
-
def
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
# @param node [Nokogiri::XML::Element]
|
83
|
-
# @return [Array<Array(String, String)>]
|
84
|
-
#
|
85
|
-
# @example
|
86
|
-
# node = Nokogiri::HTML('<a href="https://sixtwothree.org" class="p-name u-url">Jason Garber</a>').at_css('a')
|
87
|
-
# MicroMicro::Property.types_from(node) #=> [['p', 'name'], ['u', 'url']]
|
88
|
-
def self.types_from(node)
|
89
|
-
node.classes.select { |token| token.match?(/^(?:dt|e|p|u)(?:\-[0-9a-z]+)?(?:\-[a-z]+)+$/) }.map { |token| token.split(/\-/, 2) }.uniq
|
111
|
+
def value?
|
112
|
+
value.present?
|
90
113
|
end
|
91
114
|
|
92
115
|
private
|
93
116
|
|
94
|
-
# @return [MicroMicro::Item, nil]
|
95
|
-
def item
|
96
|
-
@item ||= Item.new(node) if item_node?
|
97
|
-
end
|
98
|
-
|
99
|
-
# @reutrn [String, nil]
|
100
|
-
def item_value
|
101
|
-
return unless item_node?
|
102
|
-
|
103
|
-
obj_by_prefix = case prefix
|
104
|
-
when 'e' then item
|
105
|
-
when 'p' then item.properties.find { |property| property.name == 'name' }
|
106
|
-
when 'u' then item.properties.find { |property| property.name == 'url' }
|
107
|
-
end
|
108
|
-
|
109
|
-
(obj_by_prefix || parser).value
|
110
|
-
end
|
111
|
-
|
112
117
|
def parser
|
113
118
|
@parser ||= PROPERTY_PARSERS_MAP[prefix].new(self)
|
114
119
|
end
|