libis-metadata 0.2.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/metadata +5 -0
- data/lib/libis/metadata/cli/cli_downloader.rb +182 -0
- data/lib/libis/metadata/cli/cli_helper.rb +74 -0
- data/lib/libis/metadata/command_line.rb +25 -0
- data/lib/libis/metadata/downloader.rb +117 -0
- data/lib/libis/metadata/dublin_core_record.rb +115 -0
- data/lib/libis/metadata/field_format.rb +119 -0
- data/lib/libis/metadata/fix_field.rb +33 -0
- data/lib/libis/metadata/mapper.rb +80 -0
- data/lib/libis/metadata/mappers/flandrica.rb +76 -0
- data/lib/libis/metadata/mappers/kuleuven.rb +1929 -0
- data/lib/libis/metadata/mappers/scope.rb +46 -0
- data/lib/libis/metadata/marc21_record.rb +49 -0
- data/lib/libis/metadata/marc_record.rb +285 -0
- data/lib/libis/metadata/parser/basic_parser.rb +116 -0
- data/lib/libis/metadata/parser/dublin_core_parser.rb +35 -0
- data/lib/libis/metadata/parser/marc21_parser.rb +205 -0
- data/lib/libis/metadata/parser/marc_format_parser.rb +51 -0
- data/lib/libis/metadata/parser/marc_rules.rb +34 -0
- data/lib/libis/metadata/parser/marc_select_parser.rb +24 -0
- data/lib/libis/metadata/parser/patch.rb +22 -0
- data/lib/libis/metadata/parser/subfield_criteria_parser.rb +70 -0
- data/lib/libis/metadata/parsers.rb +12 -0
- data/lib/libis/metadata/sharepoint_mapping.rb +119 -0
- data/lib/libis/metadata/sharepoint_record.rb +262 -0
- data/lib/libis/metadata/var_field.rb +242 -0
- data/lib/libis/metadata/version.rb +5 -0
- data/lib/libis/metadata.rb +25 -0
- data/lib/libis-metadata.rb +1 -0
- data/metadata.gemspec +39 -0
- metadata +266 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'parslet'
|
2
|
+
|
3
|
+
require_relative 'basic_parser'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Metadata
|
7
|
+
module Parser
|
8
|
+
# noinspection RubyResolve
|
9
|
+
|
10
|
+
# New style parsers and converters for metadata. New, not finished and untested.
|
11
|
+
class DublinCoreParser < Libis::Metadata::Parser::BasicParser
|
12
|
+
rule(:namespace) {match('[^:]').repeat(1).as(:namespace) >> str(':')}
|
13
|
+
rule(:namespace?) {namespace.maybe}
|
14
|
+
|
15
|
+
rule(:attribute) {namespace? >> name_string.as(:name) >> str('=') >> str('"') >> match('[^"]').repeat(1).as(:value) >> str('"')}
|
16
|
+
rule(:attributes) {attribute >> (spaces >> attribute).repeat}
|
17
|
+
rule(:attributes?) {attributes.maybe}
|
18
|
+
rule(:element) {name_string.as(:element)}
|
19
|
+
rule(:DC) {namespace >> element >> (spaces >> attributes.as(:attributes)).maybe}
|
20
|
+
|
21
|
+
root(:DC)
|
22
|
+
|
23
|
+
def to_target(tree)
|
24
|
+
tree = tree[:DC]
|
25
|
+
return nil unless tree
|
26
|
+
result = "xml['#{tree[:namespace]}'].#{tree[:element]}("
|
27
|
+
tree[:attributes].each {|attribute| result += "'#{attribute[:name]}' => '#{attribute[:value]}'"}
|
28
|
+
result + ').text'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'parslet'
|
2
|
+
|
3
|
+
require_relative 'basic_parser'
|
4
|
+
require_relative 'marc_rules'
|
5
|
+
|
6
|
+
module Libis
|
7
|
+
module Metadata
|
8
|
+
module Parser
|
9
|
+
# noinspection RubyResolve
|
10
|
+
|
11
|
+
# New style parsers and converters for metadata. New, not finished and untested.
|
12
|
+
class Marc21Parser < Libis::Metadata::Parser::BasicParser
|
13
|
+
|
14
|
+
root(:marc21)
|
15
|
+
rule(:marc21) {select.as(:select) | format.as(:format)}
|
16
|
+
|
17
|
+
# select syntax
|
18
|
+
rule(:select) do
|
19
|
+
str('MARC') >>
|
20
|
+
spaces? >> tag.as(:tag) >>
|
21
|
+
spaces? >> indicator.maybe.as(:ind1) >> indicator.maybe.as(:ind2) >>
|
22
|
+
spaces? >> subfield.maybe.as(:subfield) >>
|
23
|
+
spaces? >> condition.maybe.as(:condition)
|
24
|
+
end
|
25
|
+
rule(:condition) {grouped_anonymous(cond_format.as(:cond_format))}
|
26
|
+
rule(:cond_format) {cond_entry.repeat(1).maybe.as(:entry) >> postfix.maybe.as(:postfix)}
|
27
|
+
rule(:cond_entry) {sf_reference | method_call | cond_group}
|
28
|
+
rule(:cond_group) {(prefix.maybe.as(:prefix) >> grouped(cond_format)).as(:cond_group)}
|
29
|
+
|
30
|
+
# Formatting syntax
|
31
|
+
rule(:format) {entry.repeat(1).maybe.as(:entry) >> postfix.maybe.as(:postfix)}
|
32
|
+
|
33
|
+
rule(:entry) {sf_reference | method_call | group}
|
34
|
+
# noinspection RubyArgCount
|
35
|
+
rule(:group) {(prefix.maybe.as(:prefix) >> grouped(format)).as(:group)}
|
36
|
+
# noinspection RubyArgCount
|
37
|
+
rule(:method_call) {(prefix.maybe.as(:prefix) >> sf_indicator >> grouped_anonymous(format, lrparen)).as(:method_call)}
|
38
|
+
|
39
|
+
# pre- and postfix
|
40
|
+
rule(:prefix) {other.repeat(1)}
|
41
|
+
rule(:prefix) {text}
|
42
|
+
rule(:postfix) {other.repeat(1)}
|
43
|
+
rule(:postfix) {text}
|
44
|
+
|
45
|
+
# subfield reference
|
46
|
+
rule(:sf_reference) {sf_variable.as(:subfield) | sf_fixed.as(:fixfield)}
|
47
|
+
|
48
|
+
rule(:sf_variable) {prefix.maybe.as(:prefix) >> sf_indicator >> sf_repeat.maybe.as(:repeat) >> sf_name}
|
49
|
+
rule(:sf_repeat) {star >> any_quoted(:separator).maybe}
|
50
|
+
|
51
|
+
rule(:sf_fixed) {prefix.maybe.as(:prefix) >> sf_indicator >> lsparen >> (sf_range | sf_position | sf_star) >> rsparen}
|
52
|
+
rule(:sf_star) {star.as(:all)}
|
53
|
+
rule(:sf_position) {integer.as(:position)}
|
54
|
+
rule(:sf_range) {integer.as(:first) >> minus >> integer.as(:last)}
|
55
|
+
|
56
|
+
rule(:other) {paren.absent? >> dollar.absent? >> any | litteral_dollar}
|
57
|
+
|
58
|
+
# tag
|
59
|
+
rule(:tag) {tag_numeric | tag_alpha}
|
60
|
+
rule(:tag_numeric) {number.repeat(3, 3)}
|
61
|
+
rule(:tag_alpha) {character.repeat(3, 3)}
|
62
|
+
|
63
|
+
# indicator
|
64
|
+
rule(:indicator) {hashtag | underscore | number | character}
|
65
|
+
|
66
|
+
# subfield
|
67
|
+
rule(:sf_indicator) {dollar}
|
68
|
+
rule(:sf_name) {(character | number).as(:name)}
|
69
|
+
rule(:sf_names) {(character | number).repeat(1).as(:names)}
|
70
|
+
rule(:subfield) {sf_indicator >> sf_name}
|
71
|
+
rule(:litteral_dollar) {dollar >> dollar}
|
72
|
+
|
73
|
+
# noinspection RubyResolve
|
74
|
+
class Transformer < Parslet::Transform
|
75
|
+
rule(name: simple(:name)) {"#{name}"}
|
76
|
+
# select transformation rules
|
77
|
+
rule(cond_group: {
|
78
|
+
prefix: simple(:prefix),
|
79
|
+
lparen: simple(:lparen),
|
80
|
+
entry: simple(:entry),
|
81
|
+
postfix: simple(:postfix),
|
82
|
+
rparen: simple(:rparen)}) {
|
83
|
+
"#{prefix}#{lparen}#{entry}#{postfix}#{rparen}"
|
84
|
+
}
|
85
|
+
rule(cond_group: {
|
86
|
+
prefix: simple(:prefix),
|
87
|
+
lparen: simple(:lparen),
|
88
|
+
entry: sequence(:entry),
|
89
|
+
postfix: simple(:postfix),
|
90
|
+
rparen: simple(:rparen)}) {
|
91
|
+
"#{prefix}#{lparen}#{entry.join}#{postfix}#{rparen}"
|
92
|
+
}
|
93
|
+
rule(cond_format: {
|
94
|
+
entry: sequence(:entry),
|
95
|
+
postfix: simple(:postfix)
|
96
|
+
}) {", Proc.new { |f| #{entry.join}#{postfix} }"}
|
97
|
+
rule(select: {
|
98
|
+
tag: simple(:tag),
|
99
|
+
ind1: simple(:ind1),
|
100
|
+
ind2: simple(:ind2),
|
101
|
+
subfield: simple(:subfield),
|
102
|
+
condition: simple(:condition)
|
103
|
+
}) {"record.select_fields('#{tag}#{ind1 || '#'}#{ind2 || '#'}#{subfield}'#{condition || ''})"}
|
104
|
+
# format transformation rules
|
105
|
+
rule(format: {
|
106
|
+
entry: sequence(:entries),
|
107
|
+
postfix: simple(:postfix)
|
108
|
+
}) do
|
109
|
+
if entries.size == 1 && postfix.nil?
|
110
|
+
entries.first
|
111
|
+
else
|
112
|
+
"field_format(#{entries.join(',')}#{", postfix: '#{postfix}'" if postfix}).to_s"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
rule(group: {
|
116
|
+
prefix: simple(:prefix),
|
117
|
+
lparen: simple(:lparen),
|
118
|
+
entry: nil,
|
119
|
+
postfix: simple(:postfix),
|
120
|
+
rparen: simple(:rparen)}) {
|
121
|
+
"#{prefix}#{lparen}#{postfix}#{rparen}"
|
122
|
+
}
|
123
|
+
rule(group: {
|
124
|
+
prefix: simple(:prefix),
|
125
|
+
lparen: simple(:lparen),
|
126
|
+
entry: '',
|
127
|
+
postfix: simple(:postfix),
|
128
|
+
rparen: simple(:rparen)}) {
|
129
|
+
"#{prefix}#{lparen}#{postfix}#{rparen}"
|
130
|
+
}
|
131
|
+
rule(group: {
|
132
|
+
prefix: simple(:prefix),
|
133
|
+
lparen: simple(:lparen),
|
134
|
+
entry: simple(:entry),
|
135
|
+
postfix: simple(:postfix),
|
136
|
+
rparen: simple(:rparen)}) {
|
137
|
+
"field_format(#{entry}#{", prefix: '#{prefix}#{lparen}'" if prefix || lparen}#{", postfix: '#{postfix}#{rparen}'" if postfix || rparen}).to_s"
|
138
|
+
}
|
139
|
+
rule(group: {
|
140
|
+
prefix: simple(:prefix),
|
141
|
+
lparen: simple(:lparen),
|
142
|
+
entry: sequence(:entries),
|
143
|
+
postfix: simple(:postfix),
|
144
|
+
rparen: simple(:rparen)}) {
|
145
|
+
"field_format(#{entries.join(',')}#{", prefix: '#{prefix}#{lparen}'" if prefix || lparen}#{", postfix: '#{postfix}#{rparen}'" if postfix || rparen}).to_s"
|
146
|
+
}
|
147
|
+
rule(fixfield: {
|
148
|
+
prefix: nil,
|
149
|
+
all: '*'
|
150
|
+
}) {'f[]'}
|
151
|
+
rule(fixfield: {
|
152
|
+
prefix: simple(:prefix),
|
153
|
+
all: '*'
|
154
|
+
}) {"field_format(f[], prefix: '#{prefix}').to_s"}
|
155
|
+
rule(fixfield: {
|
156
|
+
prefix: nil,
|
157
|
+
position: simple(:position)
|
158
|
+
}) {"f[#{position}]"}
|
159
|
+
rule(fixfield: {
|
160
|
+
prefix: simple(:prefix),
|
161
|
+
position: simple(:position)
|
162
|
+
}) do
|
163
|
+
if prefix
|
164
|
+
"field_format(f[#{position}], prefix: '#{prefix}').to_s"
|
165
|
+
else
|
166
|
+
"f[#{position}]"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
rule(fixfield: {
|
170
|
+
prefix: nil,
|
171
|
+
first: simple(:from),
|
172
|
+
last: simple(:to)
|
173
|
+
}) {"f[#{from},#{to}]"}
|
174
|
+
rule(fixfield: {
|
175
|
+
prefix: simple(:prefix),
|
176
|
+
first: simple(:from),
|
177
|
+
last: simple(:to)
|
178
|
+
}) {"field_format(f[#{from},#{to}], prefix: '#{prefix}').to_s"}
|
179
|
+
rule(subfield: {
|
180
|
+
prefix: simple(:prefix),
|
181
|
+
repeat: nil,
|
182
|
+
name: simple(:name),
|
183
|
+
}) {"field_format(f.subfield('#{name}'), prefix: '#{prefix}').to_s"}
|
184
|
+
rule(subfield: {
|
185
|
+
prefix: simple(:prefix),
|
186
|
+
repeat: {separator: simple(:separator)},
|
187
|
+
name: simple(:name),
|
188
|
+
}) {"field_format(f.subfield_array('#{name}')#{", prefix: '#{prefix}'" if prefix}, join: '#{separator}').to_s"}
|
189
|
+
rule(subfield: {
|
190
|
+
prefix: simple(:prefix),
|
191
|
+
repeat: '*',
|
192
|
+
name: simple(:name),
|
193
|
+
}) {"field_format(f.subfield_array('#{name}')#{", prefix: '#{prefix}'" if prefix}, join: ';').to_s"}
|
194
|
+
rule(subfield: {
|
195
|
+
prefix: nil,
|
196
|
+
repeat: nil,
|
197
|
+
name: simple(:name),
|
198
|
+
}) {"f.subfield('#{name}')"}
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'parslet'
|
2
|
+
|
3
|
+
require_relative 'basic_parser'
|
4
|
+
require_relative 'marc_rules'
|
5
|
+
|
6
|
+
module Libis
|
7
|
+
module Metadata
|
8
|
+
module Parser
|
9
|
+
# noinspection RubyResolve
|
10
|
+
|
11
|
+
# New style parsers and converters for metadata. New, not finished and untested.
|
12
|
+
class MarcFormatParser < Libis::Metadata::Parser::BasicParser
|
13
|
+
include Libis::Metadata::Parser::MarcRules
|
14
|
+
|
15
|
+
root(:mapping)
|
16
|
+
|
17
|
+
rule(:mapping) {entry.repeat(1).as(:entry) >> postfix?.as(:postfix)}
|
18
|
+
|
19
|
+
rule(:entry) {group.as(:group) | sf_reference}
|
20
|
+
rule(:group) {prefix?.as(:prefix) >> grouped(mapping)}
|
21
|
+
|
22
|
+
# pre- and postfix
|
23
|
+
rule(:prefix) {other.repeat(1)}
|
24
|
+
rule(:prefix) {text}
|
25
|
+
rule(:prefix?) {prefix.maybe}
|
26
|
+
rule(:postfix) {other.repeat(1)}
|
27
|
+
rule(:postfix) {text}
|
28
|
+
rule(:postfix?) {postfix.maybe}
|
29
|
+
|
30
|
+
# subfield reference
|
31
|
+
rule(:sf_reference) {sf_variable.as(:subfield) | sf_fixed.as(:fixfield)}
|
32
|
+
|
33
|
+
rule(:sf_variable) {prefix?.as(:prefix) >> sf_indicator >> sf_repeat?.as(:repeat) >> sf_name}
|
34
|
+
rule(:sf_repeat) {star >>
|
35
|
+
(dquote >> not_dquote.repeat.as(:separator) >> dquote |
|
36
|
+
squote >> not_squote.repeat.as(:separator) >> squote
|
37
|
+
).maybe
|
38
|
+
}
|
39
|
+
rule(:sf_repeat?) {sf_repeat.maybe}
|
40
|
+
|
41
|
+
rule(:sf_fixed) {prefix?.as(:prefix) >> sf_indicator >> str('@') >> (sf_position | sf_range | sf_star)}
|
42
|
+
rule(:sf_position) {lsparen >> integer.as(:position) >> rsparen}
|
43
|
+
rule(:sf_range) {lsparen >> integer.as(:first) >> minus >> integer.as(:last) >> rsparen}
|
44
|
+
rule(:sf_star) {star.as(:all)}
|
45
|
+
|
46
|
+
rule(:other) {paren.absent? >> dollar.absent? >> any | str('$$')}
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'parslet'
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Metadata
|
5
|
+
module Parser
|
6
|
+
# noinspection RubyResolve
|
7
|
+
|
8
|
+
# New style parsers and converters for metadata. New, not finished and untested.
|
9
|
+
module MarcRules
|
10
|
+
include Parslet
|
11
|
+
|
12
|
+
# tag
|
13
|
+
rule(:tag) {tag_numeric | tag_alpha}
|
14
|
+
rule(:tag_numeric) {number.repeat(3, 3)}
|
15
|
+
rule(:tag_alpha) {character.repeat(3, 3)}
|
16
|
+
|
17
|
+
# indicator
|
18
|
+
rule(:indicator) {hashtag | underscore | number | character}
|
19
|
+
rule(:indicator?) {indicator.maybe}
|
20
|
+
rule(:indicators) {indicator?.as(:ind1) >> indicator?.as(:ind2)}
|
21
|
+
|
22
|
+
# subfield
|
23
|
+
rule(:sf_indicator) {dollar}
|
24
|
+
rule(:sf_name) {(character | number).as(:name)}
|
25
|
+
rule(:sf_name?) {sf_name.maybe}
|
26
|
+
rule(:sf_names) {(character | number).repeat(1).as(:names)}
|
27
|
+
rule(:sf_names?) {sf_names.maybe}
|
28
|
+
rule(:subfield) {sf_indicator >> sf_name}
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'parslet'
|
2
|
+
|
3
|
+
require_relative 'basic_parser'
|
4
|
+
require_relative 'marc_rules'
|
5
|
+
|
6
|
+
module Libis
|
7
|
+
module Metadata
|
8
|
+
module Parser
|
9
|
+
# noinspection RubyResolve
|
10
|
+
|
11
|
+
# New style parsers and converters for metadata. New, not finished and untested.
|
12
|
+
class MarcSelectParser < Libis::Metadata::Parser::BasicParser
|
13
|
+
include Libis::Metadata::MarcRules
|
14
|
+
root(:MARC)
|
15
|
+
rule(:MARC) {str('MARC') >> spaces? >> tag.as(:tag) >> spaces? >> indicators >> spaces? >> subfield.maybe.as(:subfield)}
|
16
|
+
|
17
|
+
# subfield
|
18
|
+
# rule(:sf_condition) { sf_indicator >> sf_names >> (space >> sf_names).repeat }
|
19
|
+
# rule(:sf_names) { sf_name.repeat(1) }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# New style parsers and converters for metadata. New, not finished and untested.
|
2
|
+
class Parslet::Pattern
|
3
|
+
|
4
|
+
def element_match_hash(tree, exp, bindings)
|
5
|
+
return false if exp.size < tree.size
|
6
|
+
exp.each do |expected_key, expected_value|
|
7
|
+
if expected_key.to_s =~ /^(.*)\?$/
|
8
|
+
expected_key = expected_key.is_a?(Symbol) ? $1.to_sym : $1
|
9
|
+
return true unless tree.has_key? expected_key
|
10
|
+
end
|
11
|
+
|
12
|
+
return false unless tree.has_key? expected_key
|
13
|
+
|
14
|
+
# Recurse into the value and stop early on failure
|
15
|
+
value = tree[expected_key]
|
16
|
+
return false unless element_match(value, expected_value, bindings)
|
17
|
+
end
|
18
|
+
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'parslet'
|
2
|
+
|
3
|
+
require_relative 'basic_parser'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Metadata
|
7
|
+
module Parser
|
8
|
+
# noinspection RubyResolve
|
9
|
+
|
10
|
+
# New style parsers and converters for metadata. New, not finished and untested.
|
11
|
+
class SubfieldCriteriaParser < Libis::Metadata::Parser::BasicParser
|
12
|
+
|
13
|
+
root(:criteria)
|
14
|
+
|
15
|
+
rule(:criteria) {selection >> (spaces >> selection).repeat}
|
16
|
+
|
17
|
+
rule(:selection) {must >> must_not.maybe}
|
18
|
+
|
19
|
+
rule(:must) {names.as(:must).maybe >> (one_of | only_one_of).maybe}
|
20
|
+
rule(:must_not) {minus >> must.as(:not)}
|
21
|
+
|
22
|
+
rule(:one_of) {lrparen >> names.as(:one_of) >> rrparen}
|
23
|
+
rule(:only_one_of) {lcparen >> names.as(:only_one_of) >> rcparen}
|
24
|
+
|
25
|
+
rule(:names) {(character | number).repeat(1)}
|
26
|
+
|
27
|
+
def criteria_to_s(criteria)
|
28
|
+
case criteria
|
29
|
+
when Array
|
30
|
+
# leave as is
|
31
|
+
when Hash
|
32
|
+
criteria = [criteria]
|
33
|
+
else
|
34
|
+
return criteria
|
35
|
+
end
|
36
|
+
criteria.map {|selection| selection_to_s(selection)}.join(' ')
|
37
|
+
end
|
38
|
+
|
39
|
+
def selection_to_s(selection)
|
40
|
+
return selection unless selection.is_a? Hash
|
41
|
+
result = "#{selection[:must]}"
|
42
|
+
result += "(#{selection[:one_of]})" if selection[:one_of]
|
43
|
+
result += "{#{selection[:only_one_of]}}" if selection[:only_one_of]
|
44
|
+
result += "-#{selection_to_s(selection[:not])}" if selection[:not]
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
def match_criteria(criteria, data)
|
49
|
+
tree = self.new.parse(criteria)
|
50
|
+
return true if tree.is_a? String
|
51
|
+
tree = [tree] unless tree.is_a? Array
|
52
|
+
tree.map {|selection| match_selection(selection, data)}.any?
|
53
|
+
end
|
54
|
+
|
55
|
+
def match_selection(selection, data)
|
56
|
+
must_match = selection[:must].to_s.split('')
|
57
|
+
return false unless must_match == (must_match & data)
|
58
|
+
one_of = selection[:one_of].to_s.split('')
|
59
|
+
return false unless one_of.empty? || (one_of & data).any?
|
60
|
+
only_one_of = selection[:only_one_of].to_s.split('')
|
61
|
+
return false unless only_one_of.empty? || (only_one_of & data).size != 1
|
62
|
+
return false if match_selection(selection[:not], data) if selection[:not]
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|