rdf-vocab 2.0.0 → 2.0.1
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 +8 -1
- data/lib/rdf/vocab/extensions.rb +475 -2
- data/spec/extensions_spec.rb +356 -0
- data/spec/matchers.rb +28 -0
- data/spec/spec_helper.rb +3 -1
- metadata +125 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb1e1b3846cdba7d14e15c200cc8ea1d3e15e712
|
4
|
+
data.tar.gz: d787b2d4898d7c9c62d95a422b31d9d8bb5cad09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 042f2e6832b90e4c9c48d68d446f6c5535d201352db7be8a673685bdd7a81eea51d06b8dfa96e57292690813b38878552ef247817d6a66f85bb4d15444aabeda
|
7
|
+
data.tar.gz: 5d570b5447478ecb809df8fc8e9655cdc6683a6c67bb86857eab15d4ffe95f25a560fdf0b250dae4e5980e14d097f338aa37a063e60510b492636abce4703bc6
|
data/README.md
CHANGED
@@ -4,7 +4,12 @@ Common OWL/RDFS Vocabularies for use with Ruby [RDF.rb][]
|
|
4
4
|
[](http://badge.fury.io/rb/rdf-vocab)
|
5
5
|
[](http://travis-ci.org/ruby-rdf/rdf-vocab)
|
6
6
|
|
7
|
-
##
|
7
|
+
## Extensions
|
8
|
+
This gem extends `RDF::Vocabulary` with `#to_ttl`, `#to_jsonld`, and `#to_html` methods to create special-purpose vocabulary serializations. The HTML version is templated using a Haml template to allow output to be customized.
|
9
|
+
|
10
|
+
Also extends `RDF::Vocabulary::Format` with the `gen-vocab` command extension to the `rdf` executable.
|
11
|
+
|
12
|
+
## Vocabularies
|
8
13
|
|
9
14
|
* RDF::Vocab::ACL - [Web Access Control](http://www.w3.org/wiki/WebAccessControl) (W3C)
|
10
15
|
* RDF::Vocab::Bibframe - [Bibliographic Framework Initiaitive](http://bibframe.org/vocab/) (LoC)
|
@@ -80,6 +85,8 @@ then
|
|
80
85
|
|
81
86
|
This will load all the vocabulary classes in the library.
|
82
87
|
|
88
|
+
Also adds the `gen-vocab` command to the `rdf` command-line executable to generate specifically generated output in Turtle, JSON-LD, and HTML+RDFa for either built-in or arbitrary vocabularies.
|
89
|
+
|
83
90
|
## Adding new vocabularies
|
84
91
|
|
85
92
|
* First, add an entry to `lib/rdf/vocab.rb`, the key names contained within
|
data/lib/rdf/vocab/extensions.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'rdf'
|
2
1
|
# frozen_string_literal: true
|
2
|
+
require 'rdf'
|
3
3
|
require 'rdf/vocabulary'
|
4
4
|
require 'rdf/vocab'
|
5
5
|
|
@@ -20,7 +20,6 @@ module RDF
|
|
20
20
|
# Ruby's autoloading facility, meaning that `@@subclasses` will be
|
21
21
|
# empty until each subclass has been touched or require'd.
|
22
22
|
RDF::Vocab::VOCABS.each do |n, params|
|
23
|
-
class_name = params.fetch(:class_name, n.upcase).to_sym
|
24
23
|
begin
|
25
24
|
require "rdf/vocab/#{n}"
|
26
25
|
rescue LoadError
|
@@ -30,6 +29,480 @@ module RDF
|
|
30
29
|
end
|
31
30
|
_orig_each(&block)
|
32
31
|
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
require 'rdf/turtle'
|
35
|
+
##
|
36
|
+
# Generate Turtle representation, specific to vocabularies
|
37
|
+
#
|
38
|
+
# @param [RDF::Queryable] :graph Optional graph, otherwise uses statements from vocabulary.
|
39
|
+
# @param [Hash{#to_sym => String}] Prefixes to add to output
|
40
|
+
# @return [String]
|
41
|
+
def to_ttl(graph: nil, prefixes: nil)
|
42
|
+
output = []
|
43
|
+
|
44
|
+
# Find namespaces used in the vocabulary
|
45
|
+
graph = RDF::Graph.new {|g| each_statement {|s| g << s}} if graph.nil? || graph.empty?
|
46
|
+
|
47
|
+
prefixes = vocab_prefixes(graph).merge(prefixes || {})
|
48
|
+
pfx_width = prefixes.keys.map(&:to_s).map(&:length).max
|
49
|
+
prefixes.each do |pfx, uri|
|
50
|
+
output << "@prefix %*s: <%s> .\n" % [pfx_width, pfx, uri]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Determine the category for each subject in the vocabulary graph
|
54
|
+
cats = subject_categories(graph)
|
55
|
+
|
56
|
+
writer = RDF::Turtle::Writer.new(StringIO.new, prefixes: prefixes)
|
57
|
+
|
58
|
+
{
|
59
|
+
ont: {
|
60
|
+
heading: "# #{__name__.split('::').last} Vocabulary definition\n"
|
61
|
+
},
|
62
|
+
classes: {
|
63
|
+
heading: "# Class definitions\n"
|
64
|
+
},
|
65
|
+
properties: {
|
66
|
+
heading: "# Property definitions\n"
|
67
|
+
},
|
68
|
+
datatypes: {
|
69
|
+
heading: "# Datatype definitions\n"
|
70
|
+
},
|
71
|
+
other: {
|
72
|
+
heading: "# Other definitions\n"
|
73
|
+
}
|
74
|
+
}.each do |key, hash|
|
75
|
+
next unless cats[key]
|
76
|
+
|
77
|
+
output << "\n\n#{hash[:heading]}"
|
78
|
+
|
79
|
+
cats[key].each do |subject|
|
80
|
+
po = {}
|
81
|
+
|
82
|
+
# Group predicates with their values
|
83
|
+
graph.query(subject: subject) do |statement|
|
84
|
+
# Sanity check this, as these are set to an empty string if not defined.
|
85
|
+
next if [RDF::RDFS.label, RDF::RDFS.comment].include?(statement.predicate) && statement.object.to_s.empty?
|
86
|
+
po[statement.predicate] ||= []
|
87
|
+
po[statement.predicate] << statement.object
|
88
|
+
end
|
89
|
+
|
90
|
+
next if po.empty?
|
91
|
+
|
92
|
+
po_list = []
|
93
|
+
unless (types = po.delete(RDF.type)).empty?
|
94
|
+
po_list << 'a ' + types.map {|o| writer.format_term(o)}.join(", ")
|
95
|
+
end
|
96
|
+
|
97
|
+
# Serialize other predicate/objects
|
98
|
+
po.each do |predicate, objects|
|
99
|
+
resource = predicate.qname ? predicate.pname : "<#{predicate}>"
|
100
|
+
po_list << resource + ' ' + objects.map {|o| writer.format_term(o)}.join(", ")
|
101
|
+
end
|
102
|
+
|
103
|
+
# Output statements for this subject
|
104
|
+
subj = subject.qname ? subject.pname : "<#{subject}>"
|
105
|
+
output << "#{subj} " + po_list.join(";\n ") + "\n .\n"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
output.join("")
|
110
|
+
end
|
111
|
+
rescue LoadError
|
112
|
+
# No Turtle serialization unless gem loaded
|
113
|
+
end
|
114
|
+
|
115
|
+
begin
|
116
|
+
require 'json/ld'
|
117
|
+
|
118
|
+
##
|
119
|
+
# Generate JSON-LD representation, specific to vocabularies
|
120
|
+
#
|
121
|
+
# @param [RDF::Queryable] :graph Optional graph, otherwise uses statements from vocabulary.
|
122
|
+
# @param [Hash{#to_sym => String}] Prefixes to add to output
|
123
|
+
# @return [String]
|
124
|
+
def to_jsonld(graph: nil, prefixes: nil)
|
125
|
+
context = {}
|
126
|
+
rdfs_context = ::JSON.parse %({
|
127
|
+
"dc:title": {"@container": "@language"},
|
128
|
+
"dc:description": {"@container": "@language"},
|
129
|
+
"dc:date": {"@type": "xsd:date"},
|
130
|
+
"rdfs:comment": {"@container": "@language"},
|
131
|
+
"rdfs:domain": {"@type": "@vocab"},
|
132
|
+
"rdfs:label": {"@container": "@language"},
|
133
|
+
"rdfs:range": {"@type": "@vocab"},
|
134
|
+
"rdfs:seeAlso": {"@type": "@id"},
|
135
|
+
"rdfs:subClassOf": {"@type": "@vocab"},
|
136
|
+
"rdfs:subPropertyOf": {"@type": "@vocab"},
|
137
|
+
"schema:domainIncludes": {"@type": "@vocab"},
|
138
|
+
"schema:rangeIncludes": {"@type": "@vocab"},
|
139
|
+
"owl:equivalentClass": {"@type": "@vocab"},
|
140
|
+
"owl:equivalentProperty": {"@type": "@vocab"},
|
141
|
+
"owl:oneOf": {"@container": "@list", "@type": "@vocab"},
|
142
|
+
"owl:imports": {"@type": "@id"},
|
143
|
+
"owl:versionInfo": {"@type": "@id"},
|
144
|
+
"owl:inverseOf": {"@type": "@vocab"},
|
145
|
+
"owl:unionOf": {"@type": "@vocab", "@container": "@list"},
|
146
|
+
"rdfs_classes": {"@reverse": "rdfs:isDefinedBy", "@type": "@id"},
|
147
|
+
"rdfs_properties": {"@reverse": "rdfs:isDefinedBy", "@type": "@id"},
|
148
|
+
"rdfs_datatypes": {"@reverse": "rdfs:isDefinedBy", "@type": "@id"},
|
149
|
+
"rdfs_instances": {"@reverse": "rdfs:isDefinedBy", "@type": "@id"}
|
150
|
+
})
|
151
|
+
rdfs_classes, rdfs_properties, rdfs_datatypes, rdfs_instances = [], [], [], [], []
|
152
|
+
|
153
|
+
ontology = {
|
154
|
+
"@context" => rdfs_context,
|
155
|
+
"@id" => to_uri.to_s
|
156
|
+
}
|
157
|
+
|
158
|
+
# Find namespaces used in the vocabulary
|
159
|
+
graph = RDF::Graph.new {|g| each_statement {|s| g << s}} if graph.nil? || graph.empty?
|
160
|
+
|
161
|
+
prefixes = vocab_prefixes(graph).merge(prefixes || {})
|
162
|
+
prefixes.each do |pfx, uri|
|
163
|
+
context[pfx.to_s] = uri.to_s unless pfx.to_s.empty?
|
164
|
+
end
|
165
|
+
|
166
|
+
# Determine the category for each subject in the vocabulary graph
|
167
|
+
cats = subject_categories(graph)
|
168
|
+
|
169
|
+
# Generate term definitions from graph subjects
|
170
|
+
cats.values.flatten.each do |term|
|
171
|
+
next unless Array(term.qname).length == 2
|
172
|
+
context[term.qname.last.to_s] = term.to_uri.to_s
|
173
|
+
end
|
174
|
+
|
175
|
+
# Parse the two contexts so we know what terms are in scope
|
176
|
+
jld_context = ::JSON::LD::Context.new.parse([context, rdfs_context])
|
177
|
+
|
178
|
+
{
|
179
|
+
ont: {
|
180
|
+
heading: "# #{__name__.split('::').last} Vocabulary definition\n",
|
181
|
+
bucket: ontology,
|
182
|
+
},
|
183
|
+
classes: {
|
184
|
+
heading: "# Class definitions\n",
|
185
|
+
bucket: rdfs_classes,
|
186
|
+
rev_prop: "rdfs_classes"
|
187
|
+
},
|
188
|
+
properties: {
|
189
|
+
heading: "# Property definitions\n",
|
190
|
+
bucket: rdfs_properties,
|
191
|
+
rev_prop: "rdfs_properties"
|
192
|
+
},
|
193
|
+
datatypes: {
|
194
|
+
heading: "# Datatype definitions\n",
|
195
|
+
bucket: rdfs_datatypes,
|
196
|
+
rev_prop: "rdfs_datatypes"
|
197
|
+
},
|
198
|
+
other: {
|
199
|
+
heading: "# Other definitions\n",
|
200
|
+
bucket: rdfs_instances,
|
201
|
+
rev_prop: "rdfs_instances"
|
202
|
+
}
|
203
|
+
}.each do |key, hash|
|
204
|
+
next unless cats[key]
|
205
|
+
|
206
|
+
cats[key].each do |subject|
|
207
|
+
node = {"@id" => subject.pname}
|
208
|
+
po = {}
|
209
|
+
|
210
|
+
# Group predicates with their values
|
211
|
+
graph.query(subject: subject) do |statement|
|
212
|
+
# Sanity check this, as these are set to an empty string if not defined.
|
213
|
+
next if [RDF::RDFS.label, RDF::RDFS.comment].include?(statement.predicate) && statement.object.to_s.empty?
|
214
|
+
po[statement.predicate] ||= []
|
215
|
+
po[statement.predicate] << statement.object
|
216
|
+
end
|
217
|
+
|
218
|
+
next if po.empty?
|
219
|
+
|
220
|
+
node['@type'] = po.delete(RDF.type).map {|t| jld_context.compact_iri(t, vocab: true)}
|
221
|
+
|
222
|
+
po.each do |predicate, objects|
|
223
|
+
term = jld_context.compact_iri(predicate, vocab: true)
|
224
|
+
node[term] = if jld_context.container(term) == '@language'
|
225
|
+
lang_map = objects.inject({}) do |memo, o|
|
226
|
+
raise "Language-mapped term #{term} with non plain-literal #{o.inspect}" unless o.literal? && o.plain?
|
227
|
+
memo.merge(o.language.to_s => o.value)
|
228
|
+
end
|
229
|
+
# Don't use language map if there's only one entry with no language
|
230
|
+
lang_map = lang_map[""] if lang_map.keys == [""]
|
231
|
+
[lang_map]
|
232
|
+
else
|
233
|
+
objects.map do |o|
|
234
|
+
expanded_value = jld_context.expand_value(term, o)
|
235
|
+
jld_context.compact_value(term, expanded_value)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
node.each do |property, values|
|
241
|
+
case values.length
|
242
|
+
when 0 then node.delete(property)
|
243
|
+
when 1 then node[property] = values.first
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# Either set bucket from node, or append node to bucket
|
248
|
+
if hash[:bucket].is_a?(Hash)
|
249
|
+
hash[:bucket].merge!(node)
|
250
|
+
else
|
251
|
+
ontology[hash[:rev_prop]] ||= hash[:bucket]
|
252
|
+
hash[:bucket] << node
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Serialize result
|
258
|
+
{
|
259
|
+
"@context" => context,
|
260
|
+
"@graph" => ontology
|
261
|
+
}.to_json(::JSON::LD::JSON_STATE)
|
262
|
+
end
|
263
|
+
rescue LoadError
|
264
|
+
# No JSON-LD serialization unless gem loaded
|
265
|
+
end
|
266
|
+
|
267
|
+
##
|
268
|
+
# Generate HTML+RDFa representation, specific to vocabularies. This uses generated JSON-LD and a Haml template.
|
269
|
+
#
|
270
|
+
# @param [RDF::Queryable] :graph Optional graph, otherwise uses statements from vocabulary.
|
271
|
+
# @param [Hash{#to_sym => String}] Prefixes to add to output
|
272
|
+
# @param [String, Hash] jsonld
|
273
|
+
# If not provided, the `to_jsonld` method is used to generate it.
|
274
|
+
# @param [String] template The path to a Haml or ERB template used to generate the output using the JSON-LD serialization
|
275
|
+
# @return [String]
|
276
|
+
def to_html(graph: nil, prefixes: nil, jsonld: nil, template: nil)
|
277
|
+
# Find namespaces used in the vocabulary
|
278
|
+
graph = RDF::Graph.new {|g| each_statement {|s| g << s}} if graph.nil? || graph.empty?
|
279
|
+
|
280
|
+
# Get JSON as an object
|
281
|
+
json = case jsonld
|
282
|
+
when String then ::JSON.parse(File.read jsonld)
|
283
|
+
when Hash then jsonld
|
284
|
+
else
|
285
|
+
::JSON.parse(to_jsonld(graph: graph, prefixes: prefixes))
|
286
|
+
end
|
287
|
+
raise "Expected JSON-LD data within the '@graph' key" unless json.has_key?('@graph')
|
288
|
+
|
289
|
+
template ||= File.expand_path("../../../../etc/template.erb", __FILE__)
|
290
|
+
|
291
|
+
prefixes = vocab_prefixes(graph).merge(prefixes || {})
|
292
|
+
prefixes[:owl] = RDF::OWL.to_uri.to_s
|
293
|
+
|
294
|
+
# Make sure ontology is typed
|
295
|
+
json['@graph']['@type'] ||= ['owl:Ontology']
|
296
|
+
|
297
|
+
jld_context = ::JSON::LD::Context.new.parse([json['@context'], json['@graph']['@context']])
|
298
|
+
|
299
|
+
# Expand the JSON-LD to normalize accesses
|
300
|
+
expanded = ::JSON::LD::API.expand(json).first
|
301
|
+
expanded.delete('@reverse')
|
302
|
+
|
303
|
+
# Re-compact keys
|
304
|
+
expanded = expanded.inject({}) do |memo, (k, v)|
|
305
|
+
term = RDF::Vocabulary.find_term(k)
|
306
|
+
k = term.pname if term
|
307
|
+
memo.merge(k => v)
|
308
|
+
end
|
309
|
+
|
310
|
+
# Normalize label accessors
|
311
|
+
expanded['rdfs:label'] ||= %w(dc:title dc11:title skos:prefLabel).inject(nil) do |memo, key|
|
312
|
+
memo || expanded[key]
|
313
|
+
end || [{'@value' => json['@graph']['@id']}]
|
314
|
+
%w(rdfs_classes rdfs_properties rdfs_datatypes rdfs_instances).each do |section|
|
315
|
+
next unless json['@graph'][section]
|
316
|
+
json['@graph'][section].each do |node|
|
317
|
+
node['rdfs:label'] ||= %w(dc:title dc11:title skos:prefLabel).inject do |memo, key|
|
318
|
+
memo || node[key]
|
319
|
+
end || [{'@value' => node['@id']}]
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
# Expand each part separately, as well.
|
324
|
+
%w(rdfs_classes rdfs_properties rdfs_datatypes rdfs_instances).each do |section|
|
325
|
+
next unless json['@graph'][section]
|
326
|
+
expanded_section = ::JSON::LD::API.expand(json['@graph'][section], expandContext: jld_context)
|
327
|
+
# Re-compact keys
|
328
|
+
expanded[section] = expanded_section.map do |node|
|
329
|
+
node.inject({}) do |memo, (k, v)|
|
330
|
+
term = RDF::Vocabulary.find_term(k)
|
331
|
+
k = term.pname if term
|
332
|
+
memo.merge(k => v)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
# Template invoked with expanded JSON-LD with outer object including `rdfs_classes`, `rdfs_properties`, and `rdf_instances` sections.
|
338
|
+
case template
|
339
|
+
when /.haml$/
|
340
|
+
require 'haml'
|
341
|
+
haml = Haml::Engine.new(File.read(template))
|
342
|
+
haml.render(self, ont: expanded, context: json['@context'], prefixes: prefixes)
|
343
|
+
when /.erb$/
|
344
|
+
require 'erubis'
|
345
|
+
eruby = Erubis::FastEruby.new(File.read(template))
|
346
|
+
result = eruby.evaluate(binding: self, ont: expanded, context: json['@context'], prefixes: prefixes)
|
347
|
+
else
|
348
|
+
raise "Unknown template type #{template}. Should have '.erb' or '.haml' extension"
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
##
|
353
|
+
# Create HTML for values (Helper method, needs to be public)
|
354
|
+
def value_to_html(property, value, tag)
|
355
|
+
value.map do |v|
|
356
|
+
%(<#{tag} property="#{property}") +
|
357
|
+
if v['@value']
|
358
|
+
(v['@language'] ? %( language="#{v['@language']}") : "") +
|
359
|
+
(v['@type'] ? %( datatype="#{RDF::URI(v['@type']).pname}") : "") +
|
360
|
+
%(>#{v['@value']})
|
361
|
+
elsif v['@id']
|
362
|
+
%( resource="#{RDF::URI(v['@id']).pname}">#{RDF::URI(v['@id']).pname})
|
363
|
+
else
|
364
|
+
raise "Unknown value type: #{v.inspect}, #{property}"
|
365
|
+
end +
|
366
|
+
%(</#{tag}>)
|
367
|
+
end.join("\n")
|
368
|
+
end
|
369
|
+
private
|
370
|
+
|
371
|
+
##
|
372
|
+
# Prefixes used in this vocabulary
|
373
|
+
#
|
374
|
+
# @param [RDF::Graph] graph
|
375
|
+
# @return [Hash{Symbol => RDF::URI}]
|
376
|
+
def vocab_prefixes(graph)
|
377
|
+
vocabs = graph.
|
378
|
+
terms.
|
379
|
+
select(&:uri?).
|
380
|
+
map {|u| RDF::Vocabulary.find(u)}.
|
381
|
+
uniq.
|
382
|
+
compact.
|
383
|
+
sort_by(&:__prefix__)
|
384
|
+
vocabs << RDF::XSD # incase we need it for a literal
|
385
|
+
|
386
|
+
# Generate prefix definitions
|
387
|
+
vocabs.inject({}) do |memo, v|
|
388
|
+
memo.merge(v.__prefix__ => v.to_uri)
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
##
|
393
|
+
# Categorize each subject in the graph
|
394
|
+
#
|
395
|
+
# @param [RDF::Graph] graph
|
396
|
+
# @return [Hash{RDF::URI => Symbol}]
|
397
|
+
def subject_categories(graph)
|
398
|
+
cats = {}
|
399
|
+
categorized = {}
|
400
|
+
uncategorized = {}
|
401
|
+
graph.query(predicate: RDF.type) do |statement|
|
402
|
+
# Only serialize statements that are in the defined vocabulary
|
403
|
+
next unless statement.subject.start_with?(self.to_uri)
|
404
|
+
case statement.object
|
405
|
+
when RDF.Property,
|
406
|
+
RDF::OWL.AnnotationProperty,
|
407
|
+
RDF::OWL.DatatypeProperty,
|
408
|
+
RDF::OWL.FunctionalProperty,
|
409
|
+
RDF::OWL.ObjectProperty,
|
410
|
+
RDF::OWL.OntologyProperty
|
411
|
+
(cats[:properties] ||= []) << statement.subject unless categorized[statement.subject]
|
412
|
+
categorized[statement.subject] = true
|
413
|
+
when RDF::RDFS.Class, RDF::OWL.Class
|
414
|
+
(cats[:classes] ||= []) << statement.subject unless categorized[statement.subject]
|
415
|
+
categorized[statement.subject] = true
|
416
|
+
when RDF::RDFS.Datatype, RDF::OWL.DataRange
|
417
|
+
(cats[:datatypes] ||= []) << statement.subject unless categorized[statement.subject]
|
418
|
+
categorized[statement.subject] = true
|
419
|
+
when RDF::OWL.Ontology
|
420
|
+
(cats[:ont] ||= []) << statement.subject unless categorized[statement.subject]
|
421
|
+
categorized[statement.subject] = true
|
422
|
+
else
|
423
|
+
if statement.subject == self.to_uri
|
424
|
+
(cats[:ont] ||= []) << statement.subject unless categorized[statement.subject]
|
425
|
+
categorized[statement.subject] = true
|
426
|
+
else
|
427
|
+
uncategorized[statement.subject] = true
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
# Add all uncategorized subjects as :other
|
433
|
+
uncat = (uncategorized.keys - categorized.keys)
|
434
|
+
cats[:other] = uncat unless uncat.empty?
|
435
|
+
|
436
|
+
cats
|
437
|
+
end
|
33
438
|
end
|
439
|
+
|
440
|
+
module VocabFormatExtensions
|
441
|
+
##
|
442
|
+
# Hash of CLI commands appropriate for this format
|
443
|
+
# @return [Hash{Symbol => Lambda(Array, Hash)}]
|
444
|
+
def cli_commands
|
445
|
+
super.merge({
|
446
|
+
:"gen-vocab" => {
|
447
|
+
description: "Generate a vocabulary using a special serialization. Accepts an input graph, or serializes built-in vocabulary",
|
448
|
+
parse: false, # Only parse if there are input files, otherwise, uses vocabulary
|
449
|
+
help: "gen-vocab --uri <vocabulary-URI> [--output format ttl|jsonld|html] [options] [files]\n",
|
450
|
+
lambda: ->(files, options) do
|
451
|
+
$stdout.puts "Generate Vocabulary"
|
452
|
+
raise ArgumentError, "Must specify vocabulary URI" unless options[:base_uri]
|
453
|
+
|
454
|
+
# Parse input graphs, if repository is not already created
|
455
|
+
if RDF::CLI.repository.empty? && !files.empty?
|
456
|
+
RDF::CLI.parse(files, options) do |reader|
|
457
|
+
RDF::CLI.repository << reader
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
# Lookup vocabulary, or generate a new vocabulary from this URI
|
462
|
+
vocab = RDF::Vocabulary.find(options[:base_uri]) || begin
|
463
|
+
raise ArgumentError, "Must specify vocabulary prefix if vocabulary not built-in" unless options[:prefix]
|
464
|
+
RDF::Vocabulary.from_graph(RDF::CLI.repository, url: options[:base_uri], class_name: options[:prefix].to_s.upcase)
|
465
|
+
end
|
466
|
+
|
467
|
+
prefixes = {}
|
468
|
+
prefixes[options[:prefix]] = options[:base_uri] if options[:prefix]
|
469
|
+
out = options[:output] || $stdout
|
470
|
+
case options[:output_format]
|
471
|
+
when :ttl, nil then out.write vocab.to_ttl(graph: RDF::CLI.repository, prefixes: prefixes)
|
472
|
+
when :jsonld then out.write vocab.to_jsonld(graph: RDF::CLI.repository, prefixes: prefixes)
|
473
|
+
when :html then out.write vocab.to_html(graph: RDF::CLI.repository, prefixes: prefixes, template: options[:template])
|
474
|
+
else
|
475
|
+
# Use whatever writer we find
|
476
|
+
writer = RDF::Writer.for(options[:output_format]) || RDF::NTriples::Writer
|
477
|
+
writer.new(out, options) do |w|
|
478
|
+
if RDF::CLI.repository.empty?
|
479
|
+
vocab.each_statement {|s| w << s}
|
480
|
+
else
|
481
|
+
w << RDF::CLI.repository
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end,
|
486
|
+
options: [
|
487
|
+
RDF::CLI::Option.new(
|
488
|
+
symbol: :prefix,
|
489
|
+
datatype: String,
|
490
|
+
on: ["--prefix PREFIX"],
|
491
|
+
description: "Prefix associated with vocabulary, if not built-in."),
|
492
|
+
RDF::CLI::Option.new(
|
493
|
+
symbol: :template,
|
494
|
+
datatype: String,
|
495
|
+
on: ["--template TEMPLATE"],
|
496
|
+
description: "Path to local template for generating HTML, either Haml or ERB, depending on file extension.\n" +
|
497
|
+
"See https://github.com/ruby-rdf/rdf-vocab/tree/develop/etc for built-in templates."),
|
498
|
+
]
|
499
|
+
}
|
500
|
+
})
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
# Add cli_commands as class method to RDF::Vocabulary::Format
|
505
|
+
# TODO: in Ruby 2.0, `prepend` seems to be a private method of the class singleton; works okay elsewhere.
|
506
|
+
Format.singleton_class.send(:prepend, VocabFormatExtensions)
|
34
507
|
end
|
35
508
|
end
|
@@ -0,0 +1,356 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require File.expand_path("../spec_helper", __FILE__)
|
3
|
+
require 'json-schema'
|
4
|
+
|
5
|
+
describe RDF::Vocabulary do
|
6
|
+
describe ".to_ttl" do
|
7
|
+
before(:all) do
|
8
|
+
@acl = RDF::Vocab::ACL.to_ttl
|
9
|
+
@bibo = RDF::Vocab::BIBO.to_ttl
|
10
|
+
@dc = RDF::Vocab::DC.to_ttl
|
11
|
+
@foaf = RDF::Vocab::FOAF.to_ttl
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:acl) {@acl}
|
15
|
+
let(:bibo) {@bibo}
|
16
|
+
let(:dc) {@dc}
|
17
|
+
let(:foaf) {@foaf}
|
18
|
+
|
19
|
+
it "defines prefixes used in vocabulary" do
|
20
|
+
%w(dc dc11 foaf geo owl rdf rdfs skos vs).each do |pfx|
|
21
|
+
expect(foaf).to match(/@prefix\s+#{pfx}: /)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Does not generate an ontology if missing" do
|
26
|
+
expect(acl).not_to include "Vocabulary definition"
|
27
|
+
expect(foaf).to include "Vocabulary definition"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "Creates Classes" do
|
31
|
+
expect(foaf).to include "Class definitions"
|
32
|
+
expect(foaf).to match /foaf:Agent a .*owl:Class/
|
33
|
+
end
|
34
|
+
|
35
|
+
it "Creates Properties" do
|
36
|
+
expect(foaf).to include "Property definitions"
|
37
|
+
expect(foaf).to match /foaf:account a .*rdf:Property/
|
38
|
+
expect(foaf).to match /foaf:account a .*owl:ObjectProperty/
|
39
|
+
end
|
40
|
+
|
41
|
+
it "Creates Datatypes" do
|
42
|
+
expect(dc).to include "Datatype definitions"
|
43
|
+
expect(dc).to include "dc:Box a rdfs:Datatype"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "Creates Other definitions" do
|
47
|
+
expect(bibo).to include "Other definitions"
|
48
|
+
expect(bibo).to match /bdarcus a .*foaf:Person/
|
49
|
+
end
|
50
|
+
|
51
|
+
it "Serializes dates" do
|
52
|
+
expect(dc).to match %r("\d{4}-\d{2}-\d{2}"\^\^xsd:date)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "Serializes long literals" do
|
56
|
+
expect(acl).to include '"""'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "Serializes PNAME_NS" do
|
60
|
+
expect(foaf).to include "rdfs:isDefinedBy foaf:"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "Serializes PNAME_LN" do
|
64
|
+
expect(foaf).to match /rdfs:subClassOf .*foaf:Document/
|
65
|
+
end
|
66
|
+
|
67
|
+
it "Serializes URIs" do
|
68
|
+
expect(foaf).to match %r(rdfs:subClassOf .*<http:)
|
69
|
+
end
|
70
|
+
|
71
|
+
context "smoke test", slow: true do
|
72
|
+
RDF::Vocabulary.each do |vocab|
|
73
|
+
it "serializes #{vocab.__name__} without raising exception" do
|
74
|
+
expect do
|
75
|
+
ttl = vocab.to_ttl
|
76
|
+
RDF::Turtle::Reader.new(ttl, validate: true).each_statement {}
|
77
|
+
end.not_to raise_error
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe ".to_jsonld" do
|
84
|
+
before(:all) do
|
85
|
+
@acl = RDF::Vocab::ACL.to_jsonld
|
86
|
+
@bibo = RDF::Vocab::BIBO.to_jsonld
|
87
|
+
@dc = RDF::Vocab::DC.to_jsonld
|
88
|
+
@foaf = RDF::Vocab::FOAF.to_jsonld
|
89
|
+
end
|
90
|
+
|
91
|
+
let(:acl) {JSON.parse @acl}
|
92
|
+
let(:bibo) {JSON.parse @bibo}
|
93
|
+
let(:dc) {JSON.parse @dc}
|
94
|
+
let(:foaf) {JSON.parse @foaf}
|
95
|
+
|
96
|
+
it "defines prefixes used in vocabulary" do
|
97
|
+
%w(dc dc11 foaf geo owl rdf rdfs skos vs).each do |pfx|
|
98
|
+
expect(foaf).to match_json_schema({
|
99
|
+
"$schema" => "http://json-schema.org/draft-04/schema#",
|
100
|
+
type: "object",
|
101
|
+
required: ["@context"],
|
102
|
+
properties: {
|
103
|
+
"@context" => {
|
104
|
+
type: "object",
|
105
|
+
required: [pfx]
|
106
|
+
}
|
107
|
+
}
|
108
|
+
})
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it "Does not generate an ontology if missing" do
|
113
|
+
schema = {
|
114
|
+
"$schema" => "http://json-schema.org/draft-04/schema#",
|
115
|
+
type: "object",
|
116
|
+
required: ["@context", "@graph"],
|
117
|
+
properties: {
|
118
|
+
"@graph" => {
|
119
|
+
type: "object",
|
120
|
+
required: ["@type"]
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
expect(acl).not_to match_json_schema(schema)
|
125
|
+
expect(foaf).to match_json_schema(schema)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "Creates Classes" do
|
129
|
+
schema = {
|
130
|
+
"$schema" => "http://json-schema.org/draft-04/schema#",
|
131
|
+
type: "object",
|
132
|
+
required: ["@context", "@graph"],
|
133
|
+
properties: {
|
134
|
+
"@graph" => {
|
135
|
+
type: "object",
|
136
|
+
required: ["rdfs_classes"],
|
137
|
+
properties: {
|
138
|
+
"rdfs_classes" => {
|
139
|
+
type: "array",
|
140
|
+
items: {
|
141
|
+
allOf: [{
|
142
|
+
type: "object",
|
143
|
+
required: ["@id", "@type"]
|
144
|
+
}]
|
145
|
+
}
|
146
|
+
}
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
expect(foaf).to match_json_schema(schema)
|
152
|
+
#expect(foaf).to match_json_path "$..rdfs_classes[?(@.@id='foaf:Agent')]"
|
153
|
+
end
|
154
|
+
|
155
|
+
it "Creates Properties" do
|
156
|
+
schema = {
|
157
|
+
"$schema" => "http://json-schema.org/draft-04/schema#",
|
158
|
+
type: "object",
|
159
|
+
required: ["@context", "@graph"],
|
160
|
+
properties: {
|
161
|
+
"@graph" => {
|
162
|
+
type: "object",
|
163
|
+
required: ["rdfs_properties"],
|
164
|
+
properties: {
|
165
|
+
"rdfs_properties" => {
|
166
|
+
type: "array",
|
167
|
+
items: {
|
168
|
+
allOf: [{
|
169
|
+
type: "object",
|
170
|
+
required: ["@id", "@type"]
|
171
|
+
}]
|
172
|
+
}
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
expect(foaf).to match_json_schema(schema)
|
179
|
+
#expect(foaf).to match_json_path "$..rdfs_properties[?(@.@id='foaf:account')]"
|
180
|
+
end
|
181
|
+
|
182
|
+
it "Creates Datatypes" do
|
183
|
+
schema = {
|
184
|
+
"$schema" => "http://json-schema.org/draft-04/schema#",
|
185
|
+
type: "object",
|
186
|
+
required: ["@context", "@graph"],
|
187
|
+
properties: {
|
188
|
+
"@graph" => {
|
189
|
+
type: "object",
|
190
|
+
required: ["rdfs_datatypes"],
|
191
|
+
properties: {
|
192
|
+
"rdfs_datatypes" => {
|
193
|
+
type: "array",
|
194
|
+
items: {
|
195
|
+
allOf: [{
|
196
|
+
type: "object",
|
197
|
+
required: ["@id", "@type"]
|
198
|
+
}]
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
expect(dc).to match_json_schema(schema)
|
206
|
+
#expect(dc).to match_json_path "$..rdfs_datatypes[?(@.@id='dc:Box')]"
|
207
|
+
end
|
208
|
+
|
209
|
+
it "Creates Other definitions" do
|
210
|
+
schema = {
|
211
|
+
"$schema" => "http://json-schema.org/draft-04/schema#",
|
212
|
+
type: "object",
|
213
|
+
required: ["@context", "@graph"],
|
214
|
+
properties: {
|
215
|
+
"@graph" => {
|
216
|
+
type: "object",
|
217
|
+
required: ["rdfs_instances"],
|
218
|
+
properties: {
|
219
|
+
"rdfs_instances" => {
|
220
|
+
type: "array",
|
221
|
+
items: {
|
222
|
+
allOf: [{
|
223
|
+
type: "object",
|
224
|
+
required: ["@id", "@type"]
|
225
|
+
}]
|
226
|
+
}
|
227
|
+
}
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
expect(bibo).to match_json_schema(schema)
|
233
|
+
#expect(bibo).to match_json_path "$..rdfs_instances[?(@.@id='bdarcus')]"
|
234
|
+
end
|
235
|
+
|
236
|
+
context "smoke test", slow: true do
|
237
|
+
RDF::Vocabulary.each do |vocab|
|
238
|
+
it "serializes #{vocab.__name__} without raising exception" do
|
239
|
+
expect do
|
240
|
+
jsonld = vocab.to_jsonld
|
241
|
+
JSON::LD::Reader.new(jsonld, validate: true).each_statement {}
|
242
|
+
end.not_to raise_error
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe ".to_html" do
|
249
|
+
before(:all) do
|
250
|
+
@acl = RDF::Vocab::ACL.to_html
|
251
|
+
@bibo = RDF::Vocab::BIBO.to_html
|
252
|
+
@dc = RDF::Vocab::DC.to_html
|
253
|
+
@foaf = RDF::Vocab::FOAF.to_html
|
254
|
+
end
|
255
|
+
|
256
|
+
let(:acl) {Nokogiri::HTML.parse @acl}
|
257
|
+
let(:bibo) {Nokogiri::HTML.parse @bibo}
|
258
|
+
let(:dc) {Nokogiri::HTML.parse @dc}
|
259
|
+
let(:foaf) {Nokogiri::HTML.parse @foaf}
|
260
|
+
|
261
|
+
it "defines prefixes used in vocabulary" do
|
262
|
+
%w(dc dc11 foaf geo owl rdf rdfs skos vs).each do |pfx|
|
263
|
+
expect(foaf.at_xpath('/html/body/@prefix').to_s).to include("#{pfx}: ")
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
it "Creates Classes" do
|
268
|
+
expect(foaf.xpath('//section/h2').to_s).to include("Class Definitions")
|
269
|
+
expect(foaf.at_xpath('//td[@resource="foaf:Group"]')).not_to be_nil
|
270
|
+
end
|
271
|
+
|
272
|
+
it "Creates Properties" do
|
273
|
+
expect(foaf.xpath('//section/h2').to_s).to include("Property Definitions")
|
274
|
+
expect(foaf.at_xpath('//td[@resource="foaf:isPrimaryTopicOf"]')).not_to be_nil
|
275
|
+
end
|
276
|
+
|
277
|
+
it "Creates Datatypes" do
|
278
|
+
expect(dc.xpath('//section/h2').to_s).to include("Datatype Definitions")
|
279
|
+
expect(dc.at_xpath('//td[@resource="dc:RFC1766"]')).not_to be_nil
|
280
|
+
end
|
281
|
+
|
282
|
+
it "Creates Other definitions" do
|
283
|
+
expect(dc.xpath('//section/h2').to_s).to include("Instance Definitions")
|
284
|
+
expect(dc.at_xpath('//td[@resource="dc:NLM"]')).not_to be_nil
|
285
|
+
end
|
286
|
+
|
287
|
+
context "smoke test", slow: true do
|
288
|
+
skips = [
|
289
|
+
RDF::Vocab::Bibframe,
|
290
|
+
RDF::Vocab::EBUCore,
|
291
|
+
RDF::Vocab::GEONAMES,
|
292
|
+
RDF::Vocab::IIIF,
|
293
|
+
RDF::Vocab::MO,
|
294
|
+
RDF::Vocab::PREMIS,
|
295
|
+
RDF::Vocab::SIOC,
|
296
|
+
]
|
297
|
+
RDF::Vocabulary.each do |vocab|
|
298
|
+
it "serializes #{vocab.__name__} without raising exception", skip: (skips.include?(vocab)) do
|
299
|
+
expect do
|
300
|
+
rdfa = vocab.to_html
|
301
|
+
RDF::RDFa::Reader.new(rdfa, validate: true, base_uri: vocab.to_uri).each_statement {}
|
302
|
+
end.not_to raise_error
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe RDF::Vocabulary::Format do
|
309
|
+
describe ".cli_commands", skip: ("Rubinius issues in RDF.rb" if RUBY_ENGINE == "rbx") do
|
310
|
+
require 'rdf/cli'
|
311
|
+
describe "gen-vocab" do
|
312
|
+
let(:vocab) {RDF::Vocab::IANA}
|
313
|
+
|
314
|
+
it "generates Turtle by default" do
|
315
|
+
stringio = StringIO.new
|
316
|
+
RDF::CLI.exec(["gen-vocab"], base_uri: vocab.to_uri, output: stringio)
|
317
|
+
expect(stringio.string).not_to be_empty
|
318
|
+
graph = RDF::Graph.new
|
319
|
+
RDF::Turtle::Reader.new(stringio.string, validate: true) {|r| graph << r}
|
320
|
+
expect(graph).not_to be_empty
|
321
|
+
expect(graph).to be_valid
|
322
|
+
end
|
323
|
+
|
324
|
+
it "generates Turtle explictly" do
|
325
|
+
stringio = StringIO.new
|
326
|
+
RDF::CLI.exec(["gen-vocab"], base_uri: vocab.to_uri, output_format: :ttl, output: stringio)
|
327
|
+
expect(stringio.string).not_to be_empty
|
328
|
+
graph = RDF::Graph.new
|
329
|
+
RDF::Turtle::Reader.new(stringio.string, validate: true) {|r| graph << r}
|
330
|
+
expect(graph).not_to be_empty
|
331
|
+
expect(graph).to be_valid
|
332
|
+
end
|
333
|
+
|
334
|
+
it "generates JSON-LD" do
|
335
|
+
stringio = StringIO.new
|
336
|
+
RDF::CLI.exec(["gen-vocab"], base_uri: vocab.to_uri, output_format: :jsonld, output: stringio)
|
337
|
+
expect(stringio.string).not_to be_empty
|
338
|
+
graph = RDF::Graph.new
|
339
|
+
JSON::LD::Reader.new(stringio.string, validate: true) {|r| graph << r}
|
340
|
+
expect(graph).not_to be_empty
|
341
|
+
expect(graph).to be_valid
|
342
|
+
end
|
343
|
+
|
344
|
+
it "generates HTML" do
|
345
|
+
stringio = StringIO.new
|
346
|
+
RDF::CLI.exec(["gen-vocab"], base_uri: vocab.to_uri, output_format: :html, output: stringio)
|
347
|
+
expect(stringio.string).not_to be_empty
|
348
|
+
graph = RDF::Graph.new
|
349
|
+
RDF::RDFa::Reader.new(stringio.string, validate: true, base_uri: vocab.to_uri) {|r| graph << r}
|
350
|
+
expect(graph).not_to be_empty
|
351
|
+
expect(graph).to be_valid
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
data/spec/matchers.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rspec/matchers' # @see http://rubygems.org/gems/rspec
|
2
|
+
require 'json-schema'
|
3
|
+
require 'jsonpath'
|
4
|
+
|
5
|
+
RSpec::Matchers.define :match_json_schema do |schema|
|
6
|
+
match do |actual|
|
7
|
+
@error_message = JSON::Validator.fully_validate(schema, actual, validate_schema: true).join("")
|
8
|
+
@error_message.empty?
|
9
|
+
end
|
10
|
+
|
11
|
+
failure_message do |actual|
|
12
|
+
@error_message +
|
13
|
+
"\nActual: #{actual.to_json(JSON::LD::JSON_STATE)}" +
|
14
|
+
"\nSchema: #{schema.to_json(JSON::LD::JSON_STATE)}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
RSpec::Matchers.define :match_json_path do |path|
|
19
|
+
match do |actual|
|
20
|
+
matched = JsonPath.new(path).on(actual)
|
21
|
+
!matched.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
failure_message do |actual|
|
25
|
+
"Path #{path} not found in data" +
|
26
|
+
"\nActual: #{actual.to_json(JSON::LD::JSON_STATE)}"
|
27
|
+
end
|
28
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "bundler/setup"
|
3
3
|
require 'rdf/vocab'
|
4
|
+
require 'matchers'
|
4
5
|
|
5
6
|
RSpec.configure do |config|
|
6
|
-
config.filter_run :
|
7
|
+
config.filter_run focus: true
|
8
|
+
config.filter_run_excluding slow: true
|
7
9
|
config.run_all_when_everything_filtered = true
|
8
10
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdf-vocab
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chandek-Stark
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-05-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rdf
|
@@ -27,33 +27,33 @@ dependencies:
|
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '2.0'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
|
-
name:
|
30
|
+
name: haml
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '0
|
35
|
+
version: '4.0'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '0
|
42
|
+
version: '4.0'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
|
-
name:
|
44
|
+
name: erubis
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '2.7'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '2.7'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: bundler
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,6 +68,76 @@ dependencies:
|
|
68
68
|
- - "~>"
|
69
69
|
- !ruby/object:Gem::Version
|
70
70
|
version: '1.7'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: json-ld
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - "~>"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '2.0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - "~>"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '2.0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: json-schema
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - "~>"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '2.0'
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - "~>"
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '2.0'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: jsonpath
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0.5'
|
106
|
+
type: :development
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0.5'
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: ld-patch
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0.3'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - "~>"
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0.3'
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: nokogiri
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - "~>"
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '1.6'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - "~>"
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '1.6'
|
71
141
|
- !ruby/object:Gem::Dependency
|
72
142
|
name: rake
|
73
143
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,6 +152,48 @@ dependencies:
|
|
82
152
|
- - "~>"
|
83
153
|
- !ruby/object:Gem::Version
|
84
154
|
version: '10.0'
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
name: rdf-rdfa
|
157
|
+
requirement: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - "~>"
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '2.0'
|
162
|
+
type: :development
|
163
|
+
prerelease: false
|
164
|
+
version_requirements: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - "~>"
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '2.0'
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: rdf-reasoner
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - "~>"
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0.4'
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - "~>"
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0.4'
|
183
|
+
- !ruby/object:Gem::Dependency
|
184
|
+
name: rdf-turtle
|
185
|
+
requirement: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - "~>"
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '2.0'
|
190
|
+
type: :development
|
191
|
+
prerelease: false
|
192
|
+
version_requirements: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - "~>"
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '2.0'
|
85
197
|
- !ruby/object:Gem::Dependency
|
86
198
|
name: rspec
|
87
199
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,6 +313,8 @@ files:
|
|
201
313
|
- lib/rdf/vocab/wot.rb
|
202
314
|
- lib/rdf/vocab/xhtml.rb
|
203
315
|
- lib/rdf/vocab/xhv.rb
|
316
|
+
- spec/extensions_spec.rb
|
317
|
+
- spec/matchers.rb
|
204
318
|
- spec/spec_helper.rb
|
205
319
|
- spec/vocab_spec.rb
|
206
320
|
homepage: http://ruby-rdf.github.com/rdf-vocab
|
@@ -223,11 +337,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
337
|
version: '0'
|
224
338
|
requirements: []
|
225
339
|
rubyforge_project:
|
226
|
-
rubygems_version: 2.
|
340
|
+
rubygems_version: 2.5.1
|
227
341
|
signing_key:
|
228
342
|
specification_version: 4
|
229
343
|
summary: A library of RDF vocabularies
|
230
344
|
test_files:
|
345
|
+
- spec/extensions_spec.rb
|
346
|
+
- spec/matchers.rb
|
231
347
|
- spec/spec_helper.rb
|
232
348
|
- spec/vocab_spec.rb
|
233
349
|
has_rdoc: false
|