json-ld 3.1.3 → 3.1.8
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 +138 -49
- data/VERSION +1 -1
- data/bin/jsonld +28 -31
- data/lib/json/ld.rb +8 -2
- data/lib/json/ld/api.rb +55 -38
- data/lib/json/ld/compact.rb +68 -40
- data/lib/json/ld/conneg.rb +1 -1
- data/lib/json/ld/context.rb +570 -521
- data/lib/json/ld/expand.rb +203 -84
- data/lib/json/ld/extensions.rb +4 -4
- data/lib/json/ld/flatten.rb +92 -9
- data/lib/json/ld/format.rb +21 -8
- data/lib/json/ld/frame.rb +8 -8
- data/lib/json/ld/from_rdf.rb +42 -19
- data/lib/json/ld/reader.rb +21 -11
- data/lib/json/ld/streaming_reader.rb +578 -0
- data/lib/json/ld/streaming_writer.rb +4 -4
- data/lib/json/ld/to_rdf.rb +11 -7
- data/lib/json/ld/utils.rb +13 -13
- data/lib/json/ld/writer.rb +12 -5
- data/spec/api_spec.rb +1 -1
- data/spec/compact_spec.rb +207 -3
- data/spec/context_spec.rb +4 -42
- data/spec/expand_spec.rb +631 -0
- data/spec/flatten_spec.rb +517 -1
- data/spec/from_rdf_spec.rb +181 -0
- data/spec/matchers.rb +1 -1
- data/spec/rdfstar_spec.rb +25 -0
- data/spec/reader_spec.rb +33 -34
- data/spec/spec_helper.rb +33 -0
- data/spec/streaming_reader_spec.rb +237 -0
- data/spec/suite_flatten_spec.rb +4 -0
- data/spec/suite_frame_spec.rb +7 -0
- data/spec/suite_helper.rb +25 -13
- data/spec/suite_to_rdf_spec.rb +1 -0
- data/spec/to_rdf_spec.rb +209 -3
- data/spec/writer_spec.rb +193 -0
- metadata +68 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8fab787ba5efd37b20576d65d5dfe524923f14c7dac53a1d9ed32cb88bd689c8
|
4
|
+
data.tar.gz: 3b8ce473fe9e05302dabedb9a631ca2212aeb03479cc2d282abf8603daeedce2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47ec226ef3c0d79702d61a7fa81ce2ed3368f64744e2fb29f1b98fdaae2aba7e6af7ed493395031eb43d89e4469c04a24ea38ad836baffb50a46854cf33a75c8
|
7
|
+
data.tar.gz: 579b1794485469d832b29a2f5f5bbf36819627d93289595da6f46e2197829e4e6365a5bbb4c88193f904ad07a21a643821195d22cb3750543e6954e986d809f4
|
data/README.md
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
[JSON-LD][] reader/writer for [RDF.rb][RDF.rb] and fully conforming [JSON-LD API][] processor. Additionally this gem implements [JSON-LD Framing][].
|
4
4
|
|
5
|
-
[](https://
|
6
|
-
[](https://coveralls.io/
|
5
|
+
[](https://rubygems.org/gems/json-ld)
|
6
|
+
[](https://github.com/ruby-rdf/json-ld/actions?query=workflow%3ACI)
|
7
|
+
[](https://coveralls.io/github/ruby-rdf/json-ld?branch=develop)
|
8
|
+
[](https://gitter.im/gitterHQ/gitter)
|
8
9
|
|
9
10
|
## Features
|
10
11
|
|
@@ -14,26 +15,103 @@ JSON::LD can now be used to create a _context_ from an RDFS/OWL definition, and
|
|
14
15
|
|
15
16
|
* If the [jsonlint][] gem is installed, it will be used when validating an input document.
|
16
17
|
* If available, uses [Nokogiri][] and/or [Nokogumbo][] for parsing HTML, falls back to REXML otherwise.
|
18
|
+
* Provisional support for [JSON-LD*][JSON-LD*].
|
17
19
|
|
18
|
-
[Implementation Report](
|
20
|
+
[Implementation Report](https://ruby-rdf.github.io/json-ld/etc/earl.html)
|
19
21
|
|
20
22
|
Install with `gem install json-ld`
|
21
23
|
|
24
|
+
### JSON-LD Streaming Profile
|
25
|
+
This gem implements an optimized streaming reader used for generating RDF from large dataset dumps formatted as JSON-LD. Such documents must correspond to the [JSON-LD Streaming Profile](https://w3c.github.io/json-ld-streaming/):
|
26
|
+
|
27
|
+
* Keys in JSON objects must be ordered with any of `@context`, and/or `@type` coming before any other keys, in that order. This includes aliases of those keys. It is strongly encouraged that `@id` be present, and come immediately after.
|
28
|
+
* JSON-LD documents can be signaled or requested in [streaming document form](https://w3c.github.io/json-ld-streaming/#dfn-streaming-document-form). The profile URI identifying the [streaming document form](https://w3c.github.io/json-ld-streaming/#dfn-streaming-document-form) is `http://www.w3.org/ns/json-ld#streaming`.
|
29
|
+
|
30
|
+
This gem also implements an optimized streaming writer used for generating JSON-LD from large repositories. Such documents result in the JSON-LD Streaming Profile:
|
31
|
+
|
32
|
+
* Each statement written as a separate node in expanded/flattened form.
|
33
|
+
* `RDF List`s are written as separate nodes using `rdf:first` and `rdf:rest` properties.
|
34
|
+
|
35
|
+
The order of triples retrieved from the `RDF::Enumerable` dataset determines the way that JSON-LD node objects are written; for best results, statements should be ordered by _graph name_, _subect_, _predicate_ and _object_.
|
36
|
+
|
22
37
|
### MultiJson parser
|
23
38
|
The [MultiJson](https://rubygems.org/gems/multi_json) gem is used for parsing JSON; this defaults to the native JSON parser, but will use a more performant parser if one is available. A specific parser can be specified by adding the `:adapter` option to any API call. See [MultiJson](https://rubygems.org/gems/multi_json) for more information.
|
24
39
|
|
25
|
-
### JSON-LD
|
26
|
-
This gem implements an optimized streaming writer used for generating JSON-LD from large repositories. Such documents result in the JSON-LD Streaming Profile:
|
40
|
+
### JSON-LD* (RDFStar)
|
27
41
|
|
28
|
-
|
29
|
-
|
42
|
+
The {JSON::LD::API.expand}, {JSON::LD::API.compact}, {JSON::LD::API.toRdf}, and {JSON::LD::API.fromRdf} API methods, along with the {JSON::LD::Reader} and {JSON::LD::Writer}, include provisional support for [JSON-LD*][JSON-LD*].
|
43
|
+
|
44
|
+
Internally, an `RDF::Statement` is treated as another resource, along with `RDF::URI` and `RDF::Node`, which allows an `RDF::Statement` to have a `#subject` or `#object` which is also an `RDF::Statement`.
|
45
|
+
|
46
|
+
In JSON-LD, with the `rdfstar` option set, the value of `@id`, in addition to an IRI or Blank Node Identifier, can be a JSON-LD node object having exactly one property with an optional `@id`, which may also be an embedded object. (It may also have `@context` and `@index` values).
|
47
|
+
|
48
|
+
{
|
49
|
+
"@id": {
|
50
|
+
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
|
51
|
+
"@index": "ignored",
|
52
|
+
"@id": "bob",
|
53
|
+
"foaf:age" 23
|
54
|
+
},
|
55
|
+
"ex:certainty": 0.9
|
56
|
+
}
|
57
|
+
|
58
|
+
Additionally, the `@annotation` property (or alias) may be used on a node object or value object to annotate the statement for which the associated node is the object of a triple.
|
59
|
+
|
60
|
+
{
|
61
|
+
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
|
62
|
+
"@id": "bob",
|
63
|
+
"foaf:age" 23,
|
64
|
+
"@annotation": {
|
65
|
+
"ex:certainty": 0.9
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
In the first case, the embedded node is not asserted, and only appears as the subject of a triple. In the second case, the triple is asserted and used as the subject in another statement which annotates it.
|
70
|
+
|
71
|
+
**Note: This feature is subject to change or elimination as the standards process progresses.**
|
72
|
+
|
73
|
+
#### Serializing a Graph containing embedded statements
|
74
|
+
|
75
|
+
require 'json-ld'
|
76
|
+
statement = RDF::Statement(RDF::URI('bob'), RDF::Vocab::FOAF.age, RDF::Literal(23))
|
77
|
+
graph = RDF::Graph.new << [statement, RDF::URI("ex:certainty"), RDF::Literal(0.9)]
|
78
|
+
graph.dump(:jsonld, validate: false, standard_prefixes: true)
|
79
|
+
# => {"@id": {"@id": "bob", "foaf:age" 23}, "ex:certainty": 0.9}
|
80
|
+
|
81
|
+
Alternatively, using the {JSON::LD::API.fromRdf} method:
|
82
|
+
|
83
|
+
JSON::LD::API::fromRdf(graph)
|
84
|
+
# => {"@id": {"@id": "bob", "foaf:age" 23}, "ex:certainty": 0.9}
|
85
|
+
|
86
|
+
#### Reading a Graph containing embedded statements
|
87
|
+
|
88
|
+
By default, {JSON::LD::API.toRdf} (and {JSON::LD::Reader}) will reject a document containing a subject resource.
|
89
|
+
|
90
|
+
jsonld = %({
|
91
|
+
"@id": {
|
92
|
+
"@id": "bob", "foaf:age" 23
|
93
|
+
},
|
94
|
+
"ex:certainty": 0.9
|
95
|
+
})
|
96
|
+
graph = RDF::Graph.new << JSON::LD::API.toRdf(input)
|
97
|
+
# => JSON::LD::JsonLdError::InvalidIdValue
|
98
|
+
|
99
|
+
{JSON::LD::API.toRdf} (and {JSON::LD::Reader}) support a boolean valued `rdfstar` option; only one statement is asserted, although the reified statement is contained within the graph.
|
100
|
+
|
101
|
+
graph = RDF::Graph.new do |graph|
|
102
|
+
JSON::LD::Reader.new(jsonld, rdfstar: true) {|reader| graph << reader}
|
103
|
+
end
|
104
|
+
graph.count #=> 1
|
30
105
|
|
31
106
|
## Examples
|
107
|
+
|
32
108
|
```ruby
|
33
109
|
require 'rubygems'
|
34
110
|
require 'json/ld'
|
35
111
|
```
|
112
|
+
|
36
113
|
### Expand a Document
|
114
|
+
|
37
115
|
```ruby
|
38
116
|
input = JSON.parse %({
|
39
117
|
"@context": {
|
@@ -53,8 +131,9 @@ require 'json/ld'
|
|
53
131
|
"http://xmlns.com/foaf/0.1/avatar": [{"@value": "https://twitter.com/account/profile_image/manusporny"}]
|
54
132
|
}]
|
55
133
|
```
|
134
|
+
|
56
135
|
### Compact a Document
|
57
|
-
|
136
|
+
|
58
137
|
input = JSON.parse %([{
|
59
138
|
"http://xmlns.com/foaf/0.1/name": ["Manu Sporny"],
|
60
139
|
"http://xmlns.com/foaf/0.1/homepage": [{"@id": "https://manu.sporny.org/"}],
|
@@ -80,9 +159,9 @@ require 'json/ld'
|
|
80
159
|
"homepage": "https://manu.sporny.org/",
|
81
160
|
"name": "Manu Sporny"
|
82
161
|
}
|
83
|
-
|
162
|
+
|
84
163
|
### Frame a Document
|
85
|
-
|
164
|
+
|
86
165
|
input = JSON.parse %({
|
87
166
|
"@context": {
|
88
167
|
"Book": "http://example.org/vocab#Book",
|
@@ -163,9 +242,9 @@ require 'json/ld'
|
|
163
242
|
}
|
164
243
|
]
|
165
244
|
}
|
166
|
-
|
245
|
+
|
167
246
|
### Turn JSON-LD into RDF (Turtle)
|
168
|
-
|
247
|
+
|
169
248
|
input = JSON.parse %({
|
170
249
|
"@context": {
|
171
250
|
"": "https://manu.sporny.org/",
|
@@ -186,9 +265,9 @@ require 'json/ld'
|
|
186
265
|
<http://example.org/people#joebob> a foaf:Person;
|
187
266
|
foaf:name "Joe Bob";
|
188
267
|
foaf:nick ("joe" "bob" "jaybe") .
|
189
|
-
|
268
|
+
|
190
269
|
### Turn RDF into JSON-LD
|
191
|
-
|
270
|
+
|
192
271
|
require 'rdf/turtle'
|
193
272
|
input = RDF::Graph.new << RDF::Turtle::Reader.new(%(
|
194
273
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
@@ -224,13 +303,14 @@ require 'json/ld'
|
|
224
303
|
"http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
|
225
304
|
}
|
226
305
|
]
|
227
|
-
|
306
|
+
|
228
307
|
## Use a custom Document Loader
|
229
308
|
In some cases, the built-in document loader {JSON::LD::API.documentLoader} is inadequate; for example, when using `http://schema.org` as a remote context, it will be re-loaded every time (however, see [json-ld-preloaded](https://rubygems.org/gems/json-ld-preloaded)).
|
230
309
|
|
231
310
|
All entries into the {JSON::LD::API} accept a `:documentLoader` option, which can be used to provide an alternative method to use when loading remote documents. For example:
|
311
|
+
|
232
312
|
```ruby
|
233
|
-
|
313
|
+
load_document_local = Proc.new do |url, **options, &block|
|
234
314
|
if RDF::URI(url, canonicalize: true) == RDF::URI('http://schema.org/')
|
235
315
|
remote_document = JSON::LD::API::RemoteDocument.new(url, File.read("etc/schema.org.jsonld"))
|
236
316
|
return block_given? ? yield(remote_document) : remote_document
|
@@ -238,28 +318,34 @@ def load_document_local(url, options={}, &block)
|
|
238
318
|
JSON::LD::API.documentLoader(url, options, &block)
|
239
319
|
end
|
240
320
|
end
|
321
|
+
|
241
322
|
```
|
242
323
|
Then, when performing something like expansion:
|
324
|
+
|
243
325
|
```ruby
|
244
326
|
JSON::LD::API.expand(input, documentLoader: load_document_local)
|
245
327
|
```
|
246
328
|
|
247
329
|
## Preloading contexts
|
248
330
|
In many cases, for small documents, processing time can be dominated by loading and parsing remote contexts. In particular, a small schema.org example may need to download a large context and turn it into an internal representation, before the actual document can be expanded for processing. Using {JSON::LD::Context.add_preloaded}, an implementation can perform this loading up-front, and make it available to the processor.
|
331
|
+
|
249
332
|
```ruby
|
250
333
|
ctx = JSON::LD::Context.new().parse('http://schema.org/')
|
251
334
|
JSON::LD::Context.add_preloaded('http://schema.org/', ctx)
|
252
335
|
```
|
336
|
+
|
253
337
|
On lookup, URIs with an `https` prefix are normalized to `http`.
|
254
338
|
|
255
339
|
A context may be serialized to Ruby to speed this process using `Context#to_rb`. When loaded, this generated file will add entries to the {JSON::LD::Context::PRELOADED}.
|
256
340
|
|
257
341
|
## RDF Reader and Writer
|
258
342
|
{JSON::LD} also acts as a normal RDF reader and writer, using the standard RDF.rb reader/writer interfaces:
|
343
|
+
|
259
344
|
```ruby
|
260
345
|
graph = RDF::Graph.load("etc/doap.jsonld", format: :jsonld)
|
261
346
|
graph.dump(:jsonld, standard_prefixes: true)
|
262
347
|
```
|
348
|
+
|
263
349
|
`RDF::GRAPH#dump` can also take a `:context` option to use a separately defined context
|
264
350
|
|
265
351
|
As JSON-LD may come from many different sources, included as an embedded script tag within an HTML document, the RDF Reader will strip input before the leading `{` or `[` and after the trailing `}` or `]`.
|
@@ -269,7 +355,7 @@ This implementation is being used as a test-bed for features planned for an upco
|
|
269
355
|
|
270
356
|
### Scoped Contexts
|
271
357
|
A term definition can include `@context`, which is applied to values of that object. This is also used when compacting. Taken together, this allows framing to effectively include context definitions more deeply within the framed structure.
|
272
|
-
|
358
|
+
|
273
359
|
{
|
274
360
|
"@context": {
|
275
361
|
"ex": "http://example.com/",
|
@@ -284,10 +370,10 @@ A term definition can include `@context`, which is applied to values of that obj
|
|
284
370
|
},
|
285
371
|
"foo": "Bar"
|
286
372
|
}
|
287
|
-
|
373
|
+
|
288
374
|
### @id and @type maps
|
289
375
|
The value of `@container` in a term definition can include `@id` or `@type`, in addition to `@set`, `@list`, `@language`, and `@index`. This allows value indexing based on either the `@id` or `@type` of associated objects.
|
290
|
-
|
376
|
+
|
291
377
|
{
|
292
378
|
"@context": {
|
293
379
|
"@vocab": "http://example/",
|
@@ -298,10 +384,10 @@ The value of `@container` in a term definition can include `@id` or `@type`, in
|
|
298
384
|
"_:bar": {"label": "Object with @id _:bar"}
|
299
385
|
}
|
300
386
|
}
|
301
|
-
|
387
|
+
|
302
388
|
### @graph containers and maps
|
303
389
|
A term can have `@container` set to include `@graph` optionally including `@id` or `@index` and `@set`. In the first form, with `@container` set to `@graph`, the value of a property is treated as a _simple graph object_, meaning that values treated as if they were contained in an object with `@graph`, creating _named graph_ with an anonymous name.
|
304
|
-
|
390
|
+
|
305
391
|
{
|
306
392
|
"@context": {
|
307
393
|
"@vocab": "http://example.org/",
|
@@ -311,9 +397,9 @@ A term can have `@container` set to include `@graph` optionally including `@id`
|
|
311
397
|
"value": "x"
|
312
398
|
}
|
313
399
|
}
|
314
|
-
|
400
|
+
|
315
401
|
which expands to the following:
|
316
|
-
|
402
|
+
|
317
403
|
[{
|
318
404
|
"http://example.org/input": [{
|
319
405
|
"@graph": [{
|
@@ -321,18 +407,18 @@ which expands to the following:
|
|
321
407
|
}]
|
322
408
|
}]
|
323
409
|
}]
|
324
|
-
|
410
|
+
|
325
411
|
Compaction reverses this process, optionally ensuring that a single value is contained within an array of `@container` also includes `@set`:
|
326
|
-
|
412
|
+
|
327
413
|
{
|
328
414
|
"@context": {
|
329
415
|
"@vocab": "http://example.org/",
|
330
416
|
"input": {"@container": ["@graph", "@set"]}
|
331
417
|
}
|
332
418
|
}
|
333
|
-
|
419
|
+
|
334
420
|
A graph map uses the map form already existing for `@index`, `@language`, `@type`, and `@id` where the index is either an index value or an id.
|
335
|
-
|
421
|
+
|
336
422
|
{
|
337
423
|
"@context": {
|
338
424
|
"@vocab": "http://example.org/",
|
@@ -342,9 +428,9 @@ A graph map uses the map form already existing for `@index`, `@language`, `@type
|
|
342
428
|
"g1": {"value": "x"}
|
343
429
|
}
|
344
430
|
}
|
345
|
-
|
431
|
+
|
346
432
|
treats "g1" as an index, and expands to the following:
|
347
|
-
|
433
|
+
|
348
434
|
[{
|
349
435
|
"http://example.org/input": [{
|
350
436
|
"@index": "g1",
|
@@ -353,11 +439,11 @@ treats "g1" as an index, and expands to the following:
|
|
353
439
|
}]
|
354
440
|
}]
|
355
441
|
}])
|
356
|
-
|
442
|
+
|
357
443
|
This can also include `@set` to ensure that, when compacting, a single value of an index will be in array form.
|
358
444
|
|
359
445
|
The _id_ version is similar:
|
360
|
-
|
446
|
+
|
361
447
|
{
|
362
448
|
"@context": {
|
363
449
|
"@vocab": "http://example.org/",
|
@@ -367,9 +453,9 @@ The _id_ version is similar:
|
|
367
453
|
"http://example.com/g1": {"value": "x"}
|
368
454
|
}
|
369
455
|
}
|
370
|
-
|
456
|
+
|
371
457
|
which expands to:
|
372
|
-
|
458
|
+
|
373
459
|
[{
|
374
460
|
"http://example.org/input": [{
|
375
461
|
"@id": "http://example.com/g1",
|
@@ -378,10 +464,10 @@ which expands to:
|
|
378
464
|
}]
|
379
465
|
}]
|
380
466
|
}])
|
381
|
-
|
467
|
+
|
382
468
|
### Transparent Nesting
|
383
469
|
Many JSON APIs separate properties from their entities using an intermediate object. For example, a set of possible labels may be grouped under a common property:
|
384
|
-
|
470
|
+
|
385
471
|
{
|
386
472
|
"@context": {
|
387
473
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -397,9 +483,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
397
483
|
"other_label": "This is the other label"
|
398
484
|
}
|
399
485
|
}
|
400
|
-
|
486
|
+
|
401
487
|
In this case, the `labels` property is semantically meaningless. Defining it as equivalent to `@nest` causes it to be ignored when expanding, making it equivalent to the following:
|
402
|
-
|
488
|
+
|
403
489
|
{
|
404
490
|
"@context": {
|
405
491
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -413,9 +499,9 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
413
499
|
"main_label": "This is the main label for my resource",
|
414
500
|
"other_label": "This is the other label"
|
415
501
|
}
|
416
|
-
|
502
|
+
|
417
503
|
Similarly, properties may be marked with "@nest": "nest-term", to cause them to be nested. Note that the `@nest` keyword can also be aliased in the context.
|
418
|
-
|
504
|
+
|
419
505
|
{
|
420
506
|
"@context": {
|
421
507
|
"skos": "http://www.w3.org/2004/02/skos/core#",
|
@@ -431,7 +517,7 @@ Many JSON APIs separate properties from their entities using an intermediate obj
|
|
431
517
|
"other_label": "This is the other label"
|
432
518
|
}
|
433
519
|
}
|
434
|
-
|
520
|
+
|
435
521
|
In this way, nesting survives round-tripping through expansion, and framed output can include nested properties.
|
436
522
|
|
437
523
|
## Sinatra/Rack support
|
@@ -509,14 +595,14 @@ Note, the API method signatures differed in versions before 1.0, in that they al
|
|
509
595
|
## Installation
|
510
596
|
The recommended installation method is via [RubyGems](https://rubygems.org/).
|
511
597
|
To install the latest official release of the `JSON-LD` gem, do:
|
512
|
-
|
513
|
-
|
514
|
-
|
598
|
+
|
599
|
+
% [sudo] gem install json-ld
|
600
|
+
|
515
601
|
## Download
|
516
602
|
To get a local working copy of the development repository, do:
|
517
|
-
|
518
|
-
|
519
|
-
|
603
|
+
|
604
|
+
% git clone git://github.com/ruby-rdf/json-ld.git
|
605
|
+
|
520
606
|
## Mailing List
|
521
607
|
* <https://lists.w3.org/Archives/Public/public-rdf-ruby/>
|
522
608
|
|
@@ -534,7 +620,9 @@ To get a local working copy of the development repository, do:
|
|
534
620
|
list in the the `README`. Alphabetical order applies.
|
535
621
|
* Do note that in order for us to merge any non-trivial changes (as a rule
|
536
622
|
of thumb, additions larger than about 15 lines of code), we need an
|
537
|
-
explicit [public domain dedication][PDD] on record from you
|
623
|
+
explicit [public domain dedication][PDD] on record from you,
|
624
|
+
which you will be asked to agree to on the first commit to a repo within the organization.
|
625
|
+
Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization.
|
538
626
|
|
539
627
|
License
|
540
628
|
-------
|
@@ -546,8 +634,9 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
546
634
|
[RDF]: https://www.w3.org/RDF/
|
547
635
|
[YARD]: https://yardoc.org/
|
548
636
|
[YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
|
549
|
-
[PDD]: https://
|
637
|
+
[PDD]: https://unlicense.org/#unlicensing-contributions
|
550
638
|
[RDF.rb]: https://rubygems.org/gems/rdf
|
639
|
+
[JSON-LD*]: https://json-ld.github.io/json-ld-star/
|
551
640
|
[Rack::LinkedData]: https://rubygems.org/gems/rack-linkeddata
|
552
641
|
[Backports]: https://rubygems.org/gems/backports
|
553
642
|
[JSON-LD]: https://www.w3.org/TR/json-ld11/ "JSON-LD 1.1"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.
|
1
|
+
3.1.8
|
data/bin/jsonld
CHANGED
@@ -10,7 +10,7 @@ require 'getoptlong'
|
|
10
10
|
require 'open-uri'
|
11
11
|
require 'logger'
|
12
12
|
|
13
|
-
def run(input, options)
|
13
|
+
def run(input, options, parser_options)
|
14
14
|
reader_class = RDF::Reader.for(options[:input_format].to_sym)
|
15
15
|
raise "Reader not found for #{options[:input_format]}" unless reader_class
|
16
16
|
|
@@ -19,38 +19,38 @@ def run(input, options)
|
|
19
19
|
|
20
20
|
# If input format is not JSON-LD, transform input to JSON-LD first
|
21
21
|
reader = if options[:input_format] != :jsonld
|
22
|
-
reader_class.new(input,
|
22
|
+
reader_class.new(input, parser_options)
|
23
23
|
end
|
24
24
|
|
25
25
|
start = Time.new
|
26
26
|
if options[:expand]
|
27
|
-
|
27
|
+
parser_options = parser_options.merge(expandContext: parser_options.delete(:context)) if parser_options.key?(:context)
|
28
28
|
input = JSON::LD::API.fromRdf(reader) if reader
|
29
|
-
output = JSON::LD::API.expand(input,
|
29
|
+
output = JSON::LD::API.expand(input, parser_options)
|
30
30
|
secs = Time.new - start
|
31
31
|
options[:output].puts output.to_json(JSON::LD::JSON_STATE)
|
32
32
|
STDERR.puts "Expanded in #{secs} seconds." unless options[:quiet]
|
33
33
|
elsif options[:compact]
|
34
34
|
input = JSON::LD::API.fromRdf(reader) if reader
|
35
|
-
output = JSON::LD::API.compact(input,
|
35
|
+
output = JSON::LD::API.compact(input, parser_options[:context], parser_options)
|
36
36
|
secs = Time.new - start
|
37
37
|
options[:output].puts output.to_json(JSON::LD::JSON_STATE)
|
38
38
|
STDERR.puts "Compacted in #{secs} seconds." unless options[:quiet]
|
39
39
|
elsif options[:flatten]
|
40
40
|
input = JSON::LD::API.fromRdf(reader) if reader
|
41
|
-
output = JSON::LD::API.flatten(input,
|
41
|
+
output = JSON::LD::API.flatten(input, parser_options[:context], parser_options)
|
42
42
|
secs = Time.new - start
|
43
43
|
options[:output].puts output.to_json(JSON::LD::JSON_STATE)
|
44
44
|
STDERR.puts "Flattened in #{secs} seconds." unless options[:quiet]
|
45
45
|
elsif options[:frame]
|
46
46
|
input = JSON::LD::API.fromRdf(reader) if reader
|
47
|
-
output = JSON::LD::API.frame(input,
|
47
|
+
output = JSON::LD::API.frame(input, parser_options[:frame], parser_options)
|
48
48
|
secs = Time.new - start
|
49
49
|
options[:output].puts output.to_json(JSON::LD::JSON_STATE)
|
50
50
|
STDERR.puts "Framed in #{secs} seconds." unless options[:quiet]
|
51
51
|
else
|
52
|
-
|
53
|
-
parser_options
|
52
|
+
parser_options = parser_options.merge(expandContext: parser_options.delete(:context)) if parser_options.key?(:context)
|
53
|
+
parser_options[:standard_prefixes] = true
|
54
54
|
reader ||= JSON::LD::Reader.new(input, parser_options)
|
55
55
|
num = 0
|
56
56
|
RDF::Writer.for(options[:output_format]).new(options[:output], parser_options) do |w|
|
@@ -86,7 +86,6 @@ parser_options = {
|
|
86
86
|
}
|
87
87
|
|
88
88
|
options = {
|
89
|
-
parser_options: parser_options,
|
90
89
|
output: STDOUT,
|
91
90
|
output_format: :jsonld,
|
92
91
|
input_format: :jsonld,
|
@@ -141,50 +140,48 @@ opts = GetoptLong.new(*OPT_ARGS.map {|o| o[0..-2]})
|
|
141
140
|
opts.each do |opt, arg|
|
142
141
|
case opt
|
143
142
|
when '--debug' then logger.level = Logger::DEBUG
|
144
|
-
when '--compact' then
|
145
|
-
when "--compactArrays" then
|
146
|
-
when '--context' then
|
143
|
+
when '--compact' then parser_options[:compact] = true
|
144
|
+
when "--compactArrays" then parser_options[:compactArrays] = (arg || 'true') == 'true'
|
145
|
+
when '--context' then parser_options[:context] = RDF::URI(arg).absolute? ? arg : File.open(arg)
|
147
146
|
when '--evaluate' then input = arg
|
148
147
|
when '--expand' then options[:expand] = true
|
149
|
-
when "--expanded" then
|
150
|
-
when "--explicit" then
|
148
|
+
when "--expanded" then parser_options[:expanded] = (arg || 'true') == 'true'
|
149
|
+
when "--explicit" then parser_options[:compactArrays] = (arg || 'true') == 'true'
|
151
150
|
when '--format' then options[:output_format] = arg.to_sym
|
152
151
|
when '--flatten' then options[:flatten] = arg
|
153
|
-
when '--frame' then options[:frame] = arg
|
152
|
+
when '--frame' then options[:frame] = parser_otpions[:frame] = RDF::URI(arg).absolute? ? arg : File.open(arg)
|
154
153
|
when '--input-format' then options[:input_format] = arg.to_sym
|
155
|
-
when "--omitDefault" then
|
154
|
+
when "--omitDefault" then parser_options[:omitDefault] = (arg || 'true') == 'true'
|
156
155
|
when '--output' then options[:output] = File.open(arg, "w")
|
157
156
|
when '--parse-only' then options[:parse_only] = true
|
158
|
-
when '--processingMode' then
|
157
|
+
when '--processingMode' then parser_options[:processingMode] = arg
|
159
158
|
when '--quiet'
|
160
159
|
options[:quiet] = true
|
161
160
|
logger.level = Logger::FATAL
|
162
|
-
when "--rename_bnodes" then
|
163
|
-
when "--requireAll" then
|
161
|
+
when "--rename_bnodes" then parser_options[:rename_bnodes] = (arg || 'true') == 'true'
|
162
|
+
when "--requireAll" then parser_options[:requireAll] = (arg || 'true') == 'true'
|
164
163
|
when '--stream' then parser_options[:stream] = true
|
165
|
-
when "--unique_bnodes" then
|
164
|
+
when "--unique_bnodes" then parser_options[:unique_bnodes] = (arg || 'true') == 'true'
|
166
165
|
when '--uri' then parser_options[:base] = arg
|
167
166
|
when '--validate' then parser_options[:validate] = true
|
168
167
|
when '--help' then usage
|
169
168
|
when '--embed'
|
170
169
|
case arg
|
171
|
-
when '@always', '@never', '@link', '@
|
172
|
-
|
170
|
+
when '@always', '@never', '@link', '@once'
|
171
|
+
parser_options[:embed] = arg
|
173
172
|
when 'true'
|
174
|
-
|
173
|
+
parser_options[:embed] = '@never'
|
175
174
|
when 'false'
|
176
|
-
|
175
|
+
parser_options[:embed] = '@first'
|
177
176
|
else
|
178
|
-
STDERR.puts "--embed option takes one of @always, @never, @link,
|
177
|
+
STDERR.puts "--embed option takes one of @always, @never, @link, or @once"
|
179
178
|
exit(1)
|
180
179
|
end
|
181
180
|
end
|
182
181
|
end
|
183
182
|
|
184
183
|
# Hack
|
185
|
-
options
|
186
|
-
|
187
|
-
if !(options.keys & [:expand, :compact, :flatten, :frame]).empty? &&
|
184
|
+
if !(options.keys & %i{expand compact flatten frame}).empty? &&
|
188
185
|
(parser_options[:stream] || options[:output_format] != :jsonld)
|
189
186
|
STDERR.puts "Incompatible options"
|
190
187
|
exit(1)
|
@@ -192,11 +189,11 @@ end
|
|
192
189
|
|
193
190
|
if ARGV.empty?
|
194
191
|
s = input ? input : $stdin.read
|
195
|
-
run(StringIO.new(s), options)
|
192
|
+
run(StringIO.new(s), options, parser_options)
|
196
193
|
else
|
197
194
|
ARGV.each do |file|
|
198
195
|
# Call with opened files
|
199
|
-
RDF::Util::File.open_file(file, options) {|f| run(f, options)}
|
196
|
+
RDF::Util::File.open_file(file, options) {|f| run(f, options, parser_options)}
|
200
197
|
end
|
201
198
|
end
|
202
199
|
puts
|